94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog';
|
|
import { Button } from '@/components/ui/button';
|
|
import { FormField } from '@/components/ui/form-field';
|
|
import { FileDropzone } from '@/components/forms/file-dropzone';
|
|
import { DescriptionList } from '@/components/data/description-list';
|
|
|
|
const ACCEPTED = '.pdf,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif';
|
|
|
|
interface ReplaceDocumentDialogProps {
|
|
document: { fileName: string; quoteNumber: string } | null;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSubmit: (file: File) => Promise<void>;
|
|
}
|
|
|
|
export function ReplaceDocumentDialog({
|
|
document,
|
|
onOpenChange,
|
|
onSubmit,
|
|
}: ReplaceDocumentDialogProps) {
|
|
const t = useTranslations('dashboard.userDocuments');
|
|
const tCommon = useTranslations('common');
|
|
const [files, setFiles] = React.useState<File[]>([]);
|
|
const [submitting, setSubmitting] = React.useState(false);
|
|
|
|
React.useEffect(() => {
|
|
if (document) setFiles([]);
|
|
}, [document]);
|
|
|
|
const submit = async () => {
|
|
if (files.length === 0 || submitting) return;
|
|
setSubmitting(true);
|
|
try {
|
|
await onSubmit(files[0]);
|
|
} finally {
|
|
setSubmitting(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog open={Boolean(document)} onOpenChange={submitting ? undefined : onOpenChange}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>{t('replaceDocument.modalTitle')}</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
{document && (
|
|
<div className="flex flex-col gap-4">
|
|
<DescriptionList
|
|
items={[
|
|
{ label: t('replaceDocument.currentDocument'), value: document.fileName },
|
|
{ label: t('replaceDocument.booking'), value: document.quoteNumber },
|
|
]}
|
|
/>
|
|
|
|
<FormField label={t('replaceDocument.newFile')} required>
|
|
<FileDropzone
|
|
accept={ACCEPTED}
|
|
files={files}
|
|
onFilesChange={setFiles}
|
|
disabled={submitting}
|
|
labels={{
|
|
dropHere: t('replaceDocument.dropHere'),
|
|
dragOrClick: t('replaceDocument.dragOrClick'),
|
|
acceptedFormats: t('replaceDocument.acceptedFormats'),
|
|
remove: tCommon('delete'),
|
|
}}
|
|
/>
|
|
</FormField>
|
|
</div>
|
|
)}
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
|
|
{t('replaceDocument.cancel')}
|
|
</Button>
|
|
<Button onClick={submit} disabled={files.length === 0 || submitting} loading={submitting}>
|
|
{submitting ? t('replaceDocument.replacing') : t('replaceDocument.replace')}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|