From e23f3383eb75e8033ab918e31a1e5f53446e13ca Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Wed, 3 Sep 2025 12:47:51 +0000 Subject: (임수민) EDP 폼 리스트의 벤더 입력 완성도 검증 서버액션 및 테스트 페이지 구현 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/[lng]/admin/edp-progress/page.tsx | 431 ++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 app/[lng]/admin/edp-progress/page.tsx (limited to 'app') diff --git a/app/[lng]/admin/edp-progress/page.tsx b/app/[lng]/admin/edp-progress/page.tsx new file mode 100644 index 00000000..4efb739c --- /dev/null +++ b/app/[lng]/admin/edp-progress/page.tsx @@ -0,0 +1,431 @@ +"use client"; + +import React from 'react'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, 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 { Separator } from '@/components/ui/separator'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { + calculateVendorFormCompletion, + getProjectVendorCompletionSummary, + calculateVendorContractCompletion, + getVendorAllContractsCompletionSummary, + getAllVendorsContractsCompletionSummary, + getAllProjectsVendorCompletionSummary, + type VendorFormCompletionStats, + type ProjectVendorCompletionSummary, + type VendorAllContractsCompletionSummary +} from '@/lib/forms/vendor-completion-stats'; +import { Loader, TestTube, BarChart, FileText, TrendingUp } from 'lucide-react'; +import { toast } from 'sonner'; + +interface TestResult { + type: string; + data: VendorFormCompletionStats | ProjectVendorCompletionSummary | VendorAllContractsCompletionSummary | unknown; +} + +export default function EDPProgressTestPage() { + const [loading, setLoading] = React.useState(null); + const [results, setResults] = React.useState(null); + + // Form inputs + const [contractItemId, setContractItemId] = React.useState('123'); + const [formCode, setFormCode] = React.useState('SPR_LST'); + const [projectId, setProjectId] = React.useState('1'); + const [vendorId, setVendorId] = React.useState('1'); + + const handleTest = async (testType: string, testFunction: () => Promise) => { + setLoading(testType); + setResults(null); + + try { + const result = await testFunction(); + setResults({ type: testType, data: result }); + + if (result) { + toast.success(`${testType} 테스트 완료`); + } else { + toast.warning(`${testType} 결과가 없습니다`); + } + } catch (error) { + console.error(`Error in ${testType}:`, error); + toast.error(`${testType} 테스트 실패: ${error instanceof Error ? error.message : '알 수 없는 오류'}`); + } finally { + setLoading(null); + } + }; + + const renderVendorFormStats = (stats: VendorFormCompletionStats) => ( +
+
+ + +
{stats.completionPercentage}%
+

완성도

+
+
+ + +
{stats.totalFilledFields}
+

입력된 필드

+
+
+ + +
{stats.totalRequiredFields}
+

총 필드

+
+
+ + +
{stats.tagCount}
+

태그 수

+
+
+
+ + + + 태그별 세부 현황 + + + +
+ {stats.detailsByTag.map((tag, index) => ( +
+ {tag.tagNo} +
+ = 80 ? "default" : tag.completionPercentage >= 50 ? "secondary" : "destructive"}> + {tag.completionPercentage}% + + + {tag.filledFields}/{tag.requiredFields} + +
+
+ ))} +
+
+
+
+
+ ); + + const renderProjectSummary = (summary: ProjectVendorCompletionSummary) => ( +
+
+ + +
{summary.averageCompletionPercentage}%
+

평균 완성도

+
+
+ + +
{summary.totalVendors}
+

참여 벤더

+
+
+ + +
{summary.projectCode}
+

프로젝트 코드

+
+
+
+ + + + 벤더별 완성도 + + + +
+ {summary.vendors.map((vendor, index) => ( +
+ {vendor.vendorName} + = 80 ? "default" : vendor.completionPercentage >= 50 ? "secondary" : "destructive"}> + {vendor.completionPercentage}% + +
+ ))} +
+
+
+
+
+ ); + + const renderVendorAllContracts = (summary: VendorAllContractsCompletionSummary) => ( +
+
+ + +
{summary.overallCompletionPercentage}%
+

전체 완성도

+
+
+ + +
{summary.totalContracts}
+

총 계약

+
+
+ + +
{summary.totalForms}
+

총 폼

+
+
+ + +
{summary.totalFilledFields}/{summary.totalRequiredFields}
+

입력 필드

+
+
+
+ +
+ + + 프로젝트별 분석 + + + +
+ {summary.projectBreakdown.map((project, index) => ( +
+
+
{project.projectName}
+
+ 계약 {project.contractsCount}개, 폼 {project.formsCount}개 +
+
+ = 80 ? "default" : "secondary"}> + {project.completionPercentage}% + +
+ ))} +
+
+
+
+ + + + 계약별 세부 현황 + + + +
+ {summary.contracts.map((contract, index) => ( +
+
+
{contract.itemName}
+
+ {contract.projectName} - 폼 {contract.totalForms}개 +
+
+ = 80 ? "default" : "secondary"}> + {contract.averageCompletionPercentage}% + +
+ ))} +
+
+
+
+
+
+ ); + + return ( +
+
+ +

EDP Progress 서버 액션 테스트

+
+ + {/* Input Parameters */} + + + + + 테스트 파라미터 + + + 아래 값들을 수정하여 다양한 시나리오를 테스트할 수 있습니다. + + + +
+
+ + setContractItemId(e.target.value)} + placeholder="123" + /> +
+
+ + setFormCode(e.target.value)} + placeholder="SPR_LST" + /> +
+
+ + setProjectId(e.target.value)} + placeholder="1" + /> +
+
+ + setVendorId(e.target.value)} + placeholder="1" + /> +
+
+
+
+ + {/* Test Buttons */} + + + + + 테스트 액션들 + + + +
+ + + + + + + + + + + +
+
+
+ + + + {/* Results */} + {results && ( + + + + + 테스트 결과: {results.type} + + + + {!results.data ? ( +
+ 데이터가 없습니다. 파라미터를 확인해주세요. +
+ ) : results.type === 'vendor-form' ? ( + renderVendorFormStats(results.data as VendorFormCompletionStats) + ) : results.type === 'project-summary' ? ( + renderProjectSummary(results.data as ProjectVendorCompletionSummary) + ) : results.type === 'vendor-all-contracts' ? ( + renderVendorAllContracts(results.data as VendorAllContractsCompletionSummary) + ) : ( +
+
+
+                    {JSON.stringify(results.data, null, 2)}
+                  
+
+
+ )} +
+
+ )} +
+ ); +} -- cgit v1.2.3