diff --git a/src/components/categorycard/CategoryCard.jsx b/src/components/categorycard/CategoryCard.jsx index 4781191..24f87da 100644 --- a/src/components/categorycard/CategoryCard.jsx +++ b/src/components/categorycard/CategoryCard.jsx @@ -11,6 +11,98 @@ import { Link, useNavigate } from "react-router-dom"; import getSafeTitle from "@/src/utils/getSafetitle"; import "./CategoryCard.css"; +const AnimeCard = ({ item, navigate, path, language, isFirstRow = false }) => { + return ( +
+
+
+ navigate( + `${path === "top-upcoming" + ? `/${item.id}` + : `/watch/${item.id}` + }` + ) + } + > + {getSafeTitle(item.title, +
+
+ +
+
+
+ {(item.tvInfo?.rating === "18+" || item?.adultContent === true) && ( +
+ 18+ +
+ )} +
+
+ {item.tvInfo?.sub && ( +
+ +

{item.tvInfo.sub}

+
+ )} + {item.tvInfo?.dub && ( +
+ +

{item.tvInfo.dub}

+
+ )} + {item.tvInfo?.showType && ( +
+ {item.tvInfo.showType.split(" ").shift()} +
+ )} + {item.releaseDate && ( +
+ {item.releaseDate} +
+ )} + {!item.tvInfo?.showType && item.type && ( +
+ {item.type} +
+ )} + {(item.tvInfo?.duration || item.duration) && ( +
+ {item.tvInfo?.duration === "m" || item.tvInfo?.duration === "?" || item.duration === "m" || item.duration === "?" + ? "N/A" + : item.tvInfo?.duration || item.duration || "N/A"} +
+ )} +
+
+
+ + {getSafeTitle(item.title, language, item.japanese_title)} + + {isFirstRow && item.description && ( +
+ {item.description} +
+ )} +
+ ); +}; + const CategoryCard = React.memo( ({ label, @@ -25,49 +117,29 @@ const CategoryCard = React.memo( const { language } = useLanguage(); const navigate = useNavigate(); - if (limit) { - data = data.slice(0, limit); - } + const displayData = limit ? data.slice(0, limit) : data; - const [itemsToRender, setItemsToRender] = useState({ - firstRow: [], - remainingItems: [], - }); - - const getItemsToRender = useCallback(() => { - if (categoryPage) { - const firstRow = - window.innerWidth > 758 && data.length > 4 ? data.slice(0, 4) : []; - const remainingItems = - window.innerWidth > 758 && data.length > 4 - ? data.slice(4) - : data.slice(0); - return { firstRow, remainingItems }; + const [itemsToRender, setItemsToRender] = useState(() => { + if (categoryPage && window.innerWidth > 758 && displayData.length > 4) { + return { firstRow: displayData.slice(0, 4), remainingItems: displayData.slice(4) }; } - return { firstRow: [], remainingItems: data.slice(0) }; - }, [categoryPage, data]); + return { firstRow: [], remainingItems: displayData }; + }); useEffect(() => { const handleResize = () => { - setItemsToRender(getItemsToRender()); - }; - const newItems = getItemsToRender(); - setItemsToRender((prev) => { - if ( - JSON.stringify(prev.firstRow) !== JSON.stringify(newItems.firstRow) || - JSON.stringify(prev.remainingItems) !== - JSON.stringify(newItems.remainingItems) - ) { - return newItems; + if (categoryPage && window.innerWidth > 758 && displayData.length > 4) { + setItemsToRender({ firstRow: displayData.slice(0, 4), remainingItems: displayData.slice(4) }); + } else { + setItemsToRender({ firstRow: [], remainingItems: displayData }); } - return prev; - }); + }; window.addEventListener("resize", handleResize); - return () => { - window.removeEventListener("resize", handleResize); - }; - }, [getItemsToRender]); + handleResize(); // Initial call to sync state + + return () => window.removeEventListener("resize", handleResize); + }, [categoryPage, displayData]); return (
@@ -89,216 +161,29 @@ const CategoryCard = React.memo( )}
<> - {categoryPage && ( -
0 - ? "mt-8 max-[758px]:hidden" - : "" - }`} - > + {categoryPage && itemsToRender.firstRow.length > 0 && ( +
{itemsToRender.firstRow.map((item, index) => ( -
-
-
- navigate( - `${path === "top-upcoming" - ? `/${item.id}` - : `/watch/${item.id}` - }` - ) - } - > - {getSafeTitle(item.title, -
-
- -
-
-
- {(item.tvInfo?.rating === "18+" || - item?.adultContent === true) && ( -
- 18+ -
- )} -
-
- {item.tvInfo?.sub && ( -
- -

- {item.tvInfo.sub} -

-
- )} - {item.tvInfo?.dub && ( -
- -

- {item.tvInfo.dub} -

-
- )} - {item.tvInfo?.showType && ( -
- {item.tvInfo.showType.split(" ").shift()} -
- )} - {item.releaseDate && ( -
- {item.releaseDate} -
- )} - {!item.tvInfo?.showType && item.type && ( -
- {item.type} -
- )} - {(item.tvInfo?.duration || item.duration) && ( -
- {item.tvInfo?.duration === "m" || - item.tvInfo?.duration === "?" || - item.duration === "m" || - item.duration === "?" - ? "N/A" - : item.tvInfo?.duration || item.duration || "N/A"} -
- )} -
-
-
- - {getSafeTitle(item.title, language, item.japanese_title)} - - {item.description && ( -
- {item.description} -
- )} -
+ item={item} + navigate={navigate} + path={path} + language={language} + isFirstRow={true} + /> ))}
)}
{itemsToRender.remainingItems.map((item, index) => ( -
-
-
- navigate( - `${path === "top-upcoming" - ? `/${item.id}` - : `/watch/${item.id}` - }` - ) - } - > - {getSafeTitle(item.title, -
-
- -
-
-
- {(item.tvInfo?.rating === "18+" || - item?.adultContent === true) && ( -
- 18+ -
- )} -
-
- {item.tvInfo?.sub && ( -
- -

- {item.tvInfo.sub} -

-
- )} - {item.tvInfo?.dub && ( -
- -

- {item.tvInfo.dub} -

-
- )} - {item.tvInfo?.showType && ( -
- {item.tvInfo.showType.split(" ").shift()} -
- )} - {item.releaseDate && ( -
- {item.releaseDate} -
- )} - {!item.tvInfo?.showType && item.type && ( -
- {item.type} -
- )} - {(item.tvInfo?.duration || item.duration) && ( -
- {item.tvInfo?.duration === "m" || - item.tvInfo?.duration === "?" || - item.duration === "m" || - item.duration === "?" - ? "N/A" - : item.tvInfo?.duration || item.duration || "N/A"} -
- )} -
-
-
- - {getSafeTitle(item.title, language, item.japanese_title)} - -
+ item={item} + navigate={navigate} + path={path} + language={language} + /> ))}
diff --git a/src/components/continue/ContinueWatching.jsx b/src/components/continue/ContinueWatching.jsx index 53fbe3e..1f3f457 100644 --- a/src/components/continue/ContinueWatching.jsx +++ b/src/components/continue/ContinueWatching.jsx @@ -18,22 +18,20 @@ const ContinueWatching = () => { useEffect(() => { const data = JSON.parse(localStorage.getItem("continueWatching") || "[]"); - setWatchList(data); + setWatchList(data.reverse()); }, []); - const memoizedWatchList = useMemo(() => watchList, [watchList]); - const removeFromWatchList = (episodeId) => { setWatchList((prevList) => { const updatedList = prevList.filter( (item) => item.episodeId !== episodeId ); - localStorage.setItem("continueWatching", JSON.stringify(updatedList)); + localStorage.setItem("continueWatching", JSON.stringify([...updatedList].reverse())); return updatedList; }); }; - if (memoizedWatchList.length === 0) return null; + if (watchList.length === 0) return null; return (
@@ -74,7 +72,7 @@ const ContinueWatching = () => { prevEl: ".continue-btn-prev", }} > - {memoizedWatchList.slice().reverse().map((item, index) => ( + {watchList.map((item, index) => ( { if (scrollContainerRef.current) { - const scrollAmount = direction === 'left' ? -300 : 300; scrollContainerRef.current.scrollBy({ - left: scrollAmount, + left: direction === 'left' ? -300 : 300, behavior: 'smooth' }); } }; - // Instant scroll on mount without animation useEffect(() => { if (scrollContainerRef.current) { - // Direct manipulation of scrollLeft for instant scroll scrollContainerRef.current.scrollLeft = 300; } }, []); diff --git a/src/components/schedule/Schedule.jsx b/src/components/schedule/Schedule.jsx index ad50748..8ab839f 100644 --- a/src/components/schedule/Schedule.jsx +++ b/src/components/schedule/Schedule.jsx @@ -24,39 +24,28 @@ const Schedule = () => { const month = currentDate.getMonth(); const monthName = currentDate.toLocaleString("default", { month: "short" }); const daysInMonth = new Date(year, month + 1, 0).getDate(); - const GMTOffset = `GMT ${ - new Date().getTimezoneOffset() > 0 ? "-" : "+" - }${String(Math.floor(Math.abs(new Date().getTimezoneOffset()) / 60)).padStart( - 2, - "0" - )}:${String(Math.abs(new Date().getTimezoneOffset()) % 60).padStart(2, "0")}`; - const months = []; + const GMTOffset = `GMT ${new Date().getTimezoneOffset() <= 0 ? "+" : "-"}${String(Math.floor(Math.abs(new Date().getTimezoneOffset()) / 60)).padStart(2, "0")}:${String(Math.abs(new Date().getTimezoneOffset()) % 60).padStart(2, "0")}`; useEffect(() => { + const monthsArr = []; for (let day = 1; day <= daysInMonth; day++) { const date = new Date(year, month, day); - const dayname = date.toLocaleString("default", { weekday: "short" }); - const yearr = date.getFullYear(); - const monthh = String(date.getMonth() + 1).padStart(2, "0"); - const dayy = String(date.getDate()).padStart(2, "0"); - const fulldate = `${yearr}-${monthh}-${dayy}`; - months.push({ day, monthName, dayname, fulldate }); + monthsArr.push({ + day, + monthName: date.toLocaleString("default", { month: "short" }), + dayname: date.toLocaleString("default", { weekday: "short" }), + fulldate: date.toISOString().split('T')[0] + }); } - setDates(months); - const timer = setInterval(() => { - setCurrentTime(new Date()); - }, 1000); + setDates(monthsArr); + + const timer = setInterval(() => setCurrentTime(new Date()), 1000); return () => clearInterval(timer); - }, []); + }, [year, month, daysInMonth]); useEffect(() => { - const todayIndex = dates.findIndex( - (date) => - date.fulldate === - `${currentDate.getFullYear()}-${String( - currentDate.getMonth() + 1 - ).padStart(2, "0")}-${String(currentDate.getDate()).padStart(2, "0")}` - ); + const today = new Date().toISOString().split('T')[0]; + const todayIndex = dates.findIndex((date) => date.fulldate === today); if (todayIndex !== -1) { setCurrentActiveIndex(todayIndex); @@ -150,21 +139,19 @@ const Schedule = () => {
(cardRefs.current[index] = el)} onClick={() => toggleActive(index)} - className={`h-[60px] flex flex-col justify-center items-center w-full text-center rounded-lg cursor-pointer transition-all duration-200 ${ - currentActiveIndex === index - ? "bg-white text-black" - : "bg-zinc-800 text-white hover:bg-zinc-700" - }`} + className={`h-[60px] flex flex-col justify-center items-center w-full text-center rounded-lg cursor-pointer transition-all duration-200 ${currentActiveIndex === index + ? "bg-white text-black" + : "bg-zinc-800 text-white hover:bg-zinc-700" + }`} >
{date.dayname}
{date.monthName} {date.day}
@@ -197,8 +184,8 @@ const Schedule = () => { {(showAll ? scheduleData : Array.isArray(scheduleData) - ? scheduleData.slice(0, 7) - : [] + ? scheduleData.slice(0, 7) + : [] ).map((item, idx) => ( 1400 ? 10 : 12); + const [itemLimit, setItemLimit] = useState(() => (window.innerWidth > 1400 ? 10 : 12)); useEffect(() => { - const handleResize = () => { - setItemLimit(window.innerWidth > 1400 ? 10 : 12); - }; - + const handleResize = () => setItemLimit(window.innerWidth > 1400 ? 10 : 12); window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []);