mirror of
https://github.com/JustAnimeCore/JustAnime.git
synced 2026-04-17 22:01:45 +00:00
home page improved
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import { SpeedInsights } from '@vercel/speed-insights/react';
|
||||
import { HomeInfoProvider } from "./context/HomeInfoContext";
|
||||
import Home from "./pages/Home/Home";
|
||||
import AnimeInfo from "./pages/animeInfo/AnimeInfo";
|
||||
@@ -71,6 +73,8 @@ function App() {
|
||||
</Routes>
|
||||
{!isSplashScreen && <Footer />}
|
||||
</main>
|
||||
<Analytics />
|
||||
<SpeedInsights />
|
||||
</div>
|
||||
</HomeInfoProvider>
|
||||
);
|
||||
|
||||
@@ -7,79 +7,132 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(18, 18, 18, 1) 0%,
|
||||
rgba(18, 18, 18, 0.7) 20%,
|
||||
rgba(18, 18, 18, 0) 60%,
|
||||
rgba(18, 18, 18, 0.2) 100%
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0.4) 50%,
|
||||
rgba(0, 0, 0, 0.95) 100%
|
||||
);
|
||||
z-index: 50;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.group:hover .overlay {
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(18, 18, 18, 0.95) 0%,
|
||||
rgba(18, 18, 18, 0.8) 50%,
|
||||
rgba(18, 18, 18, 0.6) 100%
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0.2) 0%,
|
||||
rgba(0, 0, 0, 0.6) 50%,
|
||||
rgba(0, 0, 0, 0.98) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
margin: 0 4px;
|
||||
margin: 0 6px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* Modern Card Styles */
|
||||
.category-card-container {
|
||||
transition: transform 0.3s ease-in-out;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
background: #1a1a1a;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.category-card-container:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.category-card-container img {
|
||||
border-radius: 16px;
|
||||
transform: scale(1.01);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
|
||||
.category-card-container:hover img {
|
||||
transform: scale(1.05);
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.category-badge {
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.category-badge:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.01em;
|
||||
transition: all 0.2s ease;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 15px;
|
||||
line-height: 1.4;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.item-title:hover {
|
||||
color: #ffffff;
|
||||
text-shadow: 0 0 20px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.play-icon {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(0.8);
|
||||
transition: all 0.3s ease;
|
||||
transform: translate(-50%, -50%) scale(0.9);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));
|
||||
}
|
||||
|
||||
.group:hover .play-icon {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
|
||||
.info-container {
|
||||
padding: 12px 16px 16px;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.95) 0%,
|
||||
rgba(0, 0, 0, 0.8) 50%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.group:hover .info-container {
|
||||
padding-bottom: 20px;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.98) 0%,
|
||||
rgba(0, 0, 0, 0.85) 50%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.meta-info {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -87,19 +87,20 @@ const CategoryCard = React.memo(
|
||||
};
|
||||
return (
|
||||
<div className={`w-full ${className}`}>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="font-bold text-2xl text-white max-[478px]:text-[18px] capitalize tracking-wide">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h1 className="font-semibold text-2xl text-white max-[478px]:text-[18px] capitalize tracking-wide">
|
||||
{label}
|
||||
</h1>
|
||||
{showViewMore && (
|
||||
<Link
|
||||
to={`/${path}`}
|
||||
className="flex w-fit items-baseline h-fit rounded-3xl gap-x-1 group"
|
||||
className="flex items-center gap-x-1 py-1 px-2 -mr-2 rounded-md
|
||||
text-[13px] font-medium text-[#ffffff80] hover:text-white
|
||||
transition-all duration-300 group"
|
||||
>
|
||||
<p className="text-gray-300 text-[12px] font-medium h-fit leading-0 group-hover:text-white transition-all ease-out">
|
||||
View more
|
||||
</p>
|
||||
<FaChevronRight className="text-gray-300 text-[10px] group-hover:text-white transition-all ease-out" />
|
||||
View all
|
||||
<FaChevronRight className="text-[10px] transform transition-transform duration-300
|
||||
group-hover:translate-x-0.5" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
@@ -115,12 +116,12 @@ const CategoryCard = React.memo(
|
||||
{itemsToRender.firstRow.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex flex-col transition-transform duration-300 ease-in-out category-card-container"
|
||||
className="flex flex-col category-card-container"
|
||||
style={{ height: "fit-content" }}
|
||||
ref={(el) => (cardRefs.current[index] = el)}
|
||||
>
|
||||
<div
|
||||
className="w-full relative group hover:cursor-pointer"
|
||||
className="w-full relative group hover:cursor-pointer overflow-hidden rounded-xl"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`${
|
||||
@@ -139,51 +140,72 @@ const CategoryCard = React.memo(
|
||||
className="text-[40px] text-white absolute top-1/2 left-1/2 play-icon z-[10000]"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="overlay"></div>
|
||||
<div className="overflow-hidden">
|
||||
<div className="overflow-hidden rounded-xl">
|
||||
<img
|
||||
src={`${item.poster}`}
|
||||
alt={item.title}
|
||||
className={`w-full h-[320px] object-cover max-[1200px]:h-[35vw] max-[758px]:h-[45vw] max-[478px]:h-[60vw] group-hover:blur-[7px] transform transition-all duration-300 ease-in-out ultra-wide:h-[400px] ${cardStyle}`}
|
||||
className={`w-full h-[320px] object-cover max-[1200px]:h-[35vw] max-[758px]:h-[45vw] max-[478px]:h-[60vw] transform transition-all duration-300 ease-in-out ultra-wide:h-[400px] ${cardStyle}`}
|
||||
/>
|
||||
</div>
|
||||
{(item.tvInfo?.rating === "18+" ||
|
||||
item?.adultContent === true) && (
|
||||
<div className="text-white px-2 py-1 rounded-md bg-black/50 backdrop-blur-sm border border-white/10 absolute top-2 left-2 flex items-center justify-center text-[12px] font-medium">
|
||||
<div className="text-white px-3 py-1 rounded-lg bg-black/40 backdrop-blur-md border border-white/10 absolute top-3 left-3 flex items-center justify-center text-[12px] font-medium">
|
||||
18+
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute left-2 bottom-3 flex items-center justify-center w-fit space-x-2 z-[100] max-[270px]:flex-col max-[270px]:gap-y-[3px]">
|
||||
{item.tvInfo?.sub && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faClosedCaptioning}
|
||||
className="text-[12px] text-white/90"
|
||||
/>
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.sub}
|
||||
</p>
|
||||
<div className="info-container">
|
||||
<div className="flex items-center justify-start w-fit space-x-2 z-[100] max-[270px]:flex-col max-[270px]:gap-y-[3px]">
|
||||
{item.tvInfo?.sub && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faClosedCaptioning}
|
||||
className="text-[12px] text-white/90"
|
||||
/>
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.sub}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.dub && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faMicrophone}
|
||||
className="text-[12px] text-white/90"
|
||||
/>
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.dub}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.eps && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.eps}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
className="text-white font-medium mt-3 item-title hover:text-white hover:cursor-pointer line-clamp-1 block"
|
||||
>
|
||||
{language === "EN" ? item.title : item.japanese_title}
|
||||
</Link>
|
||||
<div className="flex items-center gap-x-2 w-full mt-2 overflow-hidden">
|
||||
<div className="text-gray-300 text-[13px] text-nowrap overflow-hidden text-ellipsis font-medium">
|
||||
{item.tvInfo.showType.split(" ").shift()}
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.dub && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faMicrophone}
|
||||
className="text-[12px] text-white/90"
|
||||
/>
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.dub}
|
||||
</p>
|
||||
<div className="dot"></div>
|
||||
<div className="text-gray-300 text-[13px] text-nowrap overflow-hidden text-ellipsis font-medium">
|
||||
{item.tvInfo?.duration === "m" ||
|
||||
item.tvInfo?.duration === "?" ||
|
||||
item.duration === "m" ||
|
||||
item.duration === "?"
|
||||
? "N/A"
|
||||
: item.tvInfo?.duration || item.duration || "N/A"}
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.eps && (
|
||||
<div className="category-badge flex space-x-1 justify-center items-center">
|
||||
<p className="text-[12px] text-white/90">
|
||||
{item.tvInfo.eps}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{hoveredItem === item.id + index &&
|
||||
window.innerWidth > 1024 && (
|
||||
@@ -198,31 +220,11 @@ const CategoryCard = React.memo(
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
className="text-gray-100 font-medium mt-2 item-title hover:text-white hover:cursor-pointer line-clamp-1"
|
||||
>
|
||||
{language === "EN" ? item.title : item.japanese_title}
|
||||
</Link>
|
||||
{item.description && (
|
||||
<div className="line-clamp-3 text-[13px] font-light text-gray-400 mt-1 max-[1200px]:hidden">
|
||||
<div className="line-clamp-3 text-[13px] font-light text-gray-400 mt-3 max-[1200px]:hidden">
|
||||
{item.description}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center gap-x-2 w-full mt-2 overflow-hidden">
|
||||
<div className="text-gray-500 text-[13px] text-nowrap overflow-hidden text-ellipsis font-medium">
|
||||
{item.tvInfo.showType.split(" ").shift()}
|
||||
</div>
|
||||
<div className="dot"></div>
|
||||
<div className="text-gray-500 text-[13px] text-nowrap overflow-hidden text-ellipsis font-medium">
|
||||
{item.tvInfo?.duration === "m" ||
|
||||
item.tvInfo?.duration === "?" ||
|
||||
item.duration === "m" ||
|
||||
item.duration === "?"
|
||||
? "N/A"
|
||||
: item.tvInfo?.duration || item.duration || "N/A"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -46,10 +46,10 @@ const ContinueWatching = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex gap-x-2 pr-2 max-[350px]:hidden">
|
||||
<button className="btn-prev bg-gray-700 text-white p-3 rounded-full hover:bg-gray-500 transition max-[768px]:p-2">
|
||||
<button className="continue-btn-prev bg-gray-700 text-white p-3 rounded-full hover:bg-gray-500 transition max-[768px]:p-2">
|
||||
<FaChevronLeft className="text-xs" />
|
||||
</button>
|
||||
<button className="btn-next bg-gray-700 text-white p-3 rounded-full hover:bg-gray-500 transition max-[768px]:p-2">
|
||||
<button className="continue-btn-next bg-gray-700 text-white p-3 rounded-full hover:bg-gray-500 transition max-[768px]:p-2">
|
||||
<FaChevronRight className="text-xs" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -70,11 +70,11 @@ const ContinueWatching = () => {
|
||||
}}
|
||||
modules={[Navigation]}
|
||||
navigation={{
|
||||
nextEl: ".btn-next",
|
||||
prevEl: ".btn-prev",
|
||||
nextEl: ".continue-btn-next",
|
||||
prevEl: ".continue-btn-prev",
|
||||
}}
|
||||
>
|
||||
{memoizedWatchList.map((item, index) => (
|
||||
{memoizedWatchList.slice().reverse().map((item, index) => (
|
||||
<SwiperSlide
|
||||
key={index}
|
||||
className="text-center flex justify-center items-center"
|
||||
|
||||
@@ -114,28 +114,28 @@ const Schedule = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full mt-[60px] max-[480px]:mt-[40px]">
|
||||
<div className="w-full mt-8 max-[480px]:mt-6">
|
||||
<div className="flex items-center justify-between max-[570px]:flex-col max-[570px]:items-start max-[570px]:gap-y-2">
|
||||
<div className="font-bold text-2xl text-[#ffbade] max-[478px]:text-[18px]">
|
||||
<div className="font-bold text-2xl text-white max-[478px]:text-[18px]">
|
||||
Estimated Schedule
|
||||
</div>
|
||||
<p className="leading-[28px] px-[10px] bg-white text-black rounded-full my-[6px] text-[16px] font-bold max-[478px]:text-[12px] max-[275px]:text-[10px]">
|
||||
<p className="leading-[28px] px-3 bg-zinc-800 text-white rounded-md text-[14px] font-medium max-[478px]:text-[12px] max-[275px]:text-[10px]">
|
||||
({GMTOffset}) {currentTime.toLocaleDateString()}{" "}
|
||||
{currentTime.toLocaleTimeString()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full overflow-x-scroll space-x-4 scrollbar-hide pt-10 px-6 max-[480px]:px-4 max-[478px]:pt-4">
|
||||
<div className="w-full overflow-x-scroll space-x-4 scrollbar-hide pt-6 px-4 max-[480px]:px-2 max-[478px]:pt-4">
|
||||
<div className="relative w-full">
|
||||
<Swiper
|
||||
slidesPerView={3}
|
||||
spaceBetween={2}
|
||||
breakpoints={{
|
||||
250: { slidesPerView: 3, spaceBetween: 10 },
|
||||
640: { slidesPerView: 4, spaceBetween: 10 },
|
||||
768: { slidesPerView: 5, spaceBetween: 10 },
|
||||
1024: { slidesPerView: 7, spaceBetween: 10 },
|
||||
1300: { slidesPerView: 7, spaceBetween: 15 },
|
||||
250: { slidesPerView: 3, spaceBetween: 8 },
|
||||
640: { slidesPerView: 4, spaceBetween: 8 },
|
||||
768: { slidesPerView: 5, spaceBetween: 8 },
|
||||
1024: { slidesPerView: 7, spaceBetween: 8 },
|
||||
1300: { slidesPerView: 7, spaceBetween: 8 },
|
||||
}}
|
||||
modules={[Pagination, Navigation]}
|
||||
navigation={{
|
||||
@@ -150,20 +150,20 @@ const Schedule = () => {
|
||||
<div
|
||||
ref={(el) => (cardRefs.current[index] = el)}
|
||||
onClick={() => toggleActive(index)}
|
||||
className={`h-[70px] flex flex-col justify-center items-center w-full text-center rounded-xl shadow-lg cursor-pointer ${
|
||||
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-[#ffbade] text-black"
|
||||
: "bg-white bg-opacity-5 text-[#ffffff] hover:bg-[#373646] transition-all duration-300 ease-in-out"
|
||||
? "bg-white text-black"
|
||||
: "bg-zinc-800 text-white hover:bg-zinc-700"
|
||||
}`}
|
||||
>
|
||||
<div className="text-[18px] font-bold max-[400px]:text-[14px] max-[350px]:text-[12px]">
|
||||
<div className="text-[16px] font-bold max-[400px]:text-[14px] max-[350px]:text-[12px]">
|
||||
{date.dayname}
|
||||
</div>
|
||||
<div
|
||||
className={`text-[14px] max-[400px]:text-[12px] ${
|
||||
className={`text-[13px] max-[400px]:text-[11px] ${
|
||||
currentActiveIndex === index
|
||||
? "text-black"
|
||||
: "text-gray-400"
|
||||
? "text-zinc-800"
|
||||
: "text-zinc-400"
|
||||
} max-[350px]:text-[10px]`}
|
||||
>
|
||||
{date.monthName} {date.day}
|
||||
@@ -172,28 +172,28 @@ const Schedule = () => {
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
<button className="next absolute top-1/2 right-[-15px] transform -translate-y-1/2 flex justify-center items-center cursor-pointer">
|
||||
<button className="next absolute top-1/2 right-[-12px] transform -translate-y-1/2 flex justify-center items-center cursor-pointer">
|
||||
<FaChevronRight className="text-[12px]" />
|
||||
</button>
|
||||
<button className="prev absolute top-1/2 left-[-15px] transform -translate-y-1/2 flex justify-center items-center cursor-pointer">
|
||||
<button className="prev absolute top-1/2 left-[-12px] transform -translate-y-1/2 flex justify-center items-center cursor-pointer">
|
||||
<FaChevronLeft className="text-[12px]" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{loading ? (
|
||||
<div className="w-full h-[70px] flex justify-center items-center">
|
||||
<div className="w-full h-[60px] flex justify-center items-center">
|
||||
<BouncingLoader />
|
||||
</div>
|
||||
) : !scheduleData || scheduleData.length === 0 ? (
|
||||
<div className="w-full h-[70px] flex justify-center items-center mt-5 text-xl">
|
||||
<div className="w-full h-[60px] flex justify-center items-center mt-4 text-lg text-zinc-400">
|
||||
No data to display
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="w-full h-[70px] flex justify-center items-center mt-5 text-xl">
|
||||
<div className="w-full h-[60px] flex justify-center items-center mt-4 text-lg text-zinc-400">
|
||||
Something went wrong
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col mt-5 items-start">
|
||||
<div className="flex flex-col mt-4 items-start">
|
||||
{(showAll
|
||||
? scheduleData
|
||||
: Array.isArray(scheduleData)
|
||||
@@ -203,31 +203,31 @@ const Schedule = () => {
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
key={idx}
|
||||
className="w-full flex justify-between py-4 border-[#FFFFFF0D] border-b-[1px] group cursor-pointer max-[325px]:py-2"
|
||||
className="w-full flex justify-between py-3 border-zinc-800 border-b-[1px] group cursor-pointer hover:bg-zinc-900/50 px-2 transition-all duration-200 max-[325px]:py-2"
|
||||
>
|
||||
<div className="flex items-center max-w-[500px] gap-x-7 max-[400px]:gap-x-2">
|
||||
<div className="text-lg font-semibold text-[#ffffff59] group-hover:text-[#ffbade] transition-all duration-300 ease-in-out max-[600px]:text-[14px] max-[275px]:text-[12px]">
|
||||
<div className="flex items-center max-w-[500px] gap-x-4 max-[400px]:gap-x-2">
|
||||
<div className="text-base font-medium text-zinc-500 group-hover:text-white transition-all duration-200 max-[600px]:text-[14px] max-[275px]:text-[12px]">
|
||||
{item.time || "N/A"}
|
||||
</div>
|
||||
<h3 className="text-[17px] font-semibold line-clamp-1 group-hover:text-[#ffbade] transition-all duration-300 ease-in-out max-[600px]:text-[14px] max-[275px]:text-[12px]">
|
||||
<h3 className="text-[16px] font-medium line-clamp-1 group-hover:text-white transition-all duration-200 max-[600px]:text-[14px] max-[275px]:text-[12px]">
|
||||
{item.title || "N/A"}
|
||||
</h3>
|
||||
</div>
|
||||
<button className="max-w-[150px] flex items-center py-1 px-4 rounded-lg gap-x-2 group-hover:bg-[#ffbade] transition-all duration-300 ease-in-out">
|
||||
<div className="flex items-center gap-x-2 py-1 px-3 rounded-md bg-zinc-800 group-hover:bg-white transition-all duration-200">
|
||||
<FontAwesomeIcon
|
||||
icon={faPlay}
|
||||
className="mt-[1px] text-[10px] max-[320px]:text-[8px] group-hover:text-black transition-all duration-300 ease-in-out"
|
||||
className="mt-[1px] text-[10px] max-[320px]:text-[8px] text-zinc-400 group-hover:text-black"
|
||||
/>
|
||||
<p className="text-[14px] text-white group-hover:text-black transition-all duration-300 ease-in-out max-[275px]:text-[12px]">
|
||||
Episode {item.episode_no || "N/A"}
|
||||
<p className="text-[13px] text-zinc-400 group-hover:text-black max-[275px]:text-[12px]">
|
||||
EP {item.episode_no || "N/A"}
|
||||
</p>
|
||||
</button>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
{scheduleData.length > 7 && (
|
||||
<button
|
||||
onClick={toggleShowAll}
|
||||
className="text-white py-4 hover:text-[#ffbade] font-semibold transition-all duration-300 ease-in-out max-sm:text-[13px]"
|
||||
className="text-zinc-400 py-3 hover:text-white font-medium transition-all duration-200 max-sm:text-[13px]"
|
||||
>
|
||||
{showAll ? "Show Less" : "Show More"}
|
||||
</button>
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
.next,
|
||||
.prev {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 100%;
|
||||
background-color: white;
|
||||
color: black;
|
||||
font-size: 13px;
|
||||
padding: 10px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 6px;
|
||||
background-color: rgb(39 39 42);
|
||||
color: rgb(161 161 170);
|
||||
font-size: 12px;
|
||||
padding: 6px;
|
||||
z-index: 10;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.next:hover,
|
||||
.prev:hover {
|
||||
background-color: rgb(63 63 70);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import "./Sidebar.css";
|
||||
|
||||
const MENU_ITEMS = [
|
||||
{ name: "Home", path: "/home", icon: faHome },
|
||||
{ name: "Recently Added", path: "/recently-added", icon: faCirclePlay },
|
||||
{ name: "Top Upcoming", path: "/top-upcoming", icon: faFilePen },
|
||||
{ name: "Subbed Anime", path: "/subbed-anime", icon: faFilePen },
|
||||
{ name: "Dubbed Anime", path: "/dubbed-anime", icon: faPlay },
|
||||
{ name: "Most Popular", path: "/most-popular", icon: faFire },
|
||||
|
||||
72
src/components/tabbed-anime/TabbedAnimeSection.jsx
Normal file
72
src/components/tabbed-anime/TabbedAnimeSection.jsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import CategoryCard from "@/src/components/categorycard/CategoryCard.jsx";
|
||||
import { Link } from "react-router-dom";
|
||||
import { FaChevronRight } from "react-icons/fa";
|
||||
|
||||
function TabbedAnimeSection({ topAiring, mostFavorite, latestCompleted, className = "" }) {
|
||||
const [activeTab, setActiveTab] = useState("airing");
|
||||
|
||||
const tabs = [
|
||||
{ id: "airing", label: "Top Airing", data: topAiring, path: "top-airing" },
|
||||
{ id: "favorite", label: "Most Favorite", data: mostFavorite, path: "most-favorite" },
|
||||
{ id: "completed", label: "Latest Completed", data: latestCompleted, path: "completed" },
|
||||
];
|
||||
|
||||
const activeTabData = tabs.find((tab) => tab.id === activeTab);
|
||||
|
||||
return (
|
||||
<div className={`w-full ${className}`}>
|
||||
<div className="flex justify-between items-center border-b border-[#ffffff1a] relative">
|
||||
<div className="flex">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={`relative px-6 py-4 text-[15px] font-medium transition-all duration-300
|
||||
${activeTab === tab.id
|
||||
? "text-white after:absolute after:bottom-0 after:left-0 after:w-full after:h-[2px] after:bg-primary after:rounded-t-full"
|
||||
: "text-[#ffffff80] hover:text-white"
|
||||
}
|
||||
before:absolute before:bottom-0 before:left-1/2 before:w-0 before:h-[2px] before:bg-[#ffffff40]
|
||||
before:transition-all before:duration-300 before:-translate-x-1/2
|
||||
hover:before:w-full
|
||||
group
|
||||
`}
|
||||
>
|
||||
<span className="relative z-10 transition-transform duration-300 group-hover:transform group-hover:translate-y-[-1px]">
|
||||
{tab.label}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Link
|
||||
to={`/${activeTabData.path}`}
|
||||
className="flex items-center gap-x-1 py-1 px-2 -mr-2 rounded-md
|
||||
text-[13px] font-medium text-[#ffffff80] hover:text-white
|
||||
transition-all duration-300 group"
|
||||
>
|
||||
View all
|
||||
<FaChevronRight className="text-[10px] transform transition-transform duration-300
|
||||
group-hover:translate-x-0.5" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<CategoryCard
|
||||
data={activeTabData.data}
|
||||
path={activeTabData.path}
|
||||
limit={12}
|
||||
showViewMore={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
TabbedAnimeSection.propTypes = {
|
||||
topAiring: PropTypes.array.isRequired,
|
||||
mostFavorite: PropTypes.array.isRequired,
|
||||
latestCompleted: PropTypes.array.isRequired,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default TabbedAnimeSection;
|
||||
@@ -49,19 +49,17 @@ function Topten({ data, className }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col space-y-6 ${className}`}>
|
||||
<div className={`flex flex-col space-y-4 ${className}`}>
|
||||
<div className="flex justify-between items-center max-[350px]:flex-col max-[350px]:gap-y-2 max-[350px]:items-start">
|
||||
<h1 className="font-bold text-2xl text-[#ffbade]">Top 10</h1>
|
||||
<ul className="flex justify-between w-fit bg-[#373646] rounded-[4px] text-sm font-bold">
|
||||
<h1 className="font-bold text-2xl text-white tracking-tight">Top 10</h1>
|
||||
<ul className="flex justify-between w-fit bg-[#1a1a1a] rounded-lg overflow-hidden shadow-lg">
|
||||
{["today", "week", "month"].map((period) => (
|
||||
<li
|
||||
key={period}
|
||||
className={`cursor-pointer p-2 px-3 ${
|
||||
className={`cursor-pointer p-1.5 px-4 transition-all duration-200 ${
|
||||
activePeriod === period
|
||||
? "bg-[#ffbade] text-[#555462]"
|
||||
: "text-white hover:text-[#ffbade]"
|
||||
} ${period === "today" ? "rounded-l-[4px]" : ""} ${
|
||||
period === "month" ? "rounded-r-[4px]" : ""
|
||||
? "bg-white text-black font-medium"
|
||||
: "text-gray-400 hover:text-white hover:bg-[#2a2a2a]"
|
||||
}`}
|
||||
onClick={() => handlePeriodChange(period)}
|
||||
>
|
||||
@@ -71,19 +69,19 @@ function Topten({ data, className }) {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col space-y-4 bg-[#2B2A3C] p-4 pt-8">
|
||||
<div className="flex flex-col space-y-3 bg-[#1a1a1a] p-3 pt-6 rounded-lg shadow-lg">
|
||||
{currentData &&
|
||||
currentData.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center gap-x-4"
|
||||
className="flex items-center gap-x-3 group"
|
||||
ref={(el) => (cardRefs.current[index] = el)}
|
||||
>
|
||||
<h1
|
||||
className={`font-bold text-2xl ${
|
||||
className={`font-bold text-2xl transition-colors ${
|
||||
index < 3
|
||||
? "pb-1 text-white border-b-[3px] border-[#ffbade]"
|
||||
: "text-[#777682]"
|
||||
? "text-white border-b-2 border-white pb-0.5"
|
||||
: "text-gray-600"
|
||||
} max-[350px]:hidden`}
|
||||
>
|
||||
{`${index + 1 < 10 ? "0" : ""}${index + 1}`}
|
||||
@@ -92,16 +90,15 @@ function Topten({ data, className }) {
|
||||
style={{
|
||||
borderBottom:
|
||||
index + 1 < 10
|
||||
? "1px solid rgba(255, 255, 255, .075)"
|
||||
? "1px solid rgba(255, 255, 255, .1)"
|
||||
: "none",
|
||||
}}
|
||||
className="flex pb-4 relative container items-center"
|
||||
className="flex pb-3 relative container items-center group-hover:bg-[#2a2a2a] transition-colors duration-200 rounded-lg p-1.5"
|
||||
>
|
||||
{/* Image with tooltip behavior */}
|
||||
<img
|
||||
src={`${item.poster}`}
|
||||
alt={item.title}
|
||||
className="w-[60px] h-[75px] rounded-md object-cover flex-shrink-0 cursor-pointer"
|
||||
className="w-[55px] h-[70px] rounded-lg object-cover flex-shrink-0 cursor-pointer shadow-md transition-transform duration-200 group-hover:scale-[1.02]"
|
||||
onClick={() => navigate(`/watch/${item.id}`)}
|
||||
onMouseEnter={() => handleMouseEnter(item, index)}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
@@ -132,33 +129,33 @@ function Topten({ data, className }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col ml-4 space-y-2">
|
||||
<div className="flex flex-col ml-3 space-y-1.5">
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
className="text-[1em] font-[500] hover:cursor-pointer hover:text-[#ffbade] transform transition-all ease-out line-clamp-1 max-[478px]:line-clamp-2 max-[478px]:text-[14px]"
|
||||
className="text-[0.95em] font-medium text-gray-200 hover:text-white transform transition-all ease-out line-clamp-1 max-[478px]:line-clamp-2 max-[478px]:text-[14px]"
|
||||
onClick={() => handleNavigate(item.id)}
|
||||
>
|
||||
{language === "EN" ? item.title : item.japanese_title}
|
||||
</Link>
|
||||
<div className="flex flex-wrap items-center w-fit space-x-1 max-[350px]:gap-y-[3px]">
|
||||
<div className="flex flex-wrap items-center w-fit space-x-2 max-[350px]:gap-y-[3px]">
|
||||
{item.tvInfo?.sub && (
|
||||
<div className="flex space-x-1 justify-center items-center bg-[#B0E3AF] rounded-[4px] px-[4px] text-black py-[2px]">
|
||||
<div className="flex space-x-1 justify-center items-center bg-white bg-opacity-10 backdrop-blur-sm rounded-md px-1.5 py-0.5 transition-colors duration-200 hover:bg-opacity-20">
|
||||
<FontAwesomeIcon
|
||||
icon={faClosedCaptioning}
|
||||
className="text-[12px]"
|
||||
className="text-[11px] text-gray-300"
|
||||
/>
|
||||
<p className="text-[12px] font-bold">
|
||||
<p className="text-[11px] font-medium text-gray-300">
|
||||
{item.tvInfo.sub}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.dub && (
|
||||
<div className="flex space-x-1 justify-center items-center bg-[#B9E7FF] rounded-[4px] px-[8px] text-black py-[2px]">
|
||||
<div className="flex space-x-1 justify-center items-center bg-white bg-opacity-10 backdrop-blur-sm rounded-md px-1.5 py-0.5 transition-colors duration-200 hover:bg-opacity-20">
|
||||
<FontAwesomeIcon
|
||||
icon={faMicrophone}
|
||||
className="text-[12px]"
|
||||
className="text-[11px] text-gray-300"
|
||||
/>
|
||||
<p className="text-[12px] font-bold">
|
||||
<p className="text-[11px] font-medium text-gray-300">
|
||||
{item.tvInfo.dub}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,74 +1,79 @@
|
||||
import { Pagination, Navigation } from "swiper/modules";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { FaChevronLeft, FaChevronRight } from "react-icons/fa";
|
||||
import { useLanguage } from "@/src/context/LanguageContext";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link } from "react-router-dom";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faClosedCaptioning,
|
||||
faMicrophone,
|
||||
faFire
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
const Trending = ({ trending }) => {
|
||||
const Trending = ({ trending, className }) => {
|
||||
const { language } = useLanguage();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="mt-6 max-[1200px]:px-4 max-md:px-0">
|
||||
<h1 className="text-[#ffbade] text-2xl font-bold max-md:pl-4">
|
||||
Trending
|
||||
</h1>
|
||||
<div className="pr-[60px] relative mx-auto overflow-hidden z-[1] mt-6 max-[759px]:pr-0">
|
||||
<Swiper
|
||||
className="w-full h-full"
|
||||
slidesPerView={3}
|
||||
spaceBetween={2}
|
||||
breakpoints={{
|
||||
479: { spaceBetween: 15 },
|
||||
575: { spaceBetween: 15 },
|
||||
640: { slidesPerView: 3, spaceBetween: 15 },
|
||||
900: { slidesPerView: 4, spaceBetween: 15 },
|
||||
1300: { slidesPerView: 6, spaceBetween: 15 },
|
||||
}}
|
||||
modules={[Pagination, Navigation]}
|
||||
navigation={{
|
||||
nextEl: ".btn-next",
|
||||
prevEl: ".btn-prev",
|
||||
}}
|
||||
>
|
||||
{trending &&
|
||||
trending.map((item, idx) => (
|
||||
<SwiperSlide
|
||||
key={idx}
|
||||
className="text-center flex text-[18px] justify-center items-center"
|
||||
onClick={() => navigate(`/watch/${item.id}`)}
|
||||
<div className={`bg-[#141414] rounded-lg p-6 ${className}`}>
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<FontAwesomeIcon icon={faFire} className="text-white/90" />
|
||||
<h2 className="text-xl font-semibold text-white">Trending Now</h2>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-2 max-h-[600px] overflow-y-auto pr-2 scrollbar-thin scrollbar-track-[#1a1a1a] scrollbar-thumb-[#2a2a2a] hover:scrollbar-thumb-[#333] scrollbar-thumb-rounded">
|
||||
{trending &&
|
||||
trending.map((item, index) => (
|
||||
<div key={index} className="group">
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
|
||||
className="block"
|
||||
>
|
||||
<div className="w-full h-auto pb-[115%] relative inline-block overflow-hidden max-[575px]:pb-[150%]">
|
||||
<div className="absolute left-0 top-0 bottom-0 overflow-hidden w-[40px] text-center font-semibold bg-[#201F31] max-[575px]:top-0 max-[575px]:h-[30px] max-[575px]:z-[9] max-[575px]:bg-white">
|
||||
<span className="absolute left-0 right-0 bottom-0 text-[24px] leading-[1.1em] text-center z-[9] transform -rotate-90 max-[575px]:transform max-[575px]:rotate-0 max-[575px]:text-[#111] max-[575px]:text-[18px] max-[575px]:leading-[30px]">
|
||||
{item.number}
|
||||
</span>
|
||||
<div className="w-[150px] h-fit text-left transform -rotate-90 absolute bottom-[100px] left-[-55px] leading-[40px] text-ellipsis whitespace-nowrap overflow-hidden text-white text-[16px] font-medium">
|
||||
{language === "EN" ? item.title : item.japanese_title}
|
||||
<div className="flex items-start gap-3 p-2 rounded-lg transition-colors hover:bg-[#1a1a1a]">
|
||||
<div className="relative">
|
||||
<img
|
||||
src={item.poster}
|
||||
alt={item.title}
|
||||
className="w-[50px] h-[70px] rounded object-cover"
|
||||
/>
|
||||
<div className="absolute top-0 left-0 bg-white/90 text-black text-xs font-bold px-1.5 rounded-br">
|
||||
#{index + 1}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5 flex-1 min-w-0">
|
||||
<span className="text-sm font-medium text-gray-200 group-hover:text-white transition-colors line-clamp-2">
|
||||
{language === "EN" ? item.title : item.japanese_title}
|
||||
</span>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
{item.tvInfo?.sub && (
|
||||
<div className="flex items-center gap-1 px-1.5 py-0.5 bg-[#2a2a2a] rounded text-gray-300">
|
||||
<FontAwesomeIcon
|
||||
icon={faClosedCaptioning}
|
||||
className="text-[10px]"
|
||||
/>
|
||||
<span className="text-[10px] font-medium">
|
||||
{item.tvInfo.sub}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.dub && (
|
||||
<div className="flex items-center gap-1 px-1.5 py-0.5 bg-[#2a2a2a] rounded text-gray-300">
|
||||
<FontAwesomeIcon
|
||||
icon={faMicrophone}
|
||||
className="text-[10px]"
|
||||
/>
|
||||
<span className="text-[10px] font-medium">
|
||||
{item.tvInfo.dub}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{item.tvInfo?.showType && (
|
||||
<span className="text-xs text-gray-400">
|
||||
{item.tvInfo.showType}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Link
|
||||
to={`/${item.id}`}
|
||||
className="inline-block bg-[#2a2c31] absolute w-auto left-[40px] right-0 top-0 bottom-0 max-[575px]:left-0 max-[575px]:top-0 max-[575px]:bottom-0"
|
||||
>
|
||||
<img
|
||||
src={`${item.poster}`}
|
||||
alt={item.title}
|
||||
className="block w-full h-full object-cover hover:cursor-pointer"
|
||||
title={item.title}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
<div className="absolute top-0 right-0 bottom-0 w-[45px] flex flex-col space-y-2 max-[759px]:hidden">
|
||||
<div className="btn-next bg-[#383747] h-[50%] flex justify-center items-center rounded-[8px] cursor-pointer transition-all duration-300 ease-out hover:bg-[#ffbade] hover:text-[#383747]">
|
||||
<FaChevronRight />
|
||||
</div>
|
||||
<div className="btn-prev bg-[#383747] h-[50%] flex justify-center items-center rounded-[8px] cursor-pointer transition-all duration-300 ease-out hover:bg-[#ffbade] hover:text-[#383747]">
|
||||
<FaChevronLeft />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import website_name from "@/src/config/website.js";
|
||||
import Spotlight from "@/src/components/spotlight/Spotlight.jsx";
|
||||
import Trending from "@/src/components/trending/Trending.jsx";
|
||||
import Cart from "@/src/components/cart/Cart.jsx";
|
||||
import CategoryCard from "@/src/components/categorycard/CategoryCard.jsx";
|
||||
import Genre from "@/src/components/genres/Genre.jsx";
|
||||
import Topten from "@/src/components/topten/Topten.jsx";
|
||||
@@ -10,6 +9,7 @@ import Error from "@/src/components/error/Error.jsx";
|
||||
import { useHomeInfo } from "@/src/context/HomeInfoContext.jsx";
|
||||
import Schedule from "@/src/components/schedule/Schedule";
|
||||
import ContinueWatching from "@/src/components/continue/ContinueWatching";
|
||||
import TabbedAnimeSection from "@/src/components/tabbed-anime/TabbedAnimeSection";
|
||||
|
||||
function Home() {
|
||||
const { homeInfo, homeInfoLoading, error } = useHomeInfo();
|
||||
@@ -24,56 +24,27 @@ function Home() {
|
||||
<Genre data={homeInfo.genres} />
|
||||
</div>
|
||||
<ContinueWatching />
|
||||
<Trending trending={homeInfo.trending} />
|
||||
<div className="mt-10 flex gap-6 max-[1200px]:px-4 max-[1200px]:grid max-[1200px]:grid-cols-2 max-[1200px]:mt-12 max-[1200px]:gap-y-10 max-[680px]:grid-cols-1">
|
||||
<Cart
|
||||
label="Top Airing"
|
||||
data={homeInfo.top_airing}
|
||||
path="top-airing"
|
||||
/>
|
||||
<Cart
|
||||
label="Most Popular"
|
||||
data={homeInfo.most_popular}
|
||||
path="most-popular"
|
||||
/>
|
||||
<Cart
|
||||
label="Most Favorite"
|
||||
data={homeInfo.most_favorite}
|
||||
path="most-favorite"
|
||||
/>
|
||||
<Cart
|
||||
label="Latest Completed"
|
||||
data={homeInfo.latest_completed}
|
||||
path="completed"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full grid grid-cols-[minmax(0,75%),minmax(0,25%)] gap-x-6 max-[1200px]:flex flex-col max-[1200px]:px-4">
|
||||
<div>
|
||||
<CategoryCard
|
||||
label="Latest Episode"
|
||||
data={homeInfo.latest_episode}
|
||||
className={"mt-[60px]"}
|
||||
className="mt-[60px]"
|
||||
path="recently-updated"
|
||||
limit={12}
|
||||
/>
|
||||
<CategoryCard
|
||||
label={`New On ${website_name}`}
|
||||
data={homeInfo.recently_added}
|
||||
className={"mt-[60px]"}
|
||||
path="recently-added"
|
||||
limit={12}
|
||||
/>
|
||||
<Schedule />
|
||||
<CategoryCard
|
||||
label="Top Upcoming"
|
||||
data={homeInfo.top_upcoming}
|
||||
className={"mt-[30px]"}
|
||||
path="top-upcoming"
|
||||
limit={12}
|
||||
<Schedule className="mt-8" />
|
||||
<TabbedAnimeSection
|
||||
topAiring={homeInfo.top_airing}
|
||||
mostFavorite={homeInfo.most_favorite}
|
||||
latestCompleted={homeInfo.latest_completed}
|
||||
className="mt-8"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full mt-[60px]">
|
||||
<Topten data={homeInfo.topten} className={"mt-12"} />
|
||||
<Trending trending={homeInfo.trending} />
|
||||
<Topten data={homeInfo.topten} className="mt-12" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,17 +51,6 @@ function Category({ path, label }) {
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-y-4 mt-[64px] max-md:mt-[50px]">
|
||||
<div className="w-full flex gap-x-4 items-center bg-[#191826] p-5 max-[575px]:px-3 max-[320px]:hidden">
|
||||
<img
|
||||
src="https://media.tenor.com/hJfxLKzDUFcAAAAM/bleach-best-anime.gif"
|
||||
alt="Share Anime"
|
||||
className="w-[60px] h-auto rounded-full max-[1024px]:w-[40px] max-[575px]:hidden"
|
||||
/>
|
||||
<div className="flex flex-col w-fit">
|
||||
<p className="text-[15px] font-bold text-[#FFBADE]">Share Anime</p>
|
||||
<p className="text-[16px] text-white">to your friends</p>
|
||||
</div>
|
||||
</div>
|
||||
{categoryInfo ? (
|
||||
<div className="w-full px-4 grid grid-cols-[minmax(0,75%),minmax(0,25%)] gap-x-6 max-[1200px]:flex max-[1200px]:flex-col max-[1200px]:gap-y-10">
|
||||
{page > totalPages ? (
|
||||
|
||||
@@ -9,17 +9,14 @@ import IframePlayer from "@/src/components/player/IframePlayer";
|
||||
import Episodelist from "@/src/components/episodelist/Episodelist";
|
||||
import website_name from "@/src/config/website";
|
||||
import Sidecard from "@/src/components/sidecard/Sidecard";
|
||||
import CategoryCard from "@/src/components/categorycard/CategoryCard";
|
||||
import {
|
||||
faClosedCaptioning,
|
||||
faMicrophone,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import Servers from "@/src/components/servers/Servers";
|
||||
import CategoryCardLoader from "@/src/components/Loader/CategoryCard.loader";
|
||||
import { Skeleton } from "@/src/components/ui/Skeleton/Skeleton";
|
||||
import SidecardLoader from "@/src/components/Loader/Sidecard.loader";
|
||||
import Voiceactor from "@/src/components/voiceactor/Voiceactor";
|
||||
import Watchcontrols from "@/src/components/watchcontrols/Watchcontrols";
|
||||
import useWatchControl from "@/src/hooks/useWatchControl";
|
||||
import Player from "@/src/components/player/Player";
|
||||
|
||||
Reference in New Issue
Block a user