- 등록부 home 줄 = mountHome · 썸네일 선 · 단계 점 · 「다음: 지금 단계」 · [이어서 하기] = 그 단계 화면 · [자세히] = 상세 - 4~8 = 팀원별 · 단계 분포 · 14 일 넘게 그대로 표시 · 9 넘음 = 요약 숫자 · 회사별 막대 · 종류 원(인라인 SVG) - 오른쪽 = 처리할 일 · 임시 보관함 · 회사(회사 관리자) · 예정노선(산림청) · 처음 = 세 걸음 · 꼴 고정(자동 · 작게 · 크게) 기억 - 홈 역할 차례 = 셸 roleOf 와 같게(회사 관리자가 산림청 앞) - test_546 등록부 시험 — import 한 mount 이름을 빈 함수로 저절로(페이지 줄 갈아 끼워도 그대로) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
75 lines
2.7 KiB
TypeScript
75 lines
2.7 KiB
TypeScript
/* =============================================================================
|
|
* B01_Dashboard_Api_Home.ts
|
|
* 대시보드 홈 API(PLAN 547) — GET /dashboard/home · /dashboard/projects/summary
|
|
* ========================================================================== */
|
|
|
|
import { API_BASE_URL } from "@config/config_frontend";
|
|
|
|
/** 프로젝트 카드 요약(547-1 · `B01_Dashboard_Summary.py`) — 값이 없으면 칸이 빠짐 */
|
|
export interface ProjectSummary {
|
|
id: string;
|
|
name: string;
|
|
kind: string;
|
|
region?: string | null;
|
|
company_id?: number | null;
|
|
stage_index: number;
|
|
stage_total: number;
|
|
stage_name: string;
|
|
done: boolean;
|
|
updated_at?: string | null;
|
|
stale_days?: number | null;
|
|
owner_user_id?: number | null;
|
|
owner_names: string[];
|
|
/** 노선 중심선 0~1(y 아래로) · 없으면 null */
|
|
thumb: [number, number][] | null;
|
|
metrics: { length_m?: number; stations?: number; structures?: number };
|
|
}
|
|
|
|
export interface PlanTodo {
|
|
project_id: string;
|
|
project_name: string;
|
|
year: number;
|
|
linked_project_id: string | null;
|
|
}
|
|
|
|
export interface HomeData {
|
|
role: "SYSTEM_ADMIN" | "FOREST" | "ADMIN" | "USER";
|
|
/** 진행 중(완료 아님) · 최근 수정 순 · 썸네일은 앞 8 개만 */
|
|
projects: ProjectSummary[];
|
|
/** 홈 범위 프로젝트 전체(완료 포함) — 0 = 처음 */
|
|
project_total: number;
|
|
todos: {
|
|
new_plans: PlanTodo[];
|
|
updated_plans: PlanTodo[];
|
|
join_requests?: number;
|
|
expiring_temp: { batch_id: string; name: string; expires_at: string; days_left: number }[];
|
|
temp_count: number;
|
|
};
|
|
company?: { id: number; name: string | null; member_count: number | null };
|
|
forest?: {
|
|
plan_status: { draft: number; analyzed: number; confirmed: number };
|
|
assign_waiting: number;
|
|
};
|
|
system?: {
|
|
companies: number;
|
|
users: number;
|
|
company_names: Record<string, string>;
|
|
server: { cpu: number | null; memory: number | null; disk: number | null };
|
|
};
|
|
}
|
|
|
|
async function getJson<T>(path: string): Promise<T> {
|
|
const response = await fetch(`${API_BASE_URL}${path}`, { credentials: "include" });
|
|
if (!response.ok) throw new Error(`홈 자료를 불러오지 못했습니다 (${response.status})`);
|
|
return (await response.json()) as T;
|
|
}
|
|
|
|
export const fetchHome = (): Promise<HomeData> => getJson<HomeData>("/dashboard/home");
|
|
|
|
/** 카드 요약 — ids 없으면 보이는 프로젝트 전부(최근 수정 순) */
|
|
export async function fetchProjectSummaries(ids?: string[]): Promise<ProjectSummary[]> {
|
|
const query = ids?.length ? `?ids=${encodeURIComponent(ids.join(","))}` : "";
|
|
return (await getJson<{ projects: ProjectSummary[] }>(`/dashboard/projects/summary${query}`))
|
|
.projects;
|
|
}
|