Update Calendar component and update dependencies and updated Agents MD files (#269)

* Update Calendar component and update dependencies

* Refactor AGENTS.md and CLAUDE.md for clarity and consistency

- Streamlined project overview and architecture sections in both AGENTS.md and CLAUDE.md to enhance readability.
- Updated command sections to reflect essential commands and improved formatting for better usability.
- Clarified multi-tenant architecture details and database operations, ensuring accurate representation of the project's structure.
- Enhanced component organization and security guidelines for better developer onboarding and adherence to best practices.

* Refactor code for consistency and readability

- Improved formatting in `env-variables-model.ts` for better description clarity.
- Enhanced readability of `current-plan-alert.tsx` and `current-plan-badge.tsx` by adjusting the status badge mapping.
- Standardized object syntax in `lemon-squeezy-webhook-handler.service.ts` for consistency.
- Refined className ordering in `account-selector.tsx` for better maintainability.
- Ensured proper syntax in `console.ts` with consistent object export.
- Reorganized imports in `calendar.tsx` for clarity and structure.
- Improved className formatting in `sidebar.tsx` for better readability.

* Update package version to 2.10.0 in package.json
This commit is contained in:
Giancarlo Buomprisco
2025-06-08 13:31:49 +07:00
committed by GitHub
parent 67663b32d9
commit 1c31e7ffab
35 changed files with 1369 additions and 430 deletions

View File

@@ -21,7 +21,7 @@
"@kit/supabase": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -16,7 +16,7 @@
"./marketing": "./src/components/marketing.tsx"
},
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/billing": "workspace:*",
"@kit/eslint-config": "workspace:*",
"@kit/lemon-squeezy": "workspace:*",
@@ -26,7 +26,7 @@
"@kit/supabase": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@types/react": "19.1.6",
"date-fns": "^4.1.0",
"lucide-react": "^0.513.0",
@@ -34,7 +34,7 @@
"react": "19.1.0",
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.2",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -2,7 +2,10 @@ import { Enums } from '@kit/supabase/database';
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
import { Trans } from '@kit/ui/trans';
const statusBadgeMap: Record<Enums<'subscription_status'>, `success` | `destructive` | `warning`> = {
const statusBadgeMap: Record<
Enums<'subscription_status'>,
`success` | `destructive` | `warning`
> = {
active: 'success',
trialing: 'success',
past_due: 'destructive',
@@ -35,4 +38,4 @@ export function CurrentPlanAlert(
</AlertDescription>
</Alert>
);
}
}

View File

@@ -16,7 +16,7 @@ const statusBadgeMap: Record<Status, `success` | `destructive` | `warning`> = {
pending: 'warning',
incomplete_expired: 'destructive',
paused: 'warning',
}
};
export function CurrentPlanBadge(
props: React.PropsWithoutRef<{

View File

@@ -27,7 +27,7 @@
"@types/react": "19.1.6",
"next": "15.3.3",
"react": "19.1.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -454,7 +454,7 @@ export class LemonSqueezyWebhookHandlerService
pending: 'pending',
failed: 'failed',
refunded: 'failed',
} satisfies Record<OrderStatus, UpsertOrderParams['status']>
} satisfies Record<OrderStatus, UpsertOrderParams['status']>;
return statusMap[status] ?? 'pending';
}

View File

