Initial import of 1407 block sources under blocks/
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
"use client";
|
||||
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface Projects8type {
|
||||
id: number;
|
||||
title: string;
|
||||
category: string;
|
||||
description: string;
|
||||
image: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
const categoryLabels: Record<string, string> = {
|
||||
"MOONLIGHT VISIONS": "فروش",
|
||||
"PIXEL PARADE": "بازاریابی",
|
||||
"WANDER SKETCHES": "CRM",
|
||||
"ECHO FIELDS": "تحلیل",
|
||||
"NEON TAPESTRY": "پشتیبانی",
|
||||
VIDEOS: "گزارش",
|
||||
};
|
||||
|
||||
const filterCategories = [
|
||||
{ key: "ALL", label: "همه" },
|
||||
{ key: "MOONLIGHT VISIONS", label: "فروش" },
|
||||
{ key: "PIXEL PARADE", label: "بازاریابی" },
|
||||
{ key: "WANDER SKETCHES", label: "CRM" },
|
||||
{ key: "ECHO FIELDS", label: "تحلیل" },
|
||||
{ key: "NEON TAPESTRY", label: "پشتیبانی" },
|
||||
] as const;
|
||||
|
||||
const Projects8Data: Projects8type[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "افزایش ۴۰٪ نرخ تبدیل",
|
||||
category: "MOONLIGHT VISIONS",
|
||||
description:
|
||||
"پیادهسازی اتوماسیون ایمیل و امتیازدهی لید برای شرکت SaaS B2B.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/vanessa-werder-LjFEoGuj5eY-unsplash.jpg",
|
||||
tags: ["crm", "automation"],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "کاهش ۶۰٪ زمان پاسخگویی",
|
||||
category: "PIXEL PARADE",
|
||||
description:
|
||||
"یکپارچهسازی CRM با سیستم تیکتینگ برای تیم پشتیبانی ۵۰ نفره.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/vasilis-karkalas-qOaeVSKyhhE-unsplash.jpg",
|
||||
tags: ["support", "crm"],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "داشبورد فروش یکپارچه",
|
||||
category: "WANDER SKETCHES",
|
||||
description:
|
||||
"ساخت داشبورد KPI برای نمایش درآمد، قیف فروش و پیشبینی فصلی.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/vanessa-werder-PrsQ3hfBFTI-unsplash.jpg",
|
||||
tags: ["analytics", "sales"],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "داشبورد تحلیلی",
|
||||
category: "ECHO FIELDS",
|
||||
description:
|
||||
"داشبورد تحلیلی برای نمایش KPIهای فروش و بازاریابی با نمودارهای تعاملی.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/pat-whelen-gWfpmH0H2bM-unsplash.jpg",
|
||||
tags: ["analytics", "dashboard"],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "خودکارسازی کمپین",
|
||||
category: "NEON TAPESTRY",
|
||||
description:
|
||||
"راهاندازی جریانهای ایمیل هدفمند برای ۱۲ بخش مخاطب مختلف.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/vanessa-werder-4G228Duzmn8-unsplash.jpg",
|
||||
tags: ["marketing", "email"],
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "گزارش عملکرد فصلی",
|
||||
category: "VIDEOS",
|
||||
description:
|
||||
"گزارش تحلیلی سهماهه با بررسی ROI کمپینها و رشد درآمد تکرارشونده.",
|
||||
image:
|
||||
"/block-media/shadcnblocks/block/photos/vasilis-karkalas-1LT5DG5BD6Q-unsplash.jpg",
|
||||
tags: ["reporting", "revenue"],
|
||||
},
|
||||
];
|
||||
|
||||
interface Projects8Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Projects8 = ({ className }: Projects8Props) => {
|
||||
const [activeFilter, setActiveFilter] = useState<string>("ALL");
|
||||
const [filteredItems, setFilteredItems] = useState(Projects8Data);
|
||||
|
||||
const handleFilterChange = (category: string) => {
|
||||
setActiveFilter(category);
|
||||
|
||||
if (category === "ALL") {
|
||||
setFilteredItems(Projects8Data);
|
||||
} else {
|
||||
const filtered = Projects8Data.filter(
|
||||
(item) =>
|
||||
item.category === category ||
|
||||
item.tags.includes(category.toLowerCase().replace(" ", "-")),
|
||||
);
|
||||
setFilteredItems(filtered);
|
||||
}
|
||||
};
|
||||
|
||||
const activeFilterLabel =
|
||||
filterCategories.find((item) => item.key === activeFilter)?.label ??
|
||||
categoryLabels[activeFilter] ??
|
||||
activeFilter;
|
||||
|
||||
return (
|
||||
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
|
||||
<div className="container">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<div className="mb-16 flex flex-wrap justify-center gap-8">
|
||||
{filterCategories.map(({ key, label }) => (
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => handleFilterChange(key)}
|
||||
className={`text-sm font-medium tracking-wider transition-colors duration-300 hover:text-foreground ${
|
||||
activeFilter === key
|
||||
? "border-b-2 border-border pb-1 text-foreground"
|
||||
: "text-gray-500"
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<motion.div layout className="grid grid-cols-1 gap-8 md:grid-cols-3">
|
||||
<AnimatePresence mode="wait">
|
||||
{filteredItems.map((item) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
layout
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.9 }}
|
||||
transition={{
|
||||
duration: 0.2,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
className="group relative cursor-pointer overflow-hidden rounded-lg"
|
||||
>
|
||||
<div className="relative aspect-[4/3] h-96 w-full">
|
||||
<img
|
||||
src={item.image}
|
||||
alt={item.title}
|
||||
className="object-cover transition-transform duration-300"
|
||||
/>
|
||||
|
||||
<motion.div className="absolute inset-0 flex flex-col items-center justify-center bg-black/60 p-8 text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100">
|
||||
<motion.div className="translate-y-5 text-center opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100">
|
||||
<p className="mb-4 text-xs font-medium tracking-widest text-gray-300">
|
||||
{categoryLabels[item.category] ?? item.category}
|
||||
</p>
|
||||
<h3 className="mb-4 text-2xl font-light tracking-wide">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="max-w-xs text-sm leading-relaxed text-gray-200">
|
||||
{item.description}
|
||||
</p>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
|
||||
{filteredItems.length === 0 && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
className="py-16 text-center"
|
||||
>
|
||||
<p className="text-lg text-gray-500">
|
||||
موردی در دسته «{activeFilterLabel}» یافت نشد.
|
||||
</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export { Projects8 };
|
||||
Reference in New Issue
Block a user