@rangka/client 0.1.1 → 0.1.3

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 (317) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +7 -1
  3. package/dist/App.js.map +1 -1
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/main.d.ts.map +1 -1
  9. package/dist/main.js +20 -0
  10. package/dist/main.js.map +1 -1
  11. package/dist/shell/assets/index-63v1sBS3.css +1 -0
  12. package/dist/shell/assets/index-Dh7K40cQ.js +8634 -0
  13. package/dist/shell/assets/vendor-query-B2cydN5j.js +1 -0
  14. package/dist/shell/assets/vendor-radix-BJxYPxPb.js +69 -0
  15. package/dist/shell/assets/vendor-router-ET_myMt5.js +17 -0
  16. package/dist/shell/index.html +5 -2
  17. package/dist/theme.css +82 -0
  18. package/dist/widgets/components/lazy-manifest.d.ts +11 -0
  19. package/dist/widgets/components/lazy-manifest.d.ts.map +1 -0
  20. package/dist/widgets/components/lazy-manifest.js +32 -0
  21. package/dist/widgets/components/lazy-manifest.js.map +1 -0
  22. package/dist/widgets/components/register.js +12 -12
  23. package/dist/widgets/components/register.js.map +1 -1
  24. package/dist/widgets/loader.d.ts +3 -0
  25. package/dist/widgets/loader.d.ts.map +1 -0
  26. package/dist/widgets/loader.js +73 -0
  27. package/dist/widgets/loader.js.map +1 -0
  28. package/dist/widgets/renderer/LazyWidget.d.ts +8 -0
  29. package/dist/widgets/renderer/LazyWidget.d.ts.map +1 -0
  30. package/dist/widgets/renderer/LazyWidget.js +31 -0
  31. package/dist/widgets/renderer/LazyWidget.js.map +1 -0
  32. package/dist/widgets/renderer/WidgetErrorBoundary.d.ts +17 -0
  33. package/dist/widgets/renderer/WidgetErrorBoundary.d.ts.map +1 -0
  34. package/dist/widgets/renderer/WidgetErrorBoundary.js +18 -0
  35. package/dist/widgets/renderer/WidgetErrorBoundary.js.map +1 -0
  36. package/dist/widgets/renderer/WidgetRenderer.d.ts.map +1 -1
  37. package/dist/widgets/renderer/WidgetRenderer.js +8 -6
  38. package/dist/widgets/renderer/WidgetRenderer.js.map +1 -1
  39. package/package.json +7 -4
  40. package/.claude/skills/add-widget/SKILL.md +0 -101
  41. package/.turbo/turbo-build.log +0 -29
  42. package/CHANGELOG.md +0 -25
  43. package/CLAUDE.md +0 -236
  44. package/components.json +0 -25
  45. package/dist/components/ui/chart.d.ts +0 -45
  46. package/dist/components/ui/chart.d.ts.map +0 -1
  47. package/dist/components/ui/chart.js +0 -119
  48. package/dist/components/ui/chart.js.map +0 -1
  49. package/dist/shell/assets/index--35CAvcP.js +0 -8715
  50. package/dist/shell/assets/index-COLmoPYo.css +0 -1
  51. package/index.html +0 -12
  52. package/src/App.tsx +0 -44
  53. package/src/__tests__/setup.ts +0 -1
  54. package/src/api/auth.ts +0 -41
  55. package/src/api/boot.ts +0 -10
  56. package/src/api/client.ts +0 -26
  57. package/src/api/paths.ts +0 -3
  58. package/src/api/token.ts +0 -13
  59. package/src/auth/LoginForm.tsx +0 -67
  60. package/src/auth/SessionExpired.tsx +0 -24
  61. package/src/auth/SetupForm.tsx +0 -76
  62. package/src/boot/BootGate.tsx +0 -35
  63. package/src/boot/BootProvider.tsx +0 -28
  64. package/src/boot/types.ts +0 -9
  65. package/src/boot/useBoot.ts +0 -111
  66. package/src/components/Icon.tsx +0 -17
  67. package/src/components/ui/accordion.tsx +0 -82
  68. package/src/components/ui/alert-dialog.tsx +0 -180
  69. package/src/components/ui/alert.tsx +0 -76
  70. package/src/components/ui/aspect-ratio.tsx +0 -9
  71. package/src/components/ui/avatar.tsx +0 -94
  72. package/src/components/ui/badge.tsx +0 -45
  73. package/src/components/ui/breadcrumb.tsx +0 -104
  74. package/src/components/ui/button-group.tsx +0 -78
  75. package/src/components/ui/button.tsx +0 -65
  76. package/src/components/ui/calendar.tsx +0 -187
  77. package/src/components/ui/card.tsx +0 -85
  78. package/src/components/ui/carousel.tsx +0 -229
  79. package/src/components/ui/chart.tsx +0 -339
  80. package/src/components/ui/checkbox.tsx +0 -27
  81. package/src/components/ui/collapsible.tsx +0 -21
  82. package/src/components/ui/combobox.tsx +0 -275
  83. package/src/components/ui/command.tsx +0 -178
  84. package/src/components/ui/context-menu.tsx +0 -242
  85. package/src/components/ui/dialog.tsx +0 -146
  86. package/src/components/ui/direction.tsx +0 -20
  87. package/src/components/ui/drawer.tsx +0 -118
  88. package/src/components/ui/dropdown-menu.tsx +0 -247
  89. package/src/components/ui/empty.tsx +0 -94
  90. package/src/components/ui/field.tsx +0 -224
  91. package/src/components/ui/hover-card.tsx +0 -36
  92. package/src/components/ui/input-group.tsx +0 -142
  93. package/src/components/ui/input-otp.tsx +0 -86
  94. package/src/components/ui/input.tsx +0 -19
  95. package/src/components/ui/item.tsx +0 -182
  96. package/src/components/ui/kbd.tsx +0 -26
  97. package/src/components/ui/label.tsx +0 -19
  98. package/src/components/ui/menubar.tsx +0 -260
  99. package/src/components/ui/native-select.tsx +0 -55
  100. package/src/components/ui/navigation-menu.tsx +0 -160
  101. package/src/components/ui/pagination.tsx +0 -112
  102. package/src/components/ui/popover.tsx +0 -74
  103. package/src/components/ui/progress.tsx +0 -31
  104. package/src/components/ui/radio-group.tsx +0 -42
  105. package/src/components/ui/resizable.tsx +0 -42
  106. package/src/components/ui/scroll-area.tsx +0 -53
  107. package/src/components/ui/select.tsx +0 -185
  108. package/src/components/ui/separator.tsx +0 -26
  109. package/src/components/ui/sheet.tsx +0 -128
  110. package/src/components/ui/sidebar.tsx +0 -669
  111. package/src/components/ui/skeleton.tsx +0 -13
  112. package/src/components/ui/slider.tsx +0 -54
  113. package/src/components/ui/sonner.tsx +0 -43
  114. package/src/components/ui/spinner.tsx +0 -16
  115. package/src/components/ui/switch.tsx +0 -33
  116. package/src/components/ui/table.tsx +0 -87
  117. package/src/components/ui/tabs.tsx +0 -80
  118. package/src/components/ui/textarea.tsx +0 -18
  119. package/src/components/ui/toggle-group.tsx +0 -86
  120. package/src/components/ui/toggle.tsx +0 -44
  121. package/src/components/ui/tooltip.tsx +0 -53
  122. package/src/context/MetaContext.tsx +0 -22
  123. package/src/context/ModuleContext.tsx +0 -62
  124. package/src/context/PermissionsContext.tsx +0 -39
  125. package/src/context/ShellProviders.tsx +0 -33
  126. package/src/context/UserContext.tsx +0 -16
  127. package/src/data/QueryProvider.tsx +0 -7
  128. package/src/data/queryClient.ts +0 -18
  129. package/src/data/useModelMeta.ts +0 -17
  130. package/src/data/useMutation.ts +0 -60
  131. package/src/data/useRecord.ts +0 -29
  132. package/src/data/useSource.ts +0 -112
  133. package/src/hooks/use-mobile.ts +0 -19
  134. package/src/index.css +0 -260
  135. package/src/index.ts +0 -16
  136. package/src/lib/utils.ts +0 -6
  137. package/src/main.tsx +0 -17
  138. package/src/router/NotFound.tsx +0 -8
  139. package/src/router/RouterProvider.tsx +0 -7
  140. package/src/router/buildRouteTree.tsx +0 -63
  141. package/src/router/createShellRouter.ts +0 -9
  142. package/src/router/hooks.ts +0 -43
  143. package/src/shell/CommandPalette.tsx +0 -76
  144. package/src/shell/ConfirmDialog.tsx +0 -34
  145. package/src/shell/ConfirmProvider.tsx +0 -56
  146. package/src/shell/DrawerContext.tsx +0 -44
  147. package/src/shell/HeaderActions.tsx +0 -31
  148. package/src/shell/ModuleSelectorPage.tsx +0 -149
  149. package/src/shell/PageOutlet.tsx +0 -21
  150. package/src/shell/ShellContext.tsx +0 -45
  151. package/src/shell/ShellDevTools.tsx +0 -153
  152. package/src/shell/ShellLayout.tsx +0 -231
  153. package/src/shell/Toast.tsx +0 -58
  154. package/src/shell/ToastProvider.tsx +0 -60
  155. package/src/shell/app-sidebar/AppSidebar.tsx +0 -44
  156. package/src/shell/app-sidebar/ModuleSwitcher.tsx +0 -87
  157. package/src/shell/app-sidebar/NavMain.tsx +0 -64
  158. package/src/shell/app-sidebar/NavUser.tsx +0 -97
  159. package/src/shell/app-sidebar/SearchMenu.tsx +0 -22
  160. package/src/shell/app-sidebar/index.ts +0 -8
  161. package/src/shell/app-sidebar/types.ts +0 -38
  162. package/src/shell/types.ts +0 -6
  163. package/src/shell/useBreadcrumbs.ts +0 -42
  164. package/src/studio/bridge.ts +0 -125
  165. package/src/studio/index.ts +0 -3
  166. package/src/studio/overlay.ts +0 -47
  167. package/src/studio/types.ts +0 -32
  168. package/src/studio/walker.ts +0 -48
  169. package/src/vite-env.d.ts +0 -1
  170. package/src/widgets/__tests__/action-edge-cases.test.ts +0 -281
  171. package/src/widgets/__tests__/action.test.ts +0 -236
  172. package/src/widgets/__tests__/attachment-widget.test.tsx +0 -85
  173. package/src/widgets/__tests__/attachments-widget.test.tsx +0 -109
  174. package/src/widgets/__tests__/binding.test.ts +0 -76
  175. package/src/widgets/__tests__/button-widget.test.tsx +0 -145
  176. package/src/widgets/__tests__/checkbox-widget.test.tsx +0 -158
  177. package/src/widgets/__tests__/code-widget.test.tsx +0 -64
  178. package/src/widgets/__tests__/computed-widget.test.tsx +0 -62
  179. package/src/widgets/__tests__/condition-edge-cases.test.ts +0 -120
  180. package/src/widgets/__tests__/condition.test.ts +0 -221
  181. package/src/widgets/__tests__/context.test.ts +0 -99
  182. package/src/widgets/__tests__/data-widget.test.tsx +0 -204
  183. package/src/widgets/__tests__/datepicker-widget.test.tsx +0 -66
  184. package/src/widgets/__tests__/datetime-widget.test.tsx +0 -67
  185. package/src/widgets/__tests__/drawer-widget.test.tsx +0 -149
  186. package/src/widgets/__tests__/dynamic-link-widget.test.tsx +0 -52
  187. package/src/widgets/__tests__/edge-cases.test.ts +0 -232
  188. package/src/widgets/__tests__/evaluator.test.ts +0 -107
  189. package/src/widgets/__tests__/functions.test.ts +0 -147
  190. package/src/widgets/__tests__/grid-widget.test.tsx +0 -137
  191. package/src/widgets/__tests__/hooks.test.tsx +0 -249
  192. package/src/widgets/__tests__/icon-widget.test.tsx +0 -129
  193. package/src/widgets/__tests__/input-widget.test.tsx +0 -264
  194. package/src/widgets/__tests__/integration.test.ts +0 -116
  195. package/src/widgets/__tests__/json-widget.test.tsx +0 -70
  196. package/src/widgets/__tests__/link-widget.test.tsx +0 -92
  197. package/src/widgets/__tests__/many-to-many-widget.test.tsx +0 -93
  198. package/src/widgets/__tests__/modal-widget.test.tsx +0 -148
  199. package/src/widgets/__tests__/money-widget.test.tsx +0 -97
  200. package/src/widgets/__tests__/parser.test.ts +0 -171
  201. package/src/widgets/__tests__/reactive-variables.test.ts +0 -383
  202. package/src/widgets/__tests__/renderer.test.tsx +0 -300
  203. package/src/widgets/__tests__/repeat-widget.test.tsx +0 -229
  204. package/src/widgets/__tests__/select-widget.test.tsx +0 -231
  205. package/src/widgets/__tests__/sequence-widget.test.tsx +0 -58
  206. package/src/widgets/__tests__/shell-integration.test.tsx +0 -1343
  207. package/src/widgets/__tests__/split-widget.test.tsx +0 -133
  208. package/src/widgets/__tests__/state-edge-cases.test.ts +0 -118
  209. package/src/widgets/__tests__/state.test.ts +0 -106
  210. package/src/widgets/__tests__/table-data-binding.test.tsx +0 -482
  211. package/src/widgets/__tests__/table-filter-popover.test.tsx +0 -486
  212. package/src/widgets/__tests__/table-search.test.tsx +0 -305
  213. package/src/widgets/__tests__/table-widget.test.tsx +0 -509
  214. package/src/widgets/__tests__/textarea-widget.test.tsx +0 -105
  215. package/src/widgets/__tests__/tracker-validator-edge-cases.test.ts +0 -242
  216. package/src/widgets/__tests__/tracker.test.ts +0 -133
  217. package/src/widgets/__tests__/tree-widget.test.tsx +0 -97
  218. package/src/widgets/__tests__/use-model-source.test.ts +0 -67
  219. package/src/widgets/__tests__/validator.test.ts +0 -208
  220. package/src/widgets/action/dispatcher.ts +0 -334
  221. package/src/widgets/action/index.ts +0 -2
  222. package/src/widgets/binding/index.ts +0 -2
  223. package/src/widgets/binding/resolver.ts +0 -61
  224. package/src/widgets/components/AttachmentWidget.tsx +0 -111
  225. package/src/widgets/components/AttachmentsWidget.tsx +0 -121
  226. package/src/widgets/components/BadgeWidget.tsx +0 -35
  227. package/src/widgets/components/ButtonWidget.tsx +0 -43
  228. package/src/widgets/components/CardWidget.tsx +0 -68
  229. package/src/widgets/components/CheckboxWidget.tsx +0 -39
  230. package/src/widgets/components/CodeWidget.tsx +0 -44
  231. package/src/widgets/components/ColumnWidget.tsx +0 -22
  232. package/src/widgets/components/ComputedWidget.tsx +0 -49
  233. package/src/widgets/components/DataWidget.tsx +0 -189
  234. package/src/widgets/components/DatePickerWidget.tsx +0 -73
  235. package/src/widgets/components/DatetimeWidget.tsx +0 -160
  236. package/src/widgets/components/DividerWidget.tsx +0 -37
  237. package/src/widgets/components/DrawerWidget.tsx +0 -52
  238. package/src/widgets/components/DynamicLinkWidget.tsx +0 -130
  239. package/src/widgets/components/GridWidget.tsx +0 -134
  240. package/src/widgets/components/GroupWidget.tsx +0 -111
  241. package/src/widgets/components/IconWidget.tsx +0 -29
  242. package/src/widgets/components/ImageWidget.tsx +0 -28
  243. package/src/widgets/components/InputWidget.tsx +0 -70
  244. package/src/widgets/components/JsonWidget.tsx +0 -78
  245. package/src/widgets/components/LinkWidget.tsx +0 -99
  246. package/src/widgets/components/ManyToManyWidget.tsx +0 -125
  247. package/src/widgets/components/ModalWidget.tsx +0 -52
  248. package/src/widgets/components/MoneyWidget.tsx +0 -80
  249. package/src/widgets/components/RepeatWidget.tsx +0 -66
  250. package/src/widgets/components/ScrollAreaWidget.tsx +0 -40
  251. package/src/widgets/components/SectionWidget.tsx +0 -78
  252. package/src/widgets/components/SelectWidget.tsx +0 -63
  253. package/src/widgets/components/SequenceWidget.tsx +0 -32
  254. package/src/widgets/components/SpacerWidget.tsx +0 -29
  255. package/src/widgets/components/SplitWidget.tsx +0 -60
  256. package/src/widgets/components/StackWidget.tsx +0 -44
  257. package/src/widgets/components/TableWidget.tsx +0 -366
  258. package/src/widgets/components/TextWidget.tsx +0 -44
  259. package/src/widgets/components/TextareaWidget.tsx +0 -49
  260. package/src/widgets/components/TreeWidget.tsx +0 -109
  261. package/src/widgets/components/index.ts +0 -30
  262. package/src/widgets/components/register.ts +0 -93
  263. package/src/widgets/components/table/CellRenderers.tsx +0 -83
  264. package/src/widgets/components/table/TablePagination.tsx +0 -45
  265. package/src/widgets/components/table/TableToolbar.tsx +0 -285
  266. package/src/widgets/components/table/filter-operators.ts +0 -134
  267. package/src/widgets/components/table/index.ts +0 -11
  268. package/src/widgets/condition/evaluator.ts +0 -57
  269. package/src/widgets/condition/index.ts +0 -1
  270. package/src/widgets/context/builder.ts +0 -99
  271. package/src/widgets/context/index.ts +0 -8
  272. package/src/widgets/context/types.ts +0 -37
  273. package/src/widgets/data/index.ts +0 -5
  274. package/src/widgets/data/useModelQuery.ts +0 -116
  275. package/src/widgets/data/useModelRecord.ts +0 -37
  276. package/src/widgets/expression/evaluator.ts +0 -100
  277. package/src/widgets/expression/functions.ts +0 -131
  278. package/src/widgets/expression/index.ts +0 -13
  279. package/src/widgets/expression/parser.ts +0 -229
  280. package/src/widgets/expression/types.ts +0 -45
  281. package/src/widgets/form/FormContext.ts +0 -29
  282. package/src/widgets/form/FormProvider.tsx +0 -84
  283. package/src/widgets/form/FormWidget.tsx +0 -42
  284. package/src/widgets/form/index.ts +0 -4
  285. package/src/widgets/form/useFormState.ts +0 -127
  286. package/src/widgets/form/useFormSubmit.ts +0 -90
  287. package/src/widgets/form/useFormValidation.ts +0 -62
  288. package/src/widgets/hooks/index.ts +0 -8
  289. package/src/widgets/hooks/useAction.ts +0 -83
  290. package/src/widgets/hooks/useBind.ts +0 -34
  291. package/src/widgets/hooks/useCondition.ts +0 -21
  292. package/src/widgets/hooks/useDataQuery.ts +0 -48
  293. package/src/widgets/hooks/useExpression.ts +0 -14
  294. package/src/widgets/hooks/usePageState.ts +0 -21
  295. package/src/widgets/hooks/useSurfaceContext.ts +0 -11
  296. package/src/widgets/hooks/useWidgetContext.ts +0 -14
  297. package/src/widgets/index.ts +0 -80
  298. package/src/widgets/lib/layout-props.ts +0 -135
  299. package/src/widgets/reactivity/index.ts +0 -11
  300. package/src/widgets/reactivity/tracker.ts +0 -139
  301. package/src/widgets/reactivity/variables.ts +0 -213
  302. package/src/widgets/registry.ts +0 -41
  303. package/src/widgets/renderer/SlotRenderer.tsx +0 -47
  304. package/src/widgets/renderer/WidgetRenderer.tsx +0 -191
  305. package/src/widgets/renderer/index.ts +0 -4
  306. package/src/widgets/shell/WidgetSlotRenderer.tsx +0 -73
  307. package/src/widgets/shell/index.ts +0 -4
  308. package/src/widgets/shell/useActionHandlers.ts +0 -170
  309. package/src/widgets/state/index.ts +0 -2
  310. package/src/widgets/state/store.ts +0 -96
  311. package/src/widgets/types.ts +0 -28
  312. package/src/widgets/validation/index.ts +0 -2
  313. package/src/widgets/validation/validator.ts +0 -140
  314. package/tsconfig.json +0 -27
  315. package/tsconfig.tsbuildinfo +0 -1
  316. package/vite.config.ts +0 -21
  317. package/vitest.config.ts +0 -16