@@ -31,7 +31,7 @@
"date-fns": "^4.1.0",
"next": "15.3.3",
"react": "19.1.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -29,7 +29,7 @@
"@types/node": "^22.15.30",
"@types/react": "19.1.6",
"react": "19.1.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -22,8 +22,8 @@
"@kit/supabase": "workspace:*",
"@kit/team-accounts": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@supabase/supabase-js": "2.49.10",
"zod": "^3.25.53"
"@supabase/supabase-js": "2.50.0",
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -20,7 +20,7 @@
"nanoid": "^5.1.5"
},
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/billing-gateway": "workspace:*",
"@kit/email-templates": "workspace:*",
"@kit/eslint-config": "workspace:*",
@@ -34,7 +34,7 @@
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@radix-ui/react-icons": "^1.3.2",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@types/react": "19.1.6",
"@types/react-dom": "19.1.6",
@@ -46,7 +46,7 @@
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.2",
"sonner": "^2.0.5",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"prettier": "@kit/prettier-config",
"typesVersions": {

View File

@@ -100,7 +100,7 @@ export function AccountSelector({
role="combobox"
aria-expanded={open}
className={cn(
'dark:shadow-primary/10 group w-full min-w-0 px-2 lg:w-auto lg:max-w-fit mr-1',
'dark:shadow-primary/10 group mr-1 w-full min-w-0 px-2 lg:w-auto lg:max-w-fit',
{
'justify-start': !collapsed,
'm-auto justify-center px-2 lg:w-full': collapsed,

View File

@@ -10,7 +10,7 @@
},
"prettier": "@kit/prettier-config",
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/eslint-config": "workspace:*",
"@kit/next": "workspace:*",
"@kit/prettier-config": "workspace:*",
@@ -20,7 +20,7 @@
"@kit/ui": "workspace:*",
"@makerkit/data-loader-supabase-core": "^0.0.10",
"@makerkit/data-loader-supabase-nextjs": "^1.2.5",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@tanstack/react-table": "^8.21.3",
"@types/react": "19.1.6",
@@ -29,7 +29,7 @@
"react": "19.1.0",
"react-dom": "19.1.0",
"react-hook-form": "^7.57.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"exports": {
".": "./src/index.ts",

View File

@@ -19,7 +19,7 @@
"./resend-email-link": "./src/components/resend-auth-link-form.tsx"
},
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/eslint-config": "workspace:*",
"@kit/prettier-config": "workspace:*",
"@kit/shared": "workspace:*",
@@ -28,7 +28,7 @@
"@kit/ui": "workspace:*",
"@marsidev/react-turnstile": "^1.1.0",
"@radix-ui/react-icons": "^1.3.2",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@types/react": "19.1.6",
"lucide-react": "^0.513.0",
@@ -36,7 +36,7 @@
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.2",
"sonner": "^2.0.5",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"prettier": "@kit/prettier-config",
"typesVersions": {

View File

@@ -19,7 +19,7 @@
"@kit/supabase": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@types/react": "19.1.6",
"lucide-react": "^0.513.0",

View File

@@ -18,7 +18,7 @@
"nanoid": "^5.1.5"
},
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/accounts": "workspace:*",
"@kit/billing-gateway": "workspace:*",
"@kit/email-templates": "workspace:*",
@@ -32,7 +32,7 @@
"@kit/supabase": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@tanstack/react-table": "^8.21.3",
"@types/react": "19.1.6",
@@ -46,7 +46,7 @@
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.2",
"sonner": "^2.0.5",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"prettier": "@kit/prettier-config",
"typesVersions": {

View File

@@ -21,7 +21,7 @@
"@kit/shared": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@types/node": "^22.15.30",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -21,7 +21,7 @@
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@types/nodemailer": "6.4.17",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -18,7 +18,7 @@
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@types/node": "^22.15.30",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -16,7 +16,7 @@
"@kit/eslint-config": "workspace:*",
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -26,7 +26,7 @@
"@kit/tsconfig": "workspace:*",
"@types/react": "19.1.6",
"react": "19.1.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -26,7 +26,7 @@
"@kit/tsconfig": "workspace:*",
"@types/react": "19.1.6",
"react": "19.1.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -20,9 +20,9 @@
"@kit/prettier-config": "workspace:*",
"@kit/supabase": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"next": "15.3.3",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -14,7 +14,7 @@
"./components": "./src/components/index.ts"
},
"devDependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@kit/email-templates": "workspace:*",
"@kit/eslint-config": "workspace:*",
"@kit/mailers": "workspace:*",
@@ -25,13 +25,13 @@
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@radix-ui/react-icons": "^1.3.2",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@types/react": "19.1.6",
"@types/react-dom": "19.1.6",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-hook-form": "^7.57.0",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -4,6 +4,6 @@ const Logger = {
warn: console.warn,
debug: console.debug,
fatal: console.error,
}
};
export { Logger };
export { Logger };

View File

@@ -25,13 +25,13 @@
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@supabase/ssr": "^0.6.1",
"@supabase/supabase-js": "2.49.10",
"@supabase/supabase-js": "2.50.0",
"@tanstack/react-query": "5.80.6",
"@types/react": "19.1.6",
"next": "15.3.3",
"react": "19.1.0",
"server-only": "^0.0.1",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"typesVersions": {
"*": {

View File

@@ -9,7 +9,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@hookform/resolvers": "^5.0.1",
"@hookform/resolvers": "^5.1.0",
"@radix-ui/react-accordion": "1.2.11",
"@radix-ui/react-alert-dialog": "^1.1.14",
"@radix-ui/react-avatar": "^1.1.10",
@@ -53,16 +53,21 @@
"next": "15.3.3",
"next-themes": "0.4.6",
"prettier": "^3.5.3",
"react-day-picker": "^8.10.1",
"react-day-picker": "^9.7.0",
"react-hook-form": "^7.57.0",
"react-i18next": "^15.5.2",
"sonner": "^2.0.5",
"tailwindcss": "4.1.8",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.8.3",
"zod": "^3.25.53"
"zod": "^3.25.56"
},
"prettier": "@kit/prettier-config",
"imports": {
"#utils": [
"./src/lib/utils/index.ts"
]
},
"exports": {
"./accordion": "./src/shadcn/accordion.tsx",
"./alert-dialog": "./src/shadcn/alert-dialog.tsx",

View File

@@ -2,69 +2,210 @@
import * as React from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { DayPicker } from 'react-day-picker';
import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from 'lucide-react';
import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker';
import { cn } from '../lib/utils';
import { buttonVariants } from './button';
export type { DateRange } from 'react-day-picker';
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
import { Button, buttonVariants } from './button';
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = 'label',
buttonVariant = 'ghost',
formatters,
components,
...props
}: CalendarProps) {
}: React.ComponentProps<typeof DayPicker> & {
buttonVariant?: React.ComponentProps<typeof Button>['variant'];
}) {
const defaultClassNames = getDefaultClassNames();
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn('p-3', className)}
className={cn(
'bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent',
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
className,
)}
captionLayout={captionLayout}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString('default', { month: 'short' }),
...formatters,
}}
classNames={{
months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
month: 'space-y-4',
caption: 'flex justify-center pt-1 relative items-center',
caption_label: 'text-sm font-medium',
nav: 'gap-x-2 flex items-center',
nav_button: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
root: cn('w-fit', defaultClassNames.root),
months: cn(
'relative flex flex-col gap-4 md:flex-row',
defaultClassNames.months,
),
month: cn('flex w-full flex-col gap-4', defaultClassNames.month),
nav: cn(
'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1',
defaultClassNames.nav,
),
button_previous: cn(
buttonVariants({ variant: buttonVariant }),
'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',
defaultClassNames.button_previous,
),
button_next: cn(
buttonVariants({ variant: buttonVariant }),
'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',
defaultClassNames.button_next,
),
month_caption: cn(
'flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)',
defaultClassNames.month_caption,
),
dropdowns: cn(
'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',
defaultClassNames.dropdowns,
),
dropdown_root: cn(
'has-focus:border-ring border-input has-focus:ring-ring/50 relative rounded-md border shadow-xs has-focus:ring-[3px]',
defaultClassNames.dropdown_root,
),
dropdown: cn('absolute inset-0 opacity-0', defaultClassNames.dropdown),
caption_label: cn(
'font-medium select-none',
captionLayout === 'label'
? 'text-sm'
: '[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5',
defaultClassNames.caption_label,
),
table: 'w-full border-collapse',
weekdays: cn('flex', defaultClassNames.weekdays),
weekday: cn(
'text-muted-foreground flex-1 rounded-md text-[0.8rem] font-normal select-none',
defaultClassNames.weekday,
),
week: cn('mt-2 flex w-full', defaultClassNames.week),
week_number_header: cn(
'w-(--cell-size) select-none',
defaultClassNames.week_number_header,
),
week_number: cn(
'text-muted-foreground text-[0.8rem] select-none',
defaultClassNames.week_number,
),
nav_button_previous: 'absolute left-1',
nav_button_next: 'absolute right-1',
table: 'w-full border-collapse space-y-1',
head_row: 'flex',
head_cell:
'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]',
row: 'flex w-full mt-2',
cell: 'text-center text-sm p-0 relative [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20',
day: cn(
buttonVariants({ variant: 'ghost' }),
'h-9 w-9 p-0 font-normal aria-selected:opacity-100',
'group/day relative aspect-square h-full w-full p-0 text-center select-none [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md',
defaultClassNames.day,
),
day_selected:
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
day_today: 'bg-accent text-accent-foreground',
day_outside: 'text-muted-foreground opacity-50',
day_disabled: 'text-muted-foreground opacity-50',
day_range_middle:
'aria-selected:bg-accent aria-selected:text-accent-foreground',
day_hidden: 'invisible',
range_start: cn(
'bg-accent rounded-l-md',
defaultClassNames.range_start,
),
range_middle: cn('rounded-none', defaultClassNames.range_middle),
range_end: cn('bg-accent rounded-r-md', defaultClassNames.range_end),
today: cn(
'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',
defaultClassNames.today,
),
outside: cn(
'text-muted-foreground aria-selected:text-muted-foreground',
defaultClassNames.outside,
),
disabled: cn(
'text-muted-foreground opacity-50',
defaultClassNames.disabled,
),
hidden: cn('invisible', defaultClassNames.hidden),
...classNames,
}}
components={{
IconLeft: ({ ...props }) => (
<ChevronLeft className="h-4 w-4" {...props} />
),
IconRight: ({ ...props }) => (
<ChevronRight className="h-4 w-4" {...props} />
),
Root: ({ className, rootRef, ...props }) => {
return (
<div
data-slot="calendar"
ref={rootRef}
className={cn(className)}
{...props}
/>
);
},
Chevron: ({ className, orientation, ...props }) => {
if (orientation === 'left') {
return (
<ChevronLeftIcon className={cn('size-4', className)} {...props} />
);
}
if (orientation === 'right') {
return (
<ChevronRightIcon
className={cn('size-4', className)}
{...props}
/>
);
}
return (
<ChevronDownIcon className={cn('size-4', className)} {...props} />
);
},
DayButton: CalendarDayButton,
WeekNumber: ({ children, ...props }) => {
return (
<td {...props}>
<div className="flex size-(--cell-size) items-center justify-center text-center">
{children}
</div>
</td>
);
},
...components,
}}
{...props}
/>
);
}
Calendar.displayName = 'Calendar';
export { Calendar };
function CalendarDayButton({
className,
day,
modifiers,
...props
}: React.ComponentProps<typeof DayButton>) {
const defaultClassNames = getDefaultClassNames();
const ref = React.useRef<HTMLButtonElement>(null);
React.useEffect(() => {
if (modifiers.focused) ref.current?.focus();
}, [modifiers.focused]);
return (
<Button
ref={ref}
variant="ghost"
size="icon"
data-day={day.date.toLocaleDateString()}
data-selected-single={
modifiers.selected &&
!modifiers.range_start &&
!modifiers.range_end &&
!modifiers.range_middle
}
data-range-start={modifiers.range_start}
data-range-end={modifiers.range_end}
data-range-middle={modifiers.range_middle}
className={cn(
'data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70',
defaultClassNames.day,
className,
)}
{...props}
/>
);
}
export { Calendar, CalendarDayButton };

View File

@@ -392,7 +392,10 @@ const SidebarHeader: React.FC<React.ComponentPropsWithRef<'div'>> = ({
return (
<div
data-sidebar="header"
className={cn('flex flex-col gap-2 p-2 group-data-[state=collapsed]:group-data-[collapsible=offcanvas]:hidden', className)}
className={cn(
'flex flex-col gap-2 p-2 group-data-[state=collapsed]:group-data-[collapsible=offcanvas]:hidden',
className,
)}
{...props}
/>
);