feat: 다중 도메인 UI 개선 및 컴포넌트 리팩토링

- 게시판, HR, 설정, 차량관리, 건설, 견적 등 전반적 UI 개선
- FormField, TabChip, Select 등 공통 컴포넌트 개선
- 가격배분 edit 페이지 제거 및 상세 페이지 통합
- 체크리스트, 근태, 급여, 권한 관리 등 폼 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-25 22:30:06 +09:00
parent 1675bcbedf
commit 8f9507a665
86 changed files with 856 additions and 685 deletions

View File

@@ -569,7 +569,7 @@ export function EmployeeForm({
</CardHeader>
<CardContent className="pt-6 space-y-4">
{/* 프로필 사진 + 사원코드/성별 */}
<div className="flex gap-6">
<div className="flex flex-col md:flex-row gap-6">
{/* 프로필 사진 영역 */}
{fieldSettings.showProfileImage && (
<div className="space-y-2 flex-shrink-0">
@@ -783,47 +783,50 @@ export function EmployeeForm({
<div className="space-y-2">
{formData.departmentPositions.map((dp) => (
<div key={dp.id} className="flex items-center gap-2">
<Select
value={dp.departmentId}
onValueChange={(value) => handleDepartmentSelect(dp.id, value)}
disabled={isViewMode}
>
<SelectTrigger className="flex-1" disabled={isViewMode}>
<SelectValue placeholder="부서 선택">
{dp.departmentName || '부서 선택'}
</SelectValue>
</SelectTrigger>
<SelectContent>
{departments.map((dept) => (
<SelectItem key={dept.id} value={String(dept.id)}>
<span style={{ fontFamily: 'monospace' }}>
{formatDepartmentName(dept.name, dept.depth)}
</span>
</SelectItem>
))}
</SelectContent>
</Select>
<Select
value={dp.positionId}
onValueChange={(value) => handlePositionSelect(dp.id, value)}
disabled={isViewMode}
>
<SelectTrigger className="flex-1" disabled={isViewMode}>
<SelectValue placeholder="직책 선택">
{dp.positionName || '직책 선택'}
</SelectValue>
</SelectTrigger>
<SelectContent>
{titles.map((title) => (
<SelectItem key={title.id} value={String(title.id)}>{title.name}</SelectItem>
))}
</SelectContent>
</Select>
<div className="flex-1 min-w-0 grid grid-cols-1 sm:grid-cols-2 gap-2">
<Select
value={dp.departmentId}
onValueChange={(value) => handleDepartmentSelect(dp.id, value)}
disabled={isViewMode}
>
<SelectTrigger disabled={isViewMode}>
<SelectValue placeholder="부서 선택">
{dp.departmentName || '부서 선택'}
</SelectValue>
</SelectTrigger>
<SelectContent>
{departments.map((dept) => (
<SelectItem key={dept.id} value={String(dept.id)}>
<span style={{ fontFamily: 'monospace' }}>
{formatDepartmentName(dept.name, dept.depth)}
</span>
</SelectItem>
))}
</SelectContent>
</Select>
<Select
value={dp.positionId}
onValueChange={(value) => handlePositionSelect(dp.id, value)}
disabled={isViewMode}
>
<SelectTrigger disabled={isViewMode}>
<SelectValue placeholder="직책 선택">
{dp.positionName || '직책 선택'}
</SelectValue>
</SelectTrigger>
<SelectContent>
{titles.map((title) => (
<SelectItem key={title.id} value={String(title.id)}>{title.name}</SelectItem>
))}
</SelectContent>
</Select>
</div>
{!isViewMode && (
<Button
type="button"
variant="ghost"
size="sm"
className="shrink-0"
onClick={() => handleRemoveDepartmentPosition(dp.id)}
>
<Trash2 className="w-4 h-4 text-destructive" />