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

@@ -172,7 +172,7 @@ export default function PartForm({
value={selectedPartType}
onValueChange={handlePartTypeChange}
>
<SelectTrigger className={errors.partType ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).partType ? 'border-red-500' : ''}>
<SelectValue placeholder="부품 유형을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -181,12 +181,12 @@ export default function PartForm({
<SelectItem value="PURCHASED"> (Purchased Part)</SelectItem>
</SelectContent>
</Select>
{errors.partType && (
{(errors as any).partType && (
<p className="text-xs text-red-500 mt-1">
{errors.partType.message}
{(errors as any).partType.message}
</p>
)}
{!errors.partType && selectedPartType === 'BENDING' && (
{!(errors as any).partType && selectedPartType === 'BENDING' && (
<p className="text-xs text-muted-foreground mt-1">
* () , (BOM) .
</p>

View File

@@ -18,6 +18,11 @@ import { X } from 'lucide-react';
import type { UseFormRegister, UseFormSetValue, UseFormGetValues, FieldErrors } from 'react-hook-form';
import type { CreateItemFormData } from '@/lib/utils/validation';
// ProductForm에서 사용하는 확장 타입 (productName 포함)
type ProductFormErrors = FieldErrors<CreateItemFormData> & {
productName?: { message?: string };
};
interface ProductFormProps {
productName: string;
setProductName: (value: string) => void;
@@ -35,7 +40,7 @@ interface ProductFormProps {
register: UseFormRegister<CreateItemFormData>;
setValue: UseFormSetValue<CreateItemFormData>;
getValues: UseFormGetValues<CreateItemFormData>;
errors: FieldErrors<CreateItemFormData>;
errors: ProductFormErrors;
}
export default function ProductForm({

View File

@@ -134,7 +134,7 @@ export default function BendingPartForm({
setValue('material', value);
}}
>
<SelectTrigger className={errors.material ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).material ? 'border-red-500' : ''}>
<SelectValue placeholder="재질을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -144,9 +144,9 @@ export default function BendingPartForm({
<SelectItem value="SUS 1.5T">SUS 1.5T</SelectItem>
</SelectContent>
</Select>
{errors.material && (
{(errors as any).material && (
<p className="text-xs text-red-500 mt-1">
{errors.material.message}
{(errors as any).material.message}
</p>
)}
</div>
@@ -165,16 +165,16 @@ export default function BendingPartForm({
}}
placeholder="전개도 상세를 입력해주세요"
readOnly={bendingDetailsLength > 0}
className={`${bendingDetailsLength > 0 ? "bg-blue-50 font-medium" : ""} ${errors.length ? 'border-red-500' : ''}`}
className={`${bendingDetailsLength > 0 ? "bg-blue-50 font-medium" : ""} ${(errors as any).length ? 'border-red-500' : ''}`}
/>
<span className="text-sm text-muted-foreground">mm</span>
</div>
{errors.length && (
{(errors as any).length && (
<p className="text-xs text-red-500 mt-1">
{errors.length.message}
{(errors as any).length.message}
</p>
)}
{!errors.length && bendingDetailsLength > 0 && (
{!(errors as any).length && bendingDetailsLength > 0 && (
<p className="text-xs text-blue-600 mt-1">
*
</p>
@@ -192,7 +192,7 @@ export default function BendingPartForm({
setValue('bendingLength', value);
}}
>
<SelectTrigger className={errors.bendingLength ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).bendingLength ? 'border-red-500' : ''}>
<SelectValue placeholder="모양&길이를 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -210,9 +210,9 @@ export default function BendingPartForm({
<SelectItem value="4300">4300mm</SelectItem>
</SelectContent>
</Select>
{errors.bendingLength && (
{(errors as any).bendingLength && (
<p className="text-xs text-red-500 mt-1">
{errors.bendingLength.message}
{(errors as any).bendingLength.message}
</p>
)}
</div>

View File

@@ -119,7 +119,7 @@ export default function PurchasedPartForm({
setValue('electricOpenerPower', value);
}}
>
<SelectTrigger className={errors.electricOpenerPower ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).electricOpenerPower ? 'border-red-500' : ''}>
<SelectValue placeholder="전원을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -127,9 +127,9 @@ export default function PurchasedPartForm({
<SelectItem value="380V">380V</SelectItem>
</SelectContent>
</Select>
{errors.electricOpenerPower && (
{(errors as any).electricOpenerPower && (
<p className="text-xs text-red-500 mt-1">
{errors.electricOpenerPower.message}
{(errors as any).electricOpenerPower.message}
</p>
)}
</div>
@@ -144,7 +144,7 @@ export default function PurchasedPartForm({
setValue('electricOpenerCapacity', value);
}}
>
<SelectTrigger className={errors.electricOpenerCapacity ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).electricOpenerCapacity ? 'border-red-500' : ''}>
<SelectValue placeholder="용량을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -157,9 +157,9 @@ export default function PurchasedPartForm({
<SelectItem value="1000">1000 KG</SelectItem>
</SelectContent>
</Select>
{errors.electricOpenerCapacity && (
{(errors as any).electricOpenerCapacity && (
<p className="text-xs text-red-500 mt-1">
{errors.electricOpenerCapacity.message}
{(errors as any).electricOpenerCapacity.message}
</p>
)}
</div>
@@ -182,7 +182,7 @@ export default function PurchasedPartForm({
setValue('motorVoltage', value);
}}
>
<SelectTrigger className={errors.motorVoltage ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).motorVoltage ? 'border-red-500' : ''}>
<SelectValue placeholder="전압을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -190,9 +190,9 @@ export default function PurchasedPartForm({
<SelectItem value="380">380V</SelectItem>
</SelectContent>
</Select>
{errors.motorVoltage && (
{(errors as any).motorVoltage && (
<p className="text-xs text-red-500 mt-1">
{errors.motorVoltage.message}
{(errors as any).motorVoltage.message}
</p>
)}
</div>
@@ -211,7 +211,7 @@ export default function PurchasedPartForm({
setValue('chainSpec', value);
}}
>
<SelectTrigger className={errors.chainSpec ? 'border-red-500' : ''}>
<SelectTrigger className={(errors as any).chainSpec ? 'border-red-500' : ''}>
<SelectValue placeholder="규격을 선택하세요" />
</SelectTrigger>
<SelectContent>
@@ -221,9 +221,9 @@ export default function PurchasedPartForm({
<SelectItem value="80">80</SelectItem>
</SelectContent>
</Select>
{errors.chainSpec && (
{(errors as any).chainSpec && (
<p className="text-xs text-red-500 mt-1">
{errors.chainSpec.message}
{(errors as any).chainSpec.message}
</p>
)}
</div>