/* ============================================================================= * A01_Home_UI_Page.ts * 로그인 전 01: 홈 (소개 히어로 + 최신 소식 + 주요 기능) * * 제약 준수: * - 모든 문구는 ui_template_locale.ts 참조 (하드코딩 금지). * - 색상/간격은 A01_Home_UI_Style.css + theme.css 변수만 사용. * - 공통 컴포넌트(createButton/createCard/createTag) 우선 사용. * - 이벤트 핸들러는 on[페이지]_[기능]_[액션] 명명. * ========================================================================== */ import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale"; import { createButton, createCard, createTag } from "@ui/ui_template_elements"; import { navigateTo } from "../A00_Common/router"; import { ROUTES, AUTH_TOKEN_KEY } from "@config/config_frontend"; import "./A01_Home_UI_Style.css"; /** locale 헬퍼 */ function L(key: keyof typeof ui_locales): string { return ui_locales[key][currentLanguageIndex]; } /* ----------------------------------------------------------------------------- * Mock 데이터 (백엔드 연결 전) — 나중에 GET /api/a01/news로 교체 * -------------------------------------------------------------------------- */ interface NewsItem { id: number; title: string; date: string; } const MOCK_NEWS: NewsItem[] = [ { id: 1, title: "v0.1 프론트엔드 프로토타입 공개", date: "2026-07-05" }, { id: 2, title: "3D 지형 뷰어 Three.js 엔진 확정", date: "2026-07-04" }, { id: 3, title: "임도 설계 워크플로우 6단계 정의 완료", date: "2026-07-01" }, ]; /* ----------------------------------------------------------------------------- * 이벤트 핸들러 * -------------------------------------------------------------------------- */ function onA01_Home_GetStarted_Click(): void { navigateTo(ROUTES.A07_REGISTER); } function onA01_Home_Explore_Click(): void { navigateTo(ROUTES.A02_PROG_DETAIL); } function navigateToDevPage(route: string): void { localStorage.setItem(AUTH_TOKEN_KEY, "dev-temp-token"); navigateTo(route as never); } /* ----------------------------------------------------------------------------- * 섹션 빌더 * -------------------------------------------------------------------------- */ function buildHero(): HTMLElement { const hero = document.createElement("section"); hero.className = "a01-hero"; const inner = document.createElement("div"); inner.className = "a01-hero__inner"; const title = document.createElement("h1"); title.className = "a01-hero__title"; title.textContent = L("A01_Home_Title"); const subtitle = document.createElement("p"); subtitle.className = "a01-hero__subtitle"; subtitle.textContent = L("A01_Home_Hero_Subtitle"); const ctas = document.createElement("div"); ctas.className = "a01-hero__ctas"; ctas.append( createButton({ label: L("A01_Home_Hero_CtaPrimary"), variant: "filled", onClick: onA01_Home_GetStarted_Click, }), createButton({ label: L("A01_Home_Hero_CtaSecondary"), variant: "ghost", onClick: onA01_Home_Explore_Click, }), ); inner.append(title, subtitle, ctas); hero.append(inner); return hero; } function buildNews(): HTMLElement { const section = document.createElement("section"); section.className = "a01-section"; const heading = document.createElement("h2"); heading.className = "a01-section__title"; heading.textContent = L("A01_Home_News_SectionTitle"); const list = document.createElement("div"); list.className = "a01-news-list"; for (const item of MOCK_NEWS) { const row = document.createElement("div"); row.className = "a01-news-row"; const tag = createTag(L("A01_Home_News_Tag"), "accent"); const titleEl = document.createElement("span"); titleEl.className = "a01-news-row__title"; titleEl.textContent = item.title; const dateEl = document.createElement("span"); dateEl.className = "a01-news-row__date"; dateEl.textContent = item.date; row.append(tag, titleEl, dateEl); list.append(row); } section.append(heading, list); return section; } function buildFeatures(): HTMLElement { const section = document.createElement("section"); section.className = "a01-section"; const heading = document.createElement("h2"); heading.className = "a01-section__title"; heading.textContent = L("A01_Home_Features_SectionTitle"); const grid = document.createElement("div"); grid.className = "a01-feature-grid"; const features: [keyof typeof ui_locales, keyof typeof ui_locales][] = [ ["A01_Home_Feature1_Title", "A01_Home_Feature1_Desc"], ["A01_Home_Feature2_Title", "A01_Home_Feature2_Desc"], ["A01_Home_Feature3_Title", "A01_Home_Feature3_Desc"], ]; for (const [titleKey, descKey] of features) { const desc = document.createElement("p"); desc.className = "a01-feature__desc"; desc.textContent = L(descKey); const card = createCard({ title: L(titleKey), body: [desc] }); card.classList.add("a01-feature-card"); grid.append(card); } section.append(heading, grid); return section; } function buildDevMenu(): HTMLElement { const section = document.createElement("section"); section.className = "a01-section a01-dev-menu"; section.style.opacity = "0.6"; section.style.borderTop = "2px dashed var(--color-slate)"; section.style.marginTop = "var(--spacing-48)"; section.style.paddingTop = "var(--spacing-48)"; const heading = document.createElement("h2"); heading.className = "a01-section__title"; heading.textContent = "🔧 개발 모드 - B 그룹 테스트"; const grid = document.createElement("div"); grid.className = "a01-feature-grid"; grid.style.gridTemplateColumns = "repeat(auto-fit, minmax(200px, 1fr))"; const bPages: [string, string][] = [ [ROUTES.B01_ACCOUNT, "B01 · 계정 상세"], [ROUTES.B02_PROJ_REGISTER, "B02 · 프로젝트 등록"], [ROUTES.B03_FILE_INPUT, "B03 · 파일 입력"], [ROUTES.B04_WF1_SURFACE, "B04 · 지표면 분석"], [ROUTES.B05_WF2_ROUTE, "B05 · 경로 설계"], [ROUTES.B06_WF3_PROFILE_CROSS, "B06 · 종횡단 생성"], [ROUTES.B07_WF4_DESIGN_DETAIL, "B07 · 상세 설계"], [ROUTES.B08_WF5_QUANTITY, "B08 · 수량 산출"], [ROUTES.B09_WF6_ESTIMATION, "B09 · 견적/문서"], [ROUTES.B10_PAYMENT, "B10 · 결재"], [ROUTES.B11_STATUS, "B11 · 상태 출력"], ]; for (const [route, label] of bPages) { const btn = createButton({ label, variant: "ghost", onClick: () => navigateToDevPage(route), }); btn.style.width = "100%"; grid.append(btn); } section.append(heading, grid); return section; } /* ----------------------------------------------------------------------------- * 페이지 진입점 * -------------------------------------------------------------------------- */ export function renderA01Home(root: HTMLElement): void { const page = document.createElement("div"); page.className = "a01-home"; page.append(buildHero(), buildNews(), buildFeatures(), buildDevMenu()); root.append(page); }