convex-cms 0.0.5-alpha.2 → 0.0.5-alpha.4

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 (95) hide show
  1. package/README.md +44 -9
  2. package/admin/src/components/BulkActionBar.tsx +4 -4
  3. package/admin/src/components/ContentEntryEditor.tsx +8 -28
  4. package/admin/src/components/ContentTypeFormModal.tsx +2 -2
  5. package/admin/src/components/TaxonomyEditor.tsx +2 -2
  6. package/admin/src/components/TermTree.tsx +5 -5
  7. package/admin/src/components/VersionCompare.tsx +1 -1
  8. package/admin/src/components/VersionHistory.tsx +2 -2
  9. package/admin/src/components/fields/CategoryField.tsx +1 -1
  10. package/admin/src/components/fields/MediaField.tsx +4 -4
  11. package/admin/src/components/fields/ReferenceField.tsx +4 -4
  12. package/admin/src/components/fields/TagField.tsx +3 -3
  13. package/admin/src/components/filters/TaxonomyFilter.tsx +2 -2
  14. package/admin/src/components/media/MediaAssetEditDialog.tsx +2 -2
  15. package/admin/src/components/media/MediaFolderEditDialog.tsx +1 -1
  16. package/admin/src/components/media/MediaMoveModal.tsx +2 -2
  17. package/admin/src/components/media/MediaTaxonomyPicker.tsx +4 -4
  18. package/admin/src/contexts/SettingsConfigContext.tsx +2 -2
  19. package/admin/src/pages/MediaPage.tsx +1102 -8
  20. package/admin/src/pages/SettingsPage.tsx +171 -108
  21. package/admin/src/routes/entries/$entryId.tsx +2 -2
  22. package/admin/src/routes/entries/new.$contentTypeId.tsx +1 -1
  23. package/admin/src/routes/entries/type/$contentTypeId.tsx +6 -6
  24. package/admin/src/routes/media.tsx +23 -1094
  25. package/admin-dist/nitro.json +1 -1
  26. package/admin-dist/server/index.mjs +138 -138
  27. package/dist/cli/index.js +0 -0
  28. package/dist/client/admin/index.d.ts +75 -2
  29. package/dist/client/admin/index.d.ts.map +1 -1
  30. package/dist/client/admin/index.js +17 -1
  31. package/dist/client/admin/index.js.map +1 -1
  32. package/dist/client/admin/media.d.ts.map +1 -1
  33. package/dist/client/admin/media.js +3 -3
  34. package/dist/client/admin/media.js.map +1 -1
  35. package/dist/client/admin/settings.d.ts +50 -0
  36. package/dist/client/admin/settings.d.ts.map +1 -0
  37. package/dist/client/admin/settings.js +89 -0
  38. package/dist/client/admin/settings.js.map +1 -0
  39. package/dist/client/admin/taxonomies.d.ts.map +1 -1
  40. package/dist/client/admin/trash.d.ts.map +1 -1
  41. package/dist/client/admin/types.d.ts +40 -0
  42. package/dist/client/admin/types.d.ts.map +1 -1
  43. package/dist/client/admin/validators.d.ts +243 -3
  44. package/dist/client/admin/validators.d.ts.map +1 -1
  45. package/dist/client/admin/validators.js +18 -0
  46. package/dist/client/admin/validators.js.map +1 -1
  47. package/dist/client/adminConfig.d.ts +1 -1
  48. package/dist/client/config.d.ts +145 -0
  49. package/dist/client/config.d.ts.map +1 -0
  50. package/dist/client/config.js +132 -0
  51. package/dist/client/config.js.map +1 -0
  52. package/dist/client/index.d.ts +3 -1
  53. package/dist/client/index.d.ts.map +1 -1
  54. package/dist/client/index.js +13 -6
  55. package/dist/client/index.js.map +1 -1
  56. package/dist/client/schema/defineContentType.js +1 -1
  57. package/dist/client/schema/defineContentType.js.map +1 -1
  58. package/dist/client/wrapper.d.ts.map +1 -1
  59. package/dist/client/wrapper.js +0 -4
  60. package/dist/client/wrapper.js.map +1 -1
  61. package/dist/component/_generated/api.d.ts +2 -0
  62. package/dist/component/_generated/api.d.ts.map +1 -1
  63. package/dist/component/_generated/api.js.map +1 -1
  64. package/dist/component/_generated/component.d.ts +42 -0
  65. package/dist/component/_generated/component.d.ts.map +1 -1
  66. package/dist/component/contentEntries.d.ts.map +1 -1
  67. package/dist/component/contentEntries.js +0 -2
  68. package/dist/component/contentEntries.js.map +1 -1
  69. package/dist/component/contentEntryMutations.d.ts.map +1 -1
  70. package/dist/component/contentEntryMutations.js +0 -1
  71. package/dist/component/contentEntryMutations.js.map +1 -1
  72. package/dist/component/contentLock.d.ts.map +1 -1
  73. package/dist/component/contentLock.js +0 -2
  74. package/dist/component/contentLock.js.map +1 -1
  75. package/dist/component/index.d.ts +2 -1
  76. package/dist/component/index.d.ts.map +1 -1
  77. package/dist/component/index.js +3 -1
  78. package/dist/component/index.js.map +1 -1
  79. package/dist/component/schema.d.ts +18 -1
  80. package/dist/component/schema.d.ts.map +1 -1
  81. package/dist/component/schema.js +6 -1
  82. package/dist/component/schema.js.map +1 -1
  83. package/dist/component/settings.d.ts +60 -0
  84. package/dist/component/settings.d.ts.map +1 -0
  85. package/dist/component/settings.js +126 -0
  86. package/dist/component/settings.js.map +1 -0
  87. package/dist/component/validators.d.ts +36 -0
  88. package/dist/component/validators.d.ts.map +1 -1
  89. package/dist/component/validators.js +15 -0
  90. package/dist/component/validators.js.map +1 -1
  91. package/dist/test.d.ts +11 -2
  92. package/dist/test.d.ts.map +1 -1
  93. package/dist/test.js +2 -5
  94. package/dist/test.js.map +1 -1
  95. package/package.json +12 -3
