infoalloggi-monorepo/apps/infoalloggi/src/components/area-riservata/userViewHeader.tsx
2025-11-20 16:48:29 +01:00

250 lines
6.2 KiB
TypeScript

import { format } from "date-fns";
import {
ExternalLink,
Mail,
MessagesSquare,
Paperclip,
Search,
ShoppingBag,
Tickets,
UserCog,
UserPen,
} from "lucide-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useRouter } from "next/router";
import toast from "react-hot-toast";
import { useUserViewContext } from "~/lib/userViewContext";
import { api } from "~/utils/api";
import { WhatsAppIcon2 } from "../svgs";
import { Button } from "../ui/button";
import { Separator } from "../ui/separator";
export const UserViewHeader = () => {
const data = useUserViewContext();
const pathname = usePathname();
const router = useRouter();
const { mutate: swap } = api.auth.swapUser.useMutation({
onSuccess: async () => {
toast.success("Utente cambiato con successo");
await router.push("/area-riservata/dashboard");
router.reload();
},
});
if (!data) return <div>Errore</div>;
return (
<div className="mb-5 flex flex-col space-y-5">
<div className="flex flex-row flex-wrap items-baseline gap-3">
<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>
)}
</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/servizio/${data.id}`}>
<Button
className="border"
size="sm"
variant={pathname.includes("servizio") ? "secondary" : "outline"}
>
<Tickets /> Servizi
</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>
<Button
className="flex gap-2"
onClick={() =>
swap({
id: data.id,
})
}
size="sm"
>
<ExternalLink /> Login
</Button>
</div>
<Separator />
</div>
);
};
const VOCALI = ["A", "E", "I", "O", "U"] as const;
const IntestazioneMaker = () => {
const data = useUserViewContext();
const { data: comuni = [] } = api.catasto.searchComuniByCatasto.useQuery({
catasto: [data?.luogo_nascita || "", data?.comune_residenza || ""].filter(
(f) => f !== "",
),
});
const isDisabled =
!data.sesso ||
!data.cognome ||
!data.nome ||
!data.data_nascita ||
!data.luogo_nascita ||
!data.comune_residenza ||
!data.via_residenza ||
!data.civico_residenza;
const copyToClipboard = () => {
if (
!data.sesso ||
!data.cognome ||
!data.nome ||
!data.data_nascita ||
!data.luogo_nascita ||
!data.comune_residenza ||
!data.via_residenza ||
!data.civico_residenza
) {
toast.error("Dati mancanti");
return;
}
const comune_nascita = comuni.find((c) => c.catasto === data.luogo_nascita);
const comune_residenza = comuni.find(
(c) => c.catasto === data.comune_residenza,
);
if (!comune_nascita || !comune_residenza) {
toast.error("Errore comune non trovato");
return;
}
// Format names
const cognome = titleCase(data.cognome);
const nome = titleCase(data.nome);
const viaResidenza = titleCase(data.via_residenza);
const comuneNascita = titleCase(comune_nascita.nome);
const comuneResidenza = titleCase(comune_residenza.nome);
// Determine article
const isMale = data.sesso === "M";
const articolo = isMale ? "Al Sig." : "Alla Sig.ra";
const natoNata = isMale ? "nato" : "nata";
const preposizione = VOCALI.includes(comuneNascita[0]?.toUpperCase() || "")
? "ad"
: "a";
// Build phrase
const frase = [
`${articolo} ${cognome} ${nome}`,
`${natoNata} il ${format(data.data_nascita, "dd/MM/yyyy")}`,
`${preposizione} ${comuneNascita} (${comune_nascita.sigla}),`,
`residente in ${viaResidenza}, ${data.civico_residenza}`,
`a ${comuneResidenza} (${data.provincia_residenza})`,
`CAP ${data.cap_residenza},`,
`con codice fiscale: ${data.codice_fiscale}`,
].join(" ");
navigator.clipboard
.writeText(frase)
.then(() => {
toast.success("Intestazione copiata negli appunti");
})
.catch(() => {
toast.error("Errore nella copia");
});
};
return (
<Button disabled={isDisabled} onClick={copyToClipboard} size="sm">
<UserPen /> Intestazione
</Button>
);
};
function titleCase(str: string | null | undefined): string {
if (!str) return "";
return str
.trim()
.toLowerCase()
.split(/\s+/) // Handle multiple spaces
.map((word) => {
if (word.length === 0) return word;
return word.charAt(0).toUpperCase() + word.slice(1);
})
.join(" ");
}