feat: 레이아웃/출하/생산/회계/대시보드 전반 개선

- HeaderFavoritesBar 대폭 개선
- Sidebar/AuthenticatedLayout 소폭 수정
- ShipmentCreate, VehicleDispatch 출하 관련 개선
- WorkOrderCreate/Edit, WorkerScreen 생산 관련 개선
- InspectionCreate 자재 입고검사 개선
- DailyReport, VendorDetail 회계 수정
- CEO 대시보드: CardManagement/DailyProduction/DailyAttendance 섹션 개선
- useCEODashboard, expense transformer 정비
- DocumentViewer, PDF generate route 소폭 수정
- bill-prototype 개발 페이지 추가
- mockData 불필요 데이터 제거
This commit is contained in:
유병철
2026-03-05 13:35:48 +09:00
parent c18c68b6b7
commit 00a6209347
23 changed files with 1689 additions and 517 deletions

View File

@@ -9,11 +9,6 @@ import { useState, useCallback, useEffect, useMemo } from 'react';
import { useDashboardFetch } from './useDashboardFetch';
import {
fetchLoanDashboard,
fetchTaxSimulation,
} from '@/lib/api/dashboard/endpoints';
import type {
DailyReportApiResponse,
ReceivablesApiResponse,
@@ -36,6 +31,8 @@ import type {
UnshippedApiResponse,
ConstructionApiResponse,
DailyAttendanceApiResponse,
LoanDashboardApiResponse,
TaxSimulationApiResponse,
} from '@/lib/api/dashboard/types';
import {
@@ -105,7 +102,19 @@ function buildEndpoint(
// CardManagement 전용 fetch 유틸리티
// ============================================
async function fetchProxyJson<T>(path: string): Promise<{ success: boolean; data: T | null }> {
try {
const r = await fetch(`/api/proxy${path}`);
if (!r.ok) return { success: false, data: null };
const json = await r.json();
return { success: !!json.success, data: json.data ?? null };
} catch {
return { success: false, data: null };
}
}
async function fetchCardManagementData(fallbackData?: CardManagementData) {
const currentYear = new Date().getFullYear();
const [cardApiData, loanResponse, taxResponse] = await Promise.all([
fetch('/api/proxy/card-transactions/summary').then(async (r) => {
if (!r.ok) throw new Error(`API 오류: ${r.status}`);
@@ -113,8 +122,8 @@ async function fetchCardManagementData(fallbackData?: CardManagementData) {
if (!json.success) throw new Error(json.message || '데이터 조회 실패');
return json.data as CardTransactionApiResponse;
}),
fetchLoanDashboard(),
fetchTaxSimulation(),
fetchProxyJson<LoanDashboardApiResponse>('/loans/dashboard'),
fetchProxyJson<TaxSimulationApiResponse>(`/loans/tax-simulation?year=${currentYear}`),
]);
const loanData = loanResponse.success ? loanResponse.data : null;
@@ -696,32 +705,32 @@ export function useCEODashboard(options: UseCEODashboardOptions = {}): CEODashbo
{ initialLoading: enableStatusBoard },
);
const ss = useDashboardFetch<SalesStatusApiResponse, SalesStatusData>(
enableSalesStatus ? 'sales/summary' : null,
enableSalesStatus ? 'dashboard/sales/summary' : null,
transformSalesStatusResponse,
{ initialLoading: enableSalesStatus },
);
const ps = useDashboardFetch<PurchaseStatusApiResponse, PurchaseStatusData>(
enablePurchaseStatus ? 'purchases/summary' : null,
enablePurchaseStatus ? 'dashboard/purchases/summary' : null,
transformPurchaseStatusResponse,
{ initialLoading: enablePurchaseStatus },
);
const dp = useDashboardFetch<DailyProductionApiResponse, DailyProductionData>(
enableDailyProduction ? 'production/summary' : null,
enableDailyProduction ? 'dashboard/production/summary' : null,
transformDailyProductionResponse,
{ initialLoading: enableDailyProduction },
);
const us = useDashboardFetch<UnshippedApiResponse, UnshippedData>(
enableUnshipped ? 'unshipped/summary' : null,
enableUnshipped ? 'dashboard/unshipped/summary' : null,
transformUnshippedResponse,
{ initialLoading: enableUnshipped },
);
const cs = useDashboardFetch<ConstructionApiResponse, ConstructionData>(
enableConstruction ? 'construction/summary' : null,
enableConstruction ? 'dashboard/construction/summary' : null,
transformConstructionResponse,
{ initialLoading: enableConstruction },
);
const da = useDashboardFetch<DailyAttendanceApiResponse, DailyAttendanceData>(
enableDailyAttendance ? 'attendance/summary' : null,
enableDailyAttendance ? 'dashboard/attendance/summary' : null,
transformDailyAttendanceResponse,
{ initialLoading: enableDailyAttendance },
);