Files
reui-blocks/blocks/case-studies5.tsx
T

220 lines
7.5 KiB
TypeScript

"use client";
import { AnimatePresence, motion } from "framer-motion";
import React, { useState } from "react";
import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
const SLIDES = [
{
name: "کاوه مرادی",
content:
"Laravel نحوه ساخت اپلیکیشن‌های وب ما را کاملاً متحول کرد. نحو زیبا، قابلیت‌های قدرتمند و مستندات عالی، توسعه را لذت‌بخش کرده است.",
logo: "/block-media/shadcnblocks/block/logos/laravel-wordmark.svg",
logoAlt: "لوگوی Laravel",
logoClass: "h-10 md:h-12",
imageAlt: "نمونه کار توسعه وب با Laravel",
images: [
{
src: "/block-media/shadcnblocks/block/photos/fabian-centeno-njeVb6E3XB8-unsplash.jpg",
position: 2,
},
{
src: "/block-media/shadcnblocks/block/photos/israel-andrade-YI_9SivVt_s-unsplash.jpg",
position: 4,
},
{
src: "/block-media/shadcnblocks/block/photos/studio-kealaula-IVZ_XAoZF3s-unsplash.jpg",
position: 7,
},
],
},
{
name: "مهسا نوری",
content:
"همکاری با این تیم کسب‌وکار ما را کاملاً متحول کرد. توجه به جزئیات و راهکارهای نوآورانه آن‌ها باعث شد در تنها شش ماه، درآمدمان ۴۰٪ افزایش یابد.",
logo: "/block-media/shadcnblocks/block/logos/tailwind-wordmark.svg",
logoAlt: "لوگوی Tailwind CSS",
logoClass: "h-6 md:h-8",
imageAlt: "نمونه کار طراحی رابط کاربری",
images: [
{
src: "/block-media/shadcnblocks/block/photos/annie-spratt-AkftcHujUmk-unsplash.jpg",
position: 1,
},
{
src: "/block-media/shadcnblocks/block/photos/nastuh-abootalebi-yWwob8kwOCk-unsplash.jpg",
position: 3,
},
{
src: "/block-media/shadcnblocks/block/photos/alvin-engler-bIhpiQA009k-unsplash.jpg",
position: 5,
},
],
},
{
name: "امیر محمدی",
content:
"این محصول فراتر از تمام انتظارات ما بود. شهودی، قدرتمند و دقیقاً همان چیزی که برای ساده‌سازی فرآیندهایمان نیاز داشتیم. برای هر کسب‌وکاری توصیه می‌شود.",
logo: "/block-media/shadcnblocks/block/logos/vercel-wordmark.svg",
logoAlt: "لوگوی Vercel",
logoClass: "h-6 md:h-8",
imageAlt: "نمونه کار استقرار و زیرساخت ابری",
images: [
{
src: "/block-media/shadcnblocks/block/photos/redd-f-5U_28ojjgms-unsplash.jpg",
position: 0,
},
{
src: "/block-media/shadcnblocks/block/photos/nubelson-fernandes-tAJYoec13xk-unsplash.jpg",
position: 4,
},
{
src: "/block-media/shadcnblocks/block/photos/nubelson-fernandes-xxa7qYObMrI-unsplash.jpg",
position: 7,
},
],
},
];
interface CaseStudies5Props {
className?: string;
}
const CaseStudies5 = ({ className }: CaseStudies5Props) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [carouselApi, setCarouselApi] = useState<CarouselApi>();
React.useEffect(() => {
if (!carouselApi) {
return;
}
const onSelect = () => {
setCurrentIndex(carouselApi.selectedScrollSnap());
};
carouselApi.on("select", onSelect);
return () => {
carouselApi.off("select", onSelect);
};
}, [carouselApi]);
const renderGrid = (
images: (typeof SLIDES)[0]["images"],
imageAlt: string,
) => {
return (
<div className="grid h-full w-full grid-cols-3 grid-rows-3 gap-3 p-3">
{Array.from({ length: 9 }).map((_, index) => {
const image = images.find((img) => img.position === index);
const isImage = Boolean(image);
return (
<div
key={index}
className={cn(
"w-full overflow-hidden rounded-lg",
!isImage && "bg-muted",
)}
>
{isImage && image?.src && (
<img
src={image.src}
alt={imageAlt}
className="aspect-square h-full w-full object-cover md:aspect-video"
loading={index === 0 ? "eager" : "lazy"}
/>
)}
</div>
);
})}
</div>
);
};
return (
<section
dir="rtl"
lang="fa"
className={cn("bg-background py-32", className)}
>
<div className="relative container">
<div className="mx-auto w-full overflow-hidden rounded-lg md:border">
<Carousel setApi={setCarouselApi}>
<div className="grid grid-cols-1 md:grid-cols-2">
<div className="relative">
<CarouselContent>
{SLIDES.map((testimonial, index) => (
<CarouselItem key={index}>
<div className="relative flex items-center justify-center overflow-hidden md:h-[500px]">
{renderGrid(testimonial.images, testimonial.imageAlt)}
</div>
</CarouselItem>
))}
</CarouselContent>
</div>
<div className="z-2 flex h-full items-center p-4 md:p-10">
<div className="flex flex-col gap-y-6 md:gap-y-8">
<AnimatePresence mode="wait">
<motion.div
key={currentIndex}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{
duration: 0.4,
ease: "easeOut",
}}
className="flex h-12 items-center gap-3"
>
<img
src={SLIDES[currentIndex].logo}
alt={SLIDES[currentIndex].logoAlt}
className={SLIDES[currentIndex].logoClass}
/>
</motion.div>
</AnimatePresence>
<AnimatePresence mode="wait">
<motion.p
key={currentIndex}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{
duration: 0.4,
ease: "easeOut",
delay: 0.15,
}}
className="min-h-[100px] text-start leading-snug tracking-tight text-muted-foreground sm:text-xl xl:ms-8"
>
{SLIDES[currentIndex].content}
</motion.p>
</AnimatePresence>
<div className="flex h-12 gap-4">
<CarouselPrevious className="static translate-y-0 rtl:rotate-180" />
<CarouselNext className="static translate-y-0 rtl:rotate-180" />
</div>
</div>
</div>
</div>
</Carousel>
</div>
</div>
</section>
);
};
export { CaseStudies5 };