- 기안함(DraftBox): 문서 목록, 상신/삭제, 문서작성 연결 - 결재함(ApprovalBox): 결재 대기 문서 목록, 문서상세 모달 연결 - 참조함(ReferenceBox): 참조 문서 목록, 열람/미열람 처리 - 문서작성(DocumentCreate): 품의서, 지출결의서, 지출예상내역서 폼 - 문서상세(DocumentDetail): 공유 모달, 결재선 박스, 3종 문서 뷰어 - 테이블 번호 컬럼 추가 (1번부터 시작) - sonner toast 적용 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
'use client';
|
|
|
|
import { Plus, X } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@/components/ui/select';
|
|
import type { ApprovalPerson } from './types';
|
|
import { MOCK_EMPLOYEES } from './types';
|
|
|
|
interface ReferenceSectionProps {
|
|
data: ApprovalPerson[];
|
|
onChange: (data: ApprovalPerson[]) => void;
|
|
}
|
|
|
|
export function ReferenceSection({ data, onChange }: ReferenceSectionProps) {
|
|
const handleAdd = () => {
|
|
const newPerson: ApprovalPerson = {
|
|
id: `temp-${Date.now()}`,
|
|
department: '',
|
|
position: '',
|
|
name: '',
|
|
};
|
|
onChange([...data, newPerson]);
|
|
};
|
|
|
|
const handleRemove = (index: number) => {
|
|
onChange(data.filter((_, i) => i !== index));
|
|
};
|
|
|
|
const handleChange = (index: number, employeeId: string) => {
|
|
const employee = MOCK_EMPLOYEES.find((e) => e.id === employeeId);
|
|
if (employee) {
|
|
const newData = [...data];
|
|
newData[index] = { ...employee };
|
|
onChange(newData);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="bg-white rounded-lg border p-6">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h3 className="text-lg font-semibold">참조</h3>
|
|
<Button variant="outline" size="sm" onClick={handleAdd}>
|
|
<Plus className="w-4 h-4 mr-1" />
|
|
추가
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="space-y-3">
|
|
<div className="text-sm text-gray-500 mb-2">부서 / 직책 / 이름</div>
|
|
|
|
{data.length === 0 ? (
|
|
<div className="text-center py-4 text-gray-400">
|
|
참조자를 추가해주세요
|
|
</div>
|
|
) : (
|
|
data.map((person, index) => (
|
|
<div key={person.id} className="flex items-center gap-2">
|
|
<span className="w-8 text-center text-sm text-gray-500">{index + 1}</span>
|
|
<Select
|
|
value={person.id.startsWith('temp-') ? '' : person.id}
|
|
onValueChange={(value) => handleChange(index, value)}
|
|
>
|
|
<SelectTrigger className="flex-1">
|
|
<SelectValue placeholder="부서명 / 직책명 / 이름 ▼" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{MOCK_EMPLOYEES.map((employee) => (
|
|
<SelectItem key={employee.id} value={employee.id}>
|
|
{employee.department} / {employee.position} / {employee.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
|
|
onClick={() => handleRemove(index)}
|
|
>
|
|
<X className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
))
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
} |