feat(WEB): Pretendard 폰트 적용 및 HR/회계 모바일 필터 마이그레이션
- Pretendard Variable 폰트 추가 및 전역 적용 - HR 모듈 모바일 필터 적용: - AttendanceManagement: MobileFilter 컴포넌트 적용 - EmployeeManagement: MobileFilter 컴포넌트 적용 - SalaryManagement: MobileFilter 컴포넌트 적용 - VacationManagement: MobileFilter 컴포넌트 적용 - 회계 모듈: - VendorManagement: MobileFilter 컴포넌트 적용 - 전자결재: - ReferenceBox: 모바일 UI 개선 - AuthenticatedLayout: 레이아웃 개선 - middleware: 설정 업데이트 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,17 +22,12 @@ import {
|
||||
AlertDialogTitle,
|
||||
} from '@/components/ui/alert-dialog';
|
||||
import { TableRow, TableCell } from '@/components/ui/table';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import {
|
||||
IntegratedListTemplateV2,
|
||||
type TableColumn,
|
||||
type StatCard,
|
||||
type FilterFieldConfig,
|
||||
type FilterValues,
|
||||
} from '@/components/templates/IntegratedListTemplateV2';
|
||||
import { ListMobileCard, InfoField } from '@/components/organisms/ListMobileCard';
|
||||
import type {
|
||||
@@ -370,80 +365,96 @@ export function VendorManagement({ initialData, initialTotal }: VendorManagement
|
||||
);
|
||||
}, [handleRowClick, handleEdit, handleDeleteClick]);
|
||||
|
||||
// ===== 테이블 헤더 액션 (5개 필터) =====
|
||||
const tableHeaderActions = (
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
{/* 구분 필터 */}
|
||||
<Select value={categoryFilter} onValueChange={setCategoryFilter}>
|
||||
<SelectTrigger className="w-[120px]">
|
||||
<SelectValue placeholder="구분" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{VENDOR_CATEGORY_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
// ===== filterConfig 방식 모바일 필터 =====
|
||||
const filterConfig: FilterFieldConfig[] = useMemo(() => [
|
||||
{
|
||||
key: 'category',
|
||||
label: '구분',
|
||||
type: 'single',
|
||||
options: VENDOR_CATEGORY_OPTIONS.filter(o => o.value !== 'all').map(o => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
})),
|
||||
allOptionLabel: '전체',
|
||||
},
|
||||
{
|
||||
key: 'creditRating',
|
||||
label: '신용등급',
|
||||
type: 'single',
|
||||
options: CREDIT_RATING_OPTIONS.filter(o => o.value !== 'all').map(o => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
})),
|
||||
allOptionLabel: '전체',
|
||||
},
|
||||
{
|
||||
key: 'transactionGrade',
|
||||
label: '거래등급',
|
||||
type: 'single',
|
||||
options: TRANSACTION_GRADE_OPTIONS.filter(o => o.value !== 'all').map(o => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
})),
|
||||
allOptionLabel: '전체',
|
||||
},
|
||||
{
|
||||
key: 'badDebt',
|
||||
label: '악성채권',
|
||||
type: 'single',
|
||||
options: BAD_DEBT_STATUS_OPTIONS.filter(o => o.value !== 'all').map(o => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
})),
|
||||
allOptionLabel: '전체',
|
||||
},
|
||||
{
|
||||
key: 'sort',
|
||||
label: '정렬',
|
||||
type: 'single',
|
||||
options: SORT_OPTIONS.map(o => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
})),
|
||||
},
|
||||
], []);
|
||||
|
||||
{/* 신용등급 필터 */}
|
||||
<Select value={creditRatingFilter} onValueChange={setCreditRatingFilter}>
|
||||
<SelectTrigger className="w-[110px]">
|
||||
<SelectValue placeholder="신용등급" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{CREDIT_RATING_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
const filterValues: FilterValues = useMemo(() => ({
|
||||
category: categoryFilter,
|
||||
creditRating: creditRatingFilter,
|
||||
transactionGrade: transactionGradeFilter,
|
||||
badDebt: badDebtFilter,
|
||||
sort: sortOption,
|
||||
}), [categoryFilter, creditRatingFilter, transactionGradeFilter, badDebtFilter, sortOption]);
|
||||
|
||||
{/* 거래등급 필터 */}
|
||||
<Select value={transactionGradeFilter} onValueChange={setTransactionGradeFilter}>
|
||||
<SelectTrigger className="w-[120px]">
|
||||
<SelectValue placeholder="거래등급" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TRANSACTION_GRADE_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
const handleFilterChange = useCallback((key: string, value: string | string[]) => {
|
||||
switch (key) {
|
||||
case 'category':
|
||||
setCategoryFilter(value as string);
|
||||
break;
|
||||
case 'creditRating':
|
||||
setCreditRatingFilter(value as string);
|
||||
break;
|
||||
case 'transactionGrade':
|
||||
setTransactionGradeFilter(value as string);
|
||||
break;
|
||||
case 'badDebt':
|
||||
setBadDebtFilter(value as string);
|
||||
break;
|
||||
case 'sort':
|
||||
setSortOption(value as SortOption);
|
||||
break;
|
||||
}
|
||||
setCurrentPage(1);
|
||||
}, []);
|
||||
|
||||
{/* 악성채권 필터 */}
|
||||
<Select value={badDebtFilter} onValueChange={setBadDebtFilter}>
|
||||
<SelectTrigger className="w-[110px]">
|
||||
<SelectValue placeholder="악성채권" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{BAD_DEBT_STATUS_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
{/* 정렬 */}
|
||||
<Select value={sortOption} onValueChange={(value) => setSortOption(value as SortOption)}>
|
||||
<SelectTrigger className="w-[150px]">
|
||||
<SelectValue placeholder="정렬" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{SORT_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
);
|
||||
const handleFilterReset = useCallback(() => {
|
||||
setCategoryFilter('all');
|
||||
setCreditRatingFilter('all');
|
||||
setTransactionGradeFilter('all');
|
||||
setBadDebtFilter('all');
|
||||
setSortOption('latest');
|
||||
setCurrentPage(1);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user