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>
This commit is contained in:
유병철
2026-01-30 10:07:58 +09:00
parent 8a5cbde5ef
commit a1f4c82cec
154 changed files with 832 additions and 536 deletions

View File

@@ -134,7 +134,7 @@ export function CardManagementUnified({ initialData }: CardManagementUnifiedProp
<TableRow
key={item.id}
className="hover:bg-muted/50 cursor-pointer"
onClick={() => onRowClick(item)}
onClick={() => onRowClick?.()}
>
<TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
<Checkbox
@@ -213,7 +213,7 @@ export function CardManagementUnified({ initialData }: CardManagementUnifiedProp
}
isSelected={isSelected}
onToggleSelection={onToggle}
onCardClick={() => onRowClick(item)}
onCardClick={() => onRowClick?.()}
infoGrid={
<div className="grid grid-cols-2 gap-x-4 gap-y-3">
<InfoField label="카드번호" value={maskCardNumber(item.cardNumber)} />

View File

@@ -7,12 +7,12 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { CreditCard, ArrowLeft, Edit, Trash2 } from 'lucide-react';
import type { Card as CardType } from './types';
import type { Card as CardType } from '../types';
import {
CARD_STATUS_LABELS,
CARD_STATUS_COLORS,
getCardCompanyLabel,
} from './types';
} from '../types';
interface CardDetailProps {
card: CardType;

View File

@@ -16,9 +16,9 @@ import {
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';
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';
@@ -88,19 +88,19 @@ export function CardForm({ mode, card, onSubmit }: CardFormProps) {
const digits = value.replace(/\D/g, '').slice(0, 16);
const parts = digits.match(/.{1,4}/g) || [];
const formatted = parts.join('-');
setFormData(prev => ({ ...prev, cardNumber: formatted }));
setFormData((prev: CardFormData) => ({ ...prev, cardNumber: formatted }));
};
// 유효기간 포맷팅 (MMYY)
const handleExpiryDateChange = (value: string) => {
const digits = value.replace(/\D/g, '').slice(0, 4);
setFormData(prev => ({ ...prev, expiryDate: digits }));
setFormData((prev: CardFormData) => ({ ...prev, expiryDate: digits }));
};
// 비밀번호 앞 2자리
const handlePinPrefixChange = (value: string) => {
const digits = value.replace(/\D/g, '').slice(0, 2);
setFormData(prev => ({ ...prev, pinPrefix: digits }));
setFormData((prev: CardFormData) => ({ ...prev, pinPrefix: digits }));
};
return (
@@ -123,7 +123,7 @@ export function CardForm({ mode, card, onSubmit }: CardFormProps) {
<Label htmlFor="cardCompany"></Label>
<Select
value={formData.cardCompany}
onValueChange={(value) => setFormData(prev => ({ ...prev, cardCompany: value as CardCompany }))}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, cardCompany: value as CardCompany }))}
>
<SelectTrigger id="cardCompany">
<SelectValue placeholder="카드사를 선택하세요" />
@@ -177,7 +177,7 @@ export function CardForm({ mode, card, onSubmit }: CardFormProps) {
<Input
id="cardName"
value={formData.cardName}
onChange={(e) => setFormData(prev => ({ ...prev, cardName: e.target.value }))}
onChange={(e) => setFormData((prev: CardFormData) => ({ ...prev, cardName: e.target.value }))}
placeholder="카드명을 입력해주세요"
/>
</div>
@@ -186,7 +186,7 @@ export function CardForm({ mode, card, onSubmit }: CardFormProps) {
<Label htmlFor="status"></Label>
<Select
value={formData.status}
onValueChange={(value) => setFormData(prev => ({ ...prev, status: value as CardStatus }))}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, status: value as CardStatus }))}
>
<SelectTrigger id="status">
<SelectValue placeholder="상태 선택" />
@@ -211,7 +211,7 @@ export function CardForm({ mode, card, onSubmit }: CardFormProps) {
<Label htmlFor="userId"> / / </Label>
<Select
value={formData.userId}
onValueChange={(value) => setFormData(prev => ({ ...prev, userId: value }))}
onValueChange={(value) => setFormData((prev: CardFormData) => ({ ...prev, userId: value }))}
disabled={isLoadingEmployees}
>
<SelectTrigger id="userId">

View File

@@ -153,7 +153,7 @@ export const cardConfig: DetailConfig<Card> = {
return date || '-';
case 'userId':
// 사용자 정보 조합 표시
const userData = data as Card;
const userData = data as unknown as Card;
if (userData.user) {
return `${userData.user.departmentName} / ${userData.user.employeeName} / ${userData.user.positionName}`;
}

View File

@@ -211,7 +211,7 @@ export function EmployeeDetail({ employee, onEdit, onDelete }: EmployeeDetailPro
<IntegratedDetailTemplate
config={employeeConfig}
mode="view"
initialData={employee}
initialData={employee as unknown as Record<string, unknown>}
itemId={employee.id}
onEdit={onEdit}
onDelete={handleFormDelete}

View File

@@ -516,13 +516,12 @@ export function SalaryManagement() {
);
},
renderDialogs: () => (
renderDialogs: (_params) => (
<SalaryDetailDialog
open={detailDialogOpen}
onOpenChange={setDetailDialogOpen}
salaryDetail={selectedSalaryDetail}
onSave={handleSaveDetail}
onAddPaymentItem={handleAddPaymentItem}
/>
),
}), [

View File

@@ -659,15 +659,17 @@ export function VacationManagement() {
sort: sortOption,
}), [filterOption, sortOption]);
const handleFilterChange = useCallback((key: string, value: string | string[]) => {
switch (key) {
case 'filter':
setFilterOption(value as FilterOption);
break;
case 'sort':
setSortOption(value as SortOption);
break;
}
const handleFilterChange = useCallback((filters: Record<string, string | string[]>) => {
Object.entries(filters).forEach(([key, value]) => {
switch (key) {
case 'filter':
setFilterOption(value as FilterOption);
break;
case 'sort':
setSortOption(value as SortOption);
break;
}
});
}, []);
const handleFilterReset = useCallback(() => {
@@ -731,7 +733,7 @@ export function VacationManagement() {
renderMobileCard: renderMobileCard,
renderDialogs: () => (
renderDialogs: (_params) => (
<>
{/* 휴가 부여 다이얼로그 */}
<VacationGrantDialog