Files
reui-blocks/blocks/social-media-trending5.tsx
T

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 };