Refactor date input components across forms to use DateInput instead of Popover with Calendar for improved usability and consistency
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
76718d5647
commit
20e50d5c6d
16 changed files with 124 additions and 1085 deletions
|
|
@ -39,7 +39,8 @@
|
||||||
"@radix-ui/react-tooltip",
|
"@radix-ui/react-tooltip",
|
||||||
"@radix-ui/react-popover",
|
"@radix-ui/react-popover",
|
||||||
"@radix-ui/react-toggle-group",
|
"@radix-ui/react-toggle-group",
|
||||||
"tailwindcss"
|
"tailwindcss",
|
||||||
|
"@hookform/devtools"
|
||||||
],
|
],
|
||||||
"project": [
|
"project": [
|
||||||
"src/**",
|
"src/**",
|
||||||
|
|
|
||||||
40
apps/infoalloggi/package-lock.json
generated
40
apps/infoalloggi/package-lock.json
generated
|
|
@ -69,7 +69,6 @@
|
||||||
"radix-ui": "^1.4.3",
|
"radix-ui": "^1.4.3",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-colorful": "^5.6.1",
|
"react-colorful": "^5.6.1",
|
||||||
"react-day-picker": "^9.14.0",
|
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-hook-form": "^7.72.1",
|
"react-hook-form": "^7.72.1",
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
|
|
@ -594,10 +593,6 @@
|
||||||
"node": ">=20.19.0"
|
"node": ">=20.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@date-fns/tz": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@discoveryjs/json-ext": {
|
"node_modules/@discoveryjs/json-ext": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"license": "MIT",
|
"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": {
|
"node_modules/@tailwindcss/forms": {
|
||||||
"version": "0.5.11",
|
"version": "0.5.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -7701,10 +7687,6 @@
|
||||||
"url": "https://github.com/sponsors/kossnocorp"
|
"url": "https://github.com/sponsors/kossnocorp"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/date-fns-jalali": {
|
|
||||||
"version": "4.1.0-0",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/debounce": {
|
"node_modules/debounce": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
|
@ -11709,28 +11691,6 @@
|
||||||
"react-dom": ">=16.8.0"
|
"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": {
|
"node_modules/react-dom": {
|
||||||
"version": "19.2.3",
|
"version": "19.2.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@
|
||||||
"radix-ui": "^1.4.3",
|
"radix-ui": "^1.4.3",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-colorful": "^5.6.1",
|
"react-colorful": "^5.6.1",
|
||||||
"react-day-picker": "^9.14.0",
|
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-hook-form": "^7.72.1",
|
"react-hook-form": "^7.72.1",
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
|
|
|
||||||
27
apps/infoalloggi/src/components/custom_ui/inputDate.tsx
Normal file
27
apps/infoalloggi/src/components/custom_ui/inputDate.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import type React from "react";
|
||||||
|
import Input from "~/components/ui/input";
|
||||||
|
|
||||||
|
interface DateInputProps
|
||||||
|
extends Omit<
|
||||||
|
React.InputHTMLAttributes<HTMLInputElement>,
|
||||||
|
"type" | "value" | "onChange"
|
||||||
|
> {
|
||||||
|
value: Date | null;
|
||||||
|
onChange: (date: Date | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DateInput = ({ value, onChange, ...rest }: DateInputProps) => {
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
{...rest}
|
||||||
|
onChange={(e) => {
|
||||||
|
const date = new Date(e.currentTarget.value);
|
||||||
|
if (!Number.isNaN(date.getTime())) {
|
||||||
|
onChange(date);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
type="date"
|
||||||
|
value={value?.toISOString().split("T")[0] || ""}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { it } from "date-fns/locale";
|
import { Check, SlidersHorizontal } from "lucide-react"
|
||||||
import { CalendarIcon, Check, SlidersHorizontal } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
@ -23,10 +22,10 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
|
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
|
||||||
import { Badge } from "~/components/ui/badge";
|
import { Badge } from "~/components/ui/badge";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
|
|
@ -36,11 +35,6 @@ import {
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "~/components/ui/dialog";
|
} from "~/components/ui/dialog";
|
||||||
import { Label } from "~/components/ui/label";
|
import { Label } from "~/components/ui/label";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { Slider } from "~/components/ui/slider";
|
import { Slider } from "~/components/ui/slider";
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
import { FieldResetButton } from "~/forms/comps";
|
import { FieldResetButton } from "~/forms/comps";
|
||||||
|
|
@ -526,42 +520,12 @@ const FormServizio = ({
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="scadenza_motivazione_transitoria"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value || new Date()}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
)}
|
)}
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
es. scadenza contratto di lavoro, fine corso di studi, ecc.
|
es. scadenza contratto di lavoro, fine corso di studi, ecc.
|
||||||
|
|
|
||||||
|
|
@ -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<NavView>("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 (
|
|
||||||
<DayPicker
|
|
||||||
className={cn("p-3", className)}
|
|
||||||
classNames={{
|
|
||||||
button_next: _buttonNextClassName,
|
|
||||||
button_previous: _buttonPreviousClassName,
|
|
||||||
caption: _captionClassName,
|
|
||||||
caption_label: _captionLabelClassName,
|
|
||||||
day: _dayClassName,
|
|
||||||
day_button: _dayButtonClassName,
|
|
||||||
disabled: _disabledClassName,
|
|
||||||
hidden: _hiddenClassName,
|
|
||||||
month: _monthClassName,
|
|
||||||
month_caption: _monthCaptionClassName,
|
|
||||||
month_grid: _monthGridClassName,
|
|
||||||
months: _monthsClassName,
|
|
||||||
months_dropdown: _dropdownOverrideClassName,
|
|
||||||
nav: _navClassName,
|
|
||||||
outside: _outsideClassName,
|
|
||||||
range_end: _rangeEndClassName,
|
|
||||||
range_middle: _rangeMiddleClassName,
|
|
||||||
range_start: _rangeStartClassName,
|
|
||||||
selected: _selectedClassName,
|
|
||||||
today: _todayClassName,
|
|
||||||
week: _weekClassName,
|
|
||||||
weekday: _weekdayClassName,
|
|
||||||
weekdays: _weekdaysClassName,
|
|
||||||
years_dropdown: _dropdownOverrideClassName,
|
|
||||||
}}
|
|
||||||
components={{
|
|
||||||
// Dropdown: (props) => (
|
|
||||||
// <Dropdown className={_dropdownOverrideClassName} {...props} />
|
|
||||||
// ),
|
|
||||||
|
|
||||||
CaptionLabel: (props) => (
|
|
||||||
<CaptionLabel
|
|
||||||
displayYears={displayYears}
|
|
||||||
navView={navView}
|
|
||||||
setNavView={setNavView}
|
|
||||||
showYearSwitcher={showYearSwitcher}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
Chevron: ({ orientation }) => {
|
|
||||||
const Icon = orientation === "left" ? ChevronLeft : ChevronRight;
|
|
||||||
return <Icon className="size-4" />;
|
|
||||||
},
|
|
||||||
MonthGrid: ({ className, children, ...props }) => (
|
|
||||||
<MonthGrid
|
|
||||||
className={className}
|
|
||||||
displayYears={displayYears}
|
|
||||||
endMonth={endMonth}
|
|
||||||
navView={navView}
|
|
||||||
setNavView={setNavView}
|
|
||||||
startMonth={startMonth}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</MonthGrid>
|
|
||||||
),
|
|
||||||
Nav: ({ className }) => (
|
|
||||||
<Nav
|
|
||||||
className={className}
|
|
||||||
displayYears={displayYears}
|
|
||||||
endMonth={endMonth}
|
|
||||||
navView={navView}
|
|
||||||
onPrevClick={onPrevClick}
|
|
||||||
setDisplayYears={setDisplayYears}
|
|
||||||
startMonth={startMonth}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
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<SetStateAction<{ from: number; to: number }>>;
|
|
||||||
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 (
|
|
||||||
<nav className={cn("flex items-center", className)}>
|
|
||||||
<Button
|
|
||||||
aria-label={
|
|
||||||
navView === "years"
|
|
||||||
? `Go to the previous ${
|
|
||||||
displayYears.to - displayYears.from + 1
|
|
||||||
} years`
|
|
||||||
: labelPrevious(previousMonth)
|
|
||||||
}
|
|
||||||
className="absolute left-0 size-7 bg-transparent p-0 opacity-80 hover:opacity-100"
|
|
||||||
disabled={isPreviousDisabled}
|
|
||||||
onClick={handlePreviousClick}
|
|
||||||
tabIndex={isPreviousDisabled ? undefined : -1}
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<ChevronLeft className="size-4" />
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
aria-label={
|
|
||||||
navView === "years"
|
|
||||||
? `Go to the next ${displayYears.to - displayYears.from + 1} years`
|
|
||||||
: labelNext(nextMonth)
|
|
||||||
}
|
|
||||||
className="absolute right-0 size-7 bg-transparent p-0 opacity-80 hover:opacity-100"
|
|
||||||
disabled={isNextDisabled}
|
|
||||||
onClick={handleNextClick}
|
|
||||||
tabIndex={isNextDisabled ? undefined : -1}
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<ChevronRight className="size-4" />
|
|
||||||
</Button>
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function CaptionLabel({
|
|
||||||
children,
|
|
||||||
showYearSwitcher,
|
|
||||||
navView,
|
|
||||||
setNavView,
|
|
||||||
displayYears,
|
|
||||||
...props
|
|
||||||
}: {
|
|
||||||
showYearSwitcher?: boolean;
|
|
||||||
navView: NavView;
|
|
||||||
setNavView: Dispatch<SetStateAction<NavView>>;
|
|
||||||
displayYears: { from: number; to: number };
|
|
||||||
} & HTMLAttributes<HTMLSpanElement>) {
|
|
||||||
if (!showYearSwitcher) return <span {...props}>{children}</span>;
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
className="h-7 w-full truncate font-medium text-sm"
|
|
||||||
onClick={() => setNavView((prev) => (prev === "days" ? "years" : "days"))}
|
|
||||||
size="sm"
|
|
||||||
variant="ghost"
|
|
||||||
>
|
|
||||||
{navView === "days"
|
|
||||||
? children
|
|
||||||
: `${displayYears.from} - ${displayYears.to}`}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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<SetStateAction<NavView>>;
|
|
||||||
} & TableHTMLAttributes<HTMLTableElement>) {
|
|
||||||
if (navView === "years") {
|
|
||||||
return (
|
|
||||||
<YearGrid
|
|
||||||
className={className}
|
|
||||||
displayYears={displayYears}
|
|
||||||
endMonth={endMonth}
|
|
||||||
navView={navView}
|
|
||||||
setNavView={setNavView}
|
|
||||||
startMonth={startMonth}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<table className={className} {...props}>
|
|
||||||
{children}
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function YearGrid({
|
|
||||||
className,
|
|
||||||
displayYears,
|
|
||||||
startMonth,
|
|
||||||
endMonth,
|
|
||||||
setNavView,
|
|
||||||
navView,
|
|
||||||
...props
|
|
||||||
}: {
|
|
||||||
className?: string;
|
|
||||||
displayYears: { from: number; to: number };
|
|
||||||
startMonth?: Date;
|
|
||||||
endMonth?: Date;
|
|
||||||
setNavView: Dispatch<SetStateAction<NavView>>;
|
|
||||||
navView: NavView;
|
|
||||||
} & HTMLAttributes<HTMLDivElement>) {
|
|
||||||
const { goToMonth, selected } = useDayPicker();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={cn("grid grid-cols-4 gap-y-2", className)} {...props}>
|
|
||||||
{Array.from(
|
|
||||||
{ length: displayYears.to - displayYears.from + 1 },
|
|
||||||
(_, i) => {
|
|
||||||
const isBefore =
|
|
||||||
differenceInCalendarDays(
|
|
||||||
new Date(displayYears.from + i, 11, 31),
|
|
||||||
// biome-ignore lint/style/noNonNullAssertion: <exists>
|
|
||||||
startMonth!,
|
|
||||||
) < 0;
|
|
||||||
|
|
||||||
const isAfter =
|
|
||||||
differenceInCalendarDays(
|
|
||||||
new Date(displayYears.from + i, 0, 0),
|
|
||||||
// biome-ignore lint/style/noNonNullAssertion: <exists>
|
|
||||||
endMonth!,
|
|
||||||
) > 0;
|
|
||||||
|
|
||||||
const isDisabled = isBefore || isAfter;
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-7 w-full font-normal text-foreground text-sm",
|
|
||||||
displayYears.from + i === new Date().getFullYear() &&
|
|
||||||
"bg-accent font-medium text-accent-foreground",
|
|
||||||
)}
|
|
||||||
disabled={navView === "years" ? isDisabled : undefined}
|
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: <index is acceptable here>
|
|
||||||
key={i}
|
|
||||||
onClick={() => {
|
|
||||||
setNavView("days");
|
|
||||||
goToMonth(
|
|
||||||
new Date(
|
|
||||||
displayYears.from + i,
|
|
||||||
(selected as Date | undefined)?.getMonth() ?? 0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
variant="ghost"
|
|
||||||
>
|
|
||||||
{displayYears.from + i}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Calendar };
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
import { format } from "date-fns";
|
|
||||||
import { it } from "date-fns/locale";
|
|
||||||
import {
|
import {
|
||||||
CalendarIcon,
|
|
||||||
CodeSquare,
|
CodeSquare,
|
||||||
Eye,
|
Eye,
|
||||||
Printer,
|
Printer,
|
||||||
|
|
@ -24,13 +21,13 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
import { NumberInput } from "~/components/custom_ui/InputNumber";
|
import { NumberInput } from "~/components/custom_ui/InputNumber";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { DualInputLayout } from "~/components/custom_ui/inputLayouts";
|
import { DualInputLayout } from "~/components/custom_ui/inputLayouts";
|
||||||
import {
|
import {
|
||||||
type ListOption,
|
type ListOption,
|
||||||
MultiSelect,
|
MultiSelect,
|
||||||
} from "~/components/custom_ui/multiselect";
|
} from "~/components/custom_ui/multiselect";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import { PhoneInput } from "~/components/ui/phone-input";
|
import { PhoneInput } from "~/components/ui/phone-input";
|
||||||
|
|
@ -55,7 +52,6 @@ import { FieldResetButton } from "~/forms/comps";
|
||||||
import { filteredCaratteristiche } from "~/hooks/schedaAnnuncioUtils";
|
import { filteredCaratteristiche } from "~/hooks/schedaAnnuncioUtils";
|
||||||
import { NullableStringOnChange } from "~/lib/form_utils";
|
import { NullableStringOnChange } from "~/lib/form_utils";
|
||||||
import { getStorageUrl } from "~/lib/storage_utils";
|
import { getStorageUrl } from "~/lib/storage_utils";
|
||||||
import { cn } from "~/lib/utils";
|
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]";
|
import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
|
|
@ -1178,42 +1174,12 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithMedia }) => {
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="disponibile_da"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder="Seleziona data"
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>Scegli</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || undefined}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { format } from "date-fns";
|
import { Trash2 } from "lucide-react";
|
||||||
import { it } from "date-fns/locale";
|
|
||||||
import { CalendarIcon, Trash2 } from "lucide-react";
|
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
import { Confirm } from "~/components/confirm";
|
import { Confirm } from "~/components/confirm";
|
||||||
|
|
@ -18,14 +16,9 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
|
|
@ -35,7 +28,7 @@ import {
|
||||||
} from "~/components/ui/select";
|
} from "~/components/ui/select";
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
import { PAYMENT_TYPES, type PaymentType } from "~/i18n/stripe";
|
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 { useZodForm } from "~/lib/zodForm";
|
||||||
import { orderTypeEnum } from "~/schemas/public/OrderTypeEnum";
|
import { orderTypeEnum } from "~/schemas/public/OrderTypeEnum";
|
||||||
import type { Ordini } from "~/schemas/public/Ordini";
|
import type { Ordini } from "~/schemas/public/Ordini";
|
||||||
|
|
@ -212,42 +205,12 @@ export const FormEditOrder = ({ prezziario, data, close }: FormProps) => {
|
||||||
<FormLabel htmlFor="created_at">Data Ordine</FormLabel>
|
<FormLabel htmlFor="created_at">Data Ordine</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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="created_at"
|
id="created_at"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder="Seleziona data"
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>Scegli data</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { it } from "date-fns/locale";
|
import { it } from "date-fns/locale";
|
||||||
import { ChevronDownIcon } from "lucide-react";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Confirm } from "~/components/confirm";
|
import { Confirm } from "~/components/confirm";
|
||||||
import {
|
import {
|
||||||
|
|
@ -11,14 +10,9 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { Textarea } from "~/components/ui/textarea";
|
import { Textarea } from "~/components/ui/textarea";
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
|
|
@ -77,34 +71,12 @@ export const FormEditQueueMail = ({
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
className="w-full justify-between bg-card font-normal"
|
|
||||||
id="date-picker-optional"
|
id="date-picker-optional"
|
||||||
variant="outline"
|
onChange={field.onChange}
|
||||||
>
|
placeholder="Seleziona data"
|
||||||
{field.value
|
value={field.value}
|
||||||
? format(field.value, "PPP", { locale: it })
|
|
||||||
: "Seleziona data"}
|
|
||||||
<ChevronDownIcon />
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent
|
|
||||||
align="start"
|
|
||||||
className="w-auto overflow-hidden p-0"
|
|
||||||
>
|
|
||||||
<Calendar
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value}
|
|
||||||
mode="single"
|
|
||||||
onSelect={(date) => {
|
|
||||||
field.onChange(date);
|
|
||||||
}}
|
|
||||||
selected={field.value}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { format } from "date-fns";
|
import { X } from "lucide-react";
|
||||||
import { enUS, it } from "date-fns/locale";
|
|
||||||
import { CalendarIcon, X } from "lucide-react";
|
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
import { Counter } from "~/components/counter";
|
import { Counter } from "~/components/counter";
|
||||||
import {
|
import {
|
||||||
|
|
@ -12,14 +10,9 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import { Label } from "~/components/ui/label";
|
import { Label } from "~/components/ui/label";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
import { cn } from "~/lib/utils";
|
import { cn } from "~/lib/utils";
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
|
|
@ -80,8 +73,6 @@ export const FormEditServizio = ({
|
||||||
defaultValues: defaultValues,
|
defaultValues: defaultValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form className="space-y-8 px-0.5" onSubmit={form.handleSubmit(onSubmit)}>
|
<form className="space-y-8 px-0.5" onSubmit={form.handleSubmit(onSubmit)}>
|
||||||
|
|
@ -168,42 +159,12 @@ export const FormEditServizio = ({
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="decorrenza"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: DatePickerLocale,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={DatePickerLocale}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { format, isAfter } from "date-fns";
|
import { format, isAfter } from "date-fns";
|
||||||
import { it } from "date-fns/locale";
|
|
||||||
import { ChevronDownIcon } from "lucide-react";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useFormContext, useWatch } from "react-hook-form";
|
import { useFormContext, useWatch } from "react-hook-form";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
@ -12,15 +10,10 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import {
|
import {
|
||||||
type MailsTemplates,
|
type MailsTemplates,
|
||||||
|
|
@ -137,34 +130,12 @@ export const FormAddCodaEmail = ({ submitMutation }: FormProps) => {
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
className="w-full justify-between bg-card font-normal"
|
|
||||||
id="date-picker-optional"
|
id="date-picker-optional"
|
||||||
variant="outline"
|
onChange={field.onChange}
|
||||||
>
|
placeholder="Seleziona data"
|
||||||
{field.value
|
value={field.value}
|
||||||
? format(field.value, "PPP", { locale: it })
|
|
||||||
: "Seleziona data"}
|
|
||||||
<ChevronDownIcon />
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent
|
|
||||||
align="start"
|
|
||||||
className="w-auto overflow-hidden p-0"
|
|
||||||
>
|
|
||||||
<Calendar
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value}
|
|
||||||
mode="single"
|
|
||||||
onSelect={(date) => {
|
|
||||||
field.onChange(date);
|
|
||||||
}}
|
|
||||||
selected={field.value}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
import { format } from "date-fns";
|
|
||||||
import { it } from "date-fns/locale";
|
|
||||||
import { CalendarIcon } from "lucide-react";
|
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
import {
|
import {
|
||||||
|
|
@ -17,14 +14,9 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
|
|
@ -34,7 +26,7 @@ import {
|
||||||
} from "~/components/ui/select";
|
} from "~/components/ui/select";
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
import { PAYMENT_TYPES } from "~/i18n/stripe";
|
import { PAYMENT_TYPES } from "~/i18n/stripe";
|
||||||
import { cn, formatCurrency } from "~/lib/utils";
|
import { formatCurrency } from "~/lib/utils";
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import { orderTypeEnum } from "~/schemas/public/OrderTypeEnum";
|
import { orderTypeEnum } from "~/schemas/public/OrderTypeEnum";
|
||||||
import { paymentStatusEnum } from "~/schemas/public/PaymentStatusEnum";
|
import { paymentStatusEnum } from "~/schemas/public/PaymentStatusEnum";
|
||||||
|
|
@ -195,42 +187,12 @@ export const FormNewOrder = ({
|
||||||
<FormLabel htmlFor="created_at">Data Ordine</FormLabel>
|
<FormLabel htmlFor="created_at">Data Ordine</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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="created_at"
|
id="created_at"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder="Seleziona data"
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>Scegli data</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { differenceInYears, format } from "date-fns";
|
import { differenceInYears } from "date-fns";
|
||||||
import { enUS, it } from "date-fns/locale";
|
|
||||||
import { CalendarIcon } from "lucide-react";
|
|
||||||
import { type Control, useWatch } from "react-hook-form";
|
import { type Control, useWatch } from "react-hook-form";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
@ -12,15 +10,10 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { Separator } from "~/components/ui/separator";
|
import { Separator } from "~/components/ui/separator";
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
import {
|
import {
|
||||||
|
|
@ -33,7 +26,6 @@ import {
|
||||||
checkFiscalCodeValidity,
|
checkFiscalCodeValidity,
|
||||||
NullableStringOnChange,
|
NullableStringOnChange,
|
||||||
} from "~/lib/form_utils";
|
} from "~/lib/form_utils";
|
||||||
import { cn } from "~/lib/utils";
|
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import { useCatasto } from "~/providers/CatastoProvider";
|
import { useCatasto } from "~/providers/CatastoProvider";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
|
|
@ -135,7 +127,6 @@ export const ProfileFormAnagrafica = ({
|
||||||
admin_override: false,
|
admin_override: false,
|
||||||
};
|
};
|
||||||
const { locale, t } = useTranslation();
|
const { locale, t } = useTranslation();
|
||||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
|
||||||
z.config(z.locales[locale]());
|
z.config(z.locales[locale]());
|
||||||
|
|
||||||
const form = useZodForm(schema, {
|
const form = useZodForm(schema, {
|
||||||
|
|
@ -184,42 +175,12 @@ export const ProfileFormAnagrafica = ({
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="data_nascita"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: DatePickerLocale,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || undefined}
|
|
||||||
endMonth={new Date()}
|
|
||||||
locale={DatePickerLocale}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { add, format, formatDuration, intervalToDuration } from "date-fns";
|
import { add, formatDuration, intervalToDuration } from "date-fns";
|
||||||
import { it } from "date-fns/locale";
|
import { it } from "date-fns/locale";
|
||||||
import { CalendarIcon, Trash2 } from "lucide-react";
|
import { Trash2 } from "lucide-react";
|
||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
import { Confirm } from "~/components/confirm";
|
import { Confirm } from "~/components/confirm";
|
||||||
import {
|
import {
|
||||||
|
|
@ -11,15 +11,9 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { cn } from "~/lib/utils";
|
|
||||||
import { useZodForm } from "~/lib/zodForm";
|
import { useZodForm } from "~/lib/zodForm";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
import type { Rinnovi } from "~/schemas/public/Rinnovi";
|
import type { Rinnovi } from "~/schemas/public/Rinnovi";
|
||||||
|
|
@ -91,46 +85,16 @@ export const FormRinnovo = ({
|
||||||
<FormLabel htmlFor="decorrenza">Decorrenza</FormLabel>
|
<FormLabel htmlFor="decorrenza">Decorrenza</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
|
<DateInput
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="decorrenza"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="scadenza"
|
name="scadenza"
|
||||||
|
|
@ -140,43 +104,12 @@ export const FormRinnovo = ({
|
||||||
<FormLabel htmlFor="scadenza">Scadenza</FormLabel>
|
<FormLabel htmlFor="scadenza">Scadenza</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
|
<DateInput
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="scadenza"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { format } from "date-fns";
|
import { Check, HelpCircleIcon, Mail } from "lucide-react";
|
||||||
import { enUS, it } from "date-fns/locale";
|
|
||||||
import { CalendarIcon, Check, HelpCircleIcon, Mail } from "lucide-react";
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { type Control, useWatch } from "react-hook-form";
|
import { type Control, useWatch } from "react-hook-form";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
|
|
@ -17,10 +15,10 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "~/components/custom_ui/form";
|
} from "~/components/custom_ui/form";
|
||||||
import InputWIcon from "~/components/custom_ui/input-icon";
|
import InputWIcon from "~/components/custom_ui/input-icon";
|
||||||
|
import { DateInput } from "~/components/custom_ui/inputDate";
|
||||||
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
|
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
|
||||||
import { Badge } from "~/components/ui/badge";
|
import { Badge } from "~/components/ui/badge";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Calendar } from "~/components/ui/calendar";
|
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
|
|
@ -31,11 +29,6 @@ import {
|
||||||
import Input from "~/components/ui/input";
|
import Input from "~/components/ui/input";
|
||||||
import { Label } from "~/components/ui/label";
|
import { Label } from "~/components/ui/label";
|
||||||
import { PhoneInput } from "~/components/ui/phone-input";
|
import { PhoneInput } from "~/components/ui/phone-input";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "~/components/ui/popover";
|
|
||||||
import { Separator } from "~/components/ui/separator";
|
import { Separator } from "~/components/ui/separator";
|
||||||
import { Slider } from "~/components/ui/slider";
|
import { Slider } from "~/components/ui/slider";
|
||||||
import { Switch } from "~/components/ui/switch";
|
import { Switch } from "~/components/ui/switch";
|
||||||
|
|
@ -291,7 +284,6 @@ export const FormServizioAcquisto = ({
|
||||||
const form = useZodForm(form_schema, {
|
const form = useZodForm(form_schema, {
|
||||||
defaultValues: defaultValues,
|
defaultValues: defaultValues,
|
||||||
});
|
});
|
||||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
|
||||||
const { mutate } = api.servizio.processServizioOnboard.useMutation({
|
const { mutate } = api.servizio.processServizioOnboard.useMutation({
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error(`Errore invio dati: ${error.message}`, {
|
toast.error(`Errore invio dati: ${error.message}`, {
|
||||||
|
|
@ -734,42 +726,12 @@ export const FormServizioAcquisto = ({
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="scadenza_motivazione_transitoria"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: it,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value || new Date()}
|
|
||||||
endMonth={new Date(2050, 12)}
|
|
||||||
locale={it}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value || undefined}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -908,42 +870,12 @@ export const FormServizioAcquisto = ({
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<DateInput
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
className={cn(
|
|
||||||
"h-10 w-full bg-card pl-3 text-left font-medium",
|
|
||||||
!field.value && "text-muted-foreground",
|
|
||||||
"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"
|
id="dataNascita"
|
||||||
variant={"outline"}
|
onChange={field.onChange}
|
||||||
>
|
placeholder={t.anagrafica.scegli_data}
|
||||||
{field.value ? (
|
value={field.value}
|
||||||
format(field.value, "PPP", {
|
|
||||||
locale: DatePickerLocale,
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<span>{t.anagrafica.scegli_data}</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto size-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-auto p-0">
|
|
||||||
<Calendar
|
|
||||||
autoFocus
|
|
||||||
captionLayout="dropdown"
|
|
||||||
defaultMonth={field.value}
|
|
||||||
endMonth={new Date()}
|
|
||||||
locale={DatePickerLocale}
|
|
||||||
mode="single"
|
|
||||||
onSelect={field.onChange}
|
|
||||||
selected={field.value}
|
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ import type { ComponentProps, ReactElement, ReactNode } from "react";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
import "~/styles/globals.css";
|
import "~/styles/globals.css";
|
||||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
|
import NextNProgress from "nextjs-progressbar";
|
||||||
|
import { NuqsAdapter } from "nuqs/adapters/next/pages";
|
||||||
import { Layout } from "~/components/Layout";
|
import { Layout } from "~/components/Layout";
|
||||||
import { I18nProvider } from "~/providers/I18nProvider";
|
import { I18nProvider } from "~/providers/I18nProvider";
|
||||||
import { SessionProvider } from "~/providers/SessionProvider";
|
import { SessionProvider } from "~/providers/SessionProvider";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
import { inter } from "~/utils/fonts";
|
import { inter } from "~/utils/fonts";
|
||||||
import "react-day-picker/dist/style.css";
|
|
||||||
import NextNProgress from "nextjs-progressbar";
|
|
||||||
import { NuqsAdapter } from "nuqs/adapters/next/pages";
|
|
||||||
|
|
||||||
type ThemeProviderProps = ComponentProps<typeof NextThemesProvider>;
|
type ThemeProviderProps = ComponentProps<typeof NextThemesProvider>;
|
||||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue