@tulip-systems/core 0.5.9 → 0.5.11

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 (204) hide show
  1. package/dist/components/common/icons.d.mts +52 -52
  2. package/dist/components/common/icons.d.mts.map +1 -1
  3. package/dist/components/common/status.d.mts +3 -3
  4. package/dist/components/common/status.d.mts.map +1 -1
  5. package/dist/components/editor/components/content.client.d.mts +2 -2
  6. package/dist/components/editor/components/editor.client.d.mts +4 -4
  7. package/dist/components/editor/components/menu.client.d.mts +3 -3
  8. package/dist/components/editor/lib/helpers.d.mts.map +1 -1
  9. package/dist/components/header/back-button.client.d.mts +2 -2
  10. package/dist/components/header/bottom-bar.client.d.mts +3 -3
  11. package/dist/components/header/breadcrumbs.client.d.mts +7 -7
  12. package/dist/components/header/header.client.d.mts +2 -2
  13. package/dist/components/header/mobile-nav-switcher.client.d.mts +2 -2
  14. package/dist/components/header/top-bar.client.d.mts +4 -4
  15. package/dist/components/layouts/admin-content.client.d.mts +2 -2
  16. package/dist/components/layouts/admin-error-pages.d.mts +4 -4
  17. package/dist/components/layouts/admin-error-pages.d.mts.map +1 -1
  18. package/dist/components/layouts/admin-layout.d.mts +2 -2
  19. package/dist/components/layouts/admin-layout.d.mts.map +1 -1
  20. package/dist/components/layouts/admin-loading.d.mts +2 -2
  21. package/dist/components/layouts/admin-loading.d.mts.map +1 -1
  22. package/dist/components/layouts/empty-page.d.mts +4 -4
  23. package/dist/components/layouts/empty-page.d.mts.map +1 -1
  24. package/dist/components/layouts/error-page.d.mts +9 -9
  25. package/dist/components/layouts/error-page.d.mts.map +1 -1
  26. package/dist/components/layouts/error-sections.d.mts +5 -5
  27. package/dist/components/layouts/list-layout.d.mts +2 -2
  28. package/dist/components/layouts/providers.client.d.mts +2 -2
  29. package/dist/components/layouts/root-error-pages.d.mts +2 -2
  30. package/dist/components/layouts/root-layout.server.d.mts +2 -2
  31. package/dist/components/layouts/root-layout.server.d.mts.map +1 -1
  32. package/dist/components/layouts/root-loading.d.mts +2 -2
  33. package/dist/components/layouts/tab-layout.d.mts +2 -2
  34. package/dist/components/lists/data-list.d.mts +5 -5
  35. package/dist/components/lists/data-stack.d.mts +8 -8
  36. package/dist/components/lists/data-stack.d.mts.map +1 -1
  37. package/dist/components/navigation/admin-sidebar-paths.client.d.mts +10 -10
  38. package/dist/components/ui/accordion.d.mts +5 -5
  39. package/dist/components/ui/alert-dialog.d.mts +12 -12
  40. package/dist/components/ui/alert.d.mts +4 -4
  41. package/dist/components/ui/aspect-ratio.d.mts +2 -2
  42. package/dist/components/ui/avatar.client.d.mts +4 -4
  43. package/dist/components/ui/badge.d.mts +5 -5
  44. package/dist/components/ui/breadcrumb.d.mts +8 -8
  45. package/dist/components/ui/button.d.mts +5 -5
  46. package/dist/components/ui/button.d.mts.map +1 -1
  47. package/dist/components/ui/calendar.d.mts +3 -3
  48. package/dist/components/ui/calendar.d.mts.map +1 -1
  49. package/dist/components/ui/card.d.mts +7 -7
  50. package/dist/components/ui/card.d.mts.map +1 -1
  51. package/dist/components/ui/carousel.d.mts +6 -6
  52. package/dist/components/ui/carousel.d.mts.map +1 -1
  53. package/dist/components/ui/chart.client.d.mts +5 -5
  54. package/dist/components/ui/checkbox.d.mts +2 -2
  55. package/dist/components/ui/checkbox.d.mts.map +1 -1
  56. package/dist/components/ui/collapsible.client.d.mts +4 -4
  57. package/dist/components/ui/color-picker.client.d.mts +2 -2
  58. package/dist/components/ui/combobox-dropdown.client.d.mts +2 -2
  59. package/dist/components/ui/combobox.client.d.mts +2 -2
  60. package/dist/components/ui/command.d.mts +10 -10
  61. package/dist/components/ui/command.d.mts.map +1 -1
  62. package/dist/components/ui/context-menu.d.mts +16 -16
  63. package/dist/components/ui/context-menu.d.mts.map +1 -1
  64. package/dist/components/ui/date-picker.client.d.mts +2 -2
  65. package/dist/components/ui/dialog.client.d.mts +11 -11
  66. package/dist/components/ui/drawer.client.d.mts +11 -11
  67. package/dist/components/ui/dropdown-menu.d.mts +16 -16
  68. package/dist/components/ui/dropdown-menu.d.mts.map +1 -1
  69. package/dist/components/ui/form.client.d.mts +7 -7
  70. package/dist/components/ui/hover-card.client.d.mts +4 -4
  71. package/dist/components/ui/input.d.mts +2 -2
  72. package/dist/components/ui/label.d.mts +2 -2
  73. package/dist/components/ui/navigation-menu.d.mts +11 -11
  74. package/dist/components/ui/pagination.d.mts +8 -8
  75. package/dist/components/ui/popover.d.mts +5 -5
  76. package/dist/components/ui/progress.client.d.mts +2 -2
  77. package/dist/components/ui/radio-group.d.mts +3 -3
  78. package/dist/components/ui/resizable.client.d.mts +4 -4
  79. package/dist/components/ui/scroll-area.d.mts +3 -3
  80. package/dist/components/ui/select.client.d.mts +11 -11
  81. package/dist/components/ui/separator.d.mts +2 -2
  82. package/dist/components/ui/sheet.client.d.mts +9 -9
  83. package/dist/components/ui/sidebar.client.d.mts +24 -24
  84. package/dist/components/ui/skeleton.d.mts +2 -2
  85. package/dist/components/ui/slider.d.mts +2 -2
  86. package/dist/components/ui/sonner.client.d.mts +2 -2
  87. package/dist/components/ui/switch.d.mts +2 -2
  88. package/dist/components/ui/tabs.d.mts +5 -5
  89. package/dist/components/ui/textarea.d.mts +2 -2
  90. package/dist/components/ui/time-input.client.d.mts +2 -2
  91. package/dist/components/ui/toggle-group.client.d.mts +3 -3
  92. package/dist/components/ui/toggle.d.mts +4 -4
  93. package/dist/components/ui/toggle.d.mts.map +1 -1
  94. package/dist/components/ui/tooltip.client.d.mts +5 -5
  95. package/dist/lib/hooks/use-indicator.d.mts +2 -2
  96. package/dist/lib/hooks/use-indicator.d.mts.map +1 -1
  97. package/dist/modules/auth/components/allowed.client.d.mts +2 -2
  98. package/dist/modules/auth/components/allowed.client.d.mts.map +1 -1
  99. package/dist/modules/auth/components/auth-layout.server.d.mts +2 -2
  100. package/dist/modules/auth/components/auth-layout.server.d.mts.map +1 -1
  101. package/dist/modules/auth/components/auth-loading.d.mts +2 -2
  102. package/dist/modules/auth/components/create-first-user-page.client.d.mts +2 -2
  103. package/dist/modules/auth/components/create-first-user-page.client.d.mts.map +1 -1
  104. package/dist/modules/auth/components/forget-password-page.client.d.mts +2 -2
  105. package/dist/modules/auth/components/forget-password-page.client.d.mts.map +1 -1
  106. package/dist/modules/auth/components/guard-first-user.server.d.mts +2 -2
  107. package/dist/modules/auth/components/guard-first-user.server.d.mts.map +1 -1
  108. package/dist/modules/auth/components/guard.server.d.mts +2 -2
  109. package/dist/modules/auth/components/guard.server.d.mts.map +1 -1
  110. package/dist/modules/auth/components/login-page.client.d.mts +2 -2
  111. package/dist/modules/auth/components/login-page.client.d.mts.map +1 -1
  112. package/dist/modules/auth/components/reset-password-page.client.d.mts +2 -2
  113. package/dist/modules/auth/components/reset-password-page.client.d.mts.map +1 -1
  114. package/dist/modules/auth/components/update-password-command.d.mts +2 -2
  115. package/dist/modules/auth/components/update-password-command.d.mts.map +1 -1
  116. package/dist/modules/auth/db/schema.d.mts +73 -73
  117. package/dist/modules/auth/handler/client.client.d.mts +16 -16
  118. package/dist/modules/auth/lib/validators.d.mts +2 -2
  119. package/dist/modules/auth/lib/validators.d.mts.map +1 -1
  120. package/dist/modules/commands/components/alert-dialog-command.client.d.mts +10 -10
  121. package/dist/modules/commands/components/click-command.client.d.mts +2 -2
  122. package/dist/modules/commands/components/command-trigger.client.d.mts +6 -6
  123. package/dist/modules/commands/components/dialog-command.client.d.mts +8 -8
  124. package/dist/modules/commands/components/dropdown-command.client.d.mts +5 -5
  125. package/dist/modules/commands/components/empty-command.client.d.mts +2 -2
  126. package/dist/modules/commands/components/form-dialog-command.client.d.mts +11 -11
  127. package/dist/modules/commands/menus/context-menu.client.d.mts +2 -2
  128. package/dist/modules/commands/menus/dropdown-menu.client.d.mts +3 -3
  129. package/dist/modules/commands/menus/inline-menu.client.d.mts +3 -3
  130. package/dist/modules/commands/menus/responsive-menu.client.d.mts +3 -3
  131. package/dist/modules/commands/utils/archive-command.client.d.mts +3 -3
  132. package/dist/modules/commands/utils/delete-command.client.d.mts +3 -3
  133. package/dist/modules/config/db/helpers.d.mts +5 -5
  134. package/dist/modules/data-tables/components/cell/common.client.d.mts +5 -5
  135. package/dist/modules/data-tables/components/cell/common.client.d.mts.map +1 -1
  136. package/dist/modules/data-tables/components/column-header.d.mts +2 -2
  137. package/dist/modules/data-tables/components/column-header.d.mts.map +1 -1
  138. package/dist/modules/data-tables/components/filters/combobox.client.d.mts +2 -2
  139. package/dist/modules/data-tables/components/filters/combobox.client.d.mts.map +1 -1
  140. package/dist/modules/data-tables/components/filters/slider.client.d.mts +2 -2
  141. package/dist/modules/data-tables/components/filters/slider.client.d.mts.map +1 -1
  142. package/dist/modules/data-tables/components/header.d.mts +4 -4
  143. package/dist/modules/data-tables/components/header.d.mts.map +1 -1
  144. package/dist/modules/data-tables/components/layout.d.mts +2 -2
  145. package/dist/modules/data-tables/components/layout.d.mts.map +1 -1
  146. package/dist/modules/data-tables/components/search-input.client.d.mts +2 -2
  147. package/dist/modules/data-tables/components/search-input.client.d.mts.map +1 -1
  148. package/dist/modules/data-tables/components/skeleton.d.mts +2 -2
  149. package/dist/modules/data-tables/components/skeleton.d.mts.map +1 -1
  150. package/dist/modules/data-tables/components/table.d.mts +7 -7
  151. package/dist/modules/data-tables/components/table.d.mts.map +1 -1
  152. package/dist/modules/data-tables/components/toolbar.d.mts +3 -3
  153. package/dist/modules/data-tables/components/toolbar.d.mts.map +1 -1
  154. package/dist/modules/data-tables/hooks/use-context.client.d.mts +2 -2
  155. package/dist/modules/data-tables/hooks/use-context.client.d.mts.map +1 -1
  156. package/dist/modules/data-tables/tables/data-table/components/table.d.mts +2 -2
  157. package/dist/modules/data-tables/tables/data-table/components/table.d.mts.map +1 -1
  158. package/dist/modules/data-tables/tables/inline-table/components/cells/common.d.mts +2 -2
  159. package/dist/modules/data-tables/tables/inline-table/components/cells/common.d.mts.map +1 -1
  160. package/dist/modules/data-tables/tables/inline-table/components/cells/drag-handle.client.d.mts +2 -2
  161. package/dist/modules/data-tables/tables/inline-table/components/cells/drag-handle.client.d.mts.map +1 -1
  162. package/dist/modules/data-tables/tables/inline-table/components/cells/read-only.d.mts +2 -2
  163. package/dist/modules/data-tables/tables/inline-table/components/cells/read-only.d.mts.map +1 -1
  164. package/dist/modules/data-tables/tables/inline-table/components/table.d.mts +2 -2
  165. package/dist/modules/data-tables/tables/inline-table/components/table.d.mts.map +1 -1
  166. package/dist/modules/data-tables/tables/inline-table/hooks/context.client.d.mts +2 -2
  167. package/dist/modules/data-tables/tables/inline-table/hooks/context.client.d.mts.map +1 -1
  168. package/dist/modules/inline-edit/components/combobox-dropdown.client.d.mts +2 -2
  169. package/dist/modules/inline-edit/components/combobox.client.d.mts +2 -2
  170. package/dist/modules/inline-edit/components/date-input.client.d.mts +2 -2
  171. package/dist/modules/inline-edit/components/date-picker.client.d.mts +2 -2
  172. package/dist/modules/inline-edit/components/editor.client.d.mts +2 -2
  173. package/dist/modules/inline-edit/components/input-recipient.client.d.mts +2 -2
  174. package/dist/modules/inline-edit/components/input-toggle.client.d.mts +2 -2
  175. package/dist/modules/inline-edit/components/input.client.d.mts +4 -4
  176. package/dist/modules/inline-edit/components/select.client.d.mts +6 -6
  177. package/dist/modules/inline-edit/components/switch.client.d.mts +2 -2
  178. package/dist/modules/inline-edit/components/toggle.client.d.mts +2 -2
  179. package/dist/modules/inline-edit/hooks/context.client.d.mts +2 -2
  180. package/dist/modules/inline-edit/lib/variants.d.mts +1 -1
  181. package/dist/modules/router/lib/query-client.server.d.mts +2 -2
  182. package/dist/modules/storage/components/dropzone-context.client.d.mts +2 -2
  183. package/dist/modules/storage/components/dropzone-context.client.d.mts.map +1 -1
  184. package/dist/modules/storage/components/dropzone.client.d.mts +5 -5
  185. package/dist/modules/storage/components/dropzone.client.d.mts.map +1 -1
  186. package/dist/modules/storage/components/image-grid.client.d.mts +10 -3
  187. package/dist/modules/storage/components/image-grid.client.d.mts.map +1 -1
  188. package/dist/modules/storage/components/image-grid.client.mjs +8 -9
  189. package/dist/modules/storage/components/image-grid.client.mjs.map +1 -1
  190. package/dist/modules/storage/components/upload-zone-context.client.d.mts +7 -2
  191. package/dist/modules/storage/components/upload-zone-context.client.d.mts.map +1 -1
  192. package/dist/modules/storage/components/upload-zone-context.client.mjs.map +1 -1
  193. package/dist/modules/storage/components/upload-zone.client.d.mts +6 -9
  194. package/dist/modules/storage/components/upload-zone.client.d.mts.map +1 -1
  195. package/dist/modules/storage/components/upload-zone.client.mjs +38 -58
  196. package/dist/modules/storage/components/upload-zone.client.mjs.map +1 -1
  197. package/dist/modules/storage/lib/router.server.d.mts +12 -12
  198. package/dist/modules/storage/lib/schema.d.mts +92 -92
  199. package/dist/modules/storage/lib/service.server.d.mts +21 -21
  200. package/dist/modules/storage/lib/validators.d.mts +87 -87
  201. package/package.json +1 -1
  202. package/src/modules/storage/components/image-grid.client.tsx +10 -8
  203. package/src/modules/storage/components/upload-zone-context.client.tsx +9 -2
  204. package/src/modules/storage/components/upload-zone.client.tsx +49 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tulip-systems/core",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -14,7 +14,6 @@ import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog.cli
