refactor: streamline conditional logic and improve readability across multiple components

This commit is contained in:
Marco Pedone 2025-09-01 16:48:03 +02:00
parent 0bc1a0915c
commit 1426f0efef
24 changed files with 271 additions and 271 deletions

View file

@ -68,6 +68,7 @@
"linter": {
"domains": {
"next": "recommended",
"project": "recommended",
"react": "recommended"
},
"enabled": true,
@ -82,19 +83,33 @@
},
"correctness": {
"noUndeclaredVariables": "on",
"useExhaustiveDependencies": "off",
"useHookAtTopLevel": "off",
"useParseIntRadix": "off"
},
"nursery": {
"useExhaustiveSwitchCases": "on"
},
"performance": {
"noImgElement": "off"
"noImgElement": "off",
"useGoogleFontPreconnect": "on"
},
"recommended": true,
"security": {
"noDangerouslySetInnerHtml": "off"
},
"style": {
"noNestedTernary": "info",
"noUselessElse": "on",
"noYodaExpression": "on",
"useThrowNewError": "on",
"useThrowOnlyError": "on"
},
"suspicious": {
"noArrayIndexKey": "off",
"noDocumentImportInPage": "on",
"noHeadImportInDocument": "on",
"noUnknownAtRules": "off",
"useIterableCallbackReturn": "off"
}

View file

