fix: TypeScript 타입 오류 수정 및 설정 페이지 추가

- BOMItem Omit 타입 시그니처 통일 (useTemplateManagement, SectionsTab, ItemMasterContext)
- HeadersInit → Record<string, string> 타입 변경
- Zustand useShallow 마이그레이션 (zustand/react/shallow)
- DataTable, ListPageTemplate 제네릭 타입 제약 추가
- 설정 관리 페이지 추가 (직급, 직책, 휴가정책, 근무일정, 권한)
- HR 관리 페이지 추가 (급여, 휴가)
- 단가관리 페이지 리팩토링

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-12-09 18:07:47 +09:00
parent 48dbba0e5f
commit ded0bc2439
98 changed files with 10608 additions and 1204 deletions

View File

@@ -0,0 +1,138 @@
'use client';
import { useState } from 'react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { CalendarDays } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Card, CardContent } from '@/components/ui/card';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { toast } from 'sonner';
// 기준 타입
type StandardType = 'fiscal' | 'hire';
// 월 옵션 (1~12월)
const MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => ({
value: (i + 1).toString(),
label: `${i + 1}`,
}));
// 일 옵션 (1~31일)
const DAY_OPTIONS = Array.from({ length: 31 }, (_, i) => ({
value: (i + 1).toString(),
label: `${i + 1}`,
}));
export function LeavePolicyManagement() {
// 기준 설정 (회계연도 / 입사일)
const [standardType, setStandardType] = useState<StandardType>('fiscal');
// 기준일 (월, 일)
const [month, setMonth] = useState('1');
const [day, setDay] = useState('1');
// 저장
const handleSave = () => {
const settings = {
standardType,
month: parseInt(month),
day: parseInt(day),
};
console.log('저장할 설정:', settings);
toast.success('휴가 정책이 저장되었습니다.');
};
return (
<PageLayout>
{/* 헤더 + 저장 버튼 */}
<div className="flex items-start justify-between">
<PageHeader
title="휴가관리"
description="휴가 항목을 관리합니다"
icon={CalendarDays}
/>
<Button onClick={handleSave}>
</Button>
</div>
{/* 기본 정보 카드 */}
<Card>
<CardContent className="p-6">
<h3 className="text-lg font-semibold mb-6"> </h3>
<div className="grid grid-cols-2 gap-6">
{/* 기준 셀렉트 */}
<div className="space-y-2">
<Label></Label>
<Select value={standardType} onValueChange={(v: StandardType) => setStandardType(v)}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="fiscal"></SelectItem>
<SelectItem value="hire"></SelectItem>
</SelectContent>
</Select>
</div>
{/* 기준일 셀렉트 (월/일) */}
<div className="space-y-2">
<Label></Label>
<div className="flex items-center gap-2">
<Select
value={month}
onValueChange={setMonth}
disabled={standardType === 'hire'}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
{MONTH_OPTIONS.map((opt) => (
<SelectItem key={opt.value} value={opt.value}>
{opt.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Select
value={day}
onValueChange={setDay}
disabled={standardType === 'hire'}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
{DAY_OPTIONS.map((opt) => (
<SelectItem key={opt.value} value={opt.value}>
{opt.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
</div>
{/* 안내 문구 */}
<div className="mt-6 text-sm text-muted-foreground space-y-1">
<p>! .</p>
<ul className="list-disc list-inside ml-2 space-y-1">
<li> 기준: 사원의 .</li>
<li> 기준: 회사의 .</li>
</ul>
</div>
</CardContent>
</Card>
</PageLayout>
);
}

View File

@@ -0,0 +1,49 @@
/**
* 휴가관리(기준정보) 타입 정의 (PDF 57페이지 기준)
*/
// 휴가 기준 유형
export type LeaveStandardType = 'fiscal' | 'hire'; // 회계연도 / 입사일
export const LEAVE_STANDARD_TYPE_LABELS: Record<LeaveStandardType, string> = {
fiscal: '회계연도',
hire: '입사일',
};
// 휴가 정책 설정
export interface LeavePolicySettings {
standardType: LeaveStandardType; // 기준
fiscalStartMonth: number; // 기준일 (월) - 회계연도 기준일 때만 사용
fiscalStartDay: number; // 기준일 (일)
defaultAnnualLeave: number; // 기본 연차 일수
additionalLeavePerYear: number; // 근속년수당 추가 연차
maxAnnualLeave: number; // 최대 연차 일수
carryOverEnabled: boolean; // 이월 허용 여부
carryOverMaxDays: number; // 최대 이월 일수
carryOverExpiryMonths: number; // 이월 연차 소멸 기간 (개월)
}
// 기본 설정값
export const DEFAULT_LEAVE_POLICY: LeavePolicySettings = {
standardType: 'fiscal',
fiscalStartMonth: 1,
fiscalStartDay: 1,
defaultAnnualLeave: 15,
additionalLeavePerYear: 1,
maxAnnualLeave: 25,
carryOverEnabled: true,
carryOverMaxDays: 10,
carryOverExpiryMonths: 3,
};
// 월 옵션
export const MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => ({
value: i + 1,
label: `${i + 1}`,
}));
// 일 옵션
export const DAY_OPTIONS = Array.from({ length: 31 }, (_, i) => ({
value: i + 1,
label: `${i + 1}`,
}));