From b54f6f03150dd78d86db62201b6386bf14b72394 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 15 Oct 2025 12:52:11 +0000 Subject: (대표님) 커버, 데이터룸, 파일매니저, 담당자할당 등 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/form-data/form-data-table.tsx | 190 ++++++++++++++++++++++++------- 1 file changed, 148 insertions(+), 42 deletions(-) (limited to 'components/form-data') diff --git a/components/form-data/form-data-table.tsx b/components/form-data/form-data-table.tsx index d5d79735..9dbcb627 100644 --- a/components/form-data/form-data-table.tsx +++ b/components/form-data/form-data-table.tsx @@ -19,7 +19,7 @@ import { Upload, Plus, Tag, - TagsIcon, + TagsIcon, FileOutput, Clipboard, Send, @@ -115,7 +115,97 @@ export default function DynamicTable({ const [formStats, setFormStats] = React.useState(null); const [isLoadingStats, setIsLoadingStats] = React.useState(true); + const [activeFilter, setActiveFilter] = React.useState(null); + const [filteredTableData, setFilteredTableData] = React.useState(tableData); + // 필터링 로직 + React.useEffect(() => { + if (!activeFilter) { + setFilteredTableData(tableData); + return; + } + + const today = new Date(); + today.setHours(0, 0, 0, 0); + const sevenDaysLater = new Date(today); + sevenDaysLater.setDate(sevenDaysLater.getDate() + 7); + + let filtered = [...tableData]; + + switch (activeFilter) { + case 'completed': + // 모든 필수 필드가 완료된 태그만 표시 + filtered = tableData.filter(item => { + const tagEditableFields = editableFieldsMap.get(item.TAG_NO) || []; + return columnsJSON + .filter(col => (col.shi === 'IN' || col.shi === 'BOTH') && tagEditableFields.includes(col.key)) + .every(col => { + const value = item[col.key]; + return value !== undefined && value !== null && value !== ''; + }); + }); + break; + + case 'remaining': + // 미완료 필드가 있는 태그만 표시 + filtered = tableData.filter(item => { + const tagEditableFields = editableFieldsMap.get(item.TAG_NO) || []; + return columnsJSON + .filter(col => (col.shi === 'IN' || col.shi === 'BOTH') && tagEditableFields.includes(col.key)) + .some(col => { + const value = item[col.key]; + return value === undefined || value === null || value === ''; + }); + }); + break; + + case 'upcoming': + // 7일 이내 임박한 태그만 표시 + filtered = tableData.filter(item => { + const dueDate = item.DUE_DATE; + if (!dueDate) return false; + + const target = new Date(dueDate); + target.setHours(0, 0, 0, 0); + + // 미완료이면서 7일 이내인 경우 + const hasIncompleteFields = columnsJSON + .filter(col => col.shi === 'IN' || col.shi === 'BOTH') + .some(col => !item[col.key]); + + return hasIncompleteFields && target >= today && target <= sevenDaysLater; + }); + break; + + case 'overdue': + // 지연된 태그만 표시 + filtered = tableData.filter(item => { + const dueDate = item.DUE_DATE; + if (!dueDate) return false; + + const target = new Date(dueDate); + target.setHours(0, 0, 0, 0); + + // 미완료이면서 지연된 경우 + const hasIncompleteFields = columnsJSON + .filter(col => col.shi === 'IN' || col.shi === 'BOTH') + .some(col => !item[col.key]); + + return hasIncompleteFields && target < today; + }); + break; + + default: + filtered = tableData; + } + + setFilteredTableData(filtered); + }, [activeFilter, tableData, columnsJSON, editableFieldsMap]); + + // 카드 클릭 핸들러 + const handleCardClick = (filterType: string | null) => { + setActiveFilter(prev => prev === filterType ? null : filterType); + }; React.useEffect(() => { const fetchFormStats = async () => { @@ -310,7 +400,7 @@ export default function DynamicTable({ isArray: Array.isArray(templateResult), data: templateResult }); - + if (Array.isArray(templateResult)) { templateResult.forEach((tmpl, idx) => { console.log(` [${idx}] TMPL_ID: ${tmpl?.TMPL_ID || 'MISSING'}, NAME: ${tmpl?.NAME || 'N/A'}, TYPE: ${tmpl?.TMPL_TYPE || 'N/A'}`); @@ -687,11 +777,15 @@ export default function DynamicTable({ return ( <> - +
- {/* Tag Count */} - + {/* Total Tags Card - 클릭 시 전체 보기 */} + handleCardClick(null)} + > Total Tags @@ -707,35 +801,17 @@ export default function DynamicTable({ )}

- Total Tag Count + {activeFilter === null ? 'Showing all' : 'Click to show all'}

- {/* Completion Rate */} - - - - Completion - - - - -
- {isLoadingStats ? ( - - - ) : ( - `${formStats?.completionRate || 0}%` - )} -
-

- {formStats ? `${formStats.completedFields} / ${formStats.totalFields}` : '-'} -

-
-
- - {/* Completed Fields */} - + {/* Completed Fields Card */} + handleCardClick('completed')} + > Completed @@ -751,13 +827,17 @@ export default function DynamicTable({ )}

- Completed Fields + {activeFilter === 'completed' ? 'Filtering active' : 'Click to filter'}

- {/* Remaining Fields */} - + {/* Remaining Fields Card */} + handleCardClick('remaining')} + > Remaining @@ -773,13 +853,17 @@ export default function DynamicTable({ )}

- Remaining Fields + {activeFilter === 'remaining' ? 'Filtering active' : 'Click to filter'}

- {/* Upcoming (7 days) */} - + {/* Upcoming Card */} + handleCardClick('upcoming')} + > Upcoming @@ -795,13 +879,17 @@ export default function DynamicTable({ )}

- Due in 7 Days + {activeFilter === 'upcoming' ? 'Filtering active' : 'Click to filter'}

- {/* Overdue */} - + {/* Overdue Card */} + handleCardClick('overdue')} + > Overdue @@ -817,22 +905,40 @@ export default function DynamicTable({ )}

- Overdue + {activeFilter === 'overdue' ? 'Filtering active' : 'Click to filter'}

- + + {/* 필터 상태 표시 */} + {activeFilter && ( +
+ + Filter: {activeFilter === 'completed' ? 'Completed' : + activeFilter === 'remaining' ? 'Remaining' : + activeFilter === 'upcoming' ? 'Upcoming (7 days)' : + activeFilter === 'overdue' ? 'Overdue' : 'All'} + + +
+ )} {/* 선택된 항목 수 표시 (선택된 항목이 있을 때만) */} {selectedRowCount > 0 && (