diff options
Diffstat (limited to 'lib/general-contracts_old/main/general-contract-update-sheet.tsx')
| -rw-r--r-- | lib/general-contracts_old/main/general-contract-update-sheet.tsx | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/lib/general-contracts_old/main/general-contract-update-sheet.tsx b/lib/general-contracts_old/main/general-contract-update-sheet.tsx new file mode 100644 index 00000000..54f4ae4e --- /dev/null +++ b/lib/general-contracts_old/main/general-contract-update-sheet.tsx @@ -0,0 +1,401 @@ +"use client" + +import * as React from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import { z } from "zod" +import { toast } from "sonner" +import { Button } from "@/components/ui/button" +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" +import { + GENERAL_CONTRACT_CATEGORIES, + GENERAL_CONTRACT_TYPES, + GENERAL_EXECUTION_METHODS, +} from "@/lib/general-contracts/types" +import { updateContract } from "../service" +import { GeneralContractListItem } from "./general-contracts-table-columns" +import { useSession } from "next-auth/react" +const updateContractSchema = z.object({ + category: z.string().min(1, "계약구분을 선택해주세요"), + type: z.string().min(1, "계약종류를 선택해주세요"), + executionMethod: z.string().min(1, "체결방식을 선택해주세요"), + name: z.string().min(1, "계약명을 입력해주세요"), + startDate: z.string().min(1, "계약시작일을 선택해주세요"), + endDate: z.string().min(1, "계약종료일을 선택해주세요"), + validityEndDate: z.string().min(1, "유효기간종료일을 선택해주세요"), + contractScope: z.string().min(1, "계약확정범위를 선택해주세요"), + notes: z.string().optional(), + linkedRfqOrItb: z.string().optional(), + linkedPoNumber: z.string().optional(), + linkedBidNumber: z.string().optional(), +}) + +type UpdateContractFormData = z.infer<typeof updateContractSchema> + +interface GeneralContractUpdateSheetProps { + contract: GeneralContractListItem | null + open: boolean + onOpenChange: (open: boolean) => void + onSuccess?: () => void +} + +export function GeneralContractUpdateSheet({ + contract, + open, + onOpenChange, + onSuccess, +}: GeneralContractUpdateSheetProps) { + const [isSubmitting, setIsSubmitting] = React.useState(false) + const session = useSession() + const userId = session.data?.user?.id ? Number(session.data.user.id) : null + const form = useForm<UpdateContractFormData>({ + resolver: zodResolver(updateContractSchema), + defaultValues: { + category: "", + type: "", + executionMethod: "", + name: "", + startDate: "", + endDate: "", + validityEndDate: "", + contractScope: "", + notes: "", + linkedRfqOrItb: "", + linkedPoNumber: "", + linkedBidNumber: "", + }, + }) + + // 계약확정범위에 따른 품목정보 필드 비활성화 여부 + const watchedContractScope = form.watch("contractScope") + const isItemsDisabled = watchedContractScope === '단가' || watchedContractScope === '물량(실적)' + + // 계약 데이터가 변경될 때 폼 초기화 + React.useEffect(() => { + if (contract) { + console.log("Loading contract data:", contract) + const formData = { + category: contract.category || "", + type: contract.type || "", + executionMethod: contract.executionMethod || "", + name: contract.name || "", + startDate: contract.startDate || "", + endDate: contract.endDate || "", + validityEndDate: contract.validityEndDate || "", + contractScope: contract.contractScope || "", + notes: contract.notes || "", + linkedRfqOrItb: contract.linkedRfqOrItb || "", + linkedPoNumber: contract.linkedPoNumber || "", + linkedBidNumber: contract.linkedBidNumber || "", + } + console.log("Form data to reset:", formData) + form.reset(formData) + } + }, [contract, form]) + + const onSubmit = async (data: UpdateContractFormData) => { + if (!contract) return + + try { + setIsSubmitting(true) + + await updateContract(contract.id, { + category: data.category, + type: data.type, + executionMethod: data.executionMethod, + name: data.name, + startDate: data.startDate, + endDate: data.endDate, + validityEndDate: data.validityEndDate, + contractScope: data.contractScope, + notes: data.notes, + linkedRfqOrItb: data.linkedRfqOrItb, + linkedPoNumber: data.linkedPoNumber, + linkedBidNumber: data.linkedBidNumber, + vendorId: contract.vendorId, + lastUpdatedById: userId, + }) + + toast.success("계약 정보가 성공적으로 수정되었습니다.") + onOpenChange(false) + onSuccess?.() + } catch (error) { + console.error("Error updating contract:", error) + toast.error("계약 정보 수정 중 오류가 발생했습니다.") + } finally { + setIsSubmitting(false) + } + } + + return ( + <Sheet open={open} onOpenChange={onOpenChange}> + <SheetContent className="w-[800px] sm:max-w-[800px] flex flex-col" style={{width: 800, maxWidth: 800, height: '100vh'}}> + <SheetHeader className="flex-shrink-0"> + <SheetTitle>계약 정보 수정</SheetTitle> + <SheetDescription> + 계약의 기본 정보를 수정합니다. 변경사항은 즉시 저장됩니다. + </SheetDescription> + </SheetHeader> + + <div className="flex-1 overflow-y-auto min-h-0"> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6 h-full"> + <div className="grid gap-4 py-4"> + {/* 계약구분 */} + <FormField + control={form.control} + name="category" + render={({ field }) => ( + <FormItem> + <FormLabel>계약구분 *</FormLabel> + <Select onValueChange={field.onChange} value={field.value}> + <FormControl> + <SelectTrigger> + <SelectValue placeholder="계약구분을 선택하세요" /> + </SelectTrigger> + </FormControl> + <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> + <FormMessage /> + </FormItem> + )} + /> + + {/* 계약종류 */} + <FormField + control={form.control} + name="type" + render={({ field }) => ( + <FormItem> + <FormLabel>계약종류 *</FormLabel> + <Select onValueChange={field.onChange} value={field.value}> + <FormControl> + <SelectTrigger> + <SelectValue placeholder="계약종류를 선택하세요" /> + </SelectTrigger> + </FormControl> + <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> + <FormMessage /> + </FormItem> + )} + /> + + {/* 체결방식 */} + <FormField + control={form.control} + name="executionMethod" + render={({ field }) => ( + <FormItem> + <FormLabel>체결방식 *</FormLabel> + <Select onValueChange={field.onChange} value={field.value}> + <FormControl> + <SelectTrigger> + <SelectValue placeholder="체결방식을 선택하세요" /> + </SelectTrigger> + </FormControl> + <SelectContent> + {GENERAL_EXECUTION_METHODS.map((method) => { + const methodLabels = { + '전자계약': '전자계약', + '오프라인계약': '오프라인계약' + } + return ( + <SelectItem key={method} value={method}> + {method} - {methodLabels[method as keyof typeof methodLabels]} + </SelectItem> + )})} + </SelectContent> + </Select> + <FormMessage /> + </FormItem> + )} + /> + + {/* 계약명 */} + <FormField + control={form.control} + name="name" + render={({ field }) => ( + <FormItem> + <FormLabel>계약명 *</FormLabel> + <FormControl> + <Input placeholder="계약명을 입력하세요" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 계약시작일 */} + <FormField + control={form.control} + name="startDate" + render={({ field }) => ( + <FormItem> + <FormLabel>계약시작일 *</FormLabel> + <FormControl> + <Input type="date" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 계약종료일 */} + <FormField + control={form.control} + name="endDate" + render={({ field }) => ( + <FormItem> + <FormLabel>계약종료일 *</FormLabel> + <FormControl> + <Input type="date" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 유효기간종료일 */} + <FormField + control={form.control} + name="validityEndDate" + render={({ field }) => ( + <FormItem> + <FormLabel>유효기간종료일 *</FormLabel> + <FormControl> + <Input type="date" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 계약확정범위 */} + <FormField + control={form.control} + name="contractScope" + render={({ field }) => ( + <FormItem> + <FormLabel>계약확정범위 *</FormLabel> + <Select onValueChange={field.onChange} value={field.value}> + <FormControl> + <SelectTrigger> + <SelectValue placeholder="계약확정범위를 선택하세요" /> + </SelectTrigger> + </FormControl> + <SelectContent> + <SelectItem value="단가">단가</SelectItem> + <SelectItem value="금액">금액</SelectItem> + <SelectItem value="물량(실적)">물량(실적)</SelectItem> + </SelectContent> + </Select> + <FormMessage /> + <p className="text-sm text-muted-foreground"> + 해당 계약으로 확정되는 범위를 선택하세요. + </p> + </FormItem> + )} + /> + + {/* 비고 */} + <FormField + control={form.control} + name="notes" + render={({ field }) => ( + <FormItem> + <FormLabel>비고</FormLabel> + <FormControl> + <Textarea + placeholder="비고를 입력하세요" + className="min-h-[100px]" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + + <SheetFooter className="flex-shrink-0 mt-6"> + <Button + type="button" + variant="outline" + onClick={() => onOpenChange(false)} + disabled={isSubmitting} + > + 취소 + </Button> + <Button type="submit" disabled={isSubmitting}> + {isSubmitting ? "수정 중..." : "수정"} + </Button> + </SheetFooter> + </form> + </Form> + </div> + </SheetContent> + </Sheet> + ) +} |
