Files
mugladijitalmedya/components/WorksClient.tsx

186 lines
9.2 KiB
TypeScript
Raw 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 Image from "next/image";
import { useState } from "react";
import Link from "next/link";
import { ArrowUpRight } from "lucide-react";
interface ProjectCardProps {
hero_image: string;
category: string;
title: string;
year: string;
client: string;
slug: string;
narrative_desc: string;
index: number;
}
function ProjectCard({ hero_image, category, title, year, client, slug, narrative_desc, index }: ProjectCardProps) {
// Alternating background colors like in the reference screenshot
const bgColors = ["bg-[#e2d1c1]", "bg-[#f9f6ef]", "bg-[#d8c7b8]", "bg-[#f5f1e8]"];
const bgColor = bgColors[index % bgColors.length];
return (
<Link href={`/works/${slug}`} className="group cursor-pointer block h-full">
<div className={`p-8 md:p-10 h-full flex flex-col transition-all duration-500 group-hover:translate-y-[-8px] ${bgColor}`}>
{/* 1. Image Area */}
<div className="relative aspect-[16/10] overflow-hidden mb-12 shadow-sm">
<Image
src={hero_image || "https://images.unsplash.com/photo-1536440136628-849c177e76a1"}
alt={title}
fill
className="object-cover transition-transform duration-1000 group-hover:scale-105"
/>
{/* Floating Title on Image like reference */}
<div className="absolute inset-0 flex flex-col items-center justify-center text-center p-6 bg-black/10">
<span className="text-[10px] tracking-[0.2em] uppercase text-white/80 mb-2">
{(() => {
let current = category;
try {
for (let i = 0; i < 3; i++) {
if (typeof current === 'string' && (current.trim().startsWith('[') || current.trim().startsWith('"'))) {
current = JSON.parse(current);
} else {
break;
}
}
return Array.isArray(current) ? current.join(" / ") : current;
} catch (e) {
return current;
}
})()}
</span>
<h3 className="editorial-headline text-3xl md:text-4xl text-white uppercase leading-tight drop-shadow-md">
{title}
</h3>
</div>
</div>
{/* 2. Description Area */}
<div className="flex-grow mb-12">
<p className="text-black/70 text-[13px] leading-[1.8] line-clamp-6 font-medium italic">
{narrative_desc || "Dijital dünyada markanızın sesini duyurmak ve özgün bir kimlik kazandırmak için tasarladığımız özel projelerimizden biri."}
</p>
</div>
{/* 3. Footer / Client Area */}
<div className="border-t border-black/10 pt-8 mt-auto">
<div className="flex justify-between items-end">
<div>
<span className="text-[9px] tracking-[0.2em] uppercase text-black/30 block mb-2">Müşteri</span>
<h4 className="editorial-headline text-3xl text-black uppercase opacity-80 group-hover:opacity-100 group-hover:text-primary transition-all">
{client || "Muğla Dijital"}
</h4>
</div>
<div className="text-[10px] font-black text-black/20 group-hover:text-primary transition-colors border border-black/5 px-2 py-1 rounded">
{year}
</div>
</div>
</div>
</div>
</Link>
);
}
export default function WorksClient({ projects: initialProjects }: { projects: any[] }) {
const [activeCategory, setActiveCategory] = useState("Hepsi");
const categories = ["Hepsi", ...Array.from(new Set(initialProjects.flatMap(p => {
let current = p.category;
try {
for (let i = 0; i < 3; i++) {
if (typeof current === 'string' && (current.trim().startsWith('[') || current.trim().startsWith('"'))) {
current = JSON.parse(current);
} else {
break;
}
}
} catch (e) { }
return Array.isArray(current) ? current : (typeof current === 'string' && current ? [current] : []);
})))];
const filteredProjects = activeCategory === "Hepsi"
? initialProjects
: initialProjects.filter(p => {
let current = p.category;
try {
for (let i = 0; i < 3; i++) {
if (typeof current === 'string' && (current.trim().startsWith('[') || current.trim().startsWith('"'))) {
current = JSON.parse(current);
} else {
break;
}
}
} catch (e) { }
const cats = Array.isArray(current) ? current : (typeof current === 'string' && current ? [current] : []);
return cats.includes(activeCategory);
});
return (
<main className="min-h-screen bg-[#f5f5f0] text-black pt-24">
<section className="pt-24 pb-24 px-6 md:px-12">
<div className="max-w-7xl mx-auto">
{/* Header Area */}
<div className="mb-20">
<span className="text-[10px] tracking-[0.2em] uppercase text-black/40 block mb-6">Portfolyo</span>
<h1 className="editorial-headline text-4xl md:text-6xl lg:text-[5.5rem] text-black reveal opacity-0 uppercase">
Seçilmiş <br /> <span className="text-primary">Projeler.</span>
</h1>
<p className="text-black/40 text-[14px] max-w-2xl leading-relaxed mt-10 reveal reveal-delayed-1 opacity-0">
Markanızın dijital dünyadaki serüvenini profesyonel dokunuşlarla şekillendiriyoruz. Global vizyon, yerel strateji ile başarı hikayeleri yazıyoruz.
</p>
</div>
{/* Filter Section */}
<div className="flex flex-col md:flex-row justify-between items-center gap-8 mb-16 border-y border-black/10 py-8">
<div className="flex flex-wrap items-center gap-3">
{categories.map((cat) => (
<button
key={cat}
onClick={() => setActiveCategory(cat)}
className={`px-6 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest transition-all border
${activeCategory === cat
? "bg-black text-white border-black"
: "text-black/40 border-black/10 hover:border-black/30 hover:text-black"
}`}
>
{cat}
</button>
))}
</div>
<div className="hidden md:block">
<span className="text-[10px] font-bold text-black/20 uppercase tracking-widest">
{filteredProjects.length} Proje
</span>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-12">
{filteredProjects.map((project, index) => (
<ProjectCard key={index} {...project} index={index} />
))}
</div>
{filteredProjects.length === 0 && (
<div className="py-32 text-center border border-black/10">
<p className="text-black/40 text-sm">Bu kategoride henüz bir proje bulunmuyor.</p>
</div>
)}
{/* CTA Section Area */}
<div className="mt-32 border-t border-black/10 pt-24 text-center space-y-10">
<h2 className="editorial-headline text-3xl md:text-5xl text-black uppercase">Sıradaki Başarı Hikayesi <br /><span className="text-primary">Sizinle</span> Yazılsın.</h2>
<Link href="/contact" className="button-primary mx-auto">
Projeyi Başlat
<ArrowUpRight className="w-4 h-4" />
</Link>
</div>
</div>
</section>
</main>
);
}