feat: enhance UserViewHeader with responsive utility and navigation buttons

This commit is contained in:
Marco Pedone 2026-03-30 14:15:40 +02:00
parent 00979ecdac
commit cca50a2c6a

View file

@ -1,7 +1,9 @@
import { format } from "date-fns"; import { format } from "date-fns";
import { import {
ChevronDown,
CloudSync, CloudSync,
ExternalLink, ExternalLink,
type LucideIcon,
Mail, Mail,
MessagesSquare, MessagesSquare,
NotebookPen, NotebookPen,
@ -26,7 +28,10 @@ import {
DialogTrigger, DialogTrigger,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { Textarea } from "~/components/ui/textarea"; import { Textarea } from "~/components/ui/textarea";
import { useMediaQuery } from "~/hooks/use-media-query";
import { useUserViewContext } from "~/lib/userViewContext"; import { useUserViewContext } from "~/lib/userViewContext";
import { cn } from "~/lib/utils";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { Confirm } from "../confirm"; import { Confirm } from "../confirm";
import { WhatsAppIcon2 } from "../svgs"; import { WhatsAppIcon2 } from "../svgs";
@ -55,121 +60,161 @@ export const UserViewHeader = () => {
}); });
}, },
}); });
const isDesktop = useMediaQuery("(min-width: 640px)");
const links: { label: string; slug: string; icon: LucideIcon }[] = [
{
label: "Profilo",
slug: "edit-user",
icon: UserCog,
},
{
label: "Ricerca",
slug: "ricerca",
icon: Search,
},
{
label: "Comunicazioni",
slug: "comunicazioni",
icon: Mail,
},
{
label: "Ordini",
slug: "ordini",
icon: ShoppingBag,
},
{
label: "Allegati",
slug: "allegati",
icon: Paperclip,
},
];
useEffect(() => {
setUtilOpen(isDesktop);
setNavOpen(isDesktop);
}, [isDesktop]);
const [utilOpen, setUtilOpen] = useState(isDesktop);
const [navOpen, setNavOpen] = useState(isDesktop);
if (!data) return <div>Errore</div>; if (!data) return <div>Errore</div>;
return ( return (
<div className="mb-5 flex flex-col space-y-5"> <div className="mb-5 flex flex-col gap-y-3">
<div className="flex flex-row flex-wrap items-center gap-3"> <div className="text-3xl">{data.username}</div>
<div className="text-3xl">{data.username}</div>
<Link href={`https://wa.me/${data.telefono}`} target="_blank">
<Button size="sm" variant="success">
<WhatsAppIcon2 className="size-4 fill-white" />
WhatsApp
</Button>
</Link>
{data.codice_fiscale ? (
<IntestazioneMaker />
) : (
<Button disabled size="sm">
<UserPen /> Intestazione
</Button>
)}
<Confirm
description={`Verrà inviata un'email di invito al sito all'indirizzo ${data.email}`}
onConfirm={async () => {
await sendInvite({ id: data.id });
}}
title="Vuoi mandare l'email di invito al sito?"
>
<Button size="sm" variant="info">
<Mail /> Invita al sito
</Button>
</Confirm>
<NoteUtenteDialog />
<OverseerButton />
</div>
<div className="flex flex-row flex-wrap gap-2">
<Link href={`/area-riservata/admin/user-view/edit-user/${data.id}`}>
<Button
className="border"
size="sm"
variant={pathname.includes("edit-user") ? "secondary" : "outline"}
>
<UserCog /> Profilo
</Button>
</Link>
<Link href={`/area-riservata/admin/user-view/ricerca/${data.id}`}>
<Button
className="border"
size="sm"
variant={pathname.includes("ricerca") ? "secondary" : "outline"}
>
<Search /> Ricerca
</Button>
</Link>
<Link href={`/area-riservata/admin/user-view/comunicazioni/${data.id}`}>
<Button
className="border"
size="sm"
variant={
pathname.includes("comunicazioni") ? "secondary" : "outline"
}
>
<Mail /> Comunicazioni
</Button>
</Link>
<Link href={`/area-riservata/admin/user-view/ordini/${data.id}`}>
<Button
className="border"
size="sm"
variant={pathname.includes("ordini") ? "secondary" : "outline"}
>
<ShoppingBag /> Ordini
</Button>
</Link>
<Link href={`/area-riservata/admin/user-view/allegati/${data.id}`}>
<Button
className="border"
size="sm"
variant={pathname.includes("allegati") ? "secondary" : "outline"}
>
<Paperclip /> Allegati
</Button>
</Link>
<Link
href={
data.chatid
? {
pathname: "/area-riservata/admin/chats",
query: { chatid: data.chatid },
}
: "/area-riservata/admin/chats"
}
target="_blank"
>
<Button
className="border"
size="sm"
variant={!data.chatid ? "ghost" : "outline"}
>
<MessagesSquare /> Chat
</Button>
</Link>
<div className="grid grid-cols-2 items-center gap-2 sm:hidden">
<Button <Button
className="flex gap-2" className="w-full"
onClick={() => onClick={() => {
swap({ if (utilOpen) {
id: data.id, setUtilOpen(false);
}) return;
} }
if (navOpen) {
setNavOpen(false);
}
setUtilOpen(true);
}}
size="sm" size="sm"
variant="outline"
> >
<ExternalLink /> Login Utilità
<ChevronDown className={cn(utilOpen && "rotate-180")} />
</Button>
<Button
className="w-full"
onClick={() => {
if (navOpen) {
setNavOpen(false);
return;
}
if (utilOpen) {
setUtilOpen(false);
}
setNavOpen(true);
}}
size="sm"
variant="outline"
>
Navigazione <ChevronDown className={cn(navOpen && "rotate-180")} />
</Button> </Button>
</div> </div>
{utilOpen && (
<div className="flex flex-row flex-wrap gap-2">
<Link href={`https://wa.me/${data.telefono}`} target="_blank">
<Button size="sm" variant="success">
<WhatsAppIcon2 className="size-4 fill-white" />
WhatsApp
</Button>
</Link>
{data.codice_fiscale ? (
<IntestazioneMaker />
) : (
<Button disabled size="sm">
<UserPen /> Intestazione
</Button>
)}
<Confirm
description={`Verrà inviata un'email di invito al sito all'indirizzo ${data.email}`}
onConfirm={async () => {
await sendInvite({ id: data.id });
}}
title="Vuoi mandare l'email di invito al sito?"
>
<Button size="sm" variant="info">
<Mail /> Invita al sito
</Button>
</Confirm>
<NoteUtenteDialog />
<OverseerButton />
</div>
)}
{navOpen && (
<div className="flex flex-row flex-wrap gap-2">
{links.map((link) => (
<Link
href={`/area-riservata/admin/user-view/${link.slug}/${data.id}`}
key={link.slug}
>
<Button
size="sm"
variant={pathname.includes(link.slug) ? "secondary" : "outline"}
>
{<link.icon />} {link.label}
</Button>
</Link>
))}
<Link
href={
data.chatid
? {
pathname: "/area-riservata/admin/chats",
query: { chatid: data.chatid },
}
: "/area-riservata/admin/chats"
}
target="_blank"
>
<Button size="sm" variant={!data.chatid ? "ghost" : "outline"}>
<MessagesSquare /> Chat
</Button>
</Link>
<Button
onClick={() =>
swap({
id: data.id,
})
}
size="sm"
>
<ExternalLink /> Login
</Button>
</div>
)}
<Separator /> <Separator />
</div> </div>
); );