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:
byeongcheolryu
2026-01-14 13:46:56 +09:00
parent ea8d701a8d
commit b08366c3f7
14 changed files with 881 additions and 239 deletions

View File

@@ -20,18 +20,13 @@ import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import { TableRow, TableCell } from '@/components/ui/table';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import {
IntegratedListTemplateV2,
type TableColumn,
type StatCard,
type TabOption,
type FilterFieldConfig,
type FilterValues,
} from '@/components/templates/IntegratedListTemplateV2';
import { ListMobileCard, InfoField } from '@/components/organisms/ListMobileCard';
import { SalaryDetailDialog } from './SalaryDetailDialog';
@@ -451,19 +446,36 @@ export function SalaryManagement() {
</div>
);
// ===== 정렬 필터 =====
const extraFilters = (
<Select value={sortOption} onValueChange={(v) => setSortOption(v as SortOption)}>
<SelectTrigger className="w-[120px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
{Object.entries(SORT_OPTIONS).map(([key, label]) => (
<SelectItem key={key} value={key}>{label}</SelectItem>
))}
</SelectContent>
</Select>
);
// ===== filterConfig 기반 통합 필터 시스템 =====
const filterConfig: FilterFieldConfig[] = useMemo(() => [
{
key: 'sort',
label: '정렬',
type: 'single',
options: Object.entries(SORT_OPTIONS).map(([value, label]) => ({
value,
label,
})),
},
], []);
const filterValues: FilterValues = useMemo(() => ({
sort: sortOption,
}), [sortOption]);
const handleFilterChange = useCallback((key: string, value: string | string[]) => {
switch (key) {
case 'sort':
setSortOption(value as SortOption);
break;
}
setCurrentPage(1);
}, []);
const handleFilterReset = useCallback(() => {
setSortOption('rank');
setCurrentPage(1);
}, []);
return (
<>
@@ -476,7 +488,11 @@ export function SalaryManagement() {
searchValue={searchQuery}
onSearchChange={setSearchQuery}
searchPlaceholder="이름, 부서 검색..."
extraFilters={extraFilters}
filterConfig={filterConfig}
filterValues={filterValues}
onFilterChange={handleFilterChange}
onFilterReset={handleFilterReset}
filterTitle="급여 필터"
tabs={tabs}
activeTab={activeTab}
onTabChange={setActiveTab}