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

@@ -7,7 +7,7 @@
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { ArrowLeft, Save, MessageSquare } from 'lucide-react';
import { X, Save, MessageSquare } from 'lucide-react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
@@ -16,6 +16,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { useMenuStore } from '@/stores/menuStore';
import { createDynamicBoardPost } from '@/components/board/DynamicBoard/actions';
import { getBoardByCode } from '@/components/board/BoardManagement/actions';
@@ -25,6 +26,7 @@ interface DynamicBoardCreateFormProps {
export function DynamicBoardCreateForm({ boardCode }: DynamicBoardCreateFormProps) {
const router = useRouter();
const sidebarCollapsed = useMenuStore((state) => state.sidebarCollapsed);
// 게시판 정보
const [boardName, setBoardName] = useState<string>('게시판');
@@ -71,7 +73,7 @@ export function DynamicBoardCreateForm({ boardCode }: DynamicBoardCreateFormProp
});
if (result.success && result.data) {
router.push(`/ko/boards/${boardCode}/${result.data.id}`);
router.push(`/ko/boards/${boardCode}/${result.data.id}?mode=view`);
} else {
setError(result.error || '게시글 등록에 실패했습니다.');
setIsSubmitting(false);
@@ -91,7 +93,7 @@ export function DynamicBoardCreateForm({ boardCode }: DynamicBoardCreateFormProp
icon={MessageSquare}
/>
<form onSubmit={handleSubmit}>
<form onSubmit={handleSubmit} className="pb-24">
<Card>
<CardHeader>
<CardTitle className="text-base"> </CardTitle>
@@ -143,23 +145,21 @@ export function DynamicBoardCreateForm({ boardCode }: DynamicBoardCreateFormProp
</CardContent>
</Card>
{/* 버튼 영역 */}
<div className="mt-6 flex items-center justify-between">
<Button
type="button"
variant="outline"
onClick={handleCancel}
disabled={isSubmitting}
>
<ArrowLeft className="h-4 w-4 mr-2" />
</Button>
<Button type="submit" disabled={isSubmitting}>
<Save className="h-4 w-4 mr-2" />
{isSubmitting ? '등록 중...' : '등록'}
</Button>
</div>
</form>
{/* 하단 액션 버튼 (sticky) */}
<div
className={`fixed bottom-4 left-4 right-4 px-4 py-3 bg-background/95 backdrop-blur rounded-xl border shadow-lg z-50 transition-all duration-300 md:bottom-6 md:px-6 md:right-[48px] ${sidebarCollapsed ? 'md:left-[156px]' : 'md:left-[316px]'} flex items-center justify-between`}
>
<Button type="button" variant="outline" onClick={handleCancel} disabled={isSubmitting} size="sm" className="md:size-default">
<X className="w-4 h-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
<Button onClick={(e) => { e.preventDefault(); const form = document.querySelector('form'); form?.requestSubmit(); }} disabled={isSubmitting} size="sm" className="md:size-default">
<Save className="w-4 h-4 md:mr-2" />
<span className="hidden md:inline">{isSubmitting ? '등록 중...' : '등록'}</span>
</Button>
</div>
</PageLayout>
);
}

View File

@@ -7,7 +7,7 @@
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { ArrowLeft, Save, MessageSquare } from 'lucide-react';
import { ArrowLeft, X, Save, MessageSquare } from 'lucide-react';
import { DetailPageSkeleton } from '@/components/ui/skeleton';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
@@ -17,6 +17,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { useMenuStore } from '@/stores/menuStore';
import { getDynamicBoardPost, updateDynamicBoardPost } from '@/components/board/DynamicBoard/actions';
import { getBoardByCode } from '@/components/board/BoardManagement/actions';
import type { PostApiData } from '@/components/customer-center/shared/types';
@@ -59,6 +60,7 @@ interface DynamicBoardEditFormProps {
export function DynamicBoardEditForm({ boardCode, postId }: DynamicBoardEditFormProps) {
const router = useRouter();
const sidebarCollapsed = useMenuStore((state) => state.sidebarCollapsed);
// 게시판 정보
const [boardName, setBoardName] = useState<string>('게시판');
@@ -134,7 +136,7 @@ export function DynamicBoardEditForm({ boardCode, postId }: DynamicBoardEditForm
});
if (result.success) {
router.push(`/ko/boards/${boardCode}/${postId}`);
router.push(`/ko/boards/${boardCode}/${postId}?mode=view`);
} else {
setError(result.error || '게시글 수정에 실패했습니다.');
setIsSubmitting(false);
@@ -143,7 +145,7 @@ export function DynamicBoardEditForm({ boardCode, postId }: DynamicBoardEditForm
// 취소
const handleCancel = () => {
router.push(`/ko/boards/${boardCode}/${postId}`);
router.push(`/ko/boards/${boardCode}/${postId}?mode=view`);
};
// 로딩 상태
@@ -178,7 +180,7 @@ export function DynamicBoardEditForm({ boardCode, postId }: DynamicBoardEditForm
icon={MessageSquare}
/>
<form onSubmit={handleSubmit}>
<form onSubmit={handleSubmit} className="pb-24">
<Card>
<CardHeader>
<CardTitle className="text-base"> </CardTitle>
@@ -230,23 +232,21 @@ export function DynamicBoardEditForm({ boardCode, postId }: DynamicBoardEditForm
</CardContent>
</Card>
{/* 버튼 영역 */}
<div className="mt-6 flex items-center justify-between">
<Button
type="button"
variant="outline"
onClick={handleCancel}
disabled={isSubmitting}
>
<ArrowLeft className="h-4 w-4 mr-2" />
</Button>
<Button type="submit" disabled={isSubmitting}>
<Save className="h-4 w-4 mr-2" />
{isSubmitting ? '저장 중...' : '저장'}
</Button>
</div>
</form>
{/* 하단 액션 버튼 (sticky) */}
<div
className={`fixed bottom-4 left-4 right-4 px-4 py-3 bg-background/95 backdrop-blur rounded-xl border shadow-lg z-50 transition-all duration-300 md:bottom-6 md:px-6 md:right-[48px] ${sidebarCollapsed ? 'md:left-[156px]' : 'md:left-[316px]'} flex items-center justify-between`}
>
<Button type="button" variant="outline" onClick={handleCancel} disabled={isSubmitting} size="sm" className="md:size-default">
<X className="w-4 h-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
<Button onClick={(e) => { e.preventDefault(); const form = document.querySelector('form'); form?.requestSubmit(); }} disabled={isSubmitting} size="sm" className="md:size-default">
<Save className="w-4 h-4 md:mr-2" />
<span className="hidden md:inline">{isSubmitting ? '저장 중...' : '저장'}</span>
</Button>
</div>
</PageLayout>
);
}