Files
Aislo/B03_FileInput/B03_FileInput_State.ts
T
eomsangdonandClaude Sonnet 5.5 a826804277 refactor(B02·B03): 페이지 자체 변종을 부품 상자 부품으로 — 파일 카드 · 띠 알림 · 진행 막대 · 켜기 · 패널 머리 · 단추 (PLAN 553-1)
- B03 파일 카드 = 카드 부품 · [선택] · [×] = 단추 · 아이콘 단추 · 진행 막대 · 오류 띠 = 부품
- B03 현황 · 이어올리기 · 예정노선 바뀜 = 띠 알림 · LAS 없이 설계 = 켜기 · 노선 · 지형 제목 = 패널 머리
- B03 · B02 죽은 CSS 걷음 · 날 색 → 공통 값 · 가이드 촬영 선택자 · 지킴 시험 test_553_1_pages

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

93 lines
2.6 KiB
TypeScript

import { createBanner } from "@ui/ui_template_banner";
export type B03AnalysisStatus = "pending" | "in_progress" | "completed" | "failed";
export interface B03StoredFileState {
slot: string;
fileName: string;
fileSize: number;
status: "completed" | "failed";
}
export interface B03ProjectState {
projectId: string;
uploadedAt: number;
files: B03StoredFileState[];
analysisStatus: B03AnalysisStatus;
analysisProgress: number;
lastCheckedAt: number;
}
function key(projectId: string): string {
return `b03_project_state_${projectId}`;
}
export function loadB03ProjectState(projectId: string): B03ProjectState | null {
const raw = localStorage.getItem(key(projectId));
if (!raw) return null;
try {
return JSON.parse(raw) as B03ProjectState;
} catch {
localStorage.removeItem(key(projectId));
return null;
}
}
export function saveB03UploadedFile(
projectId: string,
file: { slot: string; fileName: string; fileSize: number },
): B03ProjectState {
const current = loadB03ProjectState(projectId);
const nextFiles = (current?.files ?? []).filter((item) => item.slot !== file.slot);
nextFiles.push({ ...file, status: "completed" });
const next: B03ProjectState = {
projectId,
uploadedAt: current?.uploadedAt ?? Date.now(),
files: nextFiles,
analysisStatus: "pending",
analysisProgress: 0,
lastCheckedAt: Date.now(),
};
localStorage.setItem(key(projectId), JSON.stringify(next));
return next;
}
export function updateB03AnalysisState(
projectId: string,
status: B03AnalysisStatus,
progress: number,
): B03ProjectState {
const current = loadB03ProjectState(projectId);
const next: B03ProjectState = {
projectId,
uploadedAt: current?.uploadedAt ?? Date.now(),
files: current?.files ?? [],
analysisStatus: status,
analysisProgress: progress,
lastCheckedAt: Date.now(),
};
localStorage.setItem(key(projectId), JSON.stringify(next));
return next;
}
export function restoreB03ProjectState(options: {
projectId: string;
label: string;
container: HTMLElement;
poll: (projectId: string) => Promise<boolean>;
onComplete: () => void;
}): void {
const state = loadB03ProjectState(options.projectId);
if (!state) return;
options.container.replaceChildren();
options.container.append(
createBanner({ tone: "info", text: `${options.label}: ${state.analysisProgress}%` }),
);
options.container.classList.add("is-visible");
if (state.analysisStatus === "in_progress" || state.analysisStatus === "pending") {
void options.poll(options.projectId).then((completed) => {
if (completed) options.onComplete();
});
}
}