create-astram-app 0.4.0 → 0.6.0

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.
Files changed (87) hide show
  1. package/README.md +211 -38
  2. package/dist/add-frontend.js.map +1 -1
  3. package/dist/index.js +14 -9
  4. package/dist/index.js.map +1 -1
  5. package/package.json +2 -2
  6. package/template/README.md +51 -20
  7. package/template/frontend/README.md +21 -11
  8. package/template/frontend/index.html +16 -0
  9. package/template/frontend/package.json +1 -1
  10. package/template/frontend/src/App.jsx +95 -20
  11. package/template/frontend/src/auth/AuthContext.jsx +145 -21
  12. package/template/frontend/src/auth/routeGate.js +31 -0
  13. package/template/frontend/src/auth/routeGate.test.mjs +59 -0
  14. package/template/frontend/src/auth/sessionFlow.js +27 -0
  15. package/template/frontend/src/auth/sessionFlow.test.mjs +63 -0
  16. package/template/frontend/src/components/EntityList.jsx +1 -7
  17. package/template/frontend/src/components/MultiSelectChecklist.jsx +166 -0
  18. package/template/frontend/src/components/PageHeader.jsx +5 -4
  19. package/template/frontend/src/components/ShareDialog.jsx +3 -5
  20. package/template/frontend/src/components/access/CollapsibleGroup.jsx +4 -1
  21. package/template/frontend/src/components/ui/alert-dialog.tsx +27 -50
  22. package/template/frontend/src/components/ui/alert.tsx +17 -23
  23. package/template/frontend/src/components/ui/avatar.tsx +8 -20
  24. package/template/frontend/src/components/ui/badge.tsx +17 -26
  25. package/template/frontend/src/components/ui/button.tsx +22 -24
  26. package/template/frontend/src/components/ui/card.tsx +19 -36
  27. package/template/frontend/src/components/ui/checkbox.tsx +7 -10
  28. package/template/frontend/src/components/ui/date-field.tsx +26 -27
  29. package/template/frontend/src/components/ui/dialog.tsx +24 -40
  30. package/template/frontend/src/components/ui/dropdown-menu.tsx +25 -54
  31. package/template/frontend/src/components/ui/input-otp.tsx +1 -4
  32. package/template/frontend/src/components/ui/label.tsx +10 -12
  33. package/template/frontend/src/components/ui/searchable-select.tsx +1 -3
  34. package/template/frontend/src/components/ui/select.tsx +31 -43
  35. package/template/frontend/src/components/ui/separator.tsx +6 -6
  36. package/template/frontend/src/components/ui/sheet.tsx +29 -38
  37. package/template/frontend/src/components/ui/skeleton.tsx +3 -3
  38. package/template/frontend/src/components/ui/sonner.tsx +7 -7
  39. package/template/frontend/src/components/ui/table.tsx +56 -70
  40. package/template/frontend/src/components/ui/tooltip.tsx +7 -11
  41. package/template/frontend/src/config/branding.js +1 -4
  42. package/template/frontend/src/hooks/useMobile.tsx +4 -6
  43. package/template/frontend/src/index.css +9 -4
  44. package/template/frontend/src/pages/Dashboard.jsx +13 -7
  45. package/template/frontend/src/pages/ForgotPassword.jsx +9 -2
  46. package/template/frontend/src/pages/Login.jsx +85 -70
  47. package/template/frontend/src/pages/ResetPassword.jsx +9 -2
  48. package/template/frontend/src/pages/access/AccessForm.jsx +49 -15
  49. package/template/frontend/src/pages/access/AccessPage.jsx +10 -6
  50. package/template/frontend/src/pages/access/RecordPoliciesPage.jsx +9 -2
  51. package/template/frontend/src/pages/account/AccountLayout.jsx +11 -6
  52. package/template/frontend/src/pages/account/ChangePasswordPage.jsx +2 -2
  53. package/template/frontend/src/pages/account/ReenrollPage.jsx +3 -5
  54. package/template/frontend/src/pages/account/TwoFactorPage.jsx +3 -8
  55. package/template/frontend/src/pages/companies/CompaniesPage.jsx +7 -9
  56. package/template/frontend/src/pages/cross-tenant/GrantForm.jsx +41 -8
  57. package/template/frontend/src/pages/cross-tenant/GrantsPage.jsx +30 -7
  58. package/template/frontend/src/pages/cross-tenant/InboxPage.jsx +12 -3
  59. package/template/frontend/src/pages/roles/RolesPage.jsx +5 -9
  60. package/template/frontend/src/pages/service-accounts/KeyRevealDialog.jsx +104 -0
  61. package/template/frontend/src/pages/service-accounts/ServiceAccountAccessDialog.jsx +231 -0
  62. package/template/frontend/src/pages/service-accounts/ServiceAccountActionsMenu.jsx +56 -0
  63. package/template/frontend/src/pages/service-accounts/ServiceAccountsPage.jsx +368 -0
  64. package/template/frontend/src/pages/service-accounts/accessModel.js +158 -0
  65. package/template/frontend/src/pages/service-accounts/accessModel.test.mjs +189 -0
  66. package/template/frontend/src/pages/users/MembershipCard.jsx +3 -1
  67. package/template/frontend/src/pages/users/PostingRow.jsx +8 -14
  68. package/template/frontend/src/pages/users/UsersPage.jsx +7 -9
  69. package/template/frontend/src/platform/httpClient.js +5 -0
  70. package/template/frontend/src/platform/sessionStore.js +55 -13
  71. package/template/frontend/src/platform/sessionStore.test.mjs +89 -0
  72. package/template/frontend/src/platform/shieldTransport.js +6 -0
  73. package/template/frontend/src/platform/shieldTransport.test.mjs +84 -5
  74. package/template/frontend/src/shell/AppShell.jsx +10 -12
  75. package/template/frontend/src/shell/Sidebar.jsx +15 -3
  76. package/template/frontend/src/shell/nav.js +13 -3
  77. package/template/frontend/vite.config.js +19 -1
  78. package/template/server/_env.example +22 -1
  79. package/template/server/eslint.config.mjs +194 -0
  80. package/template/server/package.json +11 -11
  81. package/template/server/scripts/dev.mjs +17 -6
  82. package/template/server/scripts/sync-astram-guide.mjs +45 -19
  83. package/template/server/src/app.module.ts +11 -5
  84. package/template/server/src/health/demo.controller.ts +16 -12
  85. package/template/server/src/main.ts +23 -1
  86. package/template/server/test/enforcement.e2e.spec.ts +73 -6
  87. package/template/server/eslint.config.js +0 -95
