Compare commits

...

2 Commits

Author SHA1 Message Date
72f13c7c2e ♻️ refactor: restructure hero swiper to be media-specific 2026-03-25 19:44:54 +07:00
f9104c2580 Merge pull request 'feat/recommendation' (#10) from feat/recommendation into main
All checks were successful
Sync to GitHub / sync (push) Successful in 11s
Reviewed-on: #10
2026-03-15 22:36:54 +07:00

View File

@ -5,19 +5,19 @@ import { Button } from "@/shared/libs/shadcn/ui/button";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { Autoplay, Navigation, Pagination } from "swiper/modules"; import { Autoplay, Navigation, Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
import { Icon } from "@iconify/react";
export interface HeroSwiperProps { export interface HeroSwiperProps {
data: { data: {
id: string; id: string;
isClickable: boolean;
title: string; title: string;
tags: string[]; slug: string;
description: string;
buttonContent: string;
buttonLink: string;
imageUrl: string; imageUrl: string;
startDate: string; synopsis: string;
endDate: string; genres: {
slug: string;
name: string;
}[];
}[]; }[];
} }
@ -34,16 +34,13 @@ const HeroSwiper = (props: HeroSwiperProps) => {
autoplay={{ delay: 5000, disableOnInteraction: false }} autoplay={{ delay: 5000, disableOnInteraction: false }}
modules={[Autoplay, Pagination, Navigation]} modules={[Autoplay, Pagination, Navigation]}
> >
{props.data.map((slide) => {props.data.map((slide) => (
slide.imageUrl ? (
// Slide with image background
<SwiperSlide key={slide.id} className="relative overflow-hidden"> <SwiperSlide key={slide.id} className="relative overflow-hidden">
<img <img
src={slide.imageUrl} src={slide.imageUrl}
alt={slide.title} alt={slide.title}
className="absolute top-0 left-0 z-0 object-cover w-full h-full opacity-80" className="absolute top-0 left-0 z-0 object-cover w-full h-full opacity-80"
/> />
{slide.title && slide.description && (
<div <div
className="absolute top-0 left-0 z-10 h-full w-full py-16 px-20" className="absolute top-0 left-0 z-10 h-full w-full py-16 px-20"
style={{ style={{
@ -55,61 +52,36 @@ const HeroSwiper = (props: HeroSwiperProps) => {
{slide.title} {slide.title}
</h1> </h1>
<div className="mt-4 flex gap-1.5"> <div className="mt-4 flex gap-1.5">
{slide.tags.map((tag) => ( {slide.genres.map((genre) => (
<Badge <Badge
className="bg-neutral-200 text-neutral-800" className="bg-neutral-200 text-neutral-800"
key={tag} key={genre.slug}
> >
{tag} {genre.name}
</Badge> </Badge>
))} ))}
</div> </div>
<p className="mt-4 font-medium text-base max-w-[40vw] line-clamp-6"> <p className="mt-4 font-medium text-base max-w-[40vw] line-clamp-6">
{slide.description} {slide.synopsis}
</p> </p>
{slide.isClickable && (
<Button <Button
size="lg" size="lg"
onClick={() => router.push(slide.buttonLink)} onClick={() => router.push(`/media/${slide.slug}`)}
className="mt-6" className="mt-6 h-12 rounded-xl flex gap-2 px-4 hover:bg-neutral-950 group"
> >
{slide.buttonContent} <div className="bg-neutral-950 p-2 rounded-full group-hover:bg-primary">
</Button> <Icon
)} icon="solar:play-bold"
className="text-primary group-hover:text-neutral-950"
/>
</div>
<span className="font-semibold text-neutral-950 group-hover:text-primary">
Watch Now
</span>
</Button>
</div> </div>
)}
</SwiperSlide> </SwiperSlide>
) : (
// Fallback for slides without image
<SwiperSlide
key={slide.id}
className="relative overflow-hidden bg-neutral-800 flex flex-col items-center text-center pt-18"
>
<h1 className="text-6xl font-semibold tracking-tight">
{slide.title}
</h1>
<div className="mt-4 flex justify-center gap-1.5">
{slide.tags.map((tag) => (
<Badge className="bg-neutral-200 text-neutral-800" key={tag}>
{tag}
</Badge>
))} ))}
</div>
<p className="mt-4 font-medium text-base max-w-[40vw] mx-auto">
{slide.description}
</p>
{slide.isClickable && (
<Button
size="lg"
onClick={() => router.push(slide.buttonLink)}
className="mt-6"
>
{slide.buttonContent}
</Button>
)}
</SwiperSlide>
),
)}
</Swiper> </Swiper>
</div> </div>
); );