page.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { fetchJson } from '@/lib/utils/server';
  2. import type { BannerActiveListResponse, BannerItem } from '@/types/response/banner/active-list';
  3. import type { LiveChannelListResponse } from '@/types/response/channel/live-list';
  4. import HomeBannerCarousel from './_components/HomeBannerCarousel';
  5. import LiveChannelGrid from './_components/LiveChannelGrid';
  6. import LiveChannelEmpty from './_components/LiveChannelEmpty';
  7. import './_components/home.scss';
  8. const BANNER_POSITION_CODE = 'main-top';
  9. const LIVE_PAGE_SIZE = 24;
  10. async function loadActiveBanners(): Promise<BannerItem[]> {
  11. const res = await fetchJson<BannerActiveListResponse>('/api/banner/items', {
  12. method: 'POST',
  13. body: JSON.stringify({ code: BANNER_POSITION_CODE, onlyActive: true })
  14. });
  15. if (!res.success || !res.data) {
  16. return [];
  17. }
  18. return res.data.list.filter(b => b.desktopImage !== null || b.mobileImage !== null);
  19. }
  20. async function loadLiveChannels(): Promise<{ channels: LiveChannelListResponse['channels']; total: number }> {
  21. const res = await fetchJson<LiveChannelListResponse>(`/api/channel/live-list?limit=${LIVE_PAGE_SIZE}&offset=0`, { method: 'GET' });
  22. if (!res.success || !res.data) {
  23. return { channels: [], total: 0 };
  24. }
  25. return { channels: res.data.channels, total: res.data.total };
  26. }
  27. export default async function Home() {
  28. const [banners, live] = await Promise.all([
  29. loadActiveBanners(),
  30. loadLiveChannels()
  31. ]);
  32. return (
  33. <div className="home">
  34. <div className="home__inner">
  35. <HomeBannerCarousel items={banners} />
  36. {live.channels.length === 0 ? (
  37. <LiveChannelEmpty />
  38. ) : (
  39. <LiveChannelGrid
  40. initialChannels={live.channels}
  41. initialTotal={live.total}
  42. pageSize={LIVE_PAGE_SIZE}
  43. />
  44. )}
  45. </div>
  46. </div>
  47. );
  48. }