@@ -1,8 +1,8 @@
1
- import * as React from "react";
2
- import * as LabelPrimitive from "@radix-ui/react-label";
3
- import { cva, type VariantProps } from "class-variance-authority";
1
+ import * as React from 'react';
2
+ import * as LabelPrimitive from '@radix-ui/react-label';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
4
 
5
- import { cn } from "@/lib/utils";
5
+ import { cn } from '@/lib/utils';
6
6
 
7
7
  /**
8
8
  * Label — default is the standard shadcn label (existing callers unchanged).
@@ -13,27 +13,25 @@ import { cn } from "@/lib/utils";
13
13
  * the OCA-crisp field labels.
14
14
  */
15
15
  const labelVariants = cva(
16
- "flex items-center gap-2 leading-none select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
16
+ 'flex items-center gap-2 leading-none select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
17
17
  {
18
18
  variants: {
19
19
  variant: {
20
- default: "text-sm font-medium",
21
- field:
22
- "font-mono text-[0.72rem] font-semibold tracking-[0.08em] uppercase text-primary",
20
+ default: 'text-sm font-medium',
21
+ field: 'font-mono text-[0.72rem] font-semibold tracking-[0.08em] uppercase text-primary',
23
22
  },
24
23
  },
25
24
  defaultVariants: {
26
- variant: "default",
25
+ variant: 'default',
27
26
  },
28
- }
27
+ },
29
28
  );
