/** * 검사 시작/다음 검사 이동 — POST start(회차 생성/재개) 후 미완료 검사로 라우팅 * Phase D-3: MD3 디자인 토큰 + 공용 컴포넌트(PillButton, InfoBanner, MatIcon) 적용 */ import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; import { http } from '../lib/api'; import PillButton from '../components/PillButton'; import InfoBanner from '../components/InfoBanner'; /** 백엔드 검사 코드 → 프론트 라우트 슬러그 */ const ORDER: Array<{ code: string; path: string }> = [ { code: 'MC', path: 'mc' }, { code: 'EP', path: 'ep' }, { code: 'CST', path: 'cst' }, { code: 'NBACK', path: 'nb' }, // NBACK → /test/nb (소문자 변환 시 nback이 아님) { code: 'MR', path: 'mr' }, ]; const Container = styled.div` display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; min-height: 100dvh; padding: 24px 0; text-align: center; `; const LoadingSpinner = styled.div` width: 40px; height: 40px; border: 3px solid var(--md3-outline-variant); border-top-color: var(--md3-primary); border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 16px; @keyframes spin { to { transform: rotate(360deg); } } `; const LoadingText = styled.p` font-family: 'Inter', 'Pretendard', system-ui, sans-serif; font-size: 15px; color: var(--md3-on-surface-variant); margin: 0; `; const ErrorCard = styled(InfoBanner)` && { max-width: 400px; width: 100%; margin-top: 16px; } `; const RetryButton = styled(PillButton)` && { width: 100%; max-width: 400px; margin-top: 12px; } `; export default function TestStart() { const nav = useNavigate(); const [error, setError] = useState(null); useEffect(() => { let mounted = true; (async () => { try { await http.post('/api/cntdata/start'); const s = await http.get<{ done: Record; todayCompleted: boolean }>( '/api/cntdata/status', ); if (!mounted) return; if (s.todayCompleted) { nav('/dashboard'); return; } const next = ORDER.find((t) => !s.done?.[t.code]); nav(next ? `/test/${next.path}` : '/test'); } catch (err: any) { if (!mounted) return; setError(err?.message ?? '검사 시작에 실패했습니다. 다시 시도해주세요.'); } })(); return () => { mounted = false; }; }, [nav]); if (error) { return ( {error} { setError(null); window.location.reload(); }}> 다시 시도 nav('/test')}> 검사 홈으로 ); } return ( 검사를 준비하는 중입니다… ); }