feat: update Admin confirmation modal to display transient status information; refactor related components and enhance localization strings

This commit is contained in:
Marco Pedone 2025-11-12 17:05:05 +01:00
parent 3dc0bccb58
commit 169dccfc7d
9 changed files with 139 additions and 65 deletions

View file

@ -33,42 +33,37 @@ ENV NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL
ARG NEXT_PUBLIC_STRIPE_PUBLIC_KEY ARG NEXT_PUBLIC_STRIPE_PUBLIC_KEY
ENV NEXT_PUBLIC_STRIPE_PUBLIC_KEY=$NEXT_PUBLIC_STRIPE_PUBLIC_KEY ENV NEXT_PUBLIC_STRIPE_PUBLIC_KEY=$NEXT_PUBLIC_STRIPE_PUBLIC_KEY
ARG INTERNAL_BASE_URL # ARG INTERNAL_BASE_URL
ENV INTERNAL_BASE_URL=$INTERNAL_BASE_URL # ENV INTERNAL_BASE_URL=$INTERNAL_BASE_URL
# ARG POSTGRES_USER
# ARG POSTGRES_PASSWORD
# ARG POSTGRES_DB
# ARG PGHOST
# ARG PGPORT
# ENV PGHOST=$PGHOST
# ENV POSTGRES_DB=$POSTGRES_DB
# ENV PGPORT=$PGPORT
# ENV POSTGRES_USER=$POSTGRES_USER
# ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD
# ENV JWT_SECRET="build-time-mock"
# ENV BACKENDSERVER_URL="http://backend:1323"
# ENV STRIPE_SECRET_KEY="mock"
# ENV STRIPE_WEBHOOK_SECRET="mock"
# ENV FIC_CLIENT_ID="mock"
# ENV FIC_ACCESS_TOKEN="mock"
# ENV FIC_COMPANY_ID="mock"
# ENV ARUBA_USER="mock"
# ENV ARUBA_PASS="mock"
# ENV EXP_API_USER="mock"
# ENV EXP_API_PASS="mock"
# ENV KEYDB_URL="localhost:6380"
# ENV TILES_URL="localhost:6379"
# ENV SKEBBY_USER="mock"
# ENV SKEBBY_PASS="mock"
# ENV REVALIDATION_SECRET="mock"
# ENV STORAGE_URL="mock"
# ENV STORAGE_TOKEN="mock"
# Database connection for build (if needed for static generation)
ARG POSTGRES_USER
ARG POSTGRES_PASSWORD
ARG POSTGRES_DB
ARG PGHOST
ARG PGPORT
ENV PGHOST=$PGHOST
ENV POSTGRES_DB=$POSTGRES_DB
ENV PGPORT=$PGPORT
ENV POSTGRES_USER=$POSTGRES_USER
ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD
# Mock/empty values for validation bypass during build
ENV JWT_SECRET="build-time-mock"
ENV BACKENDSERVER_URL="http://backend:1323"
ENV STRIPE_SECRET_KEY="mock"
ENV STRIPE_WEBHOOK_SECRET="mock"
ENV FIC_CLIENT_ID="mock"
ENV FIC_ACCESS_TOKEN="mock"
ENV FIC_COMPANY_ID="mock"
ENV ARUBA_USER="mock"
ENV ARUBA_PASS="mock"
ENV EXP_API_USER="mock"
ENV EXP_API_PASS="mock"
ENV KEYDB_URL="localhost:6380"
ENV TILES_URL="localhost:6379"
ENV SKEBBY_USER="mock"
ENV SKEBBY_PASS="mock"
ENV REVALIDATION_SECRET="mock"
ENV STORAGE_URL="mock"
ENV STORAGE_TOKEN="mock"
#TODO remove variabili non necessarie al build tanto la validazione viene saltata
RUN SKIP_ENV_VALIDATION=1 npm run build RUN SKIP_ENV_VALIDATION=1 npm run build

View file

@ -1,6 +1,6 @@
TODOS: TODOS:
- Post modale conferma, mostrare se transitorio , modale con informativa tipo:" il saldo del servizio e il periodo di permanenza veranno adeguati alle condizioni stabilite insieme al locatore nel momento della trattativa e alla documentazione presentata come giustificazione di transitorietà" (modificato)

View file