30
29
 
31
30
  function Label({
32
31
  className,
33
32
  variant,
34
33
  ...props
35
- }: React.ComponentProps<typeof LabelPrimitive.Root> &
36
- VariantProps<typeof labelVariants>) {
34
+ }: React.ComponentProps<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>) {
37
35
  return (
38
36
  <LabelPrimitive.Root
39
37
  data-slot="label"
@@ -413,9 +413,7 @@ export function SearchableSelect({
413
413
  )}
414
414
  >
415
415
  <span className="line-clamp-1">{opt.label}</span>
416
- {selected && (
417
- <Check className="absolute right-2 size-4 shrink-0" />
418
- )}
416
+ {selected && <Check className="absolute right-2 size-4 shrink-0" />}
419
417
  </div>
420
418
  );
421
419
  })
@@ -1,8 +1,8 @@
1
- import * as React from "react";
2
- import * as SelectPrimitive from "@radix-ui/react-select";
3
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
1
+ import * as React from 'react';
2
+ import * as SelectPrimitive from '@radix-ui/react-select';
3
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
4
4
 
5
- import { cn } from "@/lib/utils";
5
+ import { cn } from '@/lib/utils';
6
6
 
7
7
  /**
8
8
  * Radix Select — the shadcn/new-york Select set, styled to match this repo's
@@ -22,37 +22,31 @@ import { cn } from "@/lib/utils";
22
22
  * NOTE: requires `@radix-ui/react-select` to be installed.
23
23
  */
24
24
 
25
- function Select({
26
- ...props
27
- }: React.ComponentProps<typeof SelectPrimitive.Root>) {
25
+ function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {
28
26
  return <SelectPrimitive.Root data-slot="select" {...props} />;
29
27
  }
30
28
 
31
- function SelectGroup({
32
- ...props
33
- }: React.ComponentProps<typeof SelectPrimitive.Group>) {
29
+ function SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {
34
30
  return <SelectPrimitive.Group data-slot="select-group" {...props} />;
35
31
  }
36
32
 
37
- function SelectValue({
38
- ...props
39
- }: React.ComponentProps<typeof SelectPrimitive.Value>) {
33
+ function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {
40
34
  return <SelectPrimitive.Value data-slot="select-value" {...props} />;
41
35
  }
42
36
 
43
37
  const SelectTrigger = React.forwardRef<
44
38
  React.ElementRef<typeof SelectPrimitive.Trigger>,
45
39
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
46
- size?: "sm" | "default";
40
+ size?: 'sm' | 'default';
47
41
  }
48
- >(({ className, size = "default", children, ...props }, ref) => (
42
+ >(({ className, size = 'default', children, ...props }, ref) => (
49
43
  <SelectPrimitive.Trigger
50
44
  ref={ref}
51
45
  data-slot="select-trigger"
52
46
  data-size={size}
53
47
  className={cn(
54
48
  "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex w-full items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
55
- className
49
+ className,
56
50
  )}
57
51
  {...props}
58
52
  >
@@ -62,7 +56,7 @@ const SelectTrigger = React.forwardRef<
62
56
  </SelectPrimitive.Icon>
63
57
  </SelectPrimitive.Trigger>
64
58
  ));
65
- SelectTrigger.displayName = "SelectTrigger";
59
+ SelectTrigger.displayName = 'SelectTrigger';
66
60
 
67
61
  const SelectScrollUpButton = React.forwardRef<
68
62
  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
@@ -71,16 +65,13 @@ const SelectScrollUpButton = React.forwardRef<
71
65
  <SelectPrimitive.ScrollUpButton
72
66
  ref={ref}
73
67
  data-slot="select-scroll-up-button"
74
- className={cn(
75
- "flex cursor-default items-center justify-center py-1",
76
- className
77
- )}
68
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
78
69
  {...props}
79
70
  >
80
71
  <ChevronUpIcon className="size-4" />
81
72
  </SelectPrimitive.ScrollUpButton>
82
73
  ));
83
- SelectScrollUpButton.displayName = "SelectScrollUpButton";
74
+ SelectScrollUpButton.displayName = 'SelectScrollUpButton';
84
75
 
85
76
  const SelectScrollDownButton = React.forwardRef<
86
77
  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
@@ -89,30 +80,27 @@ const SelectScrollDownButton = React.forwardRef<
89
80
  <SelectPrimitive.ScrollDownButton
90
81
  ref={ref}
91
82
  data-slot="select-scroll-down-button"
92
- className={cn(
93
- "flex cursor-default items-center justify-center py-1",
94
- className
95
- )}
83
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
96
84
  {...props}
97
85
  >
98
86
  <ChevronDownIcon className="size-4" />
99
87
  </SelectPrimitive.ScrollDownButton>
100
88
  ));
