Files
ga-commission-system/ga-frontend/src/main.tsx
T

184 lines
5.2 KiB
TypeScript
Raw Normal View History

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
2026-05-14 01:21:27 +09:00
import { ConfigProvider, type ThemeConfig, message } from 'antd';
import koKR from 'antd/locale/ko_KR';
import 'dayjs/locale/ko';
2026-05-14 01:21:27 +09:00
import {
COLOR_PRIMARY, COLOR_PRIMARY_LIGHT,
COLOR_SUCCESS, COLOR_WARNING, COLOR_ERROR, COLOR_INFO,
GRAY, FONT_FAMILY, FONT_SIZE, RADIUS, SPACING, LAYOUT,
} from './theme/tokens';
import App from './App';
import './index.css';
2026-05-14 01:21:27 +09:00
// 토스트 메시지 전역 설정 (top-right, 최대 5개, 3초)
message.config({ top: 16, maxCount: 5, duration: 3 });
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: 1, staleTime: 30_000 } },
});
const theme: ThemeConfig = {
token: {
2026-05-14 01:21:27 +09:00
// ── 브랜드 — 토스 블루 ──
colorPrimary: COLOR_PRIMARY,
colorPrimaryBg: COLOR_PRIMARY_LIGHT,
colorSuccess: COLOR_SUCCESS,
colorWarning: COLOR_WARNING,
colorError: COLOR_ERROR,
colorInfo: COLOR_INFO,
// ── 배경 ──
colorBgContainer: '#ffffff',
colorBgLayout: GRAY[50],
colorBgElevated: '#ffffff',
colorBgSpotlight: GRAY[100],
// ── 텍스트 — 토스 단계 ──
colorText: GRAY[800],
colorTextSecondary: GRAY[600],
colorTextTertiary: GRAY[500],
colorTextDisabled: GRAY[400],
// ── 테두리 — 거의 보이지 않게 ──
colorBorder: GRAY[200],
colorBorderSecondary: GRAY[100],
// ── 폰트 ──
fontFamily: FONT_FAMILY,
fontSize: FONT_SIZE.base, // 15px
fontSizeHeading1: FONT_SIZE['2xl'], // 32px
fontSizeHeading2: FONT_SIZE.xl, // 24px
fontSizeHeading3: FONT_SIZE.lg, // 20px
fontSizeHeading4: FONT_SIZE.md, // 16px
fontSizeHeading5: FONT_SIZE.base, // 15px
// ── Border Radius — 토스 비율 ──
borderRadius: RADIUS.md, // 12 (버튼, 입력)
borderRadiusLG: RADIUS.lg, // 16 (카드)
borderRadiusSM: RADIUS.sm, // 8
borderRadiusXS: 4,
// ── 공간 ──
padding: SPACING[4],
paddingLG: SPACING[6],
paddingSM: SPACING[2],
paddingXS: SPACING[1],
margin: SPACING[4],
marginLG: SPACING[6],
marginSM: SPACING[2],
// ── 컨트롤 높이 — 토스는 큼직하게 ──
controlHeight: 40, // 기본 입력/버튼
controlHeightSM: 32,
controlHeightLG: 48, // large 입력/버튼
// ── 그림자 — 옅은 합성 ──
boxShadow: '0 1px 3px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.04)',
boxShadowSecondary: '0 2px 8px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.06)',
},
2026-05-14 01:21:27 +09:00
components: {
2026-05-14 01:21:27 +09:00
// ── 메뉴 ──
Menu: {
2026-05-14 01:21:27 +09:00
itemHeight: 44,
itemMarginInline: 8,
itemBorderRadius: RADIUS.sm,
subMenuItemBg: 'transparent',
itemSelectedBg: COLOR_PRIMARY_LIGHT,
itemSelectedColor: COLOR_PRIMARY,
itemHoverBg: GRAY[50],
itemHoverColor: GRAY[800],
itemColor: GRAY[600],
},
2026-05-14 01:21:27 +09:00
// ── 테이블 ──
Table: {
2026-05-14 01:21:27 +09:00
headerBg: GRAY[50],
rowHoverBg: GRAY[50],
cellPaddingBlock: 14,
cellPaddingInline: 16,
headerSplitColor: GRAY[200],
},
2026-05-14 01:21:27 +09:00
// ── 버튼 — 토스 CTA 스타일 ──
Button: {
2026-05-14 01:21:27 +09:00
paddingInline: 20,
fontWeight: 600,
borderRadius: RADIUS.md,
primaryShadow: 'none',
defaultShadow: 'none',
dangerShadow: 'none',
},
2026-05-14 01:21:27 +09:00
// ── 입력 — 토스 filled 느낌 ──
Input: {
paddingInline: 12,
paddingBlock: 12,
borderRadius: RADIUS.md,
hoverBorderColor: COLOR_PRIMARY,
},
// ── 카드 ──
Card: {
bodyPadding: SPACING[6], // 24px
headerBg: '#ffffff',
borderRadius: RADIUS.lg, // 16px
},
// ── 레이아웃 ──
Layout: {
2026-05-14 01:21:27 +09:00
headerHeight: LAYOUT.headerHeight,
headerBg: '#ffffff',
siderBg: '#ffffff',
bodyBg: GRAY[50],
},
// ── 폼 ──
Form: {
itemMarginBottom: 20,
labelFontSize: 13,
labelColor: GRAY[600],
},
// ── 배지 ──
Badge: {
textFontSize: 11,
},
// ── 태그/칩 ──
Tag: {
borderRadius: RADIUS.full,
},
// ── Select ──
Select: {
borderRadius: RADIUS.md,
},
// ── DatePicker ──
DatePicker: {
borderRadius: RADIUS.md,
},
// ── 모달 ──
Modal: {
borderRadius: RADIUS.xl, // 20px
},
},
};
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ConfigProvider locale={koKR} theme={theme}>
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<App />
</BrowserRouter>
</QueryClientProvider>
</ConfigProvider>
</React.StrictMode>,
);