summaryrefslogtreecommitdiff
path: root/lib/general-contracts_old/main/create-general-contract-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/general-contracts_old/main/create-general-contract-dialog.tsx')
-rw-r--r--lib/general-contracts_old/main/create-general-contract-dialog.tsx413
1 files changed, 413 insertions, 0 deletions
diff --git a/lib/general-contracts_old/main/create-general-contract-dialog.tsx b/lib/general-contracts_old/main/create-general-contract-dialog.tsx
new file mode 100644
index 00000000..2c3fc8bc
--- /dev/null
+++ b/lib/general-contracts_old/main/create-general-contract-dialog.tsx
@@ -0,0 +1,413 @@
+"use client"
+
+import * as React from "react"
+import { useRouter } from "next/navigation"
+import { Plus } from "lucide-react"
+import { toast } from "sonner"
+import { Button } from "@/components/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/components/ui/dialog"
+import { Input } from "@/components/ui/input"
+import { Label } from "@/components/ui/label"
+import { Textarea } from "@/components/ui/textarea"
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
+import { Calendar } from "@/components/ui/calendar"
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
+import { CalendarIcon } from "lucide-react"
+import { format } from "date-fns"
+import { ko } from "date-fns/locale"
+import { cn } from "@/lib/utils"
+import { createContract, getVendors, getProjects } from "@/lib/general-contracts/service"
+import {
+ GENERAL_CONTRACT_CATEGORIES,
+ GENERAL_CONTRACT_TYPES,
+ GENERAL_EXECUTION_METHODS
+} from "@/lib/general-contracts/types"
+import { useSession } from "next-auth/react"
+
+interface CreateContractForm {
+ contractNumber: string
+ name: string
+ category: string
+ type: string
+ executionMethod: string
+ vendorId: number | null
+ projectId: number | null
+ startDate: Date | undefined
+ endDate: Date | undefined
+ validityEndDate: Date | undefined
+ notes: string
+}
+
+export function CreateGeneralContractDialog() {
+ const router = useRouter()
+ const { data: session } = useSession()
+ const [open, setOpen] = React.useState(false)
+ const [isLoading, setIsLoading] = React.useState(false)
+ const [vendors, setVendors] = React.useState<Array<{ id: number; vendorName: string; vendorCode: string | null }>>([])
+ const [projects, setProjects] = React.useState<Array<{ id: number; code: string; name: string; type: string }>>([])
+
+ const [form, setForm] = React.useState<CreateContractForm>({
+ contractNumber: '',
+ name: '',
+ category: '',
+ type: '',
+ executionMethod: '',
+ vendorId: null,
+ projectId: null,
+ startDate: undefined,
+ endDate: undefined,
+ validityEndDate: undefined,
+ notes: '',
+ })
+
+ // 업체 목록 조회
+ React.useEffect(() => {
+ const fetchVendors = async () => {
+ try {
+ const vendorList = await getVendors()
+ setVendors(vendorList)
+ } catch (error) {
+ console.error('Error fetching vendors:', error)
+ }
+ }
+ fetchVendors()
+ }, [])
+
+ // 프로젝트 목록 조회
+ React.useEffect(() => {
+ const fetchProjects = async () => {
+ try {
+ const projectList = await getProjects()
+ console.log(projectList)
+ setProjects(projectList)
+ } catch (error) {
+ console.error('Error fetching projects:', error)
+ }
+ }
+ fetchProjects()
+ }, [])
+
+ const handleSubmit = async () => {
+ // 필수 필드 검증
+ if (!form.name || !form.category || !form.type || !form.executionMethod ||
+ !form.vendorId || !form.startDate || !form.endDate) {
+ toast.error("필수 항목을 모두 입력해주세요.")
+ return
+ }
+
+ if (!form.validityEndDate) {
+ setForm(prev => ({ ...prev, validityEndDate: form.endDate }))
+ }
+
+ try {
+ setIsLoading(true)
+
+ const contractData = {
+ contractNumber: '',
+ name: form.name,
+ category: form.category,
+ type: form.type,
+ executionMethod: form.executionMethod,
+ projectId: form.projectId,
+ contractSourceType: 'manual',
+ vendorId: form.vendorId!,
+ startDate: form.startDate!.toISOString().split('T')[0],
+ endDate: form.endDate!.toISOString().split('T')[0],
+ validityEndDate: (form.validityEndDate || form.endDate!).toISOString().split('T')[0],
+ status: 'Draft',
+ registeredById: session?.user?.id || 1,
+ lastUpdatedById: session?.user?.id || 1,
+ notes: form.notes,
+ }
+
+ await createContract(contractData)
+
+ toast.success("새 계약이 생성되었습니다.")
+ setOpen(false)
+ resetForm()
+
+ // 상세 페이지로 이동
+ router.refresh()
+ } catch (error) {
+ console.error('Error creating contract:', error)
+ toast.error("계약 생성 중 오류가 발생했습니다.")
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ const resetForm = () => {
+ setForm({
+ contractNumber: '',
+ name: '',
+ category: '',
+ type: '',
+ executionMethod: '',
+ vendorId: null,
+ projectId: null,
+ startDate: undefined,
+ endDate: undefined,
+ validityEndDate: undefined,
+ notes: '',
+ })
+ }
+
+ return (
+ <Dialog open={open} onOpenChange={(newOpen) => {
+ setOpen(newOpen)
+ if (!newOpen) resetForm()
+ }}>
+ <DialogTrigger asChild>
+ <Button size="sm">
+ <Plus className="mr-2 h-4 w-4" />
+ 신규등록
+ </Button>
+ </DialogTrigger>
+ <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
+ <DialogHeader>
+ <DialogTitle>새 계약 등록</DialogTitle>
+ <DialogDescription>
+ 새로운 계약의 기본 정보를 입력하세요.
+ </DialogDescription>
+ </DialogHeader>
+
+ <div className="grid gap-4 py-4">
+ <div className="grid grid-cols-1 gap-4">
+ <div className="grid gap-2">
+ <Label htmlFor="name">계약명 *</Label>
+ <Input
+ id="name"
+ value={form.name}
+ onChange={(e) => setForm(prev => ({ ...prev, name: e.target.value }))}
+ placeholder="계약명을 입력하세요"
+ />
+ </div>
+ </div>
+
+ <div className="grid grid-cols-3 gap-4">
+ <div className="grid gap-2">
+ <Label htmlFor="category">계약구분 *</Label>
+ <Select value={form.category} onValueChange={(value) => setForm(prev => ({ ...prev, category: value }))}>
+ <SelectTrigger>
+ <SelectValue placeholder="계약구분 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {GENERAL_CONTRACT_CATEGORIES.map((category) => {
+ const categoryLabels = {
+ 'unit_price': '단가계약',
+ 'general': '일반계약',
+ 'sale': '매각계약'
+ }
+ return (
+ <SelectItem key={category} value={category}>
+ {category} - {categoryLabels[category as keyof typeof categoryLabels]}
+ </SelectItem>
+ )
+ })}
+ </SelectContent>
+ </Select>
+ </div>
+
+ <div className="grid gap-2">
+ <Label htmlFor="type">계약종류 *</Label>
+ <Select value={form.type} onValueChange={(value) => setForm(prev => ({ ...prev, type: value }))}>
+ <SelectTrigger>
+ <SelectValue placeholder="계약종류 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {GENERAL_CONTRACT_TYPES.map((type) => {
+ const typeLabels = {
+ 'UP': '자재단가계약',
+ 'LE': '임대차계약',
+ 'IL': '개별운송계약',
+ 'AL': '연간운송계약',
+ 'OS': '외주용역계약',
+ 'OW': '도급계약',
+ 'IS': '검사계약',
+ 'LO': 'LOI',
+ 'FA': 'FA',
+ 'SC': '납품합의계약',
+ 'OF': '클레임상계계약',
+ 'AW': '사전작업합의',
+ 'AD': '사전납품합의',
+ 'AM': '설계계약',
+ 'SC_SELL': '폐기물매각계약'
+ }
+ return (
+ <SelectItem key={type} value={type}>
+ {type} - {typeLabels[type as keyof typeof typeLabels]}
+ </SelectItem>
+ )
+ })}
+ </SelectContent>
+ </Select>
+ </div>
+
+ <div className="grid gap-2">
+ <Label htmlFor="executionMethod">체결방식 *</Label>
+ <Select value={form.executionMethod} onValueChange={(value) => setForm(prev => ({ ...prev, executionMethod: value }))}>
+ <SelectTrigger>
+ <SelectValue placeholder="체결방식 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {GENERAL_EXECUTION_METHODS.map((method) => (
+ <SelectItem key={method} value={method}>
+ {method}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </div>
+ </div>
+
+ <div className="grid gap-2">
+ <Label htmlFor="project">프로젝트</Label>
+ <Select value={form.projectId?.toString()} onValueChange={(value) => setForm(prev => ({ ...prev, projectId: parseInt(value) }))}>
+ <SelectTrigger>
+ <SelectValue placeholder="프로젝트 선택 (선택사항)" />
+ </SelectTrigger>
+ <SelectContent>
+ {projects.map((project) => (
+ <SelectItem key={project.id} value={project.id.toString()}>
+ {project.name} ({project.code})
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </div>
+
+ <div className="grid gap-2">
+ <Label htmlFor="vendor">협력업체 *</Label>
+ <Select value={form.vendorId?.toString()} onValueChange={(value) => setForm(prev => ({ ...prev, vendorId: parseInt(value) }))}>
+ <SelectTrigger>
+ <SelectValue placeholder="협력업체 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {vendors.map((vendor) => (
+ <SelectItem key={vendor.id} value={vendor.id.toString()}>
+ {vendor.vendorName} ({vendor.vendorCode})
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </div>
+
+ <div className="grid grid-cols-3 gap-4">
+ <div className="grid gap-2">
+ <Label>계약시작일 *</Label>
+ <Popover>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ className={cn(
+ "justify-start text-left font-normal",
+ !form.startDate && "text-muted-foreground"
+ )}
+ >
+ <CalendarIcon className="mr-2 h-4 w-4" />
+ {form.startDate ? format(form.startDate, "yyyy-MM-dd", { locale: ko }) : "날짜 선택"}
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0">
+ <Calendar
+ mode="single"
+ selected={form.startDate}
+ onSelect={(date) => setForm(prev => ({ ...prev, startDate: date }))}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ </div>
+
+ <div className="grid gap-2">
+ <Label>계약종료일 *</Label>
+ <Popover>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ className={cn(
+ "justify-start text-left font-normal",
+ !form.endDate && "text-muted-foreground"
+ )}
+ >
+ <CalendarIcon className="mr-2 h-4 w-4" />
+ {form.endDate ? format(form.endDate, "yyyy-MM-dd", { locale: ko }) : "날짜 선택"}
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0">
+ <Calendar
+ mode="single"
+ selected={form.endDate}
+ onSelect={(date) => setForm(prev => ({ ...prev, endDate: date }))}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ </div>
+
+ <div className="grid gap-2">
+ <Label>유효기간종료일</Label>
+ <Popover>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ className={cn(
+ "justify-start text-left font-normal",
+ !form.validityEndDate && "text-muted-foreground"
+ )}
+ >
+ <CalendarIcon className="mr-2 h-4 w-4" />
+ {form.validityEndDate ? format(form.validityEndDate, "yyyy-MM-dd", { locale: ko }) : "날짜 선택"}
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0">
+ <Calendar
+ mode="single"
+ selected={form.validityEndDate}
+ onSelect={(date) => setForm(prev => ({ ...prev, validityEndDate: date }))}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ </div>
+ </div>
+ <div className="grid gap-2">
+ <Label htmlFor="notes">비고</Label>
+ <Textarea
+ id="notes"
+ value={form.notes}
+ onChange={(e) => setForm(prev => ({ ...prev, notes: e.target.value }))}
+ placeholder="비고사항을 입력하세요"
+ rows={3}
+ />
+ </div>
+ </div>
+
+ <DialogFooter>
+ <Button
+ type="button"
+ variant="outline"
+ onClick={() => setOpen(false)}
+ >
+ 취소
+ </Button>
+ <Button
+ type="button"
+ onClick={handleSubmit}
+ disabled={isLoading}
+ >
+ {isLoading ? '생성 중...' : '생성'}
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ )
+}