chore(strip): verwijder ongebruikte dependencies en marketing-restanten
- next-mdx-remote en gray-matter uit package.json (0 imports) - components/ui/hero-section-2.tsx en timeline.tsx (nergens geimporteerd) - lokale .DS_Store-bestanden opgeruimd (stonden al in .gitignore) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,204 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Image from 'next/image';
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
// Icon component for contact details
|
|
||||||
const InfoIcon = ({ type }: { type: 'website' | 'phone' | 'address' }) => {
|
|
||||||
const icons = {
|
|
||||||
website: (
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-5 w-5 text-primary">
|
|
||||||
<circle cx="12" cy="12" r="10"></circle>
|
|
||||||
<line x1="2" x2="22" y1="12" y2="12"></line>
|
|
||||||
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
phone: (
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-5 w-5 text-primary">
|
|
||||||
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
address: (
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-5 w-5 text-primary">
|
|
||||||
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path>
|
|
||||||
<circle cx="12" cy="10" r="3"></circle>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
};
|
|
||||||
return <div className="mr-2 flex-shrink-0">{icons[type]}</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Prop types for the HeroSection component
|
|
||||||
interface HeroSectionProps {
|
|
||||||
logo?: {
|
|
||||||
url: string;
|
|
||||||
alt: string;
|
|
||||||
text?: string;
|
|
||||||
};
|
|
||||||
slogan?: string;
|
|
||||||
title: React.ReactNode;
|
|
||||||
subtitle: string | React.ReactNode;
|
|
||||||
punchline?: string | React.ReactNode;
|
|
||||||
callToAction: {
|
|
||||||
text: string;
|
|
||||||
href: string;
|
|
||||||
};
|
|
||||||
secondaryCallToAction?: {
|
|
||||||
text: string;
|
|
||||||
href: string;
|
|
||||||
};
|
|
||||||
backgroundImage: string;
|
|
||||||
contactInfo?: {
|
|
||||||
website: string;
|
|
||||||
phone: string;
|
|
||||||
address: string;
|
|
||||||
};
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const HeroSection = React.forwardRef<HTMLDivElement, HeroSectionProps>(
|
|
||||||
({ className, logo, slogan, title, subtitle, punchline, callToAction, secondaryCallToAction, backgroundImage, contactInfo, ...props }, ref) => {
|
|
||||||
|
|
||||||
// Animation variants for the container to orchestrate children animations
|
|
||||||
const containerVariants = {
|
|
||||||
hidden: { opacity: 0 },
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
staggerChildren: 0.15,
|
|
||||||
delayChildren: 0.2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Animation variants for individual text/UI elements
|
|
||||||
const itemVariants = {
|
|
||||||
hidden: { y: 20, opacity: 0 },
|
|
||||||
visible: {
|
|
||||||
y: 0,
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
duration: 0.5,
|
|
||||||
ease: "easeOut" as const,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<motion.section
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"relative flex w-full flex-col overflow-hidden bg-background text-foreground md:flex-row",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
initial="hidden"
|
|
||||||
animate="visible"
|
|
||||||
variants={containerVariants}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{/* Left Side: Content */}
|
|
||||||
<div className="flex w-full flex-col justify-between p-8 md:w-1/2 md:p-12 lg:w-3/5 lg:p-16">
|
|
||||||
{/* Top Section: Logo & Main Content */}
|
|
||||||
<div>
|
|
||||||
<motion.header className="mb-12" variants={itemVariants}>
|
|
||||||
{logo && (
|
|
||||||
<div className="flex items-center">
|
|
||||||
<Image
|
|
||||||
src={logo.url}
|
|
||||||
alt={logo.alt}
|
|
||||||
width={120}
|
|
||||||
height={32}
|
|
||||||
className="mr-3 h-8 w-auto"
|
|
||||||
unoptimized
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{logo.text && <p className="text-lg font-bold text-foreground">{logo.text}</p>}
|
|
||||||
{slogan && <p className="text-xs tracking-wider text-muted-foreground">{slogan}</p>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</motion.header>
|
|
||||||
|
|
||||||
<motion.main variants={containerVariants}>
|
|
||||||
<motion.h1 className="text-4xl font-bold leading-tight text-foreground md:text-5xl lg:text-6xl" variants={itemVariants}>
|
|
||||||
{title}
|
|
||||||
</motion.h1>
|
|
||||||
<motion.div className="my-6 h-1 w-20 bg-primary" variants={itemVariants}></motion.div>
|
|
||||||
<motion.div className="mb-6 max-w-lg text-base md:text-lg leading-relaxed text-slate-600" variants={itemVariants}>
|
|
||||||
{subtitle}
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
{punchline && (
|
|
||||||
<motion.aside
|
|
||||||
className="mb-8 max-w-lg md:max-w-2xl border-l-4 border-primary bg-slate-50 p-6 rounded-r-lg"
|
|
||||||
variants={itemVariants}
|
|
||||||
role="note"
|
|
||||||
>
|
|
||||||
<div className="text-base md:text-lg font-medium text-slate-800 leading-relaxed [&_*:not(br)]:whitespace-normal md:[&_*:not(br)]:whitespace-nowrap">
|
|
||||||
{punchline}
|
|
||||||
</div>
|
|
||||||
</motion.aside>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<motion.div className="flex flex-col sm:flex-row gap-4" variants={itemVariants}>
|
|
||||||
<a
|
|
||||||
href={callToAction.href}
|
|
||||||
className="inline-block px-8 py-4 bg-primary hover:bg-primary/90 text-white font-bold text-base tracking-wide rounded-lg transition-colors text-center"
|
|
||||||
>
|
|
||||||
{callToAction.text}
|
|
||||||
</a>
|
|
||||||
{secondaryCallToAction && (
|
|
||||||
<a
|
|
||||||
href={secondaryCallToAction.href}
|
|
||||||
className="inline-block px-8 py-4 border-2 border-slate-300 hover:bg-slate-50 text-slate-700 font-medium text-base rounded-lg transition-colors text-center"
|
|
||||||
>
|
|
||||||
{secondaryCallToAction.text}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</motion.div>
|
|
||||||
</motion.main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Bottom Section: Footer Info */}
|
|
||||||
{contactInfo && (
|
|
||||||
<motion.footer className="mt-12 w-full" variants={itemVariants}>
|
|
||||||
<div className="grid grid-cols-1 gap-6 text-xs text-muted-foreground sm:grid-cols-3">
|
|
||||||
<div className="flex items-center">
|
|
||||||
<InfoIcon type="website" />
|
|
||||||
<span>{contactInfo.website}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center">
|
|
||||||
<InfoIcon type="phone" />
|
|
||||||
<span>{contactInfo.phone}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center">
|
|
||||||
<InfoIcon type="address" />
|
|
||||||
<span>{contactInfo.address}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</motion.footer>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right Side: Image with Clip Path Animation */}
|
|
||||||
<motion.div
|
|
||||||
className="w-full h-[40vh] bg-cover bg-center md:w-1/2 md:h-auto md:min-h-full lg:w-2/5"
|
|
||||||
style={{
|
|
||||||
backgroundImage: `url(${backgroundImage})`,
|
|
||||||
}}
|
|
||||||
initial={{ clipPath: 'polygon(100% 0, 100% 0, 100% 100%, 100% 100%)' }}
|
|
||||||
animate={{ clipPath: 'polygon(25% 0, 100% 0, 100% 100%, 0% 100%)' }}
|
|
||||||
transition={{ duration: 1.2, ease: "circOut" }}
|
|
||||||
>
|
|
||||||
</motion.div>
|
|
||||||
</motion.section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
HeroSection.displayName = "HeroSection";
|
|
||||||
|
|
||||||
export { HeroSection };
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import {
|
|
||||||
useMotionValueEvent,
|
|
||||||
useScroll,
|
|
||||||
useTransform,
|
|
||||||
motion,
|
|
||||||
} from "framer-motion";
|
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
|
||||||
|
|
||||||
interface TimelineEntry {
|
|
||||||
title: string;
|
|
||||||
content: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Timeline = ({ data }: { data: TimelineEntry[] }) => {
|
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
|
||||||
const [height, setHeight] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (ref.current) {
|
|
||||||
const rect = ref.current.getBoundingClientRect();
|
|
||||||
setHeight(rect.height);
|
|
||||||
}
|
|
||||||
}, [ref]);
|
|
||||||
|
|
||||||
const { scrollYProgress } = useScroll({
|
|
||||||
target: containerRef,
|
|
||||||
offset: ["start 10%", "end 50%"],
|
|
||||||
});
|
|
||||||
|
|
||||||
const heightTransform = useTransform(scrollYProgress, [0, 1], [0, height]);
|
|
||||||
const opacityTransform = useTransform(scrollYProgress, [0, 0.1], [0, 1]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="w-full bg-white dark:bg-neutral-950 font-sans md:px-10"
|
|
||||||
ref={containerRef}
|
|
||||||
>
|
|
||||||
<div className="max-w-7xl mx-auto py-20 px-4 md:px-8 lg:px-10">
|
|
||||||
<h2 className="text-lg md:text-4xl mb-4 text-black dark:text-white max-w-4xl">
|
|
||||||
Changelog from my journey
|
|
||||||
</h2>
|
|
||||||
<p className="text-neutral-700 dark:text-neutral-300 text-sm md:text-base max-w-sm">
|
|
||||||
I've been working on Aceternity for the past 2 years. Here's
|
|
||||||
a timeline of my journey.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div ref={ref} className="relative max-w-7xl mx-auto pb-20">
|
|
||||||
{data.map((item, index) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="flex justify-start pt-10 md:pt-40 md:gap-10"
|
|
||||||
>
|
|
||||||
<div className="sticky flex flex-col md:flex-row z-40 items-center top-40 self-start max-w-xs lg:max-w-sm md:w-full">
|
|
||||||
<div className="h-10 absolute left-3 md:left-3 w-10 rounded-full bg-white dark:bg-black flex items-center justify-center">
|
|
||||||
<div className="h-4 w-4 rounded-full bg-neutral-200 dark:bg-neutral-800 border border-neutral-300 dark:border-neutral-700 p-2" />
|
|
||||||
</div>
|
|
||||||
<h3 className="hidden md:block text-xl md:pl-20 md:text-5xl font-bold text-neutral-500 dark:text-neutral-500 ">
|
|
||||||
{item.title}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="relative pl-20 pr-4 md:pl-4 w-full">
|
|
||||||
<h3 className="md:hidden block text-2xl mb-4 text-left font-bold text-neutral-500 dark:text-neutral-500">
|
|
||||||
{item.title}
|
|
||||||
</h3>
|
|
||||||
{item.content}{" "}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: height + "px",
|
|
||||||
}}
|
|
||||||
className="absolute md:left-8 left-8 top-0 overflow-hidden w-[2px] bg-[linear-gradient(to_bottom,var(--tw-gradient-stops))] from-transparent from-[0%] via-neutral-200 dark:via-neutral-700 to-transparent to-[99%] [mask-image:linear-gradient(to_bottom,transparent_0%,black_10%,black_90%,transparent_100%)] "
|
|
||||||
>
|
|
||||||
<motion.div
|
|
||||||
style={{
|
|
||||||
height: heightTransform,
|
|
||||||
opacity: opacityTransform,
|
|
||||||
}}
|
|
||||||
className="absolute inset-x-0 top-0 w-[2px] bg-gradient-to-t from-teal-500 via-teal-400 to-transparent from-[0%] via-[10%] rounded-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -53,10 +53,8 @@
|
|||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"framer-motion": "^12.23.24",
|
"framer-motion": "^12.23.24",
|
||||||
"gray-matter": "^4.0.3",
|
|
||||||
"lucide-react": "^0.553.0",
|
"lucide-react": "^0.553.0",
|
||||||
"next": "14.2.18",
|
"next": "14.2.18",
|
||||||
"next-mdx-remote": "^5.0.0",
|
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
|
|||||||
1125
pnpm-lock.yaml
generated
1125
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user