✨ feat: add scroll button and card skeleton loading
This commit is contained in:
@ -13,7 +13,7 @@ export type RecommendationAnime = {
|
|||||||
export const getRecommendationAnimeAction = async (): Promise<
|
export const getRecommendationAnimeAction = async (): Promise<
|
||||||
RecommendationAnime[]
|
RecommendationAnime[]
|
||||||
> => {
|
> => {
|
||||||
// await new Promise((resolve) => setTimeout(resolve, 2000));
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,16 +1,21 @@
|
|||||||
import { Button } from "@/shared/libs/shadcn/ui/button";
|
import { Button } from "@/shared/libs/shadcn/ui/button";
|
||||||
import { ButtonGroup } from "@/shared/libs/shadcn/ui/button-group";
|
import { ButtonGroup } from "@/shared/libs/shadcn/ui/button-group";
|
||||||
import { ArrowLeft, ArrowRight } from "lucide-react";
|
import { ArrowLeft, ArrowRight } from "lucide-react";
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
const ScrollingButton = () => {
|
const ScrollingButton = ({
|
||||||
|
scrollLeft,
|
||||||
|
scrollRight,
|
||||||
|
}: {
|
||||||
|
scrollLeft: () => void;
|
||||||
|
scrollRight: () => void;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button variant="outline">
|
<Button variant="outline" onClick={scrollLeft}>
|
||||||
<ArrowLeft />
|
<ArrowLeft />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline">
|
<Button variant="outline" onClick={scrollRight}>
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|||||||
46
features/home/sections/Recommendation/main.client.tsx
Normal file
46
features/home/sections/Recommendation/main.client.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRef } from "react";
|
||||||
|
import { RecommendationAnime } from "../../actions/getRecommenationAnime";
|
||||||
|
import AnimeRecommendationCard from "./components/Card";
|
||||||
|
import ScrollingButton from "./components/ScrollingButton";
|
||||||
|
import { Skeleton } from "@/shared/libs/shadcn/ui/skeleton";
|
||||||
|
|
||||||
|
const RecommendationClient = ({
|
||||||
|
result,
|
||||||
|
}: {
|
||||||
|
result: RecommendationAnime[];
|
||||||
|
}) => {
|
||||||
|
const scrollingContainer = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
const scrollLeft = () => {
|
||||||
|
console.log("scroll left");
|
||||||
|
if (scrollingContainer.current) {
|
||||||
|
scrollingContainer.current.scrollBy({ left: -788, behavior: "smooth" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const scrollRight = () => {
|
||||||
|
console.log("scroll right");
|
||||||
|
if (scrollingContainer.current) {
|
||||||
|
scrollingContainer.current.scrollBy({ left: 788, behavior: "smooth" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="absolute top-0 right-0">
|
||||||
|
<ScrollingButton scrollLeft={scrollLeft} scrollRight={scrollRight} />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex gap-2 w-full overflow-x-scroll py-2 mt-2 hide-scrollbar relative"
|
||||||
|
ref={scrollingContainer}
|
||||||
|
>
|
||||||
|
{result.map((item, index) => (
|
||||||
|
<AnimeRecommendationCard data={item} key={index} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RecommendationClient;
|
||||||
@ -1,16 +1,10 @@
|
|||||||
import { getRecommendationAnimeAction } from "../../actions/getRecommenationAnime";
|
import { getRecommendationAnimeAction } from "../../actions/getRecommenationAnime";
|
||||||
import AnimeRecommendationCard from "./components/Card";
|
import RecommendationClient from "./main.client";
|
||||||
|
|
||||||
const RecommendationMain = async () => {
|
const RecommendationMain = async () => {
|
||||||
const data = async () => await getRecommendationAnimeAction();
|
const data = async () => await getRecommendationAnimeAction();
|
||||||
const result = await data();
|
const result = await data();
|
||||||
return (
|
return <RecommendationClient result={result} />;
|
||||||
<div className="flex gap-2 w-full overflow-x-scroll py-2 my-2 hide-scrollbar">
|
|
||||||
{result.map((item, index) => (
|
|
||||||
<AnimeRecommendationCard data={item} key={index} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RecommendationMain;
|
export default RecommendationMain;
|
||||||
|
|||||||
@ -1,5 +1,19 @@
|
|||||||
|
import { Skeleton } from "@/shared/libs/shadcn/ui/skeleton";
|
||||||
|
|
||||||
const RecommendationSkeleton = () => {
|
const RecommendationSkeleton = () => {
|
||||||
return <div>loading...</div>;
|
const skeletonLenght = 6;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex gap-2 w-full overflow-hidden mt-4">
|
||||||
|
{[...Array(skeletonLenght)].map((_, index) => (
|
||||||
|
<div tabIndex={index}>
|
||||||
|
<Skeleton className="h-88 w-64" />
|
||||||
|
<Skeleton className="mt-3 h-6 w-64 rounded-full" />
|
||||||
|
<Skeleton className="mt-1 h-4 w-12 rounded-full" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RecommendationSkeleton;
|
export default RecommendationSkeleton;
|
||||||
|
|||||||
@ -5,14 +5,11 @@ import ScrollingButton from "./components/ScrollingButton";
|
|||||||
|
|
||||||
const Recommendation = async () => {
|
const Recommendation = async () => {
|
||||||
return (
|
return (
|
||||||
<div className="mt-12">
|
<div className="mt-12 relative">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<h1 className="text-[26px] text-neutral-100 font-semibold w-fit tracking-tight">
|
<h1 className="text-[26px] text-neutral-100 font-semibold w-fit tracking-tight">
|
||||||
Maybe You Like
|
Maybe You Like
|
||||||
</h1>
|
</h1>
|
||||||
<div>
|
|
||||||
<ScrollingButton />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Suspense fallback={<RecommendationSkeleton />}>
|
<Suspense fallback={<RecommendationSkeleton />}>
|
||||||
<RecommendationMain />
|
<RecommendationMain />
|
||||||
|
|||||||
Reference in New Issue
Block a user