feat(WEB): 전체 페이지 ?mode= URL 네비게이션 패턴 적용

- 등록(?mode=new), 상세(?mode=view), 수정(?mode=edit) URL 패턴 일괄 적용
- 중복 패턴 제거: /edit?mode=edit → ?mode=edit (16개 파일)
- 제목 일관성: {기능} 등록/상세/수정 패턴 적용
- 검수 체크리스트 문서 추가 (79개 페이지)
- UniversalListPage, IntegratedDetailTemplate 공통 컴포넌트 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-01-25 12:27:43 +09:00
parent 72f1accbe4
commit f6551c7e8b
162 changed files with 2907 additions and 480 deletions

View File

@@ -11,9 +11,8 @@
* - 삭제 기능 (deleteConfirmMessage로 AlertDialog 대체)
*/
import { useState, useMemo, useCallback, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { Zap, Pencil, Trash2, FileText, CheckCircle, Clock } from 'lucide-react';
import { useState, useMemo, useEffect } from 'react';
import { Zap, Trash2, FileText, CheckCircle, Clock } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { TableCell, TableRow } from '@/components/ui/table';
import { Checkbox } from '@/components/ui/checkbox';
@@ -80,8 +79,6 @@ export default function UtilityManagementListClient({
initialData = [],
initialStats,
}: UtilityManagementListClientProps) {
const router = useRouter();
// ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
const [activeStatTab, setActiveStatTab] = useState<'all' | 'waiting' | 'complete'>('all');
const [startDate, setStartDate] = useState<string>('');
@@ -99,21 +96,6 @@ export default function UtilityManagementListClient({
}
}, [initialStats]);
// ===== 핸들러 =====
const handleRowClick = useCallback(
(item: Utility) => {
router.push(`/ko/construction/project/utility-management/${item.id}`);
},
[router]
);
const handleEdit = useCallback(
(item: Utility) => {
router.push(`/ko/construction/project/utility-management/${item.id}/edit`);
},
[router]
);
// ===== UniversalListPage Config =====
const config: UniversalListConfig<Utility> = useMemo(
() => ({
@@ -349,10 +331,9 @@ export default function UtilityManagementListClient({
) => (
<TableRow
key={item.id}
className="cursor-pointer hover:bg-muted/50"
onClick={() => handleRowClick(item)}
className="hover:bg-muted/50"
>
<TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
<TableCell className="text-center">
<Checkbox checked={handlers.isSelected} onCheckedChange={handlers.onToggle} />
</TableCell>
<TableCell className="text-center text-muted-foreground">{globalIndex}</TableCell>
@@ -372,30 +353,14 @@ export default function UtilityManagementListClient({
</TableCell>
<TableCell className="text-center">
{handlers.isSelected && (
<div className="flex items-center justify-center gap-1">
<Button
variant="ghost"
size="icon"
className="h-8 w-8"
onClick={(e) => {
e.stopPropagation();
handleEdit(item);
}}
>
<Pencil className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-destructive hover:text-destructive"
onClick={(e) => {
e.stopPropagation();
handlers.onDelete?.(item);
}}
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-destructive hover:text-destructive"
onClick={() => handlers.onDelete?.(item)}
>
<Trash2 className="h-4 w-4" />
</Button>
)}
</TableCell>
</TableRow>
@@ -416,7 +381,6 @@ export default function UtilityManagementListClient({
badgeVariant="secondary"
isSelected={handlers.isSelected}
onToggle={handlers.onToggle}
onClick={() => handleRowClick(item)}
details={[
{ label: '거래처', value: item.partnerName },
{ label: '공사PM', value: item.constructionPM },
@@ -425,7 +389,7 @@ export default function UtilityManagementListClient({
/>
),
}),
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
[startDate, endDate, activeStatTab, stats]
);
return <UniversalListPage config={config} initialData={initialData} />;