import Image from "next/image"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import { CalendarIcon } from "@heroicons/react/24/solid"; import { ClockIcon } from "@heroicons/react/24/outline"; import Loading from "@/components/shared/loading"; import { timeStamptoAMPM, timeStamptoHour } from "@/utils/getTimes"; import { filterFormattedSchedule, filterScheduleByDay, sortScheduleByDay, transformSchedule, } from "@/utils/schedulesUtils"; import { scheduleQuery } from "@/lib/graphql/query"; import MobileNav from "@/components/shared/MobileNav"; import { useSession } from "next-auth/react"; import { redis } from "@/lib/redis"; import Head from "next/head"; import { NewNavbar } from "@/components/shared/NavBar"; const day = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ]; const isAired = (timestamp) => { const currentTime = new Date().getTime() / 1000; return timestamp <= currentTime; }; export async function getServerSideProps() { const now = new Date(); // Adjust for Japan timezone (add 9 hours) const nowJapan = new Date(now.getTime() + 9 * 60 * 60 * 1000); // Calculate the time until midnight of the next day in Japan timezone const midnightTomorrowJapan = new Date( nowJapan.getFullYear(), nowJapan.getMonth(), nowJapan.getDate() + 1, 0, 0, 0, 0 ); const timeUntilMidnightJapan = Math.round( (midnightTomorrowJapan - nowJapan) / 1000 ); let cachedData; // Check if the data is already in Redis if (redis) { cachedData = await redis.get("new_schedule"); } if (cachedData) { const scheduleByDay = JSON.parse(cachedData); return { props: { schedule: scheduleByDay, // today: todaySchedule, }, }; } else { now.setHours(0, 0, 0, 0); // Set the time to 00:00:00.000 const dayInSeconds = 86400; // Number of seconds in a day const yesterdayStart = Math.floor(now.getTime() / 1000) - dayInSeconds; // Calculate weekStart from yesterday's 00:00:00 const weekStart = yesterdayStart; const weekEnd = weekStart + 604800; let page = 1; const airingSchedules = []; while (true) { const res = await fetch("https://graphql.anilist.co", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify({ query: scheduleQuery, variables: { weekStart, weekEnd, page, }, }), }); const json = await res.json(); const schedules = json.data.Page.airingSchedules; if (schedules.length === 0) { break; // No more data to fetch } airingSchedules.push(...schedules); page++; } const timestampToDay = (timestamp) => { const options = { weekday: "long" }; return new Date(timestamp * 1000).toLocaleDateString(undefined, options); }; const scheduleByDay = {}; airingSchedules.forEach((schedule) => { const day = timestampToDay(schedule.airingAt); if (!scheduleByDay[day]) { scheduleByDay[day] = []; } scheduleByDay[day].push(schedule); }); if (redis) { await redis.set( "new_schedule", JSON.stringify(scheduleByDay), "EX", timeUntilMidnightJapan ); } return { props: { schedule: scheduleByDay, // today: todaySchedule, }, }; } // setSchedule(scheduleByDay); } export default function Schedule({ schedule }) { const { data: session } = useSession(); // const [schedule, setSchedule] = useState({}); const [filterDay, setFilterDay] = useState("All"); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true); async function setDay() { const now = new Date(); const today = day[now.getDay()]; setFilterDay(today); setLoading(false); } setDay(); }, []); // Sort the schedule object by day, placing today's schedule first const sortedSchedule = sortScheduleByDay(schedule); const formattedSchedule = transformSchedule(schedule); // State to keep track of the next airing anime const [nextAiringAnime, setNextAiringAnime] = useState(null); // const [nextAiringBanner, setNextAiringBanner] = useState(null); // State to keep track of the currently airing anime const [currentlyAiringAnime, setCurrentlyAiringAnime] = useState(null); const [layout, setLayout] = useState(1); // Effect to update the next and currently airing anime useEffect(() => { const now = new Date().getTime() / 1000; // Current time in seconds let nextAiring = null; let currentlyAiring = null; for (const [, schedules] of Object.entries(sortedSchedule)) { for (const s of schedules) { if (s.airingAt > now) { if (!nextAiring) { nextAiring = s.id; // setNextAiringBanner(s.media.bannerImage); } } else if (s.airingAt + 1440 > now) { currentlyAiring = s.id; } } if (nextAiring && currentlyAiring) break; } setNextAiringAnime(nextAiring); setCurrentlyAiringAnime(currentlyAiring); }, [sortedSchedule]); const scrollContainerRef = useRef(null); useEffect(() => { // Scroll to center the active button when it changes if (scrollContainerRef.current) { const activeButton = scrollContainerRef.current.querySelector(".text-action"); if (activeButton) { const containerWidth = scrollContainerRef.current.clientWidth; const buttonLeft = activeButton.offsetLeft; const buttonWidth = activeButton.clientWidth; const scrollLeft = buttonLeft - containerWidth / 2 + buttonWidth / 2; scrollContainerRef.current.scrollLeft = scrollLeft; } } }, [filterDay]); return ( <>
Airing Next
} */}Ep {s.episode} {timeStamptoHour(s.airingAt)}
*/}
{/* */} Next Airing
Airing Now
Ep {s.episode} {timeStamptoHour(s.airingAt)}