import { ROUTES } from "@config/config_frontend"; import { createButton, createTag, hideLoadingOverlay, showLoadingOverlay, showToast, } from "@ui/ui_template_elements"; import { section } from "@ui/ui_template_general_blocks"; import { navigateTo } from "../A00_Common/router"; import { fetchAllCompanies, fetchAllJoinRequests, fetchAllProjects, fetchAllUsers, fetchAuditLogs, fetchCompanyJoinRequests, fetchCompanyMembers, fetchCompanyProjects, fetchDashboardMe, fetchSystemResources, fetchUserCompany, fetchUserProjects, type AuditLog, type CompanyInfo, type DashboardUser, type JoinRequest, type Member, type ProjectItem, type ResourceData, } from "./B01_Dashboard_Api_Fetch"; import { auditLogTable, userTable } from "./B01_Dashboard_UI_Admin"; import { L, roleLabel } from "./B01_Dashboard_UI_Common"; import { buildCompanyPanel, companyTable, joinRequestTable, memberTable, } from "./B01_Dashboard_UI_Company"; import { openAddMemberModal, openCreateCompanyModal } from "./B01_Dashboard_UI_Modals"; import { buildProfileForm, buildSecurityForm } from "./B01_Dashboard_UI_Profile"; import { projectTable } from "./B01_Dashboard_UI_Projects"; import { buildResourcePanel } from "./B01_Dashboard_UI_Resources"; import { buildTempUploadSection } from "./B01_Dashboard_UI_TempUpload"; import "./B01_Dashboard_UI_Style.css"; export interface DashboardState { user: DashboardUser; userProjects: ProjectItem[]; companyProjects: ProjectItem[]; allProjects: ProjectItem[]; company: CompanyInfo | null; members: Member[]; joinRequests: JoinRequest[]; allCompanies: CompanyInfo[]; allUsers: DashboardUser[]; allJoinRequests: JoinRequest[]; auditLogs: AuditLog[]; resources: ResourceData | null; } export async function renderB01Dashboard(root: HTMLElement): Promise { showLoadingOverlay(); try { const user = await fetchDashboardMe(); const state: DashboardState = { user, userProjects: [], companyProjects: [], allProjects: [], company: null, members: [], joinRequests: [], allCompanies: [], allUsers: [], allJoinRequests: [], auditLogs: [], resources: null, }; await loadRoleData(state); root.innerHTML = ""; root.append(buildPage(state)); } catch (error) { showToast(error instanceof Error ? error.message : L("B01_Dashboard_LoadFailed"), "error"); } finally { hideLoadingOverlay(); } } async function loadRoleData(state: DashboardState): Promise { if (state.user.role === "SYSTEM_ADMIN") { const results = await Promise.allSettled([ fetchAllCompanies(), fetchAllUsers(), fetchAllJoinRequests(), fetchAuditLogs(), fetchSystemResources(7), fetchAllProjects(), ]); state.allCompanies = results[0].status === "fulfilled" ? results[0].value : []; state.allUsers = results[1].status === "fulfilled" ? results[1].value : []; state.allJoinRequests = results[2].status === "fulfilled" ? results[2].value : []; state.auditLogs = results[3].status === "fulfilled" ? results[3].value : []; state.resources = results[4].status === "fulfilled" ? results[4].value : null; state.allProjects = results[5].status === "fulfilled" ? results[5].value : []; results.forEach((res, idx) => { if (res.status === "rejected") { console.error(`System Admin API failed at index ${idx}:`, res.reason); } }); return; } const [projects, company] = await Promise.all([ fetchUserProjects().catch(() => []), fetchUserCompany().catch(() => null), ]); state.userProjects = projects; state.company = company; if (state.user.role === "ADMIN") { const [members, requests, companyProjects] = await Promise.all([ fetchCompanyMembers().catch(() => []), fetchCompanyJoinRequests().catch(() => []), fetchCompanyProjects().catch(() => []), ]); state.members = members; state.joinRequests = requests; state.companyProjects = companyProjects; } } function buildPage(state: DashboardState): HTMLElement { const page = document.createElement("div"); page.className = "b01-dashboard"; page.append(buildHeader(state.user)); const grid = document.createElement("div"); grid.className = "b01-dashboard__grid"; if (state.user.role === "SYSTEM_ADMIN") { grid.append( section(L("B01_Dashboard_Resources"), buildResourcePanel(state.resources), true), section(L("B01_Dashboard_Projects"), projectTable(state.allProjects, state.user), true, [ createButton({ label: "+", onClick: () => navigateTo(ROUTES.B02_PROJ_REGISTER) }), ]), buildTempUploadSection(), section(L("B01_Dashboard_Users"), userTable(state.allUsers, state.user), true, [ createButton({ label: "+", onClick: () => openAddMemberModal() }), ]), section(L("B01_Dashboard_JoinRequests"), joinRequestTable(state.allJoinRequests, true), true), section(L("B01_Dashboard_Companies"), companyTable(state.allCompanies), true, [ createButton({ label: "+", onClick: () => openCreateCompanyModal() }), ]), section(L("B01_Dashboard_AuditLogs"), auditLogTable(state.auditLogs), true), ); } else if (state.user.role === "ADMIN") { grid.append( section(L("B01_Dashboard_Projects"), projectTable(state.companyProjects, state.user), true, [ createButton({ label: "+", onClick: () => navigateTo(ROUTES.B02_PROJ_REGISTER) }), ]), buildTempUploadSection(), section(L("B01_Dashboard_Members"), memberTable(state.members, state.user), true, [ createButton({ label: "+", onClick: () => openAddMemberModal() }), ]), section(L("B01_Dashboard_JoinRequests"), joinRequestTable(state.joinRequests, false), true), section(L("B01_Dashboard_Company"), buildCompanyPanel(state), true), ); } else { grid.append( section(L("B01_Dashboard_Projects"), projectTable(state.userProjects, state.user), true, [ createButton({ label: "+", onClick: () => navigateTo(ROUTES.B02_PROJ_REGISTER) }), ]), // 임시 보관함 — 프로젝트를 만들기 전에 자료를 올려 두는 곳이라 프로젝트 목록 // 바로 아래에 둔다(2026-08-08 사용자 지시). buildTempUploadSection(), section(L("B01_Dashboard_Company"), buildCompanyPanel(state), true), ); } grid.append( section(L("B01_Dashboard_Profile"), buildProfileForm(state.user)), section(L("B01_Account_Section_Security"), buildSecurityForm()), ); page.append(grid); return page; } function buildHeader(user: DashboardUser): HTMLElement { const header = document.createElement("header"); header.className = "b01-dashboard__header"; const text = document.createElement("div"); const title = document.createElement("h1"); title.className = "b01-dashboard__title"; title.textContent = L("B01_Dashboard_Title"); const subtitle = document.createElement("p"); subtitle.className = "b01-dashboard__subtitle"; subtitle.textContent = L("B01_Dashboard_Subtitle"); text.append(title, subtitle); const tag = createTag(roleLabel(user.role), user.role === "SYSTEM_ADMIN" ? "accent" : "neutral"); tag.classList.add("b01-dashboard__role"); header.append(text, tag); return header; }