@fnd-platform/cms 1.0.0-alpha.3 → 1.0.0-alpha.5
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.
- package/lib/cms-project.d.ts +88 -86
- package/lib/cms-project.d.ts.map +1 -1
- package/lib/cms-project.js +22 -3
- package/lib/cms-project.js.map +1 -1
- package/lib/index.js +5 -10
- package/lib/templates/admin-content-edit-route.d.ts +9 -0
- package/lib/templates/admin-content-edit-route.d.ts.map +1 -0
- package/lib/templates/admin-content-edit-route.js +195 -0
- package/lib/templates/admin-content-edit-route.js.map +1 -0
- package/lib/templates/admin-content-new-route.d.ts +9 -0
- package/lib/templates/admin-content-new-route.d.ts.map +1 -0
- package/lib/templates/admin-content-new-route.js +160 -0
- package/lib/templates/admin-content-new-route.js.map +1 -0
- package/lib/templates/admin-content-type-route.d.ts +2 -2
- package/lib/templates/admin-content-type-route.d.ts.map +1 -1
- package/lib/templates/admin-content-type-route.js +67 -27
- package/lib/templates/admin-content-type-route.js.map +1 -1
- package/lib/templates/content-api.d.ts +9 -0
- package/lib/templates/content-api.d.ts.map +1 -0
- package/lib/templates/content-api.js +195 -0
- package/lib/templates/content-api.js.map +1 -0
- package/lib/templates/index.d.ts +4 -0
- package/lib/templates/index.d.ts.map +1 -1
- package/lib/templates/index.js +11 -1
- package/lib/templates/index.js.map +1 -1
- package/lib/templates/ui-select.d.ts +9 -0
- package/lib/templates/ui-select.d.ts.map +1 -0
- package/lib/templates/ui-select.js +172 -0
- package/lib/templates/ui-select.js.map +1 -0
- package/package.json +13 -13
- package/LICENSE +0 -21
package/lib/cms-project.d.ts
CHANGED
|
@@ -38,90 +38,92 @@ import type { FndCmsProjectOptions } from './options';
|
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
40
|
export declare class FndCmsProject extends FndFrontendProject {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Whether media upload functionality is enabled.
|
|
43
|
+
*/
|
|
44
|
+
readonly mediaUpload: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Rich text editor to use for content editing.
|
|
47
|
+
*/
|
|
48
|
+
readonly richTextEditor: 'tiptap' | 'lexical';
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new FndCmsProject.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Configuration options for the CMS project
|
|
53
|
+
* @throws {Error} If required options are missing
|
|
54
|
+
*/
|
|
55
|
+
constructor(options: FndCmsProjectOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Generates additional shadcn/ui components for the CMS.
|
|
58
|
+
*
|
|
59
|
+
* Creates:
|
|
60
|
+
* - badge.tsx - Status badge component
|
|
61
|
+
* - avatar.tsx - User avatar component
|
|
62
|
+
* - dropdown-menu.tsx - Dropdown menu component
|
|
63
|
+
* - table.tsx - Table component
|
|
64
|
+
* - popover.tsx - Popover component for link dialogs
|
|
65
|
+
*/
|
|
66
|
+
private generateUiComponents;
|
|
67
|
+
/**
|
|
68
|
+
* Generates the admin components for the CMS.
|
|
69
|
+
*
|
|
70
|
+
* Creates:
|
|
71
|
+
* - sidebar.tsx - Admin sidebar navigation
|
|
72
|
+
* - header.tsx - Admin header with user menu
|
|
73
|
+
* - breadcrumbs.tsx - Breadcrumb navigation
|
|
74
|
+
* - dashboard-stats.tsx - Dashboard statistics cards
|
|
75
|
+
* - recent-content.tsx - Recent content list
|
|
76
|
+
* - content-table.tsx - Content list table
|
|
77
|
+
*/
|
|
78
|
+
private generateAdminComponents;
|
|
79
|
+
/**
|
|
80
|
+
* Generates the admin routes for the CMS.
|
|
81
|
+
*
|
|
82
|
+
* Creates:
|
|
83
|
+
* - _admin.tsx - Admin layout with sidebar and header
|
|
84
|
+
* - _admin._index.tsx - Admin dashboard with stats
|
|
85
|
+
* - _admin.content.tsx - Content section layout
|
|
86
|
+
* - _admin.content._index.tsx - Content overview
|
|
87
|
+
* - _admin.content.$type._index.tsx - Content type list
|
|
88
|
+
* - _admin.content.$type.new.tsx - Create new content
|
|
89
|
+
* - _admin.content.$type.$id.tsx - Edit existing content
|
|
90
|
+
*/
|
|
91
|
+
private generateAdminRoutes;
|
|
92
|
+
/**
|
|
93
|
+
* Generates the content type definition system.
|
|
94
|
+
*
|
|
95
|
+
* Creates:
|
|
96
|
+
* - app/lib/content-types.ts - Content type definitions and interfaces
|
|
97
|
+
* - app/lib/content-schema.ts - Zod schema generation utilities
|
|
98
|
+
* - app/lib/slug-utils.ts - Slug generation utilities
|
|
99
|
+
* - app/content-types/index.ts - Content type registry
|
|
100
|
+
* - app/content-types/blog-post.ts - Example blog post content type
|
|
101
|
+
* - app/content-types/page.ts - Example page content type
|
|
102
|
+
* - app/components/form-fields/* - All form field components
|
|
103
|
+
* - app/components/admin/content-editor.tsx - Dynamic content editor
|
|
104
|
+
*/
|
|
105
|
+
private generateContentTypeSystem;
|
|
106
|
+
/**
|
|
107
|
+
* Generates the editor components for rich text editing.
|
|
108
|
+
*
|
|
109
|
+
* Creates:
|
|
110
|
+
* - app/components/editor/toolbar.tsx - Editor toolbar with formatting buttons
|
|
111
|
+
* - app/components/editor/rich-text-editor.tsx - Tiptap-based rich text editor
|
|
112
|
+
*/
|
|
113
|
+
private generateEditorComponents;
|
|
114
|
+
/**
|
|
115
|
+
* Generates the media library components.
|
|
116
|
+
*
|
|
117
|
+
* Creates:
|
|
118
|
+
* - app/lib/media-api.ts - Client-side API helpers for presigned URL uploads
|
|
119
|
+
* - app/components/media/media-uploader.tsx - Drag-drop upload with progress
|
|
120
|
+
* - app/components/media/media-grid.tsx - Grid display with selection
|
|
121
|
+
* - app/components/media/media-picker.tsx - Dialog for field integration
|
|
122
|
+
* - app/routes/_admin.media.tsx - Media library route
|
|
123
|
+
* - app/components/ui/progress.tsx - Progress bar component
|
|
124
|
+
* - app/components/ui/dialog.tsx - Dialog component
|
|
125
|
+
* - app/components/ui/tabs.tsx - Tabs component
|
|
126
|
+
*/
|
|
127
|
+
private generateMediaComponents;
|
|
126
128
|
}
|
|
127
|
-
//# sourceMappingURL=cms-project.d.ts.map
|
|
129
|
+
//# sourceMappingURL=cms-project.d.ts.map
|
package/lib/cms-project.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-project.d.ts","sourceRoot":"","sources":["../src/cms-project.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cms-project.d.ts","sourceRoot":"","sources":["../src/cms-project.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AA4DtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,aAAc,SAAQ,kBAAkB;IACnD;;OAEG;IACH,SAAgB,WAAW,EAAE,OAAO,CAAC;IAErC;;OAEG;IACH,SAAgB,cAAc,EAAE,QAAQ,GAAG,SAAS,CAAC;IAErD;;;;;OAKG;gBACS,OAAO,EAAE,oBAAoB;IAmEzC;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IA0C3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,yBAAyB;IA0FjC;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAUhC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,uBAAuB;CAqChC"}
|
package/lib/cms-project.js
CHANGED
|
@@ -95,6 +95,8 @@ class FndCmsProject extends frontend_1.FndFrontendProject {
|
|
|
95
95
|
this.addDeps('@tiptap/extension-image@^2.2.0');
|
|
96
96
|
// Radix Popover for link insertion dialog
|
|
97
97
|
this.addDeps('@radix-ui/react-popover@^1.0.0');
|
|
98
|
+
// Radix Select for media grid filter
|
|
99
|
+
this.addDeps('@radix-ui/react-select@^2.0.0');
|
|
98
100
|
// Additional Radix dependencies for media library
|
|
99
101
|
this.addDeps('@radix-ui/react-dialog@^1.0.0');
|
|
100
102
|
this.addDeps('@radix-ui/react-tabs@^1.0.0');
|
|
@@ -136,6 +138,9 @@ class FndCmsProject extends frontend_1.FndFrontendProject {
|
|
|
136
138
|
new projen_1.SampleFile(this, 'app/components/ui/popover.tsx', {
|
|
137
139
|
contents: (0, templates_1.getPopoverTemplate)(),
|
|
138
140
|
});
|
|
141
|
+
new projen_1.SampleFile(this, 'app/components/ui/select.tsx', {
|
|
142
|
+
contents: (0, templates_1.getSelectTemplate)(),
|
|
143
|
+
});
|
|
139
144
|
}
|
|
140
145
|
/**
|
|
141
146
|
* Generates the admin components for the CMS.
|
|
@@ -176,7 +181,9 @@ class FndCmsProject extends frontend_1.FndFrontendProject {
|
|
|
176
181
|
* - _admin._index.tsx - Admin dashboard with stats
|
|
177
182
|
* - _admin.content.tsx - Content section layout
|
|
178
183
|
* - _admin.content._index.tsx - Content overview
|
|
179
|
-
* - _admin.content.$type.tsx - Content type list
|
|
184
|
+
* - _admin.content.$type._index.tsx - Content type list
|
|
185
|
+
* - _admin.content.$type.new.tsx - Create new content
|
|
186
|
+
* - _admin.content.$type.$id.tsx - Edit existing content
|
|
180
187
|
*/
|
|
181
188
|
generateAdminRoutes() {
|
|
182
189
|
// Admin layout with sidebar and header
|
|
@@ -195,10 +202,22 @@ class FndCmsProject extends frontend_1.FndFrontendProject {
|
|
|
195
202
|
new projen_1.SampleFile(this, 'app/routes/_admin.content._index.tsx', {
|
|
196
203
|
contents: (0, templates_1.getAdminContentIndexTemplate)(),
|
|
197
204
|
});
|
|
198
|
-
// Content type list
|
|
199
|
-
new projen_1.SampleFile(this, 'app/routes/_admin.content.$type.tsx', {
|
|
205
|
+
// Content type list (index route for the type)
|
|
206
|
+
new projen_1.SampleFile(this, 'app/routes/_admin.content.$type._index.tsx', {
|
|
200
207
|
contents: (0, templates_1.getAdminContentTypeRouteTemplate)(),
|
|
201
208
|
});
|
|
209
|
+
// Create new content route
|
|
210
|
+
new projen_1.SampleFile(this, 'app/routes/_admin.content.$type.new.tsx', {
|
|
211
|
+
contents: (0, templates_1.getAdminContentNewRouteTemplate)(),
|
|
212
|
+
});
|
|
213
|
+
// Edit content route
|
|
214
|
+
new projen_1.SampleFile(this, 'app/routes/_admin.content.$type.$id.tsx', {
|
|
215
|
+
contents: (0, templates_1.getAdminContentEditRouteTemplate)(),
|
|
216
|
+
});
|
|
217
|
+
// Content API client
|
|
218
|
+
new projen_1.SampleFile(this, 'app/lib/content-api.ts', {
|
|
219
|
+
contents: (0, templates_1.getContentApiTemplate)(),
|
|
220
|
+
});
|
|
202
221
|
}
|
|
203
222
|
/**
|
|
204
223
|
* Generates the content type definition system.
|
package/lib/cms-project.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-project.js","sourceRoot":"","sources":["../src/cms-project.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AACpC,qDAA4D;AAE5D,
|
|
1
|
+
{"version":3,"file":"cms-project.js","sourceRoot":"","sources":["../src/cms-project.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @fnd-platform/cms
|
|
4
4
|
*
|
|
@@ -7,14 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
9
9
|
*/
|
|
10
|
-
Object.defineProperty(exports,
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.FndCmsProject = void 0;
|
|
12
12
|
// Main project class
|
|
13
|
-
var cms_project_1 = require(
|
|
14
|
-
Object.defineProperty(exports,
|
|
15
|
-
|
|
16
|
-
get: function () {
|
|
17
|
-
return cms_project_1.FndCmsProject;
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
//# sourceMappingURL=index.js.map
|
|
13
|
+
var cms_project_1 = require("./cms-project");
|
|
14
|
+
Object.defineProperty(exports, "FndCmsProject", { enumerable: true, get: function () { return cms_project_1.FndCmsProject; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates the admin content edit route template.
|
|
3
|
+
*
|
|
4
|
+
* This route provides a form for editing existing content items.
|
|
5
|
+
*
|
|
6
|
+
* @returns Template string for app/routes/_admin.content.$type.$id.tsx
|
|
7
|
+
*/
|
|
8
|
+
export declare function getAdminContentEditRouteTemplate(): string;
|
|
9
|
+
//# sourceMappingURL=admin-content-edit-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-content-edit-route.d.ts","sourceRoot":"","sources":["../../src/templates/admin-content-edit-route.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,gCAAgC,IAAI,MAAM,CAuLzD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAdminContentEditRouteTemplate = getAdminContentEditRouteTemplate;
|
|
4
|
+
/**
|
|
5
|
+
* Generates the admin content edit route template.
|
|
6
|
+
*
|
|
7
|
+
* This route provides a form for editing existing content items.
|
|
8
|
+
*
|
|
9
|
+
* @returns Template string for app/routes/_admin.content.$type.$id.tsx
|
|
10
|
+
*/
|
|
11
|
+
function getAdminContentEditRouteTemplate() {
|
|
12
|
+
return `import {
|
|
13
|
+
json,
|
|
14
|
+
redirect,
|
|
15
|
+
type LoaderFunctionArgs,
|
|
16
|
+
type ActionFunctionArgs,
|
|
17
|
+
type MetaFunction,
|
|
18
|
+
} from '@remix-run/node';
|
|
19
|
+
import { useLoaderData } from '@remix-run/react';
|
|
20
|
+
import { requireAuth, hasAnyRole, getOptionalUser, getAccessToken } from '~/lib/auth.server';
|
|
21
|
+
import { ContentEditor, type ContentActionData } from '~/components/admin/content-editor';
|
|
22
|
+
import { Breadcrumbs } from '~/components/admin/breadcrumbs';
|
|
23
|
+
import { contentTypes } from '~/content-types';
|
|
24
|
+
import { contentApi, type UpdateContentInput } from '~/lib/content-api';
|
|
25
|
+
|
|
26
|
+
export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
|
27
|
+
const title = data?.content?.title ?? 'Edit Content';
|
|
28
|
+
return [{ title: \`\${title} - CMS Admin\` }];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export async function loader({ request, params }: LoaderFunctionArgs) {
|
|
32
|
+
await requireAuth(request);
|
|
33
|
+
const user = await getOptionalUser(request);
|
|
34
|
+
const token = await getAccessToken(request);
|
|
35
|
+
|
|
36
|
+
const { type, id } = params;
|
|
37
|
+
|
|
38
|
+
if (!type || !id) {
|
|
39
|
+
throw new Response('Content type and ID required', { status: 400 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Get content type definition
|
|
43
|
+
const contentType = contentTypes[type];
|
|
44
|
+
if (!contentType) {
|
|
45
|
+
throw new Response(\`Content type '\${type}' not found\`, { status: 404 });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Fetch content from API
|
|
49
|
+
let content;
|
|
50
|
+
try {
|
|
51
|
+
content = await contentApi.get(id, token);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw new Response(\`Content not found\`, { status: 404 });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check permissions
|
|
57
|
+
const canEdit = hasAnyRole(user, ['admin', 'editor']);
|
|
58
|
+
if (!canEdit) {
|
|
59
|
+
throw new Response('You do not have permission to edit content', { status: 403 });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const canPublish = hasAnyRole(user, ['admin', 'editor']);
|
|
63
|
+
const canDelete = hasAnyRole(user, ['admin']);
|
|
64
|
+
|
|
65
|
+
return json({
|
|
66
|
+
contentType,
|
|
67
|
+
content,
|
|
68
|
+
permissions: { canPublish, canDelete },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function action({ request, params }: ActionFunctionArgs) {
|
|
73
|
+
await requireAuth(request);
|
|
74
|
+
const user = await getOptionalUser(request);
|
|
75
|
+
const token = await getAccessToken(request);
|
|
76
|
+
|
|
77
|
+
const { type, id } = params;
|
|
78
|
+
|
|
79
|
+
if (!type || !id) {
|
|
80
|
+
return json<ContentActionData>(
|
|
81
|
+
{ success: false, message: 'Content type and ID required' },
|
|
82
|
+
{ status: 400 }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const formData = await request.formData();
|
|
87
|
+
const action = formData.get('_action') as string;
|
|
88
|
+
const formDataJson = formData.get('_formData') as string;
|
|
89
|
+
|
|
90
|
+
if (!formDataJson) {
|
|
91
|
+
return json<ContentActionData>(
|
|
92
|
+
{ success: false, message: 'Form data missing' },
|
|
93
|
+
{ status: 400 }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const data = JSON.parse(formDataJson) as Record<string, unknown>;
|
|
98
|
+
|
|
99
|
+
// Handle delete action
|
|
100
|
+
if (action === 'delete') {
|
|
101
|
+
const canDelete = hasAnyRole(user, ['admin']);
|
|
102
|
+
if (!canDelete) {
|
|
103
|
+
return json<ContentActionData>(
|
|
104
|
+
{ success: false, message: 'You do not have permission to delete' },
|
|
105
|
+
{ status: 403 }
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
await contentApi.delete(id, token!);
|
|
111
|
+
return redirect(\`/admin/content/\${type}\`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return json<ContentActionData>(
|
|
114
|
+
{
|
|
115
|
+
success: false,
|
|
116
|
+
message: error instanceof Error ? error.message : 'Failed to delete content',
|
|
117
|
+
},
|
|
118
|
+
{ status: 500 }
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check edit permissions
|
|
124
|
+
const canEdit = hasAnyRole(user, ['admin', 'editor']);
|
|
125
|
+
if (!canEdit) {
|
|
126
|
+
return json<ContentActionData>(
|
|
127
|
+
{ success: false, message: 'You do not have permission to edit content' },
|
|
128
|
+
{ status: 403 }
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Determine status based on action
|
|
133
|
+
let status: 'draft' | 'published' | undefined;
|
|
134
|
+
if (action === 'publish') {
|
|
135
|
+
const canPublish = hasAnyRole(user, ['admin', 'editor']);
|
|
136
|
+
if (!canPublish) {
|
|
137
|
+
return json<ContentActionData>(
|
|
138
|
+
{ success: false, message: 'You do not have permission to publish' },
|
|
139
|
+
{ status: 403 }
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
status = 'published';
|
|
143
|
+
} else if (action === 'unpublish') {
|
|
144
|
+
status = 'draft';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const input: UpdateContentInput = {
|
|
149
|
+
slug: data.slug as string,
|
|
150
|
+
title: data.title as string,
|
|
151
|
+
excerpt: data.excerpt as string | undefined,
|
|
152
|
+
content: data.content as string,
|
|
153
|
+
status,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
await contentApi.update(id, input, token!);
|
|
157
|
+
|
|
158
|
+
return json<ContentActionData>({ success: true, message: 'Content saved successfully' });
|
|
159
|
+
} catch (error) {
|
|
160
|
+
return json<ContentActionData>(
|
|
161
|
+
{
|
|
162
|
+
success: false,
|
|
163
|
+
message: error instanceof Error ? error.message : 'Failed to save content',
|
|
164
|
+
},
|
|
165
|
+
{ status: 500 }
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default function EditContent() {
|
|
171
|
+
const { contentType, content, permissions } = useLoaderData<typeof loader>();
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div className="space-y-6">
|
|
175
|
+
<Breadcrumbs
|
|
176
|
+
items={[
|
|
177
|
+
{ label: 'Content', href: '/admin/content' },
|
|
178
|
+
{ label: contentType.label, href: \`/admin/content/\${contentType.name}\` },
|
|
179
|
+
{ label: content.title },
|
|
180
|
+
]}
|
|
181
|
+
/>
|
|
182
|
+
|
|
183
|
+
<ContentEditor
|
|
184
|
+
contentType={contentType}
|
|
185
|
+
initialData={content}
|
|
186
|
+
mode="edit"
|
|
187
|
+
cancelUrl={\`/admin/content/\${contentType.name}\`}
|
|
188
|
+
permissions={permissions}
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=admin-content-edit-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-content-edit-route.js","sourceRoot":"","sources":["../../src/templates/admin-content-edit-route.ts"],"names":[],"mappings":";;AAOA,4EAuLC;AA9LD;;;;;;GAMG;AACH,SAAgB,gCAAgC;IAC9C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqLR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates the admin content create route template.
|
|
3
|
+
*
|
|
4
|
+
* This route provides a form for creating new content items.
|
|
5
|
+
*
|
|
6
|
+
* @returns Template string for app/routes/_admin.content.$type.new.tsx
|
|
7
|
+
*/
|
|
8
|
+
export declare function getAdminContentNewRouteTemplate(): string;
|
|
9
|
+
//# sourceMappingURL=admin-content-new-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-content-new-route.d.ts","sourceRoot":"","sources":["../../src/templates/admin-content-new-route.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAoJxD"}
|