feat: Update UI components and styles across multiple pages

- Enhanced the CardInfos component in [cod].tsx with improved styling and added TrafficCone icon for status indication.
- Increased dialog content width in prezziario.tsx and testi-stringhe.tsx for better layout.
- Replaced static badge elements with the Badge component in chi-siamo.tsx, contatti.tsx, guida.tsx, prezzi.tsx, and proprietari.tsx for consistent styling.
- Updated button components to use the Button component in contatti.tsx and proprietari.tsx for improved accessibility and styling.
- Modified the TrovaCasaCTA and FrequentSearches components in index.tsx for better visual consistency and updated color usage.
- Refactored global CSS variables for improved color management and added new color variables for better theme support.
- Implemented dynamic loading for the KabanExample component in test.tsx to enhance performance.
This commit is contained in:
Marco Pedone 2025-11-14 17:21:21 +01:00
parent 219f76dd10
commit d7bfd8fdf1
46 changed files with 749 additions and 609 deletions

View file

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

View file

@ -106,7 +106,7 @@ const SelectedComp = memo(
<motion.a
animate={{ opacity: 1, scale: 1 }}
aria-label="Visualizza Dettagli Annuncio"
className="group absolute right-0 bottom-0 left-0 z-20 mx-2 mb-2 flex flex-col gap-2 rounded-md bg-white p-4 ring-neutral-500 hover:ring-1"
className="group absolute right-0 bottom-0 left-0 z-20 mx-2 mb-2 flex flex-col gap-2 rounded-md bg-primary-foreground p-4 text-foreground ring-neutral-500 hover:ring-1"
exit={{ opacity: 0, scale: 0 }}
href={`/annuncio/${selected.codice}`}
initial={{ opacity: 0, scale: 0 }}

View file

@ -54,7 +54,7 @@ export const CTA_TipologiaModal = () => {
open={open}
>
<DialogTrigger asChild>
<Button variant="info">
<Button>
<CircleHelp />{" "}
<span className="hidden sm:block">
{t.tipologia_tutorial.btn_title}

View file

@ -8,7 +8,6 @@ import {
Star,
TrafficCone,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { type RefObject, useEffect, useRef, useState } from "react";
import { useIntersection } from "react-use";
@ -88,7 +87,7 @@ export const LazyCardAnnuncio = (props: CardAnnuncioProps) => {
const SkeletonCardAnnuncio = () => {
return (
<div className="h-[31.1rem] rounded-md bg-white p-2 outline outline-neutral-300 hover:outline-neutral-600">
<div className="h-[31.1rem] rounded-md bg-secondary p-2 outline outline-neutral-300 hover:outline-neutral-600">
<div className="flex h-full flex-col gap-2 p-2">
<Skeleton className="h-64 w-full rounded-t-md" />
<div className="flex flex-col gap-2">
@ -154,7 +153,7 @@ export const CardAnnuncio = ({
return (
<div
className={cn(
"relative h-[31.1rem] rounded-md bg-white outline outline-neutral-300 hover:outline-neutral-600",
"relative h-[31.1rem] rounded-md bg-secondary outline outline-fxd-foreground/60 hover:outline-fxd-foreground dark:bg-primary",
className,
)}
id={`card-annuncio-${id}`}
@ -168,10 +167,10 @@ export const CardAnnuncio = ({
"pointer-events-none absolute inset-0 z-20 size-full rounded-md",
homepage &&
(isAvailableNow
? "border-[.35rem] border-green-500"
: "border-[.35rem] border-blue-500"),
? "border-[.35rem] border-dasubito"
: "border-[.35rem] border-evidenza"),
stato === "Trattativa" && "border-[.35rem] border-violet-500",
stato === "Trattativa" && "border-[.35rem] border-trattativa",
)}
></div>
{stato !== "Trattativa" && homepage && (
@ -179,12 +178,14 @@ export const CardAnnuncio = ({
<Badge
className={cn(
"flex items-center gap-1.5 rounded-t-none px-1 py-0.5 font-semibold text-base text-white shadow-lg [&>svg]:size-4.5",
isAvailableNow ? "bg-green-500" : "bg-blue-500",
isAvailableNow
? "bg-dasubito"
: "bg-evidenza text-primary dark:text-accent",
)}
>
{isAvailableNow ? (
<>
<span>Disponibile Subito</span>
<span>Libero Subito</span>
<Siren />
</>
) : (
@ -200,7 +201,7 @@ export const CardAnnuncio = ({
<div className="absolute top-1 z-20 flex w-full justify-center px-2">
<Badge
className={cn(
"flex items-center gap-1.5 rounded-t-none bg-violet-500 px-1 py-0.5 font-semibold text-base text-white shadow-lg [&>svg]:size-4.5",
"flex items-center gap-1.5 rounded-t-none bg-trattativa px-1 py-0.5 font-semibold text-base text-white shadow-lg [&>svg]:size-4.5",
)}
>
<span>In Trattativa</span>
@ -216,7 +217,7 @@ export const CardAnnuncio = ({
<ImageFlbk
alt={t.card.alt_immagine}
blurDataURL={`/storage-api/get/${img.thumb}?image=true`}
className={"h-64 w-full object-cover"}
className={"h-64 w-full bg-[#e6e9ec] object-cover"}
height={1080}
priority={idx === 0}
src={`/storage-api/get/${img.img}?image=true`}
@ -310,11 +311,11 @@ export const CardAnnuncio = ({
<div className="w-full text-center">
<span className="sr-only">{t.card.codice}</span>
<span className="font-semibold text-red-500 text-xl">
<span className="font-semibold text-destructive text-xl">
Cod: {codice}
</span>
</div>
<div className="w-full text-center">
<div className="w-full text-center text-primary dark:text-accent">
<span className="sr-only">{t.card.prezzo}</span>
<span className="font-semibold text-xl">
@ -323,58 +324,57 @@ export const CardAnnuncio = ({
</div>
</div>
<div className="flex h-full grow flex-col justify-between">
<div className="px-4 text-center text-muted-foreground">
<div className="px-4 text-center text-primary dark:text-accent">
<span className="sr-only">{t.card.titolo}</span>
<span className="line-clamp-3 overflow-ellipsis font-medium text-base">
{locale === "it" ? titolo_it : titolo_en}
</span>
</div>
<div className="flex flex-col gap-4">
<div className="text-center text-muted-foreground">
<span className="sr-only">{t.card.indirizzo}</span>
<MapPin className="mr-1 mb-1 inline-block size-4" />
<span className="font-medium text-sm">
{comune && provincia && `${comune} (${provincia})`}
</span>
<div className="text-center text-primary dark:text-accent">
<span className="sr-only">{t.card.indirizzo}</span>
<MapPin className="mr-1 mb-1 inline-block size-4" />
<span className="font-medium text-sm">
{comune && provincia && `${comune} (${provincia})`}
</span>
</div>
<div className="flex h-9 items-center justify-around gap-1.5 text-primary text-xs">
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
<Ruler className="size-4" />
<div>
<p className="font-medium">
{mq ? Number.parseFloat(mq) : 0}{" "}
<span>
m<sup>2</sup>
</span>
</p>
</div>
</div>
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
<BedDouble className="size-4" />
<div className="flex h-9 items-center justify-around gap-1.5 text-neutral-700 text-xs">
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-neutral-100">
<Ruler className="size-4 text-neutral-900" />
<div>
<p className="font-medium">
{mq ? Number.parseFloat(mq) : 0}{" "}
<span>
m<sup>2</sup>
</span>
</p>
</div>
<div>
<p className="font-medium">
{camereTesti({ camere: camere, testi: t.card })}
</p>
</div>
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-neutral-100">
<BedDouble className="size-4 text-neutral-900" />
</div>
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
<CalendarClock className="size-4" />
<div>
<p className="font-medium">
{camereTesti({ camere: camere, testi: t.card })}
</p>
</div>
</div>
<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-neutral-100">
<CalendarClock className="size-4 text-neutral-900" />
<div>
<p className="truncate font-medium">
{handleConsegna({
aggiornamento: t.card.in_aggiornamento,
consegna: consegna,
consegna_da: t.card.consegna_da,
mesi: t.preferenze.mesi,
subito: t.card.consegna_subito,
})}
</p>
</div>
<div>
<p className="truncate font-medium">
{handleConsegna({
aggiornamento: t.card.in_aggiornamento,
consegna: consegna,
consegna_da: t.card.consegna_da,
mesi: t.preferenze.mesi,
subito: t.card.consegna_subito,
})}
</p>
</div>
</div>
</div>
@ -421,7 +421,7 @@ export const CarouselAnnuncio = ({
<ImageFlbk
alt={img}
className={cn(
"aspect-square max-h-92 w-full rounded-md object-cover sm:max-h-80 xl:max-h-[25rem]",
"aspect-square max-h-92 w-full rounded-md bg-[#e6e9ec] object-cover sm:max-h-80 xl:max-h-[25rem]",
immagini.length === 1 && "object-contain",
)}
height={400}
@ -431,7 +431,7 @@ export const CarouselAnnuncio = ({
width={800}
/>
<Maximize2
className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-white/70 stroke-2 p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-muted-foreground/60 stroke-2 stroke-muted p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
onClick={() => handleOpenModal(idx)}
/>
</CarouselItem>
@ -464,7 +464,7 @@ export const CarouselAnnuncio = ({
/>
<Maximize2
className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-white/70 stroke-2 p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-muted-foreground/60 stroke-2 stroke-muted p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
onClick={() =>
handleOpenModal(immagini?.length || 0 + idx)
}
@ -475,12 +475,12 @@ export const CarouselAnnuncio = ({
</CarouselContent>
<CarouselPrevious
className="left-2 cursor-pointer opacity-60 disabled:opacity-0"
className="left-2 cursor-pointer opacity-60 disabled:opacity-0 dark:border-muted-foreground dark:bg-muted-foreground dark:text-muted hover:dark:bg-muted-foreground/80"
disabled={!immagini || immagini.length === 1}
type="button"
/>
<CarouselNext
className="right-2 cursor-pointer opacity-60 disabled:opacity-0"
className="right-2 cursor-pointer opacity-60 disabled:opacity-0 dark:border-muted-foreground dark:bg-muted-foreground dark:text-muted hover:dark:bg-muted-foreground/80"
disabled={!immagini || immagini.length === 1}
type="button"
/>
@ -488,7 +488,7 @@ export const CarouselAnnuncio = ({
</div>
</div>
<Dialog onOpenChange={setOpenModal} open={openModal}>
<DialogContent className="flex h-full w-full max-w-full items-center justify-center border-transparent border-none bg-white p-0 md:max-w-[80vw] md:p-6 [&_#dialog-close>svg]:size-8">
<DialogContent className="flex h-full w-full max-w-full items-center justify-center border-transparent border-none bg-background p-0 md:max-w-[80vw] md:p-6 [&_#dialog-close>svg]:size-8">
<DialogHeader className="absolute top-0 right-0 left-0 z-10">
<DialogTitle className="sr-only">Image Dialog</DialogTitle>
<DialogDescription className="sr-only">Immagine</DialogDescription>
@ -497,9 +497,9 @@ export const CarouselAnnuncio = ({
<CarouselContent>
{immagini?.map((img, idx) => (
<CarouselItem key={`${img}-cD`}>
<Image
<ImageFlbk
alt={`carousel-img-${idx}`}
className="mx-auto h-[90vh] w-full rounded-md object-contain sm:w-[80vw]"
className="mx-auto h-[90vh] w-full rounded-md bg-[#e6e9ec] object-contain sm:w-[80vw]"
height={1080}
src={`/storage-api/get/${img}?image=true&${updated_at?.toString() || new Date().toString()}`}
width={1920}

View file

@ -33,13 +33,13 @@ export const Sidebar = ({
setIsAnimating(false);
}, 300);
};
//todo click to expand not working on direct links when minimized
return (
<motion.nav
animate={{ width: minimized ? 55 : 192 }}
aria-label="Sidebar Menu"
className={cn(
"z-30 hidden h-auto w-48 shrink-0 space-y-4 border-r bg-white pt-3 text-accent-foreground md:block",
"z-30 hidden h-auto w-48 shrink-0 space-y-4 border-muted border-r bg-background pt-3 md:block",
className,
minimized && "cursor-pointer",
)}

View file

@ -1,5 +1,5 @@
export default function BlurryDivider() {
return (
<hr className="h-px border-t-0 bg-gradient-to-r bg-transparent from-transparent via-neutral-500 to-transparent opacity-80 dark:via-neutral-50 dark:opacity-100" />
<hr className="h-px border-t-0 bg-gradient-to-r bg-transparent from-transparent via-foreground to-transparent opacity-80" />
);
}

View file

@ -85,7 +85,8 @@ const AutocompleteSearchBox = ({
<div className="z-[5000] w-full" ref={wrapperRef}>
<div
className={cn(
"relative flex w-full items-center justify-center rounded-md bg-white",
"relative flex w-full items-center justify-center rounded-md bg-[color-mix(in_oklch,var(--fxd-secondary)50%,white)]",
containerClassName,
)}
id="searchContainer"
@ -95,7 +96,7 @@ const AutocompleteSearchBox = ({
</label>
<Input
className={cn(
"z-10 cursor-pointer search-cancel:cursor-pointer rounded-md bg-transparent text-xl search-cancel:brightness-75 search-cancel:grayscale placeholder:font-bold placeholder:text-primary",
"z-10 cursor-pointer search-cancel:cursor-pointer rounded-md border-fxd-foreground bg-transparent text-fxd-foreground text-xl search-cancel:brightness-75 search-cancel:grayscale placeholder:font-bold placeholder:text-primary focus:ring-fxd-secondary",
className,
)}
id={inputId || "search"}
@ -121,7 +122,8 @@ const AutocompleteSearchBox = ({
{open && (
<div
className={cn(
"absolute z-50 mt-1 max-h-64 w-full overflow-hidden rounded-md border border-foreground bg-white shadow-xs ring-1 ring-foreground",
"absolute z-50 mt-1 max-h-64 w-full overflow-hidden rounded-md border border-fxd-foreground bg-fxd-secondary shadow-xs ring-1 ring-fxd-secondary",
optionBoxClassName,
)}
id="searchOptionsBox"
@ -131,7 +133,8 @@ const AutocompleteSearchBox = ({
className={cn(
"max-h-64 w-full overflow-y-auto",
navigationEnter &&
"[&>li:first-child>a]:bg-neutral-100 [&>li:first-child>a]:underline [&>li:first-child>a]:underline-offset-2",
"[&>li:first-child>a]:underline [&>li:first-child>a]:underline-offset-2",
"scrollbar-default",
)}
// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: <need list>
role="listbox"
@ -156,7 +159,7 @@ const AutocompleteSearchBox = ({
<li key={item}>
<Link
className={cn(
"flex w-full cursor-pointer items-center justify-between border-neutral-200 border-b bg-white px-4 py-2 text-neutral-500 text-xl duration-150 hover:bg-neutral-100 hover:text-neutral-600 hover:underline hover:underline-offset-2",
"flex w-full cursor-pointer items-center justify-between border-fxd-foreground border-b bg-[color-mix(in_oklch,var(--fxd-secondary)50%,white)] px-4 py-2 text-fxd-foreground text-xl duration-150 hover:bg-fxd-secondary hover:text-[color-mix(in_oklch,var(--fxd-foreground)90%,black)] hover:underline hover:underline-offset-2",
optionsClassName,
)}
href={`/annuncio/${item}`}
@ -194,7 +197,7 @@ const MovingText = ({ hidden }: { hidden: boolean }) => {
return (
<StaggeredFade
className="absolute font-bold text-2xl dark:text-neutral-800"
className="pointer-events-none absolute select-none font-bold text-2xl text-primary dark:text-primary-foreground"
hide={hidden}
key={randomFrase}
text={randomFrase}

View file

@ -58,7 +58,7 @@ export const ComeFunziona = () => {
/>
</div>
<div className="flex basis-1/2 flex-col">
<div className="flex items-center gap-3 text-blue-600">
<div className="flex items-center gap-3">
{feature.icon}
<h4 className="my-3 font-semibold text-3xl tracking-tight">
{feature.title}

View file

@ -133,12 +133,12 @@ export const MultiSelect = ({
classNames={{
control: () =>
cn(
"mt-2 w-full rounded-lg h-min-[42px] dark:bg-primary bg-white shadow-xs outline-hidden text-foreground dark:text-white",
"mt-2 w-full rounded-lg h-min-[42px] bg-foreground bg-card shadow-xs outline-hidden text-foreground",
),
input: () => cn("*:ring-0 focus:*:ring-0"),
menu: () =>
cn(
`dark:bg-black text-foreground bg-white dark:text-white border shadow-xs outline-hidden
`bg-foreground text-foreground dark:text-white border shadow-xs outline-hidden
dark:border-foreground border-neutral-300 overflow-hidden`,
menuOpen
? "animate-in fade-in-0 zoom-in-90"
@ -155,7 +155,7 @@ export const MultiSelect = ({
multiValueRemove: () => cn("rounded-s-none rounded-e-md"),
option: () =>
cn(
"dark:bg-black text-foreground bg-white dark:text-white border-b border-neutral-300 dark:border-foreground shadow-xs outline-hidden hover:text-primary hover:bg-neutral-200 dark:hover:bg-neutral-700",
"bg-card border-b border-foreground/50 shadow-xs outline-hidden hover:text-primary hover:bg-neutral-200 dark:hover:bg-neutral-700",
),
singleValue: () => cn("text-primary font-medium"),
valueContainer: () => cn("min-h-[38px]"),
@ -225,6 +225,13 @@ export const MultiSelect = ({
borderRadius: "0.5rem",
boxShadow: undefined,
minHeight: "42px",
backgroundColor: "var(--color-background)",
}) as CSSObjectWithLabel,
singleValue: (base) =>
({
...base,
color: "var(--color-primary)",
fontWeight: 500,
}) as CSSObjectWithLabel,
menu: (base) =>
({
@ -234,6 +241,7 @@ export const MultiSelect = ({
multiValue: (base) =>
({
...base,
color: "var(--color-primary)",
backgroundColor: undefined,
borderRadius: "0.5rem",
}) as CSSObjectWithLabel,
@ -241,6 +249,7 @@ export const MultiSelect = ({
({
...base,
borderRadius: "0.5rem",
color: "var(--color-primary)",
}) as CSSObjectWithLabel,
option: (base, state) =>
({

View file

@ -2,6 +2,7 @@ import Link from "next/link";
import { useRouter } from "next/router";
import { HomeIcon } from "~/components/IconComponents";
import { useTranslation } from "~/providers/I18nProvider";
import { Button } from "./ui/button";
export default function FailedAnnuncioLoading() {
const router = useRouter();
@ -10,26 +11,29 @@ export default function FailedAnnuncioLoading() {
<main>
<div className="mx-auto flex h-screen max-w-screen-xl items-center justify-start px-4 md:px-8">
<div className="mx-auto max-w-lg space-y-3 text-center">
<HomeIcon className="mx-auto size-20 text-rose-700" />
<HomeIcon className="mx-auto size-20 text-destructive" />
<h3 className="font-semibold text-4xl text-accent-foreground sm:text-5xl">
{t.annuncio_load_fail.titolo}
</h3>
<p className="text-neutral-600">{t.annuncio_load_fail.sottotitolo}</p>
<p className="">{t.annuncio_load_fail.sottotitolo}</p>
<div className="flex flex-wrap items-center justify-center gap-3">
<button
className="block rounded-lg bg-rose-600 px-4 py-2 font-medium text-white duration-150 hover:bg-rose-500 active:bg-rose-700"
<Button
onClick={() => {
router.back();
}}
type="button"
size="lg"
variant="destructive"
>
{t.annuncio_load_fail.CTA}
</button>
</Button>
<Link
className="block rounded-lg border px-4 py-2 font-medium text-neutral-700 duration-150 hover:bg-neutral-50 active:bg-neutral-100"
//className="block rounded-lg border border-border px-4 py-2 font-medium duration-150"
href="/annunci"
>
{t.annuncio_load_fail.home}
<Button size="lg" variant="outline">
{t.annuncio_load_fail.home}
</Button>
</Link>
</div>
</div>

View file

@ -11,12 +11,7 @@ export const Footer = ({ className }: FooterProps) => {
const { t } = useTranslation();
return (
<div className="mt-auto">
<footer
className={cn(
"bottom-0 z-40 w-full bg-muted text-muted-foreground",
className,
)}
>
<footer className={cn("bottom-0 z-40 w-full", className)}>
<div className="mx-auto max-w-6xl px-4 py-6 sm:px-6 lg:px-8">
<div className="text-center">
<Link
@ -24,7 +19,7 @@ export const Footer = ({ className }: FooterProps) => {
className="flex items-center justify-center font-bold text-3xl tracking-wide antialiased"
href="/"
>
<LogoSvg className="h-12 w-auto [&>g]:fill-red-500 dark:[&>g]:fill-neutral-100 [&>text]:fill-neutral-600 [&>text]:stroke-neutral-600 dark:[&>text]:fill-neutral-100 dark:[&>text]:stroke-neutral-100" />
<LogoSvg className="h-12 w-auto" />
</Link>
</div>
@ -87,12 +82,7 @@ export const MiniFooter = ({ className }: FooterProps) => {
const { t } = useTranslation();
return (
<div className="mt-auto flex w-full">
<footer
className={cn(
"z-40 w-full bg-neutral-100 text-neutral-700 dark:bg-primary dark:text-white",
className,
)}
>
<footer className={cn("z-40 w-full", className)}>
<div className="mx-auto max-w-5xl px-2 py-2 sm:px-6 lg:px-8">
<div className="text-center">
<Link

View file

@ -4,7 +4,7 @@ import { ASvg } from "~/components/svgs";
export const LoadingPage = () => {
return (
<div className="flex h-full max-h-full w-full animate-pulse items-center justify-center py-20">
<div className="relative flex size-40 animate-spin items-center justify-center rounded-full border-8 border-gray-300 border-t-red-400 text-4xl text-red-400"></div>
<div className="relative flex size-40 animate-spin items-center justify-center rounded-full border-8 border-muted-foreground border-t-red-400 text-4xl text-red-400"></div>
<ASvg className="-translate-y-2 absolute size-24" />
</div>
);

View file

@ -3,11 +3,7 @@ import { LogoSvg } from "~/components/svgs";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
type MainNavProps = {
pathname: string;
};
export function MainNav({ pathname }: MainNavProps) {
export function MainNav() {
const { t } = useTranslation();
return (
@ -17,17 +13,14 @@ export function MainNav({ pathname }: MainNavProps) {
className="flex shrink-0 items-center font-medium md:mb-0"
href="/"
>
<LogoSvg className="h-8 w-auto [&>g]:fill-red-500 [&>text]:fill-primary [&>text]:stroke-primary" />
<LogoSvg className="h-8 w-auto" />
</Link>
<nav className="flex items-center gap-4 text-lg tracking-wide lg:gap-6">
{t.nav.mainNav.map((item) => (
<Link
aria-label={item.title}
className={cn(
"transition-colors hover:text-primary/80",
pathname === item.href ? "text-primary" : "text-primary/70",
)}
className={cn("hover:text-primary")}
href={item.href}
key={item.href}
>

View file

@ -20,6 +20,7 @@ import { useMediaQuery } from "~/hooks/use-media-query";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
import { ThemeSwitch } from "./theme-toggle";
type MobileNavProps = {
pathname: string;
@ -85,7 +86,7 @@ export function MobileNav({
</>
)}
<div className="flex h-full grow flex-col gap-3 text-primary">
<div className="flex h-full grow flex-col gap-3">
{t.nav.mainNav.map((item) => (
<MobileLink
className={cn(
@ -117,7 +118,7 @@ export function MobileNav({
<div className="flex items-center justify-center gap-6">
<LangToggle />
{/* <ThemeSwitch /> */}
<ThemeSwitch />
</div>
</div>
</div>
@ -132,7 +133,7 @@ export function MobileNav({
{verySmallScreen ? (
<ASvg className="h-8 w-auto" />
) : (
<LogoSvg className="h-6 xs:h-8 w-auto text-neutral-700 sm:h-10 [&>g]:fill-red-500 dark:[&>g]:fill-neutral-100 [&>text]:fill-primary [&>text]:stroke-primary dark:[&>text]:fill-neutral-100 dark:[&>text]:stroke-neutral-100" />
<LogoSvg className="h-6 xs:h-8 w-auto sm:h-10" />
)}
</Link>
</>
@ -189,7 +190,7 @@ const AreaRiservataLinks = ({
}: AreaRiservataLinksProps) => {
const { t } = useTranslation();
return (
<div className="flex flex-col space-y-4 text-base text-primary">
<div className="flex flex-col space-y-4 text-base">
{isAdmin
? t.nav.areaRiservataAdminNav.map((item) => {
if (item.items !== undefined) {
@ -276,7 +277,7 @@ export const ARMinimizableLinks = ({
return (
<div
className={cn(
"flex w-full flex-col items-start gap-4 text-base text-primary",
"flex w-full flex-col items-start gap-4 text-base",
minimized && "justify-center",
)}
>
@ -308,9 +309,9 @@ export const ARMinimizableLinks = ({
return (
<MobileLink
className={cn(
`mx-4 block w-full border-l px-6 py-2 duration-150 hover:border-neutral-800 hover:text-accent-foreground`,
`mx-4 block w-full rounded-r-md border-l px-6 py-2 duration-150 hover:border-neutral-800 hover:bg-muted hover:text-accent-foreground`,
item.href === pathname &&
"border-neutral-900 text-neutral-900",
"border-muted-foreground",
minimized && "hidden",
)}
disabled={minimized}
@ -329,7 +330,7 @@ export const ARMinimizableLinks = ({
return (
<MobileLink
className={cn(
"flex h-8 items-center gap-3 rounded-lg px-2 py-1 font-medium",
"flex h-8 w-full items-center gap-3 rounded-lg px-2 py-1 font-medium hover:bg-muted",
item.href === pathname && "bg-muted",
)}
disabled={minimized}

View file

@ -37,7 +37,8 @@ export function RicercaCommand() {
</DialogHeader>
<div className="relative mx-auto flex w-full gap-2">
<CodiceBox
className="rounded-none rounded-t-md outline outline-foreground placeholder:text-center focus:border-none focus:outline-hidden focus:ring-foreground"
className="rounded-none rounded-t-md border-none outline-0 outline-foreground ring-1 ring-foreground placeholder:text-center focus:ring-foreground"
containerClassName="rounded-t-md rounded-b-none"
inputId="command-search"
key={"codiceBox"}
optionBoxClassName="rounded-none rounded-b-md mt-0 border-b-0 border-x-0"

View file

@ -7,6 +7,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { ThemeSwitch } from "./theme-toggle";
export const SettingsPopover = () => {
return (
@ -18,7 +19,7 @@ export const SettingsPopover = () => {
</PopoverTrigger>
<PopoverContent className="flex w-fit justify-center gap-4 p-4">
<LangToggle />
{/* <ThemeSwitch /> */}
<ThemeSwitch />
</PopoverContent>
</Popover>
);

View file

@ -21,9 +21,9 @@ export function SiteHeader() {
setOpenSidebar(status);
};
return (
<header className="sticky top-0 z-50 w-full border-border/40 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<header className="sticky top-0 z-50 w-full border-muted border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="mx-auto flex h-14 w-full items-center pr-3 pl-4 md:pr-4 md:pl-8">
<MainNav pathname={pathname} />
<MainNav />
<MobileNav
open={openSidebar}
pathname={pathname}

View file

@ -16,7 +16,7 @@ export const ThemeSwitch = () => {
<button
aria-label="Toggle Theme"
className={cn(
`flex h-10 w-20 rounded-full bg-neutral-200 p-[5px] shadow-inner hover:cursor-pointer dark:bg-neutral-700`,
`flex h-10 w-20 rounded-full bg-muted p-[5px] shadow-inner hover:cursor-pointer`,
theme === "light" && "place-content-end",
)}
onClick={() => setTheme(theme === "light" ? "dark" : "light")}

View file

@ -35,18 +35,18 @@ export const PricingChoice = () => {
}));
return (
<div className="flex flex-col items-center justify-center gap-4 text-primary">
<div className="flex flex-col items-center justify-center gap-4">
<h2 className="font-semibold text-3xl">Scegli il tuo servizio</h2>
<Tabs className="mb-2 w-full max-w-xl" defaultValue="transitorio">
<TabsList className="flex h-auto w-full items-center justify-between gap-1 p-1">
<TabsTrigger
className="w-full cursor-pointer bg-transitorio px-2 text-xl sm:px-3 [&[data-state=active]]:bg-transitorio"
className="w-full cursor-pointer border-0 bg-transitorio px-2 text-xl sm:px-3 dark:border-0 dark:text-fxd-foreground [&[data-state=active]]:border-0 [&[data-state=active]]:bg-transitorio dark:[&[data-state=active]]:border-0 dark:[&[data-state=active]]:bg-transitorio dark:[&[data-state=active]]:text-fxd-foreground"
value="transitorio"
>
Transitorio
</TabsTrigger>
<TabsTrigger
className="w-full cursor-pointer bg-stabile px-2 text-xl sm:px-3 [&[data-state=active]]:bg-stabile"
className="w-full cursor-pointer border-0 bg-stabile px-2 text-xl sm:px-3 dark:border-0 dark:text-fxd-foreground [&[data-state=active]]:border-0 [&[data-state=active]]:bg-stabile dark:[&[data-state=active]]:border-0 dark:[&[data-state=active]]:bg-stabile dark:[&[data-state=active]]:text-fxd-foreground"
value="stabile"
>
Stabile
@ -54,7 +54,7 @@ export const PricingChoice = () => {
</TabsList>
<TabsContent className="w-full" value="transitorio">
<PricingComponent
className="border-transitorio bg-transitorio"
className="border-transitorio bg-transitorio text-fxd-foreground"
cta={t.pricing_cmp.cta_breve}
opzioni={[
t.pricing_cmp.breve_option1,
@ -70,7 +70,7 @@ export const PricingChoice = () => {
</TabsContent>
<TabsContent value="stabile">
<PricingComponent
className="border-stabile bg-stabile"
className="border-stabile bg-stabile text-fxd-foreground"
cta={t.pricing_cmp.cta_stabile}
opzioni={[
t.pricing_cmp.stabile_option1,
@ -147,7 +147,7 @@ export const PricingComponent = ({
Prezzo del servizio
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col items-center justify-center gap-4 p-0 px-2 xs:px-6 py-0 sm:gap-6 sm:py-4">
<CardContent className="flex w-full flex-col items-center justify-center gap-4 p-0 px-2 xs:px-6 py-0 text-fxd-foreground sm:gap-6 sm:py-4">
<div
className="flex w-full items-center justify-center gap-0 xs:gap-x-4 xs:gap-y-1"
data-role="wrapper"

View file

@ -73,7 +73,7 @@ function SchedaAnnuncio({ data }: { data: Annunci }) {
<div className="space-y-8">
<div className="flex items-start justify-between">
<div>
<LogoSvg className="h-10 w-auto [&>g]:fill-red-500 [&>text]:fill-primary [&>text]:stroke-primary" />
<LogoSvg className="h-10 w-auto" />
</div>
<div className="relative">

View file

@ -428,13 +428,13 @@ export const LogoSvg = (props: SVGProps<SVGSVGElement>) => (
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<title>{"lloggi.it Info"}</title>
<title>{"Infolloggi.it "}</title>
<defs>
<path d="M69.953 191.276h677.665v225.16H69.953z" id="a" />
<path d="M69.953 191.276h677.665v225.16H69.953z" id="b" />
</defs>
<text
className="font-sans"
className="fill-foreground stroke-foreground font-sans"
style={{
fontSize: 40,
letterSpacing: 1,
@ -458,7 +458,7 @@ export const LogoSvg = (props: SVGProps<SVGSVGElement>) => (
</tspan>
</text>
<text
className="font-sans"
className="fill-foreground stroke-foreground font-sans"
style={{
fontSize: 40,
letterSpacing: 1,
@ -482,6 +482,7 @@ export const LogoSvg = (props: SVGProps<SVGSVGElement>) => (
</tspan>
</text>
<g
className="fill-red-500"
style={{
//fill: "#e60000",
fillOpacity: 1,

View file

@ -19,7 +19,7 @@ function Tiptap({
editorProps: {
attributes: {
class:
"prose max-w-none overflow-auto h-full w-full rounded-md border min-h-[30rem] max-h-[50rem] border-input bg-background focus:ring-offset-2 disabled:cursor-not-allows disabled:opacity-50 p-2",
"prose [&_*]:text-foreground max-w-none overflow-auto h-full w-full text-foreground rounded-md border min-h-[30rem] max-h-[50rem] border-input bg-background focus:ring-offset-2 disabled:cursor-not-allows disabled:opacity-50 p-2",
},
},
extensions: [

View file

@ -29,7 +29,7 @@ const buttonVariants = cva(
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
grey: "bg-accent/30 text-accent-foreground shadow-sm hover:bg-accent/80 dark:bg-muted dark:text-muted-foreground dark:hover:bg-muted dark:hover:text-white",
info: "bg-sky-500 text-white hover:bg-sky-500/90 dark:bg-sky-900 dark:text-white dark:hover:bg-sky-900/90",
info: "bg-info text-white hover:bg-info/90 dark:text-white ",
link: "text-primary underline-offset-4 hover:underline active:underline",
orange:
@ -38,8 +38,7 @@ const buttonVariants = cva(
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
success:
"bg-green-500 text-white hover:bg-green-500/90 dark:bg-green-900 dark:text-white dark:hover:bg-green-900/90",
success: "bg-success text-white hover:bg-success/90 dark:text-white",
warning:
"bg-yellow-500 text-white hover:bg-yellow-500/90 dark:bg-yellow-900 dark:text-white dark:hover:bg-yellow-900/90",
},

View file

@ -175,6 +175,8 @@ function Calendar({
);
const _hiddenClassName = cn("invisible flex-1", props.hiddenClassName);
const _dropdownOverrideClassName = cn("rounded-md p-2 shadow-xs bg-card");
return (
<DayPicker
className={cn("p-3", className)}
@ -191,7 +193,7 @@ function Calendar({
month_caption: _monthCaptionClassName,
month_grid: _monthGridClassName,
months: _monthsClassName,
months_dropdown: "dropdown-override",
months_dropdown: _dropdownOverrideClassName,
nav: _navClassName,
outside: _outsideClassName,
range_end: _rangeEndClassName,
@ -202,9 +204,13 @@ function Calendar({
week: _weekClassName,
weekday: _weekdayClassName,
weekdays: _weekdaysClassName,
years_dropdown: "dropdown-override",
years_dropdown: _dropdownOverrideClassName,
}}
components={{
// Dropdown: (props) => (
// <Dropdown className={_dropdownOverrideClassName} {...props} />
// ),
CaptionLabel: (props) => (
<CaptionLabel
displayYears={displayYears}

View file

@ -22,6 +22,7 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
import { NumberInput } from "~/components/custom_ui/InputNumber";
import Input from "~/components/custom_ui/input";
import { DualInputLayout } from "~/components/custom_ui/inputLayouts";
import {
@ -1011,20 +1012,18 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithImages }) => {
</div>
<FormControl>
<Input
placeholder=""
step="0.01"
type="number"
<NumberInput
suffix=" €"
{...field}
decimalScale={2}
decimalSeparator=","
fixedDecimalScale
id="prezzo"
onChange={(e) =>
e.target.value === ""
? field.onChange(null)
: field.onChange(
parseFloat(e.target.value) * 100,
)
}
value={field.value / 100 || undefined}
min={0}
onValueChange={(v) => {
field.onChange((v || 0) * 100);
}}
value={Number(field.value) / 100}
/>
</FormControl>
</FormItem>
@ -1050,7 +1049,8 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithImages }) => {
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="disponibile_da"
variant={"outline"}

View file

@ -146,7 +146,7 @@ export const FormEditServizio = ({
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="decorrenza"
variant={"outline"}

View file

@ -491,7 +491,7 @@ export const FormNewServizio = ({
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="scadenza_motivazione_transitoria"
variant={"outline"}

View file

@ -810,8 +810,8 @@ export const FormNewServizioAcquisto = ({
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
)}
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="scadenza_motivazione_transitoria"
variant={"outline"}
>
@ -1010,8 +1010,8 @@ export const FormNewServizioAcquisto = ({
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
)}
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="dataNascita"
variant={"outline"}
>

View file

@ -8,6 +8,7 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
import { NumberInput } from "~/components/custom_ui/InputNumber";
import Input from "~/components/custom_ui/input";
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
import { Textarea } from "~/components/custom_ui/textarea";
@ -134,333 +135,351 @@ export const FormPrezzo = ({
className="space-y-4 px-0.5"
onSubmit={form.handleSubmit(onSubmit)}
>
<FormField
control={form.control}
name="idprezziario"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="idprezziario">Codice</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
placeholder=""
{...field}
disabled={initialValues != null}
id="idprezziario"
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="nome_it"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="nome_it">Nome IT</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input placeholder="" {...field} id="nome_it" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="desc_it"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="desc_it"
>
Descrizione IT
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Textarea className="min-h-[150px]" {...field} id="desc_it" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="nome_en"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="nome_en">Nome EN</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input placeholder="" {...field} id="nome_en" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="desc_en"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="desc_en"
>
Descrizione EN
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Textarea className="min-h-[150px]" {...field} id="desc_en" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="prezzo_cent"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="prezzo">Prezzo</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="prezzo"
onChange={(v) => {
field.onChange(parseFloat(v.target.value) * 100);
}}
step={0.01}
type="number"
value={Number(field.value) / 100}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isAcconto"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isAcconto">Acconto</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isAcconto"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isSaldo"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isSaldo">Saldo</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isSaldo"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isConsulenza"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isConsulenza">Consulenza</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isConsulenza"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isTransitorio"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isTransitorio">Transitorio</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isTransitorio"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isStabile"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isStabile">Stabile</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isStabile"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<div className="flex flex-col gap-4 md:flex-row">
<div className="flex w-full flex-col gap-4 md:w-2/3">
<FormField
control={form.control}
name="idprezziario"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="idprezziario">Codice</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
placeholder=""
{...field}
disabled={initialValues != null}
id="idprezziario"
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="nome_it"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="nome_it">Nome IT</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input placeholder="" {...field} id="nome_it" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="desc_it"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="desc_it"
>
Descrizione IT
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Textarea
className="min-h-[150px]"
{...field}
id="desc_it"
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="nome_en"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="nome_en">Nome EN</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input placeholder="" {...field} id="nome_en" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="desc_en"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="desc_en"
>
Descrizione EN
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Textarea
className="min-h-[150px]"
{...field}
id="desc_en"
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="testo_condizioni"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="select-testo-condizioni"
>
ID Testo Condizioni
</FormLabel>
<FormMessage />
</div>
<FormField
control={form.control}
name="testo_condizioni"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel
className="font-medium text-base"
htmlFor="select-testo-condizioni"
>
ID Testo Condizioni
</FormLabel>
<FormMessage />
</div>
<MultiSelect
defaultValue={
field.value
? { label: field.value, value: field.value }
: {
label: "",
value: "",
}
}
elementId="select-testo-condizioni"
elementName="testo_condizioni"
isMulti={false}
onValueChange={async (value) => {
if (value.value === "") {
field.onChange(undefined);
} else {
field.onChange(
stringhe_condizioni_options[
Number.parseInt(value.value)
],
);
}
await form.trigger("testo_condizioni");
}}
options={UnpackOptions({
options: stringhe_condizioni_options,
})}
placeholder="Seleziona..."
/>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isActive"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isActive">Attivo</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isActive"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="sconto"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="sconto">Sconto</FormLabel>
<FormControl>
<Select
defaultValue={String(field.value)}
name="sconto"
onValueChange={(value) => {
field.onChange(Number.parseInt(value));
}}
>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Sconto" />
</SelectTrigger>
<SelectContent>
{[
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65,
70, 75, 80, 85, 90, 95, 100,
].map((v) => {
return (
<SelectItem key={v} value={String(v)}>
{v}%
</SelectItem>
<MultiSelect
defaultValue={
field.value
? { label: field.value, value: field.value }
: {
label: "",
value: "",
}
}
elementId="select-testo-condizioni"
elementName="testo_condizioni"
isMulti={false}
onValueChange={async (value) => {
if (value.value === "") {
field.onChange(undefined);
} else {
field.onChange(
stringhe_condizioni_options[
Number.parseInt(value.value)
],
);
})}
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
{scontoWch && scontoWch[0] !== 0 && (
<span className="text-gray-500 text-sm">
Prezzo scontato:{" "}
{(((1 - scontoWch[0] / 100) * scontoWch[1]) / 100).toFixed(2)}
</span>
)}
}
await form.trigger("testo_condizioni");
}}
options={UnpackOptions({
options: stringhe_condizioni_options,
})}
placeholder="Seleziona..."
/>
</FormItem>
)}
/>
</div>
<div className="flex w-full flex-col gap-4 md:w-1/3">
<FormField
control={form.control}
name="isAcconto"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isAcconto">Acconto</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isAcconto"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isSaldo"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isSaldo">Saldo</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isSaldo"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isConsulenza"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isConsulenza">Consulenza</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isConsulenza"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isTransitorio"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isTransitorio">Transitorio</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isTransitorio"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isStabile"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isStabile">Stabile</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isStabile"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isActive"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isActive">Attivo</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="isActive"
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="prezzo_cent"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="prezzo">Prezzo</FormLabel>
<FormMessage />
</div>
<FormControl>
<NumberInput
suffix=" €"
{...field}
decimalScale={2}
decimalSeparator=","
fixedDecimalScale
id="prezzo"
min={0}
onValueChange={(v) => {
field.onChange((v || 0) * 100);
}}
value={Number(field.value) / 100}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="sconto"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="sconto">Sconto</FormLabel>
<FormControl>
<Select
defaultValue={String(field.value)}
name="sconto"
onValueChange={(value) => {
field.onChange(Number.parseInt(value));
}}
>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Sconto" />
</SelectTrigger>
<SelectContent>
{[
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60,
65, 70, 75, 80, 85, 90, 95, 100,
].map((v) => {
return (
<SelectItem key={v} value={String(v)}>
{v}%
</SelectItem>
);
})}
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
{scontoWch && scontoWch[0] !== 0 && (
<span className="text-gray-500 text-sm">
Prezzo scontato:{" "}
{(((1 - scontoWch[0] / 100) * scontoWch[1]) / 100).toFixed(2)}
</span>
)}
</div>
</div>
<div className="flex flex-row gap-4">
<Button type="submit">
{initialValues ? "Aggiorna" : "Crea Prezzo"}

View file

@ -254,7 +254,7 @@ export const ProfileFormAnagrafica = ({
className={cn(
"h-[42px] w-full pl-3 text-left font-medium",
!field.value && "text-muted-foreground",
`rounded-lg border border-neutral-300 bg-white text-primary shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:bg-primary dark:text-white dark:aria-expanded:border-neutral-400 dark:focus:border-transparent dark:hover:border-neutral-400 dark:placeholder:text-neutral-400`,
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
)}
id="data_nascita"
variant={"outline"}

View file

@ -378,7 +378,7 @@ export const it: LangDict = {
camere2: "camere",
codice: "Codice",
consegna_da: "Da ",
consegna_subito: "Da Subito",
consegna_subito: "Subito",
in_aggiornamento: "In aggiornamento",
indirizzo: "Indirizzo",
prezzo: "Prezzo",

View file

@ -2,7 +2,7 @@ import type { LangDict } from "~/i18n/locales";
export const handleConsegna = ({
consegna,
consegna_da,
consegna_da: _consegna_da,
mesi,
subito,
aggiornamento,
@ -16,7 +16,7 @@ export const handleConsegna = ({
const currentMonth = new Date().getMonth() + 1;
if (consegna !== null) {
if (consegna !== currentMonth) {
return `${consegna_da} ${mesi[consegna]}`;
return `${mesi[consegna]}`;
}
return subito;
}

View file

@ -46,7 +46,7 @@ const MyApp = ({
<SessionProvider>
<ThemeProvider
attribute="class"
defaultTheme="light"
defaultTheme="dark"
disableTransitionOnChange
enableSystem
>

View file

@ -3,7 +3,7 @@ import { inter } from "~/utils/fonts";
export default function Document() {
return (
<Html className={`${inter.variable} font-sans`}>
<Html className={`${inter.variable} scrollbar-default font-sans`}>
<Head>
<link
href="/favicon/apple-touch-icon.png"

View file

@ -70,10 +70,10 @@ const Annunci = ({ options }: AnnunciPageProps) => {
<meta content={t.heads.annunci_description} name="description" />
</Head>
<main className="relative mx-auto w-full max-w-9xl space-y-5 bg-background2 px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<main className="relative mx-auto w-full max-w-10xl space-y-5 bg-background2 px-2 py-5 md:px-8">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.annunci.titolo}
</div>
</Badge>
<GoBackButton />
@ -242,7 +242,7 @@ const Filters = () => {
const RicercaSideFilters = () => {
return (
<div className="hidden h-fit w-46 max-w-46 shrink-0 grow-0 flex-col gap-3 overflow-clip rounded-md bg-white p-2 outline-neutral-300 2xl:flex">
<div className="hidden h-fit w-46 max-w-46 shrink-0 grow-0 flex-col gap-3 overflow-clip rounded-md bg-secondary p-2 outline-neutral-300 2xl:flex">
<Filters />
</div>
);
@ -296,7 +296,7 @@ const RicercaHeader = () => {
const { map, setMap } = useRicerca();
return (
<div className="mx-auto w-full max-w-9xl space-y-5">
<div className="mx-auto w-full max-w-10xl space-y-5">
<div className="flex w-full flex-col-reverse gap-4 sm:flex-row sm:gap-2">
<div className="flex w-full gap-2 sm:w-auto">
<DrowdownFilters />
@ -424,11 +424,11 @@ const AnnunciList = () => {
if (status === "error") return <Status500 />;
return (
<div className="space-y-4">
<div className="w-full space-y-4">
{status === "pending" ? (
<LoadingPage />
) : (
<div className="relative z-0 mx-auto grid max-w-8xl grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:w-7xl 2xl:grid-cols-4">
<div className="relative z-0 mx-auto grid w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4">
{data.annunci.map((annuncio, idx) => (
<LazyCardAnnuncio
key={annuncio.codice}
@ -551,7 +551,7 @@ export const SelectFilter = <T extends string>({
onValueChange={onValueChange}
value={value}
>
<SelectTrigger className="w-full">
<SelectTrigger className="w-full bg-primary-foreground text-primary">
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent>

View file

@ -11,6 +11,7 @@ import {
Printer,
Ruler,
Share2,
TrafficCone,
} from "lucide-react";
import type { GetStaticPaths, GetStaticPropsContext, NextPage } from "next";
import Head from "next/head";
@ -408,7 +409,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
const { t } = useTranslation();
return (
<Card className="relative w-full">
<Card className="relative w-full bg-secondary text-secondary-foreground outline outline-secondary-foreground">
<CardHeader>
<CardTitle className="text-center font-bold text-3xl md:pl-8 lg:pl-0">
Codice {data.codice}
@ -417,7 +418,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<CardContent className="flex flex-col gap-4 p-4 py-0">
<div className="grid grid-cols-2 gap-3 font-semibold">
<div className="relative">
<div className="rounded-md bg-neutral-100 p-2 text-center">
<div className="rounded-md bg-primary-foreground p-2 text-center text-primary">
{data.prezzo && (data.prezzo / 1e2).toFixed(2).replace(".", ",")}{" "}
/mese
</div>
@ -426,11 +427,11 @@ const CardInfos = ({ data }: { data: Annunci }) => {
icon="euro"
iconClassName="h-[19.5px] w-[19.5px] bg-orange-500 text-white rounded-full"
>
<div>
<span className="font-semibold text-primary text-sm">
<div className="text-fxd-foreground">
<span className="font-semibold text-sm">
Prezzo al giorno
</span>
<div className="text-muted-foreground text-sm">
<div className="text-sm">
{(data.prezzo / 1e2 / 30).toFixed(2).replace(".", ",")} /gg
</div>
</div>
@ -440,7 +441,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<div className="relative">
<div
className={cn(
"rounded-md bg-neutral-100 p-2 text-center outline-2",
"rounded-md bg-primary-foreground p-2 text-center text-primary outline-2",
data.tipo === "Transitorio" && "outline-transitorio",
data.tipo === "Stabile" && "outline-stabile",
)}
@ -459,7 +460,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<div className="flex flex-col gap-2">
<h3 className="px-2">Fornitura:</h3>
<div className="grid grid-cols-2 gap-3">
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<BedDouble />
{(() => {
if (!data.numero_camere) return "N/A";
@ -469,15 +470,15 @@ const CardInfos = ({ data }: { data: Annunci }) => {
return `${data.numero_camere} ${t.card.camere1}`;
})()}
</div>
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<Bath />
<span>{data.numero_bagni} bagni</span>
</div>
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<Armchair />
{data.caratteristiche?.Scheda_Arredi || ""}
</div>
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<Car />
<span>{data.numero_postiauto} posti auto</span>
</div>
@ -486,14 +487,14 @@ const CardInfos = ({ data }: { data: Annunci }) => {
<div className="flex flex-col gap-2">
<h3 className="px-2">Dati immobile:</h3>
<div className="grid grid-cols-2 gap-3">
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<Ruler />
<span>
{data.mq} m<sup>2</sup>
</span>
</div>
<div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
<Building2 />
<span>
{(() => {
@ -506,24 +507,15 @@ const CardInfos = ({ data }: { data: Annunci }) => {
</div>
</div>
</div>
<div className="text-center font-bold text-base text-neutral-700">
<div className="text-center font-bold text-base">
{data.stato === "Trattativa" ? (
"Annuncio in aggiornamento"
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 text-trattativa outline-2 outline-trattativa dark:bg-secondary-foreground">
<TrafficCone className="inline-block size-5" />
<span>Annuncio in aggiornamento</span>
</div>
) : (
// <span className="flex items-center justify-center gap-1">
// <Clock className="inline-block size-5" />
// Disponibilità:{" "}
// <span className="text-red-500">
// {handleConsegna({
// consegna: data.consegna,
// consegna_da: t.card.consegna_da,
// mesi: t.preferenze.mesi,
// subito: t.card.consegna_subito,
// aggiornamento: t.card.in_aggiornamento,
// })}
// </span>
// </span>
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 outline-2 outline-neutral-500">
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 outline-2 outline-secondary-foreground">
<Clock className="inline-block size-5" />
Disponibilità:{" "}
<span className="text-red-500">
@ -588,7 +580,7 @@ const ShareComponent = () => {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">
<Button>
<Share2 className="size-5" />
</Button>
</DialogTrigger>
@ -666,7 +658,7 @@ const AnnuncioFooter = ({
}}
target="_blank"
>
<Button className="my-10 w-full bg-neutral-500 text-xl">
<Button className="my-10 w-full text-xl" variant="info">
Cerca annunci simili <ExternalLink className="size-6" />
</Button>
</Link>

View file

@ -170,7 +170,7 @@ const EditPrezzoModal = ({
return (
<Dialog onOpenChange={setOpen} open={open}>
<DialogContent className="sm:max-w-2xl">
<DialogContent className="sm:max-w-5xl md:max-w-8xl">
<DialogHeader>
<DialogTitle>Modifica Servizio</DialogTitle>
<DialogDescription className="sr-only">

View file

@ -151,7 +151,7 @@ const EditModal = ({
return (
<Dialog onOpenChange={setOpen} open={open}>
<DialogTrigger asChild />
<DialogContent className="sm:max-w-6xl">
<DialogContent className="sm:max-w-8xl">
<DialogHeader>
<DialogTitle>
{!initial ? "Aggiungi Banner" : "Modifica Valori"}

View file

@ -1,6 +1,7 @@
import type { NextPage } from "next";
import Head from "next/head";
import Image from "next/image";
import { Badge } from "~/components/ui/badge";
import { useTranslation } from "~/providers/I18nProvider";
const ChiSiamo: NextPage = () => {
@ -12,9 +13,9 @@ const ChiSiamo: NextPage = () => {
<meta content={t.heads.main_description} name="description" />
</Head>
<main className="mx-auto w-full max-w-8xl space-y-5 px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.chi_siamo.title}
</div>
</Badge>
<div className="mx-auto w-full max-w-6xl space-y-5 sm:space-y-14">
<section className="relative mx-auto flex max-w-6xl flex-col items-center justify-between gap-8 px-4 py-4 sm:flex-row sm:gap-20 md:px-8">
<div className="mx-auto mt-5 flex-1 sm:w-9/12 md:mt-0 md:w-auto">

View file

@ -16,6 +16,8 @@ import Input from "~/components/custom_ui/input";
import { DualInputLayout } from "~/components/custom_ui/inputLayouts";
import { Textarea } from "~/components/custom_ui/textarea";
import { PhoneInput } from "~/components/phone-input";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { Checkbox } from "~/components/ui/checkbox";
import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
@ -68,11 +70,11 @@ const Contatto: NextPage = () => {
<meta content={t.heads.main_description} name="description" />
</Head>
<main className="mx-auto w-full max-w-8xl px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.contatti}
</div>
</Badge>
<div className="mx-auto max-w-screen-xl px-4 text-neutral-600 md:px-8">
<div className="mx-auto max-w-screen-xl px-4 md:px-8">
<div className="mx-auto max-w-lg space-y-3 sm:text-center">
<p className="font-semibold text-4xl text-accent-foreground">
{t.contact_form.titolo}
@ -208,12 +210,9 @@ const Contatto: NextPage = () => {
</FormItem>
)}
/>
<button
className="w-full rounded-lg bg-neutral-600 px-4 py-2 font-medium text-white duration-150 hover:bg-neutral-500 active:bg-neutral-600"
type="submit"
>
<Button className="w-full" type="submit">
{t.contact_form.invia}
</button>
</Button>
</form>
</Form>
)}
@ -235,14 +234,10 @@ const ContactSuccess = () => {
<h3 className="font-semibold text-4xl text-accent-foreground sm:text-5xl">
{t.contact_form.successo}
</h3>
<p className="text-neutral-600">{t.contact_form.inviata}</p>
<p className="text-muted-foreground">{t.contact_form.inviata}</p>
<div className="flex flex-wrap items-center justify-center gap-3">
<Link
aria-label={t.contact_form.cta}
className="block rounded-lg border px-4 py-2 font-medium text-neutral-700 duration-150 hover:bg-neutral-50 active:bg-neutral-100"
href="/"
>
{t.contact_form.cta}
<Link aria-label={t.contact_form.cta} href="/">
<Button>{t.contact_form.cta}</Button>
</Link>
</div>
</div>

View file

@ -7,6 +7,7 @@ import {
AccordionItem,
AccordionTrigger,
} from "~/components/ui/accordion";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { useTranslation } from "~/providers/I18nProvider";
@ -20,9 +21,9 @@ const Guida: NextPage = () => {
<meta content={t.heads.main_description} name="description" />
</Head>
<main className="mx-auto w-full max-w-8xl px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.guida}
</div>
</Badge>
<ComeFunziona />
<FAQSection />
@ -49,7 +50,7 @@ const FAQSection = () => {
return (
<section className="px-4 py-12 md:px-6" id="faq">
<div className="mx-auto grid max-w-5xl items-center gap-6 py-12">
<div className="flex flex-col justify-center space-y-4 text-center">
<div className="flex flex-col justify-center space-y-4">
<div className="space-y-2">
<h2 className="font-bold text-3xl tracking-tighter md:text-4xl">
{t.faq.titolo}
@ -76,7 +77,7 @@ const FAQSection = () => {
<div className="flex w-full flex-col gap-5">
{t.faq.domande.map((item) => (
<Accordion
className="relative w-full rounded-lg bg-neutral-50 p-4"
className="relative w-full rounded-lg bg-muted p-4"
collapsible
key={item.id}
//defaultValue="0"

View file

@ -71,21 +71,21 @@ const TrovaCasaCTA = (props: { testi: LangDict }) => {
<div className="z-10 flex flex-col justify-center text-center sm:p-6 lg:max-w-lg">
<h1 className="font-bold text-[2.5rem] leading-none sm:text-6xl min-[26rem]:text-5xl">
{testi.index.titolo_1}
<span className="text-red-500"> {testi.index.titolo_2}</span>{" "}
<span className="text-destructive"> {testi.index.titolo_2}</span>{" "}
{testi.index.titolo_3}
</h1>
<LogoSvg className="h-[3rem] w-auto sm:h-[4rem] md:h-[5rem] [&>g]:fill-red-500 [&>text]:fill-primary [&>text]:stroke-primary" />
<LogoSvg className="h-[3rem] w-auto sm:h-[4rem] md:h-[5rem]" />
<br />
<div className="flex flex-col space-y-4 lg:justify-start">
<Link
className="flex h-14 items-center justify-center gap-2 rounded-md bg-red-500 px-8 py-3 font-semibold text-lg text-white"
className="flex h-14 items-center justify-center gap-2 rounded-md bg-destructive px-8 py-3 font-semibold text-lg text-white"
href="/annunci"
>
{testi.index.CTA_Annunci} <Telescope className="ml-2 size-6" />
</Link>
<div className="relative mx-auto flex w-full items-center justify-center gap-2 p-1 [&:has(#searchOptionsBox)]:[&_#animationDiv]:invisible">
<div className="relative mx-auto flex w-full items-center justify-center gap-2 py-1 [&:has(#searchOptionsBox)]:[&_#animationDiv]:invisible">
<CodiceBox
className="rounded-md placeholder:text-center"
inputId="index-search"
@ -107,16 +107,16 @@ const TrovaCasaCTA = (props: { testi: LangDict }) => {
const FrequentSearches = () => {
const { locale } = useTranslation();
return (
<Card className="mx-auto mb-4 max-w-4xl gap-4 border-0 shadow-none">
<Card className="mx-auto mb-4 max-w-4xl gap-4 border-0 bg-secondary shadow-none">
<CardHeader>
<CardTitle className="text-center font-bold text-3xl text-primary sm:text-2xl">
<CardTitle className="text-center font-bold text-3xl sm:text-2xl">
{locale === "en" ? "Frequent Searches" : "Ricerche frequenti"}
</CardTitle>
</CardHeader>
<CardContent className="mx-auto flex max-w-fit flex-wrap items-center justify-center gap-4 px-2 sm:px-6">
<Link href="/annunci?tipo=Transitorio">
<Button
className="flex items-center gap-1 border-2 border-white bg-transitorio text-black text-lg"
className="flex items-center gap-1 border-2 border-transitorio bg-transitorio text-black text-lg"
size="lg"
variant="flat"
>
@ -126,7 +126,7 @@ const FrequentSearches = () => {
</Link>
<Link href="/annunci?tipo=Stabile">
<Button
className="flex items-center gap-1 border-2 border-white border-whiteborder-2 bg-stabile text-black text-lg"
className="flex items-center gap-1 border-2 border-stabile bg-stabile text-black text-lg"
size="lg"
variant="flat"
>
@ -136,7 +136,7 @@ const FrequentSearches = () => {
</Link>
<Link href="/annunci?comune=Bassano+del+Grappa">
<Button
className="flex items-center gap-1 border-2 border-white text-lg"
className="flex items-center gap-1 border-2 border-primary text-lg"
size="lg"
>
Bassano del Grappa
@ -146,7 +146,7 @@ const FrequentSearches = () => {
<Link href="/annunci?comune=Bassano+del+Grappa&tipo=Transitorio">
<Button
className="flex items-center gap-1 border-2 border-white bg-transitorio text-black text-lg"
className="flex items-center gap-1 border-2 border-transitorio bg-transitorio text-black text-lg"
size="lg"
variant="flat"
>
@ -157,7 +157,7 @@ const FrequentSearches = () => {
<Link href="/annunci?comune=Marostica">
<Button
className="flex items-center gap-1 border-2 border-white text-lg"
className="flex items-center gap-1 border-2 border-primary text-lg"
size="lg"
>
Marostica

View file

@ -8,6 +8,7 @@ import {
PricingComponentConsulenza,
} from "~/components/prezzi";
import { Status500 } from "~/components/status-page";
import { Badge } from "~/components/ui/badge";
import { Separator } from "~/components/ui/separator";
import { useTranslation } from "~/providers/I18nProvider";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
@ -44,9 +45,9 @@ const Prezzi: NextPage = () => {
<meta content={t.heads.prezzi_description} name="description" />
</Head>
<section className="mx-auto max-w-8xl px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.prezzi_titolo}
</div>
</Badge>
<div className="mt-5 space-y-14">
<section
className="mx-auto flex max-w-5xl flex-col items-center gap-8"
@ -76,11 +77,11 @@ const Prezzi: NextPage = () => {
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{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">
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-transitorio/10 text-transitorio">
<IconMatrix type={item.icon} />
</div>
<div>
<h4 className="font-semibold text-gray-800 text-lg">
<h4 className="font-semibold text-[color-mix(in_oklch,var(--transitorio)80%,black)] text-lg dark:text-transitorio">
{item.titolo}
</h4>
<p className="mt-3">{item.desc}</p>
@ -121,11 +122,11 @@ const Prezzi: NextPage = () => {
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{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">
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-stabile/10 text-stabile">
<IconMatrix type={item.icon} />
</div>
<div>
<h4 className="font-semibold text-gray-800 text-lg">
<h4 className="font-semibold text-[color-mix(in_oklch,var(--stabile)80%,black)] text-lg dark:text-stabile">
{item.titolo}
</h4>
<p className="mt-3">{item.desc}</p>
@ -150,7 +151,7 @@ const Prezzi: NextPage = () => {
</h1>
<PricingComponentConsulenza
className="border-green-400 bg-green-400"
className="border-consulenza bg-consulenza"
cta={t.pricing_cmp.cta_consulenza}
opzioni={[
"Libero (4 + 4 anni)",
@ -168,11 +169,11 @@ const Prezzi: NextPage = () => {
<ul className="grid gap-x-12 gap-y-8 sm:grid-cols-2 lg:grid-cols-2">
{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">
<div className="flex size-12 flex-none items-center justify-center rounded-lg bg-consulenza/10 text-consulenza">
<IconMatrix type={item.icon} />
</div>
<div>
<h4 className="font-semibold text-gray-800 text-lg">
<h4 className="font-semibold text-[color-mix(in_oklch,var(--consulenza)80%,black)] text-lg dark:text-consulenza">
{item.titolo}
</h4>
<p className="mt-3">{item.desc}</p>

View file

@ -4,6 +4,8 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { AccordionComp } from "~/components/accordionComp";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { Card, CardContent } from "~/components/ui/card";
import { useTranslation } from "~/providers/I18nProvider";
@ -17,27 +19,24 @@ const Proprietari: NextPage = () => {
<meta content={t.proprietari.description} name="description" />
</Head>
<main className="mx-auto w-full max-w-8xl space-y-5 px-2 py-5 md:px-8">
<div className="inline-block rounded-md bg-accent px-3 py-1 text-primary text-sm outline outline-neutral-500">
<Badge className="bg-muted py-1 text-muted-foreground text-sm outline outline-muted-foreground">
{t.proprietari.titolo}
</div>
</Badge>
<div className="mx-auto w-full space-y-5 sm:space-y-14">
<section className="relative mx-auto flex max-w-6xl flex-col-reverse items-center justify-between gap-8 px-4 py-4 sm:flex-row sm:gap-20 md:px-8">
<div className="max-w-lg flex-1 py-5 sm:mx-auto sm:text-center md:max-w-max md:text-left">
<h3 className="font-semibold text-3xl text-gray-800 md:text-4xl">
<h3 className="font-semibold text-3xl md:text-4xl">
{t.proprietari.cta1.title1}{" "}
<span className="text-indigo-600">
<span className="text-red-500">
{t.proprietari.cta1.title2}
</span>
</h3>
<p className="mt-3 text-gray-500 leading-relaxed">
{t.proprietari.cta1.desc}
</p>
<Link
className="mt-5 inline-flex items-center rounded-full bg-indigo-50 px-4 py-2 font-medium text-indigo-600"
href="/contatti"
>
{t.proprietari.contattaci}
<ArrowRight className="ml-1 h-5 w-5 duration-150" />
<p className="mt-3 leading-relaxed">{t.proprietari.cta1.desc}</p>
<Link href="/contatti">
<Button className="mt-5">
{t.proprietari.contattaci}
<ArrowRight className="ml-1 h-5 w-5 duration-150" />
</Button>
</Link>
</div>
<div className="mx-auto mt-5 flex-1 sm:w-9/12 md:mt-0 md:w-auto">
@ -71,22 +70,19 @@ const Proprietari: NextPage = () => {
/>
</div>
<div className="max-w-lg flex-1 py-5 sm:mx-auto sm:text-center md:max-w-max md:text-left">
<h3 className="font-semibold text-3xl text-gray-800 md:text-4xl">
<h3 className="font-semibold text-3xl md:text-4xl">
{t.proprietari.cta2.title1}{" "}
<span className="text-indigo-600">
<span className="text-red-500">
{t.proprietari.cta2.title2}
</span>
{t.proprietari.cta2.title3}
</h3>
<p className="mt-3 text-gray-500 leading-relaxed">
{t.proprietari.cta2.desc}
</p>
<Link
className="mt-5 inline-flex items-center rounded-full bg-indigo-50 px-4 py-2 font-medium text-indigo-600"
href="/contatti"
>
{t.proprietari.contattaci}
<ArrowRight className="ml-1 h-5 w-5 duration-150" />
<p className="mt-3 leading-relaxed">{t.proprietari.cta2.desc}</p>
<Link href="/contatti">
<Button className="mt-5">
{t.proprietari.contattaci}
<ArrowRight className="ml-1 h-5 w-5 duration-150" />
</Button>
</Link>
</div>
</section>

View file

@ -1,16 +1,20 @@
import type { NextPage } from "next";
import Example from "~/components/KabanExample";
import { NoSSR } from "~/lib/nossr";
import dynamic from "next/dynamic";
import { LoadingPage } from "~/components/loading";
import type { NextPageWithLayout } from "./_app";
const Test: NextPage = () => {
const Kaban = dynamic(() => import("~/components/KabanExample"), {
loading: () => <LoadingPage />,
ssr: false,
});
const Test: NextPageWithLayout = () => {
return (
<div className="p-4">
<NoSSR>
<Example />
</NoSSR>
</div>
<main className="flex flex-col gap-4 p-8">
<Kaban />
</main>
);
};
export default Test;
/*

View file

@ -76,8 +76,17 @@
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--color-transitorio: var(--color-sky-500);
--color-stabile: var(--color-orange-500);
--color-transitorio: var(--transitorio);
--color-stabile: var(--stabile);
--color-consulenza: var(--consulenza);
--color-dasubito: var(--dasubito);
--color-evidenza: var(--evidenza);
--color-trattativa: var(--trattativa);
--color-info: var(--info);
--color-success: var(--success);
--color-fxd-foreground: var(--fxd-foreground);
--color-fxd-secondary: var(--fxd-secondary);
--accordion-down: accordion-down 0.2s ease-out;
--accordion-up: accordion-up 0.2s ease-out;
@ -160,9 +169,120 @@
}
:root {
--background: oklch(0.98 0 0);
--foreground: oklch(0.24 0 0);
--card: oklch(0.99 0 0);
--card-foreground: oklch(0.24 0 0);
--popover: oklch(0.99 0 0);
--popover-foreground: oklch(0.24 0 0);
--primary: oklch(0.43 0.04 42.00);
--primary-foreground: oklch(1.00 0 0);
--secondary: oklch(0.92 0.07 76.67);
--secondary-foreground: oklch(0.35 0.07 41.41);
--muted: oklch(0.95 0 0);
--muted-foreground: oklch(0.50 0 0);
--accent: oklch(0.93 0 0);
--accent-foreground: oklch(0.24 0 0);
--destructive: oklch(61.229% 0.20547 28.742);
--border: oklch(0.88 0 0);
--input: oklch(0.88 0 0);
--ring: oklch(0.43 0.04 42.00);
--chart-1: oklch(0.43 0.04 42.00);
--chart-2: oklch(0.92 0.07 76.67);
--chart-3: oklch(0.93 0 0);
--chart-4: oklch(0.94 0.05 75.02);
--chart-5: oklch(0.43 0.04 42.00);
--sidebar: oklch(0.99 0 0);
--sidebar-foreground: oklch(0.26 0 0);
--sidebar-primary: oklch(0.33 0 0);
--sidebar-primary-foreground: oklch(0.99 0 0);
--sidebar-accent: oklch(0.98 0 0);
--sidebar-accent-foreground: oklch(0.33 0 0);
--sidebar-border: oklch(0.94 0 0);
--sidebar-ring: oklch(0.77 0 0);
--stabile: oklch(0.63 0.19 33.26);
--transitorio: oklch(59.784% 0.09034 248.137);
--consulenza: oklch(56.144% 0.13916 147.417);
--dasubito: oklch(60.733% 0.12323 151.794);
--evidenza: oklch(89.076% 0.1829 96.164);
--trattativa: oklch(54.164% 0.19878 27.041);
--info: oklch(62.956% 0.12519 239.161);
--success: oklch(62.7% 0.194 149.214);
--fxd-foreground: oklch(0.24 0 0);
--fxd-secondary: oklch(0.92 0.07 76.67);
--radius: 0.5rem;
--shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
--shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
--shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
--shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
--shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10);
--shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10);
--shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10);
--shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25);
}
.dark {
--background: oklch(0.18 0 0);
--foreground: oklch(0.95 0 0);
--card: oklch(0.21 0 0);
--card-foreground: oklch(0.95 0 0);
--popover: oklch(0.21 0 0);
--popover-foreground: oklch(0.95 0 0);
--primary: oklch(0.92 0.05 67.14);
--primary-foreground: oklch(0.20 0.02 201.14);
--secondary: oklch(0.32 0.02 67.00);
--secondary-foreground: oklch(0.92 0.05 67.14);
--muted: oklch(0.25 0 0);
--muted-foreground: oklch(0.77 0 0);
--accent: oklch(0.29 0 0);
--accent-foreground: oklch(0.95 0 0);
--destructive: oklch(61.197% 0.22381 29.492);
--border: oklch(0.24 0.01 88.77);
--input: oklch(0.40 0 0);
--ring: oklch(0.92 0.05 67.14);
--chart-1: oklch(0.92 0.05 67.14);
--chart-2: oklch(0.32 0.02 67.00);
--chart-3: oklch(0.29 0 0);
--chart-4: oklch(0.35 0.02 67.11);
--chart-5: oklch(0.92 0.05 67.14);
--sidebar: oklch(0.21 0.01 285.56);
--sidebar-foreground: oklch(0.97 0 0);
--sidebar-primary: oklch(0.49 0.22 264.43);
--sidebar-primary-foreground: oklch(1.00 0 0);
--sidebar-accent: oklch(0.27 0.01 285.81);
--sidebar-accent-foreground: oklch(0.97 0 0);
--sidebar-border: oklch(0.27 0.01 285.81);
--sidebar-ring: oklch(0.87 0.01 286.27);
--info: oklch(50.208% 0.11698 241.771);
--success: oklch(0.46 0.12 142.21);
--fxd-foreground: oklch(0.24 0 0);
--fxd-secondary: oklch(0.92 0.07 76.67);
--shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
--shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
--shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
--shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
--shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10);
--shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10);
--shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10);
--shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25);
}
/*
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--background2: oklch(80.395% 0.06402 83.429);
--backgroundbkp: oklch(1 0 0);
--background: oklch(70.716% 0.07403 219.01);
--background2bkp: oklch(91.587% 0.08721 83.88);
--background2: oklch(70.716% 0.07403 219.01);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
@ -227,7 +347,7 @@
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
}*/
@layer base {
html {
@ -284,7 +404,7 @@
}
@utility scrollbar-default {
@apply scrollbar-thin scrollbar-track-muted scrollbar-thumb-neutral-300 scrollbar-track-rounded-full scrollbar-thumb-rounded-full;
@apply scrollbar-thin scrollbar-track-primary-foreground scrollbar-thumb-primary scrollbar-track-rounded-full scrollbar-thumb-rounded-full;
}
@utility ph-input-fix {