@arch-cadre/blog-module 0.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.
- package/dist/actions/index.cjs +158 -0
- package/dist/actions/index.d.ts +34 -0
- package/dist/actions/index.mjs +121 -0
- package/dist/components/ui/button.cjs +53 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.mjs +44 -0
- package/dist/components/ui/card.cjs +46 -0
- package/dist/components/ui/card.d.ts +6 -0
- package/dist/components/ui/card.mjs +35 -0
- package/dist/components/ui/input.cjs +23 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.mjs +20 -0
- package/dist/components/ui/table.cjs +66 -0
- package/dist/components/ui/table.d.ts +8 -0
- package/dist/components/ui/table.mjs +59 -0
- package/dist/components/ui/textarea.cjs +21 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/textarea.mjs +19 -0
- package/dist/index.cjs +37 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +30 -0
- package/dist/intl.d.ts +7 -0
- package/dist/lib/utils.cjs +11 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.mjs +5 -0
- package/dist/lib/validation.cjs +16 -0
- package/dist/lib/validation.d.ts +24 -0
- package/dist/lib/validation.mjs +10 -0
- package/dist/navigation.cjs +21 -0
- package/dist/navigation.d.ts +2 -0
- package/dist/navigation.mjs +19 -0
- package/dist/routes.cjs +70 -0
- package/dist/routes.d.ts +3 -0
- package/dist/routes.mjs +64 -0
- package/dist/schema.cjs +62 -0
- package/dist/schema.d.ts +0 -0
- package/dist/schema.mjs +53 -0
- package/dist/styles/globals.css +1 -0
- package/dist/ui/views.cjs +448 -0
- package/dist/ui/views.d.ts +16 -0
- package/dist/ui/views.mjs +232 -0
- package/locales/en/global.json +36 -0
- package/manifest.json +11 -0
- package/package.json +62 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../../lib/utils.mjs";
|
|
3
|
+
const Table = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement("div", { className: "relative w-full overflow-auto" }, /* @__PURE__ */ React.createElement(
|
|
4
|
+
"table",
|
|
5
|
+
{
|
|
6
|
+
ref,
|
|
7
|
+
className: cn("w-full caption-bottom text-sm", className),
|
|
8
|
+
...props
|
|
9
|
+
}
|
|
10
|
+
)));
|
|
11
|
+
Table.displayName = "Table";
|
|
12
|
+
const TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
|
|
13
|
+
TableHeader.displayName = "TableHeader";
|
|
14
|
+
const TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
15
|
+
"tbody",
|
|
16
|
+
{
|
|
17
|
+
ref,
|
|
18
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
19
|
+
...props
|
|
20
|
+
}
|
|
21
|
+
));
|
|
22
|
+
TableBody.displayName = "TableBody";
|
|
23
|
+
const TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
24
|
+
"tr",
|
|
25
|
+
{
|
|
26
|
+
ref,
|
|
27
|
+
className: cn(
|
|
28
|
+
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
|
29
|
+
className
|
|
30
|
+
),
|
|
31
|
+
...props
|
|
32
|
+
}
|
|
33
|
+
));
|
|
34
|
+
TableRow.displayName = "TableRow";
|
|
35
|
+
const TableHead = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
36
|
+
"th",
|
|
37
|
+
{
|
|
38
|
+
ref,
|
|
39
|
+
className: cn(
|
|
40
|
+
"h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
41
|
+
className
|
|
42
|
+
),
|
|
43
|
+
...props
|
|
44
|
+
}
|
|
45
|
+
));
|
|
46
|
+
TableHead.displayName = "TableHead";
|
|
47
|
+
const TableCell = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
48
|
+
"td",
|
|
49
|
+
{
|
|
50
|
+
ref,
|
|
51
|
+
className: cn(
|
|
52
|
+
"p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
53
|
+
className
|
|
54
|
+
),
|
|
55
|
+
...props
|
|
56
|
+
}
|
|
57
|
+
));
|
|
58
|
+
TableCell.displayName = "TableCell";
|
|
59
|
+
export { Table, TableHeader, TableBody, TableHead, TableRow, TableCell };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Textarea = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _utils = require("../../lib/utils.cjs");
|
|
9
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
10
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
11
|
+
const Textarea = exports.Textarea = React.forwardRef(({
|
|
12
|
+
className,
|
|
13
|
+
...props
|
|
14
|
+
}, ref) => {
|
|
15
|
+
return /* @__PURE__ */React.createElement("textarea", {
|
|
16
|
+
className: (0, _utils.cn)("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
17
|
+
ref,
|
|
18
|
+
...props
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
Textarea.displayName = "Textarea";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../../lib/utils.mjs";
|
|
3
|
+
const Textarea = React.forwardRef(
|
|
4
|
+
({ className, ...props }, ref) => {
|
|
5
|
+
return /* @__PURE__ */ React.createElement(
|
|
6
|
+
"textarea",
|
|
7
|
+
{
|
|
8
|
+
className: cn(
|
|
9
|
+
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
10
|
+
className
|
|
11
|
+
),
|
|
12
|
+
ref,
|
|
13
|
+
...props
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
Textarea.displayName = "Textarea";
|
|
19
|
+
export { Textarea };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _server = require("@arch-cadre/core/server");
|
|
8
|
+
var _manifest = _interopRequireDefault(require("../manifest.json"));
|
|
9
|
+
var _navigation = require("./navigation.cjs");
|
|
10
|
+
var _routes = require("./routes.cjs");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
const blogModule = {
|
|
13
|
+
manifest: _manifest.default,
|
|
14
|
+
init: async () => {
|
|
15
|
+
console.log("[BlogModule] ready.");
|
|
16
|
+
},
|
|
17
|
+
onEnable: async () => {
|
|
18
|
+
console.log("[BlogModule] enabled.");
|
|
19
|
+
},
|
|
20
|
+
onDisable: async () => {
|
|
21
|
+
console.log("[Blog] onDisable: Dropping all tables physically...");
|
|
22
|
+
try {
|
|
23
|
+
const tables = ["blog_posts", "blog_comments"];
|
|
24
|
+
for (const table of tables) {
|
|
25
|
+
await _server.db.execute(`DROP TABLE IF EXISTS ${table} CASCADE`);
|
|
26
|
+
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error("[Blog] onDisable Error:", e);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
routes: {
|
|
32
|
+
public: _routes.publicRoutes,
|
|
33
|
+
private: _routes.privateRoutes
|
|
34
|
+
},
|
|
35
|
+
navigation: _navigation.navigation
|
|
36
|
+
};
|
|
37
|
+
module.exports = blogModule;
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { db } from "@arch-cadre/core/server";
|
|
2
|
+
import manifest from "../manifest.json" with { type: "json" };
|
|
3
|
+
import { navigation } from "./navigation.mjs";
|
|
4
|
+
import { privateRoutes, publicRoutes } from "./routes.mjs";
|
|
5
|
+
const blogModule = {
|
|
6
|
+
manifest,
|
|
7
|
+
init: async () => {
|
|
8
|
+
console.log("[BlogModule] ready.");
|
|
9
|
+
},
|
|
10
|
+
onEnable: async () => {
|
|
11
|
+
console.log("[BlogModule] enabled.");
|
|
12
|
+
},
|
|
13
|
+
onDisable: async () => {
|
|
14
|
+
console.log("[Blog] onDisable: Dropping all tables physically...");
|
|
15
|
+
try {
|
|
16
|
+
const tables = ["blog_posts", "blog_comments"];
|
|
17
|
+
for (const table of tables) {
|
|
18
|
+
await db.execute(`DROP TABLE IF EXISTS ${table} CASCADE`);
|
|
19
|
+
}
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error("[Blog] onDisable Error:", e);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
routes: {
|
|
25
|
+
public: publicRoutes,
|
|
26
|
+
private: privateRoutes
|
|
27
|
+
},
|
|
28
|
+
navigation
|
|
29
|
+
};
|
|
30
|
+
export default blogModule;
|
package/dist/intl.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cn = cn;
|
|
7
|
+
var _clsx = require("clsx");
|
|
8
|
+
var _tailwindMerge = require("tailwind-merge");
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return (0, _tailwindMerge.twMerge)((0, _clsx.clsx)(inputs));
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.postSchema = exports.commentSchema = void 0;
|
|
7
|
+
var _zod = require("zod");
|
|
8
|
+
const postSchema = exports.postSchema = _zod.z.object({
|
|
9
|
+
title: _zod.z.string().min(3, "Title must be at least 3 characters"),
|
|
10
|
+
content: _zod.z.string().min(10, "Content must be at least 10 characters"),
|
|
11
|
+
slug: _zod.z.string().min(3, "Slug is required")
|
|
12
|
+
});
|
|
13
|
+
const commentSchema = exports.commentSchema = _zod.z.object({
|
|
14
|
+
content: _zod.z.string().min(2, "Comment is too short"),
|
|
15
|
+
postId: _zod.z.string().uuid()
|
|
16
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const postSchema: z.ZodObject<{
|
|
3
|
+
title: z.ZodString;
|
|
4
|
+
content: z.ZodString;
|
|
5
|
+
slug: z.ZodString;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
title: string;
|
|
8
|
+
content: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
}, {
|
|
11
|
+
title: string;
|
|
12
|
+
content: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
}>;
|
|
15
|
+
export declare const commentSchema: z.ZodObject<{
|
|
16
|
+
content: z.ZodString;
|
|
17
|
+
postId: z.ZodString;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
content: string;
|
|
20
|
+
postId: string;
|
|
21
|
+
}, {
|
|
22
|
+
content: string;
|
|
23
|
+
postId: string;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const postSchema = z.object({
|
|
3
|
+
title: z.string().min(3, "Title must be at least 3 characters"),
|
|
4
|
+
content: z.string().min(10, "Content must be at least 10 characters"),
|
|
5
|
+
slug: z.string().min(3, "Slug is required")
|
|
6
|
+
});
|
|
7
|
+
export const commentSchema = z.object({
|
|
8
|
+
content: z.string().min(2, "Comment is too short"),
|
|
9
|
+
postId: z.string().uuid()
|
|
10
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.navigation = void 0;
|
|
7
|
+
var _intl = require("@arch-cadre/intl");
|
|
8
|
+
const navigation = exports.navigation = {
|
|
9
|
+
public: [{
|
|
10
|
+
title: (0, _intl.i18n)("Blog"),
|
|
11
|
+
url: "/blog",
|
|
12
|
+
icon: "solar:pen-2-broken"
|
|
13
|
+
}],
|
|
14
|
+
admin: {
|
|
15
|
+
[(0, _intl.i18n)("CMS")]: [{
|
|
16
|
+
title: (0, _intl.i18n)("Blog Manager"),
|
|
17
|
+
url: "/blog",
|
|
18
|
+
icon: "solar:posts-carousel-vertical-broken"
|
|
19
|
+
}]
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { i18n } from "@arch-cadre/intl";
|
|
2
|
+
export const navigation = {
|
|
3
|
+
public: [
|
|
4
|
+
{
|
|
5
|
+
title: i18n("Blog"),
|
|
6
|
+
url: "/blog",
|
|
7
|
+
icon: "solar:pen-2-broken"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
admin: {
|
|
11
|
+
[i18n("CMS")]: [
|
|
12
|
+
{
|
|
13
|
+
title: i18n("Blog Manager"),
|
|
14
|
+
url: "/blog",
|
|
15
|
+
icon: "solar:posts-carousel-vertical-broken"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
};
|
package/dist/routes.cjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.publicRoutes = exports.privateRoutes = void 0;
|
|
7
|
+
var _server = require("@arch-cadre/core/server");
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _actions = require("./actions/index.cjs");
|
|
10
|
+
var _views = require("./ui/views.cjs");
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
+
const publicRoutes = exports.publicRoutes = [{
|
|
14
|
+
path: "/blog",
|
|
15
|
+
component: async () => {
|
|
16
|
+
const posts = await (0, _actions.getPosts)();
|
|
17
|
+
return /* @__PURE__ */React.createElement(_views.BlogListPage, {
|
|
18
|
+
posts
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
auth: false
|
|
22
|
+
}, {
|
|
23
|
+
path: "/blog/:slug",
|
|
24
|
+
component: async ({
|
|
25
|
+
params
|
|
26
|
+
}) => {
|
|
27
|
+
const {
|
|
28
|
+
slug
|
|
29
|
+
} = await params;
|
|
30
|
+
const post = await (0, _actions.getPostBySlug)(slug);
|
|
31
|
+
const comments = post ? await (0, _actions.getComments)(post.id) : [];
|
|
32
|
+
const session = await (0, _server.getCurrentSession)();
|
|
33
|
+
return /* @__PURE__ */React.createElement(_views.PostDetailPage, {
|
|
34
|
+
post,
|
|
35
|
+
comments,
|
|
36
|
+
currentUser: session?.user
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
auth: false
|
|
40
|
+
}];
|
|
41
|
+
const privateRoutes = exports.privateRoutes = [{
|
|
42
|
+
path: "/blog",
|
|
43
|
+
component: async () => {
|
|
44
|
+
const posts = await (0, _actions.getPosts)();
|
|
45
|
+
return /* @__PURE__ */React.createElement(_views.BlogAdminPage, {
|
|
46
|
+
posts
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
auth: true
|
|
50
|
+
}, {
|
|
51
|
+
path: "/blog/new",
|
|
52
|
+
component: _views.CreatePostForm,
|
|
53
|
+
auth: true,
|
|
54
|
+
roles: ["admin"]
|
|
55
|
+
}, {
|
|
56
|
+
path: "/blog/edit/:id",
|
|
57
|
+
component: async ({
|
|
58
|
+
params
|
|
59
|
+
}) => {
|
|
60
|
+
const {
|
|
61
|
+
id
|
|
62
|
+
} = await params;
|
|
63
|
+
const post = await (0, _actions.getPostById)(id);
|
|
64
|
+
return /* @__PURE__ */React.createElement(_views.EditPostForm, {
|
|
65
|
+
post
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
auth: true,
|
|
69
|
+
roles: ["admin"]
|
|
70
|
+
}];
|
package/dist/routes.d.ts
ADDED
package/dist/routes.mjs
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { getCurrentSession } from "@arch-cadre/core/server";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { getComments, getPostById, getPostBySlug, getPosts } from "./actions/index.mjs";
|
|
4
|
+
import {
|
|
5
|
+
BlogAdminPage,
|
|
6
|
+
BlogListPage,
|
|
7
|
+
CreatePostForm,
|
|
8
|
+
EditPostForm,
|
|
9
|
+
PostDetailPage
|
|
10
|
+
} from "./ui/views.mjs";
|
|
11
|
+
export const publicRoutes = [
|
|
12
|
+
{
|
|
13
|
+
path: "/blog",
|
|
14
|
+
component: async () => {
|
|
15
|
+
const posts = await getPosts();
|
|
16
|
+
return /* @__PURE__ */ React.createElement(BlogListPage, { posts });
|
|
17
|
+
},
|
|
18
|
+
auth: false
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
path: "/blog/:slug",
|
|
22
|
+
component: async ({ params }) => {
|
|
23
|
+
const { slug } = await params;
|
|
24
|
+
const post = await getPostBySlug(slug);
|
|
25
|
+
const comments = post ? await getComments(post.id) : [];
|
|
26
|
+
const session = await getCurrentSession();
|
|
27
|
+
return /* @__PURE__ */ React.createElement(
|
|
28
|
+
PostDetailPage,
|
|
29
|
+
{
|
|
30
|
+
post,
|
|
31
|
+
comments,
|
|
32
|
+
currentUser: session?.user
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
auth: false
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
export const privateRoutes = [
|
|
40
|
+
{
|
|
41
|
+
path: "/blog",
|
|
42
|
+
component: async () => {
|
|
43
|
+
const posts = await getPosts();
|
|
44
|
+
return /* @__PURE__ */ React.createElement(BlogAdminPage, { posts });
|
|
45
|
+
},
|
|
46
|
+
auth: true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
path: "/blog/new",
|
|
50
|
+
component: CreatePostForm,
|
|
51
|
+
auth: true,
|
|
52
|
+
roles: ["admin"]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
path: "/blog/edit/:id",
|
|
56
|
+
component: async ({ params }) => {
|
|
57
|
+
const { id } = await params;
|
|
58
|
+
const post = await getPostById(id);
|
|
59
|
+
return /* @__PURE__ */ React.createElement(EditPostForm, { post });
|
|
60
|
+
},
|
|
61
|
+
auth: true,
|
|
62
|
+
roles: ["admin"]
|
|
63
|
+
}
|
|
64
|
+
];
|
package/dist/schema.cjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.relations = exports.postsTable = exports.commentsTable = exports.blogSchema = void 0;
|
|
7
|
+
var _core = require("@arch-cadre/core");
|
|
8
|
+
var _drizzleOrm = require("drizzle-orm");
|
|
9
|
+
var _pgCore = require("drizzle-orm/pg-core");
|
|
10
|
+
const postsTable = exports.postsTable = (0, _pgCore.pgTable)("blog_posts", {
|
|
11
|
+
id: (0, _pgCore.text)("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
|
12
|
+
title: (0, _pgCore.text)("title").notNull(),
|
|
13
|
+
slug: (0, _pgCore.text)("slug").unique().notNull(),
|
|
14
|
+
content: (0, _pgCore.text)("content").notNull(),
|
|
15
|
+
authorId: (0, _pgCore.text)("author_id").references(() => _core.userTable.id, {
|
|
16
|
+
onDelete: "cascade"
|
|
17
|
+
}).notNull(),
|
|
18
|
+
createdAt: (0, _pgCore.timestamp)("created_at").defaultNow().notNull()
|
|
19
|
+
});
|
|
20
|
+
const commentsTable = exports.commentsTable = (0, _pgCore.pgTable)("blog_comments", {
|
|
21
|
+
id: (0, _pgCore.text)("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
|
22
|
+
postId: (0, _pgCore.text)("post_id").references(() => postsTable.id, {
|
|
23
|
+
onDelete: "cascade"
|
|
24
|
+
}).notNull(),
|
|
25
|
+
authorId: (0, _pgCore.text)("author_id").references(() => _core.userTable.id, {
|
|
26
|
+
onDelete: "cascade"
|
|
27
|
+
}).notNull(),
|
|
28
|
+
content: (0, _pgCore.text)("content").notNull(),
|
|
29
|
+
createdAt: (0, _pgCore.timestamp)("created_at").defaultNow().notNull()
|
|
30
|
+
});
|
|
31
|
+
const blogSchema = exports.blogSchema = {
|
|
32
|
+
postsTable,
|
|
33
|
+
commentsTable
|
|
34
|
+
};
|
|
35
|
+
const relations = exports.relations = (0, _drizzleOrm.defineRelations)({
|
|
36
|
+
user: _core.userTable,
|
|
37
|
+
post: postsTable,
|
|
38
|
+
comment: commentsTable
|
|
39
|
+
}, r => ({
|
|
40
|
+
user: {
|
|
41
|
+
posts: r.many.post({
|
|
42
|
+
from: r.user.id,
|
|
43
|
+
to: r.post.authorId
|
|
44
|
+
}),
|
|
45
|
+
comments: r.many.comment({
|
|
46
|
+
from: r.user.id,
|
|
47
|
+
to: r.comment.authorId
|
|
48
|
+
})
|
|
49
|
+
},
|
|
50
|
+
post: {
|
|
51
|
+
comments: r.many.comment({
|
|
52
|
+
from: r.post.id,
|
|
53
|
+
to: r.comment.postId
|
|
54
|
+
})
|
|
55
|
+
},
|
|
56
|
+
comment: {
|
|
57
|
+
post: r.one.post({
|
|
58
|
+
from: r.comment.postId,
|
|
59
|
+
to: r.post.id
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}));
|
package/dist/schema.d.ts
ADDED
|
File without changes
|
package/dist/schema.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { userTable } from "@arch-cadre/core";
|
|
2
|
+
import { defineRelations } from "drizzle-orm";
|
|
3
|
+
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
4
|
+
export const postsTable = pgTable("blog_posts", {
|
|
5
|
+
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
|
6
|
+
title: text("title").notNull(),
|
|
7
|
+
slug: text("slug").unique().notNull(),
|
|
8
|
+
content: text("content").notNull(),
|
|
9
|
+
authorId: text("author_id").references(() => userTable.id, { onDelete: "cascade" }).notNull(),
|
|
10
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
11
|
+
});
|
|
12
|
+
export const commentsTable = pgTable("blog_comments", {
|
|
13
|
+
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
|
14
|
+
postId: text("post_id").references(() => postsTable.id, { onDelete: "cascade" }).notNull(),
|
|
15
|
+
authorId: text("author_id").references(() => userTable.id, { onDelete: "cascade" }).notNull(),
|
|
16
|
+
content: text("content").notNull(),
|
|
17
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
18
|
+
});
|
|
19
|
+
export const blogSchema = {
|
|
20
|
+
postsTable,
|
|
21
|
+
commentsTable
|
|
22
|
+
};
|
|
23
|
+
export const relations = defineRelations(
|
|
24
|
+
{
|
|
25
|
+
user: userTable,
|
|
26
|
+
post: postsTable,
|
|
27
|
+
comment: commentsTable
|
|
28
|
+
},
|
|
29
|
+
(r) => ({
|
|
30
|
+
user: {
|
|
31
|
+
posts: r.many.post({
|
|
32
|
+
from: r.user.id,
|
|
33
|
+
to: r.post.authorId
|
|
34
|
+
}),
|
|
35
|
+
comments: r.many.comment({
|
|
36
|
+
from: r.user.id,
|
|
37
|
+
to: r.comment.authorId
|
|
38
|
+
})
|
|
39
|
+
},
|
|
40
|
+
post: {
|
|
41
|
+
comments: r.many.comment({
|
|
42
|
+
from: r.post.id,
|
|
43
|
+
to: r.comment.postId
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
comment: {
|
|
47
|
+
post: r.one.post({
|
|
48
|
+
from: r.comment.postId,
|
|
49
|
+
to: r.post.id
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";@import "tw-animate-css";@custom-variant dark (&:is(.dark *));:root{--background:oklch(1 0 0);--foreground:oklch(0.145 0 0);--card:oklch(1 0 0);--card-foreground:oklch(0.145 0 0);--popover:oklch(1 0 0);--popover-foreground:oklch(0.145 0 0);--primary:oklch(0.205 0 0);--primary-foreground:oklch(0.985 0 0);--secondary:oklch(0.97 0 0);--secondary-foreground:oklch(0.205 0 0);--muted:oklch(0.97 0 0);--muted-foreground:oklch(0.556 0 0);--accent:oklch(0.97 0 0);--accent-foreground:oklch(0.205 0 0);--destructive:oklch(0.577 0.245 27.325);--destructive-foreground:oklch(0.577 0.245 27.325);--border:oklch(0.922 0 0);--input:oklch(0.922 0 0);--ring:oklch(0.708 0 0);--chart-1:oklch(0.646 0.222 41.116);--chart-2:oklch(0.6 0.118 184.704);--chart-3:oklch(0.398 0.07 227.392);--chart-4:oklch(0.828 0.189 84.429);--chart-5:oklch(0.769 0.188 70.08);--radius:0.625rem;--sidebar:oklch(0.985 0 0);--sidebar-foreground:oklch(0.145 0 0);--sidebar-primary:oklch(0.205 0 0);--sidebar-primary-foreground:oklch(0.985 0 0);--sidebar-accent:oklch(0.97 0 0);--sidebar-accent-foreground:oklch(0.205 0 0);--sidebar-border:oklch(0.922 0 0);--sidebar-ring:oklch(0.708 0 0)}.dark{--background:oklch(0.145 0 0);--foreground:oklch(0.985 0 0);--card:oklch(0.145 0 0);--card-foreground:oklch(0.985 0 0);--popover:oklch(0.145 0 0);--popover-foreground:oklch(0.985 0 0);--primary:oklch(0.985 0 0);--primary-foreground:oklch(0.205 0 0);--secondary:oklch(0.269 0 0);--secondary-foreground:oklch(0.985 0 0);--muted:oklch(0.269 0 0);--muted-foreground:oklch(0.708 0 0);--accent:oklch(0.269 0 0);--accent-foreground:oklch(0.985 0 0);--destructive:oklch(0.396 0.141 25.723);--destructive-foreground:oklch(0.637 0.237 25.331);--border:oklch(0.269 0 0);--input:oklch(0.269 0 0);--ring:oklch(0.439 0 0);--chart-1:oklch(0.488 0.243 264.376);--chart-2:oklch(0.696 0.17 162.48);--chart-3:oklch(0.769 0.188 70.08);--chart-4:oklch(0.627 0.265 303.9);--chart-5:oklch(0.645 0.246 16.439);--sidebar:oklch(0.205 0 0);--sidebar-foreground:oklch(0.985 0 0);--sidebar-primary:oklch(0.488 0.243 264.376);--sidebar-primary-foreground:oklch(0.985 0 0);--sidebar-accent:oklch(0.269 0 0);--sidebar-accent-foreground:oklch(0.985 0 0);--sidebar-border:oklch(0.269 0 0);--sidebar-ring:oklch(0.439 0 0)}@theme inline{--color-background:var(--background);--color-foreground:var(--foreground);--color-card:var(--card);--color-card-foreground:var(--card-foreground);--color-popover:var(--popover);--color-popover-foreground:var(--popover-foreground);--color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);--color-secondary:var(--secondary);--color-secondary-foreground:var(--secondary-foreground);--color-muted:var(--muted);--color-muted-foreground:var(--muted-foreground);--color-accent:var(--accent);--color-accent-foreground:var(--accent-foreground);--color-destructive:var(--destructive);--color-destructive-foreground:var(--destructive-foreground);--color-border:var(--border);--color-input:var(--input);--color-ring:var(--ring);--color-chart-1:var(--chart-1);--color-chart-2:var(--chart-2);--color-chart-3:var(--chart-3);--color-chart-4:var(--chart-4);--color-chart-5:var(--chart-5);--radius-sm:calc(var(--radius) - 4px);--radius-md:calc(var(--radius) - 2px);--radius-lg:var(--radius);--radius-xl:calc(var(--radius) + 4px);--color-sidebar:var(--sidebar);--color-sidebar-foreground:var(--sidebar-foreground);--color-sidebar-primary:var(--sidebar-primary);--color-sidebar-primary-foreground:var(--sidebar-primary-foreground);--color-sidebar-accent:var(--sidebar-accent);--color-sidebar-accent-foreground:var(--sidebar-accent-foreground);--color-sidebar-border:var(--sidebar-border);--color-sidebar-ring:var(--sidebar-ring)}@layer base{*{@apply border-border outline-ring/50}body{@apply bg-background text-foreground}}
|