diff --git a/apps/infoalloggi/knip.json b/apps/infoalloggi/knip.json
index f7a2769..cc97b90 100644
--- a/apps/infoalloggi/knip.json
+++ b/apps/infoalloggi/knip.json
@@ -39,7 +39,8 @@
"@radix-ui/react-tooltip",
"@radix-ui/react-popover",
"@radix-ui/react-toggle-group",
- "tailwindcss"
+ "tailwindcss",
+ "@hookform/devtools"
],
"project": [
"src/**",
diff --git a/apps/infoalloggi/package-lock.json b/apps/infoalloggi/package-lock.json
index e704704..0ffdc4e 100644
--- a/apps/infoalloggi/package-lock.json
+++ b/apps/infoalloggi/package-lock.json
@@ -69,7 +69,6 @@
"radix-ui": "^1.4.3",
"react": "^19.2.3",
"react-colorful": "^5.6.1",
- "react-day-picker": "^9.14.0",
"react-dom": "^19.2.3",
"react-hook-form": "^7.72.1",
"react-hot-toast": "^2.5.2",
@@ -594,10 +593,6 @@
"node": ">=20.19.0"
}
},
- "node_modules/@date-fns/tz": {
- "version": "1.4.1",
- "license": "MIT"
- },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
"license": "MIT",
@@ -5867,15 +5862,6 @@
}
}
},
- "node_modules/@tabby_ai/hijri-converter": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz",
- "integrity": "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==",
- "license": "MIT",
- "engines": {
- "node": ">=16.0.0"
- }
- },
"node_modules/@tailwindcss/forms": {
"version": "0.5.11",
"license": "MIT",
@@ -7701,10 +7687,6 @@
"url": "https://github.com/sponsors/kossnocorp"
}
},
- "node_modules/date-fns-jalali": {
- "version": "4.1.0-0",
- "license": "MIT"
- },
"node_modules/debounce": {
"version": "2.2.0",
"dev": true,
@@ -11709,28 +11691,6 @@
"react-dom": ">=16.8.0"
}
},
- "node_modules/react-day-picker": {
- "version": "9.14.0",
- "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz",
- "integrity": "sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==",
- "license": "MIT",
- "dependencies": {
- "@date-fns/tz": "^1.4.1",
- "@tabby_ai/hijri-converter": "1.0.5",
- "date-fns": "^4.1.0",
- "date-fns-jalali": "4.1.0-0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "individual",
- "url": "https://github.com/sponsors/gpbl"
- },
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
"node_modules/react-dom": {
"version": "19.2.3",
"license": "MIT",
diff --git a/apps/infoalloggi/package.json b/apps/infoalloggi/package.json
index cd09b21..6ea20a0 100644
--- a/apps/infoalloggi/package.json
+++ b/apps/infoalloggi/package.json
@@ -84,7 +84,6 @@
"radix-ui": "^1.4.3",
"react": "^19.2.3",
"react-colorful": "^5.6.1",
- "react-day-picker": "^9.14.0",
"react-dom": "^19.2.3",
"react-hook-form": "^7.72.1",
"react-hot-toast": "^2.5.2",
@@ -160,4 +159,4 @@
"axios": "^1.16.0"
}
}
-}
\ No newline at end of file
+}
diff --git a/apps/infoalloggi/src/components/custom_ui/inputDate.tsx b/apps/infoalloggi/src/components/custom_ui/inputDate.tsx
new file mode 100644
index 0000000..08abb1b
--- /dev/null
+++ b/apps/infoalloggi/src/components/custom_ui/inputDate.tsx
@@ -0,0 +1,27 @@
+import type React from "react";
+import Input from "~/components/ui/input";
+
+interface DateInputProps
+ extends Omit<
+ React.InputHTMLAttributes,
+ "type" | "value" | "onChange"
+ > {
+ value: Date | null;
+ onChange: (date: Date | null) => void;
+}
+
+export const DateInput = ({ value, onChange, ...rest }: DateInputProps) => {
+ return (
+ {
+ const date = new Date(e.currentTarget.value);
+ if (!Number.isNaN(date.getTime())) {
+ onChange(date);
+ }
+ }}
+ type="date"
+ value={value?.toISOString().split("T")[0] || ""}
+ />
+ );
+};
diff --git a/apps/infoalloggi/src/components/servizio/parametri_ricerca.tsx b/apps/infoalloggi/src/components/servizio/parametri_ricerca.tsx
index 19c294e..3c67bfe 100644
--- a/apps/infoalloggi/src/components/servizio/parametri_ricerca.tsx
+++ b/apps/infoalloggi/src/components/servizio/parametri_ricerca.tsx
@@ -1,6 +1,5 @@
import { format } from "date-fns";
-import { it } from "date-fns/locale";
-import { CalendarIcon, Check, SlidersHorizontal } from "lucide-react";
+import { Check, SlidersHorizontal } from "lucide-react"
import { useState } from "react";
import toast from "react-hot-toast";
import { z } from "zod/v4";
@@ -23,10 +22,10 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
+import { DateInput } from "~/components/custom_ui/inputDate";
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
-import { Calendar } from "~/components/ui/calendar";
import {
Dialog,
DialogContent,
@@ -36,11 +35,6 @@ import {
DialogTrigger,
} from "~/components/ui/dialog";
import { Label } from "~/components/ui/label";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "~/components/ui/popover";
import { Slider } from "~/components/ui/slider";
import { Switch } from "~/components/ui/switch";
import { FieldResetButton } from "~/forms/comps";
@@ -526,42 +520,12 @@ const FormServizio = ({
) : (
-
-
-
-
-
-
-
-
-
-
+
)}
es. scadenza contratto di lavoro, fine corso di studi, ecc.
diff --git a/apps/infoalloggi/src/components/ui/calendar.tsx b/apps/infoalloggi/src/components/ui/calendar.tsx
deleted file mode 100644
index 8520eeb..0000000
--- a/apps/infoalloggi/src/components/ui/calendar.tsx
+++ /dev/null
@@ -1,532 +0,0 @@
-"use client";
-
-import { differenceInCalendarDays } from "date-fns";
-import { ChevronLeft, ChevronRight } from "lucide-react";
-import {
- type Dispatch,
- type HTMLAttributes,
- type ReactNode,
- type SetStateAction,
- type TableHTMLAttributes,
- useCallback,
- useMemo,
- useState,
-} from "react";
-import {
- DayPicker,
- type DayPickerProps,
- labelNext,
- labelPrevious,
- useDayPicker,
-} from "react-day-picker";
-import { Button, buttonVariants } from "~/components/ui/button";
-import { cn } from "~/lib/utils";
-
-type CalendarProps = DayPickerProps & {
- /**
- * In the year view, the number of years to display at once.
- * @default 12
- */
- yearRange?: number;
-
- /**
- * Wether to show the year switcher in the caption.
- * @default true
- */
- showYearSwitcher?: boolean;
-
- monthsClassName?: string;
- monthCaptionClassName?: string;
- weekdaysClassName?: string;
- weekdayClassName?: string;
- monthClassName?: string;
- captionClassName?: string;
- captionLabelClassName?: string;
- buttonNextClassName?: string;
- buttonPreviousClassName?: string;
- navClassName?: string;
- monthGridClassName?: string;
- weekClassName?: string;
- dayClassName?: string;
- dayButtonClassName?: string;
- rangeStartClassName?: string;
- rangeEndClassName?: string;
- selectedClassName?: string;
- todayClassName?: string;
- outsideClassName?: string;
- disabledClassName?: string;
- rangeMiddleClassName?: string;
- hiddenClassName?: string;
-};
-
-type NavView = "days" | "years";
-
-/**
- * A custom calendar component built on top of react-day-picker.
- * @param props The props for the calendar.
- * @default yearRange 12
- * @returns
- */
-function Calendar({
- className,
- showOutsideDays = true,
- showYearSwitcher = true,
- yearRange = 12,
- numberOfMonths,
- ...props
-}: CalendarProps) {
- const [navView, setNavView] = useState("days");
- const [displayYears, setDisplayYears] = useState<{
- from: number;
- to: number;
- }>(
- useMemo(() => {
- const currentYear = new Date().getFullYear();
- return {
- from: currentYear - Math.floor(yearRange / 2 - 1),
- to: currentYear + Math.ceil(yearRange / 2),
- };
- }, [yearRange]),
- );
-
- const { onPrevClick, startMonth, endMonth } = props;
-
- const columnsDisplayed = navView === "years" ? 1 : numberOfMonths;
-
- const _monthsClassName = cn("relative flex", props.monthsClassName);
- const _monthCaptionClassName = cn(
- "relative mx-10 flex h-7 items-center justify-center",
- props.monthCaptionClassName,
- );
- const _weekdaysClassName = cn("flex flex-row", props.weekdaysClassName);
- const _weekdayClassName = cn(
- "w-8 text-sm font-normal text-muted-foreground",
- props.weekdayClassName,
- );
- const _monthClassName = cn("w-full", props.monthClassName);
- const _captionClassName = cn(
- "relative flex items-center justify-center pt-1",
- props.captionClassName,
- );
- const _captionLabelClassName = cn(
- "truncate text-sm font-medium",
- props.captionLabelClassName,
- props.captionLayout === "dropdown" &&
- "flex items-center text-sm font-medium border border-neutral-200 rounded-md px-2 py-1",
- );
- const buttonNavClassName = buttonVariants({
- className:
- "absolute size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
- variant: "outline",
- });
- const _buttonNextClassName = cn(
- buttonNavClassName,
- "right-0",
- props.buttonNextClassName,
- );
- const _buttonPreviousClassName = cn(
- buttonNavClassName,
- "left-0",
- props.buttonPreviousClassName,
- );
- const _navClassName = cn("flex items-start", props.navClassName);
- const _monthGridClassName = cn("mx-auto mt-4", props.monthGridClassName);
- const _weekClassName = cn("mt-2 flex w-max items-start", props.weekClassName);
- const _dayClassName = cn(
- "flex size-8 flex-1 items-center justify-center p-0 text-sm",
- props.dayClassName,
- );
- const _dayButtonClassName = cn(
- buttonVariants({ variant: "ghost" }),
- "size-8 rounded-md p-0 font-normal transition-none aria-selected:opacity-100",
- props.dayButtonClassName,
- );
- const buttonRangeClassName =
- "bg-accent [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground";
- const _rangeStartClassName = cn(
- buttonRangeClassName,
- "rounded-s-md",
- props.rangeStartClassName,
- );
- const _rangeEndClassName = cn(
- buttonRangeClassName,
- "rounded-e-md",
- props.rangeEndClassName,
- );
- const _rangeMiddleClassName = cn(
- "bg-accent !text-foreground [&>button]:bg-transparent [&>button]:!text-foreground [&>button]:hover:bg-transparent [&>button]:hover:!text-foreground",
- props.rangeMiddleClassName,
- );
- const _selectedClassName = cn(
- "[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
- props.selectedClassName,
- );
- const _todayClassName = cn(
- "[&>button]:bg-accent [&>button]:text-accent-foreground",
- props.todayClassName,
- );
- const _outsideClassName = cn(
- "text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
- props.outsideClassName,
- );
- const _disabledClassName = cn(
- "text-muted-foreground opacity-50",
- props.disabledClassName,
- );
- const _hiddenClassName = cn("invisible flex-1", props.hiddenClassName);
-
- const _dropdownOverrideClassName = cn("rounded-md p-2 shadow-xs bg-card");
-
- return (
- (
- //
- // ),
-
- CaptionLabel: (props) => (
-
- ),
- Chevron: ({ orientation }) => {
- const Icon = orientation === "left" ? ChevronLeft : ChevronRight;
- return ;
- },
- MonthGrid: ({ className, children, ...props }) => (
-
- {children}
-
- ),
- Nav: ({ className }) => (
-
- ),
- }}
- numberOfMonths={columnsDisplayed}
- showOutsideDays={showOutsideDays}
- style={{
- width: `${248.8 * (columnsDisplayed ?? 1)}px`,
- }}
- {...props}
- />
- );
-}
-Calendar.displayName = "Calendar";
-
-function Nav({
- className,
- navView,
- startMonth,
- endMonth,
- displayYears,
- setDisplayYears,
- onPrevClick,
- onNextClick,
-}: {
- className?: string;
- navView: NavView;
- startMonth?: Date;
- endMonth?: Date;
- displayYears: { from: number; to: number };
- setDisplayYears: Dispatch>;
- onPrevClick?: (date: Date) => void;
- onNextClick?: (date: Date) => void;
-}) {
- const { nextMonth, previousMonth, goToMonth } = useDayPicker();
-
- const isPreviousDisabled = (() => {
- if (navView === "years") {
- return (
- (startMonth &&
- differenceInCalendarDays(
- new Date(displayYears.from - 1, 0, 1),
- startMonth,
- ) < 0) ||
- (endMonth &&
- differenceInCalendarDays(
- new Date(displayYears.from - 1, 0, 1),
- endMonth,
- ) > 0)
- );
- }
- return !previousMonth;
- })();
-
- const isNextDisabled = (() => {
- if (navView === "years") {
- return (
- (startMonth &&
- differenceInCalendarDays(
- new Date(displayYears.to + 1, 0, 1),
- startMonth,
- ) < 0) ||
- (endMonth &&
- differenceInCalendarDays(
- new Date(displayYears.to + 1, 0, 1),
- endMonth,
- ) > 0)
- );
- }
- return !nextMonth;
- })();
-
- const handlePreviousClick = useCallback(() => {
- if (!previousMonth) return;
- if (navView === "years") {
- setDisplayYears((prev) => ({
- from: prev.from - (prev.to - prev.from + 1),
- to: prev.to - (prev.to - prev.from + 1),
- }));
- onPrevClick?.(
- new Date(
- displayYears.from - (displayYears.to - displayYears.from),
- 0,
- 1,
- ),
- );
- return;
- }
- goToMonth(previousMonth);
- onPrevClick?.(previousMonth);
- }, [previousMonth, goToMonth]);
-
- const handleNextClick = useCallback(() => {
- if (!nextMonth) return;
- if (navView === "years") {
- setDisplayYears((prev) => ({
- from: prev.from + (prev.to - prev.from + 1),
- to: prev.to + (prev.to - prev.from + 1),
- }));
- onNextClick?.(
- new Date(
- displayYears.from + (displayYears.to - displayYears.from),
- 0,
- 1,
- ),
- );
- return;
- }
- goToMonth(nextMonth);
- onNextClick?.(nextMonth);
- }, [goToMonth, nextMonth]);
- return (
-
- );
-}
-
-function CaptionLabel({
- children,
- showYearSwitcher,
- navView,
- setNavView,
- displayYears,
- ...props
-}: {
- showYearSwitcher?: boolean;
- navView: NavView;
- setNavView: Dispatch>;
- displayYears: { from: number; to: number };
-} & HTMLAttributes) {
- if (!showYearSwitcher) return {children};
- return (
-
- );
-}
-
-function MonthGrid({
- className,
- children,
- displayYears,
- startMonth,
- endMonth,
- navView,
- setNavView,
- ...props
-}: {
- className?: string;
- children: ReactNode;
- displayYears: { from: number; to: number };
- startMonth?: Date;
- endMonth?: Date;
- navView: NavView;
- setNavView: Dispatch>;
-} & TableHTMLAttributes) {
- if (navView === "years") {
- return (
-
- );
- }
- return (
-
- );
-}
-
-function YearGrid({
- className,
- displayYears,
- startMonth,
- endMonth,
- setNavView,
- navView,
- ...props
-}: {
- className?: string;
- displayYears: { from: number; to: number };
- startMonth?: Date;
- endMonth?: Date;
- setNavView: Dispatch>;
- navView: NavView;
-} & HTMLAttributes) {
- const { goToMonth, selected } = useDayPicker();
-
- return (
-
- {Array.from(
- { length: displayYears.to - displayYears.from + 1 },
- (_, i) => {
- const isBefore =
- differenceInCalendarDays(
- new Date(displayYears.from + i, 11, 31),
- // biome-ignore lint/style/noNonNullAssertion:
- startMonth!,
- ) < 0;
-
- const isAfter =
- differenceInCalendarDays(
- new Date(displayYears.from + i, 0, 0),
- // biome-ignore lint/style/noNonNullAssertion:
- endMonth!,
- ) > 0;
-
- const isDisabled = isBefore || isAfter;
- return (
-
- );
- },
- )}
-
- );
-}
-
-export { Calendar };
diff --git a/apps/infoalloggi/src/forms/FormEditAnnuncio.tsx b/apps/infoalloggi/src/forms/FormEditAnnuncio.tsx
index 89dcda1..ba590dd 100644
--- a/apps/infoalloggi/src/forms/FormEditAnnuncio.tsx
+++ b/apps/infoalloggi/src/forms/FormEditAnnuncio.tsx
@@ -1,7 +1,4 @@
-import { format } from "date-fns";
-import { it } from "date-fns/locale";
import {
- CalendarIcon,
CodeSquare,
Eye,
Printer,
@@ -24,13 +21,13 @@ import {
FormMessage,
} from "~/components/custom_ui/form";
import { NumberInput } from "~/components/custom_ui/InputNumber";
+import { DateInput } from "~/components/custom_ui/inputDate";
import { DualInputLayout } from "~/components/custom_ui/inputLayouts";
import {
type ListOption,
MultiSelect,
} from "~/components/custom_ui/multiselect";
import { Button } from "~/components/ui/button";
-import { Calendar } from "~/components/ui/calendar";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import Input from "~/components/ui/input";
import { PhoneInput } from "~/components/ui/phone-input";
@@ -55,7 +52,6 @@ import { FieldResetButton } from "~/forms/comps";
import { filteredCaratteristiche } from "~/hooks/schedaAnnuncioUtils";
import { NullableStringOnChange } from "~/lib/form_utils";
import { getStorageUrl } from "~/lib/storage_utils";
-import { cn } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]";
import { useTranslation } from "~/providers/I18nProvider";
@@ -1178,42 +1174,12 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithMedia }) => {
)}
-
-
-
-
-
-
-
-
-
-
+
)}
/>
diff --git a/apps/infoalloggi/src/forms/FormEditOrdine.tsx b/apps/infoalloggi/src/forms/FormEditOrdine.tsx
index 01e6aeb..e45926e 100644
--- a/apps/infoalloggi/src/forms/FormEditOrdine.tsx
+++ b/apps/infoalloggi/src/forms/FormEditOrdine.tsx
@@ -1,6 +1,4 @@
-import { format } from "date-fns";
-import { it } from "date-fns/locale";
-import { CalendarIcon, Trash2 } from "lucide-react";
+import { Trash2 } from "lucide-react";
import toast from "react-hot-toast";
import { z } from "zod/v4";
import { Confirm } from "~/components/confirm";
@@ -18,14 +16,9 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
+import { DateInput } from "~/components/custom_ui/inputDate";
import { MultiSelect } from "~/components/custom_ui/multiselect";
import { Button } from "~/components/ui/button";
-import { Calendar } from "~/components/ui/calendar";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "~/components/ui/popover";
import {
Select,
SelectContent,
@@ -35,7 +28,7 @@ import {
} from "~/components/ui/select";
import { Switch } from "~/components/ui/switch";
import { PAYMENT_TYPES, type PaymentType } from "~/i18n/stripe";
-import { cn, formatCurrency } from "~/lib/utils";
+import { formatCurrency } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
import { orderTypeEnum } from "~/schemas/public/OrderTypeEnum";
import type { Ordini } from "~/schemas/public/Ordini";
@@ -212,42 +205,12 @@ export const FormEditOrder = ({ prezziario, data, close }: FormProps) => {
Data Ordine
-
-
-
-
-
-
-
-
-
-
+
)}
/>
diff --git a/apps/infoalloggi/src/forms/FormEditQueueMail.tsx b/apps/infoalloggi/src/forms/FormEditQueueMail.tsx
index 8097cac..5b4ed18 100644
--- a/apps/infoalloggi/src/forms/FormEditQueueMail.tsx
+++ b/apps/infoalloggi/src/forms/FormEditQueueMail.tsx
@@ -1,6 +1,5 @@
import { format } from "date-fns";
import { it } from "date-fns/locale";
-import { ChevronDownIcon } from "lucide-react";
import { z } from "zod";
import { Confirm } from "~/components/confirm";
import {
@@ -11,14 +10,9 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
+import { DateInput } from "~/components/custom_ui/inputDate";
import { Button } from "~/components/ui/button";
-import { Calendar } from "~/components/ui/calendar";
import Input from "~/components/ui/input";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "~/components/ui/popover";
import { Textarea } from "~/components/ui/textarea";
import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
@@ -77,34 +71,12 @@ export const FormEditQueueMail = ({
-
-
-
-
-
- {
- field.onChange(date);
- }}
- selected={field.value}
- />
-
-
+
)}
diff --git a/apps/infoalloggi/src/forms/FormEditServizioAdmin.tsx b/apps/infoalloggi/src/forms/FormEditServizioAdmin.tsx
index 21d17b4..5a18c24 100644
--- a/apps/infoalloggi/src/forms/FormEditServizioAdmin.tsx
+++ b/apps/infoalloggi/src/forms/FormEditServizioAdmin.tsx
@@ -1,6 +1,4 @@
-import { format } from "date-fns";
-import { enUS, it } from "date-fns/locale";
-import { CalendarIcon, X } from "lucide-react";
+import { X } from "lucide-react";
import { z } from "zod/v4";
import { Counter } from "~/components/counter";
import {
@@ -12,14 +10,9 @@ import {
FormLabel,
FormMessage,
} from "~/components/custom_ui/form";
+import { DateInput } from "~/components/custom_ui/inputDate";
import { Button } from "~/components/ui/button";
-import { Calendar } from "~/components/ui/calendar";
import { Label } from "~/components/ui/label";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "~/components/ui/popover";
import { Switch } from "~/components/ui/switch";
import { cn } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
@@ -80,8 +73,6 @@ export const FormEditServizio = ({
defaultValues: defaultValues,
});
- const DatePickerLocale = locale === "it" ? it : enUS;
-
return (