diff options
Diffstat (limited to 'components/bidding/manage/bidding-basic-info-editor.tsx')
| -rw-r--r-- | components/bidding/manage/bidding-basic-info-editor.tsx | 136 |
1 files changed, 77 insertions, 59 deletions
diff --git a/components/bidding/manage/bidding-basic-info-editor.tsx b/components/bidding/manage/bidding-basic-info-editor.tsx index e92c39a5..f0d56689 100644 --- a/components/bidding/manage/bidding-basic-info-editor.tsx +++ b/components/bidding/manage/bidding-basic-info-editor.tsx @@ -45,6 +45,16 @@ import type { ProcurementManagerWithUser } from '@/components/common/selectors/p import { getBiddingDocuments, uploadBiddingDocument, deleteBiddingDocument } from '@/lib/bidding/detail/service' import { downloadFile } from '@/lib/file-download' +// Dropzone components +import { + Dropzone, + DropzoneDescription, + DropzoneInput, + DropzoneTitle, + DropzoneUploadIcon, + DropzoneZone, +} from "@/components/ui/dropzone" + // 입찰 기본 정보 에디터 컴포넌트 interface BiddingBasicInfo { title?: string @@ -78,6 +88,7 @@ interface BiddingBasicInfo { interface BiddingBasicInfoEditorProps { biddingId: number + readonly?: boolean } interface UploadedDocument { @@ -95,7 +106,7 @@ interface UploadedDocument { uploadedBy: string } -export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProps) { +export function BiddingBasicInfoEditor({ biddingId, readonly = false }: BiddingBasicInfoEditorProps) { const [isLoading, setIsLoading] = React.useState(true) const [isSubmitting, setIsSubmitting] = React.useState(false) const [isLoadingTemplate, setIsLoadingTemplate] = React.useState(false) @@ -535,7 +546,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp <FormItem> <FormLabel>입찰명 <span className="text-red-500">*</span></FormLabel> <FormControl> - <Input placeholder="입찰명을 입력하세요" {...field} /> + <Input placeholder="입찰명을 입력하세요" {...field} disabled={readonly} /> </FormControl> <FormMessage /> </FormItem> @@ -883,7 +894,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp <FormItem> <FormLabel>입찰개요</FormLabel> <FormControl> - <Textarea placeholder="입찰에 대한 설명을 입력하세요" rows={2} {...field} /> + <Textarea placeholder="입찰에 대한 설명을 입력하세요" rows={2} {...field} readOnly={readonly} /> </FormControl> <FormMessage /> </FormItem> @@ -896,7 +907,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp <FormItem> <FormLabel>비고</FormLabel> <FormControl> - <Textarea placeholder="추가 사항이나 참고사항을 입력하세요" rows={3} {...field} /> + <Textarea placeholder="추가 사항이나 참고사항을 입력하세요" rows={3} {...field} readOnly={readonly} /> </FormControl> <FormMessage /> </FormItem> @@ -1123,6 +1134,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp })) }} rows={3} + readOnly={readonly} /> </div> </div> @@ -1138,7 +1150,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp <TiptapEditor content={field.value || noticeTemplate} setContent={field.onChange} - disabled={isLoadingTemplate} + disabled={isLoadingTemplate || readonly} height="300px" /> </div> @@ -1156,12 +1168,14 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp </div> {/* 액션 버튼 */} - <div className="flex justify-end gap-4 pt-4"> - <Button type="submit" disabled={isSubmitting} className="flex items-center gap-2"> - {isSubmitting ? '저장 중...' : '저장'} - <ChevronRight className="h-4 w-4" /> - </Button> - </div> + {!readonly && ( + <div className="flex justify-end gap-4 pt-4"> + <Button type="submit" disabled={isSubmitting} className="flex items-center gap-2"> + {isSubmitting ? '저장 중...' : '저장'} + <ChevronRight className="h-4 w-4" /> + </Button> + </div> + )} </form> </Form> </CardContent> @@ -1175,33 +1189,35 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp SHI용 첨부파일 </CardTitle> <p className="text-sm text-muted-foreground"> - SHI에서 제공하는 문서나 파일을 업로드하세요 + 내부 보관를 위해 필요한 문서나 파일을 업로드 하세요. </p> </CardHeader> <CardContent className="space-y-4"> - <div className="border-2 border-dashed border-gray-300 rounded-lg p-6"> - <div className="text-center"> - <Upload className="h-12 w-12 text-gray-400 mx-auto mb-4" /> - <div className="space-y-2"> - <p className="text-sm text-gray-600"> - 파일을 드래그 앤 드롭하거나{' '} - <label className="text-blue-600 hover:text-blue-500 cursor-pointer"> - <input - type="file" - multiple - className="hidden" - onChange={(e) => { - const files = Array.from(e.target.files || []) - setShiAttachmentFiles(prev => [...prev, ...files]) - }} - accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg" - /> - 찾아보세요 - </label> - </p> - </div> - </div> - </div> + <Dropzone + maxSize={6e8} // 600MB + onDropAccepted={(files) => { + const newFiles = Array.from(files) + setShiAttachmentFiles(prev => [...prev, ...newFiles]) + }} + onDropRejected={() => { + toast({ + title: "File upload rejected", + description: "Please check file size and type.", + variant: "destructive", + }) + }} + > + {() => ( + <DropzoneZone className="flex justify-center h-32"> + <div className="flex items-center gap-6"> + <DropzoneUploadIcon /> + <div className="grid gap-0.5"> + <DropzoneTitle>파일을 드래그하여 업로드</DropzoneTitle> + </div> + </div> + </DropzoneZone> + )} + </Dropzone> {shiAttachmentFiles.length > 0 && ( <div className="space-y-2"> @@ -1307,33 +1323,35 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp 협력업체용 첨부파일 </CardTitle> <p className="text-sm text-muted-foreground"> - 협력업체에서 제공하는 문서나 파일을 업로드하세요 + 협력사로 제공하는 문서나 파일을 업로드 하세요. </p> </CardHeader> <CardContent className="space-y-4"> - <div className="border-2 border-dashed border-gray-300 rounded-lg p-6"> - <div className="text-center"> - <Upload className="h-12 w-12 text-gray-400 mx-auto mb-4" /> - <div className="space-y-2"> - <p className="text-sm text-gray-600"> - 파일을 드래그 앤 드롭하거나{' '} - <label className="text-blue-600 hover:text-blue-500 cursor-pointer"> - <input - type="file" - multiple - className="hidden" - onChange={(e) => { - const files = Array.from(e.target.files || []) - setVendorAttachmentFiles(prev => [...prev, ...files]) - }} - accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg" - /> - 찾아보세요 - </label> - </p> - </div> - </div> - </div> + <Dropzone + maxSize={6e8} // 600MB + onDropAccepted={(files) => { + const newFiles = Array.from(files) + setVendorAttachmentFiles(prev => [...prev, ...newFiles]) + }} + onDropRejected={() => { + toast({ + title: "File upload rejected", + description: "Please check file size and type.", + variant: "destructive", + }) + }} + > + {() => ( + <DropzoneZone className="flex justify-center h-32"> + <div className="flex items-center gap-6"> + <DropzoneUploadIcon /> + <div className="grid gap-0.5"> + <DropzoneTitle>파일을 드래그하여 업로드</DropzoneTitle> + </div> + </div> + </DropzoneZone> + )} + </Dropzone> {vendorAttachmentFiles.length > 0 && ( <div className="space-y-2"> |
