summaryrefslogtreecommitdiff
path: root/lib/bidding/selection/selection-result-form.tsx
blob: 7f1229a22b275bf6386d333b8aa433a32498ae5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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>
  )
}