/* ============================================================================= * B01_Dashboard_UI_NewProject.ts * 대시보드 [+] 고르기 모달(요구 345 · PLAN 528-2) — 카드 넷(그림 + 제목) = 예정노선 · 임도설계 · * 사방설계 · 안정성평가. 그림 = SVG 직접(선 색 = 글자 색 → 밝음 · 어두움 그대로). * 예정노선 = 산림청(세션 is_forest_service)만 · 아니면 흐림 + 까닭 툴팁(누름 = 같은 까닭 알림) * 사방설계 = 「준비 중」 · 임도설계 = B02 · 예정노선 = D01 · 안정성평가 = E01 * ========================================================================== */ import "./B01_Dashboard_UI_NewProject.css"; import { ROUTES, type RoutePath } from "@config/config_frontend"; import { el, showToast } from "@ui/ui_template_elements"; import { t, type LocaleKey } from "@ui/ui_template_locale"; import { openModal } from "@ui/ui_template_modal"; import { fetchSessionUser } from "../A06_Login/A06_Login_Api_Fetch"; import { navigateTo } from "../A00_Common/router"; /** 48 칸 그림 — 선 · 면은 currentColor */ const ICONS = { plan: ``, road: ``, erosion: ``, stability: ``, } as const; interface CardSpec { icon: keyof typeof ICONS; title: LocaleKey; route?: RoutePath; /** 못 고르는 까닭(툴팁 · 누름 알림) — 없으면 고를 수 있음 */ reason?: LocaleKey; soon?: boolean; } function svgIcon(kind: keyof typeof ICONS): HTMLElement { const box = el("span", { className: "b01-new-project__icon", attrs: { "aria-hidden": "true" } }); box.innerHTML = `${ICONS[kind]}`; return box; } function card(spec: CardSpec, close: () => void): HTMLButtonElement { const button = el("button", { className: "b01-new-project__card", attrs: { type: "button" }, children: [svgIcon(spec.icon), el("span", { text: t(spec.title) })], }); button.dataset.newProject = spec.icon; if (spec.soon) { button.classList.add("is-soon"); button.append(el("span", { className: "b01-new-project__badge", text: t("DE_New_Soon") })); } if (spec.reason) { button.classList.add("is-dim"); button.title = t(spec.reason); } button.addEventListener("click", () => { if (spec.reason || spec.soon) return void showToast(t(spec.reason ?? "DE_New_Soon")); close(); navigateTo(spec.route!); }); return button; } /** [+] — 세션의 산림청 판정으로 예정노선 카드 켬 · 흐림 */ export async function openNewProjectPicker(): Promise { const forest = Boolean((await fetchSessionUser())?.is_forest_service); const specs: CardSpec[] = [ { icon: "plan", title: "DE_New_Plan", route: ROUTES.D01_PLAN_REGISTER, reason: forest ? undefined : "DE_New_PlanForestOnly", }, { icon: "road", title: "DE_New_Road", route: ROUTES.B02_PROJ_REGISTER }, { icon: "erosion", title: "DE_New_Erosion", soon: true }, { icon: "stability", title: "DE_New_Stability", route: ROUTES.E01_STAB_REGISTER }, ]; openModal({ title: t("DE_New_Title"), closeLabel: t("Common_Btn_Close"), dialogClass: "b01-new-project", mount: (body, close) => body.append( el("div", { className: "b01-new-project__grid", children: specs.map((spec) => card(spec, close)), }), ), }); }