summaryrefslogtreecommitdiff
path: root/lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx')
-rw-r--r--lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx427
1 files changed, 0 insertions, 427 deletions
diff --git a/lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx b/lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx
deleted file mode 100644
index 8cc4fa6f..00000000
--- a/lib/vendor-rfq-response/vendor-cbe-table/respond-cbe-sheet.tsx
+++ /dev/null
@@ -1,427 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { zodResolver } from "@hookform/resolvers/zod"
-import { Loader } from "lucide-react"
-import { useForm } from "react-hook-form"
-import { toast } from "sonner"
-import { z } from "zod"
-
-import { Button } from "@/components/ui/button"
-import {
- Form,
- FormControl,
- FormField,
- FormItem,
- FormLabel,
- FormMessage,
-} from "@/components/ui/form"
-import {
- Select,
- SelectContent,
- SelectGroup,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/components/ui/select"
-import { Input } from "@/components/ui/input"
-import {
- Sheet,
- SheetClose,
- SheetContent,
- SheetDescription,
- SheetFooter,
- SheetHeader,
- SheetTitle,
-} from "@/components/ui/sheet"
-import { Textarea } from "@/components/ui/textarea"
-import { VendorWithCbeFields } from "@/config/vendorCbeColumnsConfig"
-import { getCommercialResponseByResponseId, updateCommercialResponse } from "../service"
-
-// Define schema for form validation (client-side)
-const commercialResponseFormSchema = z.object({
- responseStatus: z.enum(["PENDING", "IN_PROGRESS", "SUBMITTED", "REJECTED", "ACCEPTED"]),
- totalPrice: z.coerce.number().optional(),
- currency: z.string().default("USD"),
- paymentTerms: z.string().optional(),
- incoterms: z.string().optional(),
- deliveryPeriod: z.string().optional(),
- warrantyPeriod: z.string().optional(),
- validityPeriod: z.string().optional(),
- priceBreakdown: z.string().optional(),
- commercialNotes: z.string().optional(),
-})
-
-type CommercialResponseFormInput = z.infer<typeof commercialResponseFormSchema>
-
-interface CommercialResponseSheetProps
- extends React.ComponentPropsWithRef<typeof Sheet> {
- rfq: VendorWithCbeFields | null
- responseId: number | null // This is the vendor_responses.id
- onSuccess?: () => void
-}
-
-export function CommercialResponseSheet({
- rfq,
- responseId,
- onSuccess,
- ...props
-}: CommercialResponseSheetProps) {
- const [isSubmitting, startSubmitTransition] = React.useTransition()
- const [isLoading, setIsLoading] = React.useState(true)
-
- const form = useForm<CommercialResponseFormInput>({
- resolver: zodResolver(commercialResponseFormSchema),
- defaultValues: {
- responseStatus: "PENDING",
- totalPrice: undefined,
- currency: "USD",
- paymentTerms: "",
- incoterms: "",
- deliveryPeriod: "",
- warrantyPeriod: "",
- validityPeriod: "",
- priceBreakdown: "",
- commercialNotes: "",
- },
- })
-
- // Load existing commercial response data when sheet opens
- React.useEffect(() => {
- async function loadCommercialResponse() {
- if (!responseId) return
-
- setIsLoading(true)
- try {
- // Use the helper function to get existing data
- const existingResponse = await getCommercialResponseByResponseId(responseId)
-
- if (existingResponse) {
- // If we found existing data, populate the form
- form.reset({
- responseStatus: existingResponse.responseStatus,
- totalPrice: existingResponse.totalPrice,
- currency: existingResponse.currency || "USD",
- paymentTerms: existingResponse.paymentTerms || "",
- incoterms: existingResponse.incoterms || "",
- deliveryPeriod: existingResponse.deliveryPeriod || "",
- warrantyPeriod: existingResponse.warrantyPeriod || "",
- validityPeriod: existingResponse.validityPeriod || "",
- priceBreakdown: existingResponse.priceBreakdown || "",
- commercialNotes: existingResponse.commercialNotes || "",
- })
- } else if (rfq) {
- // If no existing data but we have rfq data with some values already
- form.reset({
- responseStatus: rfq.commercialResponseStatus as any || "PENDING",
- totalPrice: rfq.totalPrice || undefined,
- currency: rfq.currency || "USD",
- paymentTerms: rfq.paymentTerms || "",
- incoterms: rfq.incoterms || "",
- deliveryPeriod: rfq.deliveryPeriod || "",
- warrantyPeriod: rfq.warrantyPeriod || "",
- validityPeriod: rfq.validityPeriod || "",
- priceBreakdown: "",
- commercialNotes: "",
- })
- }
- } catch (error) {
- console.error("Failed to load commercial response data:", error)
- toast.error("상업 응답 데이터를 불러오는데 실패했습니다")
- } finally {
- setIsLoading(false)
- }
- }
-
- loadCommercialResponse()
- }, [responseId, rfq, form])
-
- function onSubmit(formData: CommercialResponseFormInput) {
- if (!responseId) {
- toast.error("응답 ID를 찾을 수 없습니다")
- return
- }
-
- if (!rfq?.vendorId) {
- toast.error("협력업체 ID를 찾을 수 없습니다")
- return
- }
-
- startSubmitTransition(async () => {
- try {
- // Pass both responseId and vendorId to the server action
- const result = await updateCommercialResponse({
- responseId,
- vendorId: rfq.vendorId, // Include vendorId for revalidateTag
- ...formData,
- })
-
- if (!result.success) {
- toast.error(result.error || "응답 제출 중 오류가 발생했습니다")
- return
- }
-
- toast.success("Commercial response successfully submitted")
- props.onOpenChange?.(false)
-
- if (onSuccess) {
- onSuccess()
- }
- } catch (error) {
- console.error("Error submitting response:", error)
- toast.error("응답 제출 중 오류가 발생했습니다")
- }
- })
- }
-
- return (
- <Sheet {...props}>
- <SheetContent className="flex flex-col gap-6 sm:max-w-md">
- <SheetHeader className="text-left">
- <SheetTitle>Commercial Response</SheetTitle>
- <SheetDescription>
- {rfq?.rfqCode && <span className="font-medium">{rfq.rfqCode}</span>}
- <div className="mt-1">Please provide your commercial response for this RFQ</div>
- </SheetDescription>
- </SheetHeader>
-
- {isLoading ? (
- <div className="flex items-center justify-center py-8">
- <Loader className="h-8 w-8 animate-spin text-muted-foreground" />
- </div>
- ) : (
- <Form {...form}>
- <form
- onSubmit={form.handleSubmit(onSubmit)}
- className="flex flex-col gap-4 overflow-y-auto max-h-[calc(100vh-200px)] pr-2"
- >
- <FormField
- control={form.control}
- name="responseStatus"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Response Status</FormLabel>
- <Select
- onValueChange={field.onChange}
- defaultValue={field.value}
- >
- <FormControl>
- <SelectTrigger className="capitalize">
- <SelectValue placeholder="Select response status" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- <SelectGroup>
- <SelectItem value="PENDING">Pending</SelectItem>
- <SelectItem value="IN_PROGRESS">In Progress</SelectItem>
- <SelectItem value="SUBMITTED">Submitted</SelectItem>
- </SelectGroup>
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <div className="grid grid-cols-2 gap-4">
- <FormField
- control={form.control}
- name="totalPrice"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Total Price</FormLabel>
- <FormControl>
- <Input
- type="number"
- placeholder="0.00"
- {...field}
- value={field.value || ''}
- onChange={(e) => {
- const value = e.target.value === '' ? undefined : parseFloat(e.target.value);
- field.onChange(value);
- }}
- />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="currency"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Currency</FormLabel>
- <Select
- onValueChange={field.onChange}
- defaultValue={field.value}
- >
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Select currency" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- <SelectGroup>
- <SelectItem value="USD">USD</SelectItem>
- <SelectItem value="EUR">EUR</SelectItem>
- <SelectItem value="GBP">GBP</SelectItem>
- <SelectItem value="KRW">KRW</SelectItem>
- <SelectItem value="JPY">JPY</SelectItem>
- </SelectGroup>
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
- </div>
-
- {/* Other form fields remain the same */}
- <FormField
- control={form.control}
- name="paymentTerms"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Payment Terms</FormLabel>
- <FormControl>
- <Input placeholder="e.g. Net 30" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="incoterms"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Incoterms</FormLabel>
- <Select
- onValueChange={field.onChange}
- defaultValue={field.value || ''}
- >
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Select incoterms" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- <SelectGroup>
- <SelectItem value="EXW">EXW (Ex Works)</SelectItem>
- <SelectItem value="FCA">FCA (Free Carrier)</SelectItem>
- <SelectItem value="FOB">FOB (Free On Board)</SelectItem>
- <SelectItem value="CIF">CIF (Cost, Insurance & Freight)</SelectItem>
- <SelectItem value="DAP">DAP (Delivered At Place)</SelectItem>
- <SelectItem value="DDP">DDP (Delivered Duty Paid)</SelectItem>
- </SelectGroup>
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="deliveryPeriod"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Delivery Period</FormLabel>
- <FormControl>
- <Input placeholder="e.g. 4-6 weeks" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="warrantyPeriod"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Warranty Period</FormLabel>
- <FormControl>
- <Input placeholder="e.g. 12 months" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="validityPeriod"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Validity Period</FormLabel>
- <FormControl>
- <Input placeholder="e.g. 30 days" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="priceBreakdown"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Price Breakdown (Optional)</FormLabel>
- <FormControl>
- <Textarea
- placeholder="Enter price breakdown details here"
- className="min-h-[100px]"
- {...field}
- />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <FormField
- control={form.control}
- name="commercialNotes"
- render={({ field }) => (
- <FormItem>
- <FormLabel>Additional Notes (Optional)</FormLabel>
- <FormControl>
- <Textarea
- placeholder="Any additional comments or notes"
- className="min-h-[100px]"
- {...field}
- />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
-
- <SheetFooter className="gap-2 pt-4 sm:space-x-0">
- <SheetClose asChild>
- <Button type="button" variant="outline">
- Cancel
- </Button>
- </SheetClose>
- <Button disabled={isSubmitting} type="submit">
- {isSubmitting && (
- <Loader
- className="mr-2 size-4 animate-spin"
- aria-hidden="true"
- />
- )}
- Submit Response
- </Button>
- </SheetFooter>
- </form>
- </Form>
- )}
- </SheetContent>
- </Sheet>
- )
-} \ No newline at end of file