diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-12 10:42:36 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-12 10:42:36 +0000 |
| commit | 8642ee064ddf96f1db2b948b4cc8bbbd6cfee820 (patch) | |
| tree | 36bd57d147ba929f1d72918d1fb91ad2c4778624 /lib/bidding/selection/selection-result-form.tsx | |
| parent | 57ea2f740abf1c7933671561cfe0e421fb5ef3fc (diff) | |
(최겸) 구매 일반계약, 입찰 수정
Diffstat (limited to 'lib/bidding/selection/selection-result-form.tsx')
| -rw-r--r-- | lib/bidding/selection/selection-result-form.tsx | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/bidding/selection/selection-result-form.tsx b/lib/bidding/selection/selection-result-form.tsx new file mode 100644 index 00000000..7f1229a2 --- /dev/null +++ b/lib/bidding/selection/selection-result-form.tsx @@ -0,0 +1,143 @@ +'use client' + +import * as React from 'react' +import { useForm } from 'react-hook-form' +import { zodResolver } from '@hookform/resolvers/zod' +import * as z from 'zod' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import { Button } from '@/components/ui/button' +import { Textarea } from '@/components/ui/textarea' +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form' +import { FileUpload } from '@/components/ui/file-upload' +import { useToast } from '@/hooks/use-toast' +import { saveSelectionResult } from './actions' +import { Loader2, Save } from 'lucide-react' + +const selectionResultSchema = z.object({ + summary: z.string().min(1, '결과요약을 입력해주세요'), + attachments: z.array(z.any()).optional(), +}) + +type SelectionResultFormData = z.infer<typeof selectionResultSchema> + +interface SelectionResultFormProps { + biddingId: number + onSuccess: () => void +} + +export function SelectionResultForm({ biddingId, onSuccess }: SelectionResultFormProps) { + const { toast } = useToast() + const [isSubmitting, setIsSubmitting] = React.useState(false) + + const form = useForm<SelectionResultFormData>({ + resolver: zodResolver(selectionResultSchema), + defaultValues: { + summary: '', + attachments: [], + }, + }) + + const onSubmit = async (data: SelectionResultFormData) => { + setIsSubmitting(true) + try { + const result = await saveSelectionResult({ + biddingId, + summary: data.summary, + attachments: data.attachments + }) + + if (result.success) { + toast({ + title: '저장 완료', + description: result.message, + }) + onSuccess() + } else { + toast({ + title: '저장 실패', + description: result.error, + variant: 'destructive', + }) + } + } catch (error) { + console.error('Failed to save selection result:', error) + toast({ + title: '저장 실패', + description: '선정결과 저장 중 오류가 발생했습니다.', + variant: 'destructive', + }) + } finally { + setIsSubmitting(false) + } + } + + return ( + <Card> + <CardHeader> + <CardTitle>선정결과</CardTitle> + </CardHeader> + <CardContent> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6"> + {/* 결과요약 */} + <FormField + control={form.control} + name="summary" + render={({ field }) => ( + <FormItem> + <FormLabel>결과요약</FormLabel> + <FormControl> + <Textarea + placeholder="선정결과에 대한 요약을 입력해주세요..." + className="min-h-[120px]" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 첨부파일 */} + <FormField + control={form.control} + name="attachments" + render={({ field }) => ( + <FormItem> + <FormLabel>첨부파일</FormLabel> + <FormControl> + <FileUpload + value={field.value || []} + onChange={field.onChange} + accept={{ + 'application/pdf': ['.pdf'], + 'application/msword': ['.doc'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], + 'application/vnd.ms-excel': ['.xls'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'], + 'image/*': ['.png', '.jpg', '.jpeg', '.gif'], + }} + maxSize={10 * 1024 * 1024} // 10MB + maxFiles={5} + placeholder="선정결과 관련 문서를 업로드해주세요" + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* 저장 버튼 */} + <div className="flex justify-end"> + <Button type="submit" disabled={isSubmitting}> + {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />} + <Save className="mr-2 h-4 w-4" /> + 저장 + </Button> + </div> + </form> + </Form> + </CardContent> + </Card> + ) +} |
