feat: update admin actions layout and add contact details dialog; modify user link path in UsersTable

This commit is contained in:
Marco Pedone 2026-03-12 17:02:35 +01:00
parent 300c9edfc4
commit d18aee8a95
3 changed files with 139 additions and 144 deletions

View file

@ -1,17 +1,27 @@
import { import {
ExternalLink,
Eye,
FileBadge, FileBadge,
FileText, FileText,
FolderKanban, FolderKanban,
Info,
Mail, Mail,
PackageCheck, PackageCheck,
Pointer, Pointer,
Printer, Printer,
Trash2, Trash2,
Wrench,
} from "lucide-react"; } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "~/components/ui/alert-dialog";
import { Button, type ButtonConfigs } from "~/components/ui/button"; import { Button, type ButtonConfigs } from "~/components/ui/button";
import { import {
Tooltip, Tooltip,
@ -49,8 +59,11 @@ export const AdminActions = () => {
if (!isAdmin) return null; if (!isAdmin) return null;
return ( return (
<>
<h3 className="ml-1 font-semibold">Azioni Admin:</h3>
<div className="flex w-full max-w-fit flex-wrap justify-start gap-3"> <div className="flex w-full max-w-fit flex-wrap justify-start gap-3">
{<AdminSendScheda />} <AdminAnnuncioContatti />
<AdminSendScheda />
{data.user_confirmed_at != null && <AdminLavoraConferma />} {data.user_confirmed_at != null && <AdminLavoraConferma />}
{data.accettato_conferma_at != null && ( {data.accettato_conferma_at != null && (
<> <>
@ -68,11 +81,11 @@ export const AdminActions = () => {
)} )}
</> </>
)} )}
<Link href={`/annuncio/${data.codice}`} target="_blank"> {/* <Link href={`/annuncio/${data.codice}`} target="_blank">
<Button size="sm" type="button" variant="outline"> <Button size="sm" type="button" variant="outline">
<Eye /> pubblica <Eye /> pubblica
</Button> </Button>
</Link> </Link> */}
<Link <Link
href={`/area-riservata/admin/edit-annuncio/${annuncioId}`} href={`/area-riservata/admin/edit-annuncio/${annuncioId}`}
target="_blank" target="_blank"
@ -83,8 +96,8 @@ export const AdminActions = () => {
size="sm" size="sm"
variant="secondary" variant="secondary"
> >
<ExternalLink /> <Wrench />
<span>Modifica</span> <span>Modifica Annuncio</span>
</Button> </Button>
</Link> </Link>
@ -118,6 +131,7 @@ export const AdminActions = () => {
</Button> </Button>
</Confirm> </Confirm>
</div> </div>
</>
); );
}; };
@ -156,7 +170,7 @@ const AdminSendScheda = () => {
> >
<Button className="w-fit" size="sm" variant="outline"> <Button className="w-fit" size="sm" variant="outline">
<Mail /> <Mail />
<span>Invia email contatti</span> <span>Invia Scheda</span>
</Button> </Button>
</Confirm> </Confirm>
); );
@ -243,6 +257,61 @@ export const UserActions = () => {
</> </>
); );
}; };
const AdminAnnuncioContatti = () => {
const { data } = useServizioAnnuncio();
const { data: annuncio, isLoading } = api.annunci.getAnnuncioFull.useQuery({
id: data.id,
});
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button size="sm" variant="outline">
<Info />
<span>Dati Contatto</span>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Contatti Annuncio {data.codice}</AlertDialogTitle>
<AlertDialogDescription className="sr-only">
desc
</AlertDialogDescription>
</AlertDialogHeader>
<div className="flex w-full flex-col gap-4">
<div>
<span className="font-semibold">Contatti Aperti il: </span>
{data.open_contatti_at
? new Date(data.open_contatti_at).toLocaleString("it-IT")
: "Non ancora aperti"}
</div>
{isLoading ? (
<div className="flex h-24 w-full items-center justify-center">
Loading...
</div>
) : (
<>
<div>
<span className="font-semibold">Locatore/Incaricato: </span>
{annuncio?.locatore || "N/A"}
</div>
<div>
<span className="font-semibold">Email: </span>
{annuncio?.email || "N/A"}
</div>
<div>
<span className="font-semibold">Telefono: </span>
{annuncio?.numero || "N/A"}
</div>
</>
)}
</div>
<AlertDialogFooter>
<AlertDialogCancel>Chiudi</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
const PostConfermaSection = () => { const PostConfermaSection = () => {
const { servizio, servizioId } = useServizio(); const { servizio, servizioId } = useServizio();

View file

@ -1,19 +1,9 @@
import { Info, Toolbox } from "lucide-react"; import { Toolbox } from "lucide-react";
import Image from "next/image"; import Image from "next/image";
import { import {
AdminActions, AdminActions,
UserActions, UserActions,
} from "~/components/servizio/annuncio_actions"; } from "~/components/servizio/annuncio_actions";
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "~/components/ui/alert-dialog";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { handleConsegna } from "~/lib/annuncio_details"; import { handleConsegna } from "~/lib/annuncio_details";
import { getStorageUrl } from "~/lib/storage_utils"; import { getStorageUrl } from "~/lib/storage_utils";
@ -21,7 +11,6 @@ import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider"; import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller"; import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
import { api } from "~/utils/api";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
import { import {
Collapsible, Collapsible,
@ -49,7 +38,7 @@ export const AnnuncioCard = ({ className }: { className?: string }) => {
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Collapsible className="space-y-2"> <Collapsible className="space-y-2">
<CollapsibleTrigger asChild> <CollapsibleTrigger asChild>
<Button variant="outline"> <Button size="sm" variant="outline">
<Toolbox /> <Toolbox />
<span>Azioni Utente</span> <span>Azioni Utente</span>
</Button> </Button>
@ -108,7 +97,6 @@ export const AnnuncioDisplay = ({
data: AnnuncioRicerca; data: AnnuncioRicerca;
className?: string; className?: string;
}) => { }) => {
const { isAdmin } = useServizio();
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@ -158,71 +146,9 @@ export const AnnuncioDisplay = ({
{formatCurrency(data.prezzo / 1e2)} {formatCurrency(data.prezzo / 1e2)}
</span> </span>
</div> </div>
<div <div className="col-span-2 w-full max-w-xl md:col-span-1 md:pr-8">
className={cn(
"col-span-2 grid w-full max-w-xl items-center gap-2 md:col-span-1 md:pr-8",
isAdmin && "grid-cols-2",
)}
>
<AnnuncioDettaglio data={data} /> <AnnuncioDettaglio data={data} />
{isAdmin && <AdminAnnuncioContatti />}
</div> </div>
</div> </div>
); );
}; };
const AdminAnnuncioContatti = () => {
const { data } = useServizioAnnuncio();
const { data: annuncio, isLoading } = api.annunci.getAnnuncioFull.useQuery({
id: data.id,
});
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button className="" variant="outline">
<Info />
<span>Dati Contatto</span>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Contatti Annuncio {data.codice}</AlertDialogTitle>
<AlertDialogDescription className="sr-only">
desc
</AlertDialogDescription>
</AlertDialogHeader>
<div className="flex w-full flex-col gap-4">
<div>
<span className="font-semibold">Contatti Aperti il: </span>
{data.open_contatti_at
? new Date(data.open_contatti_at).toLocaleString("it-IT")
: "Non ancora aperti"}
</div>
{isLoading ? (
<div className="flex h-24 w-full items-center justify-center">
Loading...
</div>
) : (
<>
<div>
<span className="font-semibold">Locatore/Incaricato: </span>
{annuncio?.locatore || "N/A"}
</div>
<div>
<span className="font-semibold">Email: </span>
{annuncio?.email || "N/A"}
</div>
<div>
<span className="font-semibold">Telefono: </span>
{annuncio?.numero || "N/A"}
</div>
</>
)}
</div>
<AlertDialogFooter>
<AlertDialogCancel>Chiudi</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};

View file

@ -135,7 +135,7 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => {
<Link <Link
aria-label="Visualizza Utente" aria-label="Visualizza Utente"
className="flex items-center gap-2" className="flex items-center gap-2"
href={`/area-riservata/admin/user-view/edit-user/${user.id}`} href={`/area-riservata/admin/user-view/ricerca/${user.id}`}
> >
<UserAvatar <UserAvatar
className="size-8" className="size-8"