feat: 다중 도메인 UI 개선 및 컴포넌트 리팩토링
- 게시판, HR, 설정, 차량관리, 건설, 견적 등 전반적 UI 개선 - FormField, TabChip, Select 등 공통 컴포넌트 개선 - 가격배분 edit 페이지 제거 및 상세 페이지 통합 - 체크리스트, 근태, 급여, 권한 관리 등 폼 개선 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { ArrowLeft, FileText, CheckCircle2, Edit3, Save, X } from 'lucide-react';
|
||||
import { ArrowLeft, FileText, CheckCircle2, Edit, Save, X } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useMenuStore } from '@/stores/menuStore';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -135,7 +135,7 @@ export function PriceDistributionDetail({ id, mode: propMode }: Props) {
|
||||
const result = await updatePriceDistribution(id, formData);
|
||||
if (result.success) {
|
||||
toast.success('저장되었습니다.');
|
||||
router.push(`/master-data/price-distribution/${id}`);
|
||||
router.push(`/master-data/price-distribution/${id}?mode=view`);
|
||||
} else {
|
||||
toast.error(result.error || '저장에 실패했습니다.');
|
||||
}
|
||||
@@ -164,12 +164,12 @@ export function PriceDistributionDetail({ id, mode: propMode }: Props) {
|
||||
|
||||
// 수정 모드 전환
|
||||
const handleEditMode = () => {
|
||||
router.push(`/master-data/price-distribution/${id}/edit`);
|
||||
router.push(`/master-data/price-distribution/${id}?mode=edit`);
|
||||
};
|
||||
|
||||
// 취소
|
||||
const handleCancel = () => {
|
||||
router.push(`/master-data/price-distribution/${id}`);
|
||||
router.push(`/master-data/price-distribution/${id}?mode=view`);
|
||||
};
|
||||
|
||||
// 목록으로
|
||||
@@ -352,25 +352,27 @@ export function PriceDistributionDetail({ id, mode: propMode }: Props) {
|
||||
|
||||
{/* 단가 목록 테이블 */}
|
||||
<Card className="mt-4">
|
||||
<CardHeader className="flex flex-row items-center justify-between">
|
||||
<CardTitle className="text-base">단가표 목록</CardTitle>
|
||||
<div className="flex items-center gap-3">
|
||||
<Select value={gradeFilter} onValueChange={setGradeFilter}>
|
||||
<SelectTrigger className="h-8 min-w-[120px] w-auto text-sm">
|
||||
<SelectValue placeholder="등급" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">전체</SelectItem>
|
||||
{TRADE_GRADE_OPTIONS.map((opt) => (
|
||||
<SelectItem key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
총 {detail.items.length}건
|
||||
</span>
|
||||
<CardHeader>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
|
||||
<CardTitle className="text-base">단가표 목록</CardTitle>
|
||||
<div className="flex items-center gap-3">
|
||||
<Select value={gradeFilter} onValueChange={setGradeFilter}>
|
||||
<SelectTrigger className="h-8 min-w-[120px] w-auto text-sm">
|
||||
<SelectValue placeholder="등급" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">전체</SelectItem>
|
||||
{TRADE_GRADE_OPTIONS.map((opt) => (
|
||||
<SelectItem key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<span className="text-sm text-muted-foreground whitespace-nowrap">
|
||||
총 {detail.items.length}건
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="p-0">
|
||||
@@ -492,7 +494,7 @@ export function PriceDistributionDetail({ id, mode: propMode }: Props) {
|
||||
className="md:size-default"
|
||||
disabled={detail.status === 'finalized'}
|
||||
>
|
||||
<Edit3 className="w-4 h-4 md:mr-2" />
|
||||
<Edit className="w-4 h-4 md:mr-2" />
|
||||
<span className="hidden md:inline">수정</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -110,7 +110,7 @@ export function PriceDistributionList() {
|
||||
if (result.success && result.data) {
|
||||
toast.success('단가배포가 등록되었습니다.');
|
||||
setShowRegisterDialog(false);
|
||||
router.push(`/master-data/price-distribution/${result.data.id}`);
|
||||
router.push(`/master-data/price-distribution/${result.data.id}?mode=view`);
|
||||
} else {
|
||||
toast.error(result.error || '등록에 실패했습니다.');
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export function PriceDistributionList() {
|
||||
|
||||
// 행 클릭 → 상세
|
||||
const handleRowClick = (item: PriceDistributionListItem) => {
|
||||
router.push(`/master-data/price-distribution/${item.id}`);
|
||||
router.push(`/master-data/price-distribution/${item.id}?mode=view`);
|
||||
};
|
||||
|
||||
// 상태 필터 설정
|
||||
|
||||
Reference in New Issue
Block a user