@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,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.BlogAdminPage = BlogAdminPage;
|
|
8
|
+
exports.BlogListPage = BlogListPage;
|
|
9
|
+
exports.CreatePostForm = CreatePostForm;
|
|
10
|
+
exports.EditPostForm = EditPostForm;
|
|
11
|
+
exports.PostDetailPage = PostDetailPage;
|
|
12
|
+
var _client = require("@arch-cadre/intl/client");
|
|
13
|
+
var _zod = require("@hookform/resolvers/zod");
|
|
14
|
+
var _lucideReact = require("lucide-react");
|
|
15
|
+
var _link = _interopRequireDefault(require("next/link"));
|
|
16
|
+
var _navigation = require("next/navigation");
|
|
17
|
+
var React = _interopRequireWildcard(require("react"));
|
|
18
|
+
var _reactHookForm = require("react-hook-form");
|
|
19
|
+
var _sonner = require("sonner");
|
|
20
|
+
var _actions = require("../actions/index.cjs");
|
|
21
|
+
var _button = require("../components/ui/button.cjs");
|
|
22
|
+
var _card = require("../components/ui/card.cjs");
|
|
23
|
+
var _input = require("../components/ui/input.cjs");
|
|
24
|
+
var _table = require("../components/ui/table.cjs");
|
|
25
|
+
var _textarea = require("../components/ui/textarea.cjs");
|
|
26
|
+
var _validation = require("../lib/validation.cjs");
|
|
27
|
+
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); }
|
|
28
|
+
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; }
|
|
29
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
|
+
function BlogListPage({
|
|
31
|
+
posts = []
|
|
32
|
+
}) {
|
|
33
|
+
const {
|
|
34
|
+
t
|
|
35
|
+
} = (0, _client.useTranslation)();
|
|
36
|
+
return /* @__PURE__ */React.createElement("div", {
|
|
37
|
+
className: "max-w-4xl mx-auto p-6 space-y-8"
|
|
38
|
+
}, /* @__PURE__ */React.createElement("header", {
|
|
39
|
+
className: "border-b pb-6"
|
|
40
|
+
}, /* @__PURE__ */React.createElement("h1", {
|
|
41
|
+
className: "text-4xl font-black tracking-tighter text-primary"
|
|
42
|
+
}, t("Blog Posts")), /* @__PURE__ */React.createElement("p", {
|
|
43
|
+
className: "text-muted-foreground mt-2"
|
|
44
|
+
}, t("Reading your blog posts"))), /* @__PURE__ */React.createElement("div", {
|
|
45
|
+
className: "grid gap-6"
|
|
46
|
+
}, posts.map(post => /* @__PURE__ */React.createElement(_link.default, {
|
|
47
|
+
href: `/blog/${post.slug}`,
|
|
48
|
+
key: post.id
|
|
49
|
+
}, /* @__PURE__ */React.createElement(_card.Card, {
|
|
50
|
+
className: "group hover:shadow-lg transition-all cursor-pointer overflow-hidden border-primary/5"
|
|
51
|
+
}, /* @__PURE__ */React.createElement(_card.CardHeader, null, /* @__PURE__ */React.createElement(_card.CardTitle, {
|
|
52
|
+
className: "text-2xl group-hover:text-primary transition-colors"
|
|
53
|
+
}, post.title), /* @__PURE__ */React.createElement("div", {
|
|
54
|
+
className: "flex items-center gap-2 text-xs text-muted-foreground mt-1"
|
|
55
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.User, {
|
|
56
|
+
className: "size-3"
|
|
57
|
+
}), /* @__PURE__ */React.createElement("span", null, post.author?.name), /* @__PURE__ */React.createElement("span", null, "\u2022"), /* @__PURE__ */React.createElement("span", null, new Date(post.createdAt).toLocaleDateString()))), /* @__PURE__ */React.createElement(_card.CardContent, null, /* @__PURE__ */React.createElement("p", {
|
|
58
|
+
className: "text-secondary-foreground line-clamp-2"
|
|
59
|
+
}, post.content)))))));
|
|
60
|
+
}
|
|
61
|
+
function CommentForm({
|
|
62
|
+
postId
|
|
63
|
+
}) {
|
|
64
|
+
const router = (0, _navigation.useRouter)();
|
|
65
|
+
const {
|
|
66
|
+
t
|
|
67
|
+
} = (0, _client.useTranslation)();
|
|
68
|
+
const {
|
|
69
|
+
register,
|
|
70
|
+
handleSubmit,
|
|
71
|
+
reset,
|
|
72
|
+
formState: {
|
|
73
|
+
errors,
|
|
74
|
+
isSubmitting
|
|
75
|
+
}
|
|
76
|
+
} = (0, _reactHookForm.useForm)({
|
|
77
|
+
resolver: (0, _zod.zodResolver)(_validation.commentSchema.omit({
|
|
78
|
+
postId: true
|
|
79
|
+
}))
|
|
80
|
+
});
|
|
81
|
+
const onSubmit = async data => {
|
|
82
|
+
const result = await (0, _actions.createComment)({
|
|
83
|
+
...data,
|
|
84
|
+
postId
|
|
85
|
+
});
|
|
86
|
+
if (result.success) {
|
|
87
|
+
_sonner.toast.success(t("Comment added"));
|
|
88
|
+
reset();
|
|
89
|
+
router.refresh();
|
|
90
|
+
} else {
|
|
91
|
+
_sonner.toast.error(result.error);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return /* @__PURE__ */React.createElement("form", {
|
|
95
|
+
onSubmit: handleSubmit(onSubmit),
|
|
96
|
+
className: "space-y-4"
|
|
97
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
98
|
+
className: "space-y-1"
|
|
99
|
+
}, /* @__PURE__ */React.createElement(_textarea.Textarea, {
|
|
100
|
+
...register("content"),
|
|
101
|
+
placeholder: t("Add your comment here..."),
|
|
102
|
+
className: errors.content ? "border-destructive" : ""
|
|
103
|
+
}), errors.content && /* @__PURE__ */React.createElement("p", {
|
|
104
|
+
className: "text-xs text-destructive"
|
|
105
|
+
}, errors.content.message)), /* @__PURE__ */React.createElement(_button.Button, {
|
|
106
|
+
type: "submit",
|
|
107
|
+
disabled: isSubmitting,
|
|
108
|
+
size: "sm"
|
|
109
|
+
}, isSubmitting ? t("Please wait...") : t("Create Comment")));
|
|
110
|
+
}
|
|
111
|
+
function PostDetailPage({
|
|
112
|
+
post,
|
|
113
|
+
comments = [],
|
|
114
|
+
currentUser
|
|
115
|
+
}) {
|
|
116
|
+
const {
|
|
117
|
+
t
|
|
118
|
+
} = (0, _client.useTranslation)();
|
|
119
|
+
if (!post) return /* @__PURE__ */React.createElement("div", {
|
|
120
|
+
className: "p-20 text-center"
|
|
121
|
+
}, t("Post not found"));
|
|
122
|
+
return /* @__PURE__ */React.createElement("div", {
|
|
123
|
+
className: "max-w-3xl mx-auto p-6 space-y-10 pb-20"
|
|
124
|
+
}, /* @__PURE__ */React.createElement(_button.Button, {
|
|
125
|
+
asChild: true,
|
|
126
|
+
variant: "ghost",
|
|
127
|
+
size: "sm",
|
|
128
|
+
className: "gap-2"
|
|
129
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
130
|
+
href: "/blog"
|
|
131
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.ArrowLeft, {
|
|
132
|
+
className: "size-4"
|
|
133
|
+
}), " ", t("Back to posts"))), /* @__PURE__ */React.createElement("article", {
|
|
134
|
+
className: "space-y-6"
|
|
135
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
136
|
+
className: "space-y-2"
|
|
137
|
+
}, /* @__PURE__ */React.createElement("h1", {
|
|
138
|
+
className: "text-5xl font-black tracking-tighter leading-tight"
|
|
139
|
+
}, post.title), /* @__PURE__ */React.createElement("div", {
|
|
140
|
+
className: "flex items-center gap-3 text-muted-foreground"
|
|
141
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
142
|
+
className: "size-8 rounded-full bg-primary/10 flex items-center justify-center"
|
|
143
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.User, {
|
|
144
|
+
className: "size-4 text-primary"
|
|
145
|
+
})), /* @__PURE__ */React.createElement("div", {
|
|
146
|
+
className: "text-sm"
|
|
147
|
+
}, /* @__PURE__ */React.createElement("p", {
|
|
148
|
+
className: "font-bold text-foreground leading-none"
|
|
149
|
+
}, post.author?.name), /* @__PURE__ */React.createElement("p", {
|
|
150
|
+
className: "text-xs"
|
|
151
|
+
}, new Date(post.createdAt).toLocaleDateString())))), /* @__PURE__ */React.createElement("div", {
|
|
152
|
+
className: "prose prose-lg dark:prose-invert max-w-none whitespace-pre-wrap pt-4 border-t"
|
|
153
|
+
}, post.content)), /* @__PURE__ */React.createElement("section", {
|
|
154
|
+
className: "pt-10 border-t space-y-8"
|
|
155
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
156
|
+
className: "flex items-center gap-2"
|
|
157
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.MessageSquare, {
|
|
158
|
+
className: "size-5"
|
|
159
|
+
}), /* @__PURE__ */React.createElement("h3", {
|
|
160
|
+
className: "text-2xl font-bold tracking-tight"
|
|
161
|
+
}, t("Comments"), " (", comments.length, ")")), currentUser ? /* @__PURE__ */React.createElement("div", {
|
|
162
|
+
className: "bg-muted/30 p-6 rounded-2xl border"
|
|
163
|
+
}, /* @__PURE__ */React.createElement("p", {
|
|
164
|
+
className: "text-sm font-bold mb-4"
|
|
165
|
+
}, t("Leave a comment")), /* @__PURE__ */React.createElement(CommentForm, {
|
|
166
|
+
postId: post.id
|
|
167
|
+
})) : /* @__PURE__ */React.createElement("div", {
|
|
168
|
+
className: "p-6 bg-amber-50 border border-amber-100 rounded-2xl text-center"
|
|
169
|
+
}, /* @__PURE__ */React.createElement("p", {
|
|
170
|
+
className: "text-sm font-medium text-amber-800"
|
|
171
|
+
}, "Please", " ", /* @__PURE__ */React.createElement(_link.default, {
|
|
172
|
+
href: "/signin",
|
|
173
|
+
className: "underline font-bold"
|
|
174
|
+
}, t("Sign in")), " ", t("to join the conversation."))), /* @__PURE__ */React.createElement("div", {
|
|
175
|
+
className: "space-y-6"
|
|
176
|
+
}, comments.map(comment => /* @__PURE__ */React.createElement("div", {
|
|
177
|
+
key: comment.id,
|
|
178
|
+
className: "flex gap-4"
|
|
179
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
180
|
+
className: "size-10 rounded-full bg-muted flex items-center justify-center shrink-0"
|
|
181
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.User, {
|
|
182
|
+
className: "size-5 opacity-40"
|
|
183
|
+
})), /* @__PURE__ */React.createElement("div", {
|
|
184
|
+
className: "space-y-1"
|
|
185
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
186
|
+
className: "flex items-center gap-2"
|
|
187
|
+
}, /* @__PURE__ */React.createElement("span", {
|
|
188
|
+
className: "font-bold text-sm"
|
|
189
|
+
}, comment.author?.name), /* @__PURE__ */React.createElement("span", {
|
|
190
|
+
className: "text-[10px] opacity-50"
|
|
191
|
+
}, new Date(comment.createdAt).toLocaleDateString())), /* @__PURE__ */React.createElement("p", {
|
|
192
|
+
className: "text-sm text-secondary-foreground leading-relaxed"
|
|
193
|
+
}, comment.content)))), comments.length === 0 && /* @__PURE__ */React.createElement("p", {
|
|
194
|
+
className: "text-center text-muted-foreground text-sm py-10 italic"
|
|
195
|
+
}, t("No comments yet. Be the first to comment!")))));
|
|
196
|
+
}
|
|
197
|
+
function BlogAdminPage({
|
|
198
|
+
posts = []
|
|
199
|
+
}) {
|
|
200
|
+
const router = (0, _navigation.useRouter)();
|
|
201
|
+
const {
|
|
202
|
+
t
|
|
203
|
+
} = (0, _client.useTranslation)();
|
|
204
|
+
const handleDelete = async id => {
|
|
205
|
+
if (!confirm(t("Confirm deletion of this post?"))) return;
|
|
206
|
+
const result = await (0, _actions.deletePost)(id);
|
|
207
|
+
if (result.success) {
|
|
208
|
+
_sonner.toast.success(t("Post deleted"));
|
|
209
|
+
router.refresh();
|
|
210
|
+
} else {
|
|
211
|
+
_sonner.toast.error(t("UnexpectedError") + result.error);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
return /* @__PURE__ */React.createElement("div", {
|
|
215
|
+
className: "p-6 space-y-6"
|
|
216
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
217
|
+
className: "flex justify-between items-center"
|
|
218
|
+
}, /* @__PURE__ */React.createElement("h1", {
|
|
219
|
+
className: "text-3xl font-black tracking-tight text-foreground"
|
|
220
|
+
}, t("Blog posts")), /* @__PURE__ */React.createElement(_button.Button, {
|
|
221
|
+
asChild: true,
|
|
222
|
+
size: "sm",
|
|
223
|
+
className: "gap-2"
|
|
224
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
225
|
+
href: "/kryo/blog/new"
|
|
226
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.Plus, {
|
|
227
|
+
className: "size-4"
|
|
228
|
+
}), " ", t("New Post")))), /* @__PURE__ */React.createElement(_card.Card, {
|
|
229
|
+
className: "border-primary/10 shadow-sm overflow-hidden"
|
|
230
|
+
}, /* @__PURE__ */React.createElement(_table.Table, null, /* @__PURE__ */React.createElement(_table.TableHeader, null, /* @__PURE__ */React.createElement(_table.TableRow, null, /* @__PURE__ */React.createElement(_table.TableHead, {
|
|
231
|
+
className: "w-[40%]"
|
|
232
|
+
}, t("Title")), /* @__PURE__ */React.createElement(_table.TableHead, null, t("Author")), /* @__PURE__ */React.createElement(_table.TableHead, null, t("Date")), /* @__PURE__ */React.createElement(_table.TableHead, {
|
|
233
|
+
className: "text-right"
|
|
234
|
+
}, t("Actions")))), /* @__PURE__ */React.createElement(_table.TableBody, null, posts.length === 0 && /* @__PURE__ */React.createElement(_table.TableRow, null, /* @__PURE__ */React.createElement(_table.TableCell, {
|
|
235
|
+
colSpan: 4,
|
|
236
|
+
className: "h-24 text-center text-muted-foreground italic"
|
|
237
|
+
}, t("No posts found. Create your first post!"))), posts.map(post => /* @__PURE__ */React.createElement(_table.TableRow, {
|
|
238
|
+
key: post.id,
|
|
239
|
+
className: "transition-colors"
|
|
240
|
+
}, /* @__PURE__ */React.createElement(_table.TableCell, {
|
|
241
|
+
className: "font-bold"
|
|
242
|
+
}, post.title), /* @__PURE__ */React.createElement(_table.TableCell, {
|
|
243
|
+
className: "text-xs"
|
|
244
|
+
}, post.author?.name), /* @__PURE__ */React.createElement(_table.TableCell, {
|
|
245
|
+
className: "text-muted-foreground text-xs"
|
|
246
|
+
}, new Date(post.createdAt).toLocaleDateString()), /* @__PURE__ */React.createElement(_table.TableCell, {
|
|
247
|
+
className: "text-right"
|
|
248
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
249
|
+
className: "flex justify-end gap-2"
|
|
250
|
+
}, /* @__PURE__ */React.createElement(_button.Button, {
|
|
251
|
+
asChild: true,
|
|
252
|
+
variant: "ghost",
|
|
253
|
+
size: "icon",
|
|
254
|
+
className: "size-8"
|
|
255
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
256
|
+
href: `/blog/${post.slug}`,
|
|
257
|
+
target: "_blank"
|
|
258
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.Eye, {
|
|
259
|
+
className: "size-4"
|
|
260
|
+
}))), /* @__PURE__ */React.createElement(_button.Button, {
|
|
261
|
+
asChild: true,
|
|
262
|
+
variant: "ghost",
|
|
263
|
+
size: "icon",
|
|
264
|
+
className: "size-8"
|
|
265
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
266
|
+
href: `/kryo/blog/edit/${post.id}`
|
|
267
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.Pencil, {
|
|
268
|
+
className: "size-4"
|
|
269
|
+
}))), /* @__PURE__ */React.createElement(_button.Button, {
|
|
270
|
+
variant: "ghost",
|
|
271
|
+
size: "icon",
|
|
272
|
+
className: "size-8 text-destructive hover:text-destructive hover:bg-destructive/10",
|
|
273
|
+
onClick: () => handleDelete(post.id)
|
|
274
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.Trash2, {
|
|
275
|
+
className: "size-4"
|
|
276
|
+
}))))))))));
|
|
277
|
+
}
|
|
278
|
+
function CreatePostForm() {
|
|
279
|
+
const router = (0, _navigation.useRouter)();
|
|
280
|
+
const {
|
|
281
|
+
t
|
|
282
|
+
} = (0, _client.useTranslation)();
|
|
283
|
+
const {
|
|
284
|
+
register,
|
|
285
|
+
handleSubmit,
|
|
286
|
+
formState: {
|
|
287
|
+
errors,
|
|
288
|
+
isSubmitting
|
|
289
|
+
}
|
|
290
|
+
} = (0, _reactHookForm.useForm)({
|
|
291
|
+
resolver: (0, _zod.zodResolver)(_validation.postSchema.omit({
|
|
292
|
+
slug: true
|
|
293
|
+
}))
|
|
294
|
+
});
|
|
295
|
+
const onSubmit = async data => {
|
|
296
|
+
const slug = data.title.toLowerCase().replace(/ /g, "-").replace(/[^\w-]+/g, "");
|
|
297
|
+
const result = await (0, _actions.createPost)({
|
|
298
|
+
...data,
|
|
299
|
+
slug
|
|
300
|
+
});
|
|
301
|
+
if (result.success) {
|
|
302
|
+
_sonner.toast.success(t("Post created"));
|
|
303
|
+
router.push("/kryo/blog");
|
|
304
|
+
router.refresh();
|
|
305
|
+
} else {
|
|
306
|
+
_sonner.toast.error(t("UnexpectedError") + result.error);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
return /* @__PURE__ */React.createElement("div", {
|
|
310
|
+
className: "max-w-2xl mx-auto p-6 space-y-6"
|
|
311
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
312
|
+
className: "flex items-center gap-4"
|
|
313
|
+
}, /* @__PURE__ */React.createElement(_button.Button, {
|
|
314
|
+
asChild: true,
|
|
315
|
+
variant: "outline",
|
|
316
|
+
size: "icon",
|
|
317
|
+
className: "rounded-lg"
|
|
318
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
319
|
+
href: "/kryo/blog"
|
|
320
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.ArrowLeft, {
|
|
321
|
+
className: "size-4"
|
|
322
|
+
}))), /* @__PURE__ */React.createElement("h1", {
|
|
323
|
+
className: "text-2xl font-black text-foreground"
|
|
324
|
+
}, t("New Post"))), /* @__PURE__ */React.createElement(_card.Card, {
|
|
325
|
+
className: "border-primary/10 shadow-lg"
|
|
326
|
+
}, /* @__PURE__ */React.createElement(_card.CardContent, {
|
|
327
|
+
className: "pt-6"
|
|
328
|
+
}, /* @__PURE__ */React.createElement("form", {
|
|
329
|
+
onSubmit: handleSubmit(onSubmit),
|
|
330
|
+
className: "space-y-6"
|
|
331
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
332
|
+
className: "space-y-2"
|
|
333
|
+
}, /* @__PURE__ */React.createElement("label", {
|
|
334
|
+
className: "text-xs font-black uppercase tracking-widest opacity-50 px-1"
|
|
335
|
+
}, t("Title")), /* @__PURE__ */React.createElement(_input.Input, {
|
|
336
|
+
...register("title"),
|
|
337
|
+
className: errors.title ? "border-destructive font-bold" : "font-bold",
|
|
338
|
+
placeholder: t("Title of your post")
|
|
339
|
+
}), errors.title && /* @__PURE__ */React.createElement("p", {
|
|
340
|
+
className: "text-xs text-destructive font-bold"
|
|
341
|
+
}, errors.title.message)), /* @__PURE__ */React.createElement("div", {
|
|
342
|
+
className: "space-y-2"
|
|
343
|
+
}, /* @__PURE__ */React.createElement("label", {
|
|
344
|
+
className: "text-xs font-black uppercase tracking-widest opacity-50 px-1"
|
|
345
|
+
}, t("Content")), /* @__PURE__ */React.createElement(_textarea.Textarea, {
|
|
346
|
+
...register("content"),
|
|
347
|
+
rows: 12,
|
|
348
|
+
className: errors.content ? "border-destructive resize-none" : "resize-none",
|
|
349
|
+
placeholder: t("Content of your post")
|
|
350
|
+
}), errors.content && /* @__PURE__ */React.createElement("p", {
|
|
351
|
+
className: "text-xs text-destructive font-bold"
|
|
352
|
+
}, errors.content.message)), /* @__PURE__ */React.createElement(_button.Button, {
|
|
353
|
+
type: "submit",
|
|
354
|
+
disabled: isSubmitting,
|
|
355
|
+
className: "w-full text-sm uppercase tracking-widest transition-all"
|
|
356
|
+
}, isSubmitting ? t("Please wait...") : t("Publish"))))));
|
|
357
|
+
}
|
|
358
|
+
function EditPostForm({
|
|
359
|
+
post
|
|
360
|
+
}) {
|
|
361
|
+
const router = (0, _navigation.useRouter)();
|
|
362
|
+
const {
|
|
363
|
+
t
|
|
364
|
+
} = (0, _client.useTranslation)();
|
|
365
|
+
const {
|
|
366
|
+
register,
|
|
367
|
+
handleSubmit,
|
|
368
|
+
formState: {
|
|
369
|
+
errors,
|
|
370
|
+
isSubmitting
|
|
371
|
+
}
|
|
372
|
+
} = (0, _reactHookForm.useForm)({
|
|
373
|
+
resolver: (0, _zod.zodResolver)(_validation.postSchema),
|
|
374
|
+
defaultValues: {
|
|
375
|
+
title: post.title,
|
|
376
|
+
content: post.content,
|
|
377
|
+
slug: post.slug
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
const onSubmit = async data => {
|
|
381
|
+
const result = await (0, _actions.updatePost)(post.id, data);
|
|
382
|
+
if (result.success) {
|
|
383
|
+
_sonner.toast.success(t("Post updated"));
|
|
384
|
+
router.push("/kryo/blog");
|
|
385
|
+
router.refresh();
|
|
386
|
+
} else {
|
|
387
|
+
_sonner.toast.error(t("UnexpectedError") + result.error);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
return /* @__PURE__ */React.createElement("div", {
|
|
391
|
+
className: "max-w-2xl mx-auto p-6 space-y-6"
|
|
392
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
393
|
+
className: "flex items-center gap-4"
|
|
394
|
+
}, /* @__PURE__ */React.createElement(_button.Button, {
|
|
395
|
+
asChild: true,
|
|
396
|
+
variant: "outline",
|
|
397
|
+
size: "icon",
|
|
398
|
+
className: "rounded-lg"
|
|
399
|
+
}, /* @__PURE__ */React.createElement(_link.default, {
|
|
400
|
+
href: "/kryo/blog"
|
|
401
|
+
}, /* @__PURE__ */React.createElement(_lucideReact.ArrowLeft, {
|
|
402
|
+
className: "size-4"
|
|
403
|
+
}))), /* @__PURE__ */React.createElement("h1", {
|
|
404
|
+
className: "text-2xl font-black text-foreground"
|
|
405
|
+
}, t("Edit Post"))), /* @__PURE__ */React.createElement(_card.Card, {
|
|
406
|
+
className: "border-primary/10 shadow-lg"
|
|
407
|
+
}, /* @__PURE__ */React.createElement(_card.CardContent, {
|
|
408
|
+
className: "pt-6"
|
|
409
|
+
}, /* @__PURE__ */React.createElement("form", {
|
|
410
|
+
onSubmit: handleSubmit(onSubmit),
|
|
411
|
+
className: "space-y-6"
|
|
412
|
+
}, /* @__PURE__ */React.createElement("div", {
|
|
413
|
+
className: "space-y-2"
|
|
414
|
+
}, /* @__PURE__ */React.createElement("label", {
|
|
415
|
+
className: "text-xs font-black uppercase tracking-widest opacity-50 px-1"
|
|
416
|
+
}, t("Title")), /* @__PURE__ */React.createElement(_input.Input, {
|
|
417
|
+
...register("title"),
|
|
418
|
+
className: errors.title ? "border-destructive font-bold" : "font-bold",
|
|
419
|
+
placeholder: t("Title of your post")
|
|
420
|
+
}), errors.title && /* @__PURE__ */React.createElement("p", {
|
|
421
|
+
className: "text-xs text-destructive font-bold"
|
|
422
|
+
}, errors.title.message)), /* @__PURE__ */React.createElement("div", {
|
|
423
|
+
className: "space-y-2"
|
|
424
|
+
}, /* @__PURE__ */React.createElement("label", {
|
|
425
|
+
className: "text-xs font-black uppercase tracking-widest opacity-50 px-1"
|
|
426
|
+
}, t("Slug")), /* @__PURE__ */React.createElement(_input.Input, {
|
|
427
|
+
...register("slug"),
|
|
428
|
+
className: errors.slug ? "border-destructive font-mono text-sm" : "font-mono text-sm",
|
|
429
|
+
placeholder: t("Slug URL")
|
|
430
|
+
}), errors.slug && /* @__PURE__ */React.createElement("p", {
|
|
431
|
+
className: "text-xs text-destructive font-bold"
|
|
432
|
+
}, errors.slug.message)), /* @__PURE__ */React.createElement("div", {
|
|
433
|
+
className: "space-y-2"
|
|
434
|
+
}, /* @__PURE__ */React.createElement("label", {
|
|
435
|
+
className: "text-xs font-black uppercase tracking-widest opacity-50 px-1"
|
|
436
|
+
}, t("Content")), /* @__PURE__ */React.createElement(_textarea.Textarea, {
|
|
437
|
+
...register("content"),
|
|
438
|
+
rows: 12,
|
|
439
|
+
className: errors.content ? "border-destructive resize-none" : "resize-none",
|
|
440
|
+
placeholder: t("Content of your post")
|
|
441
|
+
}), errors.content && /* @__PURE__ */React.createElement("p", {
|
|
442
|
+
className: "text-xs text-destructive font-bold"
|
|
443
|
+
}, errors.content.message)), /* @__PURE__ */React.createElement(_button.Button, {
|
|
444
|
+
type: "submit",
|
|
445
|
+
disabled: isSubmitting,
|
|
446
|
+
className: "w-full text-sm uppercase tracking-widest transition-all"
|
|
447
|
+
}, isSubmitting ? t("Please wait...") : t("Update"))))));
|
|
448
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export declare function BlogListPage({ posts }: {
|
|
3
|
+
posts?: any[];
|
|
4
|
+
}): React.JSX.Element;
|
|
5
|
+
export declare function PostDetailPage({ post, comments, currentUser, }: {
|
|
6
|
+
post: any;
|
|
7
|
+
comments: any[];
|
|
8
|
+
currentUser?: any;
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
export declare function BlogAdminPage({ posts }: {
|
|
11
|
+
posts: any[];
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
export declare function CreatePostForm(): React.JSX.Element;
|
|
14
|
+
export declare function EditPostForm({ post }: {
|
|
15
|
+
post: any;
|
|
16
|
+
}): React.JSX.Element;
|