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:
138
src/components/settings/LeavePolicyManagement/index.tsx
Normal file
138
src/components/settings/LeavePolicyManagement/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
49
src/components/settings/LeavePolicyManagement/types.ts
Normal file
49
src/components/settings/LeavePolicyManagement/types.ts
Normal 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}일`,
|
||||
}));
|
||||
Reference in New Issue
Block a user