250 lines
6.2 KiB
TypeScript
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(" ");
|
|
}
|