From ed52f5f887fa79addf0d9686cc440a626d22f6bf Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 5 Sep 2025 01:16:42 +0000 Subject: (대표님, 임수민) 벤더별 EDP 데이터 입력 진행률 페이지 개선 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/[lng]/admin/edp-progress-debug/page.tsx | 210 ---------------------------- app/[lng]/admin/edp-progress/page.tsx | 135 ------------------ app/[lng]/evcp/(evcp)/edp-progress/page.tsx | 21 +-- 3 files changed, 3 insertions(+), 363 deletions(-) delete mode 100644 app/[lng]/admin/edp-progress-debug/page.tsx delete mode 100644 app/[lng]/admin/edp-progress/page.tsx (limited to 'app') diff --git a/app/[lng]/admin/edp-progress-debug/page.tsx b/app/[lng]/admin/edp-progress-debug/page.tsx deleted file mode 100644 index ebaa07a2..00000000 --- a/app/[lng]/admin/edp-progress-debug/page.tsx +++ /dev/null @@ -1,210 +0,0 @@ -"use client"; - -import React from 'react'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Badge } from '@/components/ui/badge'; -import { ScrollArea } from '@/components/ui/scroll-area'; -import { debugVendorFieldCalculation } from '@/lib/forms/vendor-completion-stats'; -import { Loader, Search, FileText, Tag, CheckCircle, XCircle } from 'lucide-react'; -import { toast } from 'sonner'; - -export default function DebugVendorFieldsPage() { - const [loading, setLoading] = React.useState(false); - const [vendorId, setVendorId] = React.useState('1'); - const [debugData, setDebugData] = React.useState(null); - - const handleDebug = async () => { - setLoading(true); - setDebugData(null); - - try { - const result = await debugVendorFieldCalculation(Number(vendorId)); - setDebugData(result); - - if (result) { - toast.success(`${result.vendorName}의 필드 계산 디버그 완료`); - } else { - toast.warning('벤더 데이터가 없습니다'); - } - } catch (error) { - console.error('Error debugging vendor fields:', error); - toast.error(`디버그 실패: ${error instanceof Error ? error.message : '알 수 없는 오류'}`); - } finally { - setLoading(false); - } - }; - - const renderFieldDetails = (fieldDetails: any[]) => ( -
- {fieldDetails.map((field, index) => ( -
- {field.fieldKey} - = - {String(field.fieldValue ?? 'null')} - {field.isEmpty ? ( - - ) : ( - - )} -
- ))} -
- ); - - return ( -
-
- -

벤더 필드 계산 디버그

-
- - {/* Input */} - - - 벤더 ID 입력 - - -
-
- - setVendorId(e.target.value)} - placeholder="1" - type="number" - /> -
-
- -
-
-
-
- - {/* Results */} - {debugData && ( -
- {/* Summary */} - - - - - {debugData.vendorName} - 전체 요약 - - - -
-
-
- {debugData.debugInfo.grandTotal.totalRequiredFields} -
-

전체 필드

-
-
-
- {debugData.debugInfo.grandTotal.totalFilledFields} -
-

입력 필드

-
-
-
- {debugData.debugInfo.grandTotal.totalEmptyFields} -
-

빈 필드

-
-
-
- {debugData.debugInfo.grandTotal.completionPercentage}% -
-

완성도

-
-
-
-
- - {/* Detailed Breakdown */} - - - 상세 분석 - - - -
- {debugData.debugInfo.contracts.map((contract: any, contractIndex: number) => ( -
-
- - - 계약 {contract.contractId} - {contract.projectName} - - - 전체: {contract.totalRequiredFields} | 입력: {contract.totalFilledFields} - -
- -
- {contract.forms.map((form: any, formIndex: number) => ( -
-
- - {form.formName} ({form.formCode}) - - 전체: {form.totalRequiredFields} | 입력: {form.totalFilledFields} - -
- -
- {form.tags.map((tag: any, tagIndex: number) => ( -
-
- - {tag.tagNo} - - 전체: {tag.requiredFieldsCount} | 입력: {tag.filledFieldsCount} - -
- -
-
- 편집 가능한 필드: {tag.editableFields.join(', ')} -
- {renderFieldDetails(tag.fieldDetails)} -
-
- ))} -
-
- ))} -
-
- ))} -
-
-
-
- - {/* Raw Data */} - - - 원시 데이터 (JSON) - - - -
-                  {JSON.stringify(debugData, null, 2)}
-                
-
-
-
-
- )} -
- ); -} \ No newline at end of file diff --git a/app/[lng]/admin/edp-progress/page.tsx b/app/[lng]/admin/edp-progress/page.tsx deleted file mode 100644 index c42a1db7..00000000 --- a/app/[lng]/admin/edp-progress/page.tsx +++ /dev/null @@ -1,135 +0,0 @@ -"use client"; - -import React from 'react'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Badge } from '@/components/ui/badge'; -import { ScrollArea } from '@/components/ui/scroll-area'; -import { getAllVendorsContractsCompletionSummary } from '@/lib/forms/vendor-completion-stats'; -import { Loader, Users, RefreshCw } from 'lucide-react'; -import { toast } from 'sonner'; - -interface VendorProgress { - vendorId: number; - vendorName: string; - totalForms: number; - tagCount: number; - totalRequiredFields: number; - totalFilledFields: number; - completionPercentage: number; -} - -export default function EDPProgressTestPage() { - const [loading, setLoading] = React.useState(false); - const [vendorProgress, setVendorProgress] = React.useState([]); - - const loadVendorProgress = async () => { - setLoading(true); - - try { - const result = await getAllVendorsContractsCompletionSummary(); - - if (result && result.vendors) { - const progressData: VendorProgress[] = result.vendors.map(vendor => ({ - vendorId: vendor.vendorId, - vendorName: vendor.vendorName, - totalForms: vendor.totalForms, - tagCount: vendor.totalTags, - totalRequiredFields: vendor.totalRequiredFields, - totalFilledFields: vendor.totalFilledFields, - completionPercentage: vendor.overallCompletionPercentage - })); - - setVendorProgress(progressData); - toast.success(`${progressData.length}개 벤더의 진척도를 불러왔습니다`); - } else { - toast.warning('벤더 데이터가 없습니다'); - } - } catch (error) { - console.error('Error loading vendor progress:', error); - toast.error(`벤더 진척도 로드 실패: ${error instanceof Error ? error.message : '알 수 없는 오류'}`); - } finally { - setLoading(false); - } - }; - - React.useEffect(() => { - loadVendorProgress(); - }, []); - - return ( -
-
-
- -

벤더 진척도 현황

-
- -
- - {/* Vendor Progress List */} - - - 벤더별 작업 진척도 - - - {loading ? ( -
- - 벤더 진척도를 불러오는 중... -
- ) : vendorProgress.length === 0 ? ( -
- 벤더 데이터가 없습니다. -
- ) : ( -
- {/* Header */} -
-
벤더명
-
폼 개수
-
태그 개수
-
전체 필드
-
입력 필드
-
완성도
-
- - {/* Vendor Rows */} - -
- {vendorProgress.map((vendor) => ( -
-
{vendor.vendorName}
-
{vendor.totalForms}
-
{vendor.tagCount}
-
{vendor.totalRequiredFields}
-
{vendor.totalFilledFields}
-
- = 80 ? "default" : - vendor.completionPercentage >= 50 ? "secondary" : - "destructive" - } - > - {vendor.completionPercentage}% - -
-
- ))} -
-
-
- )} -
-
-
- ); -} \ No newline at end of file diff --git a/app/[lng]/evcp/(evcp)/edp-progress/page.tsx b/app/[lng]/evcp/(evcp)/edp-progress/page.tsx index 12e14b98..7edc52c9 100644 --- a/app/[lng]/evcp/(evcp)/edp-progress/page.tsx +++ b/app/[lng]/evcp/(evcp)/edp-progress/page.tsx @@ -1,27 +1,12 @@ import * as React from "react" -import { type SearchParams } from "@/types/table" -import { getValidFilters } from "@/lib/data-table" import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton" -import { EDPProgressTable } from "@/lib/edp-progress/table/edp-progress-table" -import { getEDPProgressLists } from "@/lib/edp-progress/service" import { Shell } from "@/components/shell" import { InformationButton } from "@/components/information/information-button" -import { searchParamsCache } from "@/lib/edp-progress/validations" +import { VendorFormStatusTable } from "@/components/form-data-stat/form-data-stat-table" -interface IndexPageProps { - searchParams: Promise -} - -export default async function IndexPage(props: IndexPageProps) { - const searchParams = await props.searchParams - const search = searchParamsCache.parse(searchParams) - - const validFilters = getValidFilters(search.filters) - const promises = Promise.all([ - getEDPProgressLists({ filters: validFilters, sort: search.sort, search: search.search, joinOperator: search.joinOperator as any }), - ]) +export default async function IndexPage() { return ( @@ -43,7 +28,7 @@ export default async function IndexPage(props: IndexPageProps) { /> } > - + ) -- cgit v1.2.3