@questpie/admin 0.0.1 → 1.0.1

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 (250) hide show
  1. package/README.md +439 -424
  2. package/dist/auth-layout-M8K8_q5R.mjs +181 -0
  3. package/dist/auth-layout-M8K8_q5R.mjs.map +1 -0
  4. package/dist/bulk-upload-dialog-D7w7W1Hl.mjs +273 -0
  5. package/dist/bulk-upload-dialog-D7w7W1Hl.mjs.map +1 -0
  6. package/dist/{components/ui/card.mjs → card-BKHjBQfw.mjs} +8 -8
  7. package/dist/card-BKHjBQfw.mjs.map +1 -0
  8. package/dist/client/styles/index.css +434 -0
  9. package/dist/client-DbpZKSgH.d.mts +13585 -0
  10. package/dist/client-DbpZKSgH.d.mts.map +1 -0
  11. package/dist/client-njX1rZmi.mjs +22612 -0
  12. package/dist/client-njX1rZmi.mjs.map +1 -0
  13. package/dist/client.d.mts +3 -0
  14. package/dist/client.mjs +13 -0
  15. package/dist/content-locales-provider-BXvuIgfg.mjs +1650 -0
  16. package/dist/content-locales-provider-BXvuIgfg.mjs.map +1 -0
  17. package/dist/dashboard-page-B4PGEdc2.mjs +2500 -0
  18. package/dist/dashboard-page-B4PGEdc2.mjs.map +1 -0
  19. package/dist/dashboard-page-mCY0pgZv.mjs +3 -0
  20. package/dist/dropzone-Do3awXKd.mjs +634 -0
  21. package/dist/dropzone-Do3awXKd.mjs.map +1 -0
  22. package/dist/{views/auth/forgot-password-form.mjs → forgot-password-page-Bcp-An4Y.mjs} +87 -14
  23. package/dist/forgot-password-page-Bcp-An4Y.mjs.map +1 -0
  24. package/dist/forgot-password-page-CEwsdLwn.mjs +3 -0
  25. package/dist/index-B9Xwk4hi.d.mts +2753 -0
  26. package/dist/index-B9Xwk4hi.d.mts.map +1 -0
  27. package/dist/index.d.mts +3 -0
  28. package/dist/index.mjs +13 -0
  29. package/dist/login-page-BUnpCbCa.mjs +3 -0
  30. package/dist/login-page-CP4gA-dl.mjs +298 -0
  31. package/dist/login-page-CP4gA-dl.mjs.map +1 -0
  32. package/dist/preview-utils-BKQ9-TMa.mjs +65 -0
  33. package/dist/preview-utils-BKQ9-TMa.mjs.map +1 -0
  34. package/dist/{views/auth/reset-password-form.mjs → reset-password-page-BqfDmLxA.mjs} +111 -14
  35. package/dist/reset-password-page-BqfDmLxA.mjs.map +1 -0
  36. package/dist/reset-password-page-CufHz3h3.mjs +3 -0
  37. package/dist/runtime-6VZM878K.mjs +69 -0
  38. package/dist/runtime-6VZM878K.mjs.map +1 -0
  39. package/dist/saved-views.types-BMsz5mCy.d.mts +42 -0
  40. package/dist/saved-views.types-BMsz5mCy.d.mts.map +1 -0
  41. package/dist/server.d.mts +250 -0
  42. package/dist/server.d.mts.map +1 -0
  43. package/dist/server.mjs +832 -0
  44. package/dist/server.mjs.map +1 -0
  45. package/dist/setup-page-BNNzt_Z6.mjs +3 -0
  46. package/dist/setup-page-YAP_fzqh.mjs +264 -0
  47. package/dist/setup-page-YAP_fzqh.mjs.map +1 -0
  48. package/dist/shared.d.mts +57 -0
  49. package/dist/shared.d.mts.map +1 -0
  50. package/dist/shared.mjs +3 -0
  51. package/dist/{hooks/use-auth.mjs → use-auth-BoLmWtmU.mjs} +42 -30
  52. package/dist/use-auth-BoLmWtmU.mjs.map +1 -0
  53. package/package.json +48 -198
  54. package/.turbo/turbo-build.log +0 -108
  55. package/CHANGELOG.md +0 -10
  56. package/STATUS.md +0 -917
  57. package/VALIDATION.md +0 -602
  58. package/components.json +0 -24
  59. package/dist/__tests__/setup.mjs +0 -38
  60. package/dist/__tests__/test-utils.mjs +0 -45
  61. package/dist/__tests__/vitest.d.mjs +0 -3
  62. package/dist/components/admin-app.mjs +0 -69
  63. package/dist/components/fields/array-field.mjs +0 -190
  64. package/dist/components/fields/checkbox-field.mjs +0 -34
  65. package/dist/components/fields/custom-field.mjs +0 -32
  66. package/dist/components/fields/date-field.mjs +0 -41
  67. package/dist/components/fields/datetime-field.mjs +0 -42
  68. package/dist/components/fields/email-field.mjs +0 -37
  69. package/dist/components/fields/embedded-collection.mjs +0 -253
  70. package/dist/components/fields/field-types.mjs +0 -1
  71. package/dist/components/fields/field-utils.mjs +0 -10
  72. package/dist/components/fields/field-wrapper.mjs +0 -34
  73. package/dist/components/fields/index.mjs +0 -23
  74. package/dist/components/fields/json-field.mjs +0 -243
  75. package/dist/components/fields/locale-badge.mjs +0 -16
  76. package/dist/components/fields/number-field.mjs +0 -39
  77. package/dist/components/fields/password-field.mjs +0 -37
  78. package/dist/components/fields/relation-field.mjs +0 -104
  79. package/dist/components/fields/relation-picker.mjs +0 -229
  80. package/dist/components/fields/relation-select.mjs +0 -188
  81. package/dist/components/fields/rich-text-editor/index.mjs +0 -897
  82. package/dist/components/fields/select-field.mjs +0 -41
  83. package/dist/components/fields/switch-field.mjs +0 -34
  84. package/dist/components/fields/text-field.mjs +0 -38
  85. package/dist/components/fields/textarea-field.mjs +0 -38
  86. package/dist/components/index.mjs +0 -59
  87. package/dist/components/primitives/checkbox-input.mjs +0 -127
  88. package/dist/components/primitives/date-input.mjs +0 -303
  89. package/dist/components/primitives/index.mjs +0 -12
  90. package/dist/components/primitives/number-input.mjs +0 -104
  91. package/dist/components/primitives/select-input.mjs +0 -177
  92. package/dist/components/primitives/tag-input.mjs +0 -135
  93. package/dist/components/primitives/text-input.mjs +0 -39
  94. package/dist/components/primitives/textarea-input.mjs +0 -37
  95. package/dist/components/primitives/toggle-input.mjs +0 -31
  96. package/dist/components/primitives/types.mjs +0 -12
  97. package/dist/components/ui/accordion.mjs +0 -55
  98. package/dist/components/ui/avatar.mjs +0 -54
  99. package/dist/components/ui/badge.mjs +0 -34
  100. package/dist/components/ui/button.mjs +0 -48
  101. package/dist/components/ui/checkbox.mjs +0 -21
  102. package/dist/components/ui/combobox.mjs +0 -163
  103. package/dist/components/ui/dialog.mjs +0 -95
  104. package/dist/components/ui/dropdown-menu.mjs +0 -138
  105. package/dist/components/ui/field.mjs +0 -113
  106. package/dist/components/ui/input-group.mjs +0 -82
  107. package/dist/components/ui/input.mjs +0 -17
  108. package/dist/components/ui/label.mjs +0 -15
  109. package/dist/components/ui/popover.mjs +0 -56
  110. package/dist/components/ui/scroll-area.mjs +0 -38
  111. package/dist/components/ui/select.mjs +0 -100
  112. package/dist/components/ui/separator.mjs +0 -16
  113. package/dist/components/ui/sheet.mjs +0 -90
  114. package/dist/components/ui/sidebar.mjs +0 -387
  115. package/dist/components/ui/skeleton.mjs +0 -14
  116. package/dist/components/ui/spinner.mjs +0 -16
  117. package/dist/components/ui/switch.mjs +0 -22
  118. package/dist/components/ui/table.mjs +0 -68
  119. package/dist/components/ui/tabs.mjs +0 -48
  120. package/dist/components/ui/textarea.mjs +0 -15
  121. package/dist/components/ui/tooltip.mjs +0 -44
  122. package/dist/config/component-registry.mjs +0 -38
  123. package/dist/config/index.mjs +0 -129
  124. package/dist/hooks/admin-provider.mjs +0 -70
  125. package/dist/hooks/index.mjs +0 -7
  126. package/dist/hooks/store.mjs +0 -178
  127. package/dist/hooks/use-collection-db.mjs +0 -146
  128. package/dist/hooks/use-collection.mjs +0 -112
  129. package/dist/hooks/use-global.mjs +0 -46
  130. package/dist/hooks/use-mobile.mjs +0 -20
  131. package/dist/lib/utils.mjs +0 -10
  132. package/dist/styles/index.css +0 -336
  133. package/dist/styles/index.mjs +0 -1
  134. package/dist/utils/index.mjs +0 -9
  135. package/dist/views/auth/auth-layout.mjs +0 -52
  136. package/dist/views/auth/index.mjs +0 -6
  137. package/dist/views/auth/login-form.mjs +0 -156
  138. package/dist/views/collection/auto-form-fields.mjs +0 -525
  139. package/dist/views/collection/collection-form.mjs +0 -91
  140. package/dist/views/collection/collection-list.mjs +0 -76
  141. package/dist/views/collection/form-field.mjs +0 -42
  142. package/dist/views/collection/index.mjs +0 -6
  143. package/dist/views/common/index.mjs +0 -4
  144. package/dist/views/common/locale-switcher.mjs +0 -39
  145. package/dist/views/common/version-history.mjs +0 -272
  146. package/dist/views/index.mjs +0 -9
  147. package/dist/views/layout/admin-layout.mjs +0 -40
  148. package/dist/views/layout/admin-router.mjs +0 -95
  149. package/dist/views/layout/admin-sidebar.mjs +0 -63
  150. package/dist/views/layout/index.mjs +0 -5
  151. package/src/__tests__/setup.ts +0 -44
  152. package/src/__tests__/test-utils.tsx +0 -49
  153. package/src/__tests__/vitest.d.ts +0 -9
  154. package/src/components/admin-app.tsx +0 -221
  155. package/src/components/fields/array-field.tsx +0 -237
  156. package/src/components/fields/checkbox-field.tsx +0 -47
  157. package/src/components/fields/custom-field.tsx +0 -50
  158. package/src/components/fields/date-field.tsx +0 -65
  159. package/src/components/fields/datetime-field.tsx +0 -67
  160. package/src/components/fields/email-field.tsx +0 -51
  161. package/src/components/fields/embedded-collection.tsx +0 -315
  162. package/src/components/fields/field-types.ts +0 -162
  163. package/src/components/fields/field-utils.ts +0 -6
  164. package/src/components/fields/field-wrapper.tsx +0 -52
  165. package/src/components/fields/index.ts +0 -66
  166. package/src/components/fields/json-field.tsx +0 -440
  167. package/src/components/fields/locale-badge.tsx +0 -15
  168. package/src/components/fields/number-field.tsx +0 -57
  169. package/src/components/fields/password-field.tsx +0 -51
  170. package/src/components/fields/relation-field.tsx +0 -243
  171. package/src/components/fields/relation-picker.tsx +0 -402
  172. package/src/components/fields/relation-select.tsx +0 -327
  173. package/src/components/fields/rich-text-editor/index.tsx +0 -1337
  174. package/src/components/fields/select-field.tsx +0 -61
  175. package/src/components/fields/switch-field.tsx +0 -47
  176. package/src/components/fields/text-field.tsx +0 -55
  177. package/src/components/fields/textarea-field.tsx +0 -55
  178. package/src/components/index.ts +0 -40
  179. package/src/components/primitives/checkbox-input.tsx +0 -193
  180. package/src/components/primitives/date-input.tsx +0 -401
  181. package/src/components/primitives/index.ts +0 -24
  182. package/src/components/primitives/number-input.tsx +0 -132
  183. package/src/components/primitives/select-input.tsx +0 -296
  184. package/src/components/primitives/tag-input.tsx +0 -200
  185. package/src/components/primitives/text-input.tsx +0 -49
  186. package/src/components/primitives/textarea-input.tsx +0 -46
  187. package/src/components/primitives/toggle-input.tsx +0 -36
  188. package/src/components/primitives/types.ts +0 -235
  189. package/src/components/ui/accordion.tsx +0 -72
  190. package/src/components/ui/avatar.tsx +0 -106
  191. package/src/components/ui/badge.tsx +0 -48
  192. package/src/components/ui/button.tsx +0 -53
  193. package/src/components/ui/card.tsx +0 -94
  194. package/src/components/ui/checkbox.tsx +0 -27
  195. package/src/components/ui/combobox.tsx +0 -290
  196. package/src/components/ui/dialog.tsx +0 -151
  197. package/src/components/ui/dropdown-menu.tsx +0 -254
  198. package/src/components/ui/field.tsx +0 -227
  199. package/src/components/ui/input-group.tsx +0 -149
  200. package/src/components/ui/input.tsx +0 -20
  201. package/src/components/ui/label.tsx +0 -18
  202. package/src/components/ui/popover.tsx +0 -88
  203. package/src/components/ui/scroll-area.tsx +0 -53
  204. package/src/components/ui/select.tsx +0 -192
  205. package/src/components/ui/separator.tsx +0 -23
  206. package/src/components/ui/sheet.tsx +0 -127
  207. package/src/components/ui/sidebar.tsx +0 -723
  208. package/src/components/ui/skeleton.tsx +0 -13
  209. package/src/components/ui/spinner.tsx +0 -10
  210. package/src/components/ui/switch.tsx +0 -32
  211. package/src/components/ui/table.tsx +0 -99
  212. package/src/components/ui/tabs.tsx +0 -82
  213. package/src/components/ui/textarea.tsx +0 -18
  214. package/src/components/ui/tooltip.tsx +0 -70
  215. package/src/config/component-registry.ts +0 -190
  216. package/src/config/index.ts +0 -1099
  217. package/src/hooks/README.md +0 -269
  218. package/src/hooks/admin-provider.tsx +0 -110
  219. package/src/hooks/index.ts +0 -41
  220. package/src/hooks/store.ts +0 -248
  221. package/src/hooks/use-auth.ts +0 -168
  222. package/src/hooks/use-collection-db.ts +0 -209
  223. package/src/hooks/use-collection.ts +0 -156
  224. package/src/hooks/use-global.ts +0 -69
  225. package/src/hooks/use-mobile.ts +0 -21
  226. package/src/lib/utils.ts +0 -6
  227. package/src/styles/index.css +0 -340
  228. package/src/utils/index.ts +0 -6
  229. package/src/views/auth/auth-layout.tsx +0 -77
  230. package/src/views/auth/forgot-password-form.tsx +0 -192
  231. package/src/views/auth/index.ts +0 -21
  232. package/src/views/auth/login-form.tsx +0 -229
  233. package/src/views/auth/reset-password-form.tsx +0 -232
  234. package/src/views/collection/auto-form-fields.tsx +0 -982
  235. package/src/views/collection/collection-form.tsx +0 -186
  236. package/src/views/collection/collection-list.tsx +0 -223
  237. package/src/views/collection/form-field.tsx +0 -52
  238. package/src/views/collection/index.ts +0 -15
  239. package/src/views/common/index.ts +0 -8
  240. package/src/views/common/locale-switcher.tsx +0 -45
  241. package/src/views/common/version-history.tsx +0 -406
  242. package/src/views/index.ts +0 -25
  243. package/src/views/layout/admin-layout.tsx +0 -117
  244. package/src/views/layout/admin-router.tsx +0 -206
  245. package/src/views/layout/admin-sidebar.tsx +0 -185
  246. package/src/views/layout/index.ts +0 -12
  247. package/tsconfig.json +0 -13
  248. package/tsconfig.tsbuildinfo +0 -1
  249. package/tsdown.config.ts +0 -13
  250. package/vitest.config.ts +0 -29
