@ampless/admin 0.2.0-alpha.0
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/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/api/index.d.ts +24 -0
- package/dist/api/index.js +41 -0
- package/dist/chunk-BN6BW7MP.js +2074 -0
- package/dist/chunk-TJR3ALRJ.js +575 -0
- package/dist/components/index.d.ts +169 -0
- package/dist/components/index.js +44 -0
- package/dist/i18n-ByHM_Bho.d.ts +738 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.js +115 -0
- package/dist/pages/index.d.ts +90 -0
- package/dist/pages/index.js +839 -0
- package/package.json +83 -0
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
import {
|
|
2
|
+
I18nProvider,
|
|
3
|
+
MediaUploader,
|
|
4
|
+
PostForm,
|
|
5
|
+
Sidebar,
|
|
6
|
+
SiteSelector,
|
|
7
|
+
SiteSettingsForm,
|
|
8
|
+
ThemeSettingsForm,
|
|
9
|
+
setAdminCmsConfigClient,
|
|
10
|
+
useT
|
|
11
|
+
} from "../chunk-BN6BW7MP.js";
|
|
12
|
+
import {
|
|
13
|
+
readAdminSiteIdFromCookie,
|
|
14
|
+
setAdminCmsConfig,
|
|
15
|
+
setAdminMediaContext
|
|
16
|
+
} from "../chunk-TJR3ALRJ.js";
|
|
17
|
+
|
|
18
|
+
// src/pages/admin-layout.tsx
|
|
19
|
+
import { redirect } from "next/navigation";
|
|
20
|
+
|
|
21
|
+
// src/pages/admin-providers.tsx
|
|
22
|
+
import { useEffect } from "react";
|
|
23
|
+
|
|
24
|
+
// src/lib/amplify-client.ts
|
|
25
|
+
import { Amplify } from "aws-amplify";
|
|
26
|
+
var configured = false;
|
|
27
|
+
function configureAmplify(outputs) {
|
|
28
|
+
if (configured) return;
|
|
29
|
+
Amplify.configure(outputs, { ssr: true });
|
|
30
|
+
configured = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/lib/posts-provider.ts
|
|
34
|
+
import { generateClient } from "aws-amplify/api";
|
|
35
|
+
import {
|
|
36
|
+
setPostsProvider,
|
|
37
|
+
composeSiteIdStatus,
|
|
38
|
+
composeSiteIdSlug
|
|
39
|
+
} from "ampless";
|
|
40
|
+
function encodeBody(value) {
|
|
41
|
+
if (typeof value === "string") return value;
|
|
42
|
+
return JSON.stringify(value ?? null);
|
|
43
|
+
}
|
|
44
|
+
function decodeBody(value) {
|
|
45
|
+
if (typeof value !== "string") return value;
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(value);
|
|
48
|
+
} catch {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function toCorePost(p) {
|
|
53
|
+
return {
|
|
54
|
+
postId: p.postId,
|
|
55
|
+
siteId: p.siteId,
|
|
56
|
+
slug: p.slug,
|
|
57
|
+
title: p.title,
|
|
58
|
+
excerpt: p.excerpt ?? void 0,
|
|
59
|
+
format: p.format ?? "markdown",
|
|
60
|
+
body: decodeBody(p.body),
|
|
61
|
+
status: p.status ?? "draft",
|
|
62
|
+
publishedAt: p.publishedAt ?? void 0,
|
|
63
|
+
tags: (p.tags ?? []).filter((t) => typeof t === "string")
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function postTagEntries(post) {
|
|
67
|
+
if (post.status !== "published" || !post.publishedAt || !post.tags?.length) return [];
|
|
68
|
+
return post.tags.map((tag) => ({
|
|
69
|
+
siteIdTag: `${post.siteId}#${tag}`,
|
|
70
|
+
publishedAtPostId: `${post.publishedAt}#${post.postId}`
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
function entryKey(e) {
|
|
74
|
+
return `${e.siteIdTag}|${e.publishedAtPostId}`;
|
|
75
|
+
}
|
|
76
|
+
var installed = false;
|
|
77
|
+
function installAdminPostsProvider() {
|
|
78
|
+
if (installed) return;
|
|
79
|
+
installed = true;
|
|
80
|
+
const client = generateClient();
|
|
81
|
+
async function syncPostTags(post, oldPost) {
|
|
82
|
+
const oldEntries = oldPost ? postTagEntries(oldPost) : [];
|
|
83
|
+
const newEntries = postTagEntries(post);
|
|
84
|
+
const oldKeys = new Set(oldEntries.map(entryKey));
|
|
85
|
+
const newKeys = new Set(newEntries.map(entryKey));
|
|
86
|
+
await Promise.all(
|
|
87
|
+
oldEntries.filter((e) => !newKeys.has(entryKey(e))).map((e) => client.models.PostTag.delete(e))
|
|
88
|
+
);
|
|
89
|
+
await Promise.all(
|
|
90
|
+
newEntries.filter((e) => !oldKeys.has(entryKey(e))).map(
|
|
91
|
+
(e) => client.models.PostTag.create({
|
|
92
|
+
siteIdTag: e.siteIdTag,
|
|
93
|
+
publishedAtPostId: e.publishedAtPostId,
|
|
94
|
+
siteId: post.siteId,
|
|
95
|
+
tag: e.siteIdTag.slice(post.siteId.length + 1),
|
|
96
|
+
postId: post.postId,
|
|
97
|
+
publishedAt: post.publishedAt,
|
|
98
|
+
slug: post.slug,
|
|
99
|
+
title: post.title,
|
|
100
|
+
excerpt: post.excerpt,
|
|
101
|
+
tags: post.tags ?? []
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
await Promise.all(
|
|
106
|
+
newEntries.filter((e) => oldKeys.has(entryKey(e))).map(
|
|
107
|
+
(e) => client.models.PostTag.update({
|
|
108
|
+
siteIdTag: e.siteIdTag,
|
|
109
|
+
publishedAtPostId: e.publishedAtPostId,
|
|
110
|
+
slug: post.slug,
|
|
111
|
+
title: post.title,
|
|
112
|
+
excerpt: post.excerpt,
|
|
113
|
+
tags: post.tags ?? []
|
|
114
|
+
})
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const provider = {
|
|
119
|
+
async list(opts = {}) {
|
|
120
|
+
const siteId = opts.siteId ?? "default";
|
|
121
|
+
const status = opts.status ?? "published";
|
|
122
|
+
const filter = { siteId: { eq: siteId } };
|
|
123
|
+
if (status !== "all") filter.status = { eq: status };
|
|
124
|
+
const { data } = await client.models.Post.list({ filter, limit: opts.limit ?? 100 });
|
|
125
|
+
return data.map(toCorePost);
|
|
126
|
+
},
|
|
127
|
+
async get(slug, opts = {}) {
|
|
128
|
+
const siteId = opts.siteId ?? "default";
|
|
129
|
+
const { data } = await client.models.Post.list({
|
|
130
|
+
filter: { siteId: { eq: siteId }, slug: { eq: slug } },
|
|
131
|
+
limit: 1
|
|
132
|
+
});
|
|
133
|
+
return data[0] ? toCorePost(data[0]) : null;
|
|
134
|
+
},
|
|
135
|
+
async getById(postId, opts = {}) {
|
|
136
|
+
const siteId = opts.siteId ?? "default";
|
|
137
|
+
const { data } = await client.models.Post.get({ siteId, postId });
|
|
138
|
+
return data ? toCorePost(data) : null;
|
|
139
|
+
},
|
|
140
|
+
async create(input) {
|
|
141
|
+
const postId = input.postId ?? `post-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
142
|
+
const { data, errors } = await client.models.Post.create({
|
|
143
|
+
siteId: input.siteId,
|
|
144
|
+
postId,
|
|
145
|
+
slug: input.slug,
|
|
146
|
+
title: input.title,
|
|
147
|
+
excerpt: input.excerpt,
|
|
148
|
+
format: input.format,
|
|
149
|
+
body: encodeBody(input.body),
|
|
150
|
+
status: input.status,
|
|
151
|
+
publishedAt: input.publishedAt,
|
|
152
|
+
tags: input.tags,
|
|
153
|
+
// Denormalized GSI keys. Must match every change to slug /
|
|
154
|
+
// status — see the update() branch below.
|
|
155
|
+
siteIdStatus: composeSiteIdStatus(input.siteId, input.status),
|
|
156
|
+
siteIdSlug: composeSiteIdSlug(input.siteId, input.slug)
|
|
157
|
+
});
|
|
158
|
+
if (errors || !data) throw new Error(errors?.[0]?.message ?? "Failed to create post");
|
|
159
|
+
const created = toCorePost(data);
|
|
160
|
+
await syncPostTags(created, null);
|
|
161
|
+
return created;
|
|
162
|
+
},
|
|
163
|
+
async update(postId, patch, opts = {}) {
|
|
164
|
+
const siteId = opts.siteId ?? "default";
|
|
165
|
+
const oldPost = await this.getById(postId, { siteId });
|
|
166
|
+
const nextStatus = patch.status ?? oldPost?.status;
|
|
167
|
+
const nextSlug = patch.slug ?? oldPost?.slug;
|
|
168
|
+
const { data, errors } = await client.models.Post.update({
|
|
169
|
+
siteId,
|
|
170
|
+
postId,
|
|
171
|
+
...patch.slug !== void 0 && { slug: patch.slug },
|
|
172
|
+
...patch.title !== void 0 && { title: patch.title },
|
|
173
|
+
...patch.excerpt !== void 0 && { excerpt: patch.excerpt },
|
|
174
|
+
...patch.format !== void 0 && { format: patch.format },
|
|
175
|
+
...patch.body !== void 0 && { body: encodeBody(patch.body) },
|
|
176
|
+
...patch.status !== void 0 && { status: patch.status },
|
|
177
|
+
...patch.publishedAt !== void 0 && { publishedAt: patch.publishedAt },
|
|
178
|
+
...patch.tags !== void 0 && { tags: patch.tags },
|
|
179
|
+
...patch.status !== void 0 && nextStatus && { siteIdStatus: composeSiteIdStatus(siteId, nextStatus) },
|
|
180
|
+
...patch.slug !== void 0 && nextSlug && { siteIdSlug: composeSiteIdSlug(siteId, nextSlug) }
|
|
181
|
+
});
|
|
182
|
+
if (errors || !data) throw new Error(errors?.[0]?.message ?? "Failed to update post");
|
|
183
|
+
const updated = toCorePost(data);
|
|
184
|
+
await syncPostTags(updated, oldPost);
|
|
185
|
+
return updated;
|
|
186
|
+
},
|
|
187
|
+
async remove(postId, opts = {}) {
|
|
188
|
+
const siteId = opts.siteId ?? "default";
|
|
189
|
+
const oldPost = await this.getById(postId, { siteId });
|
|
190
|
+
if (oldPost) {
|
|
191
|
+
await syncPostTags({ ...oldPost, status: "draft" }, oldPost);
|
|
192
|
+
}
|
|
193
|
+
const { errors } = await client.models.Post.delete({ siteId, postId });
|
|
194
|
+
if (errors) throw new Error(errors[0]?.message ?? "Failed to delete post");
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
setPostsProvider(provider);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/lib/kv-provider.ts
|
|
201
|
+
import { generateClient as generateClient2 } from "aws-amplify/api";
|
|
202
|
+
import { setKvStore } from "ampless";
|
|
203
|
+
var installed2 = false;
|
|
204
|
+
function installAdminKvProvider() {
|
|
205
|
+
if (installed2) return;
|
|
206
|
+
installed2 = true;
|
|
207
|
+
const client = generateClient2();
|
|
208
|
+
function requireModel() {
|
|
209
|
+
const m = client.models.KvStore;
|
|
210
|
+
if (!m) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
"KvStore model is not available on the AppSync client. Did you redeploy the sandbox? Run `npx ampx sandbox` and wait for it to finish, then reload this page."
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
return m;
|
|
216
|
+
}
|
|
217
|
+
function encodeValue(value) {
|
|
218
|
+
return JSON.stringify(value ?? null);
|
|
219
|
+
}
|
|
220
|
+
function decodeValue(raw) {
|
|
221
|
+
if (typeof raw !== "string") return raw;
|
|
222
|
+
try {
|
|
223
|
+
return JSON.parse(raw);
|
|
224
|
+
} catch {
|
|
225
|
+
return raw;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const store = {
|
|
229
|
+
async get(pk, sk) {
|
|
230
|
+
const model = requireModel();
|
|
231
|
+
const { data } = await model.get({ pk, sk });
|
|
232
|
+
return data ? decodeValue(data.value) : null;
|
|
233
|
+
},
|
|
234
|
+
async query(pk) {
|
|
235
|
+
const model = requireModel();
|
|
236
|
+
const { data } = await model.list({
|
|
237
|
+
filter: { pk: { eq: pk } },
|
|
238
|
+
limit: 1e3
|
|
239
|
+
});
|
|
240
|
+
return (data ?? []).map((row) => ({
|
|
241
|
+
pk: row.pk,
|
|
242
|
+
sk: row.sk,
|
|
243
|
+
value: decodeValue(row.value),
|
|
244
|
+
ttl: row.ttl ?? void 0
|
|
245
|
+
}));
|
|
246
|
+
},
|
|
247
|
+
async put(pk, sk, value, opts) {
|
|
248
|
+
const model = requireModel();
|
|
249
|
+
const ttl = opts?.ttlSeconds ? Math.floor(Date.now() / 1e3) + opts.ttlSeconds : void 0;
|
|
250
|
+
const existing = await model.get({ pk, sk });
|
|
251
|
+
if (existing.data) {
|
|
252
|
+
const { errors } = await model.update({
|
|
253
|
+
pk,
|
|
254
|
+
sk,
|
|
255
|
+
value: encodeValue(value),
|
|
256
|
+
ttl: ttl ?? null
|
|
257
|
+
});
|
|
258
|
+
if (errors) throw new Error(errors[0]?.message ?? "KvStore.update failed");
|
|
259
|
+
} else {
|
|
260
|
+
const { errors } = await model.create({
|
|
261
|
+
pk,
|
|
262
|
+
sk,
|
|
263
|
+
value: encodeValue(value),
|
|
264
|
+
ttl
|
|
265
|
+
});
|
|
266
|
+
if (errors) throw new Error(errors[0]?.message ?? "KvStore.create failed");
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
async remove(pk, sk) {
|
|
270
|
+
const model = requireModel();
|
|
271
|
+
const { errors } = await model.delete({ pk, sk });
|
|
272
|
+
if (errors) throw new Error(errors[0]?.message ?? "KvStore.delete failed");
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
setKvStore(store);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// src/pages/admin-providers.tsx
|
|
279
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
280
|
+
function AdminProviders({ outputs, cmsConfig, children }) {
|
|
281
|
+
configureAmplify(outputs);
|
|
282
|
+
setAdminCmsConfig(cmsConfig);
|
|
283
|
+
setAdminCmsConfigClient(cmsConfig);
|
|
284
|
+
setAdminMediaContext(outputs, cmsConfig);
|
|
285
|
+
useEffect(() => {
|
|
286
|
+
installAdminPostsProvider();
|
|
287
|
+
installAdminKvProvider();
|
|
288
|
+
}, []);
|
|
289
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/pages/admin-layout.tsx
|
|
293
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
294
|
+
function createAdminLayout(admin) {
|
|
295
|
+
async function AdminLayout({ children }) {
|
|
296
|
+
const session = await admin.getServerSession();
|
|
297
|
+
if (!admin.isEditor(session)) {
|
|
298
|
+
redirect("/login");
|
|
299
|
+
}
|
|
300
|
+
const sites = admin.adminSiteOptions();
|
|
301
|
+
const currentSiteId = await admin.currentAdminSiteId();
|
|
302
|
+
const selector = sites.length > 0 ? /* @__PURE__ */ jsx2(SiteSelector, { current: currentSiteId, sites }) : null;
|
|
303
|
+
return /* @__PURE__ */ jsx2(AdminProviders, { outputs: admin.outputs, cmsConfig: admin.cmsConfig, children: /* @__PURE__ */ jsx2(I18nProvider, { locale: admin.locale, dict: admin.dict, children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-screen", children: [
|
|
304
|
+
/* @__PURE__ */ jsx2(Sidebar, { email: session.email, siteSelector: selector }),
|
|
305
|
+
/* @__PURE__ */ jsx2("main", { className: "flex-1 overflow-auto", children })
|
|
306
|
+
] }) }) });
|
|
307
|
+
}
|
|
308
|
+
return AdminLayout;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/pages/dashboard.tsx
|
|
312
|
+
import { useEffect as useEffect2, useState } from "react";
|
|
313
|
+
import Link from "next/link";
|
|
314
|
+
import { listPosts } from "ampless";
|
|
315
|
+
import { Button, Card, CardContent, CardHeader, CardTitle } from "@ampless/runtime/ui";
|
|
316
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
317
|
+
function AdminDashboard() {
|
|
318
|
+
const t = useT();
|
|
319
|
+
const [posts, setPosts] = useState([]);
|
|
320
|
+
const [loading, setLoading] = useState(true);
|
|
321
|
+
useEffect2(() => {
|
|
322
|
+
listPosts({ status: "all" }).then(setPosts).finally(() => setLoading(false));
|
|
323
|
+
}, []);
|
|
324
|
+
const published = posts.filter((p) => p.status === "published").length;
|
|
325
|
+
const drafts = posts.filter((p) => p.status === "draft").length;
|
|
326
|
+
return /* @__PURE__ */ jsxs2("div", { className: "p-8", children: [
|
|
327
|
+
/* @__PURE__ */ jsxs2("div", { className: "mb-8 flex items-center justify-between", children: [
|
|
328
|
+
/* @__PURE__ */ jsx3("h1", { className: "text-3xl font-bold", children: t("dashboard.title") }),
|
|
329
|
+
/* @__PURE__ */ jsx3(Button, { asChild: true, children: /* @__PURE__ */ jsx3(Link, { href: "/admin/posts/new", children: t("dashboard.newPost") }) })
|
|
330
|
+
] }),
|
|
331
|
+
/* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", children: [
|
|
332
|
+
/* @__PURE__ */ jsxs2(Card, { children: [
|
|
333
|
+
/* @__PURE__ */ jsx3(CardHeader, { children: /* @__PURE__ */ jsx3(CardTitle, { children: t("dashboard.totalPosts") }) }),
|
|
334
|
+
/* @__PURE__ */ jsxs2(CardContent, { children: [
|
|
335
|
+
/* @__PURE__ */ jsx3("p", { className: "text-3xl font-bold", children: loading ? "\u2014" : posts.length }),
|
|
336
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: t("dashboard.totalLabel") })
|
|
337
|
+
] })
|
|
338
|
+
] }),
|
|
339
|
+
/* @__PURE__ */ jsxs2(Card, { children: [
|
|
340
|
+
/* @__PURE__ */ jsx3(CardHeader, { children: /* @__PURE__ */ jsx3(CardTitle, { children: t("dashboard.published") }) }),
|
|
341
|
+
/* @__PURE__ */ jsx3(CardContent, { children: /* @__PURE__ */ jsx3("p", { className: "text-3xl font-bold", children: loading ? "\u2014" : published }) })
|
|
342
|
+
] }),
|
|
343
|
+
/* @__PURE__ */ jsxs2(Card, { children: [
|
|
344
|
+
/* @__PURE__ */ jsx3(CardHeader, { children: /* @__PURE__ */ jsx3(CardTitle, { children: t("dashboard.drafts") }) }),
|
|
345
|
+
/* @__PURE__ */ jsx3(CardContent, { children: /* @__PURE__ */ jsx3("p", { className: "text-3xl font-bold", children: loading ? "\u2014" : drafts }) })
|
|
346
|
+
] })
|
|
347
|
+
] })
|
|
348
|
+
] });
|
|
349
|
+
}
|
|
350
|
+
function createAdminDashboardPage(_admin) {
|
|
351
|
+
return AdminDashboard;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// src/pages/posts-list.tsx
|
|
355
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
356
|
+
import Link2 from "next/link";
|
|
357
|
+
import { listPosts as listPosts2 } from "ampless";
|
|
358
|
+
import {
|
|
359
|
+
Button as Button2,
|
|
360
|
+
Table,
|
|
361
|
+
TableBody,
|
|
362
|
+
TableCell,
|
|
363
|
+
TableHead,
|
|
364
|
+
TableHeader,
|
|
365
|
+
TableRow
|
|
366
|
+
} from "@ampless/runtime/ui";
|
|
367
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
368
|
+
function PostsList() {
|
|
369
|
+
const t = useT();
|
|
370
|
+
const [posts, setPosts] = useState2([]);
|
|
371
|
+
const [loading, setLoading] = useState2(true);
|
|
372
|
+
useEffect3(() => {
|
|
373
|
+
const siteId = readAdminSiteIdFromCookie();
|
|
374
|
+
listPosts2({ status: "all", siteId }).then(setPosts).finally(() => setLoading(false));
|
|
375
|
+
}, []);
|
|
376
|
+
return /* @__PURE__ */ jsxs3("div", { className: "p-8", children: [
|
|
377
|
+
/* @__PURE__ */ jsxs3("div", { className: "mb-8 flex items-center justify-between", children: [
|
|
378
|
+
/* @__PURE__ */ jsx4("h1", { className: "text-3xl font-bold", children: t("posts.list.title") }),
|
|
379
|
+
/* @__PURE__ */ jsx4(Button2, { asChild: true, children: /* @__PURE__ */ jsx4(Link2, { href: "/admin/posts/new", children: t("posts.list.newButton") }) })
|
|
380
|
+
] }),
|
|
381
|
+
loading ? /* @__PURE__ */ jsx4("p", { className: "text-muted-foreground", children: t("common.loading") }) : posts.length === 0 ? /* @__PURE__ */ jsxs3("div", { className: "rounded-md border p-12 text-center", children: [
|
|
382
|
+
/* @__PURE__ */ jsx4("p", { className: "text-muted-foreground", children: t("posts.list.empty") }),
|
|
383
|
+
/* @__PURE__ */ jsx4(Button2, { asChild: true, className: "mt-4", children: /* @__PURE__ */ jsx4(Link2, { href: "/admin/posts/new", children: t("posts.list.createFirst") }) })
|
|
384
|
+
] }) : /* @__PURE__ */ jsx4("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs3(Table, { children: [
|
|
385
|
+
/* @__PURE__ */ jsx4(TableHeader, { children: /* @__PURE__ */ jsxs3(TableRow, { children: [
|
|
386
|
+
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnTitle") }),
|
|
387
|
+
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnStatus") }),
|
|
388
|
+
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnSlug") }),
|
|
389
|
+
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnUpdated") })
|
|
390
|
+
] }) }),
|
|
391
|
+
/* @__PURE__ */ jsx4(TableBody, { children: posts.map((post) => /* @__PURE__ */ jsxs3(TableRow, { children: [
|
|
392
|
+
/* @__PURE__ */ jsx4(TableCell, { children: /* @__PURE__ */ jsx4(
|
|
393
|
+
Link2,
|
|
394
|
+
{
|
|
395
|
+
href: `/admin/posts/${post.postId}`,
|
|
396
|
+
className: "font-medium hover:underline",
|
|
397
|
+
children: post.title
|
|
398
|
+
}
|
|
399
|
+
) }),
|
|
400
|
+
/* @__PURE__ */ jsx4(TableCell, { children: /* @__PURE__ */ jsx4(
|
|
401
|
+
"span",
|
|
402
|
+
{
|
|
403
|
+
className: post.status === "published" ? "inline-block rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-700" : "inline-block rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-700",
|
|
404
|
+
children: t(`common.${post.status}`)
|
|
405
|
+
}
|
|
406
|
+
) }),
|
|
407
|
+
/* @__PURE__ */ jsx4(TableCell, { className: "font-mono text-xs text-muted-foreground", children: post.slug }),
|
|
408
|
+
/* @__PURE__ */ jsx4(TableCell, { className: "text-sm text-muted-foreground", children: post.publishedAt ? new Date(post.publishedAt).toLocaleDateString() : "\u2014" })
|
|
409
|
+
] }, post.postId)) })
|
|
410
|
+
] }) })
|
|
411
|
+
] });
|
|
412
|
+
}
|
|
413
|
+
function createPostsListPage(_admin) {
|
|
414
|
+
return PostsList;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/pages/post-new.tsx
|
|
418
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
419
|
+
function NewPostPage() {
|
|
420
|
+
const t = useT();
|
|
421
|
+
return /* @__PURE__ */ jsxs4("div", { className: "p-8", children: [
|
|
422
|
+
/* @__PURE__ */ jsx5("h1", { className: "mb-8 text-3xl font-bold", children: t("posts.form.newTitle") }),
|
|
423
|
+
/* @__PURE__ */ jsx5(PostForm, {})
|
|
424
|
+
] });
|
|
425
|
+
}
|
|
426
|
+
function createNewPostPage(_admin) {
|
|
427
|
+
return NewPostPage;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/pages/post-edit.tsx
|
|
431
|
+
import { useEffect as useEffect4, useState as useState3, use } from "react";
|
|
432
|
+
import { notFound } from "next/navigation";
|
|
433
|
+
import { getPostById } from "ampless";
|
|
434
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
435
|
+
function EditPostPage({ params }) {
|
|
436
|
+
const t = useT();
|
|
437
|
+
const { postId } = use(params);
|
|
438
|
+
const [post, setPost] = useState3(null);
|
|
439
|
+
const [loading, setLoading] = useState3(true);
|
|
440
|
+
const [missing, setMissing] = useState3(false);
|
|
441
|
+
useEffect4(() => {
|
|
442
|
+
const siteId = readAdminSiteIdFromCookie();
|
|
443
|
+
getPostById(postId, { siteId }).then((p) => {
|
|
444
|
+
if (!p) setMissing(true);
|
|
445
|
+
else setPost(p);
|
|
446
|
+
}).finally(() => setLoading(false));
|
|
447
|
+
}, [postId]);
|
|
448
|
+
if (loading) return /* @__PURE__ */ jsx6("div", { className: "p-8", children: t("common.loading") });
|
|
449
|
+
if (missing) notFound();
|
|
450
|
+
return /* @__PURE__ */ jsxs5("div", { className: "p-8", children: [
|
|
451
|
+
/* @__PURE__ */ jsx6("h1", { className: "mb-8 text-3xl font-bold", children: t("posts.form.editTitle") }),
|
|
452
|
+
post && /* @__PURE__ */ jsx6(PostForm, { post })
|
|
453
|
+
] });
|
|
454
|
+
}
|
|
455
|
+
function createEditPostPage(_admin) {
|
|
456
|
+
return EditPostPage;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// src/pages/media.tsx
|
|
460
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
461
|
+
function MediaPage() {
|
|
462
|
+
const t = useT();
|
|
463
|
+
return /* @__PURE__ */ jsxs6("div", { className: "p-8", children: [
|
|
464
|
+
/* @__PURE__ */ jsx7("h1", { className: "mb-8 text-3xl font-bold", children: t("media.title") }),
|
|
465
|
+
/* @__PURE__ */ jsx7(MediaUploader, {})
|
|
466
|
+
] });
|
|
467
|
+
}
|
|
468
|
+
function createMediaPage(_admin) {
|
|
469
|
+
return MediaPage;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/pages/sites-list.tsx
|
|
473
|
+
import Link3 from "next/link";
|
|
474
|
+
import { DEFAULT_SITE_ID, isMultiSite, siteFor } from "ampless";
|
|
475
|
+
import {
|
|
476
|
+
Button as Button3,
|
|
477
|
+
Table as Table2,
|
|
478
|
+
TableBody as TableBody2,
|
|
479
|
+
TableCell as TableCell2,
|
|
480
|
+
TableHead as TableHead2,
|
|
481
|
+
TableHeader as TableHeader2,
|
|
482
|
+
TableRow as TableRow2
|
|
483
|
+
} from "@ampless/runtime/ui";
|
|
484
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
485
|
+
function createSitesListPage(admin) {
|
|
486
|
+
const { cmsConfig, t } = admin;
|
|
487
|
+
async function SitesPage() {
|
|
488
|
+
const multi = isMultiSite(cmsConfig);
|
|
489
|
+
const ids = multi ? Object.keys(cmsConfig.sites ?? {}) : [DEFAULT_SITE_ID];
|
|
490
|
+
return /* @__PURE__ */ jsxs7("div", { className: "p-8", children: [
|
|
491
|
+
/* @__PURE__ */ jsx8("div", { className: "mb-8 flex items-center justify-between", children: /* @__PURE__ */ jsxs7("div", { children: [
|
|
492
|
+
/* @__PURE__ */ jsx8("h1", { className: "text-3xl font-bold", children: t("sites.list.title") }),
|
|
493
|
+
/* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm text-muted-foreground", children: t("sites.list.description") })
|
|
494
|
+
] }) }),
|
|
495
|
+
/* @__PURE__ */ jsx8("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs7(Table2, { children: [
|
|
496
|
+
/* @__PURE__ */ jsx8(TableHeader2, { children: /* @__PURE__ */ jsxs7(TableRow2, { children: [
|
|
497
|
+
/* @__PURE__ */ jsx8(TableHead2, { children: t("sites.list.columnSiteId") }),
|
|
498
|
+
/* @__PURE__ */ jsx8(TableHead2, { children: t("sites.list.columnName") }),
|
|
499
|
+
/* @__PURE__ */ jsx8(TableHead2, { children: t("sites.list.columnUrl") }),
|
|
500
|
+
/* @__PURE__ */ jsx8(TableHead2, { children: t("sites.list.columnDomains") }),
|
|
501
|
+
/* @__PURE__ */ jsx8(TableHead2, {})
|
|
502
|
+
] }) }),
|
|
503
|
+
/* @__PURE__ */ jsx8(TableBody2, { children: ids.map((id) => {
|
|
504
|
+
const site = siteFor(id, cmsConfig);
|
|
505
|
+
const domains = cmsConfig.sites?.[id]?.domains ?? [];
|
|
506
|
+
return /* @__PURE__ */ jsxs7(TableRow2, { children: [
|
|
507
|
+
/* @__PURE__ */ jsx8(TableCell2, { className: "font-mono text-xs", children: id }),
|
|
508
|
+
/* @__PURE__ */ jsx8(TableCell2, { className: "font-medium", children: site.name }),
|
|
509
|
+
/* @__PURE__ */ jsx8(TableCell2, { className: "text-sm text-muted-foreground", children: site.url }),
|
|
510
|
+
/* @__PURE__ */ jsx8(TableCell2, { className: "text-sm text-muted-foreground", children: domains.length > 0 ? domains.join(", ") : "\u2014" }),
|
|
511
|
+
/* @__PURE__ */ jsx8(TableCell2, { children: /* @__PURE__ */ jsx8(Button3, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsx8(Link3, { href: `/admin/sites/${id}`, children: t("sites.list.edit") }) }) })
|
|
512
|
+
] }, id);
|
|
513
|
+
}) })
|
|
514
|
+
] }) })
|
|
515
|
+
] });
|
|
516
|
+
}
|
|
517
|
+
return SitesPage;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/pages/site-edit.tsx
|
|
521
|
+
import Link4 from "next/link";
|
|
522
|
+
import { siteFor as siteFor2 } from "ampless";
|
|
523
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
524
|
+
function createSiteEditPage(admin) {
|
|
525
|
+
const { cmsConfig, t, loadSiteSettings } = admin;
|
|
526
|
+
async function EditSitePage({ params }) {
|
|
527
|
+
const { siteId } = await params;
|
|
528
|
+
const settings = await loadSiteSettings(siteId);
|
|
529
|
+
const defaults = siteFor2(siteId, cmsConfig);
|
|
530
|
+
const fallback = {
|
|
531
|
+
"site.name": defaults.name,
|
|
532
|
+
"site.url": defaults.url,
|
|
533
|
+
"site.description": defaults.description,
|
|
534
|
+
"media.imageDisplay": cmsConfig.media?.imageDisplay,
|
|
535
|
+
"media.imageMaxWidth": cmsConfig.media?.imageMaxWidth,
|
|
536
|
+
dateFormat: cmsConfig.dateFormat,
|
|
537
|
+
timezone: cmsConfig.timezone
|
|
538
|
+
};
|
|
539
|
+
const initial = {
|
|
540
|
+
"site.name": settings.site.name,
|
|
541
|
+
"site.url": settings.site.url,
|
|
542
|
+
"site.description": settings.site.description,
|
|
543
|
+
"media.imageDisplay": settings.media.imageDisplay,
|
|
544
|
+
"media.imageMaxWidth": settings.media.imageMaxWidth,
|
|
545
|
+
dateFormat: settings.dateFormat,
|
|
546
|
+
timezone: settings.timezone
|
|
547
|
+
};
|
|
548
|
+
return /* @__PURE__ */ jsxs8("div", { className: "p-8", children: [
|
|
549
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-8", children: [
|
|
550
|
+
/* @__PURE__ */ jsxs8(
|
|
551
|
+
Link4,
|
|
552
|
+
{
|
|
553
|
+
href: "/admin/sites",
|
|
554
|
+
className: "text-sm text-muted-foreground hover:underline",
|
|
555
|
+
children: [
|
|
556
|
+
"\u2190 ",
|
|
557
|
+
t("sidebar.sites")
|
|
558
|
+
]
|
|
559
|
+
}
|
|
560
|
+
),
|
|
561
|
+
/* @__PURE__ */ jsx9("h1", { className: "mt-2 text-3xl font-bold", children: settings.site.name }),
|
|
562
|
+
/* @__PURE__ */ jsxs8("p", { className: "text-sm text-muted-foreground", children: [
|
|
563
|
+
t("common.siteId"),
|
|
564
|
+
": ",
|
|
565
|
+
/* @__PURE__ */ jsx9("code", { className: "font-mono", children: siteId })
|
|
566
|
+
] }),
|
|
567
|
+
/* @__PURE__ */ jsx9("div", { className: "mt-4", children: /* @__PURE__ */ jsx9(
|
|
568
|
+
Link4,
|
|
569
|
+
{
|
|
570
|
+
href: `/admin/sites/${siteId}/theme`,
|
|
571
|
+
className: "text-sm font-medium underline",
|
|
572
|
+
children: t("sites.edit.themeLink")
|
|
573
|
+
}
|
|
574
|
+
) })
|
|
575
|
+
] }),
|
|
576
|
+
/* @__PURE__ */ jsx9(SiteSettingsForm, { siteId, initial, fallback })
|
|
577
|
+
] });
|
|
578
|
+
}
|
|
579
|
+
return EditSitePage;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// src/pages/site-theme.tsx
|
|
583
|
+
import Link5 from "next/link";
|
|
584
|
+
import { siteFor as siteFor3, resolveLocalized } from "ampless";
|
|
585
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
586
|
+
function createSiteThemePage(admin, themeList) {
|
|
587
|
+
const { cmsConfig, t, locale, loadThemeConfig } = admin;
|
|
588
|
+
async function ThemePage({ params }) {
|
|
589
|
+
const { siteId } = await params;
|
|
590
|
+
const site = siteFor3(siteId, cmsConfig);
|
|
591
|
+
const theme = await loadThemeConfig(siteId);
|
|
592
|
+
const themeOptions = themeList.map((m) => ({
|
|
593
|
+
value: m.name,
|
|
594
|
+
label: m.manifest.label,
|
|
595
|
+
description: m.manifest.description
|
|
596
|
+
}));
|
|
597
|
+
return /* @__PURE__ */ jsxs9("div", { className: "p-8", children: [
|
|
598
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-8", children: [
|
|
599
|
+
/* @__PURE__ */ jsxs9(
|
|
600
|
+
Link5,
|
|
601
|
+
{
|
|
602
|
+
href: `/admin/sites/${siteId}`,
|
|
603
|
+
className: "text-sm text-muted-foreground hover:underline",
|
|
604
|
+
children: [
|
|
605
|
+
"\u2190 ",
|
|
606
|
+
site.name
|
|
607
|
+
]
|
|
608
|
+
}
|
|
609
|
+
),
|
|
610
|
+
/* @__PURE__ */ jsx10("h1", { className: "mt-2 text-3xl font-bold", children: t("theme.title") }),
|
|
611
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-sm text-muted-foreground", children: [
|
|
612
|
+
t("common.active"),
|
|
613
|
+
":",
|
|
614
|
+
" ",
|
|
615
|
+
/* @__PURE__ */ jsx10("strong", { children: resolveLocalized(theme.manifest.label, locale) }),
|
|
616
|
+
" (",
|
|
617
|
+
theme.activeTheme,
|
|
618
|
+
")"
|
|
619
|
+
] })
|
|
620
|
+
] }),
|
|
621
|
+
/* @__PURE__ */ jsx10(
|
|
622
|
+
ThemeSettingsForm,
|
|
623
|
+
{
|
|
624
|
+
siteId,
|
|
625
|
+
manifest: theme.manifest,
|
|
626
|
+
activeTheme: theme.activeTheme,
|
|
627
|
+
themeOptions,
|
|
628
|
+
initial: theme.values
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
] });
|
|
632
|
+
}
|
|
633
|
+
return ThemePage;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// src/pages/login.tsx
|
|
637
|
+
import { useState as useState4 } from "react";
|
|
638
|
+
import { useRouter } from "next/navigation";
|
|
639
|
+
import {
|
|
640
|
+
signIn,
|
|
641
|
+
signUp,
|
|
642
|
+
confirmSignUp,
|
|
643
|
+
resetPassword,
|
|
644
|
+
confirmResetPassword
|
|
645
|
+
} from "aws-amplify/auth";
|
|
646
|
+
import {
|
|
647
|
+
Button as Button4,
|
|
648
|
+
Input,
|
|
649
|
+
Label,
|
|
650
|
+
Card as Card2,
|
|
651
|
+
CardContent as CardContent2,
|
|
652
|
+
CardHeader as CardHeader2,
|
|
653
|
+
CardTitle as CardTitle2,
|
|
654
|
+
CardDescription
|
|
655
|
+
} from "@ampless/runtime/ui";
|
|
656
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
657
|
+
function LoginPage() {
|
|
658
|
+
const router = useRouter();
|
|
659
|
+
const t = useT();
|
|
660
|
+
const [mode, setMode] = useState4("signIn");
|
|
661
|
+
const [email, setEmail] = useState4("");
|
|
662
|
+
const [password, setPassword] = useState4("");
|
|
663
|
+
const [code, setCode] = useState4("");
|
|
664
|
+
const [error, setError] = useState4(null);
|
|
665
|
+
const [info, setInfo] = useState4(null);
|
|
666
|
+
const [loading, setLoading] = useState4(false);
|
|
667
|
+
function go(next) {
|
|
668
|
+
setMode(next);
|
|
669
|
+
setError(null);
|
|
670
|
+
setInfo(null);
|
|
671
|
+
setCode("");
|
|
672
|
+
if (next === "signIn" || next === "signUp" || next === "forgot") setPassword("");
|
|
673
|
+
}
|
|
674
|
+
async function handleSubmit(e) {
|
|
675
|
+
e.preventDefault();
|
|
676
|
+
setError(null);
|
|
677
|
+
setInfo(null);
|
|
678
|
+
setLoading(true);
|
|
679
|
+
try {
|
|
680
|
+
if (mode === "signIn") {
|
|
681
|
+
const result = await signIn({ username: email, password });
|
|
682
|
+
if (result.isSignedIn) {
|
|
683
|
+
router.push("/admin");
|
|
684
|
+
router.refresh();
|
|
685
|
+
} else {
|
|
686
|
+
setError(t("auth.additionalStep", { step: result.nextStep.signInStep }));
|
|
687
|
+
}
|
|
688
|
+
} else if (mode === "signUp") {
|
|
689
|
+
await signUp({
|
|
690
|
+
username: email,
|
|
691
|
+
password,
|
|
692
|
+
options: { userAttributes: { email } }
|
|
693
|
+
});
|
|
694
|
+
go("confirm");
|
|
695
|
+
} else if (mode === "confirm") {
|
|
696
|
+
await confirmSignUp({ username: email, confirmationCode: code });
|
|
697
|
+
const result = await signIn({ username: email, password });
|
|
698
|
+
if (result.isSignedIn) {
|
|
699
|
+
router.push("/admin");
|
|
700
|
+
router.refresh();
|
|
701
|
+
}
|
|
702
|
+
} else if (mode === "forgot") {
|
|
703
|
+
await resetPassword({ username: email });
|
|
704
|
+
setMode("reset");
|
|
705
|
+
setInfo(t("auth.forgot.codeSent"));
|
|
706
|
+
} else if (mode === "reset") {
|
|
707
|
+
await confirmResetPassword({
|
|
708
|
+
username: email,
|
|
709
|
+
confirmationCode: code,
|
|
710
|
+
newPassword: password
|
|
711
|
+
});
|
|
712
|
+
const result = await signIn({ username: email, password });
|
|
713
|
+
if (result.isSignedIn) {
|
|
714
|
+
router.push("/admin");
|
|
715
|
+
router.refresh();
|
|
716
|
+
} else {
|
|
717
|
+
setMode("signIn");
|
|
718
|
+
setInfo(t("auth.reset.passwordUpdated"));
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
} catch (err) {
|
|
722
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
723
|
+
} finally {
|
|
724
|
+
setLoading(false);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
const showEmail = mode !== "confirm" && mode !== "reset";
|
|
728
|
+
const showPassword = mode === "signIn" || mode === "signUp" || mode === "reset";
|
|
729
|
+
const showCode = mode === "confirm" || mode === "reset";
|
|
730
|
+
return /* @__PURE__ */ jsx11("main", { className: "flex min-h-screen items-center justify-center bg-muted/30 p-4", children: /* @__PURE__ */ jsxs10(Card2, { className: "w-full max-w-md", children: [
|
|
731
|
+
/* @__PURE__ */ jsxs10(CardHeader2, { children: [
|
|
732
|
+
/* @__PURE__ */ jsx11(CardTitle2, { children: t(`auth.${mode}.title`) }),
|
|
733
|
+
/* @__PURE__ */ jsx11(CardDescription, { children: t(`auth.${mode}.description`) })
|
|
734
|
+
] }),
|
|
735
|
+
/* @__PURE__ */ jsx11(CardContent2, { children: /* @__PURE__ */ jsxs10("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
736
|
+
showEmail && /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
737
|
+
/* @__PURE__ */ jsx11(Label, { htmlFor: "email", children: t("auth.common.email") }),
|
|
738
|
+
/* @__PURE__ */ jsx11(
|
|
739
|
+
Input,
|
|
740
|
+
{
|
|
741
|
+
id: "email",
|
|
742
|
+
type: "email",
|
|
743
|
+
required: true,
|
|
744
|
+
value: email,
|
|
745
|
+
onChange: (e) => setEmail(e.target.value),
|
|
746
|
+
autoComplete: "email"
|
|
747
|
+
}
|
|
748
|
+
)
|
|
749
|
+
] }),
|
|
750
|
+
showCode && /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
751
|
+
/* @__PURE__ */ jsx11(Label, { htmlFor: "code", children: t("auth.common.code") }),
|
|
752
|
+
/* @__PURE__ */ jsx11(
|
|
753
|
+
Input,
|
|
754
|
+
{
|
|
755
|
+
id: "code",
|
|
756
|
+
required: true,
|
|
757
|
+
value: code,
|
|
758
|
+
onChange: (e) => setCode(e.target.value),
|
|
759
|
+
autoComplete: "one-time-code"
|
|
760
|
+
}
|
|
761
|
+
)
|
|
762
|
+
] }),
|
|
763
|
+
showPassword && /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
764
|
+
/* @__PURE__ */ jsx11(Label, { htmlFor: "password", children: mode === "reset" ? t("auth.common.newPassword") : t("auth.common.password") }),
|
|
765
|
+
/* @__PURE__ */ jsx11(
|
|
766
|
+
Input,
|
|
767
|
+
{
|
|
768
|
+
id: "password",
|
|
769
|
+
type: "password",
|
|
770
|
+
required: true,
|
|
771
|
+
minLength: 8,
|
|
772
|
+
value: password,
|
|
773
|
+
onChange: (e) => setPassword(e.target.value),
|
|
774
|
+
autoComplete: mode === "signIn" ? "current-password" : "new-password"
|
|
775
|
+
}
|
|
776
|
+
),
|
|
777
|
+
(mode === "signUp" || mode === "reset") && /* @__PURE__ */ jsx11("p", { className: "text-xs text-muted-foreground", children: t("auth.common.passwordHint") })
|
|
778
|
+
] }),
|
|
779
|
+
info && /* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground", children: info }),
|
|
780
|
+
error && /* @__PURE__ */ jsx11("p", { className: "text-sm text-destructive", children: error }),
|
|
781
|
+
/* @__PURE__ */ jsx11(Button4, { type: "submit", className: "w-full", disabled: loading, children: loading ? t("auth.common.working") : t(`auth.${mode}.submit`) }),
|
|
782
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-1 text-center text-sm", children: [
|
|
783
|
+
mode === "signIn" && /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
784
|
+
/* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
785
|
+
"button",
|
|
786
|
+
{
|
|
787
|
+
type: "button",
|
|
788
|
+
className: "text-primary hover:underline",
|
|
789
|
+
onClick: () => go("forgot"),
|
|
790
|
+
children: t("auth.signIn.forgotPassword")
|
|
791
|
+
}
|
|
792
|
+
) }),
|
|
793
|
+
/* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
794
|
+
"button",
|
|
795
|
+
{
|
|
796
|
+
type: "button",
|
|
797
|
+
className: "text-primary hover:underline",
|
|
798
|
+
onClick: () => go("signUp"),
|
|
799
|
+
children: t("auth.signIn.createAccount")
|
|
800
|
+
}
|
|
801
|
+
) })
|
|
802
|
+
] }),
|
|
803
|
+
(mode === "signUp" || mode === "forgot" || mode === "reset") && /* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
804
|
+
"button",
|
|
805
|
+
{
|
|
806
|
+
type: "button",
|
|
807
|
+
className: "text-primary hover:underline",
|
|
808
|
+
onClick: () => go("signIn"),
|
|
809
|
+
children: t("auth.signUp.backToSignIn")
|
|
810
|
+
}
|
|
811
|
+
) }),
|
|
812
|
+
mode === "reset" && /* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
813
|
+
"button",
|
|
814
|
+
{
|
|
815
|
+
type: "button",
|
|
816
|
+
className: "text-primary hover:underline",
|
|
817
|
+
onClick: () => go("forgot"),
|
|
818
|
+
children: t("auth.reset.resendCode")
|
|
819
|
+
}
|
|
820
|
+
) })
|
|
821
|
+
] })
|
|
822
|
+
] }) })
|
|
823
|
+
] }) });
|
|
824
|
+
}
|
|
825
|
+
function createLoginPage(_admin) {
|
|
826
|
+
return LoginPage;
|
|
827
|
+
}
|
|
828
|
+
export {
|
|
829
|
+
createAdminDashboardPage,
|
|
830
|
+
createAdminLayout,
|
|
831
|
+
createEditPostPage,
|
|
832
|
+
createLoginPage,
|
|
833
|
+
createMediaPage,
|
|
834
|
+
createNewPostPage,
|
|
835
|
+
createPostsListPage,
|
|
836
|
+
createSiteEditPage,
|
|
837
|
+
createSiteThemePage,
|
|
838
|
+
createSitesListPage
|
|
839
|
+
};
|