101
- SelectScrollDownButton.displayName = "SelectScrollDownButton";
89
+ SelectScrollDownButton.displayName = 'SelectScrollDownButton';
102
90
 
103
91
  const SelectContent = React.forwardRef<
104
92
  React.ElementRef<typeof SelectPrimitive.Content>,
105
93
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
106
- >(({ className, children, position = "popper", ...props }, ref) => (
94
+ >(({ className, children, position = 'popper', ...props }, ref) => (
107
95
  <SelectPrimitive.Portal>
108
96
  <SelectPrimitive.Content
109
97
  ref={ref}
110
98
  data-slot="select-content"
111
99
  className={cn(
112
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
113
- position === "popper" &&
114
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
115
- className
100
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md',
101
+ position === 'popper' &&
102
+ 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
103
+ className,
116
104
  )}
117
105
  position={position}
118
106
  {...props}
@@ -120,9 +108,9 @@ const SelectContent = React.forwardRef<
120
108
  <SelectScrollUpButton />
121
109
  <SelectPrimitive.Viewport
122
110
  className={cn(
123
- "p-1",
124
- position === "popper" &&
125
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
111
+ 'p-1',
112
+ position === 'popper' &&
113
+ 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1',
126
114
  )}
127
115
  >
128
116
  {children}
@@ -131,7 +119,7 @@ const SelectContent = React.forwardRef<
131
119
  </SelectPrimitive.Content>
132
120
  </SelectPrimitive.Portal>
133
121
  ));
134
- SelectContent.displayName = "SelectContent";
122
+ SelectContent.displayName = 'SelectContent';
135
123
 
136
124
  const SelectLabel = React.forwardRef<
137
125
  React.ElementRef<typeof SelectPrimitive.Label>,
@@ -141,13 +129,13 @@ const SelectLabel = React.forwardRef<
141
129
  ref={ref}
142
130
  data-slot="select-label"
143
131
  className={cn(
144
- "text-muted-foreground px-2 py-1.5 font-mono text-[0.68rem] font-semibold tracking-[0.08em] uppercase",
145
- className
132
+ 'text-muted-foreground px-2 py-1.5 font-mono text-[0.68rem] font-semibold tracking-[0.08em] uppercase',
133
+ className,
146
134
  )}
147
135
  {...props}
148
136
  />
149
137
  ));
150
- SelectLabel.displayName = "SelectLabel";
138
+ SelectLabel.displayName = 'SelectLabel';
151
139
 
152
140
  const SelectItem = React.forwardRef<
153
141
  React.ElementRef<typeof SelectPrimitive.Item>,
@@ -158,7 +146,7 @@ const SelectItem = React.forwardRef<
158
146
  data-slot="select-item"
