@greatapps/common 1.1.166 → 1.1.168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/AppNavBar.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs +29 -1
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
- package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/Button.mjs.map +1 -1
- package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
- package/dist/components/ui/data-display/Badge.mjs.map +1 -1
- package/dist/components/ui/data-display/Card.mjs.map +1 -1
- package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
- package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
- package/dist/components/ui/data-display/Separator.mjs.map +1 -1
- package/dist/components/ui/data-display/Table.mjs.map +1 -1
- package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
- package/dist/components/ui/feedback/Progress.mjs.map +1 -1
- package/dist/components/ui/feedback/Toast.mjs.map +1 -1
- package/dist/components/ui/form/Calendar.mjs.map +1 -1
- package/dist/components/ui/form/Checkbox.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/Input.mjs.map +1 -1
- package/dist/components/ui/form/InputOtp.mjs.map +1 -1
- package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
- package/dist/components/ui/form/Select.mjs +1 -1
- package/dist/components/ui/form/Select.mjs.map +1 -1
- package/dist/components/ui/form/Switch.mjs.map +1 -1
- package/dist/components/ui/form/Textarea.mjs.map +1 -1
- package/dist/components/ui/overlay/Command.mjs.map +1 -1
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
- package/dist/components/ui/overlay/Popover.mjs.map +1 -1
- package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
- package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
- package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
- package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
- package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
- package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
- package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
- package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
- package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
- package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
- package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel-styles.action.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
- package/dist/modules/whitelabel/services/whitelabel-styles.service.mjs.map +1 -1
- package/dist/providers/whitelabel.provider.mjs.map +1 -1
- package/dist/utils/safeServerAction.mjs.map +1 -1
- package/dist/utils/withAction.mjs.map +1 -1
- package/package.json +90 -90
- package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
- package/src/components/account/DeleteAccountModal.tsx +130 -130
- package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
- package/src/components/layouts/AppMobileNavBar.tsx +125 -125
- package/src/components/layouts/AppNavBar.tsx +57 -57
- package/src/components/layouts/NavBar.tsx +139 -112
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +69 -69
- package/src/components/navigation/NavItemsContext.ts +20 -20
- package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
- package/src/components/pages/notifications/Notifications.tsx +160 -160
- package/src/components/ui/buttons/Button.tsx +57 -57
- package/src/components/ui/buttons/CancelButton.tsx +14 -14
- package/src/components/ui/buttons/CopyButton.tsx +54 -54
- package/src/components/ui/data-display/Accordion.tsx +81 -81
- package/src/components/ui/data-display/Badge.tsx +47 -47
- package/src/components/ui/data-display/Card.tsx +93 -93
- package/src/components/ui/data-display/Pagination.tsx +126 -126
- package/src/components/ui/data-display/ScrollArea.tsx +59 -59
- package/src/components/ui/data-display/Separator.tsx +29 -29
- package/src/components/ui/data-display/Table.tsx +117 -117
- package/src/components/ui/data-display/Tabs.tsx +67 -67
- package/src/components/ui/feedback/CircularProgress.tsx +75 -75
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -53
- package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
- package/src/components/ui/feedback/Progress.tsx +40 -40
- package/src/components/ui/feedback/Toast.tsx +101 -101
- package/src/components/ui/form/Calendar.tsx +228 -228
- package/src/components/ui/form/Checkbox.tsx +31 -31
- package/src/components/ui/form/DatePicker.tsx +97 -97
- package/src/components/ui/form/DateRangePicker.tsx +108 -108
- package/src/components/ui/form/Input.tsx +20 -20
- package/src/components/ui/form/InputOtp.tsx +80 -80
- package/src/components/ui/form/RadioGroup.tsx +45 -45
- package/src/components/ui/form/Select.tsx +200 -200
- package/src/components/ui/form/Switch.tsx +32 -32
- package/src/components/ui/form/Textarea.tsx +19 -19
- package/src/components/ui/overlay/Command.tsx +185 -185
- package/src/components/ui/overlay/Dialog.tsx +151 -151
- package/src/components/ui/overlay/Popover.tsx +49 -49
- package/src/components/ui/overlay/Sheet.tsx +159 -159
- package/src/components/ui/overlay/Tooltip.tsx +62 -62
- package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
- package/src/index.ts +348 -348
- package/src/middleware.ts +4 -4
- package/src/modules/accounts/actions/account-management.action.ts +90 -90
- package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
- package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
- package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
- package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
- package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
- package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
- package/src/modules/accounts/hooks/useTimezones.ts +15 -15
- package/src/modules/accounts/types.ts +214 -214
- package/src/modules/auth/hooks/login.hook.tsx +13 -13
- package/src/modules/auth/hooks/logout.hook.tsx +11 -11
- package/src/modules/auth/hooks/register.hook.tsx +11 -11
- package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
- package/src/modules/projects/actions/add-project-user.action.ts +9 -9
- package/src/modules/projects/actions/list-available-users.action.ts +9 -9
- package/src/modules/projects/actions/list-project-users.action.ts +9 -9
- package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
- package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
- package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
- package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
- package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
- package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +17 -17
- package/src/modules/users/action/find-user-by-id.action.ts +8 -8
- package/src/modules/users/action/list-messages.action.ts +12 -12
- package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
- package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
- package/src/modules/users/hooks/messages.hook.ts +60 -60
- package/src/modules/whitelabel/actions/find-whitelabel-styles.action.ts +14 -14
- package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
- package/src/modules/whitelabel/services/whitelabel-styles.service.ts +98 -98
- package/src/modules/whitelabel/styles-schema.ts +37 -37
- package/src/providers/whitelabel.provider.tsx +46 -46
- package/src/utils/safeServerAction.ts +21 -21
- package/src/utils/withAction.ts +13 -13
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
5
|
-
import { CheckIcon } from "lucide-react";
|
|
6
|
-
import { cn } from "../../../infra/utils/clsx";
|
|
7
|
-
|
|
8
|
-
function Checkbox({
|
|
9
|
-
className,
|
|
10
|
-
...props
|
|
11
|
-
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
|
|
12
|
-
return (
|
|
13
|
-
<CheckboxPrimitive.Root
|
|
14
|
-
data-slot="checkbox"
|
|
15
|
-
className={cn(
|
|
16
|
-
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4.5 shrink-0 rounded-[4px] border-[1.6px] shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 hover:border-gray-950 cursor-pointer",
|
|
17
|
-
className,
|
|
18
|
-
)}
|
|
19
|
-
{...props}
|
|
20
|
-
>
|
|
21
|
-
<CheckboxPrimitive.Indicator
|
|
22
|
-
data-slot="checkbox-indicator"
|
|
23
|
-
className="grid place-content-center text-current transition-none"
|
|
24
|
-
>
|
|
25
|
-
<CheckIcon className="size-3 text-current" />
|
|
26
|
-
</CheckboxPrimitive.Indicator>
|
|
27
|
-
</CheckboxPrimitive.Root>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export { Checkbox };
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
5
|
+
import { CheckIcon } from "lucide-react";
|
|
6
|
+
import { cn } from "../../../infra/utils/clsx";
|
|
7
|
+
|
|
8
|
+
function Checkbox({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<CheckboxPrimitive.Root
|
|
14
|
+
data-slot="checkbox"
|
|
15
|
+
className={cn(
|
|
16
|
+
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4.5 shrink-0 rounded-[4px] border-[1.6px] shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 hover:border-gray-950 cursor-pointer",
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<CheckboxPrimitive.Indicator
|
|
22
|
+
data-slot="checkbox-indicator"
|
|
23
|
+
className="grid place-content-center text-current transition-none"
|
|
24
|
+
>
|
|
25
|
+
<CheckIcon className="size-3 text-current" />
|
|
26
|
+
</CheckboxPrimitive.Indicator>
|
|
27
|
+
</CheckboxPrimitive.Root>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { Checkbox };
|
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState, forwardRef, useEffect } from "react";
|
|
4
|
-
import { format } from "date-fns";
|
|
5
|
-
import { Calendar } from "./Calendar";
|
|
6
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
|
|
7
|
-
import { cn } from "../../../infra/utils/clsx";
|
|
8
|
-
|
|
9
|
-
// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local
|
|
10
|
-
// Evita bug de timezone onde new Date("2025-08-02") interpreta como UTC
|
|
11
|
-
const isoParaDataLocal = (iso: string): Date => {
|
|
12
|
-
const [ano, mes, dia] = iso.split("-").map(Number);
|
|
13
|
-
return new Date(ano, mes - 1, dia);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
interface DatePickerProps {
|
|
17
|
-
value?: string;
|
|
18
|
-
onChange?: (date: string | undefined) => void;
|
|
19
|
-
placeholder?: string;
|
|
20
|
-
className?: string;
|
|
21
|
-
disabled?: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
|
|
25
|
-
(
|
|
26
|
-
{ value, onChange, placeholder = "Selecione a data", className, disabled },
|
|
27
|
-
ref,
|
|
28
|
-
) => {
|
|
29
|
-
const [open, setOpen] = useState(false);
|
|
30
|
-
const [date, setDate] = useState<Date | undefined>(() => {
|
|
31
|
-
return value ? isoParaDataLocal(value) : undefined;
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Sincroniza estado interno quando value mudar externamente
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
if (value) {
|
|
37
|
-
setDate(isoParaDataLocal(value));
|
|
38
|
-
} else {
|
|
39
|
-
setDate(undefined);
|
|
40
|
-
}
|
|
41
|
-
}, [value]);
|
|
42
|
-
|
|
43
|
-
const handleDateSelect = (selectedDate: Date | undefined) => {
|
|
44
|
-
setDate(selectedDate);
|
|
45
|
-
|
|
46
|
-
if (selectedDate) {
|
|
47
|
-
onChange?.(format(selectedDate, "yyyy-MM-dd"));
|
|
48
|
-
setOpen(false); // Fecha o popover após seleção
|
|
49
|
-
} else {
|
|
50
|
-
onChange?.(undefined);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const displayText = date ? format(date, "dd/MM/yyyy") : placeholder;
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<Popover open={open} onOpenChange={setOpen}>
|
|
58
|
-
<PopoverTrigger asChild>
|
|
59
|
-
<button
|
|
60
|
-
ref={ref}
|
|
61
|
-
disabled={disabled}
|
|
62
|
-
className={cn(
|
|
63
|
-
"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start",
|
|
64
|
-
"border-gray-200 hover:border-gray-400 focus-within:border-gray-950",
|
|
65
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
66
|
-
className,
|
|
67
|
-
)}
|
|
68
|
-
>
|
|
69
|
-
<span
|
|
70
|
-
className={cn(
|
|
71
|
-
"paragraph-small-medium",
|
|
72
|
-
date ? "text-gray-950" : "text-gray-500",
|
|
73
|
-
)}
|
|
74
|
-
>
|
|
75
|
-
{displayText}
|
|
76
|
-
</span>
|
|
77
|
-
</button>
|
|
78
|
-
</PopoverTrigger>
|
|
79
|
-
<PopoverContent
|
|
80
|
-
className="w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200"
|
|
81
|
-
align="start"
|
|
82
|
-
sideOffset={8}
|
|
83
|
-
>
|
|
84
|
-
<div className="p-3">
|
|
85
|
-
<Calendar
|
|
86
|
-
mode="single"
|
|
87
|
-
selected={date}
|
|
88
|
-
onSelect={handleDateSelect}
|
|
89
|
-
/>
|
|
90
|
-
</div>
|
|
91
|
-
</PopoverContent>
|
|
92
|
-
</Popover>
|
|
93
|
-
);
|
|
94
|
-
},
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
DatePicker.displayName = "DatePicker";
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState, forwardRef, useEffect } from "react";
|
|
4
|
+
import { format } from "date-fns";
|
|
5
|
+
import { Calendar } from "./Calendar";
|
|
6
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
|
|
7
|
+
import { cn } from "../../../infra/utils/clsx";
|
|
8
|
+
|
|
9
|
+
// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local
|
|
10
|
+
// Evita bug de timezone onde new Date("2025-08-02") interpreta como UTC
|
|
11
|
+
const isoParaDataLocal = (iso: string): Date => {
|
|
12
|
+
const [ano, mes, dia] = iso.split("-").map(Number);
|
|
13
|
+
return new Date(ano, mes - 1, dia);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
interface DatePickerProps {
|
|
17
|
+
value?: string;
|
|
18
|
+
onChange?: (date: string | undefined) => void;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
|
|
25
|
+
(
|
|
26
|
+
{ value, onChange, placeholder = "Selecione a data", className, disabled },
|
|
27
|
+
ref,
|
|
28
|
+
) => {
|
|
29
|
+
const [open, setOpen] = useState(false);
|
|
30
|
+
const [date, setDate] = useState<Date | undefined>(() => {
|
|
31
|
+
return value ? isoParaDataLocal(value) : undefined;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Sincroniza estado interno quando value mudar externamente
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (value) {
|
|
37
|
+
setDate(isoParaDataLocal(value));
|
|
38
|
+
} else {
|
|
39
|
+
setDate(undefined);
|
|
40
|
+
}
|
|
41
|
+
}, [value]);
|
|
42
|
+
|
|
43
|
+
const handleDateSelect = (selectedDate: Date | undefined) => {
|
|
44
|
+
setDate(selectedDate);
|
|
45
|
+
|
|
46
|
+
if (selectedDate) {
|
|
47
|
+
onChange?.(format(selectedDate, "yyyy-MM-dd"));
|
|
48
|
+
setOpen(false); // Fecha o popover após seleção
|
|
49
|
+
} else {
|
|
50
|
+
onChange?.(undefined);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const displayText = date ? format(date, "dd/MM/yyyy") : placeholder;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
58
|
+
<PopoverTrigger asChild>
|
|
59
|
+
<button
|
|
60
|
+
ref={ref}
|
|
61
|
+
disabled={disabled}
|
|
62
|
+
className={cn(
|
|
63
|
+
"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start",
|
|
64
|
+
"border-gray-200 hover:border-gray-400 focus-within:border-gray-950",
|
|
65
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
66
|
+
className,
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
<span
|
|
70
|
+
className={cn(
|
|
71
|
+
"paragraph-small-medium",
|
|
72
|
+
date ? "text-gray-950" : "text-gray-500",
|
|
73
|
+
)}
|
|
74
|
+
>
|
|
75
|
+
{displayText}
|
|
76
|
+
</span>
|
|
77
|
+
</button>
|
|
78
|
+
</PopoverTrigger>
|
|
79
|
+
<PopoverContent
|
|
80
|
+
className="w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200"
|
|
81
|
+
align="start"
|
|
82
|
+
sideOffset={8}
|
|
83
|
+
>
|
|
84
|
+
<div className="p-3">
|
|
85
|
+
<Calendar
|
|
86
|
+
mode="single"
|
|
87
|
+
selected={date}
|
|
88
|
+
onSelect={handleDateSelect}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
</PopoverContent>
|
|
92
|
+
</Popover>
|
|
93
|
+
);
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
DatePicker.displayName = "DatePicker";
|
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState, forwardRef, useEffect } from "react";
|
|
4
|
-
import { format } from "date-fns";
|
|
5
|
-
import { Calendar as CalendarIcon } from "lucide-react";
|
|
6
|
-
import { DateRange } from "react-day-picker";
|
|
7
|
-
import { Calendar } from "./Calendar";
|
|
8
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
|
|
9
|
-
import { cn } from "../../../infra/utils/clsx";
|
|
10
|
-
|
|
11
|
-
// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local
|
|
12
|
-
// Evita bug de timezone onde new Date("2025-08-02") interpreta como UTC
|
|
13
|
-
const isoParaDataLocal = (iso: string): Date => {
|
|
14
|
-
const [ano, mes, dia] = iso.split("-").map(Number);
|
|
15
|
-
return new Date(ano, mes - 1, dia);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
interface DateRangePickerProps {
|
|
19
|
-
value?: { from: string; to: string };
|
|
20
|
-
onChange?: (range: { from: string; to: string } | undefined) => void;
|
|
21
|
-
placeholder?: string;
|
|
22
|
-
className?: string;
|
|
23
|
-
disabled?: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const DateRangePicker = forwardRef<HTMLButtonElement, DateRangePickerProps>(
|
|
27
|
-
({ value, onChange, placeholder = "Selecione o período", className, disabled }, ref) => {
|
|
28
|
-
const [open, setOpen] = useState(false);
|
|
29
|
-
const [range, setRange] = useState<DateRange | undefined>(() => {
|
|
30
|
-
if (value?.from && value?.to) {
|
|
31
|
-
return {
|
|
32
|
-
from: isoParaDataLocal(value.from),
|
|
33
|
-
to: isoParaDataLocal(value.to)
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return undefined;
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
if (value?.from && value?.to) {
|
|
41
|
-
setRange({
|
|
42
|
-
from: isoParaDataLocal(value.from),
|
|
43
|
-
to: isoParaDataLocal(value.to)
|
|
44
|
-
});
|
|
45
|
-
} else {
|
|
46
|
-
setRange(undefined);
|
|
47
|
-
}
|
|
48
|
-
}, [value]);
|
|
49
|
-
|
|
50
|
-
const handleRangeSelect = (newRange: DateRange | undefined) => {
|
|
51
|
-
setRange(newRange);
|
|
52
|
-
|
|
53
|
-
if (newRange?.from && newRange?.to) {
|
|
54
|
-
onChange?.({
|
|
55
|
-
from: format(newRange.from, "yyyy-MM-dd"),
|
|
56
|
-
to: format(newRange.to, "yyyy-MM-dd")
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
onChange?.(undefined);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const displayText = range?.from && range?.to
|
|
64
|
-
? `${format(range.from, "dd/MM/yyyy")} - ${format(range.to, "dd/MM/yyyy")}`
|
|
65
|
-
: placeholder;
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<Popover open={open} onOpenChange={setOpen}>
|
|
69
|
-
<PopoverTrigger asChild>
|
|
70
|
-
<button
|
|
71
|
-
ref={ref}
|
|
72
|
-
disabled={disabled}
|
|
73
|
-
className={cn(
|
|
74
|
-
"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start",
|
|
75
|
-
"border-gray-200 hover:border-gray-400 focus-within:border-gray-950",
|
|
76
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
77
|
-
className
|
|
78
|
-
)}
|
|
79
|
-
>
|
|
80
|
-
<CalendarIcon size={20} className="text-gray-400" />
|
|
81
|
-
<span className={cn(
|
|
82
|
-
"paragraph-small-medium",
|
|
83
|
-
range?.from && range?.to ? "text-gray-950" : "text-gray-500"
|
|
84
|
-
)}>
|
|
85
|
-
{displayText}
|
|
86
|
-
</span>
|
|
87
|
-
</button>
|
|
88
|
-
</PopoverTrigger>
|
|
89
|
-
<PopoverContent
|
|
90
|
-
className="w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200"
|
|
91
|
-
align="start"
|
|
92
|
-
sideOffset={8}
|
|
93
|
-
>
|
|
94
|
-
<div className="p-3">
|
|
95
|
-
<Calendar
|
|
96
|
-
mode="range"
|
|
97
|
-
selected={range}
|
|
98
|
-
onSelect={handleRangeSelect}
|
|
99
|
-
numberOfMonths={1}
|
|
100
|
-
/>
|
|
101
|
-
</div>
|
|
102
|
-
</PopoverContent>
|
|
103
|
-
</Popover>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
DateRangePicker.displayName = "DateRangePicker";
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState, forwardRef, useEffect } from "react";
|
|
4
|
+
import { format } from "date-fns";
|
|
5
|
+
import { Calendar as CalendarIcon } from "lucide-react";
|
|
6
|
+
import { DateRange } from "react-day-picker";
|
|
7
|
+
import { Calendar } from "./Calendar";
|
|
8
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
|
|
9
|
+
import { cn } from "../../../infra/utils/clsx";
|
|
10
|
+
|
|
11
|
+
// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local
|
|
12
|
+
// Evita bug de timezone onde new Date("2025-08-02") interpreta como UTC
|
|
13
|
+
const isoParaDataLocal = (iso: string): Date => {
|
|
14
|
+
const [ano, mes, dia] = iso.split("-").map(Number);
|
|
15
|
+
return new Date(ano, mes - 1, dia);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
interface DateRangePickerProps {
|
|
19
|
+
value?: { from: string; to: string };
|
|
20
|
+
onChange?: (range: { from: string; to: string } | undefined) => void;
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const DateRangePicker = forwardRef<HTMLButtonElement, DateRangePickerProps>(
|
|
27
|
+
({ value, onChange, placeholder = "Selecione o período", className, disabled }, ref) => {
|
|
28
|
+
const [open, setOpen] = useState(false);
|
|
29
|
+
const [range, setRange] = useState<DateRange | undefined>(() => {
|
|
30
|
+
if (value?.from && value?.to) {
|
|
31
|
+
return {
|
|
32
|
+
from: isoParaDataLocal(value.from),
|
|
33
|
+
to: isoParaDataLocal(value.to)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (value?.from && value?.to) {
|
|
41
|
+
setRange({
|
|
42
|
+
from: isoParaDataLocal(value.from),
|
|
43
|
+
to: isoParaDataLocal(value.to)
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
setRange(undefined);
|
|
47
|
+
}
|
|
48
|
+
}, [value]);
|
|
49
|
+
|
|
50
|
+
const handleRangeSelect = (newRange: DateRange | undefined) => {
|
|
51
|
+
setRange(newRange);
|
|
52
|
+
|
|
53
|
+
if (newRange?.from && newRange?.to) {
|
|
54
|
+
onChange?.({
|
|
55
|
+
from: format(newRange.from, "yyyy-MM-dd"),
|
|
56
|
+
to: format(newRange.to, "yyyy-MM-dd")
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
onChange?.(undefined);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const displayText = range?.from && range?.to
|
|
64
|
+
? `${format(range.from, "dd/MM/yyyy")} - ${format(range.to, "dd/MM/yyyy")}`
|
|
65
|
+
: placeholder;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
69
|
+
<PopoverTrigger asChild>
|
|
70
|
+
<button
|
|
71
|
+
ref={ref}
|
|
72
|
+
disabled={disabled}
|
|
73
|
+
className={cn(
|
|
74
|
+
"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start",
|
|
75
|
+
"border-gray-200 hover:border-gray-400 focus-within:border-gray-950",
|
|
76
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
77
|
+
className
|
|
78
|
+
)}
|
|
79
|
+
>
|
|
80
|
+
<CalendarIcon size={20} className="text-gray-400" />
|
|
81
|
+
<span className={cn(
|
|
82
|
+
"paragraph-small-medium",
|
|
83
|
+
range?.from && range?.to ? "text-gray-950" : "text-gray-500"
|
|
84
|
+
)}>
|
|
85
|
+
{displayText}
|
|
86
|
+
</span>
|
|
87
|
+
</button>
|
|
88
|
+
</PopoverTrigger>
|
|
89
|
+
<PopoverContent
|
|
90
|
+
className="w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200"
|
|
91
|
+
align="start"
|
|
92
|
+
sideOffset={8}
|
|
93
|
+
>
|
|
94
|
+
<div className="p-3">
|
|
95
|
+
<Calendar
|
|
96
|
+
mode="range"
|
|
97
|
+
selected={range}
|
|
98
|
+
onSelect={handleRangeSelect}
|
|
99
|
+
numberOfMonths={1}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
</PopoverContent>
|
|
103
|
+
</Popover>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { cn } from "../../../infra/utils/clsx"
|
|
5
|
-
|
|
6
|
-
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
7
|
-
return (
|
|
8
|
-
<input
|
|
9
|
-
type={type}
|
|
10
|
-
data-slot="input"
|
|
11
|
-
className={cn(
|
|
12
|
-
"outline-none",
|
|
13
|
-
className
|
|
14
|
-
)}
|
|
15
|
-
{...props}
|
|
16
|
-
/>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export { Input }
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "../../../infra/utils/clsx"
|
|
5
|
+
|
|
6
|
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
7
|
+
return (
|
|
8
|
+
<input
|
|
9
|
+
type={type}
|
|
10
|
+
data-slot="input"
|
|
11
|
+
className={cn(
|
|
12
|
+
"outline-none",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { Input }
|