package/README.md CHANGED
@@ -1,7 +1,19 @@
1
1
  # Convex CMS
2
2
 
3
+ > **Alpha Status (v0.0.5)** — Actively developed. APIs may change. [Report issues](https://github.com/obkaro/convex-cms/issues).
4
+
3
5
  A headless CMS built as a [Convex Component](https://docs.convex.dev/components) — content management that runs inside your Convex app.
4
6
 
7
+ ## Why Convex CMS?
8
+
9
+ If you're building on Convex and need content management, this is the most integrated option:
10
+
11
+ - **Zero infrastructure** — Runs entirely within your Convex deployment
12
+ - **True real-time** — Content updates via Convex subscriptions, not polling
13
+ - **Type-safe** — Code-first schemas with full TypeScript inference
14
+ - **Component isolation** — Separate database tables, versioned independently
15
+ - **Agent-native** — 23 pre-built tools for AI agent integration via `@convex-dev/agent`
16
+
5
17
  ## Choose Your Path
6
18
 
7
19
  ### Need an Admin Interface?
@@ -17,7 +29,7 @@ Your App Admin UI
17
29
  ├── listContentTypes
18
30
  ├── getEntry
19
31
  ├── publishEntry
20
- └── ... (30+ functions)
32
+ └── ... (60+ functions across 11 domains)
21
33
 
22
34
 
23
35
  CMS Component
@@ -100,13 +112,33 @@ export default app;
100
112
 
101
113
  ## What's Included
102
114
 
103
- - **13 field types** — text, richText, media, reference, select, and more
115
+ ### Core Content
116
+ - **13 field types** — text, richText, number, boolean, date, datetime, select, multiSelect, reference, media, json, tags, category
104
117
  - **Publishing workflows** — draft → scheduled → published with version history
105
- - **Media management** — uploads, folders, variants, and metadata
118
+ - **Content versioning** — Snapshots, comparison, and rollback
119
+ - **Scheduled publishing** — Convex scheduler integration for future publish dates
120
+
121
+ ### Media Management
122
+ - **File uploads** — Direct to Convex storage with folder organization
123
+ - **Image variants** — Automatic resizing and format conversion
124
+ - **Metadata & tagging** — Alt text, descriptions, taxonomy support
125
+
126
+ ### Organization
127
+ - **Taxonomies** — Hierarchical categories and flat tags
128
+ - **Content locking** — Prevent concurrent edit conflicts
129
+ - **Soft delete & trash** — Configurable retention with restore
130
+
131
+ ### Integration
106
132
  - **RBAC** — 4 built-in roles + custom roles with fine-grained permissions
107
- - **Multi-locale** — content localization with fallback chains
108
- - **Admin UI** — pre-built React interface (CLI or embeddable)
109
- - **Agent tools** — Zod schemas for AI integration
133
+ - **Multi-locale** — Content localization with fallback chains
134
+ - **Webhooks** — Event-driven integration with external systems
135
+ - **Event system** — All mutations emit events for async processing
136
+ - **Agent tools** — 23 pre-built tools with Zod schemas for AI integration
137
+ - **Query builder** — Fluent API for complex content queries
138
+
139
+ ### Admin UI
140
+ - **Pre-built React interface** — CLI mode for development, embeddable for production
141
+ - **Visual content editing** — Rich text, media picker, reference selector
110
142
 
111
143
  ## Admin UI Modes
112
144
 
@@ -121,17 +153,20 @@ Both modes call the same functions from your `convex/admin.ts`.
121
153
 
122
154
  | Guide | Description |
123
155
  |-------|-------------|
124
- | [Admin UI Setup](./docs/guides/admin-ui-setup.md) | CLI and embed modes, auth integration |
125
156
  | [Getting Started](./docs/guides/getting-started.md) | Programmatic usage with createCmsClient |
126
- | [Integration Patterns](./docs/guides/integration-patterns.md) | Common setups and when to use each |
157
+ | [Admin UI Setup](./docs/guides/admin-ui-setup.md) | CLI and embed modes, auth integration |
127
158
  | [Content Modeling](./docs/guides/content-modeling.md) | Content types and field definitions |
159
+ | [Query Builder](./docs/guides/query-builder.md) | Fluent API for complex queries |
160
+ | [Taxonomies](./docs/guides/taxonomies.md) | Categories, tags, and organization |
128
161
  | [Authorization](./docs/guides/authorization.md) | Roles, permissions, and custom auth |
129
162
  | [Media Management](./docs/guides/media.md) | Uploads, folders, and variants |
163
+ | [Agent Tools](./docs/guides/agent-tools.md) | AI agent integration with Zod schemas |
164
+ | [Integration Patterns](./docs/guides/integration-patterns.md) | Common setups and when to use each |
130
165
 
131
166
  | Reference | Description |
132
167
  |-----------|-------------|
133
168
  | [Client API](./docs/api/client-api.md) | createCmsClient methods |
134
- | [Admin API](./docs/api/admin-api.md) | defineAdminAPI functions |
169
+ | [Admin API](./docs/api/admin-api.md) | 60+ defineAdminAPI functions |
135
170
  | [Code-First Schema](./docs/api/code-first-schema.md) | TypeScript-first content types |
136
171
  | [Field Types](./docs/api/field-types.md) | All 13 field types |
137
172
  | [Configuration](./docs/api/configuration.md) | All config options |
@@ -27,10 +27,10 @@ export function BulkActionBar({
27
27
  errors?: string[]
28
28
  } | null>(null)
29
29
 
30
- const bulkPublish = useMutation(api.bulkOperations.bulkPublish)
31
- const bulkUnpublish = useMutation(api.bulkOperations.bulkUnpublish)
32
- const bulkDelete = useMutation(api.bulkOperations.bulkDelete)
33
- const bulkUpdate = useMutation(api.bulkOperations.bulkUpdate)
30
+ const bulkPublish = useMutation(api.admin.bulkPublish)
31
+ const bulkUnpublish = useMutation(api.admin.bulkUnpublish)
32
+ const bulkDelete = useMutation(api.admin.bulkDelete)
33
+ const bulkUpdate = useMutation(api.admin.bulkUpdate)
34
34
 
35
35
  const handleAction = useCallback((action: BulkAction) => {
36
36
  setActiveAction(action)
@@ -188,14 +188,14 @@ export function ContentEntryEditor({
188
188
  const formDataRef = useRef(formData)
189
189
  formDataRef.current = formData
190
190
 
191
- const createEntry = useMutation(api.entries.create)
192
- const updateEntry = useMutation(api.entries.update)
193
- const publishEntry = useMutation(api.entries.publish)
194
- const unpublishEntry = useMutation(api.entries.unpublish)
195
- const scheduleEntry = useMutation(api.entries.schedule)
196
- const cancelScheduleEntry = useMutation(api.entries.cancelSchedule)
197
- const deleteEntryMutation = useMutation(api.entries.remove)
198
- const duplicateEntryMutation = useMutation(api.entries.duplicate)
191
+ const createEntry = useMutation(api.admin.createEntry)
192
+ const updateEntry = useMutation(api.admin.updateEntry)
193
+ const publishEntry = useMutation(api.admin.publishEntry)
194
+ const unpublishEntry = useMutation(api.admin.unpublishEntry)
195
+ const scheduleEntry = useMutation(api.admin.scheduleEntry)
196
+ const cancelScheduleEntry = useMutation(api.admin.cancelScheduledEntry)
197
+ const deleteEntryMutation = useMutation(api.admin.deleteEntry)
198
+ const duplicateEntryMutation = useMutation(api.admin.duplicateEntry)
199
199
 
200
200
  const [showScheduleModal, setShowScheduleModal] = useState(false)
201
201
  const [scheduleDateTime, setScheduleDateTime] = useState<string>(() => {
@@ -500,26 +500,6 @@ export function ContentEntryEditor({
500
500
  }
501
501
  }, [entry, publishEntry, onSave])
502
502
 
503
- const _handleUnpublish = useCallback(async () => {
504
- if (!entry) return
505
-
506
- setIsPublishing(true)
507
- setPublishError(null)
508
-
509
- try {
510
- const draftEntry = (await unpublishEntry({
511
- id: entry._id,
512
- })) as ContentEntry
513
- onSave?.(draftEntry)
514
- } catch (error) {
515
- const message =
516
- error instanceof Error ? error.message : 'Failed to unpublish'
517
- setPublishError(message)
518
- } finally {
519
- setIsPublishing(false)
520
- }
521
- }, [entry, unpublishEntry, onSave])
522
-
523
503
  const handleSchedule = useCallback(async () => {
524
504
  if (!entry) return
525
505
 
@@ -188,8 +188,8 @@ export function ContentTypeFormModal({
188
188
  const [showBreakingWarning, setShowBreakingWarning] = useState(false);
189
189
  const [isForceUpdating, setIsForceUpdating] = useState(false);
190
190
 
191
- const createContentType = useMutation(api.contentTypes.create);
192
- const updateContentType = useMutation(api.contentTypes.update);
191
+ const createContentType = useMutation(api.admin.createContentType);
192
+ const updateContentType = useMutation(api.admin.updateContentType);
193
193
 
194
194
  // Populate form when editing
195
195
  useEffect(() => {
@@ -49,8 +49,8 @@ export function TaxonomyEditor({
49
49
  const [submitError, setSubmitError] = useState<string | null>(null)
50
50
  const [slugManuallyEdited, setSlugManuallyEdited] = useState(false)
51
51
 
52
- const createTaxonomy = useMutation(api.taxonomies.createTaxonomy)
53
- const updateTaxonomy = useMutation(api.taxonomies.updateTaxonomy)
52
+ const createTaxonomy = useMutation(api.admin.createTaxonomy)
53
+ const updateTaxonomy = useMutation(api.admin.updateTaxonomy)
54
54
 
55
55
  useEffect(() => {
56
56
  if (taxonomy) {
@@ -42,10 +42,10 @@ export function TermTree({
42
42
  const [error, setError] = useState<string | null>(null)
43
43
 
44
44
  const termsQuery = isHierarchical
45
- ? useQuery(api.taxonomies.getTermsHierarchy, { taxonomyId })
46
- : useQuery(api.taxonomies.listTerms, { taxonomyId })
45
+ ? useQuery(api.admin.getTermsHierarchy, { taxonomyId })
46
+ : useQuery(api.admin.listTerms, { taxonomyId })
47
47
 
48
- const deleteTerm = useMutation(api.taxonomies.deleteTerm)
48
+ const deleteTerm = useMutation(api.admin.deleteTerm)
49
49
 
50
50
  const terms = (
51
51
  isHierarchical ? termsQuery : (termsQuery as { page?: Term[] })?.page
@@ -304,8 +304,8 @@ function TermEditModal({
304
304
  const [submitError, setSubmitError] = useState<string | null>(null)
305
305
  const [slugManuallyEdited, setSlugManuallyEdited] = useState(false)
306
306
 
307
- const createTerm = useMutation(api.taxonomies.createTerm)
308
- const updateTerm = useMutation(api.taxonomies.updateTerm)
307
+ const createTerm = useMutation(api.admin.createTerm)
308
+ const updateTerm = useMutation(api.admin.updateTerm)
309
309
 
310
310
  const handleChange = useCallback(
311
311
  (field: keyof typeof formData, value: string | number) => {
@@ -47,7 +47,7 @@ export function VersionCompare({
47
47
  onClose,
48
48
  onRollback,
49
49
  }: VersionCompareProps) {
50
- const comparisonQuery = useQuery(api.versions.compare, {
50
+ const comparisonQuery = useQuery(api.admin.compareVersions, {
51
51
  entryId,
52
52
  fromVersionNumber: fromVersion,
53
53
  toVersionNumber: toVersion,
@@ -42,12 +42,12 @@ export function VersionHistory({
42
42
  const [rollbackError, setRollbackError] = useState<string | null>(null)
43
43
  const [rollbackSuccess, setRollbackSuccess] = useState(false)
44
44
 
45
- const versionsQuery = useQuery(api.versions.getHistory, {
45
+ const versionsQuery = useQuery(api.admin.getVersionHistory, {
46
46
  entryId,
47
47
  paginationOpts: { numItems: 50, cursor: null },
48
48
  })
49
49
 
50
- const rollbackMutation = useMutation(api.versions.rollback)
50
+ const rollbackMutation = useMutation(api.admin.rollbackVersion)
51
51
 
52
52
  const versions = (versionsQuery?.page ?? []) as VersionItem[]
53
53
  const isLoading = versionsQuery === undefined
@@ -52,7 +52,7 @@ export function CategoryField({
52
52
  const containerRef = useRef<HTMLDivElement>(null)
53
53
 
54
54
  const hierarchyResult = useQuery(
55
- api.taxonomies.getTermsHierarchy,
55
+ api.admin.getTermsHierarchy,
56
56
  taxonomyId ? { taxonomyId: asTaxonomyId(taxonomyId) } : 'skip'
57
57
  )
58
58
  const categoryTree = (hierarchyResult ?? []) as CategoryTerm[]
@@ -105,12 +105,12 @@ export function MediaField({
105
105
  const allowedMimeTypes = field.options?.allowedMimeTypes ?? []
106
106
 
107
107
  const selectedAsset = useQuery(
108
- api.media.getAsset,
108
+ api.admin.getMediaAsset,
109
109
  value ? { id: value } : 'skip'
110
110
  )
111
111
 
112
112
  const assetsResult = useQuery(
113
- api.media.listAssets,
113
+ api.admin.listMediaAssets,
114
114
  showPicker
115
115
  ? {
116
116
  type: typeFilter
@@ -345,8 +345,8 @@ export function MediaField({
345
345
 
346
346
  <TabsContent value="upload" className="mt-4">
347
347
  <UploadDropzone
348
- generateUploadUrl={api.media.generateUploadUrl}
349
- createAsset={api.media.createAsset}
348
+ generateUploadUrl={api.admin.generateUploadUrl}
349
+ createAsset={api.admin.createMediaAsset}
350
350
  onUploadComplete={handleUploadComplete}
351
351
  allowedMimeTypes={allowedMimeTypes}
352
352
  maxFileSize={field.options?.maxFileSize}
@@ -75,7 +75,7 @@ export function ReferenceField({
75
75
  return Array.isArray(value) ? value : [value]
76
76
  }, [value])
77
77
 
78
- const contentTypes = useQuery(api.contentTypes.list, {
78
+ const contentTypes = useQuery(api.admin.listContentTypes, {
79
79
  isActive: true,
80
80
  includeEntryCounts: false,
81
81
  })
@@ -91,12 +91,12 @@ export function ReferenceField({
91
91
  }, [contentTypes?.page, allowedContentTypes])
92
92
 
93
93
  const selectedEntry = useQuery(
94
- api.entries.get,
94
+ api.admin.getEntry,
95
95
  selectedIds.length === 1 ? { id: selectedIds[0] } : 'skip'
96
96
  )
97
97
 
98
98
  const selectedEntries = useQuery(
99
- api.entries.list,
99
+ api.admin.listEntries,
100
100
  selectedIds.length > 1
101
101
  ? {
102
102
  paginationOpts: { numItems: 100, cursor: null },
@@ -110,7 +110,7 @@ export function ReferenceField({
110
110
  }, [selectedEntries?.page, selectedIds])
111
111
 
112
112
  const entriesResult = useQuery(
113
- api.entries.list,
113
+ api.admin.listEntries,
114
114
  showPicker
115
115
  ? {
116
116
  contentTypeId: contentTypeFilter || undefined,
@@ -51,7 +51,7 @@ export function TagField({
51
51
  const containerRef = useRef<HTMLDivElement>(null)
52
52
 
53
53
  const suggestionsResult = useQuery(
54
- api.taxonomies.suggestTerms,
54
+ api.admin.suggestTerms,
55
55
  taxonomyId
56
56
  ? {
57
57
  taxonomyId: asTaxonomyId(taxonomyId),
@@ -64,7 +64,7 @@ export function TagField({
64
64
  const suggestions = suggestionsResult ?? []
65
65
 
66
66
  const selectedTermsResult = useQuery(
67
- api.taxonomies.listTerms,
67
+ api.admin.listTerms,
68
68
  taxonomyId && value && value.length > 0
69
69
  ? {
70
70
  taxonomyId: asTaxonomyId(taxonomyId),
@@ -82,7 +82,7 @@ export function TagField({
82
82
  }
83
83
  }
84
84
 
85
- const createTermMutation = useMutation(api.taxonomies.createTerm)
85
+ const createTermMutation = useMutation(api.admin.createTerm)
86
86
 
87
87
  useEffect(() => {
88
88
  function handleClickOutside(event: MouseEvent) {
@@ -49,7 +49,7 @@ export function TaxonomyFilter({
49
49
  const [open, setOpen] = useState(false)
50
50
  const [search, setSearch] = useState('')
51
51
 
52
- const taxonomiesResult = useQuery(api.taxonomies.list, { isActive: true })
52
+ const taxonomiesResult = useQuery(api.admin.listTaxonomies, { isActive: true })
53
53
  const taxonomies = taxonomiesResult?.page ?? []
54
54
 
55
55
  const activeTaxonomy = useMemo(() => {
@@ -62,7 +62,7 @@ export function TaxonomyFilter({
62
62
  const targetTaxonomyId = taxonomyId ?? taxonomies[0]?._id
63
63
 
64
64
  const termsResult = useQuery(
65
- api.taxonomies.listTerms,
65
+ api.admin.listTerms,
66
66
  targetTaxonomyId
67
67
  ? {
68
68
  taxonomyId: targetTaxonomyId,
@@ -38,9 +38,9 @@ export function MediaAssetEditDialog({
38
38
  const [isSaving, setIsSaving] = useState(false)
39
39
  const [error, setError] = useState('')
40
40
 
41
- const updateAsset = useMutation(api.media.updateAsset)
41
+ const updateAsset = useMutation(api.admin.updateMediaAsset)
42
42
 
43
- const taxonomiesResult = useQuery(api.taxonomies.list, {
43
+ const taxonomiesResult = useQuery(api.admin.listTaxonomies, {
44
44
  isActive: true,
45
45
  paginationOpts: { numItems: 50, cursor: null },
46
46
  })
@@ -31,7 +31,7 @@ export function MediaFolderEditDialog({
31
31
  const [isSaving, setIsSaving] = useState(false)
32
32
  const [error, setError] = useState('')
33
33
 
34
- const updateFolder = useMutation(api.media.updateFolder)
34
+ const updateFolder = useMutation(api.admin.updateMediaFolder)
35
35
 
36
36
  useEffect(() => {
37
37
  if (folder) {
@@ -34,8 +34,8 @@ export function MediaMoveModal({
34
34
  const [isMoving, setIsMoving] = useState(false)
35
35
  const [error, setError] = useState('')
36
36
 
37
- const folderTree = useQuery(api.media.getFolderTree, {})
38
- const moveAssets = useMutation(api.media.moveAssets)
37
+ const folderTree = useQuery(api.admin.getMediaFolderTree, {})
38
+ const moveAssets = useMutation(api.admin.moveMediaAssets)
39
39
 
40
40
  const sortedFolders = useMemo(() => {
41
41
  if (!folderTree) return []
@@ -42,14 +42,14 @@ export function MediaTaxonomyPicker({
42
42
  const suggestionsRef = useRef<HTMLDivElement>(null)
43
43
  const containerRef = useRef<HTMLDivElement>(null)
44
44
 
45
- const currentTerms = useQuery(api.taxonomies.getTermsByMedia, {
45
+ const currentTerms = useQuery(api.admin.getTermsByMedia, {
46
46
  mediaId,
47
47
  taxonomyId,
48
48
  })
49
49
 
50
50
  const selectedTermIds = currentTerms?.map((t: TaxonomyTermDisplay) => t._id) ?? []
51
51
 
52
- const suggestionsResult = useQuery(api.taxonomies.suggestTerms, {
52
+ const suggestionsResult = useQuery(api.admin.suggestTerms, {
53
53
  taxonomyId,
54
54
  query: inputValue,
55
55
  limit: 10,
@@ -57,8 +57,8 @@ export function MediaTaxonomyPicker({
57
57
  })
58
58
  const suggestions = (suggestionsResult ?? []) as TaxonomyTermDisplay[]
59
59
 
60
- const setMediaTermsMutation = useMutation(api.taxonomies.setMediaTerms)
61
- const createTermMutation = useMutation(api.taxonomies.createTermAndAddToMedia)
60
+ const setMediaTermsMutation = useMutation(api.admin.setMediaTerms)
61
+ const createTermMutation = useMutation(api.admin.createTermAndAddToMedia)
62
62
 
63
63
  useEffect(() => {
64
64
  function handleClickOutside(event: MouseEvent) {
@@ -4,7 +4,7 @@ import { api } from "../../convex/_generated/api";
4
4
  import type { AdminConfig } from "~/lib/admin-config";
5
5
  import { AdminConfigProvider } from "./AdminConfigContext";
6
6
 
7
- type Settings = NonNullable<typeof api.settings.get._returnType>;
7
+ type Settings = NonNullable<typeof api.admin.getSettings._returnType>;
8
8
 
9
9
  interface SettingsConfigContextValue {
10
10
  baseConfig: AdminConfig;
@@ -20,7 +20,7 @@ export function SettingsConfigProvider({
20
20
  baseConfig: AdminConfig;
21
21
  children: ReactNode;
22
22
  }) {
23
- const settings = useQuery(api.settings.get);
23
+ const settings = useQuery(api.admin.getSettings);
24
24
 
25
25
  const mergedConfig = useMemo((): AdminConfig => {
26
26
  if (!settings) return baseConfig;