| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import { fetchJson } from '@/lib/utils/server';
- import type { BannerActiveListResponse, BannerItem } from '@/types/response/banner/active-list';
- import type { LiveChannelListResponse } from '@/types/response/channel/live-list';
- import type { WorldIndexRow } from '@/types/worldIndex';
- import type { MarketQuoteRow } from '@/types/marketQuote';
- import { fetchWorldIndices } from '@/lib/api/worldIndices';
- import { fetchMarketQuotes } from '@/lib/api/marketQuotes';
- import type { DomesticIndexRow } from '@/types/domesticSummary';
- import { fetchDomesticSummary } from '@/lib/api/domesticSummary';
- import type { MarketMoversResponse } from '@/types/marketMover';
- import { fetchMarketMovers } from '@/lib/api/marketMovers';
- import HomeBannerCarousel from './_components/HomeBannerCarousel';
- import WorldMarketMap from './_components/WorldMarketMap';
- import DomesticSummary from './_components/DomesticSummary';
- import MajorQuotesGrid from './_components/MajorQuotesGrid';
- import MarketMovers from './_components/MarketMovers';
- import LiveChannelGrid from './_components/LiveChannelGrid';
- import LiveChannelEmpty from './_components/LiveChannelEmpty';
- import { FEATURE_CHANNEL } from '@/constants/features';
- import './_components/home.scss';
- const BANNER_POSITION_CODE = 'main-top';
- const LIVE_PAGE_SIZE = 24;
- async function loadActiveBanners(): Promise<BannerItem[]> {
- const res = await fetchJson<BannerActiveListResponse>('/api/banner/items', {
- method: 'POST',
- body: JSON.stringify({ code: BANNER_POSITION_CODE, onlyActive: true })
- });
- if (!res.success || !res.data) {
- return [];
- }
- return res.data.list.filter(b => b.desktopImage !== null || b.mobileImage !== null);
- }
- async function loadLiveChannels(): Promise<{ channels: LiveChannelListResponse['channels']; total: number }> {
- const res = await fetchJson<LiveChannelListResponse>(`/api/channel/live-list?limit=${LIVE_PAGE_SIZE}&offset=0`, { method: 'GET' });
- if (!res.success || !res.data) {
- return { channels: [], total: 0 };
- }
- return { channels: res.data.channels, total: res.data.total };
- }
- async function loadWorldIndices(): Promise<WorldIndexRow[]> {
- // 백엔드 미기동/데이터 없음이어도 홈은 렌더 — 지도는 데이터 있을 때만 표시
- const res = await fetchWorldIndices();
- if (!res.success || !res.data) {
- return [];
- }
- return res.data.list;
- }
- async function loadMarketQuotes(): Promise<MarketQuoteRow[]> {
- // 백엔드 미기동/데이터 없음이어도 홈은 렌더 — 그리드는 데이터 있을 때만 표시
- const res = await fetchMarketQuotes();
- if (!res.success || !res.data) {
- return [];
- }
- return res.data.list;
- }
- async function loadDomesticSummary(): Promise<DomesticIndexRow[]> {
- const res = await fetchDomesticSummary();
- if (!res.success || !res.data) {
- return [];
- }
- return res.data.list;
- }
- async function loadMarketMovers(): Promise<MarketMoversResponse|null> {
- // 백엔드 미기동/데이터 없음이어도 홈은 렌더 — 섹션은 데이터 있을 때만 표시
- const res = await fetchMarketMovers();
- if (!res.success || !res.data) {
- return null;
- }
- return res.data;
- }
- export default async function Home() {
- // 채널 기능 OFF: 라이브 채널 섹션 미노출이므로 조회 생략
- const [banners, live, worldIndices, marketQuotes, domesticSummary, marketMovers] = await Promise.all([
- loadActiveBanners(),
- FEATURE_CHANNEL ? loadLiveChannels() : Promise.resolve({ channels: [], total: 0 }),
- loadWorldIndices(),
- loadMarketQuotes(),
- loadDomesticSummary(),
- loadMarketMovers()
- ]);
- return (
- <div className="home">
- <div className="home__inner">
- {worldIndices.length > 0 && <WorldMarketMap rows={worldIndices} />}
- {domesticSummary.length > 0 && <DomesticSummary rows={domesticSummary} />}
- {marketMovers && <MarketMovers data={marketMovers} />}
- {marketQuotes.length > 0 && <MajorQuotesGrid rows={marketQuotes} />}
- <HomeBannerCarousel items={banners} />
- {FEATURE_CHANNEL && (
- live.channels.length === 0 ? (
- <LiveChannelEmpty />
- ) : (
- <LiveChannelGrid
- initialChannels={live.channels}
- initialTotal={live.total}
- pageSize={LIVE_PAGE_SIZE}
- />
- )
- )}
- </div>
- </div>
- );
- }
|