fix: [accounting] 경조사비 금액 입력 NumberInput → CurrencyInput 전환 + 리스트 리팩토링
This commit is contained in:
@@ -13,7 +13,7 @@ import { DatePicker } from '@/components/ui/date-picker';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { NumberInput } from '@/components/ui/number-input';
|
||||
import { CurrencyInput } from '@/components/ui/currency-input';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import {
|
||||
Select,
|
||||
@@ -253,11 +253,9 @@ export function CondolenceExpenseFormModal({
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>금액</Label>
|
||||
<NumberInput
|
||||
<CurrencyInput
|
||||
value={form.cash_amount}
|
||||
onChange={(v) => handleChange('cash_amount', v ?? 0)}
|
||||
min={0}
|
||||
useComma
|
||||
onChange={(v: number | undefined) => handleChange('cash_amount', v ?? 0)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -286,11 +284,9 @@ export function CondolenceExpenseFormModal({
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>금액</Label>
|
||||
<NumberInput
|
||||
<CurrencyInput
|
||||
value={form.gift_amount}
|
||||
onChange={(v) => handleChange('gift_amount', v ?? 0)}
|
||||
min={0}
|
||||
useComma
|
||||
onChange={(v: number | undefined) => handleChange('gift_amount', v ?? 0)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,37 +3,34 @@
|
||||
/**
|
||||
* 경조사비 관리 - 목록 페이지
|
||||
*
|
||||
* UniversalListPage + clientSideFiltering 패턴 (품목관리와 동일)
|
||||
* - 통계카드 (총건수/총금액/부조금합계/선물합계)
|
||||
* - 필터: 연도 Select, 구분 Select, 검색 Input
|
||||
* - 테이블 13컬럼 + 하단 합계행
|
||||
* - 등록/수정 모달 (Dialog)
|
||||
* - 필터: 연도 Select, 구분 filterConfig, 검색 (클라이언트 사이드)
|
||||
* - 테이블 + 등록/수정 모달
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import {
|
||||
Heart,
|
||||
DollarSign,
|
||||
Banknote,
|
||||
Gift,
|
||||
Plus,
|
||||
Edit,
|
||||
Trash2,
|
||||
Loader2,
|
||||
} from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { BadgeSm } from '@/components/atoms/BadgeSm';
|
||||
import {
|
||||
IntegratedListTemplateV2,
|
||||
UniversalListPage,
|
||||
type UniversalListConfig,
|
||||
type TableColumn,
|
||||
type FilterFieldConfig,
|
||||
type FilterValues,
|
||||
} from '@/components/templates/IntegratedListTemplateV2';
|
||||
import { useColumnSettings } from '@/hooks/useColumnSettings';
|
||||
import { ColumnSettingsPopover } from '@/components/molecules/ColumnSettingsPopover';
|
||||
} from '@/components/templates/UniversalListPage';
|
||||
import { toast } from 'sonner';
|
||||
import { TableRow, TableCell } from '@/components/ui/table';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { MobileCard, InfoField } from '@/components/organisms/MobileCard';
|
||||
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
|
||||
import { formatAmount } from '@/lib/utils/amount';
|
||||
@@ -48,7 +45,6 @@ import {
|
||||
CATEGORY_OPTIONS,
|
||||
type CondolenceExpense,
|
||||
type CondolenceExpenseSummary,
|
||||
type CondolenceCategory,
|
||||
} from './types';
|
||||
|
||||
// 연도 옵션 (당해 ~ 5년 전)
|
||||
@@ -60,12 +56,14 @@ function getYearOptions() {
|
||||
}));
|
||||
}
|
||||
|
||||
const TABLE_COLUMNS: TableColumn[] = [
|
||||
const BASE_PATH = '/accounting/condolence-expenses';
|
||||
|
||||
const tableColumns: TableColumn[] = [
|
||||
{ key: 'no', label: '번호', className: 'text-center w-[50px]' },
|
||||
{ key: 'event_date', label: '경조사일자', className: 'px-2 w-[100px]' },
|
||||
{ key: 'expense_date', label: '지출일자', className: 'px-2 w-[100px]' },
|
||||
{ key: 'partner_name', label: '거래처명', className: 'px-2' },
|
||||
{ key: 'description', label: '내역', className: 'px-2' },
|
||||
{ key: 'event_date', label: '경조사일자', className: 'px-2 w-[100px]', sortable: true, copyable: true },
|
||||
{ key: 'expense_date', label: '지출일자', className: 'px-2 w-[100px]', copyable: true },
|
||||
{ key: 'partner_name', label: '거래처명', className: 'px-2', sortable: true, copyable: true },
|
||||
{ key: 'description', label: '내역', className: 'px-2', copyable: true },
|
||||
{ key: 'category', label: '구분', className: 'px-2 text-center w-[70px]' },
|
||||
{ key: 'has_cash', label: '부조금', className: 'px-2 text-center w-[60px]' },
|
||||
{ key: 'cash_method', label: '지출방법', className: 'px-2 w-[80px]' },
|
||||
@@ -75,33 +73,28 @@ const TABLE_COLUMNS: TableColumn[] = [
|
||||
{ key: 'gift_amount', label: '선물금액', className: 'px-2 text-right w-[100px]' },
|
||||
{ key: 'total_amount', label: '총금액', className: 'px-2 text-right w-[100px]' },
|
||||
{ key: 'memo', label: '비고', className: 'px-2' },
|
||||
{ key: 'actions', label: '작업', className: 'text-center w-[60px]' },
|
||||
];
|
||||
|
||||
export function CondolenceExpenseList() {
|
||||
// 필터 상태
|
||||
const router = useRouter();
|
||||
|
||||
// 연도 필터
|
||||
const [year, setYear] = useState<string>(String(new Date().getFullYear()));
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const itemsPerPage = 50;
|
||||
|
||||
// 필터 (filterConfig)
|
||||
const [filterCategory, setFilterCategory] = useState('all');
|
||||
const [filterValues, setFilterValues] = useState<Record<string, string | string[]>>({
|
||||
category: 'all',
|
||||
});
|
||||
|
||||
const filterConfig: FilterFieldConfig[] = useMemo(() => [
|
||||
const filterConfig: FilterFieldConfig[] = [
|
||||
{
|
||||
key: 'category',
|
||||
label: '구분',
|
||||
type: 'single' as const,
|
||||
type: 'single',
|
||||
options: CATEGORY_OPTIONS.map((o) => ({ value: o.value, label: o.label })),
|
||||
allOptionLabel: '전체 구분',
|
||||
},
|
||||
], []);
|
||||
|
||||
const filterValues: FilterValues = useMemo(() => ({
|
||||
category: filterCategory,
|
||||
}), [filterCategory]);
|
||||
];
|
||||
|
||||
// 모달 상태
|
||||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||||
@@ -116,44 +109,29 @@ export function CondolenceExpenseList() {
|
||||
const [data, setData] = useState<CondolenceExpense[]>([]);
|
||||
const [summaryData, setSummaryData] = useState<CondolenceExpenseSummary | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [totalCount, setTotalCount] = useState(0);
|
||||
|
||||
// 컬럼 설정
|
||||
const {
|
||||
visibleColumns,
|
||||
allColumnsWithVisibility,
|
||||
columnWidths,
|
||||
setColumnWidth,
|
||||
toggleColumnVisibility,
|
||||
resetSettings,
|
||||
hasHiddenColumns,
|
||||
} = useColumnSettings({
|
||||
pageId: 'condolence-expenses',
|
||||
columns: TABLE_COLUMNS,
|
||||
alwaysVisibleKeys: ['no', 'partner_name', 'total_amount', 'actions'],
|
||||
});
|
||||
// 선택
|
||||
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
|
||||
|
||||
// 데이터 로드
|
||||
const loadData = useCallback(async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const categoryFilter = filterValues.category as string;
|
||||
const [listResult, summaryResult] = await Promise.all([
|
||||
getCondolenceExpenses({
|
||||
year: year ? Number(year) : undefined,
|
||||
category: filterCategory !== 'all' ? filterCategory : undefined,
|
||||
search: searchTerm || undefined,
|
||||
per_page: itemsPerPage,
|
||||
page: currentPage,
|
||||
category: categoryFilter !== 'all' ? categoryFilter : undefined,
|
||||
per_page: 200,
|
||||
}),
|
||||
getCondolenceExpenseSummary({
|
||||
year: year ? Number(year) : undefined,
|
||||
category: filterCategory !== 'all' ? filterCategory : undefined,
|
||||
category: categoryFilter !== 'all' ? categoryFilter : undefined,
|
||||
}),
|
||||
]);
|
||||
|
||||
if (listResult.success) {
|
||||
setData(listResult.data);
|
||||
setTotalCount(listResult.pagination?.total ?? 0);
|
||||
} else {
|
||||
toast.error(listResult.error || '목록 조회 실패');
|
||||
}
|
||||
@@ -166,7 +144,7 @@ export function CondolenceExpenseList() {
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [year, filterCategory, searchTerm, currentPage]);
|
||||
}, [year, filterValues]);
|
||||
|
||||
useEffect(() => { loadData(); }, [loadData]);
|
||||
|
||||
@@ -181,13 +159,6 @@ export function CondolenceExpenseList() {
|
||||
];
|
||||
}, [summaryData]);
|
||||
|
||||
// 하단 합계
|
||||
const totals = useMemo(() => ({
|
||||
cash: data.reduce((sum, d) => sum + (d.cash_amount || 0), 0),
|
||||
gift: data.reduce((sum, d) => sum + (d.gift_amount || 0), 0),
|
||||
total: data.reduce((sum, d) => sum + (d.total_amount || 0), 0),
|
||||
}), [data]);
|
||||
|
||||
// 핸들러
|
||||
const handleCreate = () => { setEditingItem(null); setIsFormOpen(true); };
|
||||
const handleEdit = (item: CondolenceExpense) => { setEditingItem(item); setIsFormOpen(true); };
|
||||
@@ -219,34 +190,39 @@ export function CondolenceExpenseList() {
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 선택
|
||||
const toggleSelection = useCallback((id: string) => {
|
||||
setSelectedItems(prev => {
|
||||
const next = new Set(prev);
|
||||
next.has(id) ? next.delete(id) : next.add(id);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
// 선택 핸들러
|
||||
const toggleSelection = (id: string) => {
|
||||
const next = new Set(selectedItems);
|
||||
next.has(id) ? next.delete(id) : next.add(id);
|
||||
setSelectedItems(next);
|
||||
};
|
||||
|
||||
const toggleSelectAll = useCallback(() => {
|
||||
setSelectedItems(prev =>
|
||||
prev.size === data.length ? new Set() : new Set(data.map(d => String(d.id)))
|
||||
);
|
||||
}, [data]);
|
||||
const toggleSelectAll = () => {
|
||||
if (selectedItems.size === data.length && data.length > 0) {
|
||||
setSelectedItems(new Set());
|
||||
} else {
|
||||
setSelectedItems(new Set(data.map((d) => String(d.id))));
|
||||
}
|
||||
};
|
||||
|
||||
// 테이블 행
|
||||
const renderTableRow = useCallback((
|
||||
const renderTableRow = (
|
||||
item: CondolenceExpense,
|
||||
_index: number,
|
||||
globalIndex: number,
|
||||
handlers: { isSelected: boolean; onToggle: () => void }
|
||||
) => {
|
||||
const { isSelected, onToggle } = handlers;
|
||||
const badge = CATEGORY_BADGE[item.category];
|
||||
return (
|
||||
<TableRow
|
||||
key={item.id}
|
||||
className="cursor-pointer hover:bg-muted/50"
|
||||
className={`cursor-pointer hover:bg-muted/50 ${isSelected ? 'bg-blue-50' : ''}`}
|
||||
onClick={() => handleEdit(item)}
|
||||
>
|
||||
<TableCell onClick={(e) => e.stopPropagation()} className="text-center">
|
||||
<Checkbox checked={isSelected} onCheckedChange={onToggle} />
|
||||
</TableCell>
|
||||
<TableCell className="text-center">{globalIndex}</TableCell>
|
||||
<TableCell>{item.event_date || '-'}</TableCell>
|
||||
<TableCell>{item.expense_date || '-'}</TableCell>
|
||||
@@ -263,59 +239,138 @@ export function CondolenceExpenseList() {
|
||||
<TableCell className="text-right">{item.has_gift ? formatAmount(item.gift_amount) : '-'}</TableCell>
|
||||
<TableCell className="text-right font-bold">{formatAmount(item.total_amount)}</TableCell>
|
||||
<TableCell className="max-w-[100px] truncate">{item.memo || '-'}</TableCell>
|
||||
<TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 text-red-500 hover:text-red-700"
|
||||
onClick={() => handleDelete(item.id)}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}, []);
|
||||
};
|
||||
|
||||
// 모바일 카드
|
||||
const renderMobileCard = useCallback((
|
||||
const renderMobileCard = (
|
||||
item: CondolenceExpense,
|
||||
_index: number,
|
||||
globalIndex: number,
|
||||
handlers: { isSelected: boolean; onToggle: () => void }
|
||||
) => {
|
||||
const { isSelected, onToggle } = handlers;
|
||||
const badge = CATEGORY_BADGE[item.category];
|
||||
return (
|
||||
<MobileCard
|
||||
<ListMobileCard
|
||||
key={item.id}
|
||||
title={item.partner_name}
|
||||
subtitle={item.description || '-'}
|
||||
id={String(item.id)}
|
||||
isSelected={isSelected}
|
||||
onToggleSelection={onToggle}
|
||||
onCardClick={() => handleEdit(item)}
|
||||
headerBadges={
|
||||
<BadgeSm className={badge.className}>{badge.label}</BadgeSm>
|
||||
}
|
||||
title={item.partner_name}
|
||||
statusBadge={
|
||||
<span className="text-sm font-bold text-blue-700">{formatAmount(item.total_amount)}</span>
|
||||
}
|
||||
infoGrid={
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-3">
|
||||
<InfoField label="경조사일" value={item.event_date || '-'} />
|
||||
<InfoField label="총금액" value={formatAmount(item.total_amount)} valueClassName="font-bold text-blue-700" />
|
||||
<InfoField label="내역" value={item.description || '-'} />
|
||||
<InfoField label="부조금" value={item.has_cash ? formatAmount(item.cash_amount) : '-'} />
|
||||
<InfoField label="선물" value={item.has_gift ? `${item.gift_type} ${formatAmount(item.gift_amount)}` : '-'} />
|
||||
</div>
|
||||
}
|
||||
onClick={() => handleEdit(item)}
|
||||
/>
|
||||
);
|
||||
}, []);
|
||||
};
|
||||
|
||||
// 합계 표시 (tableHeaderActions에 인라인)
|
||||
const summaryText = useMemo(() => {
|
||||
if (data.length === 0) return null;
|
||||
return (
|
||||
<div className="flex items-center gap-3 text-sm text-muted-foreground">
|
||||
<span>부조금 <strong className="text-foreground">{formatAmount(totals.cash)}</strong></span>
|
||||
<span>선물 <strong className="text-foreground">{formatAmount(totals.gift)}</strong></span>
|
||||
<span>합계 <strong className="text-blue-700">{formatAmount(totals.total)}</strong></span>
|
||||
</div>
|
||||
);
|
||||
}, [data.length, totals]);
|
||||
// UniversalListPage config
|
||||
const config: UniversalListConfig<CondolenceExpense> = {
|
||||
title: '경조사비 관리',
|
||||
description: '거래처/임직원 경조사비 관리',
|
||||
icon: Heart,
|
||||
basePath: BASE_PATH,
|
||||
idField: 'id',
|
||||
|
||||
actions: {
|
||||
getList: async () => ({
|
||||
success: true,
|
||||
data,
|
||||
totalCount: data.length,
|
||||
}),
|
||||
deleteItem: async (id) => {
|
||||
const result = await deleteCondolenceExpense(id);
|
||||
if (result.success) loadData();
|
||||
return result;
|
||||
},
|
||||
},
|
||||
|
||||
columns: tableColumns,
|
||||
|
||||
computeStats: () => stats,
|
||||
|
||||
searchPlaceholder: '거래처명, 내역, 비고 검색...',
|
||||
|
||||
// 연도 Select
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
hideDateInputs: true,
|
||||
showPresets: false,
|
||||
extraActions: (
|
||||
<Select value={year} onValueChange={(v) => { setYear(v); }}>
|
||||
<SelectTrigger className="w-[120px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{getYearOptions().map((o) => (
|
||||
<SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
|
||||
itemsPerPage: 50,
|
||||
|
||||
// 클라이언트 사이드 필터링 (검색 깜빡임 없음)
|
||||
clientSideFiltering: true,
|
||||
|
||||
searchFilter: (item, searchValue) => {
|
||||
const q = searchValue.toLowerCase();
|
||||
return (
|
||||
(item.partner_name || '').toLowerCase().includes(q) ||
|
||||
(item.description || '').toLowerCase().includes(q) ||
|
||||
(item.memo || '').toLowerCase().includes(q)
|
||||
);
|
||||
},
|
||||
|
||||
// 구분 필터
|
||||
filterConfig,
|
||||
initialFilters: filterValues,
|
||||
filterTitle: '경조사비 필터',
|
||||
|
||||
customFilterFn: (items, fv) => {
|
||||
const cat = fv.category as string;
|
||||
if (!cat || cat === 'all') return items;
|
||||
return items.filter((item) => item.category === cat);
|
||||
},
|
||||
|
||||
// 등록 버튼
|
||||
headerActions: () => (
|
||||
<Button onClick={handleCreate}>
|
||||
<Heart className="w-4 h-4 mr-2" />
|
||||
등록
|
||||
</Button>
|
||||
),
|
||||
|
||||
renderTableRow,
|
||||
renderMobileCard,
|
||||
|
||||
renderDialogs: () => (
|
||||
<DeleteConfirmDialog
|
||||
open={isDeleteDialogOpen}
|
||||
onOpenChange={setIsDeleteDialogOpen}
|
||||
onConfirm={handleConfirmDelete}
|
||||
title="경조사비 삭제"
|
||||
description="이 경조사비 항목을 삭제하시겠습니까?"
|
||||
loading={isDeleting}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -330,88 +385,20 @@ export function CondolenceExpenseList() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<IntegratedListTemplateV2<CondolenceExpense>
|
||||
// 헤더
|
||||
title="경조사비 관리"
|
||||
description="거래처/임직원 경조사비 관리"
|
||||
icon={Heart}
|
||||
|
||||
// 연도 선택 (dateRangeSelector 대신 extraActions 사용)
|
||||
dateRangeSelector={{
|
||||
enabled: true,
|
||||
hideDateInputs: true,
|
||||
showPresets: false,
|
||||
extraActions: (
|
||||
<Select value={year} onValueChange={(v) => { setYear(v); setCurrentPage(1); }}>
|
||||
<SelectTrigger className="w-[120px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{getYearOptions().map((o) => (
|
||||
<SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
),
|
||||
<UniversalListPage<CondolenceExpense>
|
||||
config={config}
|
||||
initialData={data}
|
||||
initialTotalCount={data.length}
|
||||
externalSelection={{
|
||||
selectedItems,
|
||||
onToggleSelection: toggleSelection,
|
||||
onToggleSelectAll: toggleSelectAll,
|
||||
setSelectedItems,
|
||||
getItemId: (item) => String(item.id),
|
||||
}}
|
||||
|
||||
// 검색
|
||||
searchValue={searchTerm}
|
||||
onSearchChange={(q) => { setSearchTerm(q); setCurrentPage(1); }}
|
||||
searchPlaceholder="거래처명, 내역, 비고 검색..."
|
||||
|
||||
// 등록 버튼
|
||||
createButton={{ label: '등록', onClick: handleCreate }}
|
||||
|
||||
// 통계
|
||||
stats={stats}
|
||||
|
||||
// 필터
|
||||
filterConfig={filterConfig}
|
||||
filterValues={filterValues}
|
||||
onFilterChange={(key, value) => {
|
||||
if (key === 'category') { setFilterCategory(value as string); setCurrentPage(1); }
|
||||
onFilterChange={(newFilters) => {
|
||||
setFilterValues(newFilters);
|
||||
}}
|
||||
onFilterReset={() => { setFilterCategory('all'); setCurrentPage(1); }}
|
||||
filterTitle="경조사비 필터"
|
||||
|
||||
// 테이블 + 컬럼 설정
|
||||
tableColumns={visibleColumns}
|
||||
columnSettings={{
|
||||
columnWidths,
|
||||
onColumnResize: setColumnWidth,
|
||||
settingsPopover: (
|
||||
<ColumnSettingsPopover
|
||||
columns={allColumnsWithVisibility}
|
||||
onToggle={toggleColumnVisibility}
|
||||
onReset={resetSettings}
|
||||
hasHiddenColumns={hasHiddenColumns}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
|
||||
// 데이터
|
||||
data={data}
|
||||
selectedItems={selectedItems}
|
||||
onToggleSelection={toggleSelection}
|
||||
onToggleSelectAll={toggleSelectAll}
|
||||
getItemId={(item) => String(item.id)}
|
||||
|
||||
// 렌더링
|
||||
renderTableRow={renderTableRow}
|
||||
renderMobileCard={renderMobileCard}
|
||||
tableHeaderActions={summaryText}
|
||||
|
||||
// 페이지네이션
|
||||
pagination={{
|
||||
currentPage,
|
||||
totalPages: Math.ceil(totalCount / itemsPerPage),
|
||||
totalItems: totalCount,
|
||||
itemsPerPage,
|
||||
onPageChange: setCurrentPage,
|
||||
}}
|
||||
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
|
||||
{/* 등록/수정 모달 */}
|
||||
@@ -421,16 +408,6 @@ export function CondolenceExpenseList() {
|
||||
editItem={editingItem}
|
||||
onSuccess={handleFormSuccess}
|
||||
/>
|
||||
|
||||
{/* 삭제 확인 */}
|
||||
<DeleteConfirmDialog
|
||||
open={isDeleteDialogOpen}
|
||||
onOpenChange={setIsDeleteDialogOpen}
|
||||
onConfirm={handleConfirmDelete}
|
||||
title="경조사비 삭제"
|
||||
description="이 경조사비 항목을 삭제하시겠습니까?"
|
||||
loading={isDeleting}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user