chore: update biome schema and dependencies, refactor key usage in components

- Updated biome schema version from 2.2.2 to 2.3.1 in biome.json.
- Removed experimentalScannerIgnores from files section and replaced with ignore patterns.
- Added CSS parser configuration for Tailwind directives.
- Updated linter rules for better code quality.
- Refactored key usage in various components to use unique identifiers instead of array indices.
- Updated package-lock.json and package.json to reflect new biome version.
- General code cleanup and improvements across multiple components for better maintainability.
This commit is contained in:
Marco Pedone 2025-10-28 11:55:01 +01:00
parent b83527eb97
commit f85ea22215
29 changed files with 143 additions and 122 deletions

View file

@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.2/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.1/schema.json",
"assist": {
"actions": {
"source": {
@ -11,19 +11,6 @@
},
"files": {
"experimentalScannerIgnores": [
"node_modules",
"dist",
"build",
".next",
".git",
"public",
".github",
".vscode",
"certificates",
"headers",
"schemas"
],
"ignoreUnknown": true,
"includes": [
"**",
@ -52,7 +39,18 @@
"!src/i18n/comuni.ts",
"!src/i18n/nazioni.ts",
"!src/i18n/provincie.ts",
"!src/styles/globals.css"
"!src/styles/globals.css",
"!!**/node_modules",
"!!**/dist",
"!!**/build",
"!!**/.next",
"!!**/.git",
"!!**/public",
"!!**/.github",
"!!**/.vscode",
"!!**/certificates",
"!!**/headers",
"!!**/schemas"
]
},
"formatter": {
@ -64,6 +62,11 @@
"quoteStyle": "double"
}
},
"css": {
"parser": {
"tailwindDirectives": true
}
},
"linter": {
"domains": {
"next": "recommended",
@ -85,7 +88,9 @@
"noUndeclaredVariables": "on",
"useExhaustiveDependencies": "off",
"useHookAtTopLevel": "off",
"useParseIntRadix": "off"
"useParseIntRadix": "off",
"noChildrenProp": "error",
"noReactPropAssignments": "error"
},
"nursery": {
"useExhaustiveSwitchCases": "on",
@ -111,7 +116,7 @@
"useThrowOnlyError": "on"
},
"suspicious": {
"noArrayIndexKey": "off",
"noArrayIndexKey": "info",
"noDocumentImportInPage": "on",
"noHeadImportInDocument": "on",
"noUnknownAtRules": "off",

View file

@ -54,12 +54,12 @@ const OnboardingServizio = ({
</Button>
</Section>
<Section>
{annunci?.map((annuncio, index) => (
{annunci?.map((annuncio) => (
<>
<Text className="font-semibold">
Annunci selezionati per te:
</Text>
<Section className="mb-[30px]" key={index}>
<Section className="mb-[30px]" key={annuncio.codice}>
<Row className="mb-[12px]">
<Img
alt={`Annuncio image - ${annuncio.codice}`}

View file

@ -91,7 +91,7 @@
"zod": "^4.1.12"
},
"devDependencies": {
"@biomejs/biome": "2.2.2",
"@biomejs/biome": "^2.3.1",
"@hookform/devtools": "^4.4.0",
"@react-email/preview-server": "^4.2.8",
"@total-typescript/ts-reset": "^0.6.1",
@ -1044,9 +1044,9 @@
}
},
"node_modules/@biomejs/biome": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.2.tgz",
"integrity": "sha512-j1omAiQWCkhuLgwpMKisNKnsM6W8Xtt1l0WZmqY/dFj8QPNkIoTvk4tSsi40FaAAkBE1PU0AFG2RWFBWenAn+w==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.1.tgz",
"integrity": "sha512-A29evf1R72V5bo4o2EPxYMm5mtyGvzp2g+biZvRFx29nWebGyyeOSsDWGx3tuNNMFRepGwxmA9ZQ15mzfabK2w==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@ -1060,20 +1060,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "2.2.2",
"@biomejs/cli-darwin-x64": "2.2.2",
"@biomejs/cli-linux-arm64": "2.2.2",
"@biomejs/cli-linux-arm64-musl": "2.2.2",
"@biomejs/cli-linux-x64": "2.2.2",
"@biomejs/cli-linux-x64-musl": "2.2.2",
"@biomejs/cli-win32-arm64": "2.2.2",
"@biomejs/cli-win32-x64": "2.2.2"
"@biomejs/cli-darwin-arm64": "2.3.1",
"@biomejs/cli-darwin-x64": "2.3.1",
"@biomejs/cli-linux-arm64": "2.3.1",
"@biomejs/cli-linux-arm64-musl": "2.3.1",
"@biomejs/cli-linux-x64": "2.3.1",
"@biomejs/cli-linux-x64-musl": "2.3.1",
"@biomejs/cli-win32-arm64": "2.3.1",
"@biomejs/cli-win32-x64": "2.3.1"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.2.tgz",
"integrity": "sha512-6ePfbCeCPryWu0CXlzsWNZgVz/kBEvHiPyNpmViSt6A2eoDf4kXs3YnwQPzGjy8oBgQulrHcLnJL0nkCh80mlQ==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.1.tgz",
"integrity": "sha512-ombSf3MnTUueiYGN1SeI9tBCsDUhpWzOwS63Dove42osNh0PfE1cUtHFx6eZ1+MYCCLwXzlFlYFdrJ+U7h6LcA==",
"cpu": [
"arm64"
],
@ -1088,9 +1088,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.2.tgz",
"integrity": "sha512-Tn4JmVO+rXsbRslml7FvKaNrlgUeJot++FkvYIhl1OkslVCofAtS35MPlBMhXgKWF9RNr9cwHanrPTUUXcYGag==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.1.tgz",
"integrity": "sha512-pcOfwyoQkrkbGvXxRvZNe5qgD797IowpJPovPX5biPk2FwMEV+INZqfCaz4G5bVq9hYnjwhRMamg11U4QsRXrQ==",
"cpu": [
"x64"
],
@ -1105,9 +1105,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.2.tgz",
"integrity": "sha512-JfrK3gdmWWTh2J5tq/rcWCOsImVyzUnOS2fkjhiYKCQ+v8PqM+du5cfB7G1kXas+7KQeKSWALv18iQqdtIMvzw==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.1.tgz",
"integrity": "sha512-td5O8pFIgLs8H1sAZsD6v+5quODihyEw4nv2R8z7swUfIK1FKk+15e4eiYVLcAE4jUqngvh4j3JCNgg0Y4o4IQ==",
"cpu": [
"arm64"
],
@ -1122,9 +1122,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.2.tgz",
"integrity": "sha512-/MhYg+Bd6renn6i1ylGFL5snYUn/Ct7zoGVKhxnro3bwekiZYE8Kl39BSb0MeuqM+72sThkQv4TnNubU9njQRw==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.1.tgz",
"integrity": "sha512-+DZYv8l7FlUtTrWs1Tdt1KcNCAmRO87PyOnxKGunbWm5HKg1oZBSbIIPkjrCtDZaeqSG1DiGx7qF+CPsquQRcg==",
"cpu": [
"arm64"
],
@ -1139,9 +1139,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.2.tgz",
"integrity": "sha512-Ogb+77edO5LEP/xbNicACOWVLt8mgC+E1wmpUakr+O4nKwLt9vXe74YNuT3T1dUBxC/SnrVmlzZFC7kQJEfquQ==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.1.tgz",
"integrity": "sha512-PYWgEO7up7XYwSAArOpzsVCiqxBCXy53gsReAb1kKYIyXaoAlhBaBMvxR/k2Rm9aTuZ662locXUmPk/Aj+Xu+Q==",
"cpu": [
"x64"
],
@ -1156,9 +1156,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.2.tgz",
"integrity": "sha512-ZCLXcZvjZKSiRY/cFANKg+z6Fhsf9MHOzj+NrDQcM+LbqYRT97LyCLWy2AS+W2vP+i89RyRM+kbGpUzbRTYWig==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.1.tgz",
"integrity": "sha512-Y3Ob4nqgv38Mh+6EGHltuN+Cq8aj/gyMTJYzkFZV2AEj+9XzoXB9VNljz9pjfFNHUxvLEV4b55VWyxozQTBaUQ==",
"cpu": [
"x64"
],
@ -1173,9 +1173,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.2.tgz",
"integrity": "sha512-wBe2wItayw1zvtXysmHJQoQqXlTzHSpQRyPpJKiNIR21HzH/CrZRDFic1C1jDdp+zAPtqhNExa0owKMbNwW9cQ==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.1.tgz",
"integrity": "sha512-RHIG/zgo+69idUqVvV3n8+j58dKYABRpMyDmfWu2TITC+jwGPiEaT0Q3RKD+kQHiS80mpBrST0iUGeEXT0bU9A==",
"cpu": [
"arm64"
],
@ -1190,9 +1190,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.2.tgz",
"integrity": "sha512-DAuHhHekGfiGb6lCcsT4UyxQmVwQiBCBUMwVra/dcOSs9q8OhfaZgey51MlekT3p8UwRqtXQfFuEJBhJNdLZwg==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.1.tgz",
"integrity": "sha512-izl30JJ5Dp10mi90Eko47zhxE6pYyWPcnX1NQxKpL/yMhXxf95oLTzfpu4q+MDBh/gemNqyJEwjBpe0MT5iWPA==",
"cpu": [
"x64"
],

View file

@ -101,7 +101,7 @@
"zod": "^4.1.12"
},
"devDependencies": {
"@biomejs/biome": "2.2.2",
"@biomejs/biome": "^2.3.1",
"@hookform/devtools": "^4.4.0",
"@react-email/preview-server": "^4.2.8",
"@total-typescript/ts-reset": "^0.6.1",

View file

@ -11,8 +11,8 @@ export default function AnnunciList({ annunci }: AnnunciProps) {
return (
<ul>
{allAnnunci.map((ann, i) => (
<li key={i}>{ann.codice}</li>
{allAnnunci.map((ann) => (
<li key={ann.codice}>{ann.codice}</li>
))}
</ul>
);

View file

@ -40,6 +40,7 @@ export const AccordionComp = forwardRef<HTMLDivElement, AccordionCompProps>(
>
<Accordion className="w-full" collapsible type="single">
{texts.map((text, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: <index is safe here>
<AccordionItem key={`ac-item-${index}`} value={`item-${index}`}>
<AccordionTrigger className="cursor-pointer gap-4 text-left text-lg">
{text.title}

View file

@ -130,8 +130,8 @@ function Receipt({ data }: ReceiptProps) {
</tr>
</thead>
<tbody>
{data.items.map((item, idx) => (
<tr className="border-b" key={idx}>
{data.items.map((item) => (
<tr className="border-b" key={item.description}>
<td className="py-2">{item.description}</td>
<td className="py-2 text-right">
{formatCurrency(item.price)}

View file

@ -89,7 +89,7 @@ export const CardAnnuncio = ({
<Carousel opts={{ loop: true }}>
<CarouselContent>
{images?.map((img, idx) => (
<CarouselItem className="" key={`${img}-${idx}`}>
<CarouselItem className="" key={`${img.img}key`}>
<ImageFlbk
alt={t.card.alt_immagine}
blurDataURL={`/storage-api/get/${img.thumb}?image=true`}
@ -101,7 +101,7 @@ export const CardAnnuncio = ({
/>
</CarouselItem>
))}
{videos?.map((video, idx) => {
{videos?.map((video) => {
if (!video) return null;
if (video.includes("youtu")) {
return null;
@ -123,7 +123,7 @@ export const CardAnnuncio = ({
? `/storage-api/get/${images[0].img}?image=true`
: ""
}
key={`videoplayer-${idx}`}
key={`videoplayer-${video}`}
videoSrc={video}
/>
</CarouselItem>
@ -268,7 +268,7 @@ export const CarouselAnnuncio = ({
? ""
: !single && "md:basis-1/2 lg:basis-1/3",
)}
key={`${img}-${idx}-cF`}
key={`${img}-cF`}
>
<ImageFlbk
alt={img}
@ -348,7 +348,7 @@ export const CarouselAnnuncio = ({
<Carousel opts={{ loop: true, startIndex: idxModal }}>
<CarouselContent>
{immagini?.map((img, idx) => (
<CarouselItem key={`${img}-${idx}-cD`}>
<CarouselItem key={`${img}-cD`}>
<Image
alt={`carousel-img-${idx}`}
className="mx-auto h-[90vh] w-full rounded-md object-contain sm:w-[80vw]"

View file

@ -34,7 +34,7 @@ export const EmailAccordion = ({ userId }: { userId: UsersId }) => {
{data.map((email, index) => (
<AccordionItem
className="space-y-2 border-none"
key={index}
key={email.title}
value={String(index)}
>
<AccordionTrigger className="rounded-md bg-muted px-4 py-2">

View file

@ -309,7 +309,7 @@ const Typers = ({
}) => {
return (
<>
{currentTypers.map((typer, index) => {
{currentTypers.map((typer) => {
if (typer.userId === userId) return null;
const variant = "received";
@ -319,7 +319,7 @@ const Typers = ({
className="flex flex-col gap-2 py-2"
exit={{ opacity: 0, scale: 1, x: 0, y: 1 }}
initial={{ opacity: 0, scale: 1, x: 0, y: 50 }}
key={`typers${messageLenght}${index}`}
key={`typers${messageLenght}${typer.userId}`}
layout
style={{ originX: 0.5, originY: 0.5 }}
transition={{

View file

@ -137,7 +137,7 @@ const UserStatus = ({
<div className="flex flex-row items-center gap-2">
{onlineStatus.map((user, idx) =>
user.isAdmin ? (
<TooltipProvider delayDuration={0} key={idx}>
<TooltipProvider delayDuration={0} key={user.userId}>
<Tooltip>
<TooltipTrigger>
<span
@ -160,7 +160,7 @@ const UserStatus = ({
) : (
<span
className={cn("flex flex-row font-bold text-green-500 text-xs")}
key={idx}
key={user.userId}
>
<span>
{user.nome}

View file

@ -43,14 +43,14 @@ export const ComeFunziona = () => {
{t.come_funziona.title}
</h2>
<div className="mx-auto mt-8 w-full space-y-12 md:mt-16">
{features.map((feature, idx) => (
{features.map((feature) => (
<div
className="flex flex-col items-center gap-x-8 gap-y-6 lg:flex-row lg:odd:flex-row-reverse"
key={idx}
key={feature.title}
>
<div className="flex shrink-0 basis-1/2 justify-center">
<Image
alt={`img${idx}`}
alt={`img${feature.title}`}
className="aspect-[6/4] rounded-xl border border-border/50"
height={200}
src={feature.image}

View file

@ -113,6 +113,7 @@ export const AnimatedButton = forwardRef<
`absolute top-1/2 left-1/2 opacity-0 sparkle-${index}`,
sparklesClassName,
)}
// biome-ignore lint/suspicious/noArrayIndexKey: <index is safe here>
key={index}
type={sparklesIcon}
/>

View file

@ -55,7 +55,14 @@ export const StaggeredFade: React.FC<TextStaggeredFadeProps> = ({
viewport={{ once: true }}
>
{letters.map((word, i) => (
<motion.span custom={i} key={`${word}-${i}`} variants={variants}>
<motion.span
custom={i}
key={`${word}-${
// biome-ignore lint/suspicious/noArrayIndexKey: <index is safe here>
i
}`}
variants={variants}
>
{word}
</motion.span>
))}

View file

@ -101,8 +101,11 @@ export const EtichetteModal = ({
</DialogHeader>
<div className="space-y-5">
<div className="flex flex-col gap-2">
{data.map((etichetta, idx) => (
<div className="flex gap-2" key={idx}>
{data.map((etichetta) => (
<div
className="flex gap-2"
key={`${etichetta.id_etichetta}${chatId}`}
>
<Etichetta
color_hex={etichetta.color_hex}
title={etichetta.title}
@ -128,8 +131,11 @@ export const EtichetteModal = ({
<SelectValue placeholder="Seleziona" />
</SelectTrigger>
<SelectContent>
{etichette?.map((etichetta, idx) => (
<SelectItem key={idx} value={String(etichetta.id_etichetta)}>
{etichette?.map((etichetta) => (
<SelectItem
key={etichetta.id_etichetta}
value={String(etichetta.id_etichetta)}
>
{etichetta.title}
</SelectItem>
))}

View file

@ -188,6 +188,7 @@ const MapComp = ({
/>
{isGroup ? (
// biome-ignore lint/suspicious/noArrayIndexKey: <index is acceptable here>
groupData.map((pos, i) => <MarkerComp key={i} pos={pos} />)
) : (
<MarkerComp pos={posix} />

View file

@ -178,8 +178,8 @@ const Items = ({
}) => {
return (
<DropdownMenuGroup>
{items?.map((item, idx) => (
<DropdownMenuItem className="p-0" key={idx}>
{items?.map((item) => (
<DropdownMenuItem className="p-0" key={item.href}>
<Link
aria-label={`Link to ${item.title}`}
className="flex h-full w-full items-center gap-3 px-2 py-1.5"

View file

@ -214,7 +214,7 @@ export const PricingComponent = ({
"h-9 xs:h-10 rounded-md border-none px-3 xs:px-4 xs:py-2",
idx === Value ? "fade-in-0 animate-in" : "",
)}
key={idx}
key={opzione}
onClick={() => {
ClearCarousel();
setValue(idx);
@ -294,7 +294,7 @@ export const PricingComponentConsulenza = ({
"h-9 xs:h-10 rounded-md border-none px-3 xs:px-4 xs:py-2",
idx === Value ? "fade-in-0 animate-in" : "",
)}
key={idx}
key={opzione}
onClick={() => {
ClearCarousel();
setValue(idx);

View file

@ -209,13 +209,12 @@ function SchedaAnnuncio({ data }: { data: Annunci }) {
</h3>
<div className="grid grid-cols-4 gap-2 text-sm">
{data.caratteristiche &&
filteredCaratteristiche(data.caratteristiche).map(
(item, index) => {
filteredCaratteristiche(data.caratteristiche).map((item) => {
if (!item.value) return null;
return (
<div
className="flex items-center justify-start gap-2"
key={index}
key={item.text}
>
<span className="">
<IconMatrix type={item.icon} />
@ -225,8 +224,7 @@ function SchedaAnnuncio({ data }: { data: Annunci }) {
</span>
</div>
);
},
)}
})}
</div>
</div>

View file

@ -47,7 +47,7 @@ export const TabRicerca = ({
<Row
defaultOpen={getDefaultOpen(idx)}
isAdmin={isAdmin}
key={idx}
key={servizio.servizio_id}
servizio={servizio}
userId={userId}
/>

View file

@ -105,13 +105,13 @@ export const TabServizio = ({
</TableRow>
</TableHeader>
<TableBody>
{data.map((servizio, idx) => {
{data.map((servizio) => {
const onboardDone =
servizio.isInterrotto ||
servizio.isOkAcconto ||
servizio.decorrenza !== null;
return (
<TableRow key={idx}>
<TableRow key={servizio.servizio_id}>
<TableCell className="max-w-20 truncate font-medium">
{servizio.servizio_id}
</TableCell>

View file

@ -501,6 +501,7 @@ function YearGrid({
"bg-accent font-medium text-accent-foreground",
)}
disabled={navView === "years" ? isDisabled : undefined}
// biome-ignore lint/suspicious/noArrayIndexKey: <index is acceptable here>
key={i}
onClick={() => {
setNavView("days");

View file

@ -58,6 +58,7 @@ function Slider({
thumbClassName,
)}
data-slot="slider-thumb"
// biome-ignore lint/suspicious/noArrayIndexKey: <index is safe here>
key={index}
/>
))}

View file

@ -248,8 +248,8 @@ export const UploadComponent = ({
</FileUploadTrigger>
</FileUploadDropzone>
<FileUploadList>
{files.map((file, index) => (
<FileUploadItem key={index} value={file}>
{files.map((file) => (
<FileUploadItem key={file.name} value={file}>
<FileUploadItemPreview />
<FileUploadItemMetadata />
<FileUploadItemDelete asChild>

View file

@ -479,12 +479,12 @@ export const FormNewServizio = ({
</Label>
<FormDescription>{t.preferenze.altrepref_desc}</FormDescription>
<div className="mt-2 flex flex-wrap gap-2">
{altrePrefMapping.map((pair, index) => {
{altrePrefMapping.map((pair) => {
if (pair) {
return (
<FormField
control={form.control}
key={index}
key={pair[0]}
name={pair[0]}
render={({ field }) => (
<FormItem>

View file

@ -776,12 +776,12 @@ export const FormNewServizioAcquisto = ({
</Label>
<FormDescription>{t.preferenze.altrepref_desc}</FormDescription>
<div className="mt-2 flex flex-wrap gap-2">
{altrePrefMapping.map((pair, index) => {
{altrePrefMapping.map((pair) => {
if (pair) {
return (
<FormField
control={form.control}
key={index}
key={pair[0]}
name={pair[0]}
render={({ field }) => (
<FormItem>

View file

@ -267,8 +267,8 @@ const FatturazioneData = ({ cf }: { cf: string }) => {
return (
<>
{data.data && data.data.length > 0 ? (
data.data.map((client, idx) => (
<div className="space-y-4" key={idx}>
data.data.map((client, i) => (
<div className="space-y-4" key={client.id || i}>
<h3 className="font-semibold text-lg">Dati Fatturazione</h3>
<p>Nome: {client.name}</p>
<p>Codice Fiscale: {client.tax_code}</p>

View file

@ -62,10 +62,10 @@ const FAQSection = () => {
<div className="flex w-full max-w-6xl justify-between gap-5">
<div className="hidden flex-col gap-5 md:flex">
{t.faq.domande.map((item, index) => (
{t.faq.domande.map((item) => (
<Button
className="justify-start font-semibold text-lg"
key={index}
key={item.id}
onClick={() => handleScroll(`faq-${item.id}`)}
variant="ghost"
>
@ -74,11 +74,11 @@ const FAQSection = () => {
))}
</div>
<div className="flex w-full flex-col gap-5">
{t.faq.domande.map((item, index) => (
{t.faq.domande.map((item) => (
<Accordion
className="relative w-full rounded-lg bg-neutral-50 p-4"
collapsible
key={index}
key={item.id}
//defaultValue="0"
type="single"
>
@ -86,7 +86,7 @@ const FAQSection = () => {
<h3 className="font-semibold text-2xl">{item.label}</h3>
<div className="flex flex-col gap-1">
{item.qas.map((f, i) => (
<AccordionItem key={i} value={i.toString()}>
<AccordionItem key={item.id} value={i.toString()}>
<AccordionTrigger className="text-left">
{f.title}
</AccordionTrigger>

View file

@ -74,8 +74,8 @@ const Prezzi: NextPage = () => {
<p>{t.prezzi.desc_transitori}</p>
<div className="my-5">
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{t.prezzi.cta_transitori.map((item, idx) => (
<li className="flex gap-x-4" key={idx}>
{t.prezzi.cta_transitori.map((item) => (
<li className="flex gap-x-4" key={item.titolo}>
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-sky-50 text-sky-600">
<IconMatrix type={item.icon} />
</div>
@ -119,8 +119,8 @@ const Prezzi: NextPage = () => {
<p>{t.prezzi.desc_stabile}</p>
<div className="my-5">
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{t.prezzi.cta_stabile.map((item, idx) => (
<li className="flex gap-x-4" key={idx}>
{t.prezzi.cta_stabile.map((item) => (
<li className="flex gap-x-4" key={item.titolo}>
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-orange-50 text-orange-600">
<IconMatrix type={item.icon} />
</div>
@ -166,8 +166,8 @@ const Prezzi: NextPage = () => {
<p>{t.prezzi.desc_contratti}</p>
<div className="my-5">
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{t.prezzi.cta_contratti.map((item, idx) => (
<li className="flex gap-x-4" key={idx}>
{t.prezzi.cta_contratti.map((item) => (
<li className="flex gap-x-4" key={item.titolo}>
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-green-50 text-green-600">
<IconMatrix type={item.icon} />
</div>