14
14
  import { Input } from "@/components/ui/input";
15
15
  import { Skeleton } from "@/components/ui/skeleton";
16
16
  import { useAction } from "@/lib/entry.client";
17
- import { arrayMove } from "@/lib/utils/array-move";
18
17
  import { cn } from "@/lib/utils/cn";
19
18
  import {
20
19
  closestCenter,
@@ -47,10 +46,13 @@ type ImageGridProps = ComponentProps<"div"> & {
47
46
  nodes: FileNode[];
48
47
  disabled?: boolean;
49
48
  moveAction: (params: { fromIndex: number; toIndex: number }) => Promise<void>;
49
+ optimistic?: {
50
+ move?: (params: { fromIndex: number; toIndex: number }) => Promise<void> | void;
51
+ };
50
52
  };
51
53
 
52
- export function ImageGrid({ nodes, moveAction, disabled, ...props }: ImageGridProps) {
53
- const { onUpload, updateData, invalidateQuery } = useUploadZone();
54
+ export function ImageGrid({ nodes, moveAction, optimistic, disabled, ...props }: ImageGridProps) {
55
+ const uploadZone = useUploadZone();
54
56
 
55
57
  const images = nodes.flatMap((node) => ({ ...node, url: getFileUrl(node.id) }));
56
58
 
@@ -75,12 +77,12 @@ export function ImageGrid({ nodes, moveAction, disabled, ...props }: ImageGridPr
75
77
  const fromIndex = images.findIndex((image) => image.id === activeId);
76
78
  const toIndex = images.findIndex((image) => image.id === overId);
77
79
 
78
- await updateData((prev) => arrayMove(prev, { fromIndex, toIndex }));
80
+ await optimistic?.move?.({ fromIndex, toIndex });
79
81
  await moveAction({ fromIndex, toIndex });
80
82
  },
81
83
  onSuccess: async () => {
82
84
  setCurrent(0);
83
- await invalidateQuery();
85
+ await uploadZone.optimistic?.invalidate?.();
84
86
  },
85
87
  onError: (error) => {
86
88
  console.error("Error moving image:", error);
@@ -113,7 +115,7 @@ export function ImageGrid({ nodes, moveAction, disabled, ...props }: ImageGridPr
113
115
  multiple
114
116
  onChange={(e) => {
115
117
  if (!e.target.files) return;
116
- return Array.from(e.target.files).map(onUpload);
118
+ return Array.from(e.target.files).map(uploadZone.onUpload);
117
119
  }}
118
120
  />
119
121
  </label>
@@ -156,7 +158,7 @@ type ImageGridItemProps = {
156
158
  };
157
159
 
158
160
  function ImageGridItem({ node, index, setCurrent }: ImageGridItemProps) {
159
- const { uploadClient } = useUploadZone();
161
+ const uploadZone = useUploadZone();
160
162
 
161
163
  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: node.id });
162
164
 
@@ -198,7 +200,7 @@ function ImageGridItem({ node, index, setCurrent }: ImageGridItemProps) {
198
200
  type="button"
199
201
  variant="destructive"
200
202
  size="icon"
201
- onClick={() => uploadClient.deleteFiles([node.id])}
203
+ onClick={() => uploadZone.onRemove([node.id])}
202
204
  className="absolute left-2 top-2 hidden p-1 group-hover:flex"
203
205
  >
204
206
  <Icons.trash className="size-4" />
@@ -9,9 +9,16 @@ import { FileNode, Node } from "../lib/validators";
9
9
  */
10
10
  export type UploadZoneContextValue = {
11
11
  uploadClient: UploadClient;
12
- updateData: (newValue: FileNode[] | ((oldValue: FileNode[]) => FileNode[])) => Promise<void>;
13
- invalidateQuery: () => Promise<void> | void;
14
12
  onUpload: (file: File) => Promise<Node>;
13
+ onRemove: (ids: string[]) => Promise<void>;
14
+ optimistic?: {
15
+ add?: (newValue: FileNode) => Promise<void> | void;
16
+ remove?: (ids: string[]) => Promise<void> | void;
17
+ invalidate?: () => Promise<void> | void;
18
+ cancel?: () => Promise<void> | void;
19
+ };
20
+ // updateData: (newValue: FileNode[] | ((oldValue: FileNode[]) => FileNode[])) => Promise<void>;
21
+ // invalidateQuery: () => Promise<void> | void;
15
22
  };
16
23
 
17
24
  /**
@@ -1,74 +1,49 @@
1
1
  "use client";
2
2
 
3
- import { Input } from "@/components/ui/input";
4
3
  import { toast } from "@/components/ui/sonner.client";
5
- import { cn } from "@/lib/entry";
6
4
  import { useAction } from "@/lib/hooks/use-action";
7
- import { useQueryClient } from "@tanstack/react-query";
8
- import { ComponentProps, useCallback, useState } from "react";
9
- import { UploadClient, UploadFileRequest, UploadHooks } from "../lib/create-upload.client";
5
+ import { cn } from "@/lib/utils/cn";
6
+ import { ComponentProps, useCallback } from "react";
7
+ import { useDropzone } from "react-dropzone";
8
+ import { UploadFileRequest, UploadHooks } from "../lib/create-upload.client";
10
9
  import { FileNode, Node, UploadFileSchema } from "../lib/validators";
11
- import { UploadZoneContext } from "./upload-zone-context.client";
10
+ import { UploadZoneContext, UploadZoneContextValue } from "./upload-zone-context.client";
12
11
 
13
- export type UploadZoneProps = ComponentProps<"div"> & {
14
- queryKey: readonly unknown[];
12
+ export type UploadZoneProps = ComponentProps<"div"> &
13
+ Pick<UploadZoneContextValue, "optimistic" | "uploadClient"> & {
14
+ variables: Pick<UploadFileSchema, "namespace" | "parentId" | "mode" | "hidden" | "readonly">;
15
+ uploadHooks?: UploadHooks;
15
16
 
16
- variables: Pick<UploadFileSchema, "namespace" | "parentId" | "mode" | "hidden" | "readonly">;
17
- uploadClient: UploadClient;
18
- uploadHooks?: UploadHooks;
19
-
20
- onUploadCompleted?: (node: Node) => Promise<void> | void;
21
- onUploadFailed?: (error: unknown) => Promise<void> | void;
22
- };
17
+ onUploadCompleted?: (node: Node) => Promise<void> | void;
18
+ onUploadFailed?: (error: unknown) => Promise<void> | void;
19
+ };
23
20
 
24
21
  export function UploadZone({
25
22
  variables,
26
- queryKey,
23
+ optimistic,
27
24
  uploadClient,
28
25
  uploadHooks,
29
26
  onUploadCompleted,
30
27
  onUploadFailed,
31
28
  children,
32
29
  className,
33
- onDragOver,
34
- onDragLeave,
35
30
  ...props
36
31
  }: UploadZoneProps) {
37
- const queryClient = useQueryClient();
38
- const [isDragging, setIsDragging] = useState(false);
39
-
40
- /**
41
- * Optimisticly update the data
42
- */
43
- const updateData = useCallback(
44
- async (newValue: FileNode[] | ((oldValue: FileNode[]) => FileNode[])) => {
45
- await queryClient.cancelQueries({ queryKey });
46
- await queryClient.setQueryData(queryKey, newValue);
47
- },
48
- [queryClient, queryKey],
49
- );
50
-
51
- /**
52
- * Invalidate the query
53
- */
54
- const invalidateQuery = useCallback(async () => {
55
- await queryClient.invalidateQueries({ queryKey });
56
- }, [queryClient, queryKey]);
57
-
58
32
  /**
59
33
  * Delete mutation
60
34
  */
61
35
  const deleteMutation = useAction({
62
- mutationFn: async (params: { ids: string[] }) => uploadClient.deleteFiles(params.ids),
63
- onMutate: async (variables) => {
64
- await updateData((prev) => prev.filter((node) => !variables.ids.includes(node.id)));
65
- },
66
- onSuccess: async () => {
67
- await invalidateQuery();
36
+ mutationFn: async (ids: string[]) => uploadClient.deleteFiles(ids),
37
+ onMutate: async (ids) => {
38
+ await optimistic?.cancel?.();
39
+ await optimistic?.remove?.(ids);
68
40
  },
69
41
  onError: async (error) => {
70
- await onUploadFailed?.(error);
71
42
  console.error("Delete failed upload error: ", error);
43
+ await onUploadFailed?.(error);
44
+ },
45
+ onSettled: () => {
46
+ optimistic?.invalidate?.();
72
47
  },
73
48
  });
74
49
 
@@ -85,7 +60,8 @@ export function UploadZone({
85
60
  isPending: true,
86
61
  } as FileNode;
87
62
 
88
- await updateData((prev) => [...(prev ?? []), newNode]);
63
+ await optimistic?.cancel?.();
64
+ await optimistic?.add?.(newNode);
89
65
  },
90
66
  onSuccess: async (data) => {
91
67
  await onUploadCompleted?.(data);
@@ -100,10 +76,10 @@ export function UploadZone({
100
76
  });
101
77
 
102
78
  console.info("Deleting failed upload");
103
- await deleteMutation.mutateAsync({ ids: [variables.id] });
79
+ await deleteMutation.mutateAsync([variables.id]);
104
80
  },
105
81
  onSettled: () => {
106
- queryClient.invalidateQueries({ queryKey });
82
+ optimistic?.invalidate?.();
107
83
  },
108
84
  });
109
85
 
@@ -112,47 +88,43 @@ export function UploadZone({
112
88
  */
113
89
  const onUpload = useCallback(
114
90
  async (file: File) => {
91
+ console.info("Uploading file", file);
115
92
  const req = uploadClient.prepareUpload({ ...variables, file });
116
93
  return await uploadMutation.mutateAsync(req);
117
94
  },
118
95
  [uploadClient, variables, uploadMutation],
119
96
  );
120
97
 
121
- return (
122
- <div
123
- {...props}
124
- className={cn("relative z-0 flex-1 space-y-6", className)}
125
- onDragOver={(...args) => {
126
- setIsDragging(true);
127
- return onDragOver?.(...args);
128
- }}
129
- onDragLeave={(...args) => {
130
- setIsDragging(false);
131
- return onDragLeave?.(...args);
132
- }}
133
- >
134
- {isDragging && (
135
- <div className="border-primary bg-primary/20 absolute -inset-5 z-10 rounded-md border opacity-70 backdrop-blur-3xl">
136
- <Input
137
- multiple
138
- type="file"
139
- className="h-full w-full opacity-0"
140
- onChange={async (e) => {
141
- setIsDragging(false);
98
+ /**
99
+ * Drop handler
100
+ */
101
+ const onDrop = useCallback(
102
+ async (acceptedFiles: File[]) => {
103
+ if (acceptedFiles.length === 0) return;
104
+ await Promise.allSettled(acceptedFiles.map(onUpload));
105
+ },
106
+ [onUpload],
107
+ );
108
+
109
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, noClick: true });
142
110
 
143
- if (!e.target.files) return;
111
+ console.log("isDragActive", isDragActive);
144
112
 
145
- await Promise.allSettled(Array.from(e.target.files).map(onUpload));
146
- }}
147
- />
148
- </div>
113
+ return (
114
+ <div {...props} {...getRootProps()} className={cn("relative z-0", className)}>
115
+ <input {...getInputProps()} />
116
+
117
+ {/* Show drag overlay when drag is active */}
118
+ {isDragActive && (
119
+ <div className="bg-primary/20 border-primary absolute inset-0 z-10 rounded-md border opacity-70 backdrop-blur-3xl" />
149
120
  )}
121
+
150
122
  <UploadZoneContext
151
123
  value={{
152
124
  uploadClient,
153
125
  onUpload,
154
- updateData,
155
- invalidateQuery,
126
+ onRemove: deleteMutation.mutateAsync,
127
+ optimistic,
156
128
  }}
157
129
  >
158
130
  {children}