@ -19,11 +19,6 @@ const EmailContattoInteressato = ({
indirizzo,
sesso,
}: EmailContattoInteressatoProps) => {
const sig = sesso
? sesso === "M"
? "Il Sig."
: "La Sig.ra"
: "Il/La Sig./Sig.ra";
return (
<Base preview="Contatto Email">
<>
@ -34,9 +29,15 @@ const EmailContattoInteressato = ({
<Row>
<Text className="text-base">
Gentile proprietario {nome_cognome}, le comunichiamo che a breve
la contatterà {sig} {nome_cognome_utente} (tel: {telefono}),
cliente Arca abbonato tramite il nostro servizio online
Infoalloggi.it interessato a vedere il Suo immobile{" "}
la contatterà {(() => {
if (sesso) {
if (sesso === "M") return "il Sig.";
if (sesso === "F") return "la Sig.ra";
}
return "il Sig./la Sig.ra";
})()} {nome_cognome_utente} (tel: {telefono}), cliente Arca
abbonato tramite il nostro servizio online Infoalloggi.it
interessato a vedere il Suo immobile{" "}
{indirizzo ? `di ${indirizzo}` : ""}.
</Text>
<Text className="text-base">

View file

@ -202,6 +202,8 @@ export const IconMatrix = ({ type, ...rest }: IconMatrixProps) => {
return <Target {...rest} />;
case "thumbs-up":
return <ThumbsUp {...rest} />;
default:
return <div>Icon not found</div>;
}
};

View file

@ -56,43 +56,49 @@ export const AcquistoProcessing = ({
<h3 className="mt-2 text-center text-2xl font-bold tracking-wide text-neutral-700 uppercase">
{t.acquisto.titolo}
</h3>
{!generatedIntent ? (
<PricePreparation
onProcedi={() => {
setGeneratedIntent(true);
mutate({
paymentId,
});
}}
packId={packId}
/>
) : isPending ? (
<LoadingPage />
) : (
stripeIntent?.clientSecret && (
<>
<Elements
options={{
appearance: {
theme: "stripe",
variables: {
colorPrimary: "#18181b",
colorText: "#18181b",
},
},
clientSecret: stripeIntent.clientSecret,
{(() => {
if (!generatedIntent) {
return (
<PricePreparation
onProcedi={() => {
setGeneratedIntent(true);
mutate({
paymentId,
});
}}
stripe={stripePromise}
>
<CheckoutForm
descrizione={stripeIntent.descrizione}
prezzo={stripeIntent.prezzo}
titolo={stripeIntent.titolo}
/>
</Elements>
</>
)
)}
packId={packId}
/>
);
}
if (isPending) {
return <LoadingPage />;
}
if (stripeIntent?.clientSecret) {
return (
<>
<Elements
options={{
appearance: {
theme: "stripe",
variables: {
colorPrimary: "#18181b",
colorText: "#18181b",
},
},
clientSecret: stripeIntent.clientSecret,
}}
stripe={stripePromise}
>
<CheckoutForm
descrizione={stripeIntent.descrizione}
prezzo={stripeIntent.prezzo}
titolo={stripeIntent.titolo}
/>
</Elements>
</>
);
}
})()}
</div>
);
};

View file

@ -256,33 +256,32 @@ export const CarouselAnnuncio = ({
if (!video) return null;
if (video.includes("youtu")) {
return null;
} else {
return (
<CarouselItem
className={cn(
"group relative",
immagini && immagini.length === 1
? ""
: !single && "md:basis-1/2 lg:basis-1/3",
)}
key={`videoplayer-${video}`}
>
<VideoPlayer
className="h-72 "
coverImage={immagini?.[0] ? immagini[0] : ""}
key={`videoplayer-${idx}-${openModal}`}
videoSrc={video}
/>
<Maximize2
className="absolute right-2 bottom-2 transition-all duration-300 hover:scale-150 origin-bottom-right ease-in-out cursor-pointer size-7 rounded-md bg-white/70 stroke-2 p-1 group-hover:opacity-100 sm:opacity-0"
onClick={() =>
handleOpenModal(immagini?.length || 0 + idx)
}
/>
</CarouselItem>
);
}
return (
<CarouselItem
className={cn(
"group relative",
immagini && immagini.length === 1
? ""
: !single && "md:basis-1/2 lg:basis-1/3",
)}
key={`videoplayer-${video}`}
>
<VideoPlayer
className="h-72 "
coverImage={immagini?.[0] ? immagini[0] : ""}
key={`videoplayer-${idx}-${openModal}`}
videoSrc={video}
/>
<Maximize2
className="absolute right-2 bottom-2 transition-all duration-300 hover:scale-150 origin-bottom-right ease-in-out cursor-pointer size-7 rounded-md bg-white/70 stroke-2 p-1 group-hover:opacity-100 sm:opacity-0"
onClick={() =>
handleOpenModal(immagini?.length || 0 + idx)
}
/>
</CarouselItem>
);
})}
</CarouselContent>
@ -322,20 +321,19 @@ export const CarouselAnnuncio = ({
if (!video) return null;
if (video.includes("youtu")) {
return null;
} else {
return (
<CarouselItem
className="relative flex items-center justify-center"
key={`carousel-videoplayer-${video}`}
>
<VideoPlayer
className="h-[90vh] absolute w-full mx-auto max-w-fit rounded-md object-contain"
coverImage={immagini?.[0] ? immagini[0] : ""}
videoSrc={video}
/>
</CarouselItem>
);
}
return (
<CarouselItem
className="relative flex items-center justify-center"
key={`carousel-videoplayer-${video}`}
>
<VideoPlayer
className="h-[90vh] absolute w-full mx-auto max-w-fit rounded-md object-contain"
coverImage={immagini?.[0] ? immagini[0] : ""}
videoSrc={video}
/>
</CarouselItem>
);
})}
</CarouselContent>

View file

@ -193,36 +193,37 @@ export const ExtIcon = ({
if (!ext) return <File className={cn("size-5 text-gray-500", className)} />;
if (ext.includes("pdf")) {
return <FileText className={cn("size-5 text-red-500", className)} />;
} else if (
}
if (
ext.includes("image") ||
["jpg", "jpeg", "png", "gif", "svg", "webp"].some((ext) =>
ext.includes(ext),
)
) {
return <ImageIcon className={cn("size-5 text-blue-500", className)} />;
} else if (
}
if (
["html", "css", "js", "jsx", "ts", "tsx", "json", "xml"].some((ext) =>
ext.includes(ext),
)
) {
return <FileCode className={cn("size-5 text-emerald-500", className)} />;
} else if (["xls", "xlsx", "csv"].some((ext) => ext.includes(ext))) {
}
if (["xls", "xlsx", "csv"].some((ext) => ext.includes(ext))) {
return (
<FileSpreadsheet className={cn("size-5 text-green-600", className)} />
);
} else if (
["zip", "rar", "7z", "tar", "gz"].some((ext) => ext.includes(ext))
) {
return <FileArchive className={cn("size-5 text-amber-600", className)} />;
} else if (["mp3", "wav", "ogg", "flac"].some((ext) => ext.includes(ext))) {
return <FileAudio className={cn("size-5 text-purple-500", className)} />;
} else if (
["mp4", "avi", "mov", "wmv", "webm"].some((ext) => ext.includes(ext))
) {
return <FileVideo className={cn("size-5 text-pink-500", className)} />;
} else {
return <File className={cn("size-5 text-gray-500", className)} />;
}
if (["zip", "rar", "7z", "tar", "gz"].some((ext) => ext.includes(ext))) {
return <FileArchive className={cn("size-5 text-amber-600", className)} />;
}
if (["mp3", "wav", "ogg", "flac"].some((ext) => ext.includes(ext))) {
return <FileAudio className={cn("size-5 text-purple-500", className)} />;
}
if (["mp4", "avi", "mov", "wmv", "webm"].some((ext) => ext.includes(ext))) {
return <FileVideo className={cn("size-5 text-pink-500", className)} />;
}
return <File className={cn("size-5 text-gray-500", className)} />;
};
const EditFileDialog = ({

View file

@ -6,6 +6,7 @@ import { IconMatrix, type IconType } from "~/components/IconComponents";
import { cn } from "~/lib/utils";
import type { Banners } from "~/schemas/public/Banners";
const defaultHideDuration = 365; // days
export const BannerFactory = (bannerData: Banners) => {
const NEW_BANNER_KEY = `bannercookie_${bannerData.idbanner}`;
@ -55,7 +56,7 @@ export const BannerFactory = (bannerData: Banners) => {
e.preventDefault();
Cookies.set(NEW_BANNER_KEY, "true", {
expires: bannerData.hide_duration || 365,
expires: bannerData.hide_duration || defaultHideDuration,
});
setIsBannerToShow(false);
};

View file

@ -60,9 +60,8 @@ type ChatBubbleReadStatusProps = {
export const ChatBubbleReadStatus = ({ isread }: ChatBubbleReadStatusProps) => {
if (isread) {
return <CheckCheck className="mt-2 size-4 text-green-500" />;
} else {
return <Check className="text-muted-foreground mt-2 size-4" />;
}
return <Check className="text-muted-foreground mt-2 size-4" />;
};
// ChatBubbleMessage

View file

@ -41,13 +41,13 @@ export function DataTableColumnHeader<TData, TValue>({
variant="ghost"
>
<span>{title}</span>
{column.getIsSorted() === "desc" ? (
<ArrowDownIcon className="ml-2 size-4" />
) : column.getIsSorted() === "asc" ? (
<ArrowUpIcon className="ml-2 size-4" />
) : (
<ChevronsUpDown className="ml-2 size-4" />
)}
{(() => {
if (column.getIsSorted() === "desc")
return <ArrowDownIcon className="ml-2 size-4" />;
if (column.getIsSorted() === "asc")
return <ArrowUpIcon className="ml-2 size-4" />;
return <ChevronsUpDown className="ml-2 size-4" />;
})()}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">

View file

@ -916,13 +916,13 @@ const FileUploadItem = forwardRef<HTMLDivElement, FileUploadItemProps>(
if (!fileState) return null;
const statusText = fileState.error
? `Error: ${fileState.error}`
: fileState.status === "uploading"
? `Uploading: ${fileState.progress}% complete`
: fileState.status === "success"
? "Upload complete"
: "Ready to upload";
const statusText = (() => {
if (fileState.error) return `Error: ${fileState.error}`;
if (fileState.status === "uploading")
return `Uploading: ${fileState.progress}% complete`;
if (fileState.status === "success") return "Upload complete";
return "Ready to upload";
})();
const ItemPrimitive = asChild ? Slot : "div";

View file

@ -37,9 +37,8 @@ const getCoordsFromPointExpression = (expression?: PointExpression) => {
if (!expression) return [];
if (Array.isArray(expression)) {
return expression;
} else {
return [expression.x, expression.y] as PointTuple;
}
return [expression.x, expression.y] as PointTuple;
};
const useCoordsFromPointExpression = (expression?: PointExpression) =>

View file

@ -199,10 +199,9 @@ const parseContrattoImport = (ingest: string) => {
? new Date(parsed.data.contratto_scadenza)
: null,
};
} else {
console.error("Invalid format:", parsed.error);
return undefined;
}
console.error("Invalid format:", parsed.error);
return undefined;
};
const ContrattoImport = ({
@ -950,10 +949,9 @@ const parseCaparra = (ingest: string) => {
const parsed = CaparraSchema.safeParse(parsedJson);
if (parsed.success) {
return parsed.data;
} else {
console.error("Invalid caparra format:", parsed.error);
return undefined;
}
console.error("Invalid caparra format:", parsed.error);
return undefined;
};
const Caparra = ({
@ -1165,19 +1163,16 @@ const SendConferma = ({
</p>
</>
);
} else {
return (
<>
<p>
Budget (da preferenze): {formatCurrency(servizio.budget)}
</p>
<p>
Canone Mensile (da descrizione):{" "}
{formatCurrency(data.prezzo / 100)}
</p>
</>
);
}
return (
<>
<p>Budget (da preferenze): {formatCurrency(servizio.budget)}</p>
<p>
Canone Mensile (da descrizione):{" "}
{formatCurrency(data.prezzo / 100)}
</p>
</>
);
})()}
</div>
<div className="flex items-center gap-3">

View file

@ -144,14 +144,13 @@ export const OrdiniTable = ({ data, isAdmin, userId }: PaymentsTableProps) => {
Pagato
</span>
);
} else {
return (
<span className="inline-flex items-center gap-1 text-red-500">
<CircleCheck className="size-5" />
Non pagato
</span>
);
}
return (
<span className="inline-flex items-center gap-1 text-red-500">
<CircleCheck className="size-5" />
Non pagato
</span>
);
},
filterFn: (row, id, value) => {

View file

@ -102,13 +102,13 @@ export const PrezzarioTable = ({
cell: ({ row }) => {
return (
<div>
{row.original.isTransitorio
? row.original.isStabile
? "Transitorio/Stabile"
: "Transitorio"
: row.original.isStabile
? "Stabile"
: ""}
{(() => {
if (row.original.isTransitorio && row.original.isStabile)
return "Transitorio/Stabile";
if (row.original.isTransitorio) return "Transitorio";
if (row.original.isStabile) return "Stabile";
return "";
})()}
</div>
);
},

View file

@ -79,13 +79,14 @@ const Row = ({
Affitto {servizio.tipologia}
</div>
<div className="col-span-2">
{servizio.isInterrotto ? (
<span className="text-red-500">Interrotto</span>
) : servizio.isOkAcconto && servizio.decorrenza !== null ? (
<span className="text-green-500">Attivo</span>
) : (
<span className="text-neutral-500">Inattivo</span>
)}
{(() => {
if (servizio.isInterrotto)
return <span className="text-red-500">Interrotto</span>;
if (servizio.isOkAcconto && servizio.decorrenza !== null) {
return <span className="text-green-500">Attivo</span>;
}
return <span className="text-neutral-500">Inattivo</span>;
})()}
</div>
<div className="hidden text-sm sm:col-span-2 sm:contents sm:text-base">
{servizio.created_at.toLocaleDateString("it", {

View file

@ -132,13 +132,13 @@ export const TabServizio = ({
)}
</TableCell>
<TableCell>
{servizio.isInterrotto ? (
<span className="text-red-500">Interrotto</span>
) : servizio.isOkAcconto && servizio.decorrenza !== null ? (
<span className="text-green-500">Attivo</span>
) : (
<span className="text-neutral-500">Inattivo</span>
)}
{(() => {
if (servizio.isInterrotto)
return <span className="text-red-500">Interrotto</span>;
if (servizio.isOkAcconto && servizio.decorrenza !== null)
return <span className="text-green-500">Attivo</span>;
return <span className="text-neutral-500">Inattivo</span>;
})()}
</TableCell>
<TableCell>
<AnnunciSection

View file

@ -18,15 +18,11 @@ function Slider({
max = 100,
...props
}: React.ComponentProps<typeof SliderPrimitive.Root> & SliderProps) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max],
);
const _values = React.useMemo(() => {
if (Array.isArray(value)) return value;
if (Array.isArray(defaultValue)) return defaultValue;
return [min, max];
}, [value, defaultValue, min, max]);
return (
<SliderPrimitive.Root

View file

@ -9,11 +9,10 @@ export const getUserColor = (str: string) => {
if (colorOptions.has(str)) {
// biome-ignore lint/style/noNonNullAssertion: <exists>
return colorOptions.get(str)!;
} else {
const usercolor = getHexColorFromString(str);
colorOptions.set(str, usercolor);
return usercolor;
}
const usercolor = getHexColorFromString(str);
colorOptions.set(str, usercolor);
return usercolor;
};
export const UserAvatar = ({

View file

@ -79,11 +79,10 @@ export const authMiddleware = async (req: NextRequest) => {
return NextResponse.redirect(
new URL("/area-riservata/dashboard", req.nextUrl),
);
} else {
return NextResponse.redirect(
new URL("/area-riservata/dashboard", req.nextUrl),
);
}
return NextResponse.redirect(
new URL("/area-riservata/dashboard", req.nextUrl),
);
}
// If access token is invalid, delete it
const destination = new URL("/login", req.nextUrl);

View file

@ -198,10 +198,9 @@ const RicercaFilters = () => {
if (t.preferenze.mesi.includes(value)) {
await setConsegna(t.preferenze.mesi.indexOf(value));
return;
} else {
console.warn("Value not found in preferenze.mesi");
await setConsegna(null);
}
console.warn("Value not found in preferenze.mesi");
await setConsegna(null);
}}
options={mappedConsegnaOptions}
placeholder={t.seleziona_placeholder}

View file

@ -309,32 +309,31 @@ const Pricing = ({
}
/>
);
} else {
return (
<Accordion className="w-full" collapsible type="single">
<AccordionItem value="item-1">
<AccordionTrigger className="px-1 text-xl font-semibold">
{t.pricing_cmp.cta_costo}
</AccordionTrigger>
<AccordionContent className="flex justify-center">
<PricingComponent
className={cn(style)}
cta={cta}
opzioni={opzioni}
pricingData={pricing}
statico={true}
tipo={tipologia}
title={
tipologia === TipologiaPosizioneEnum.Transitorio
? t.prezzi.titolo_transitori
: t.prezzi.titolo_stabile
}
/>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
return (
<Accordion className="w-full" collapsible type="single">
<AccordionItem value="item-1">
<AccordionTrigger className="px-1 text-xl font-semibold">
{t.pricing_cmp.cta_costo}
</AccordionTrigger>
<AccordionContent className="flex justify-center">
<PricingComponent
className={cn(style)}
cta={cta}
opzioni={opzioni}
pricingData={pricing}
statico={true}
tipo={tipologia}
title={
tipologia === TipologiaPosizioneEnum.Transitorio
? t.prezzi.titolo_transitori
: t.prezzi.titolo_stabile
}
/>
</AccordionContent>
</AccordionItem>
</Accordion>
);
};
const TestiAnnuncio = ({
@ -459,11 +458,13 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<div className="grid grid-cols-2 gap-3">
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<BedDouble />
{data.numero_camere && data.numero_camere
? data.numero_camere > 1
? `${data.numero_camere} ${t.card.camere2}`
: `${data.numero_camere} ${t.card.camere1}`
: "N/A"}
{(() => {
if (!data.numero_camere) return "N/A";
if (data.numero_camere > 1)
return `${data.numero_camere} ${t.card.camere2}`;
if (data.numero_camere === 1)
return `${data.numero_camere} ${t.card.camere1}`;
})()}
</div>
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<Bath />
@ -492,11 +493,12 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<Building2 />
<span>
{data.piano && data.piano === "0"
? "piano terra"
: data.piano === "0.5"
? "piano rialz."
: `${data.piano}° piano`}
{(() => {
if (data.piano === "0") return "piano terra";
if (data.piano === "0.5") return "piano rialz.";
if (data.piano) return `${data.piano}° piano`;
return "";
})()}
</span>
</div>
</div>
@ -635,27 +637,15 @@ const AnnuncioFooter = ({
if (!video) return null;
if (video.includes("youtu")) {
return null;
/*return (
<iframe
title="video"
className={cn("h-96 w-auto rounded-md")}
src={video}
//src={`https://www.youtube-nocookie.com/embed/${video.split(/[/ ]+/).pop()}`}
allow=" autoplay; encrypted-media"
allowFullScreen
key={`ytplayer-${video}`}
/>
);*/
} else {
return (
<VideoPlayer
className="h-96 max-w-96"
coverImage={first_image}
key={`videoplayer-${video}`}
videoSrc={video}
/>
);
}
return (
<VideoPlayer
className="h-96 max-w-96"
coverImage={first_image}
key={`videoplayer-${video}`}
videoSrc={video}
/>
);
})}
</div>

View file

@ -59,12 +59,11 @@ export const getServerSideProps = (async (context) => {
token,
},
};
} else {
return {
redirect: {
destination: "/auth/nonvalid-password-reset-token",
permanent: false,
},
};
}
return {
redirect: {
destination: "/auth/nonvalid-password-reset-token",
permanent: false,
},
};
}) satisfies GetServerSideProps<ResetWTokenProps>;

View file

@ -277,22 +277,24 @@ export const getCursor_AnnunciHandler = async ({
if (consegna) {
query = query.where("consegna", "=", consegna);
}
if (sort) {
switch (sort) {
case "Recenti":
query = query.orderBy("modificato_il", "desc");
break;
case "Prezzo":
query = query.orderBy("prezzo", "asc");
break;
case "Consegna":
query = query.orderBy("consegna", "asc");
break;
case "Mq":
query = query.orderBy("mq", "asc");
break;
}
switch (sort) {
case "Recenti":
query = query.orderBy("modificato_il", "desc");
break;
case "Prezzo":
query = query.orderBy("prezzo", "asc");
break;
case "Consegna":
query = query.orderBy("consegna", "asc");
break;
case "Mq":
query = query.orderBy("mq", "asc");
break;
case undefined:
break;
}
query = query.orderBy("id", "asc");
const annunci = await query

View file

@ -158,17 +158,16 @@ export const upsertAnagrafica = async ({
.where("userid", "=", userid)
.returningAll()
.executeTakeFirst();
} else {
return await db
.insertInto("users_anagrafica")
.values({
userid,
...rest,
})
.onConflict((oc) => oc.column("userid").doNothing())
.returningAll()
.executeTakeFirst();
}
return await db
.insertInto("users_anagrafica")
.values({
userid,
...rest,
})
.onConflict((oc) => oc.column("userid").doNothing())
.returningAll()
.executeTakeFirst();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",