@ampless/admin 0.2.0-alpha.5 → 0.2.0-alpha.7
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/api/index.d.ts +1 -1
- package/dist/{chunk-7WFZULH7.js → chunk-GXPSAOES.js} +200 -85
- package/dist/{chunk-FI7CM4LH.js → chunk-L5NHN3MY.js} +50 -2
- package/dist/components/index.d.ts +4 -2
- package/dist/components/index.js +2 -2
- package/dist/{i18n-ByHM_Bho.d.ts → i18n-Bc4SYgWx.d.ts} +74 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/pages/index.d.ts +9 -2
- package/dist/pages/index.js +184 -17
- package/package.json +3 -3
package/dist/api/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
publicMediaUrl,
|
|
5
5
|
setAdminMediaContext,
|
|
6
6
|
translate
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-L5NHN3MY.js";
|
|
8
8
|
import {
|
|
9
9
|
invalidateSiteSettingsCache
|
|
10
10
|
} from "./chunk-VXEVLHGL.js";
|
|
@@ -82,6 +82,18 @@ function decodeBody(value) {
|
|
|
82
82
|
return value;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
function decodeMetadata(value) {
|
|
86
|
+
if (value === null || value === void 0) return void 0;
|
|
87
|
+
const parsed = typeof value === "string" ? safeJsonParse(value) : value;
|
|
88
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
89
|
+
}
|
|
90
|
+
function safeJsonParse(value) {
|
|
91
|
+
try {
|
|
92
|
+
return JSON.parse(value);
|
|
93
|
+
} catch {
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
85
97
|
function toCorePost(p) {
|
|
86
98
|
return {
|
|
87
99
|
postId: p.postId,
|
|
@@ -93,7 +105,8 @@ function toCorePost(p) {
|
|
|
93
105
|
body: decodeBody(p.body),
|
|
94
106
|
status: p.status ?? "draft",
|
|
95
107
|
publishedAt: p.publishedAt ?? void 0,
|
|
96
|
-
tags: (p.tags ?? []).filter((t) => typeof t === "string")
|
|
108
|
+
tags: (p.tags ?? []).filter((t) => typeof t === "string"),
|
|
109
|
+
metadata: decodeMetadata(p.metadata)
|
|
97
110
|
};
|
|
98
111
|
}
|
|
99
112
|
function postTagEntries(post) {
|
|
@@ -190,6 +203,7 @@ function installAdminPostsProvider() {
|
|
|
190
203
|
status: input.status,
|
|
191
204
|
publishedAt: input.publishedAt,
|
|
192
205
|
tags: input.tags,
|
|
206
|
+
...input.metadata !== void 0 && { metadata: encodeBody(input.metadata) },
|
|
193
207
|
// Denormalized GSI keys. Must match every change to slug /
|
|
194
208
|
// status — see the update() branch below.
|
|
195
209
|
siteIdStatus: composeSiteIdStatus(input.siteId, input.status),
|
|
@@ -216,6 +230,7 @@ function installAdminPostsProvider() {
|
|
|
216
230
|
...patch.status !== void 0 && { status: patch.status },
|
|
217
231
|
...patch.publishedAt !== void 0 && { publishedAt: patch.publishedAt },
|
|
218
232
|
...patch.tags !== void 0 && { tags: patch.tags },
|
|
233
|
+
...patch.metadata !== void 0 && { metadata: encodeBody(patch.metadata) },
|
|
219
234
|
...patch.status !== void 0 && nextStatus && { siteIdStatus: composeSiteIdStatus(siteId, nextStatus) },
|
|
220
235
|
...patch.slug !== void 0 && nextSlug && { siteIdSlug: composeSiteIdSlug(siteId, nextSlug) }
|
|
221
236
|
});
|
|
@@ -351,12 +366,12 @@ function AdminDashboard() {
|
|
|
351
366
|
}, []);
|
|
352
367
|
const published = posts.filter((p) => p.status === "published").length;
|
|
353
368
|
const drafts = posts.filter((p) => p.status === "draft").length;
|
|
354
|
-
return /* @__PURE__ */ jsxs("div", { className: "p-8", children: [
|
|
355
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-
|
|
356
|
-
/* @__PURE__ */ jsx3("h1", { className: "text-
|
|
369
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
370
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3 md:mb-8", children: [
|
|
371
|
+
/* @__PURE__ */ jsx3("h1", { className: "text-2xl font-bold md:text-3xl", children: t("dashboard.title") }),
|
|
357
372
|
/* @__PURE__ */ jsx3(Button, { asChild: true, children: /* @__PURE__ */ jsx3(Link, { href: "/admin/posts/new", children: t("dashboard.newPost") }) })
|
|
358
373
|
] }),
|
|
359
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4
|
|
374
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: [
|
|
360
375
|
/* @__PURE__ */ jsxs(Card, { children: [
|
|
361
376
|
/* @__PURE__ */ jsx3(CardHeader, { children: /* @__PURE__ */ jsx3(CardTitle, { children: t("dashboard.totalPosts") }) }),
|
|
362
377
|
/* @__PURE__ */ jsxs(CardContent, { children: [
|
|
@@ -398,15 +413,15 @@ function PostsList() {
|
|
|
398
413
|
const siteId = readAdminSiteIdFromCookie();
|
|
399
414
|
listPosts2({ status: "all", siteId }).then(setPosts).finally(() => setLoading(false));
|
|
400
415
|
}, []);
|
|
401
|
-
return /* @__PURE__ */ jsxs2("div", { className: "p-8", children: [
|
|
402
|
-
/* @__PURE__ */ jsxs2("div", { className: "mb-
|
|
403
|
-
/* @__PURE__ */ jsx4("h1", { className: "text-
|
|
416
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
417
|
+
/* @__PURE__ */ jsxs2("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3 md:mb-8", children: [
|
|
418
|
+
/* @__PURE__ */ jsx4("h1", { className: "text-2xl font-bold md:text-3xl", children: t("posts.list.title") }),
|
|
404
419
|
/* @__PURE__ */ jsx4(Button2, { asChild: true, children: /* @__PURE__ */ jsx4(Link2, { href: "/admin/posts/new", children: t("posts.list.newButton") }) })
|
|
405
420
|
] }),
|
|
406
421
|
loading ? /* @__PURE__ */ jsx4("p", { className: "text-muted-foreground", children: t("common.loading") }) : posts.length === 0 ? /* @__PURE__ */ jsxs2("div", { className: "rounded-md border p-12 text-center", children: [
|
|
407
422
|
/* @__PURE__ */ jsx4("p", { className: "text-muted-foreground", children: t("posts.list.empty") }),
|
|
408
423
|
/* @__PURE__ */ jsx4(Button2, { asChild: true, className: "mt-4", children: /* @__PURE__ */ jsx4(Link2, { href: "/admin/posts/new", children: t("posts.list.createFirst") }) })
|
|
409
|
-
] }) : /* @__PURE__ */ jsx4("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs2(Table, { children: [
|
|
424
|
+
] }) : /* @__PURE__ */ jsx4("div", { className: "overflow-x-auto rounded-md border", children: /* @__PURE__ */ jsxs2(Table, { children: [
|
|
410
425
|
/* @__PURE__ */ jsx4(TableHeader, { children: /* @__PURE__ */ jsxs2(TableRow, { children: [
|
|
411
426
|
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnTitle") }),
|
|
412
427
|
/* @__PURE__ */ jsx4(TableHead, { children: t("posts.list.columnStatus") }),
|
|
@@ -1169,9 +1184,16 @@ function PostForm({ post }) {
|
|
|
1169
1184
|
const [body, setBody] = useState5(post?.body ?? EMPTY_TIPTAP_DOC);
|
|
1170
1185
|
const [status, setStatus] = useState5(post?.status ?? "draft");
|
|
1171
1186
|
const [tagsInput, setTagsInput] = useState5((post?.tags ?? []).join(", "));
|
|
1187
|
+
const [noLayout, setNoLayout] = useState5(post?.metadata?.no_layout === true);
|
|
1172
1188
|
const [saving, setSaving] = useState5(false);
|
|
1173
1189
|
const [error, setError] = useState5(null);
|
|
1174
1190
|
const [view, setView] = useState5("edit");
|
|
1191
|
+
function buildMetadata() {
|
|
1192
|
+
const next = { ...post?.metadata ?? {} };
|
|
1193
|
+
if (noLayout && format === "html") next.no_layout = true;
|
|
1194
|
+
else delete next.no_layout;
|
|
1195
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
1196
|
+
}
|
|
1175
1197
|
function parseTags(raw) {
|
|
1176
1198
|
return Array.from(
|
|
1177
1199
|
new Set(
|
|
@@ -1228,6 +1250,7 @@ function PostForm({ post }) {
|
|
|
1228
1250
|
}
|
|
1229
1251
|
setFormat(next);
|
|
1230
1252
|
setBody(nextBody);
|
|
1253
|
+
if (next !== "html") setNoLayout(false);
|
|
1231
1254
|
}
|
|
1232
1255
|
async function save(e) {
|
|
1233
1256
|
e.preventDefault();
|
|
@@ -1235,6 +1258,7 @@ function PostForm({ post }) {
|
|
|
1235
1258
|
setError(null);
|
|
1236
1259
|
try {
|
|
1237
1260
|
const tags = parseTags(tagsInput);
|
|
1261
|
+
const metadata = buildMetadata();
|
|
1238
1262
|
if (isEdit) {
|
|
1239
1263
|
await updatePost(
|
|
1240
1264
|
post.postId,
|
|
@@ -1246,7 +1270,8 @@ function PostForm({ post }) {
|
|
|
1246
1270
|
body,
|
|
1247
1271
|
status,
|
|
1248
1272
|
publishedAt: status === "published" ? post?.publishedAt ?? (/* @__PURE__ */ new Date()).toISOString() : void 0,
|
|
1249
|
-
tags
|
|
1273
|
+
tags,
|
|
1274
|
+
metadata
|
|
1250
1275
|
},
|
|
1251
1276
|
{ siteId: post.siteId }
|
|
1252
1277
|
);
|
|
@@ -1260,7 +1285,8 @@ function PostForm({ post }) {
|
|
|
1260
1285
|
body,
|
|
1261
1286
|
status,
|
|
1262
1287
|
publishedAt: status === "published" ? (/* @__PURE__ */ new Date()).toISOString() : void 0,
|
|
1263
|
-
tags
|
|
1288
|
+
tags,
|
|
1289
|
+
metadata
|
|
1264
1290
|
});
|
|
1265
1291
|
}
|
|
1266
1292
|
router.push("/admin/posts");
|
|
@@ -1465,6 +1491,21 @@ function PostForm({ post }) {
|
|
|
1465
1491
|
}
|
|
1466
1492
|
)
|
|
1467
1493
|
] }),
|
|
1494
|
+
format === "html" && /* @__PURE__ */ jsx10("div", { className: "space-y-2", children: /* @__PURE__ */ jsxs8("label", { className: "flex items-start gap-2 text-sm", children: [
|
|
1495
|
+
/* @__PURE__ */ jsx10(
|
|
1496
|
+
"input",
|
|
1497
|
+
{
|
|
1498
|
+
type: "checkbox",
|
|
1499
|
+
checked: noLayout,
|
|
1500
|
+
onChange: (e) => setNoLayout(e.target.checked),
|
|
1501
|
+
className: "mt-1"
|
|
1502
|
+
}
|
|
1503
|
+
),
|
|
1504
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
1505
|
+
/* @__PURE__ */ jsx10("span", { className: "font-medium", children: t("posts.form.noLayout") }),
|
|
1506
|
+
/* @__PURE__ */ jsx10("span", { className: "block text-xs text-muted-foreground", children: t("posts.form.noLayoutHint") })
|
|
1507
|
+
] })
|
|
1508
|
+
] }) }),
|
|
1468
1509
|
error && /* @__PURE__ */ jsx10("p", { className: "text-sm text-destructive", children: error }),
|
|
1469
1510
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
1470
1511
|
/* @__PURE__ */ jsx10(Button7, { type: "submit", disabled: saving, children: saving ? t("common.saving") : isEdit ? t("posts.form.saveChanges") : t("posts.form.createPost") }),
|
|
@@ -1478,8 +1519,8 @@ function PostForm({ post }) {
|
|
|
1478
1519
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1479
1520
|
function NewPostPage() {
|
|
1480
1521
|
const t = useT();
|
|
1481
|
-
return /* @__PURE__ */ jsxs9("div", { className: "p-8", children: [
|
|
1482
|
-
/* @__PURE__ */ jsx11("h1", { className: "mb-
|
|
1522
|
+
return /* @__PURE__ */ jsxs9("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
1523
|
+
/* @__PURE__ */ jsx11("h1", { className: "mb-6 text-2xl font-bold md:mb-8 md:text-3xl", children: t("posts.form.newTitle") }),
|
|
1483
1524
|
/* @__PURE__ */ jsx11(PostForm, {})
|
|
1484
1525
|
] });
|
|
1485
1526
|
}
|
|
@@ -1502,10 +1543,11 @@ function EditPostPage({ params }) {
|
|
|
1502
1543
|
else setPost(p);
|
|
1503
1544
|
}).finally(() => setLoading(false));
|
|
1504
1545
|
}, [postId]);
|
|
1505
|
-
if (loading)
|
|
1546
|
+
if (loading)
|
|
1547
|
+
return /* @__PURE__ */ jsx12("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: t("common.loading") });
|
|
1506
1548
|
if (missing) notFound();
|
|
1507
|
-
return /* @__PURE__ */ jsxs10("div", { className: "p-8", children: [
|
|
1508
|
-
/* @__PURE__ */ jsx12("h1", { className: "mb-
|
|
1549
|
+
return /* @__PURE__ */ jsxs10("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
1550
|
+
/* @__PURE__ */ jsx12("h1", { className: "mb-6 text-2xl font-bold md:mb-8 md:text-3xl", children: t("posts.form.editTitle") }),
|
|
1509
1551
|
post && /* @__PURE__ */ jsx12(PostForm, { post })
|
|
1510
1552
|
] });
|
|
1511
1553
|
}
|
|
@@ -1749,8 +1791,8 @@ function MediaUploader() {
|
|
|
1749
1791
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1750
1792
|
function MediaPage() {
|
|
1751
1793
|
const t = useT();
|
|
1752
|
-
return /* @__PURE__ */ jsxs12("div", { className: "p-8", children: [
|
|
1753
|
-
/* @__PURE__ */ jsx14("h1", { className: "mb-
|
|
1794
|
+
return /* @__PURE__ */ jsxs12("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
1795
|
+
/* @__PURE__ */ jsx14("h1", { className: "mb-6 text-2xl font-bold md:mb-8 md:text-3xl", children: t("media.title") }),
|
|
1754
1796
|
/* @__PURE__ */ jsx14(MediaUploader, {})
|
|
1755
1797
|
] });
|
|
1756
1798
|
}
|
|
@@ -1946,77 +1988,150 @@ function LoginPage() {
|
|
|
1946
1988
|
}
|
|
1947
1989
|
|
|
1948
1990
|
// src/components/sidebar.tsx
|
|
1991
|
+
import { useEffect as useEffect7, useState as useState9 } from "react";
|
|
1949
1992
|
import Link4 from "next/link";
|
|
1950
1993
|
import { usePathname } from "next/navigation";
|
|
1951
1994
|
import { signOut } from "aws-amplify/auth";
|
|
1952
|
-
import {
|
|
1995
|
+
import {
|
|
1996
|
+
LayoutDashboard,
|
|
1997
|
+
FileText as FileText2,
|
|
1998
|
+
Image as Image2,
|
|
1999
|
+
Globe,
|
|
2000
|
+
Users,
|
|
2001
|
+
LogOut,
|
|
2002
|
+
ExternalLink,
|
|
2003
|
+
Menu,
|
|
2004
|
+
X
|
|
2005
|
+
} from "lucide-react";
|
|
1953
2006
|
import { Button as Button10, cn as cn3 } from "@ampless/runtime/ui";
|
|
1954
|
-
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2007
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1955
2008
|
var navItems = [
|
|
1956
2009
|
{ href: "/admin", key: "sidebar.dashboard", icon: LayoutDashboard },
|
|
1957
2010
|
{ href: "/admin/posts", key: "sidebar.posts", icon: FileText2 },
|
|
1958
2011
|
{ href: "/admin/media", key: "sidebar.media", icon: Image2 },
|
|
1959
|
-
{ href: "/admin/sites", key: "sidebar.sites", icon: Globe }
|
|
2012
|
+
{ href: "/admin/sites", key: "sidebar.sites", icon: Globe },
|
|
2013
|
+
{ href: "/admin/users", key: "sidebar.users", icon: Users, adminOnly: true }
|
|
1960
2014
|
];
|
|
1961
2015
|
function Sidebar({
|
|
1962
2016
|
email,
|
|
1963
|
-
siteSelector
|
|
2017
|
+
siteSelector,
|
|
2018
|
+
isAdmin
|
|
1964
2019
|
}) {
|
|
1965
2020
|
const pathname = usePathname();
|
|
1966
2021
|
const t = useT();
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
t(item.key)
|
|
1984
|
-
]
|
|
1985
|
-
},
|
|
1986
|
-
item.href
|
|
1987
|
-
);
|
|
1988
|
-
}) }),
|
|
1989
|
-
/* @__PURE__ */ jsxs14("div", { className: "border-t p-2 space-y-1", children: [
|
|
1990
|
-
/* @__PURE__ */ jsxs14(
|
|
1991
|
-
Link4,
|
|
1992
|
-
{
|
|
1993
|
-
href: "/",
|
|
1994
|
-
target: "_blank",
|
|
1995
|
-
className: "flex items-center gap-3 rounded-md px-3 py-2 text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1996
|
-
children: [
|
|
1997
|
-
/* @__PURE__ */ jsx16(ExternalLink, { className: "h-4 w-4" }),
|
|
1998
|
-
t("sidebar.viewSite")
|
|
1999
|
-
]
|
|
2000
|
-
}
|
|
2001
|
-
),
|
|
2002
|
-
/* @__PURE__ */ jsx16("div", { className: "px-3 py-2 text-xs text-muted-foreground truncate", children: email }),
|
|
2003
|
-
/* @__PURE__ */ jsxs14(
|
|
2022
|
+
const [open, setOpen] = useState9(false);
|
|
2023
|
+
useEffect7(() => {
|
|
2024
|
+
setOpen(false);
|
|
2025
|
+
}, [pathname]);
|
|
2026
|
+
useEffect7(() => {
|
|
2027
|
+
if (!open) return;
|
|
2028
|
+
const prev = document.body.style.overflow;
|
|
2029
|
+
document.body.style.overflow = "hidden";
|
|
2030
|
+
return () => {
|
|
2031
|
+
document.body.style.overflow = prev;
|
|
2032
|
+
};
|
|
2033
|
+
}, [open]);
|
|
2034
|
+
return /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
2035
|
+
/* @__PURE__ */ jsxs14("header", { className: "sticky top-0 z-30 flex h-14 items-center justify-between border-b bg-background px-4 md:hidden", children: [
|
|
2036
|
+
/* @__PURE__ */ jsx16(Link4, { href: "/admin", className: "font-semibold", children: t("sidebar.brand") }),
|
|
2037
|
+
/* @__PURE__ */ jsx16(
|
|
2004
2038
|
Button10,
|
|
2005
2039
|
{
|
|
2006
2040
|
variant: "ghost",
|
|
2007
|
-
size: "
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
},
|
|
2013
|
-
children: [
|
|
2014
|
-
/* @__PURE__ */ jsx16(LogOut, { className: "h-4 w-4" }),
|
|
2015
|
-
t("sidebar.signOut")
|
|
2016
|
-
]
|
|
2041
|
+
size: "icon",
|
|
2042
|
+
"aria-label": t("sidebar.openMenu"),
|
|
2043
|
+
"aria-expanded": open,
|
|
2044
|
+
onClick: () => setOpen(true),
|
|
2045
|
+
children: /* @__PURE__ */ jsx16(Menu, { className: "h-5 w-5" })
|
|
2017
2046
|
}
|
|
2018
2047
|
)
|
|
2019
|
-
] })
|
|
2048
|
+
] }),
|
|
2049
|
+
open && /* @__PURE__ */ jsx16(
|
|
2050
|
+
"div",
|
|
2051
|
+
{
|
|
2052
|
+
className: "fixed inset-0 z-40 bg-black/40 md:hidden",
|
|
2053
|
+
"aria-hidden": "true",
|
|
2054
|
+
onClick: () => setOpen(false)
|
|
2055
|
+
}
|
|
2056
|
+
),
|
|
2057
|
+
/* @__PURE__ */ jsxs14(
|
|
2058
|
+
"aside",
|
|
2059
|
+
{
|
|
2060
|
+
className: cn3(
|
|
2061
|
+
"fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r bg-muted/30 transition-transform md:sticky md:top-0 md:h-screen md:translate-x-0",
|
|
2062
|
+
open ? "translate-x-0" : "-translate-x-full md:translate-x-0"
|
|
2063
|
+
),
|
|
2064
|
+
"aria-label": t("sidebar.brand"),
|
|
2065
|
+
children: [
|
|
2066
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between border-b p-4", children: [
|
|
2067
|
+
/* @__PURE__ */ jsx16(Link4, { href: "/admin", className: "font-semibold", children: t("sidebar.brand") }),
|
|
2068
|
+
/* @__PURE__ */ jsx16(
|
|
2069
|
+
Button10,
|
|
2070
|
+
{
|
|
2071
|
+
variant: "ghost",
|
|
2072
|
+
size: "icon",
|
|
2073
|
+
className: "md:hidden",
|
|
2074
|
+
"aria-label": t("sidebar.closeMenu"),
|
|
2075
|
+
onClick: () => setOpen(false),
|
|
2076
|
+
children: /* @__PURE__ */ jsx16(X, { className: "h-5 w-5" })
|
|
2077
|
+
}
|
|
2078
|
+
)
|
|
2079
|
+
] }),
|
|
2080
|
+
siteSelector ? /* @__PURE__ */ jsx16("div", { className: "border-b", children: siteSelector }) : null,
|
|
2081
|
+
/* @__PURE__ */ jsx16("nav", { className: "flex-1 space-y-1 overflow-y-auto p-2", children: navItems.map((item) => {
|
|
2082
|
+
if (item.adminOnly && !isAdmin) return null;
|
|
2083
|
+
const Icon = item.icon;
|
|
2084
|
+
const isActive = pathname === item.href || item.href !== "/admin" && pathname?.startsWith(item.href);
|
|
2085
|
+
return /* @__PURE__ */ jsxs14(
|
|
2086
|
+
Link4,
|
|
2087
|
+
{
|
|
2088
|
+
href: item.href,
|
|
2089
|
+
className: cn3(
|
|
2090
|
+
"flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors",
|
|
2091
|
+
isActive ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
2092
|
+
),
|
|
2093
|
+
children: [
|
|
2094
|
+
/* @__PURE__ */ jsx16(Icon, { className: "h-4 w-4" }),
|
|
2095
|
+
t(item.key)
|
|
2096
|
+
]
|
|
2097
|
+
},
|
|
2098
|
+
item.href
|
|
2099
|
+
);
|
|
2100
|
+
}) }),
|
|
2101
|
+
/* @__PURE__ */ jsxs14("div", { className: "border-t p-2 space-y-1", children: [
|
|
2102
|
+
/* @__PURE__ */ jsxs14(
|
|
2103
|
+
Link4,
|
|
2104
|
+
{
|
|
2105
|
+
href: "/",
|
|
2106
|
+
target: "_blank",
|
|
2107
|
+
className: "flex items-center gap-3 rounded-md px-3 py-2 text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
2108
|
+
children: [
|
|
2109
|
+
/* @__PURE__ */ jsx16(ExternalLink, { className: "h-4 w-4" }),
|
|
2110
|
+
t("sidebar.viewSite")
|
|
2111
|
+
]
|
|
2112
|
+
}
|
|
2113
|
+
),
|
|
2114
|
+
/* @__PURE__ */ jsx16("div", { className: "px-3 py-2 text-xs text-muted-foreground truncate", children: email }),
|
|
2115
|
+
/* @__PURE__ */ jsxs14(
|
|
2116
|
+
Button10,
|
|
2117
|
+
{
|
|
2118
|
+
variant: "ghost",
|
|
2119
|
+
size: "sm",
|
|
2120
|
+
className: "w-full justify-start gap-3",
|
|
2121
|
+
onClick: async () => {
|
|
2122
|
+
await signOut();
|
|
2123
|
+
window.location.href = "/login";
|
|
2124
|
+
},
|
|
2125
|
+
children: [
|
|
2126
|
+
/* @__PURE__ */ jsx16(LogOut, { className: "h-4 w-4" }),
|
|
2127
|
+
t("sidebar.signOut")
|
|
2128
|
+
]
|
|
2129
|
+
}
|
|
2130
|
+
)
|
|
2131
|
+
] })
|
|
2132
|
+
]
|
|
2133
|
+
}
|
|
2134
|
+
)
|
|
2020
2135
|
] });
|
|
2021
2136
|
}
|
|
2022
2137
|
|
|
@@ -2046,7 +2161,7 @@ function SiteSelector({ current, sites }) {
|
|
|
2046
2161
|
}
|
|
2047
2162
|
|
|
2048
2163
|
// src/components/site-settings-form.tsx
|
|
2049
|
-
import { useState as
|
|
2164
|
+
import { useState as useState10 } from "react";
|
|
2050
2165
|
import { useRouter as useRouter4 } from "next/navigation";
|
|
2051
2166
|
import { setSiteSetting } from "ampless";
|
|
2052
2167
|
import { Button as Button11, Input as Input5, Label as Label4, Textarea as Textarea2 } from "@ampless/runtime/ui";
|
|
@@ -2063,10 +2178,10 @@ var KEYS = [
|
|
|
2063
2178
|
function SiteSettingsForm({ siteId, initial, fallback }) {
|
|
2064
2179
|
const router = useRouter4();
|
|
2065
2180
|
const t = useT();
|
|
2066
|
-
const [values, setValues] =
|
|
2067
|
-
const [saving, setSaving] =
|
|
2068
|
-
const [error, setError] =
|
|
2069
|
-
const [info, setInfo] =
|
|
2181
|
+
const [values, setValues] = useState10(initial);
|
|
2182
|
+
const [saving, setSaving] = useState10(false);
|
|
2183
|
+
const [error, setError] = useState10(null);
|
|
2184
|
+
const [info, setInfo] = useState10(null);
|
|
2070
2185
|
function update(key, value) {
|
|
2071
2186
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
2072
2187
|
}
|
|
@@ -2208,7 +2323,7 @@ function SiteSettingsForm({ siteId, initial, fallback }) {
|
|
|
2208
2323
|
}
|
|
2209
2324
|
|
|
2210
2325
|
// src/components/theme-settings-form.tsx
|
|
2211
|
-
import { useState as
|
|
2326
|
+
import { useState as useState11 } from "react";
|
|
2212
2327
|
import { useRouter as useRouter5 } from "next/navigation";
|
|
2213
2328
|
import {
|
|
2214
2329
|
setSiteSetting as setSiteSetting2,
|
|
@@ -2232,14 +2347,14 @@ function ThemeSettingsForm({
|
|
|
2232
2347
|
const router = useRouter5();
|
|
2233
2348
|
const t = useT();
|
|
2234
2349
|
const locale = useLocale();
|
|
2235
|
-
const [state, setState] =
|
|
2236
|
-
const [pendingTheme, setPendingTheme] =
|
|
2237
|
-
const [optimisticActive, setOptimisticActive] =
|
|
2238
|
-
const [saving, setSaving] =
|
|
2239
|
-
const [switching, setSwitching] =
|
|
2240
|
-
const [error, setError] =
|
|
2241
|
-
const [info, setInfo] =
|
|
2242
|
-
const [invalid, setInvalid] =
|
|
2350
|
+
const [state, setState] = useState11({ values: initial, touched: {} });
|
|
2351
|
+
const [pendingTheme, setPendingTheme] = useState11(activeTheme);
|
|
2352
|
+
const [optimisticActive, setOptimisticActive] = useState11(activeTheme);
|
|
2353
|
+
const [saving, setSaving] = useState11(false);
|
|
2354
|
+
const [switching, setSwitching] = useState11(false);
|
|
2355
|
+
const [error, setError] = useState11(null);
|
|
2356
|
+
const [info, setInfo] = useState11(null);
|
|
2357
|
+
const [invalid, setInvalid] = useState11({});
|
|
2243
2358
|
function update(key, value) {
|
|
2244
2359
|
setState((prev) => ({
|
|
2245
2360
|
values: { ...prev.values, [key]: value },
|
|
@@ -34,9 +34,12 @@ var en_default = {
|
|
|
34
34
|
posts: "Posts",
|
|
35
35
|
media: "Media",
|
|
36
36
|
sites: "Sites",
|
|
37
|
+
users: "Users",
|
|
37
38
|
viewSite: "View site",
|
|
38
39
|
signOut: "Sign out",
|
|
39
|
-
site: "Site"
|
|
40
|
+
site: "Site",
|
|
41
|
+
openMenu: "Open menu",
|
|
42
|
+
closeMenu: "Close menu"
|
|
40
43
|
},
|
|
41
44
|
dashboard: {
|
|
42
45
|
title: "Dashboard",
|
|
@@ -76,6 +79,8 @@ var en_default = {
|
|
|
76
79
|
tagsPlaceholder: "comma, separated, tags",
|
|
77
80
|
tagsHint: "Used to group posts on tag pages (e.g. /tag/tech).",
|
|
78
81
|
status: "Status",
|
|
82
|
+
noLayout: "No layout",
|
|
83
|
+
noLayoutHint: "Serve this post as bare HTML \u2014 no theme header, footer, or root layout. The body is returned as the entire response. Best paired with format: HTML when the body contains a full <!DOCTYPE html>\u2026</html> document.",
|
|
79
84
|
saveChanges: "Save changes",
|
|
80
85
|
createPost: "Create post",
|
|
81
86
|
delete: "Delete",
|
|
@@ -147,6 +152,25 @@ var en_default = {
|
|
|
147
152
|
label: "Site"
|
|
148
153
|
}
|
|
149
154
|
},
|
|
155
|
+
users: {
|
|
156
|
+
list: {
|
|
157
|
+
title: "Users",
|
|
158
|
+
description: "Promote signed-up users to admin or editor. Sign-ups always start with no role and must be granted access here.",
|
|
159
|
+
columnEmail: "Email",
|
|
160
|
+
columnRole: "Role",
|
|
161
|
+
columnActions: "Actions",
|
|
162
|
+
save: "Save",
|
|
163
|
+
saving: "Saving...",
|
|
164
|
+
saved: "Saved.",
|
|
165
|
+
cannotEditSelf: "You cannot change your own role.",
|
|
166
|
+
empty: "No users yet.",
|
|
167
|
+
loading: "Loading users...",
|
|
168
|
+
error: "Failed to load users",
|
|
169
|
+
roleAdmin: "Admin",
|
|
170
|
+
roleEditor: "Editor",
|
|
171
|
+
roleNone: "None"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
150
174
|
theme: {
|
|
151
175
|
title: "Theme",
|
|
152
176
|
activeLabel: "Active theme",
|
|
@@ -269,9 +293,12 @@ var ja_default = {
|
|
|
269
293
|
posts: "\u8A18\u4E8B",
|
|
270
294
|
media: "\u30E1\u30C7\u30A3\u30A2",
|
|
271
295
|
sites: "\u30B5\u30A4\u30C8",
|
|
296
|
+
users: "\u30E6\u30FC\u30B6\u30FC",
|
|
272
297
|
viewSite: "\u30B5\u30A4\u30C8\u3092\u8868\u793A",
|
|
273
298
|
signOut: "\u30B5\u30A4\u30F3\u30A2\u30A6\u30C8",
|
|
274
|
-
site: "\u30B5\u30A4\u30C8"
|
|
299
|
+
site: "\u30B5\u30A4\u30C8",
|
|
300
|
+
openMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u958B\u304F",
|
|
301
|
+
closeMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B"
|
|
275
302
|
},
|
|
276
303
|
dashboard: {
|
|
277
304
|
title: "\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9",
|
|
@@ -311,6 +338,8 @@ var ja_default = {
|
|
|
311
338
|
tagsPlaceholder: "\u30AB\u30F3\u30DE, \u533A\u5207\u308A, \u30BF\u30B0",
|
|
312
339
|
tagsHint: "\u30BF\u30B0\u30DA\u30FC\u30B8\u3067\u8A18\u4E8B\u3092\u30B0\u30EB\u30FC\u30D4\u30F3\u30B0 (\u4F8B: /tag/tech)\u3002",
|
|
313
340
|
status: "\u30B9\u30C6\u30FC\u30BF\u30B9",
|
|
341
|
+
noLayout: "\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u4F7F\u308F\u306A\u3044",
|
|
342
|
+
noLayoutHint: "\u30C6\u30FC\u30DE\u306E\u30D8\u30C3\u30C0\u30FC / \u30D5\u30C3\u30BF\u30FC / root layout \u3092\u4ECB\u3055\u305A\u3001\u672C\u6587\u3092 HTTP \u30EC\u30B9\u30DD\u30F3\u30B9\u672C\u4F53\u3068\u3057\u3066\u305D\u306E\u307E\u307E\u8FD4\u3057\u307E\u3059\u3002\u672C\u6587\u306B <!DOCTYPE html>\u2026</html> \u304C\u542B\u307E\u308C\u308B\u5834\u5408\u306F\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8: HTML \u3068\u306E\u7D44\u307F\u5408\u308F\u305B\u304C\u6700\u9069\u3067\u3059\u3002",
|
|
314
343
|
saveChanges: "\u5909\u66F4\u3092\u4FDD\u5B58",
|
|
315
344
|
createPost: "\u8A18\u4E8B\u3092\u4F5C\u6210",
|
|
316
345
|
delete: "\u524A\u9664",
|
|
@@ -382,6 +411,25 @@ var ja_default = {
|
|
|
382
411
|
label: "\u30B5\u30A4\u30C8"
|
|
383
412
|
}
|
|
384
413
|
},
|
|
414
|
+
users: {
|
|
415
|
+
list: {
|
|
416
|
+
title: "\u30E6\u30FC\u30B6\u30FC",
|
|
417
|
+
description: "\u30B5\u30A4\u30F3\u30A2\u30C3\u30D7\u6E08\u307F\u30E6\u30FC\u30B6\u30FC\u3092\u7BA1\u7406\u8005\u307E\u305F\u306F\u7DE8\u96C6\u8005\u306B\u6607\u683C\u3057\u307E\u3059\u3002\u30B5\u30A4\u30F3\u30A2\u30C3\u30D7\u76F4\u5F8C\u306F\u30ED\u30FC\u30EB\u7121\u3057\u306E\u305F\u3081\u3001\u3053\u3053\u3067\u30A2\u30AF\u30BB\u30B9\u3092\u4ED8\u4E0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
418
|
+
columnEmail: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9",
|
|
419
|
+
columnRole: "\u30ED\u30FC\u30EB",
|
|
420
|
+
columnActions: "\u64CD\u4F5C",
|
|
421
|
+
save: "\u4FDD\u5B58",
|
|
422
|
+
saving: "\u4FDD\u5B58\u4E2D...",
|
|
423
|
+
saved: "\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
|
|
424
|
+
cannotEditSelf: "\u81EA\u5206\u81EA\u8EAB\u306E\u30ED\u30FC\u30EB\u306F\u5909\u66F4\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
425
|
+
empty: "\u30E6\u30FC\u30B6\u30FC\u304C\u3044\u307E\u305B\u3093\u3002",
|
|
426
|
+
loading: "\u30E6\u30FC\u30B6\u30FC\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...",
|
|
427
|
+
error: "\u30E6\u30FC\u30B6\u30FC\u4E00\u89A7\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
428
|
+
roleAdmin: "\u7BA1\u7406\u8005",
|
|
429
|
+
roleEditor: "\u7DE8\u96C6\u8005",
|
|
430
|
+
roleNone: "\u306A\u3057"
|
|
431
|
+
}
|
|
432
|
+
},
|
|
385
433
|
theme: {
|
|
386
434
|
title: "\u30C6\u30FC\u30DE",
|
|
387
435
|
activeLabel: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30C6\u30FC\u30DE",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { L as Locale, D as Dictionary } from '../i18n-
|
|
2
|
+
import { L as Locale, D as Dictionary } from '../i18n-Bc4SYgWx.js';
|
|
3
3
|
import { Config, Post, ThemeManifest, LocalizedString, MediaProcessingDefaults } from 'ampless';
|
|
4
4
|
import { AmplessOutputs } from '@ampless/runtime';
|
|
5
5
|
export { A as AdminDashboard, E as EditPostPage, L as LoginPage, M as MediaPage, N as NewPostPage, P as PostsList } from '../login-view-BKrSZLJu.js';
|
|
@@ -108,10 +108,12 @@ declare function uploadProcessedImage(file: File, options: ProcessOptions): Prom
|
|
|
108
108
|
url: string;
|
|
109
109
|
}>;
|
|
110
110
|
|
|
111
|
-
declare function Sidebar({ email, siteSelector, }: {
|
|
111
|
+
declare function Sidebar({ email, siteSelector, isAdmin, }: {
|
|
112
112
|
email: string;
|
|
113
113
|
/** Rendered above the main nav in multi-site mode. */
|
|
114
114
|
siteSelector?: React.ReactNode;
|
|
115
|
+
/** Gates `adminOnly` nav entries (user management). */
|
|
116
|
+
isAdmin: boolean;
|
|
115
117
|
}): react_jsx_runtime.JSX.Element;
|
|
116
118
|
|
|
117
119
|
interface SiteOption {
|
package/dist/components/index.js
CHANGED
|
@@ -22,12 +22,12 @@ import {
|
|
|
22
22
|
uploadProcessedImage,
|
|
23
23
|
useLocale,
|
|
24
24
|
useT
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-GXPSAOES.js";
|
|
26
26
|
import {
|
|
27
27
|
ADMIN_SITE_COOKIE,
|
|
28
28
|
publicMediaUrl,
|
|
29
29
|
setAdminMediaContext
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-L5NHN3MY.js";
|
|
31
31
|
import {
|
|
32
32
|
invalidateSiteSettingsCache
|
|
33
33
|
} from "../chunk-VXEVLHGL.js";
|