Files
sam-react-prod/src/components/hr/CardManagement/_legacy/CardForm.tsx
유병철 a1f4c82cec fix: 프로젝트 전체 TypeScript 타입에러 408개 수정 (tsc --noEmit 0 errors)
- 공통 템플릿 타입 수정 (IntegratedDetailTemplate, UniversalListPage)
- 페이지(app/[locale]) 타입 호환성 수정 (80개)
- 재고/자재 모듈 타입 수정 (StockStatus, ReceivingManagement)
- 생산 모듈 타입 수정 (WorkOrders, WorkerScreen, WorkResults)
- 주문/출고 모듈 타입 수정 (ShipmentManagement, Orders)
- 견적/단가 모듈 타입 수정 (Quotes, Pricing)
- 건설 모듈 타입 수정 (49개, 17개 하위 모듈)
- HR 모듈 타입 수정 (CardManagement, VacationManagement 등)
- 설정 모듈 타입 수정 (PermissionManagement, AccountManagement 등)
- 게시판 모듈 타입 수정 (BoardManagement, BoardList 등)
- 회계 모듈 타입 수정 (VendorManagement, BadDebtCollection 등)
- 기타 모듈 타입 수정 (CEODashboard, clients, vehicle 등)
- 유틸/훅/API 타입 수정 (hooks, contexts, lib)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:07:58 +09:00

246 lines
8.5 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { CreditCard, ArrowLeft, Save } from 'lucide-react';
import type { Card as CardType, CardFormData, CardCompany, CardStatus } from '../types';
import { CARD_COMPANIES, CARD_STATUS_LABELS } from '../types';
import { getActiveEmployees } from '../actions';
interface CardFormProps {
mode: 'create' | 'edit';
card?: CardType;
onSubmit: (data: CardFormData) => void;
}
export function CardForm({ mode, card, onSubmit }: CardFormProps) {
const router = useRouter();
const [formData, setFormData] = useState<CardFormData>({
cardCompany: '',
cardNumber: '',
cardName: '',
expiryDate: '',
pinPrefix: '',
status: 'active',
userId: '',
});
// 직원 목록 상태
const [employees, setEmployees] = useState<Array<{ id: string; label: string }>>([]);
const [isLoadingEmployees, setIsLoadingEmployees] = useState(true);
// 직원 목록 로드
useEffect(() => {
const loadEmployees = async () => {
setIsLoadingEmployees(true);
const result = await getActiveEmployees();
if (result.success && result.data) {
setEmployees(result.data);
}
setIsLoadingEmployees(false);
};
loadEmployees();
}, []);
// 수정 모드일 때 기존 데이터 로드
useEffect(() => {
if (mode === 'edit' && card) {
setFormData({
cardCompany: card.cardCompany,
cardNumber: card.cardNumber,
cardName: card.cardName,
expiryDate: card.expiryDate,
pinPrefix: card.pinPrefix,
status: card.status,
userId: card.user?.id || '',
});
}
}, [mode, card]);
const handleBack = () => {
if (mode === 'edit' && card) {
router.push(`/ko/hr/card-management/${card.id}?mode=view`);
} else {
router.push('/ko/hr/card-management');
}
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);
};
// 카드번호 포맷팅 (1234-1234-1234-1234)
const handleCardNumberChange = (value: string) => {
const digits = value.replace(/\D/g, '').slice(0, 16);
const parts = digits.match(/.{1,4}/g) || [];
const formatted = parts.join('-');
setFormData((prev: CardFormData) => ({ ...prev, cardNumber: formatted }));
};
// 유효기간 포맷팅 (MMYY)
const handleExpiryDateChange = (value: string) => {
const digits = value.replace(/\D/g, '').slice(0, 4);
setFormData((prev: CardFormData) => ({ ...prev, expiryDate: digits }));
};
// 비밀번호 앞 2자리
const handlePinPrefixChange = (value: string) => {
const digits = value.replace(/\D/g, '').slice(0, 2);
setFormData((prev: CardFormData) => ({ ...prev, pinPrefix: digits }));
};
return (
<PageLayout>
<PageHeader
title={mode === 'create' ? '카드 등록' : '카드 수정'}
description={mode === 'create' ? '새로운 카드를 등록합니다' : '카드 정보를 수정합니다'}
icon={CreditCard}
/>
<form onSubmit={handleSubmit} className="space-y-6">
{/* 기본 정보 */}
<Card>
<CardHeader>
<CardTitle className="text-base"> </CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="cardCompany"></Label>
<Select
value={formData.cardCompany}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, cardCompany: value as CardCompany }))}
>
<SelectTrigger id="cardCompany">
<SelectValue placeholder="카드사를 선택하세요" />
</SelectTrigger>
<SelectContent>
{CARD_COMPANIES.map((company) => (
<SelectItem key={company.value} value={company.value}>
{company.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="cardNumber"></Label>
<Input
id="cardNumber"
value={formData.cardNumber}
onChange={(e) => handleCardNumberChange(e.target.value)}
placeholder="1234-1234-1234-1234"
maxLength={19}
/>
</div>
<div className="space-y-2">
<Label htmlFor="expiryDate"></Label>
<Input
id="expiryDate"
value={formData.expiryDate}
onChange={(e) => handleExpiryDateChange(e.target.value)}
placeholder="MMYY"
maxLength={4}
/>
</div>
<div className="space-y-2">
<Label htmlFor="pinPrefix"> 2</Label>
<Input
id="pinPrefix"
type="password"
value={formData.pinPrefix}
onChange={(e) => handlePinPrefixChange(e.target.value)}
placeholder="**"
maxLength={2}
/>
</div>
<div className="space-y-2">
<Label htmlFor="cardName"></Label>
<Input
id="cardName"
value={formData.cardName}
onChange={(e) => setFormData((prev: CardFormData) => ({ ...prev, cardName: e.target.value }))}
placeholder="카드명을 입력해주세요"
/>
</div>
<div className="space-y-2">
<Label htmlFor="status"></Label>
<Select
value={formData.status}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, status: value as CardStatus }))}
>
<SelectTrigger id="status">
<SelectValue placeholder="상태 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="active">{CARD_STATUS_LABELS.active}</SelectItem>
<SelectItem value="suspended">{CARD_STATUS_LABELS.suspended}</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardContent>
</Card>
{/* 사용자 정보 */}
<Card>
<CardHeader>
<CardTitle className="text-base"> </CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
<Label htmlFor="userId"> / / </Label>
<Select
value={formData.userId}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, userId: value }))}
disabled={isLoadingEmployees}
>
<SelectTrigger id="userId">
<SelectValue placeholder={isLoadingEmployees ? '직원 목록 로딩 중...' : '선택해서 해당 카드의 사용자로 설정'} />
</SelectTrigger>
<SelectContent>
{employees.map((employee) => (
<SelectItem key={employee.id} value={employee.id}>
{employee.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</CardContent>
</Card>
{/* 버튼 영역 */}
<div className="flex items-center justify-between">
<Button type="button" variant="outline" onClick={handleBack}>
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
<Button type="submit">
<Save className="w-4 h-4 mr-2" />
{mode === 'create' ? '등록' : '저장'}
</Button>
</div>
</form>
</PageLayout>
);
}