Files
sam-react-prod/src/components/business/construction/estimates/sections/EstimateSummarySection.tsx
byeongcheolryu 387672b5b2 refactor(WEB): URL 경로 juil → construction 변경
- /juil/ 경로를 /construction/으로 변경
- 컴포넌트 폴더명 juil → construction 변경
- 컴포넌트명 Juil* → Construction* 변경
- 테스트 URL 페이지 경로 업데이트
- claudedocs 문서 경로 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-08 17:13:22 +09:00

183 lines
7.3 KiB
TypeScript

'use client';
import React from 'react';
import { Plus, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import type { EstimateSummaryItem } from '../types';
import { formatAmount } from '../utils';
interface EstimateSummarySectionProps {
summaryItems: EstimateSummaryItem[];
summaryMemo: string;
isViewMode: boolean;
onAddItem: () => void;
onRemoveItem: (id: string) => void;
onItemChange: (id: string, field: keyof EstimateSummaryItem, value: string | number) => void;
onMemoChange: (memo: string) => void;
}
export function EstimateSummarySection({
summaryItems,
summaryMemo,
isViewMode,
onAddItem,
onRemoveItem,
onItemChange,
onMemoChange,
}: EstimateSummarySectionProps) {
return (
<Card>
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle className="text-lg"> </CardTitle>
{!isViewMode && (
<Button type="button" variant="outline" size="sm" onClick={onAddItem}>
<Plus className="h-4 w-4 mr-1" />
</Button>
)}
</CardHeader>
<CardContent>
<div className="overflow-x-auto">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[200px]"></TableHead>
<TableHead className="w-[80px] text-center"></TableHead>
<TableHead className="w-[80px] text-center"></TableHead>
<TableHead className="w-[120px] text-right"></TableHead>
<TableHead className="w-[120px] text-right"></TableHead>
<TableHead className="w-[120px] text-right"></TableHead>
<TableHead className="w-[150px]"></TableHead>
{!isViewMode && <TableHead className="w-[60px] text-center"></TableHead>}
</TableRow>
</TableHeader>
<TableBody>
{summaryItems.length === 0 ? (
<TableRow>
<TableCell colSpan={isViewMode ? 7 : 8} className="text-center text-gray-500 py-8">
.
</TableCell>
</TableRow>
) : (
summaryItems.map((item) => (
<TableRow key={item.id}>
<TableCell>
<Input
value={item.name}
onChange={(e) => onItemChange(item.id, 'name', e.target.value)}
disabled={isViewMode}
className={isViewMode ? 'bg-gray-50' : 'bg-white'}
/>
</TableCell>
<TableCell>
<Input
type="number"
value={item.quantity}
onChange={(e) => onItemChange(item.id, 'quantity', Number(e.target.value))}
disabled={isViewMode}
className={`text-center ${isViewMode ? 'bg-gray-50' : 'bg-white'}`}
/>
</TableCell>
<TableCell>
<Input
value={item.unit}
onChange={(e) => onItemChange(item.id, 'unit', e.target.value)}
disabled={isViewMode}
className={`text-center ${isViewMode ? 'bg-gray-50' : 'bg-white'}`}
/>
</TableCell>
<TableCell>
<Input
type="number"
value={item.materialCost}
onChange={(e) => onItemChange(item.id, 'materialCost', Number(e.target.value))}
disabled={isViewMode}
className={`text-right ${isViewMode ? 'bg-gray-50' : 'bg-white'}`}
/>
</TableCell>
<TableCell>
<Input
type="number"
value={item.laborCost}
onChange={(e) => onItemChange(item.id, 'laborCost', Number(e.target.value))}
disabled={isViewMode}
className={`text-right ${isViewMode ? 'bg-gray-50' : 'bg-white'}`}
/>
</TableCell>
<TableCell className="text-right font-medium">
{formatAmount(item.totalCost)}
</TableCell>
<TableCell>
<Input
value={item.remarks}
onChange={(e) => onItemChange(item.id, 'remarks', e.target.value)}
disabled={isViewMode}
className={isViewMode ? 'bg-gray-50' : 'bg-white'}
/>
</TableCell>
{!isViewMode && (
<TableCell className="text-center">
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 text-red-500 hover:text-red-600"
onClick={() => onRemoveItem(item.id)}
>
<X className="h-4 w-4" />
</Button>
</TableCell>
)}
</TableRow>
))
)}
{/* 합계 행 */}
{summaryItems.length > 0 && (
<TableRow className="bg-gray-50 font-medium">
<TableCell colSpan={3} className="text-center">
</TableCell>
<TableCell className="text-right">
{formatAmount(summaryItems.reduce((sum, item) => sum + item.materialCost, 0))}
</TableCell>
<TableCell className="text-right">
{formatAmount(summaryItems.reduce((sum, item) => sum + item.laborCost, 0))}
</TableCell>
<TableCell className="text-right">
{formatAmount(summaryItems.reduce((sum, item) => sum + item.totalCost, 0))}
</TableCell>
<TableCell colSpan={isViewMode ? 1 : 2}></TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{/* 메모 입력 */}
<div className="mt-4 space-y-2">
<Label className="text-sm font-medium text-gray-700"></Label>
<Textarea
value={summaryMemo}
onChange={(e) => onMemoChange(e.target.value)}
placeholder="견적 관련 메모를 입력하세요"
disabled={isViewMode}
className={isViewMode ? 'bg-gray-50' : 'bg-white'}
rows={3}
/>
</div>
</CardContent>
</Card>
);
}