From 72f13c7c2e02c4e4e86e1e159056c30279597617 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Wed, 25 Mar 2026 19:44:54 +0700 Subject: [PATCH 1/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20restructur?= =?UTF-8?q?e=20hero=20swiper=20to=20be=20media-specific?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/sections/Hero/components/Swiper.tsx | 122 +++++++----------- 1 file changed, 47 insertions(+), 75 deletions(-) diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index 82239d8..60f11c2 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -5,19 +5,19 @@ import { Button } from "@/shared/libs/shadcn/ui/button"; import { useRouter } from "next/navigation"; import { Autoplay, Navigation, Pagination } from "swiper/modules"; import { Swiper, SwiperSlide } from "swiper/react"; +import { Icon } from "@iconify/react"; export interface HeroSwiperProps { data: { id: string; - isClickable: boolean; title: string; - tags: string[]; - description: string; - buttonContent: string; - buttonLink: string; + slug: string; imageUrl: string; - startDate: string; - endDate: string; + synopsis: string; + genres: { + slug: string; + name: string; + }[]; }[]; } @@ -34,82 +34,54 @@ const HeroSwiper = (props: HeroSwiperProps) => { autoplay={{ delay: 5000, disableOnInteraction: false }} modules={[Autoplay, Pagination, Navigation]} > - {props.data.map((slide) => - slide.imageUrl ? ( - // Slide with image background - - {slide.title} - {slide.title && slide.description && ( -
-

- {slide.title} -

-
- {slide.tags.map((tag) => ( - - {tag} - - ))} -
-

- {slide.description} -

- {slide.isClickable && ( - - )} -
- )} -
- ) : ( - // Fallback for slides without image - ( + + {slide.title} +

{slide.title}

-
- {slide.tags.map((tag) => ( - - {tag} +
+ {slide.genres.map((genre) => ( + + {genre.name} ))}
-

- {slide.description} +

+ {slide.synopsis}

- {slide.isClickable && ( - - )} - - ), - )} + +
+ + ))}
); From 4e5d509e99c30b04cbd81bce9090ebe5581e521c Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Thu, 26 Mar 2026 14:02:46 +0700 Subject: [PATCH 2/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20change=20s?= =?UTF-8?q?wiper=20key=20from=20banner=20id=20to=20index?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/home/sections/Hero/components/Swiper.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index 60f11c2..f722fbb 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -34,8 +34,8 @@ const HeroSwiper = (props: HeroSwiperProps) => { autoplay={{ delay: 5000, disableOnInteraction: false }} modules={[Autoplay, Pagination, Navigation]} > - {props.data.map((slide) => ( - + {props.data.map((slide, index) => ( + {slide.title} Date: Thu, 26 Mar 2026 15:22:01 +0700 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=90=9B=20fix:=20correct=20watch=20but?= =?UTF-8?q?ton=20and=20genre=20on=20swiper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/sections/Hero/components/Swiper.tsx | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index f722fbb..09c1362 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -2,10 +2,10 @@ import "swiper/css"; import { Badge } from "@/shared/libs/shadcn/ui/badge"; import { Button } from "@/shared/libs/shadcn/ui/button"; -import { useRouter } from "next/navigation"; import { Autoplay, Navigation, Pagination } from "swiper/modules"; import { Swiper, SwiperSlide } from "swiper/react"; import { Icon } from "@iconify/react"; +import Link from "next/link"; export interface HeroSwiperProps { data: { @@ -22,7 +22,6 @@ export interface HeroSwiperProps { } const HeroSwiper = (props: HeroSwiperProps) => { - const router = useRouter(); return (
{
{slide.genres.map((genre) => ( - - {genre.name} - + + + {genre.name} + + ))}

{slide.synopsis}

- +
+ + + +
))} From 7a4c92526e35a197ff98bd846f30c6693059a501 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Thu, 26 Mar 2026 16:50:31 +0700 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=92=84=20style:=20add=20"add=20to=20l?= =?UTF-8?q?ist"=20button=20to=20banner=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/sections/Hero/components/Swiper.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index 09c1362..2b78bdd 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -6,6 +6,7 @@ import { Autoplay, Navigation, Pagination } from "swiper/modules"; import { Swiper, SwiperSlide } from "swiper/react"; import { Icon } from "@iconify/react"; import Link from "next/link"; +import { useAuth } from "@/shared/contexts/AuthContext"; export interface HeroSwiperProps { data: { @@ -22,6 +23,7 @@ export interface HeroSwiperProps { } const HeroSwiper = (props: HeroSwiperProps) => { + const { session } = useAuth(); return (
{

{slide.synopsis}

-
+
+ {session?.user && ( + + )}
From 6f2588250cd50748c539f884038e571871dff7c0 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Fri, 27 Mar 2026 22:28:32 +0700 Subject: [PATCH 5/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20extract=20?= =?UTF-8?q?bookmark=20logic=20from=20banner=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/Hero/components/AddToList.tsx | 23 +++++++++++++++++++ .../home/sections/Hero/components/Swiper.tsx | 13 ++--------- 2 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 features/home/sections/Hero/components/AddToList.tsx diff --git a/features/home/sections/Hero/components/AddToList.tsx b/features/home/sections/Hero/components/AddToList.tsx new file mode 100644 index 0000000..2ae4380 --- /dev/null +++ b/features/home/sections/Hero/components/AddToList.tsx @@ -0,0 +1,23 @@ +import { useAuth } from "@/shared/contexts/AuthContext"; +import { Button } from "@/shared/libs/shadcn/ui/button"; +import { Icon } from "@iconify/react"; + +const AddToList = ({ mediaId }: { mediaId: string }) => { + const { session } = useAuth(); + + return ( +
+ {session?.user && ( + + )} +
+ ); +}; + +export default AddToList; diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index 2b78bdd..0fddea5 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -6,7 +6,7 @@ import { Autoplay, Navigation, Pagination } from "swiper/modules"; import { Swiper, SwiperSlide } from "swiper/react"; import { Icon } from "@iconify/react"; import Link from "next/link"; -import { useAuth } from "@/shared/contexts/AuthContext"; +import AddToList from "./AddToList"; export interface HeroSwiperProps { data: { @@ -23,7 +23,6 @@ export interface HeroSwiperProps { } const HeroSwiper = (props: HeroSwiperProps) => { - const { session } = useAuth(); return (
{ - {session?.user && ( - - )} +
From 99bf72c1af3ba08eca3fe7c75e6675a6262f3062 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Sun, 29 Mar 2026 11:34:08 +0700 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=91=94=20feat:=20add=20save=20button?= =?UTF-8?q?=20endpoint=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/Hero/addHeroBannerMediaToSaved.ts | 18 ++++++++++++++++++ .../sections/Hero/components/AddToList.tsx | 8 ++++++++ .../home/sections/Hero/components/Swiper.tsx | 2 -- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 features/home/actions/Hero/addHeroBannerMediaToSaved.ts diff --git a/features/home/actions/Hero/addHeroBannerMediaToSaved.ts b/features/home/actions/Hero/addHeroBannerMediaToSaved.ts new file mode 100644 index 0000000..8a1c3a1 --- /dev/null +++ b/features/home/actions/Hero/addHeroBannerMediaToSaved.ts @@ -0,0 +1,18 @@ +"use server"; + +import { backendFetch } from "@/shared/helpers/backendFetch"; + +export const addHeroBannerMediaToSaved = async (mediaId: string) => { + try { + return await backendFetch("collections/sys", { + method: "POST", + body: JSON.stringify({ + name: "Saved", + itemId: mediaId, + }), + }); + } catch (error) { + console.error("Error adding media to saved list:", error); + return { success: false, message: "Failed to add media to saved list." }; + } +}; diff --git a/features/home/sections/Hero/components/AddToList.tsx b/features/home/sections/Hero/components/AddToList.tsx index 2ae4380..c9606ec 100644 --- a/features/home/sections/Hero/components/AddToList.tsx +++ b/features/home/sections/Hero/components/AddToList.tsx @@ -1,3 +1,5 @@ +"use client"; +import { addHeroBannerMediaToSaved } from "@/features/home/actions/Hero/addHeroBannerMediaToSaved"; import { useAuth } from "@/shared/contexts/AuthContext"; import { Button } from "@/shared/libs/shadcn/ui/button"; import { Icon } from "@iconify/react"; @@ -5,10 +7,16 @@ import { Icon } from "@iconify/react"; const AddToList = ({ mediaId }: { mediaId: string }) => { const { session } = useAuth(); + const handleAddToList = async () => { + const result = await addHeroBannerMediaToSaved(mediaId); + console.log("Hasil dari fungsi server:", result); + }; + return (
{session?.user && ( - )} + {session?.user && + (isSaved ? ( + + ) : ( + + ))}
); }; diff --git a/features/home/sections/Hero/components/Swiper.tsx b/features/home/sections/Hero/components/Swiper.tsx index 5b9ddfc..40322f5 100644 --- a/features/home/sections/Hero/components/Swiper.tsx +++ b/features/home/sections/Hero/components/Swiper.tsx @@ -19,6 +19,7 @@ export interface HeroSwiperProps { slug: string; name: string; }[]; + isInCollection: boolean; }[]; } @@ -81,7 +82,10 @@ const HeroSwiper = (props: HeroSwiperProps) => { - +
diff --git a/features/home/sections/Recommendation/components/Card.tsx b/features/home/sections/Recommendation/components/Card.tsx index d4662c4..d93df64 100644 --- a/features/home/sections/Recommendation/components/Card.tsx +++ b/features/home/sections/Recommendation/components/Card.tsx @@ -1,4 +1,4 @@ -import { RecommendationAnime } from "@/features/home/actions/getRecommenationAnime"; +import { RecommendationAnime } from "@/features/home/actions/Hero/getRecommenationAnime"; import { Icon } from "@iconify/react"; const AnimeRecommendationCard = ({ data }: { data: RecommendationAnime }) => { diff --git a/features/home/sections/Recommendation/main.client.tsx b/features/home/sections/Recommendation/main.client.tsx index 3fae04f..d4871d3 100644 --- a/features/home/sections/Recommendation/main.client.tsx +++ b/features/home/sections/Recommendation/main.client.tsx @@ -1,7 +1,7 @@ "use client"; import { useRef } from "react"; -import { RecommendationAnime } from "../../actions/getRecommenationAnime"; +import { RecommendationAnime } from "../../actions/Hero/getRecommenationAnime"; import AnimeRecommendationCard from "./components/Card"; import ScrollingButton from "./components/ScrollingButton"; diff --git a/features/home/sections/Recommendation/main.tsx b/features/home/sections/Recommendation/main.tsx index e4d3229..83d7850 100644 --- a/features/home/sections/Recommendation/main.tsx +++ b/features/home/sections/Recommendation/main.tsx @@ -1,4 +1,4 @@ -import { getRecommendationAnimeAction } from "../../actions/getRecommenationAnime"; +import { getRecommendationAnimeAction } from "../../actions/Hero/getRecommenationAnime"; import RecommendationClient from "./main.client"; const RecommendationMain = async () => {