@ -1,5 +1,12 @@
import { format } from "date-fns"; import { format } from "date-fns";
import { CircleCheck, ClipboardPaste, Pen, Trash2, Wrench } from "lucide-react"; import {
CircleCheck,
ClipboardPaste,
FlaskConical,
Pen,
Trash2,
Wrench,
} from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
@ -11,6 +18,7 @@ import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage"; import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { Confirm } from "../confirm";
import { import {
Credenza, Credenza,
CredenzaBody, CredenzaBody,
@ -39,6 +47,7 @@ import {
CardTitle, CardTitle,
} from "../ui/card"; } from "../ui/card";
import { Label } from "../ui/label"; import { Label } from "../ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import { Switch } from "../ui/switch"; import { Switch } from "../ui/switch";
import { UploadModal } from "../upload_modal"; import { UploadModal } from "../upload_modal";
import { DocCombo, DocInfo } from "./shared"; import { DocCombo, DocInfo } from "./shared";
@ -82,6 +91,7 @@ export const AdminLavoraConferma = () => {
</CredenzaBody> </CredenzaBody>
<CredenzaFooter> <CredenzaFooter>
<DebugActions />
<CredenzaClose asChild> <CredenzaClose asChild>
<Button aria-label="Close Credenza" variant="outline"> <Button aria-label="Close Credenza" variant="outline">
Chiudi Chiudi
@ -93,6 +103,66 @@ export const AdminLavoraConferma = () => {
); );
}; };
const DebugActions = () => {
const { servizioId, userId } = useServizio();
const { annuncioId } = useServizioAnnuncio();
const utils = api.useUtils();
const { mutate } = api.servizio.updateServizioAnnunci.useMutation({
onError: (error) => {
toast.error(error.message);
},
onSuccess: async () => {
await utils.servizio.getAllServizioAnnunci.invalidate({
userId: userId,
});
await utils.servizio.getServizio.invalidate({
servizioId,
});
toast.success("Dati salvati con successo");
},
});
return (
<Popover>
<PopoverTrigger asChild>
<Button>
<FlaskConical />
<span>Debug</span>
</Button>
</PopoverTrigger>
<PopoverContent
align="end"
className="flex w-fit flex-col items-center gap-4"
>
<Confirm
description="Sei sicuro di voler eliminare l'annuncio?"
onConfirm={() => {
mutate({
annuncioId,
servizioId,
data: {
user_confirmed_at: null,
},
});
}}
title="Elimina annuncio"
>
<Button
aria-label="Delete Annuncio"
className="w-full"
size="sm"
variant="destructive"
>
<Trash2 />
<span>Elimina Conferma</span>
</Button>
</Confirm>
</PopoverContent>
</Popover>
);
};
const DocSection = () => { const DocSection = () => {
const { userId } = useServizio(); const { userId } = useServizio();
const { data, updateServizioAnnunci } = useServizioAnnuncio(); const { data, updateServizioAnnunci } = useServizioAnnuncio();

View file

@ -54,13 +54,12 @@ export const ConfermaAnnuncioModal = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
//TODO need to show messaggio in alert dialog after invio conferma about adeguamento saldo e permanenza based on doc presented
const needsDocuments = const needsDocuments =
!servizio.skipDocMotivazione && !servizio.skipDocMotivazione &&
!servizio.doc_motivazione && !servizio.doc_motivazione &&
servizio.tipologia === TipologiaPosizioneEnum.Transitorio; servizio.tipologia === TipologiaPosizioneEnum.Transitorio;
return ( return (
<>
<Credenza onOpenChange={setOpen} open={open}> <Credenza onOpenChange={setOpen} open={open}>
<CredenzaTrigger asChild> <CredenzaTrigger asChild>
<Button aria-label="Conferma immobile" className="w-fit"> <Button aria-label="Conferma immobile" className="w-fit">
@ -74,17 +73,19 @@ export const ConfermaAnnuncioModal = () => {
{t.richieste.conf_desc} {t.richieste.conf_desc}
</CredenzaDescription> </CredenzaDescription>
</CredenzaHeader> </CredenzaHeader>
{needsDocuments ? ( {needsDocuments ? (
<DocCheckpoint /> <DocCheckpoint />
) : ( ) : (
<InvioConferma setOpen={setOpen} /> <InvioConferma closeModal={() => setOpen(false)} />
)} )}
</CredenzaContent> </CredenzaContent>
</Credenza> </Credenza>
</>
); );
}; };
const InvioConferma = ({ setOpen }: { setOpen: (value: boolean) => void }) => { const InvioConferma = ({ closeModal }: { closeModal: () => void }) => {
const { userId, servizioId } = useServizio(); const { userId, servizioId } = useServizio();
const { annuncioId } = useServizioAnnuncio(); const { annuncioId } = useServizioAnnuncio();
const { t } = useTranslation(); const { t } = useTranslation();
@ -103,15 +104,16 @@ const InvioConferma = ({ setOpen }: { setOpen: (value: boolean) => void }) => {
}); });
await utils.servizio.getAllServizioAnnunci.invalidate({ userId }); await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
setOpen(false); closeModal();
}, },
}, },
); );
return ( return (
<> <>
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5"> <CredenzaBody className="flex flex-col gap-4">
<p>{t.richieste.conferma_txt}</p> <p>{t.richieste.conferma_txt}</p>
<p className="text-sm">{t.richieste.conf_alert}</p>
</CredenzaBody> </CredenzaBody>
<CredenzaFooter> <CredenzaFooter>
<LoadingButton <LoadingButton

View file

@ -202,9 +202,8 @@ export const ServizioContent = () => {
const annunciSelezionati = servizio.annunci.filter( const annunciSelezionati = servizio.annunci.filter(
(a) => a.user_confirmed_at === null, (a) => a.user_confirmed_at === null,
); );
const openContattiAnnunci = servizio.annunci.filter( const openContattiAnnunci = servizio.annunci.filter(
(a) => a.open_contatti_at !== null && a.user_confirmed_at === null, (a) => a.open_contatti_at !== null,
); );
const annunciInConferma = servizio.annunci.filter( const annunciInConferma = servizio.annunci.filter(

View file

@ -1233,6 +1233,7 @@ The Stable Rent service, ideal for those with demonstrable work references and f
vai_al_servizio: "Go to the service", vai_al_servizio: "Go to the service",
valutazione: "Your visit rating", valutazione: "Your visit rating",
valutazione_del: "Rating submitted on", valutazione_del: "Rating submitted on",
conf_alert: `The duration of stay and budget indicated in the search parameters will be adjusted to the conditions established together with the landlord at the time of negotiation.`,
}, },
richieste_contatto: "Contact requests", richieste_contatto: "Contact requests",
rimuovi: "Remove", rimuovi: "Remove",

View file

@ -1231,6 +1231,7 @@ export const it: LangDict = {
vai_al_servizio: "Vai al servizio", vai_al_servizio: "Vai al servizio",
valutazione: "La valutazione della tua visita", valutazione: "La valutazione della tua visita",
valutazione_del: "Valutazione inserita il", valutazione_del: "Valutazione inserita il",
conf_alert: `Il periodo di permanenza e il budget indicati nei parametri di ricerca veranno adeguati alle condizioni stabilite insieme al locatore nel momento della trattativa.`,
}, },
richieste_contatto: "Richieste di contatto", richieste_contatto: "Richieste di contatto",
rimuovi: "Rimuovi", rimuovi: "Rimuovi",

View file

@ -695,6 +695,7 @@ export type LangDict = {
valutazione: string; valutazione: string;
valutazione_del: string; valutazione_del: string;
conferma_txt: string; conferma_txt: string;
conf_alert: string;
}; };
tipologia_tutorial: { tipologia_tutorial: {
btn_title: string; btn_title: string;

View file

@ -64,6 +64,7 @@ export const ServizioAnnuncioProvider = ({
children, children,
}: ServizioAnnuncioProviderProps) => { }: ServizioAnnuncioProviderProps) => {
const utils = api.useUtils(); const utils = api.useUtils();
const { mutateAsync } = api.servizio.updateServizioAnnunci.useMutation({ const { mutateAsync } = api.servizio.updateServizioAnnunci.useMutation({
onError: (error) => { onError: (error) => {
toast.error(error.message); toast.error(error.message);
@ -89,7 +90,11 @@ export const ServizioAnnuncioProvider = ({
return ( return (
<ServizioAnnuncioContext.Provider <ServizioAnnuncioContext.Provider
value={{ annuncioId: data.annunci_id, data, updateServizioAnnunci }} value={{
annuncioId: data.annunci_id,
data,
updateServizioAnnunci,
}}
> >
{children} {children}
</ServizioAnnuncioContext.Provider> </ServizioAnnuncioContext.Provider>