| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- import '../style.scss';
- import '@/app/styles/data-table.scss';
- import { Metadata } from 'next';
- import Link from 'next/link';
- import MarketNav from '../_components/MarketNav';
- import EsgSecuritiesTable from '../_components/EsgSecuritiesTable';
- import EsgIndicesTable from '../_components/EsgIndicesTable';
- import SriBondsTable from '../_components/SriBondsTable';
- import Pager from '../_components/Pager';
- import { fetchMarketEsgSecurities, fetchMarketEsgIndices, fetchMarketSriBonds } from '@/lib/api/market';
- import { formatNumber } from '@/lib/utils/stock';
- import { tradeDateLabel } from '@/lib/utils/market';
- export const metadata: Metadata = {
- title: 'ESG (사회책임투자) — 개미투자',
- description: 'ESG 증권·ESG 지수·SRI 채권 시세 — 사회책임투자 시장 데이터 (전일 종가 기준)'
- };
- type EsgTab = 'securities'|'indices'|'sri-bonds';
- const TABS: { value: EsgTab; label: string }[] = [
- { value: 'securities', label: 'ESG 증권' },
- { value: 'indices', label: 'ESG 지수' },
- { value: 'sri-bonds', label: 'SRI 채권' }
- ];
- const PER_PAGE = 20;
- type Props = {
- searchParams: Promise<{
- tab?: string;
- page?: string;
- }>;
- };
- export default async function MarketEsgPage({ searchParams }: Props)
- {
- const query = await searchParams;
- const tab: EsgTab = TABS.some(c => c.value === query.tab) ? (query.tab as EsgTab) : 'securities';
- const page = Math.max(Number(query.page) || 1, 1);
- const securitiesRes = tab === 'securities' ? await fetchMarketEsgSecurities({ page }) : null;
- const indicesRes = tab === 'indices' ? await fetchMarketEsgIndices({ page }) : null;
- const sriBondsRes = tab === 'sri-bonds' ? await fetchMarketSriBonds({ page }) : null;
- const res = securitiesRes ?? indicesRes ?? sriBondsRes!;
- const data = res.success ? res.data : null;
- const tradeDate = securitiesRes?.data?.tradeDate ?? indicesRes?.data?.tradeDate ?? sriBondsRes?.data?.tradeDate;
- return (
- <div className='market'>
- <div className='market__head'>
- <h1 className='market__title'>ESG</h1>
- <span className='market__basis'>{tradeDateLabel(tradeDate)} · 사회책임투자</span>
- </div>
- <MarketNav />
- <div className='market__filters'>
- <div className='market__filter-group' role='group' aria-label='ESG 구분'>
- <span className='market__filter-label'>구분</span>
- {TABS.map(item => (
- <Link
- key={item.value}
- href={`/market/esg?tab=${item.value}`}
- className={`market__tab${tab === item.value ? ' market__tab--active' : ''}`}
- {...(tab === item.value ? { 'aria-current': 'page' as const } : {})}
- >
- {item.label}
- </Link>
- ))}
- </div>
- </div>
- {!res.success ? (
- <div className='market__error' role='alert'>
- <strong>ESG 데이터를 불러오지 못했습니다.</strong>
- 잠시 후 다시 시도해 주세요.
- </div>
- ) : !data || data.list.length === 0 ? (
- <div className='market__empty'>표시할 항목이 없습니다.</div>
- ) : (
- <>
- <p className='market__total'>전체 {formatNumber(data.total)}건</p>
- <div className='market__table-wrap'>
- {tab === 'securities' && <EsgSecuritiesTable rows={securitiesRes!.data!.list} />}
- {tab === 'indices' && <EsgIndicesTable rows={indicesRes!.data!.list} />}
- {tab === 'sri-bonds' && <SriBondsTable rows={sriBondsRes!.data!.list} />}
- </div>
- <Pager
- total={data.total}
- page={page}
- perPage={PER_PAGE}
- basePath='/market/esg'
- query={{ tab }}
- />
- </>
- )}
- </div>
- );
- }
|