@@ -1,168 +0,0 @@
1
- /**
2
- * Auth client utilities for admin package
3
- *
4
- * Better Auth handles all auth state management internally.
5
- * This module provides type-safe client creation helpers with
6
- * full type inference from your CMS auth configuration.
7
- *
8
- * @example
9
- * ```tsx
10
- * // In your app, create the auth client once:
11
- * import { createAdminAuthClient } from '@questpie/admin/hooks'
12
- * import type { cms } from './server/cms'
13
- *
14
- * export const authClient = createAdminAuthClient<typeof cms>({
15
- * baseURL: 'http://localhost:3000'
16
- * })
17
- *
18
- * // Then use the built-in hooks:
19
- * function MyComponent() {
20
- * const { data: session, isPending, error } = authClient.useSession()
21
- *
22
- * if (isPending) return <div>Loading...</div>
23
- * if (!session) return <LoginForm />
24
- *
25
- * return <div>Welcome {session.user.name}</div>
26
- * }
27
- * ```
28
- */
29
-
30
- import { createAuthClient } from "better-auth/react";
31
- import type { Questpie } from "questpie";
32
- import type { BetterAuthOptions } from "better-auth";
33
-
34
- /**
35
- * Extract auth options type from Questpie instance
36
- */
37
- type ExtractAuthOptions<T extends Questpie<any>> =
38
- T extends Questpie<infer TConfig>
39
- ? TConfig["auth"] extends BetterAuthOptions
40
- ? TConfig["auth"]
41
- : BetterAuthOptions
42
- : BetterAuthOptions;
43
-
44
- /**
45
- * Options for creating admin auth client
46
- */
47
- export type AdminAuthClientOptions = {
48
- /**
49
- * Base URL of the CMS API
50
- * @example 'http://localhost:3000'
51
- */
52
- baseURL: string;
53
-
54
- /**
55
- * Base path for auth routes
56
- * @default '/cms/auth'
57
- */
58
- basePath?: string;
59
-
60
- /**
61
- * Custom fetch implementation
62
- */
63
- fetchOptions?: {
64
- credentials?: RequestCredentials;
65
- headers?: Record<string, string>;
66
- };
67
- };
68
-
69
- /**
70
- * Internal client options type that includes $InferAuth
71
- */
72
- type InternalClientOptions<T extends Questpie<any>> = {
73
- baseURL: string;
74
- fetchOptions?: {
75
- credentials?: RequestCredentials;
76
- headers?: Record<string, string>;
77
- };
78
- $InferAuth: ExtractAuthOptions<T>;
79
- };
80
-
81
- /**
82
- * Create a type-safe Better Auth client for the admin UI
83
- *
84
- * The returned client includes full type inference from your CMS auth configuration:
85
- * - `useSession()` - React hook for session state (typed based on your user/session schema)
86
- * - `signIn` methods (email, social providers configured in CMS)
87
- * - `signOut` - Sign out the current user
88
- * - `signUp` - Register new users
89
- * - Plugin-specific hooks (e.g., `useListAccounts` for admin plugin)
90
- *
91
- * @example
92
- * ```tsx
93
- * import { createAdminAuthClient } from '@questpie/admin/hooks'
94
- * import type { cms } from './server/cms'
95
- *
96
- * // Create client with type inference from your CMS
97
- * export const authClient = createAdminAuthClient<typeof cms>({
98
- * baseURL: 'http://localhost:3000'
99
- * })
100
- *
101
- * // Session data is fully typed based on your CMS auth config
102
- * function App() {
103
- * const { data: session, isPending } = authClient.useSession()
104
- *
105
- * if (isPending) return <Loading />
106
- * if (!session) return <LoginPage authClient={authClient} />
107
- *
108
- * // session.user has all fields from your user schema
109
- * return <AdminDashboard user={session.user} />
110
- * }
111
- * ```
112
- */
113
- export function createAdminAuthClient<T extends Questpie<any>>(
114
- options: AdminAuthClientOptions,
115
- ): ReturnType<typeof createAuthClient<InternalClientOptions<T>>> {
116
- const basePath = options.basePath ?? "/cms/auth";
117
-
118
- return createAuthClient<InternalClientOptions<T>>({
119
- baseURL: `${options.baseURL}${basePath}`,
120
- fetchOptions: {
121
- credentials: options.fetchOptions?.credentials ?? "include",
122
- headers: options.fetchOptions?.headers,
123
- },
124
- } as InternalClientOptions<T>);
125
- }
126
-
127
- /**
128
- * Type helper to extract auth client type from CMS instance
129
- *
130
- * @example
131
- * ```tsx
132
- * import type { AdminAuthClient } from '@questpie/admin/hooks'
133
- * import type { cms } from './server/cms'
134
- *
135
- * type MyAuthClient = AdminAuthClient<typeof cms>
136
- * ```
137
- */
138
- export type AdminAuthClient<T extends Questpie<any>> = ReturnType<
139
- typeof createAdminAuthClient<T>
140
- >;
141
-
142
- /**
143
- * Type helper to extract session type from auth client
144
- *
145
- * @example
146
- * ```tsx
147
- * import type { AdminSession } from '@questpie/admin/hooks'
148
- * import type { cms } from './server/cms'
149
- *
150
- * type MySession = AdminSession<typeof cms>
151
- * // Includes: { user: { id, email, name, role, ... }, session: { ... } }
152
- * ```
153
- */
154
- export type AdminSession<T extends Questpie<any>> =
155
- AdminAuthClient<T>["$Infer"]["Session"];
156
-
157
- /**
158
- * Type helper to extract user type from CMS auth configuration
159
- *
160
- * @example
161
- * ```tsx
162
- * import type { AdminUser } from '@questpie/admin/hooks'
163
- * import type { cms } from './server/cms'
164
- *
165
- * type MyUser = AdminUser<typeof cms>
166
- * ```
167
- */
168
- export type AdminUser<T extends Questpie<any>> = AdminSession<T>["user"];
@@ -1,209 +0,0 @@
1
- import { useMemo } from "react";
2
- import type { Collection } from "@tanstack/db";
3
- import type { QuestpieClient } from "questpie/client";
4
- import type { Questpie } from "questpie";
5
- import { createQuestpieDBHelpers } from "@questpie/tanstack-query/db";
6
- import { useAdminContext } from "./admin-provider";
7
- import { useQueryClient } from "@tanstack/react-query";
8
-
9
- /**
10
- * Collection item type helper
11
- * Extracts the item type from a collection's find method return type
12
- */
13
- type CollectionItem<
14
- T extends Questpie<any>,
15
- K extends keyof QuestpieClient<T>["collections"],
16
- > = Awaited<ReturnType<QuestpieClient<T>["collections"][K]["find"]>> extends {
17
- docs: Array<infer TItem extends object>;
18
- }
19
- ? TItem
20
- : Record<string, unknown>;
21
-
22
- /**
23
- * Hook to get TanStack DB Collection for a CMS collection
24
- * Provides offline-first, realtime-synced collection with optimistic updates
25
- *
26
- * @example
27
- * ```tsx
28
- * function PostsList() {
29
- * const posts = useCollection('posts', {
30
- * baseFindOptions: { where: { published: { eq: true } } },
31
- * realtime: true, // Enable realtime sync
32
- * })
33
- *
34
- * return (
35
- * <div>
36
- * {posts.items.map(post => (
37
- * <div key={post.id}>{post.title}</div>
38
- * ))}
39
- * </div>
40
- * )
41
- * }
42
- * ```
43
- */
44
- export function useCollection<
45
- T extends Questpie<any>,
46
- K extends keyof QuestpieClient<T>["collections"],
47
- >(
48
- collectionName: K,
49
- options?: {
50
- /**
51
- * Base query options (filters, sorting, relations)
52
- */
53
- baseFindOptions?: Parameters<QuestpieClient<T>["collections"][K]["find"]>[0];
54
- /**
55
- * Enable realtime sync via SSE
56
- */
57
- realtime?:
58
- | boolean
59
- | {
60
- enabled?: boolean;
61
- baseURL?: string;
62
- basePath?: string;
63
- };
64
- /**
65
- * Custom key extractor (defaults to 'id')
66
- */
67
- getKey?: (item: CollectionItem<T, K>) => string | number;
68
- },
69
- ): Collection<CollectionItem<T, K>, string | number> {
70
- const { client, locale } = useAdminContext<T>();
71
- const queryClient = useQueryClient();
72
- const localeKey = locale ?? "default";
73
-
74
- const collection = useMemo(() => {
75
- const dbHelpers = createQuestpieDBHelpers(client, {
76
- keyPrefix: ["qcms", "locale", localeKey],
77
- });
78
- const collectionHelper = dbHelpers.collections[collectionName as string];
79
-
80
- if (!collectionHelper) {
81
- throw new Error(
82
- `Collection "${String(collectionName)}" not found in CMS`,
83
- );
84
- }
85
-
86
- return collectionHelper.createCollection({
87
- queryClient,
88
- getKey: options?.getKey ?? ((item: any) => item.id),
89
- baseFindOptions: options?.baseFindOptions,
90
- realtime: options?.realtime ?? false,
91
- } as any);
92
- }, [
93
- client,
94
- queryClient,
95
- collectionName,
96
- localeKey,
97
- options?.baseFindOptions,
98
- options?.realtime,
99
- options?.getKey,
100
- ]);
101
-
102
- return collection as Collection<CollectionItem<T, K>, string | number>;
103
- }
104
-
105
- /**
106
- * Hook to get a single item from collection by ID
107
- * Uses TanStack DB Collection for offline-first access
108
- *
109
- * @example
110
- * ```tsx
111
- * function PostDetail({ id }: { id: string }) {
112
- * const posts = useCollection('posts')
113
- * const post = useCollectionItemById(posts, id)
114
- *
115
- * if (!post) return <div>Loading...</div>
116
- *
117
- * return <div>{post.title}</div>
118
- * }
119
- * ```
120
- */
121
- export function useCollectionItemById<TItem extends object>(
122
- collection: Collection<TItem, string | number>,
123
- id: string | number,
124
- ): TItem | undefined {
125
- return collection.toArray.find(
126
- (item) => collection.config.getKey(item) === id,
127
- );
128
- }
129
-
130
- /**
131
- * Hook to create item in collection
132
- * Uses TanStack DB Collection with optimistic updates
133
- *
134
- * @example
135
- * ```tsx
136
- * function CreatePost() {
137
- * const posts = useCollection('posts')
138
- *
139
- * const handleCreate = async () => {
140
- * await posts.insert({
141
- * title: 'New Post',
142
- * content: 'Hello World'
143
- * })
144
- * }
145
- *
146
- * return <button onClick={handleCreate}>Create Post</button>
147
- * }
148
- * ```
149
- */
150
- export function useCollectionInsert<
151
- T extends Questpie<any>,
152
- K extends keyof QuestpieClient<T>["collections"],
153
- >(collectionName: K): any {
154
- const collection = useCollection<T, K>(collectionName);
155
- return collection.insert.bind(collection);
156
- }
157
-
158
- /**
159
- * Hook to update item in collection
160
- * Uses TanStack DB Collection with optimistic updates
161
- *
162
- * @example
163
- * ```tsx
164
- * function EditPost({ id }: { id: string }) {
165
- * const posts = useCollection('posts')
166
- * const post = useCollectionItemById(posts, id)
167
- *
168
- * const handleUpdate = async () => {
169
- * await posts.update(id, {
170
- * title: 'Updated Title'
171
- * })
172
- * }
173
- *
174
- * return <button onClick={handleUpdate}>Update</button>
175
- * }
176
- * ```
177
- */
178
- export function useCollectionUpdate<
179
- T extends Questpie<any>,
180
- K extends keyof QuestpieClient<T>["collections"],
181
- >(collectionName: K): any {
182
- const collection = useCollection<T, K>(collectionName);
183
- return collection.update.bind(collection);
184
- }
185
-
186
- /**
187
- * Hook to delete item from collection
188
- * Uses TanStack DB Collection with optimistic updates
189
- *
190
- * @example
191
- * ```tsx
192
- * function DeletePost({ id }: { id: string }) {
193
- * const posts = useCollection('posts')
194
- *
195
- * const handleDelete = async () => {
196
- * await posts.delete(id)
197
- * }
198
- *
199
- * return <button onClick={handleDelete}>Delete</button>
200
- * }
201
- * ```
202
- */
203
- export function useCollectionDelete<
204
- T extends Questpie<any>,
205
- K extends keyof QuestpieClient<T>["collections"],
206
- >(collectionName: K): any {
207
- const collection = useCollection<T, K>(collectionName);
208
- return collection.delete.bind(collection);
209
- }
@@ -1,156 +0,0 @@
1
- import {
2
- useQuery,
3
- useMutation,
4
- useQueryClient,
5
- type UseQueryOptions,
6
- type UseMutationOptions,
7
- } from "@tanstack/react-query";
8
- import type { QuestpieClient } from "questpie/client";
9
- import type { Questpie } from "questpie";
10
- import { createQuestpieQueryOptions } from "@questpie/tanstack-query";
11
-
12
- import { useAdminContext } from "./admin-provider";
13
-
14
- /**
15
- * Hook to fetch collection list with filters, sorting, pagination
16
- */
17
- export function useCollectionList<
18
- T extends Questpie<any>,
19
- K extends keyof QuestpieClient<T>["collections"],
20
- >(
21
- collection: K,
22
- options?: Parameters<QuestpieClient<T>["collections"][K]["find"]>[0],
23
- queryOptions?: Omit<UseQueryOptions, "queryKey" | "queryFn">,
24
- ): any {
25
- const { client, locale } = useAdminContext<T>();
26
- const localeKey = locale ?? "default";
27
- const keyPrefix = ["qcms", "locale", localeKey] as const;
28
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
29
-
30
- return useQuery({
31
- ...queryOpts.collections[collection as string].find(options as any),
32
- ...queryOptions,
33
- });
34
- }
35
-
36
- /**
37
- * Hook to fetch single collection item
38
- */
39
- export function useCollectionItem<
40
- T extends Questpie<any>,
41
- K extends keyof QuestpieClient<T>["collections"],
42
- >(
43
- collection: K,
44
- id: string,
45
- options?: Omit<
46
- Parameters<QuestpieClient<T>["collections"][K]["findOne"]>[0],
47
- "where"
48
- >,
49
- queryOptions?: Omit<UseQueryOptions, "queryKey" | "queryFn">,
50
- ): any {
51
- const { client, locale } = useAdminContext<T>();
52
- const localeKey = locale ?? "default";
53
- const keyPrefix = ["qcms", "locale", localeKey] as const;
54
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
55
-
56
- return useQuery({
57
- ...queryOpts.collections[collection as string].findOne({
58
- where: { id },
59
- ...options,
60
- } as any),
61
- ...queryOptions,
62
- });
63
- }
64
-
65
- /**
66
- * Hook to create collection item
67
- */
68
- export function useCollectionCreate<
69
- T extends Questpie<any>,
70
- K extends keyof QuestpieClient<T>["collections"],
71
- >(
72
- collection: K,
73
- mutationOptions?: Omit<UseMutationOptions, "mutationFn">,
74
- ): any {
75
- const { client, locale } = useAdminContext<T>();
76
- const queryClient = useQueryClient();
77
- const localeKey = locale ?? "default";
78
- const keyPrefix = ["qcms", "locale", localeKey] as const;
79
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
80
-
81
- const baseOptions = queryOpts.collections[collection as string].create();
82
-
83
- return useMutation({
84
- ...baseOptions,
85
- onSuccess: (data: any, variables: any, context: any) => {
86
- // Invalidate list queries
87
- queryClient.invalidateQueries({
88
- queryKey: [...keyPrefix, "collections", collection, "find"],
89
- });
90
- (mutationOptions?.onSuccess as any)?.(data, variables, context);
91
- },
92
- ...mutationOptions,
93
- } as any);
94
- }
95
-
96
- /**
97
- * Hook to update collection item
98
- */
99
- export function useCollectionUpdate<
100
- T extends Questpie<any>,
101
- K extends keyof QuestpieClient<T>["collections"],
102
- >(
103
- collection: K,
104
- mutationOptions?: Omit<UseMutationOptions, "mutationFn">,
105
- ): any {
106
- const { client, locale } = useAdminContext<T>();
107
- const queryClient = useQueryClient();
108
- const localeKey = locale ?? "default";
109
- const keyPrefix = ["qcms", "locale", localeKey] as const;
110
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
111
-
112
- const baseOptions = queryOpts.collections[collection as string].update();
113
-
114
- return useMutation({
115
- ...baseOptions,
116
- onSuccess: (data: any, variables: any, context: any) => {
117
- // Invalidate list and detail queries
118
- queryClient.invalidateQueries({
119
- queryKey: [...keyPrefix, "collections", collection],
120
- });
121
- (mutationOptions?.onSuccess as any)?.(data, variables, context);
122
- },
123
- ...mutationOptions,
124
- } as any);
125
- }
126
-
127
- /**
128
- * Hook to delete collection item
129
- */
130
- export function useCollectionDelete<
131
- T extends Questpie<any>,
132
- K extends keyof QuestpieClient<T>["collections"],
133
- >(
134
- collection: K,
135
- mutationOptions?: Omit<UseMutationOptions, "mutationFn">,
136
- ): any {
137
- const { client, locale } = useAdminContext<T>();
138
- const queryClient = useQueryClient();
139
- const localeKey = locale ?? "default";
140
- const keyPrefix = ["qcms", "locale", localeKey] as const;
141
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
142
-
143
- const baseOptions = queryOpts.collections[collection as string].delete();
144
-
145
- return useMutation({
146
- ...baseOptions,
147
- onSuccess: (data: any, variables: any, context: any) => {
148
- // Invalidate list queries
149
- queryClient.invalidateQueries({
150
- queryKey: [...keyPrefix, "collections", collection],
151
- });
152
- (mutationOptions?.onSuccess as any)?.(data, variables, context);
153
- },
154
- ...mutationOptions,
155
- } as any);
156
- }
@@ -1,69 +0,0 @@
1
- import {
2
- useQuery,
3
- useMutation,
4
- useQueryClient,
5
- type UseQueryOptions,
6
- type UseMutationOptions,
7
- } from "@tanstack/react-query";
8
- import type { QuestpieClient } from "questpie/client";
9
- import type { Questpie } from "questpie";
10
- import { createQuestpieQueryOptions } from "@questpie/tanstack-query";
11
- import { useAdminContext } from "./admin-provider";
12
-
13
- /**
14
- * Hook to fetch global settings
15
- */
16
- export function useGlobal<
17
- T extends Questpie<any>,
18
- K extends keyof QuestpieClient<T>["globals"],
19
- >(
20
- globalName: K,
21
- options?: Parameters<QuestpieClient<T>["globals"][K]["get"]>[0],
22
- queryOptions?: Omit<UseQueryOptions, "queryKey" | "queryFn">,
23
- ): any {
24
- const { client, locale } = useAdminContext<T>();
25
- const localeKey = locale ?? "default";
26
- const keyPrefix = ["qcms", "locale", localeKey] as const;
27
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
28
-
29
- return useQuery({
30
- ...queryOpts.globals[globalName as string].get(options as any),
31
- ...queryOptions,
32
- });
33
- }
34
-
35
- /**
36
- * Hook to update global settings
37
- */
38
- export function useGlobalUpdate<
39
- T extends Questpie<any>,
40
- K extends keyof QuestpieClient<T>["globals"],
41
- >(
42
- globalName: K,
43
- mutationOptions?: UseMutationOptions<
44
- Awaited<ReturnType<QuestpieClient<T>["globals"][K]["update"]>>,
45
- Error,
46
- {
47
- data: Parameters<QuestpieClient<T>["globals"][K]["update"]>[0];
48
- options?: Parameters<QuestpieClient<T>["globals"][K]["update"]>[1];
49
- }
50
- >,
51
- ): any {
52
- const { client, locale } = useAdminContext<T>();
53
- const queryClient = useQueryClient();
54
- const localeKey = locale ?? "default";
55
- const keyPrefix = ["qcms", "locale", localeKey] as const;
56
- const queryOpts = createQuestpieQueryOptions(client, { keyPrefix });
57
-
58
- return useMutation({
59
- ...queryOpts.globals[globalName as string].update(),
60
- onSuccess: (...args) => {
61
- // Invalidate global queries
62
- queryClient.invalidateQueries({
63
- queryKey: [...keyPrefix, "globals", globalName],
64
- });
65
- mutationOptions?.onSuccess?.(...args);
66
- },
67
- ...mutationOptions,
68
- });
69
- }
@@ -1,21 +0,0 @@
1
- import * as React from "react";
2
-
3
- const MOBILE_BREAKPOINT = 768;
4
-
5
- export function useIsMobile() {
6
- const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
7
- undefined,
8
- );
9
-
10
- React.useEffect(() => {
11
- const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
12
- const onChange = () => {
13
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
14
- };
15
- mql.addEventListener("change", onChange);
16
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
17
- return () => mql.removeEventListener("change", onChange);
18
- }, []);
19
-
20
- return !!isMobile;
21
- }
package/src/lib/utils.ts DELETED
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from "clsx";
2
- import { twMerge } from "tailwind-merge";
3
-
4
- export function cn(...inputs: ClassValue[]): string {
5
- return twMerge(clsx(inputs));
6
- }