159
147
  className={cn(
160
148
  "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
161
- className
149
+ className,
162
150
  )}
163
151
  {...props}
164
152
  >
@@ -170,7 +158,7 @@ const SelectItem = React.forwardRef<
170
158
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
171
159
  </SelectPrimitive.Item>
172
160
  ));
173
- SelectItem.displayName = "SelectItem";
161
+ SelectItem.displayName = 'SelectItem';
174
162
 
175
163
  const SelectSeparator = React.forwardRef<
176
164
  React.ElementRef<typeof SelectPrimitive.Separator>,
@@ -179,11 +167,11 @@ const SelectSeparator = React.forwardRef<
179
167
  <SelectPrimitive.Separator
180
168
  ref={ref}
181
169
  data-slot="select-separator"
182
- className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
170
+ className={cn('bg-border pointer-events-none -mx-1 my-1 h-px', className)}
183
171
  {...props}
184
172
  />
185
173
  ));
186
- SelectSeparator.displayName = "SelectSeparator";
174
+ SelectSeparator.displayName = 'SelectSeparator';
187
175
 
188
176
  export {
189
177
  Select,
@@ -1,11 +1,11 @@
1
- import * as React from "react";
2
- import * as SeparatorPrimitive from "@radix-ui/react-separator";
1
+ import * as React from 'react';
2
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
3
3
 
4
- import { cn } from "@/lib/utils";
4
+ import { cn } from '@/lib/utils';
5
5
 
6
6
  function Separator({
7
7
  className,
8
- orientation = "horizontal",
8
+ orientation = 'horizontal',
9
9
  decorative = true,
10
10
  ...props
11
11
  }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
@@ -15,8 +15,8 @@ function Separator({
15
15
  decorative={decorative}
16
16
  orientation={orientation}
17
17
  className={cn(
18
- "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
19
- className
18
+ 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
19
+ className,
20
20
  )}
21
21
  {...props}
22
22
  />
@@ -1,30 +1,24 @@
1
- "use client";
1
+ 'use client';
2
2
 
3
- import * as React from "react";
4
- import * as SheetPrimitive from "@radix-ui/react-dialog";
5
- import { XIcon } from "lucide-react";
3
+ import * as React from 'react';
4
+ import * as SheetPrimitive from '@radix-ui/react-dialog';
5
+ import { XIcon } from 'lucide-react';
6
6
 
7
- import { cn } from "@/lib/utils";
7
+ import { cn } from '@/lib/utils';
8
8
 
9
9
  function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10
10
  return <SheetPrimitive.Root data-slot="sheet" {...props} />;
11
11
  }
12
12
 
13
- function SheetTrigger({
14
- ...props
15
- }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
13
+ function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
16
14
  return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
17
15
  }
18
16
 
19
- function SheetClose({
20
- ...props
21
- }: React.ComponentProps<typeof SheetPrimitive.Close>) {
17
+ function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {
22
18
  return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
23
19
  }
24
20
 
25
- function SheetPortal({
26
- ...props
27
- }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
21
+ function SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
28
22
  return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
29
23
  }
30
24
 
@@ -36,8 +30,8 @@ function SheetOverlay({
36
30
  <SheetPrimitive.Overlay
37
31
  data-slot="sheet-overlay"
38
32
  className={cn(
39
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
40
- className
33
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
34
+ className,
41
35
  )}
42
36
  {...props}
43
37
  />
@@ -47,10 +41,10 @@ function SheetOverlay({
47
41
  function SheetContent({
48
42
  className,
49
43
  children,
50
- side = "right",
44
+ side = 'right',
51
45
  ...props
52
46
  }: React.ComponentProps<typeof SheetPrimitive.Content> & {
53
- side?: "top" | "right" | "bottom" | "left";
47
+ side?: 'top' | 'right' | 'bottom' | 'left';
54
48
  }) {
55
49
  return (
56
50
  <SheetPortal>
@@ -58,16 +52,16 @@ function SheetContent({
58
52
  <SheetPrimitive.Content
59
53
  data-slot="sheet-content"
60
54
  className={cn(
61
- "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
62
- side === "right" &&
63
- "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
64
- side === "left" &&
65
- "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
66
- side === "top" &&
67
- "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
68
- side === "bottom" &&
69
- "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
70
- className
55
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
56
+ side === 'right' &&
57
+ 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
58
+ side === 'left' &&
59
+ 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
60
+ side === 'top' &&
61
+ 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
62
+ side === 'bottom' &&
63
+ 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
64
+ className,
71
65
  )}
72
66
  {...props}
73
67
  >
@@ -81,34 +75,31 @@ function SheetContent({
81
75
  );
82
76
  }
83
77
 
84
- function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
78
+ function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
85
79
  return (
86
80
  <div
87
81
  data-slot="sheet-header"
88
- className={cn("flex flex-col gap-1.5 p-4", className)}
82
+ className={cn('flex flex-col gap-1.5 p-4', className)}
89
83
  {...props}
90
84
  />
91
85
  );
92
86
  }
93
87
 
94
- function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
88
+ function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
95
89
  return (
96
90
  <div
97
91
  data-slot="sheet-footer"
98
- className={cn("mt-auto flex flex-col gap-2 p-4", className)}
92
+ className={cn('mt-auto flex flex-col gap-2 p-4', className)}
99
93
  {...props}
100
94
  />
101
95
  );
102
96
  }
103
97
 
104
- function SheetTitle({
105
- className,
106
- ...props
107
- }: React.ComponentProps<typeof SheetPrimitive.Title>) {
98
+ function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {
108
99
  return (
109
100
  <SheetPrimitive.Title
110
101
  data-slot="sheet-title"
111
- className={cn("text-foreground font-semibold", className)}
102
+ className={cn('text-foreground font-semibold', className)}
112
103
  {...props}
113
104
  />
114
105
  );
@@ -121,7 +112,7 @@ function SheetDescription({
121
112
  return (
122
113
  <SheetPrimitive.Description
123
114
  data-slot="sheet-description"
124
- className={cn("text-muted-foreground text-sm", className)}
115
+ className={cn('text-muted-foreground text-sm', className)}
125
116
  {...props}
126
117
  />
127
118
  );
@@ -1,10 +1,10 @@
1
- import { cn } from "@/lib/utils";
1
+ import { cn } from '@/lib/utils';
2
2
 
3
- function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
3
+ function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
4
4
  return (
5
5
  <div
6
6
  data-slot="skeleton"
7
- className={cn("bg-accent animate-pulse rounded-md", className)}
7
+ className={cn('bg-accent animate-pulse rounded-md', className)}
8
8
  {...props}
9
9
  />
10
10
  );
@@ -1,18 +1,18 @@
1
- import { useTheme } from "next-themes";
2
- import { Toaster as Sonner, type ToasterProps } from "sonner";
1
+ import { useTheme } from 'next-themes';
2
+ import { Toaster as Sonner, type ToasterProps } from 'sonner';
3
3
 
4
4
  const Toaster = ({ ...props }: ToasterProps) => {
5
- const { theme = "system" } = useTheme();
5
+ const { theme = 'system' } = useTheme();
6
6
 
7
7
  return (
8
8
  <Sonner
9
- theme={theme as ToasterProps["theme"]}
9
+ theme={theme as ToasterProps['theme']}
10
10
  className="toaster group"
11
11
  style={
12
12
  {
13
- "--normal-bg": "var(--popover)",
14
- "--normal-text": "var(--popover-foreground)",
15
- "--normal-border": "var(--border)",
13
+ '--normal-bg': 'var(--popover)',
14
+ '--normal-text': 'var(--popover-foreground)',
15
+ '--normal-border': 'var(--border)',
16
16
  } as React.CSSProperties
17
17
  }
18
18
  {...props}