291 lines
8.7 KiB
TypeScript
291 lines
8.7 KiB
TypeScript
"use client";
|
|
|
|
import { Play } from "lucide-react";
|
|
import { useRef, useState } from "react";
|
|
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const SOCIAL_ICONS = {
|
|
instagram: {
|
|
title: "اینستاگرام",
|
|
light:
|
|
"/block-media/shadcnblocks/block/logos/instagram-icon.svg",
|
|
dark: "/block-media/shadcnblocks/block/logos/instagram-icon.svg",
|
|
},
|
|
twitter: {
|
|
title: "توییتر",
|
|
light:
|
|
"/block-media/shadcnblocks/block/logos/twitter-icon.svg",
|
|
dark: "/block-media/shadcnblocks/block/logos/twitter-icon.svg",
|
|
},
|
|
} as const;
|
|
|
|
type SocialMediaIcon = { title: string; light: string; dark: string };
|
|
|
|
type ImagePost = {
|
|
type: "image";
|
|
image: {
|
|
src: string;
|
|
alt: string;
|
|
};
|
|
productLink: string;
|
|
socialMediaIcon?: SocialMediaIcon;
|
|
};
|
|
|
|
type VideoPost = {
|
|
type: "video";
|
|
video: string;
|
|
productLink: string;
|
|
socialMediaIcon?: SocialMediaIcon;
|
|
};
|
|
|
|
type SocialMediaPost = ImagePost | VideoPost;
|
|
|
|
type FeaturedSection = {
|
|
title: string;
|
|
profile: {
|
|
image: string;
|
|
username: string;
|
|
followers: string;
|
|
};
|
|
cta: {
|
|
label: string;
|
|
href: string;
|
|
};
|
|
};
|
|
|
|
interface SocialMediaTrending5Props {
|
|
className?: string;
|
|
posts?: SocialMediaPost[];
|
|
featuredSection?: FeaturedSection;
|
|
}
|
|
|
|
const SECTION_DATA = {
|
|
featuredSection: {
|
|
title: "آنلاین با ما در ارتباط باشید",
|
|
profile: {
|
|
image:
|
|
"/block-media/shadcnblocks/block/block-6.svg",
|
|
username: "@instagram",
|
|
followers: "۲۸ هزار دنبالکننده",
|
|
},
|
|
cta: {
|
|
label: "همین حالا بپیوندید",
|
|
href: "#",
|
|
},
|
|
},
|
|
posts: [
|
|
{
|
|
type: "image" as const,
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Checkered-Sunglasses-on-Stone-Pedestal-2.png",
|
|
alt: "عینک آفتابی شطرنجی",
|
|
},
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.instagram,
|
|
},
|
|
{
|
|
type: "video" as const,
|
|
video:
|
|
"/block-media/shadcnblocks/block/6875749-hd_720_1366_25fps.mp4",
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.instagram,
|
|
},
|
|
{
|
|
type: "image" as const,
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Elegant-Gold-Earrings-2.png",
|
|
alt: "گوشواره طلای ظریف",
|
|
},
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.twitter,
|
|
},
|
|
{
|
|
type: "image" as const,
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Golden-Hair-Clip-Close-Up-2.png",
|
|
alt: "کلیپس مو طلایی",
|
|
},
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.instagram,
|
|
},
|
|
{
|
|
type: "image" as const,
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Elegant-Jewelry-Close-Up-2.png",
|
|
alt: "نمای نزدیک جواهرات",
|
|
},
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.twitter,
|
|
},
|
|
{
|
|
type: "image" as const,
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Elegant-Pearl-Bracelet-on-Wrist-2.png",
|
|
alt: "دستبند مروارید",
|
|
},
|
|
productLink: "#",
|
|
socialMediaIcon: SOCIAL_ICONS.instagram,
|
|
},
|
|
] satisfies SocialMediaPost[],
|
|
};
|
|
|
|
const SocialIconOverlay = ({
|
|
icon,
|
|
showOnHover = true,
|
|
}: {
|
|
icon: SocialMediaIcon;
|
|
showOnHover?: boolean;
|
|
}) => (
|
|
<div
|
|
className={cn(
|
|
"pointer-events-none absolute top-3 end-3 flex size-10 items-center justify-center rounded-full bg-background/90 shadow-sm transition-opacity duration-200",
|
|
showOnHover ? "opacity-0 group-hover:opacity-100" : "invisible",
|
|
)}
|
|
>
|
|
<img className="size-5 dark:hidden" alt={icon.title} src={icon.light} />
|
|
<img
|
|
className="hidden size-5 dark:block"
|
|
alt={icon.title}
|
|
src={icon.dark}
|
|
/>
|
|
</div>
|
|
);
|
|
|
|
const VideoCard = ({
|
|
video,
|
|
productLink,
|
|
socialMediaIcon,
|
|
}: {
|
|
video: string;
|
|
productLink: string;
|
|
socialMediaIcon?: SocialMediaIcon;
|
|
}) => {
|
|
const videoRef = useRef<HTMLVideoElement>(null);
|
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
|
|
return (
|
|
<a
|
|
href={productLink}
|
|
className="group relative block aspect-square size-full overflow-hidden rounded-xl bg-muted"
|
|
aria-label="مشاهده ویدیوی شبکه اجتماعی"
|
|
>
|
|
<video
|
|
muted
|
|
playsInline
|
|
preload="metadata"
|
|
className="block size-full object-cover object-center"
|
|
onPlay={() => setIsPlaying(true)}
|
|
onPause={() => setIsPlaying(false)}
|
|
onMouseEnter={() => videoRef.current?.play()}
|
|
onMouseLeave={() => {
|
|
if (!videoRef.current) return;
|
|
videoRef.current.pause();
|
|
videoRef.current.currentTime = 0;
|
|
}}
|
|
ref={videoRef}
|
|
src={video}
|
|
/>
|
|
{!isPlaying && (
|
|
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
<div
|
|
className="rounded-full bg-background/80 p-4 transition-opacity duration-300 group-hover:scale-110 group-hover:bg-background/90"
|
|
aria-hidden
|
|
>
|
|
<Play className="size-8 fill-foreground text-foreground" />
|
|
<span className="sr-only">پخش ویدیو</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{socialMediaIcon && (
|
|
<SocialIconOverlay icon={socialMediaIcon} showOnHover={!isPlaying} />
|
|
)}
|
|
</a>
|
|
);
|
|
};
|
|
|
|
const SocialMediaTrending5 = ({
|
|
className,
|
|
posts = SECTION_DATA.posts,
|
|
featuredSection = SECTION_DATA.featuredSection,
|
|
}: SocialMediaTrending5Props) => {
|
|
return (
|
|
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
|
|
<div className="container">
|
|
<ul className="grid grid-cols-2 gap-4 lg:grid-cols-3 xl:grid-cols-4 [&>li]:overflow-hidden [&>li]:rounded-xl [&>li]:bg-accent">
|
|
<li className="col-span-2">
|
|
<div className="flex h-full flex-col gap-4 p-6 sm:flex-row sm:items-center">
|
|
<div className="flex-1 text-start">
|
|
<h3 className="text-xl leading-tight tracking-tight sm:max-w-60">
|
|
{featuredSection.title}
|
|
</h3>
|
|
</div>
|
|
<div className="space-y-10 lg:basis-50">
|
|
<div className="flex items-center gap-2.5">
|
|
<div className="shrink-0 basis-10">
|
|
<Avatar className="size-10 border">
|
|
<AvatarImage
|
|
src={featuredSection.profile.image}
|
|
alt={`آواتار ${featuredSection.profile.username}`}
|
|
/>
|
|
<AvatarFallback>
|
|
{featuredSection.profile.username}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
</div>
|
|
<div className="space-y-0.5 text-start">
|
|
<p className="leading-normal font-medium">
|
|
{featuredSection.profile.username}
|
|
</p>
|
|
<p className="text-sm text-muted-foreground">
|
|
{featuredSection.profile.followers}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<Button asChild size="lg" className="w-full">
|
|
<a
|
|
href={featuredSection.cta.href}
|
|
aria-label={`${featuredSection.cta.label} ${featuredSection.profile.username}`}
|
|
>
|
|
{featuredSection.cta.label}
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
{posts.map((post, index) => (
|
|
<li key={index} className="aspect-square">
|
|
{post.type === "video" ? (
|
|
<VideoCard
|
|
video={post.video}
|
|
productLink={post.productLink}
|
|
socialMediaIcon={post.socialMediaIcon}
|
|
/>
|
|
) : (
|
|
<a
|
|
href={post.productLink}
|
|
className="group relative block size-full overflow-hidden"
|
|
aria-label={`مشاهده پست ${post.socialMediaIcon?.title ?? "شبکه اجتماعی"}: ${post.image.alt}`}
|
|
>
|
|
<img
|
|
src={post.image.src}
|
|
alt={post.image.alt}
|
|
className="block size-full object-cover object-center"
|
|
/>
|
|
{post.socialMediaIcon && (
|
|
<SocialIconOverlay icon={post.socialMediaIcon} />
|
|
)}
|
|
</a>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { SocialMediaTrending5 };
|