@@ -1,24 +0,0 @@
1
- import { Button } from '@/components/ui/button';
2
- import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
3
-
4
- export interface SessionExpiredProps {
5
- onReLogin: () => void;
6
- }
7
-
8
- export function SessionExpired({ onReLogin }: SessionExpiredProps) {
9
- return (
10
- <div className="flex min-h-screen items-center justify-center bg-background">
11
- <Card className="w-full max-w-sm text-center">
12
- <CardHeader>
13
- <CardTitle>Session Expired</CardTitle>
14
- </CardHeader>
15
- <CardContent className="flex flex-col items-center gap-4">
16
- <p className="text-sm text-muted-foreground">
17
- Your session has expired. Please sign in again to continue.
18
- </p>
19
- <Button onClick={onReLogin}>Sign in</Button>
20
- </CardContent>
21
- </Card>
22
- </div>
23
- );
24
- }
@@ -1,76 +0,0 @@
1
- import { useState } from 'react';
2
- import { Button } from '@/components/ui/button';
3
- import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
4
- import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field';
5
- import { Input } from '@/components/ui/input';
6
-
7
- export interface SetupFormProps {
8
- onSetup: (data: { name: string; email: string; password: string }) => void | Promise<void>;
9
- error?: string;
10
- loading?: boolean;
11
- }
12
-
13
- export function SetupForm({ onSetup, error, loading }: SetupFormProps) {
14
- const [name, setName] = useState('');
15
- const [email, setEmail] = useState('');
16
- const [password, setPassword] = useState('');
17
-
18
- const handleSubmit = (e: React.FormEvent) => {
19
- e.preventDefault();
20
- onSetup({ name, email, password });
21
- };
22
-
23
- return (
24
- <div className="flex min-h-screen items-center justify-center bg-background">
25
- <Card className="w-full max-w-sm">
26
- <CardHeader>
27
- <CardTitle>Setup</CardTitle>
28
- </CardHeader>
29
- <CardContent>
30
- <form onSubmit={handleSubmit}>
31
- <FieldGroup>
32
- <Field>
33
- <FieldLabel htmlFor="name">Name</FieldLabel>
34
- <Input
35
- id="name"
36
- value={name}
37
- onChange={(e) => setName(e.target.value)}
38
- placeholder="Your name"
39
- required
40
- autoFocus
41
- />
42
- </Field>
43
- <Field>
44
- <FieldLabel htmlFor="email">Email</FieldLabel>
45
- <Input
46
- id="email"
47
- type="email"
48
- value={email}
49
- onChange={(e) => setEmail(e.target.value)}
50
- placeholder="you@example.com"
51
- required
52
- />
53
- </Field>
54
- <Field>
55
- <FieldLabel htmlFor="password">Password</FieldLabel>
56
- <Input
57
- id="password"
58
- type="password"
59
- value={password}
60
- onChange={(e) => setPassword(e.target.value)}
61
- required
62
- />
63
- </Field>
64
- {error && <FieldError>{error}</FieldError>}
65
- <Field>
66
- <Button type="submit" className="w-full" disabled={loading}>
67
- {loading ? 'Setting up...' : 'Complete setup'}
68
- </Button>
69
- </Field>
70
- </FieldGroup>
71
- </form>
72
- </CardContent>
73
- </Card>
74
- </div>
75
- );
76
- }
@@ -1,35 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { useBootContext } from './BootProvider.js';
3
- import { LoginForm } from '../auth/LoginForm.js';
4
- import { SessionExpired } from '../auth/SessionExpired.js';
5
- import { SetupForm } from '../auth/SetupForm.js';
6
-
7
- export function BootGate({ children }: { children: ReactNode }) {
8
- const { state, handleLogin, handleSetup, handleSessionExpired, retry } = useBootContext();
9
-
10
- switch (state.status) {
11
- case 'checking':
12
- case 'loading':
13
- return (
14
- <div role="status" aria-label="Loading">
15
- Loading…
16
- </div>
17
- );
18
- case 'setup':
19
- return <SetupForm onSetup={handleSetup} />;
20
- case 'login':
21
- if (state.sessionExpired) {
22
- return <SessionExpired onReLogin={handleSessionExpired} />;
23
- }
24
- return <LoginForm onLogin={handleLogin} />;
25
- case 'error':
26
- return (
27
- <div role="alert">
28
- <p>Something went wrong. Unable to load the application.</p>
29
- <button onClick={retry}>Retry</button>
30
- </div>
31
- );
32
- case 'ready':
33
- return <>{children}</>;
34
- }
35
- }
@@ -1,28 +0,0 @@
1
- import { createContext, useContext, type ReactNode } from 'react';
2
- import type { LoginCredentials, SetupCredentials } from '../api/auth.js';
3
- import type { BootState } from './types.js';
4
- import { useBoot } from './useBoot.js';
5
-
6
- interface BootContextValue {
7
- state: BootState;
8
- handleLogin: (credentials: LoginCredentials) => Promise<void>;
9
- handleSetup: (credentials: SetupCredentials) => Promise<void>;
10
- handleSessionExpired: () => void;
11
- handleLogout: () => void;
12
- retry: () => void;
13
- }
14
-
15
- const BootContext = createContext<BootContextValue | null>(null);
16
-
17
- export function BootProvider({ children }: { children: ReactNode }) {
18
- const boot = useBoot();
19
- return <BootContext.Provider value={boot}>{children}</BootContext.Provider>;
20
- }
21
-
22
- export function useBootContext(): BootContextValue {
23
- const ctx = useContext(BootContext);
24
- if (!ctx) {
25
- throw new Error('useBootContext must be used within a BootProvider');
26
- }
27
- return ctx;
28
- }
package/src/boot/types.ts DELETED
@@ -1,9 +0,0 @@
1
- import type { BootResponse } from '@rangka/shared';
2
-
3
- export type BootState =
4
- | { status: 'checking' }
5
- | { status: 'setup' }
6
- | { status: 'login'; sessionExpired?: boolean }
7
- | { status: 'loading' }
8
- | { status: 'ready'; data: BootResponse }
9
- | { status: 'error'; error: unknown };
@@ -1,111 +0,0 @@
1
- import { useCallback, useEffect, useReducer } from 'react';
2
- import type { BootResponse } from '@rangka/shared';
3
- import { fetchBoot } from '../api/boot.js';
4
- import { login, setup, type LoginCredentials, type SetupCredentials } from '../api/auth.js';
5
- import { getToken, clearToken } from '../api/token.js';
6
- import type { BootState } from './types.js';
7
-
8
- type BootAction =
9
- | { type: 'SETUP_REQUIRED' }
10
- | { type: 'AUTH_REQUIRED'; sessionExpired?: boolean }
11
- | { type: 'LOADING' }
12
- | { type: 'READY'; data: BootResponse }
13
- | { type: 'ERROR'; error: unknown }
14
- | { type: 'RESET' };
15
-
16
- function bootReducer(_state: BootState, action: BootAction): BootState {
17
- switch (action.type) {
18
- case 'SETUP_REQUIRED':
19
- return { status: 'setup' };
20
- case 'AUTH_REQUIRED':
21
- return { status: 'login', sessionExpired: action.sessionExpired };
22
- case 'LOADING':
23
- return { status: 'loading' };
24
- case 'READY':
25
- return { status: 'ready', data: action.data };
26
- case 'ERROR':
27
- return { status: 'error', error: action.error };
28
- case 'RESET':
29
- return { status: 'login' };
30
- }
31
- }
32
-
33
- export interface UseBootResult {
34
- state: BootState;
35
- handleLogin: (credentials: LoginCredentials) => Promise<void>;
36
- handleSetup: (credentials: SetupCredentials) => Promise<void>;
37
- handleSessionExpired: () => void;
38
- handleLogout: () => void;
39
- retry: () => void;
40
- }
41
-
42
- export function useBoot(): UseBootResult {
43
- const [state, dispatch] = useReducer(bootReducer, { status: 'checking' });
44
-
45
- const performBoot = useCallback(async () => {
46
- dispatch({ type: 'LOADING' });
47
- try {
48
- const data = await fetchBoot();
49
- dispatch({ type: 'READY', data });
50
- } catch (err: unknown) {
51
- const status = (err as { status?: number }).status;
52
- if (status === 503) {
53
- dispatch({ type: 'SETUP_REQUIRED' });
54
- } else if (status === 401 || !getToken()) {
55
- dispatch({ type: 'AUTH_REQUIRED' });
56
- } else {
57
- dispatch({ type: 'ERROR', error: err });
58
- }
59
- }
60
- }, []);
61
-
62
- useEffect(() => {
63
- performBoot();
64
- }, [performBoot]);
65
-
66
- useEffect(() => {
67
- const onSessionExpired = () => {
68
- dispatch({ type: 'AUTH_REQUIRED', sessionExpired: true });
69
- };
70
- window.addEventListener('rangka:session-expired', onSessionExpired);
71
- return () => window.removeEventListener('rangka:session-expired', onSessionExpired);
72
- }, []);
73
-
74
- const handleLogin = useCallback(
75
- async (credentials: LoginCredentials) => {
76
- const response = await login(credentials);
77
- if (!response.ok) {
78
- throw response;
79
- }
80
- await performBoot();
81
- },
82
- [performBoot],
83
- );
84
-
85
- const handleSetup = useCallback(
86
- async (credentials: SetupCredentials) => {
87
- const response = await setup(credentials);
88
- if (!response.ok) {
89
- const body = await response.json().catch(() => ({}));
90
- throw new Error(body.message ?? 'Setup failed');
91
- }
92
- await performBoot();
93
- },
94
- [performBoot],
95
- );
96
-
97
- const handleSessionExpired = useCallback(() => {
98
- dispatch({ type: 'AUTH_REQUIRED', sessionExpired: true });
99
- }, []);
100
-
101
- const handleLogout = useCallback(() => {
102
- clearToken();
103
- dispatch({ type: 'RESET' });
104
- }, []);
105
-
106
- const retry = useCallback(() => {
107
- performBoot();
108
- }, [performBoot]);
109
-
110
- return { state, handleLogin, handleSetup, handleSessionExpired, handleLogout, retry };
111
- }
@@ -1,17 +0,0 @@
1
- import { icons, type LucideProps } from 'lucide-react';
2
-
3
- export interface IconProps extends Omit<LucideProps, 'ref'> {
4
- name: string;
5
- }
6
-
7
- export function Icon({ name, size = 14, ...props }: IconProps) {
8
- const pascalName = name
9
- .split('-')
10
- .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
11
- .join('');
12
-
13
- const LucideIcon = icons[pascalName as keyof typeof icons];
14
- if (!LucideIcon) return null;
15
-
16
- return <LucideIcon size={size} {...props} />;
17
- }
@@ -1,82 +0,0 @@
1
- import * as React from 'react';
2
- import { Accordion as AccordionPrimitive } from 'radix-ui';
3
-
4
- import { cn } from '@/lib/utils';
5
- import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
6
-
7
- function Accordion({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
8
- return (
9
- <AccordionPrimitive.Root
10
- data-slot="accordion"
11
- className={cn('flex w-full flex-col', className)}
12
- {...props}
13
- />
14
- );
15
- }
16
-
17
- function AccordionItem({
18
- className,
19
- ...props
20
- }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
21
- return (
22
- <AccordionPrimitive.Item
23
- data-slot="accordion-item"
24
- className={cn('not-last:border-b', className)}
25
- {...props}
26
- />
27
- );
28
- }
29
-
30
- function AccordionTrigger({
31
- className,
32
- children,
33
- ...props
34
- }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
35
- return (
36
- <AccordionPrimitive.Header className="flex">
37
- <AccordionPrimitive.Trigger
38
- data-slot="accordion-trigger"
39
- className={cn(
40
- 'group/accordion-trigger relative flex flex-1 items-start justify-between rounded-none border border-transparent py-2.5 text-left text-xs font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground',
41
- className,
42
- )}
43
- {...props}
44
- >
45
- {children}
46
- <ChevronDownIcon
47
- data-slot="accordion-trigger-icon"
48
- className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
49
- />
50
- <ChevronUpIcon
51
- data-slot="accordion-trigger-icon"
52
- className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
53
- />
54
- </AccordionPrimitive.Trigger>
55
- </AccordionPrimitive.Header>
56
- );
57
- }
58
-
59
- function AccordionContent({
60
- className,
61
- children,
62
- ...props
63
- }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
64
- return (
65
- <AccordionPrimitive.Content
66
- data-slot="accordion-content"
67
- className="overflow-hidden text-xs data-open:animate-accordion-down data-closed:animate-accordion-up"
68
- {...props}
69
- >
70
- <div
71
- className={cn(
72
- 'h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4',
73
- className,
74
- )}
75
- >
76
- {children}
77
- </div>
78
- </AccordionPrimitive.Content>
79
- );
80
- }
81
-
82
- export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
@@ -1,180 +0,0 @@
1
- import * as React from 'react';
2
- import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
3
-
4
- import { cn } from '@/lib/utils';
5
- import { Button } from '@/components/ui/button';
6
-
7
- function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
8
- return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
9
- }
10
-
11
- function AlertDialogTrigger({
12
- ...props
13
- }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
14
- return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;
15
- }
16
-
17
- function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
18
- return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />;
19
- }
20
-
21
- function AlertDialogOverlay({
22
- className,
23
- ...props
24
- }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
25
- return (
26
- <AlertDialogPrimitive.Overlay
27
- data-slot="alert-dialog-overlay"
28
- className={cn(
29
- 'fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',
30
- className,
31
- )}
32
- {...props}
33
- />
34
- );
35
- }
36
-
37
- function AlertDialogContent({
38
- className,
39
- size = 'default',
40
- ...props
41
- }: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
42
- size?: 'default' | 'sm';
43
- }) {
44
- return (
45
- <AlertDialogPortal>
46
- <AlertDialogOverlay />
47
- <AlertDialogPrimitive.Content
48
- data-slot="alert-dialog-content"
49
- data-size={size}
50
- className={cn(
51
- 'group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-none bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
52
- className,
53
- )}
54
- {...props}
55
- />
56
- </AlertDialogPortal>
57
- );
58
- }
59
-
60
- function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
61
- return (
62
- <div
63
- data-slot="alert-dialog-header"
64
- className={cn(
65
- 'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]',
66
- className,
67
- )}
68
- {...props}
69
- />
70
- );
71
- }
72
-
73
- function AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
74
- return (
75
- <div
76
- data-slot="alert-dialog-footer"
77
- className={cn(
78
- 'flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end',
79
- className,
80
- )}
81
- {...props}
82
- />
83
- );
84
- }
85
-
86
- function AlertDialogMedia({ className, ...props }: React.ComponentProps<'div'>) {
87
- return (
88
- <div
89
- data-slot="alert-dialog-media"
90
- className={cn(
91
- "mb-2 inline-flex size-10 items-center justify-center rounded-none bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
92
- className,
93
- )}
94
- {...props}
95
- />
96
- );
97
- }
98
-
99
- function AlertDialogTitle({
100
- className,
101
- ...props
102
- }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
103
- return (
104
- <AlertDialogPrimitive.Title
105
- data-slot="alert-dialog-title"
106
- className={cn(
107
- 'font-heading text-sm font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2',
108
- className,
109
- )}
110
- {...props}
111
- />
112
- );
113
- }
114
-
115
- function AlertDialogDescription({
116
- className,
117
- ...props
118
- }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
119
- return (
120
- <AlertDialogPrimitive.Description
121
- data-slot="alert-dialog-description"
122
- className={cn(
123
- 'text-xs/relaxed text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground',
124
- className,
125
- )}
126
- {...props}
127
- />
128
- );
129
- }
130
-
131
- function AlertDialogAction({
132
- className,
133
- variant = 'default',
134
- size = 'default',
135
- ...props
136
- }: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
137
- Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>) {
138
- return (
139
- <Button variant={variant} size={size} asChild>
140
- <AlertDialogPrimitive.Action
141
- data-slot="alert-dialog-action"
142
- className={cn(className)}
143
- {...props}
144
- />
145
- </Button>
146
- );
147
- }
148
-
149
- function AlertDialogCancel({
150
- className,
151
- variant = 'outline',
152
- size = 'default',
153
- ...props
154
- }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
155
- Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>) {
156
- return (
157
- <Button variant={variant} size={size} asChild>
158
- <AlertDialogPrimitive.Cancel
159
- data-slot="alert-dialog-cancel"
160
- className={cn(className)}
161
- {...props}
162
- />
163
- </Button>
164
- );
165
- }
166
-
167
- export {
168
- AlertDialog,
169
- AlertDialogAction,
170
- AlertDialogCancel,
171
- AlertDialogContent,
172
- AlertDialogDescription,
173
- AlertDialogFooter,
174
- AlertDialogHeader,
175
- AlertDialogMedia,
176
- AlertDialogOverlay,
177
- AlertDialogPortal,
178
- AlertDialogTitle,
179
- AlertDialogTrigger,
180
- };
@@ -1,76 +0,0 @@
1
- import * as React from 'react';
2
- import { cva, type VariantProps } from 'class-variance-authority';
3
-
4
- import { cn } from '@/lib/utils';
5
-
6
- const alertVariants = cva(
7
- "group/alert relative grid w-full gap-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
8
- {
9
- variants: {
10
- variant: {
11
- default: 'bg-card text-card-foreground',
12
- destructive:
13
- 'bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current',
14
- },
15
- },
16
- defaultVariants: {
17
- variant: 'default',
18
- },
19
- },
20
- );
21
-
22
- function Alert({
23
- className,
24
- variant,
25
- ...props
26
- }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {
27
- return (
28
- <div
29
- data-slot="alert"
30
- role="alert"
31
- className={cn(alertVariants({ variant }), className)}
32
- {...props}
33
- />
34
- );
35
- }
36
-
37
- function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
38
- return (
39
- <div
40
- data-slot="alert-title"
41
- className={cn(
42
- 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground',
43
- className,
44
- )}
45
- {...props}
46
- />
47
- );
48
- }
49
-
50
- function AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {
51
- return (
52
- <div
53
- data-slot="alert-description"
54
- className={cn(
55
- 'text-xs/relaxed text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-2',
56
- className,
57
- )}
58
- {...props}
59
- />
60
- );
61
- }
62
-
63
- function AlertAction({ className, ...props }: React.ComponentProps<'div'>) {
64
- return (
65
- <div
66
- data-slot="alert-action"
67
- className={cn(
68
- 'absolute top-[calc(--spacing(1.25))] right-[calc(--spacing(1.25))]',
69
- className,
70
- )}
71
- {...props}
72
- />
73
- );
74
- }
75
-
76
- export { Alert, AlertTitle, AlertDescription, AlertAction };
@@ -1,9 +0,0 @@
1
- 'use client';
2
-
3
- import { AspectRatio as AspectRatioPrimitive } from 'radix-ui';
4
-
5
- function AspectRatio({ ...props }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
6
- return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
7
- }
8
-
9
- export { AspectRatio };