Files
Aislo/A01_Home/A01_Home_UI_Page.ts
T
eomsangdonandClaude Sonnet 5.5 25adc2f0e7 refactor(공개화면): A01~A09 · B10 · B11 을 공개 화면 틀 · 카드 · 알림 · 배지 · 체크 · 접이 부품으로 (PLAN 553-7)
- A01~A05 hero 다섯 벌 · 구역 제목 복제 CSS 걷고 공개 화면 틀 한 벌(wide 옵션 · 구역 제목 가운데 · 머리 아랫줄은 자리 안 먹는 그림자)
- 카드 = 카드 부품(로그인 · 가입 · 지원 · 약관 · 기능 카드 · 소식 줄 · B11 단계 카드) · 지원 성공 · B10 안내 = 띠 알림 · 태그 = 배지
- A07 약관 날 체크 · 날 details = 체크 + 접이 부품 · A08 날 textarea = 입력 여러 줄 · 빈 소식 = 빈 상태
- 죽은 A07_Register_UI_Page · 쓰이지 않는 CSS 걷음 · 띠 알림 hidden 받음
- 지킴 시험 test_553_7_public_pages

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 21:56:42 +09:00

117 lines
4.3 KiB
TypeScript

/* =============================================================================
* A01_Home_UI_Page.ts
* 로그인 전 01: 홈 (소개 히어로 + 최신 소식 + 주요 기능)
*
* 제약 준수:
* - 모든 문구는 ui_template_locale.ts 참조 (하드코딩 금지).
* - 색상/간격은 A01_Home_UI_Style.css + theme.css 변수만 사용.
* - 공통 부품(createPublicFrame/createCard/createBadge/createButton) 우선 사용.
* - 이벤트 핸들러는 on[페이지]_[기능]_[액션] 명명.
* ========================================================================== */
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
import { createBadge } from "@ui/ui_template_badge";
import { createButton, createCard } from "@ui/ui_template_elements";
import { createPublicFrame } from "@ui/ui_template_public_layout";
import { createText } from "@ui/ui_template_text";
import { navigateTo } from "../A00_Common/router";
import { ROUTES } 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 buildNews(): HTMLElement {
const list = document.createElement("div");
list.className = "a01-news-list";
for (const item of MOCK_NEWS) {
const tag = createBadge(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;
const row = createCard({ body: [tag, titleEl, dateEl] });
row.classList.add("a01-news-row");
list.append(row);
}
return list;
}
function buildFeatures(): HTMLElement {
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 card = createCard({ title: L(titleKey), body: [createText(L(descKey), "muted", 14)] });
card.classList.add("a01-feature-card");
grid.append(card);
}
return grid;
}
/* -----------------------------------------------------------------------------
* 페이지 진입점
* -------------------------------------------------------------------------- */
export function renderA01Home(root: HTMLElement): void {
const frame = createPublicFrame({
title: L("A01_Home_Title"),
lead: L("A01_Home_Hero_Subtitle"),
actions: [
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,
}),
],
});
frame.addSection(L("A01_Home_News_SectionTitle")).append(buildNews());
frame.addSection(L("A01_Home_Features_SectionTitle")).append(buildFeatures());
root.append(frame.root);
}