feat: enhance document upload functionality and add save state indicators in Admin sections
This commit is contained in:
parent
8f3802ede3
commit
890f0572f3
2 changed files with 119 additions and 14 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import {
|
import {
|
||||||
|
CircleAlert,
|
||||||
CircleCheck,
|
CircleCheck,
|
||||||
ClipboardPaste,
|
ClipboardPaste,
|
||||||
FlaskConical,
|
FlaskConical,
|
||||||
|
|
@ -230,7 +231,18 @@ const DocSection = () => {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<UploadModal isAdmin userId={userId} />
|
<UploadModal
|
||||||
|
cb_onUpload={async ({ storageIds }) => {
|
||||||
|
if (storageIds.length === 1 && storageIds[0]) {
|
||||||
|
await updateServizioAnnunci({
|
||||||
|
doc_conferma_added: true,
|
||||||
|
doc_conferma_ref: storageIds[0],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
isAdmin
|
||||||
|
userId={userId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -266,13 +278,16 @@ const parseCaparra = (ingest: string) => {
|
||||||
|
|
||||||
const Caparra = () => {
|
const Caparra = () => {
|
||||||
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
||||||
|
const initialCaparra = {
|
||||||
const [caparra, setCaparra] = useState<CaparraObj | undefined>({
|
|
||||||
caparra_causale: data.caparra_causale,
|
caparra_causale: data.caparra_causale,
|
||||||
caparra_iban: data.caparra_iban,
|
caparra_iban: data.caparra_iban,
|
||||||
caparra_importo: data.caparra_importo,
|
caparra_importo: data.caparra_importo,
|
||||||
caparra_intestazione: data.caparra_intestazione,
|
caparra_intestazione: data.caparra_intestazione,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const [caparra, setCaparra] = useState<CaparraObj | undefined>(
|
||||||
|
initialCaparra,
|
||||||
|
);
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
await updateServizioAnnunci({
|
await updateServizioAnnunci({
|
||||||
caparra_causale: caparra?.caparra_causale || null,
|
caparra_causale: caparra?.caparra_causale || null,
|
||||||
|
|
@ -415,9 +430,10 @@ const Caparra = () => {
|
||||||
<p>Inserisci la stringa dal gestionale e elabora</p>
|
<p>Inserisci la stringa dal gestionale e elabora</p>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter className="gap-4">
|
||||||
<Button
|
<Button
|
||||||
aria-label="Save Caparra"
|
aria-label="Save Caparra"
|
||||||
|
disabled={JSON.stringify(caparra) === JSON.stringify(initialCaparra)}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await handleSave();
|
await handleSave();
|
||||||
}}
|
}}
|
||||||
|
|
@ -425,6 +441,19 @@ const Caparra = () => {
|
||||||
>
|
>
|
||||||
Salva
|
Salva
|
||||||
</Button>
|
</Button>
|
||||||
|
{JSON.stringify(caparra) !== JSON.stringify(initialCaparra) ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleAlert className="size-5 text-orange-500" />
|
||||||
|
<span className="text-orange-500">Salva modifiche</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
Object.values(initialCaparra).every((v) => v !== null) && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleCheck className="size-5 text-green-500" />
|
||||||
|
<span className="text-green-500">Dati salvati</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
import { CircleCheck, ClipboardPaste, Pen, Trash2, Wrench } from "lucide-react";
|
import {
|
||||||
|
CircleAlert,
|
||||||
|
CircleCheck,
|
||||||
|
ClipboardPaste,
|
||||||
|
Pen,
|
||||||
|
Trash2,
|
||||||
|
Wrench,
|
||||||
|
} from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
|
|
@ -77,6 +84,7 @@ export const AdminContratto = () => {
|
||||||
const ContrattoSection = () => {
|
const ContrattoSection = () => {
|
||||||
const { userId } = useServizio();
|
const { userId } = useServizio();
|
||||||
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
||||||
|
const initialDoc = data.doc_contratto_ref;
|
||||||
const [selectedDoc, setSelectedDoc] = useState<string | null>(
|
const [selectedDoc, setSelectedDoc] = useState<string | null>(
|
||||||
data.doc_contratto_ref,
|
data.doc_contratto_ref,
|
||||||
);
|
);
|
||||||
|
|
@ -112,6 +120,7 @@ const ContrattoSection = () => {
|
||||||
if (files === undefined) {
|
if (files === undefined) {
|
||||||
return <p>Errore nel caricamento dei documenti</p>;
|
return <p>Errore nel caricamento dei documenti</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|
@ -146,11 +155,20 @@ const ContrattoSection = () => {
|
||||||
setSelectedDoc(f.id);
|
setSelectedDoc(f.id);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<UploadModal isAdmin userId={userId} />
|
<UploadModal
|
||||||
|
cb_onUpload={({ storageIds }) => {
|
||||||
|
if (storageIds.length === 1 && storageIds[0]) {
|
||||||
|
setSelectedDoc(storageIds[0]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
isAdmin
|
||||||
|
userId={userId}
|
||||||
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter className="gap-4">
|
||||||
<Button
|
<Button
|
||||||
aria-label="Save Contratto"
|
aria-label="Save Contratto"
|
||||||
|
disabled={selectedDoc === initialDoc}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await handleSave();
|
await handleSave();
|
||||||
}}
|
}}
|
||||||
|
|
@ -158,6 +176,20 @@ const ContrattoSection = () => {
|
||||||
>
|
>
|
||||||
Salva
|
Salva
|
||||||
</Button>
|
</Button>
|
||||||
|
{selectedDoc !== initialDoc ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleAlert className="size-5 text-orange-500" />
|
||||||
|
<span className="text-orange-500">Salva modifiche</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
initialDoc &&
|
||||||
|
selectedDoc === initialDoc && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleCheck className="size-5 text-green-500" />
|
||||||
|
<span className="text-green-500">Dati salvati</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
@ -217,8 +249,7 @@ const parseContrattoImport = (ingest: string) => {
|
||||||
|
|
||||||
const ContrattoImport = () => {
|
const ContrattoImport = () => {
|
||||||
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
||||||
|
const initialContratto = {
|
||||||
const [contratto, setContratto] = useState<ContrattoImportObj | undefined>({
|
|
||||||
contratto_decorrenza: data.contratto_decorrenza
|
contratto_decorrenza: data.contratto_decorrenza
|
||||||
? new Date(data.contratto_decorrenza)
|
? new Date(data.contratto_decorrenza)
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -227,7 +258,11 @@ const ContrattoImport = () => {
|
||||||
: null,
|
: null,
|
||||||
contratto_tipo: data.contratto_tipo as ContrattoImportObj["contratto_tipo"],
|
contratto_tipo: data.contratto_tipo as ContrattoImportObj["contratto_tipo"],
|
||||||
gestionale_id: data.gestionale_id,
|
gestionale_id: data.gestionale_id,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const [contratto, setContratto] = useState<ContrattoImportObj | undefined>(
|
||||||
|
initialContratto,
|
||||||
|
);
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
await updateServizioAnnunci({
|
await updateServizioAnnunci({
|
||||||
contratto_decorrenza: contratto?.contratto_decorrenza || null,
|
contratto_decorrenza: contratto?.contratto_decorrenza || null,
|
||||||
|
|
@ -404,9 +439,12 @@ const ContrattoImport = () => {
|
||||||
<p>Inserisci la stringa dal gestionale e elabora</p>
|
<p>Inserisci la stringa dal gestionale e elabora</p>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter className="gap-4">
|
||||||
<Button
|
<Button
|
||||||
aria-label="Save Contratto"
|
aria-label="Save Contratto"
|
||||||
|
disabled={
|
||||||
|
JSON.stringify(contratto) === JSON.stringify(initialContratto)
|
||||||
|
}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await handleSave();
|
await handleSave();
|
||||||
}}
|
}}
|
||||||
|
|
@ -414,6 +452,19 @@ const ContrattoImport = () => {
|
||||||
>
|
>
|
||||||
Salva
|
Salva
|
||||||
</Button>
|
</Button>
|
||||||
|
{JSON.stringify(contratto) !== JSON.stringify(initialContratto) ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleAlert className="size-5 text-orange-500" />
|
||||||
|
<span className="text-orange-500">Salva modifiche</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
Object.values(initialContratto).every((v) => v !== null) && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleCheck className="size-5 text-green-500" />
|
||||||
|
<span className="text-green-500">Dati salvati</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
@ -422,6 +473,7 @@ const ContrattoImport = () => {
|
||||||
const RicevutaSection = () => {
|
const RicevutaSection = () => {
|
||||||
const { userId } = useServizio();
|
const { userId } = useServizio();
|
||||||
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
const { data, updateServizioAnnunci } = useServizioAnnuncio();
|
||||||
|
const initialDoc = data.doc_registrazione_ref;
|
||||||
const [selectedDoc, setSelectedDoc] = useState<string | null>(
|
const [selectedDoc, setSelectedDoc] = useState<string | null>(
|
||||||
data.doc_registrazione_ref,
|
data.doc_registrazione_ref,
|
||||||
);
|
);
|
||||||
|
|
@ -457,6 +509,7 @@ const RicevutaSection = () => {
|
||||||
if (files === undefined) {
|
if (files === undefined) {
|
||||||
return <p>Errore nel caricamento dei documenti</p>;
|
return <p>Errore nel caricamento dei documenti</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|
@ -491,11 +544,20 @@ const RicevutaSection = () => {
|
||||||
setSelectedDoc(f.id);
|
setSelectedDoc(f.id);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<UploadModal isAdmin userId={userId} />
|
<UploadModal
|
||||||
|
cb_onUpload={({ storageIds }) => {
|
||||||
|
if (storageIds.length === 1 && storageIds[0]) {
|
||||||
|
setSelectedDoc(storageIds[0]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
isAdmin
|
||||||
|
userId={userId}
|
||||||
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter className="gap-4">
|
||||||
<Button
|
<Button
|
||||||
aria-label="Save Ricevuta"
|
aria-label="Save Ricevuta"
|
||||||
|
disabled={selectedDoc === initialDoc}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await handleSave();
|
await handleSave();
|
||||||
}}
|
}}
|
||||||
|
|
@ -503,6 +565,20 @@ const RicevutaSection = () => {
|
||||||
>
|
>
|
||||||
Salva
|
Salva
|
||||||
</Button>
|
</Button>
|
||||||
|
{selectedDoc !== initialDoc ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleAlert className="size-5 text-orange-500" />
|
||||||
|
<span className="text-orange-500">Salva modifiche</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
initialDoc &&
|
||||||
|
selectedDoc === initialDoc && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CircleCheck className="size-5 text-green-500" />
|
||||||
|
<span className="text-green-500">Dati salvati</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue