Files
mugladijitalmedya/components/SelectedWorks.tsx

135 lines
5.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { motion } from "framer-motion";
import { ArrowRight, Loader2 } from "lucide-react";
import { getFeaturedProjects } from "@/app/actions";
interface ProjectCardProps {
hero_image: string;
category: string;
title: string;
year: string;
subtitle: string;
slug: string;
index: number;
}
function ProjectCard({ hero_image, category, title, year, subtitle, slug, index }: ProjectCardProps) {
return (
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-50px" }}
transition={{ duration: 0.8, delay: (index % 3) * 0.1, ease: [0.16, 1, 0.3, 1] }}
>
<Link href={`/works/${slug}`} className="group cursor-pointer block">
<div className="space-y-5">
<div className="relative aspect-video overflow-hidden bg-black/5 border border-black/10">
<motion.div
className="w-full h-full"
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
>
<Image
src={hero_image || "https://images.unsplash.com/photo-1550745165-9bc0b252726f"}
alt={title}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
priority={index < 3}
className="object-cover transition-all duration-700 grayscale group-hover:grayscale-0"
/>
</motion.div>
{/* Category Badge */}
<div className="absolute top-4 right-4">
<span className="bg-white/90 backdrop-blur-sm border border-black/10 px-3 py-1 text-[9px] tracking-[0.15em] uppercase text-black/60">
{category}
</span>
</div>
</div>
{/* Content Below Image */}
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ delay: 0.2 + (index % 3) * 0.1 }}
>
<div className="flex justify-between items-start mb-2">
<h3 className="text-[14px] tracking-[0.05em] uppercase text-black group-hover:text-primary transition-colors leading-tight">
{title}
</h3>
<span className="text-[10px] text-black/30 tracking-[0.1em] uppercase mt-0.5">
{year}
</span>
</div>
<p className="text-[11px] text-black/40 leading-relaxed line-clamp-1">
{subtitle}
</p>
</motion.div>
</div>
</Link>
</motion.div>
);
}
export default function SelectedWorks() {
const [projects, setProjects] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchFeatured() {
setLoading(true);
const data = await getFeaturedProjects();
if (data && data.length > 0) {
setProjects(data);
}
setLoading(false);
}
fetchFeatured();
}, []);
if (loading) return (
<div className="py-32 flex justify-center">
<Loader2 className="w-8 h-8 text-primary animate-spin" />
</div>
);
if (projects.length === 0) return null;
return (
<section className="py-24 px-6 md:px-12 border-t border-black/10">
<div className="max-w-7xl mx-auto">
{/* Header Section */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8, ease: [0.16, 1, 0.3, 1] }}
className="flex flex-col md:flex-row justify-between items-start md:items-end gap-8 mb-16"
>
<div>
<span className="text-[10px] tracking-[0.2em] uppercase text-black/40 block mb-4">Son Projeler</span>
<h2 className="editorial-headline text-4xl md:text-5xl text-black">
Çalışma Örnekleri
</h2>
</div>
<Link href="/works" className="button-primary group">
Tüm Portfolyo
<ArrowRight className="w-3 h-3 group-hover:translate-x-1 transition-transform" />
</Link>
</motion.div>
{/* Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-10">
{projects.map((project, index) => (
<ProjectCard key={index} {...project} index={index} />
))}
</div>
</div>
</section>
);
}