Enhance AnnuncioActions and ServizioMain components: refactor document handling and update layout for better responsiveness

This commit is contained in:
Marco Pedone 2025-08-19 19:14:27 +02:00
parent 0ae854ede5
commit 709ac307e1
3 changed files with 147 additions and 107 deletions

View file

@ -47,7 +47,7 @@ import {
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import Link from "next/link"; import Link from "next/link";
import { cn } from "~/lib/utils"; import { cn, formatCurrency } from "~/lib/utils";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { z } from "zod/v4"; import { z } from "zod/v4";
import { Separator } from "~/components/ui/separator"; import { Separator } from "~/components/ui/separator";
@ -67,6 +67,8 @@ import {
type AnimatedButtonRef, type AnimatedButtonRef,
} from "~/components/custom_ui/animated-button"; } from "~/components/custom_ui/animated-button";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import { useTranslation } from "~/providers/I18nProvider";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
export const AnnuncioActions = () => { export const AnnuncioActions = () => {
const { servizioId, userId, isAdmin } = useServizio(); const { servizioId, userId, isAdmin } = useServizio();
@ -537,7 +539,7 @@ const ContrattoSection = ({
<CardContent className="space-y-4"> <CardContent className="space-y-4">
{selectedDoc && ( {selectedDoc && (
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<DocInfo storageId={selectedDoc} /> <DocInfo storageId={selectedDoc}>
<Button <Button
aria-label="Reset Contratto" aria-label="Reset Contratto"
variant="destructive" variant="destructive"
@ -550,8 +552,9 @@ const ContrattoSection = ({
setSelectedDoc(null); setSelectedDoc(null);
}} }}
> >
<Trash2 className="size-6" /> Reset <Trash2 className="size-6" />
</Button> </Button>
</DocInfo>
</div> </div>
)} )}
<DocCombo <DocCombo
@ -628,7 +631,7 @@ const RicevutaSection = ({
<CardContent className="space-y-4"> <CardContent className="space-y-4">
{selectedDoc && ( {selectedDoc && (
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<DocInfo storageId={selectedDoc} /> <DocInfo storageId={selectedDoc}>
<Button <Button
aria-label="Reset Ricevuta" aria-label="Reset Ricevuta"
variant="destructive" variant="destructive"
@ -641,8 +644,9 @@ const RicevutaSection = ({
setSelectedDoc(null); setSelectedDoc(null);
}} }}
> >
<Trash2 className="size-6" /> Reset <Trash2 className="size-6" />
</Button> </Button>
</DocInfo>
</div> </div>
)} )}
<DocCombo <DocCombo
@ -754,9 +758,6 @@ const DocSection = ({
}) => { }) => {
const { userId } = useServizio(); const { userId } = useServizio();
const { data } = useServizioAnnuncio(); const { data } = useServizioAnnuncio();
const [selectedDoc, setSelectedDoc] = useState<StorageindexId | null>(
data.doc_conferma_ref,
);
const utils = api.useUtils(); const utils = api.useUtils();
@ -771,19 +772,6 @@ const DocSection = ({
}, },
}); });
const handleSave = () => {
handleUpdate({
doc_conferma_ref: selectedDoc,
doc_conferma_added: selectedDoc != null,
});
if (selectedDoc) {
setUserStorage({
userId,
fileId: selectedDoc,
});
}
};
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (files == undefined) { if (files == undefined) {
return <p>Errore nel caricamento dei documenti</p>; return <p>Errore nel caricamento dei documenti</p>;
@ -797,10 +785,9 @@ const DocSection = ({
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-4">
{selectedDoc && ( {data.doc_conferma_ref && (
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-start gap-3">
<DocInfo storageId={selectedDoc} /> <DocInfo storageId={data.doc_conferma_ref}>
<Button <Button
aria-label="Reset Conferma" aria-label="Reset Conferma"
variant="destructive" variant="destructive"
@ -812,42 +799,50 @@ const DocSection = ({
}); });
}} }}
> >
<Trash2 /> Reset <Trash2 />
</Button> </Button>
</DocInfo>
</div> </div>
)} )}
<div className="flex flex-wrap items-center gap-3">
<DocCombo <DocCombo
files={files} files={files}
onSelect={(f) => { onSelect={(f) => {
setSelectedDoc(f.id); handleUpdate({
doc_conferma_ref: f.id,
doc_conferma_added: true,
});
setUserStorage({
userId,
fileId: f.id,
});
}} }}
current={selectedDoc} current={data.doc_conferma_ref}
/> />
<UploadModal isAdmin userId={userId} /> <UploadModal isAdmin userId={userId} />
</div>
</CardContent> </CardContent>
<CardFooter>
<Button
aria-label="Save Conferma"
onClick={() => {
handleSave();
}}
variant="success"
>
Salva
</Button>
</CardFooter>
</Card> </Card>
); );
}; };
const DocInfo = ({ storageId }: { storageId: StorageindexId }) => { const DocInfo = ({
storageId,
children,
}: {
storageId: StorageindexId;
children: React.ReactNode;
}) => {
const { data: file_info } = api.storage.getStorageFromId.useQuery({ const { data: file_info } = api.storage.getStorageFromId.useQuery({
storageId, storageId,
}); });
if (!file_info) return null; if (!file_info) return null;
return ( return (
<div className="flex flex-wrap items-center gap-2"> <div className="flex w-full flex-col gap-2">
<Label htmlFor="selected-file">File Selezionato: </Label> <Label htmlFor="selected-file">File Selezionato: </Label>
<div className="flex w-full items-center gap-2 sm:max-w-[30rem]">
<div className="flex w-full flex-1">
<Link <Link
aria-label="Open Selected File" aria-label="Open Selected File"
href={`/area-riservata/allegato-view/${storageId}`} href={`/area-riservata/allegato-view/${storageId}`}
@ -856,15 +851,20 @@ const DocInfo = ({ storageId }: { storageId: StorageindexId }) => {
buttonVariants({ buttonVariants({
variant: "outline", variant: "outline",
}), }),
"flex w-fit items-center justify-center gap-2", "flex w-fit grow items-center gap-2",
)} )}
id="selected-file" id="selected-file"
> >
{file_info.ext && <ExtIcon ext={file_info.ext} />} {file_info.ext && <ExtIcon ext={file_info.ext} />}
<span className="max-w-40 truncate sm:max-w-80">
{file_info.filename} {file_info.filename}
</span>
<ExternalLink className="size-4" /> <ExternalLink className="size-4" />
</Link> </Link>
</div> </div>
{children}
</div>
</div>
); );
}; };
@ -981,7 +981,7 @@ const Caparra = ({
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-4">
<div className="flex items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<Button <Button
aria-label="Import Caparra" aria-label="Import Caparra"
onClick={async () => { onClick={async () => {
@ -993,7 +993,7 @@ const Caparra = ({
variant="info" variant="info"
> >
<ClipboardPaste className="size-4" /> <ClipboardPaste className="size-4" />
Clicca qui per importare la stringa dal gestionale Dal gestionale
</Button> </Button>
<Button <Button
aria-label="Reset Caparra" aria-label="Reset Caparra"
@ -1009,7 +1009,6 @@ const Caparra = ({
variant="destructive" variant="destructive"
> >
<Trash2 className="size-4" /> <Trash2 className="size-4" />
Reset
</Button> </Button>
</div> </div>
{caparra ? ( {caparra ? (
@ -1129,7 +1128,9 @@ const SendConferma = ({
}: { }: {
handleUpdate: (upd: ServizioAnnunciUpdate) => void; handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => { }) => {
const { servizio } = useServizio();
const { data } = useServizioAnnuncio(); const { data } = useServizioAnnuncio();
const { t } = useTranslation();
const [check, setCheck] = useState(data.hasConfermaAdmin); const [check, setCheck] = useState(data.hasConfermaAdmin);
return ( return (
@ -1137,10 +1138,47 @@ const SendConferma = ({
<CardHeader> <CardHeader>
<CardTitle>Lavorazione Conferma</CardTitle> <CardTitle>Lavorazione Conferma</CardTitle>
<CardDescription> <CardDescription>
Se accettare la conferma, controlla i parametri di ricerca prima! controlla i parametri di ricerca prima!
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="space-y-4">
<div className="flex flex-col gap-2">
<p>Tipologia servizio: {servizio.tipologia}</p>
{(() => {
if (servizio.tipologia === TipologiaPosizioneEnum.Transitorio) {
return (
<>
<p>
Permanenza (da preferenze):{" "}
{servizio.permanenza
? t.preferenze.permanenza[servizio.permanenza]
: "non inserita"}
</p>
<p>
Permanenza (da descrizione): &quot;
{(() => {
const match = data.desc_it?.match(/Permanenza:.*$/m);
return match ? match[0] : "";
})()}
&quot;
</p>
</>
);
} else {
return (
<>
<p>
Budget (da preferenze): {formatCurrency(servizio.budget)}
</p>
<p>
Canone Mensile (da descrizione):{" "}
{formatCurrency(data.prezzo / 100)}
</p>
</>
);
}
})()}
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Switch <Switch
aria-label="Conferma Lavorata" aria-label="Conferma Lavorata"

View file

@ -164,7 +164,7 @@ const ServizioMain = () => {
} }
content={ content={
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<div className="flex gap-3"> <div className="flex flex-wrap gap-3">
<Link <Link
href={`/servizio/onboard/${servizio.servizio_id}`} href={`/servizio/onboard/${servizio.servizio_id}`}
aria-label="Attiva Servizio" aria-label="Attiva Servizio"

View file

@ -621,6 +621,8 @@ export const getAllServizioAnnunci = async (userId: UsersId) => {
"servizio.created_at", "servizio.created_at",
"servizio.decorrenza", "servizio.decorrenza",
"servizio.tipologia", "servizio.tipologia",
"servizio.budget",
"servizio.permanenza",
"servizio.isInterrotto", "servizio.isInterrotto",
"servizio.isOkAcconto", "servizio.isOkAcconto",
"servizio.isOkSaldo", "servizio.isOkSaldo",