@ampless/admin 0.2.0-alpha.0 → 0.2.0-alpha.10
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-OFHKZNZS.js +33 -0
- package/dist/{chunk-TJR3ALRJ.js → chunk-OPQ3SAZJ.js} +75 -66
- package/dist/chunk-PAL62MXF.js +3228 -0
- package/dist/chunk-QMVFRT62.js +42 -0
- package/dist/chunk-UOU7KQLR.js +149 -0
- package/dist/chunk-VXEVLHGL.js +10 -0
- package/dist/components/index.d.ts +33 -15
- package/dist/components/index.js +29 -9
- package/dist/components/users-list-view.d.ts +7 -0
- package/dist/components/users-list-view.js +9 -0
- package/dist/{i18n-ByHM_Bho.d.ts → i18n-DzXXcIQQ.d.ts} +110 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -2
- package/dist/lib/theme-actions.d.ts +17 -0
- package/dist/lib/theme-actions.js +7 -0
- package/dist/login-view-BKrSZLJu.d.ts +24 -0
- package/dist/metafile-esm.json +1 -0
- package/dist/pages/index.d.ts +44 -15
- package/dist/pages/index.js +97 -658
- package/package.json +19 -18
- package/dist/chunk-BN6BW7MP.js +0 -2074
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/lib/media.ts
|
|
2
|
+
var state = { outputs: null, cmsConfig: null };
|
|
3
|
+
function setAdminMediaContext(outputs, cmsConfig) {
|
|
4
|
+
state.outputs = outputs;
|
|
5
|
+
state.cmsConfig = cmsConfig;
|
|
6
|
+
}
|
|
7
|
+
function publicMediaUrl(input) {
|
|
8
|
+
if (/^https?:\/\//.test(input)) return input;
|
|
9
|
+
let path = input.replace(/^\/+/, "");
|
|
10
|
+
if (path.startsWith("public/")) path = path.slice("public/".length);
|
|
11
|
+
const { outputs, cmsConfig } = state;
|
|
12
|
+
const delivery = cmsConfig?.media?.delivery ?? "nextjs";
|
|
13
|
+
if (delivery !== "s3-direct") return `/api/media/${path}`;
|
|
14
|
+
const storage = outputs?.storage;
|
|
15
|
+
if (!storage) return `/api/media/${path}`;
|
|
16
|
+
return `https://${storage.bucket_name}.s3.${storage.aws_region}.amazonaws.com/public/${path}`;
|
|
17
|
+
}
|
|
18
|
+
function createMedia(outputs, cmsConfig) {
|
|
19
|
+
const storage = outputs.storage;
|
|
20
|
+
function s3DirectUrl(path) {
|
|
21
|
+
if (!storage) return `/api/media/${path}`;
|
|
22
|
+
return `https://${storage.bucket_name}.s3.${storage.aws_region}.amazonaws.com/public/${path}`;
|
|
23
|
+
}
|
|
24
|
+
function urlFor(input) {
|
|
25
|
+
if (/^https?:\/\//.test(input)) return input;
|
|
26
|
+
let path = input.replace(/^\/+/, "");
|
|
27
|
+
if (path.startsWith("public/")) path = path.slice("public/".length);
|
|
28
|
+
const delivery = cmsConfig.media?.delivery ?? "nextjs";
|
|
29
|
+
return delivery === "s3-direct" ? s3DirectUrl(path) : `/api/media/${path}`;
|
|
30
|
+
}
|
|
31
|
+
return { publicMediaUrl: urlFor };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/lib/admin-site-cookie.ts
|
|
35
|
+
var ADMIN_SITE_COOKIE = "admin-site-id";
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
setAdminMediaContext,
|
|
39
|
+
publicMediaUrl,
|
|
40
|
+
createMedia,
|
|
41
|
+
ADMIN_SITE_COOKIE
|
|
42
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
useT
|
|
4
|
+
} from "./chunk-OFHKZNZS.js";
|
|
5
|
+
|
|
6
|
+
// src/components/users-list-view.tsx
|
|
7
|
+
import { useEffect, useState } from "react";
|
|
8
|
+
import { generateClient } from "aws-amplify/api";
|
|
9
|
+
import {
|
|
10
|
+
Button,
|
|
11
|
+
Table,
|
|
12
|
+
TableBody,
|
|
13
|
+
TableCell,
|
|
14
|
+
TableHead,
|
|
15
|
+
TableHeader,
|
|
16
|
+
TableRow
|
|
17
|
+
} from "@ampless/runtime/ui";
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
function isAdminRole(value) {
|
|
20
|
+
return value === "admin" || value === "editor" || value === "none";
|
|
21
|
+
}
|
|
22
|
+
function UsersListView({ currentUserId }) {
|
|
23
|
+
const t = useT();
|
|
24
|
+
const [users, setUsers] = useState(null);
|
|
25
|
+
const [loading, setLoading] = useState(true);
|
|
26
|
+
const [loadError, setLoadError] = useState(null);
|
|
27
|
+
const [rows, setRows] = useState({});
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const client = generateClient();
|
|
30
|
+
client.queries.listAdminUsers().then(({ data, errors }) => {
|
|
31
|
+
if (errors && errors.length > 0) {
|
|
32
|
+
const msg = errors[0]?.message ?? "listAdminUsers failed";
|
|
33
|
+
console.error("[users-list-view] listAdminUsers errors:", errors);
|
|
34
|
+
setLoadError(msg);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const list = data ?? [];
|
|
38
|
+
setUsers(list);
|
|
39
|
+
setRows(
|
|
40
|
+
Object.fromEntries(
|
|
41
|
+
list.map((u) => [u.userId, { selected: u.role, saving: false, error: null }])
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
}).catch((err) => {
|
|
45
|
+
console.error("[users-list-view] listAdminUsers threw:", err);
|
|
46
|
+
setLoadError(err instanceof Error ? err.message : String(err));
|
|
47
|
+
}).finally(() => setLoading(false));
|
|
48
|
+
}, []);
|
|
49
|
+
function updateRow(userId, patch) {
|
|
50
|
+
setRows((prev) => ({
|
|
51
|
+
...prev,
|
|
52
|
+
[userId]: { ...prev[userId], ...patch }
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
async function save(userId) {
|
|
56
|
+
const row = rows[userId];
|
|
57
|
+
if (!row) return;
|
|
58
|
+
updateRow(userId, { saving: true, error: null });
|
|
59
|
+
try {
|
|
60
|
+
const client = generateClient();
|
|
61
|
+
const { data, errors } = await client.mutations.setAdminUserRole({
|
|
62
|
+
userId,
|
|
63
|
+
role: row.selected
|
|
64
|
+
});
|
|
65
|
+
if (errors && errors.length > 0) {
|
|
66
|
+
const msg = errors[0]?.message ?? "setAdminUserRole failed";
|
|
67
|
+
console.error("[users-list-view] setAdminUserRole errors:", errors);
|
|
68
|
+
updateRow(userId, { saving: false, error: msg });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (data) {
|
|
72
|
+
setUsers(
|
|
73
|
+
(prev) => (prev ?? []).map((u) => u.userId === userId ? data : u)
|
|
74
|
+
);
|
|
75
|
+
updateRow(userId, { saving: false, selected: data.role, error: null });
|
|
76
|
+
} else {
|
|
77
|
+
updateRow(userId, { saving: false });
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error("[users-list-view] setAdminUserRole threw:", err);
|
|
81
|
+
updateRow(userId, {
|
|
82
|
+
saving: false,
|
|
83
|
+
error: err instanceof Error ? err.message : String(err)
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
88
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-6 md:mb-8", children: [
|
|
89
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold md:text-3xl", children: t("users.list.title") }),
|
|
90
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t("users.list.description") })
|
|
91
|
+
] }),
|
|
92
|
+
loading ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("users.list.loading") }) : loadError ? /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
93
|
+
t("users.list.error"),
|
|
94
|
+
": ",
|
|
95
|
+
loadError
|
|
96
|
+
] }) : !users || users.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("users.list.empty") }) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
97
|
+
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
98
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("users.list.columnEmail") }),
|
|
99
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("users.list.columnRole") }),
|
|
100
|
+
/* @__PURE__ */ jsx(TableHead, { className: "w-[1%] whitespace-nowrap", children: t("users.list.columnActions") })
|
|
101
|
+
] }) }),
|
|
102
|
+
/* @__PURE__ */ jsx(TableBody, { children: users.map((u) => {
|
|
103
|
+
const row = rows[u.userId];
|
|
104
|
+
if (!row) return null;
|
|
105
|
+
const isSelf = u.userId === currentUserId;
|
|
106
|
+
const dirty = row.selected !== u.role;
|
|
107
|
+
return /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
108
|
+
/* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: u.email || u.userId }),
|
|
109
|
+
/* @__PURE__ */ jsxs(TableCell, { children: [
|
|
110
|
+
/* @__PURE__ */ jsxs(
|
|
111
|
+
"select",
|
|
112
|
+
{
|
|
113
|
+
className: "rounded-md border bg-background px-2 py-1.5 text-sm disabled:cursor-not-allowed disabled:opacity-60",
|
|
114
|
+
value: row.selected,
|
|
115
|
+
disabled: isSelf || row.saving,
|
|
116
|
+
onChange: (e) => {
|
|
117
|
+
const next = e.target.value;
|
|
118
|
+
if (isAdminRole(next)) {
|
|
119
|
+
updateRow(u.userId, { selected: next });
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
children: [
|
|
123
|
+
/* @__PURE__ */ jsx("option", { value: "admin", children: t("users.list.roleAdmin") }),
|
|
124
|
+
/* @__PURE__ */ jsx("option", { value: "editor", children: t("users.list.roleEditor") }),
|
|
125
|
+
/* @__PURE__ */ jsx("option", { value: "none", children: t("users.list.roleNone") })
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
isSelf && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("users.list.cannotEditSelf") }),
|
|
130
|
+
row.error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive", children: row.error })
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
133
|
+
Button,
|
|
134
|
+
{
|
|
135
|
+
size: "sm",
|
|
136
|
+
disabled: isSelf || row.saving || !dirty,
|
|
137
|
+
onClick: () => save(u.userId),
|
|
138
|
+
children: row.saving ? t("users.list.saving") : t("users.list.save")
|
|
139
|
+
}
|
|
140
|
+
) })
|
|
141
|
+
] }, u.userId);
|
|
142
|
+
}) })
|
|
143
|
+
] }) })
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
UsersListView
|
|
149
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
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-DzXXcIQQ.js';
|
|
3
3
|
import { Config, Post, ThemeManifest, LocalizedString, MediaProcessingDefaults } from 'ampless';
|
|
4
4
|
import { AmplessOutputs } from '@ampless/runtime';
|
|
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';
|
|
5
6
|
import { ProcessOptions } from 'ampless/media';
|
|
7
|
+
export { invalidateSiteSettingsCache } from '../lib/theme-actions.js';
|
|
6
8
|
|
|
7
9
|
interface ProviderProps {
|
|
8
10
|
locale: Locale;
|
|
@@ -23,7 +25,33 @@ declare function useT(): (key: string, vars?: Record<string, string | number>) =
|
|
|
23
25
|
/** Read the active locale from context (e.g. for `<html lang>` parity). */
|
|
24
26
|
declare function useLocale(): Locale;
|
|
25
27
|
|
|
28
|
+
interface Props$3 {
|
|
29
|
+
outputs: AmplessOutputs;
|
|
30
|
+
cmsConfig: Config;
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Client-side admin bootstrap. Runs on first render of any admin route
|
|
35
|
+
* — configures the Amplify SDK, registers the cms.config / outputs in
|
|
36
|
+
* the client-side state modules, and installs the admin's posts / kv
|
|
37
|
+
* providers so 'ampless'-imported functions hit the AppSync client.
|
|
38
|
+
*
|
|
39
|
+
* All bootstrap calls happen synchronously during render, NOT in
|
|
40
|
+
* `useEffect`. React runs child useEffects before parent useEffects,
|
|
41
|
+
* so if `installAdminPostsProvider` were inside an effect, a child
|
|
42
|
+
* page's first `listPosts()` call (also in a useEffect) would race
|
|
43
|
+
* the install and fall back to ampless's dummy data. Synchronous
|
|
44
|
+
* registration guarantees the provider is in place before any child
|
|
45
|
+
* component mounts.
|
|
46
|
+
*
|
|
47
|
+
* All side effects are idempotent (the install functions guard with an
|
|
48
|
+
* `installed` flag) — mounting this multiple times (e.g. during HMR or
|
|
49
|
+
* remount) is safe.
|
|
50
|
+
*/
|
|
51
|
+
declare function AdminProviders({ outputs, cmsConfig, children }: Props$3): react_jsx_runtime.JSX.Element;
|
|
52
|
+
|
|
26
53
|
declare const ADMIN_SITE_COOKIE = "admin-site-id";
|
|
54
|
+
|
|
27
55
|
/**
|
|
28
56
|
* Register the cms.config for client-side multi-site lookups. Called
|
|
29
57
|
* once from the admin layout factory.
|
|
@@ -80,22 +108,12 @@ declare function uploadProcessedImage(file: File, options: ProcessOptions): Prom
|
|
|
80
108
|
url: string;
|
|
81
109
|
}>;
|
|
82
110
|
|
|
83
|
-
|
|
84
|
-
* Force-invalidate the Next.js fetch cache for a site's settings JSON.
|
|
85
|
-
* Used by the admin theme switcher: writes to KvStore propagate to S3
|
|
86
|
-
* via the trusted processor (~5-10s), and without this call the
|
|
87
|
-
* `revalidate: 60` on the public-side fetch would keep serving the old
|
|
88
|
-
* cached response for up to a minute after the rebuild.
|
|
89
|
-
*
|
|
90
|
-
* The cache tag matches the one used in `theme-active.ts` and
|
|
91
|
-
* `theme-config.ts` (in `@ampless/runtime`): `site-settings:{siteId}`.
|
|
92
|
-
*/
|
|
93
|
-
declare function invalidateSiteSettingsCache(siteId: string): Promise<void>;
|
|
94
|
-
|
|
95
|
-
declare function Sidebar({ email, siteSelector, }: {
|
|
111
|
+
declare function Sidebar({ email, siteSelector, isAdmin, }: {
|
|
96
112
|
email: string;
|
|
97
113
|
/** Rendered above the main nav in multi-site mode. */
|
|
98
114
|
siteSelector?: React.ReactNode;
|
|
115
|
+
/** Gates `adminOnly` nav entries (user management). */
|
|
116
|
+
isAdmin: boolean;
|
|
99
117
|
}): react_jsx_runtime.JSX.Element;
|
|
100
118
|
|
|
101
119
|
interface SiteOption {
|
|
@@ -166,4 +184,4 @@ interface ImageUploadDialogProps {
|
|
|
166
184
|
}
|
|
167
185
|
declare function ImageUploadDialog({ file, remaining, busy, defaults, onConfirm, onSkip, onCancel, }: ImageUploadDialogProps): react_jsx_runtime.JSX.Element | null;
|
|
168
186
|
|
|
169
|
-
export { ADMIN_SITE_COOKIE, I18nProvider, ImageUploadDialog, type ImageUploadDialogProps, MediaPicker, MediaUploader, PostForm, Sidebar, SiteSelector, SiteSettingsForm, type SiteSettingsFormValues, ThemeSettingsForm,
|
|
187
|
+
export { ADMIN_SITE_COOKIE, AdminProviders, I18nProvider, ImageUploadDialog, type ImageUploadDialogProps, MediaPicker, MediaUploader, PostForm, Sidebar, SiteSelector, SiteSettingsForm, type SiteSettingsFormValues, ThemeSettingsForm, publicMediaUrl, readAdminSiteIdFromCookie, sanitizeName, setAdminCmsConfig, setAdminMediaContext, uploadProcessedImage, useLocale, useT };
|
package/dist/components/index.js
CHANGED
|
@@ -1,33 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
+
AdminDashboard,
|
|
4
|
+
AdminProviders,
|
|
5
|
+
EditPostPage,
|
|
3
6
|
ImageUploadDialog,
|
|
7
|
+
LoginPage,
|
|
8
|
+
MediaPage,
|
|
4
9
|
MediaPicker,
|
|
5
10
|
MediaUploader,
|
|
11
|
+
NewPostPage,
|
|
6
12
|
PostForm,
|
|
13
|
+
PostsList,
|
|
7
14
|
Sidebar,
|
|
8
15
|
SiteSelector,
|
|
9
16
|
SiteSettingsForm,
|
|
10
17
|
ThemeSettingsForm,
|
|
11
|
-
|
|
18
|
+
readAdminSiteIdFromCookie,
|
|
12
19
|
sanitizeName,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "../chunk-BN6BW7MP.js";
|
|
20
|
+
setAdminCmsConfig,
|
|
21
|
+
uploadProcessedImage
|
|
22
|
+
} from "../chunk-PAL62MXF.js";
|
|
17
23
|
import {
|
|
18
24
|
ADMIN_SITE_COOKIE,
|
|
19
25
|
publicMediaUrl,
|
|
20
|
-
readAdminSiteIdFromCookie,
|
|
21
|
-
setAdminCmsConfig,
|
|
22
26
|
setAdminMediaContext
|
|
23
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-QMVFRT62.js";
|
|
28
|
+
import {
|
|
29
|
+
I18nProvider,
|
|
30
|
+
useLocale,
|
|
31
|
+
useT
|
|
32
|
+
} from "../chunk-OFHKZNZS.js";
|
|
33
|
+
import "../chunk-OPQ3SAZJ.js";
|
|
34
|
+
import {
|
|
35
|
+
invalidateSiteSettingsCache
|
|
36
|
+
} from "../chunk-VXEVLHGL.js";
|
|
24
37
|
export {
|
|
25
38
|
ADMIN_SITE_COOKIE,
|
|
39
|
+
AdminDashboard,
|
|
40
|
+
AdminProviders,
|
|
41
|
+
EditPostPage,
|
|
26
42
|
I18nProvider,
|
|
27
43
|
ImageUploadDialog,
|
|
44
|
+
LoginPage,
|
|
45
|
+
MediaPage,
|
|
28
46
|
MediaPicker,
|
|
29
47
|
MediaUploader,
|
|
48
|
+
NewPostPage,
|
|
30
49
|
PostForm,
|
|
50
|
+
PostsList,
|
|
31
51
|
Sidebar,
|
|
32
52
|
SiteSelector,
|
|
33
53
|
SiteSettingsForm,
|
|
@@ -32,9 +32,12 @@ var sidebar = {
|
|
|
32
32
|
posts: "Posts",
|
|
33
33
|
media: "Media",
|
|
34
34
|
sites: "Sites",
|
|
35
|
+
users: "Users",
|
|
35
36
|
viewSite: "View site",
|
|
36
37
|
signOut: "Sign out",
|
|
37
|
-
site: "Site"
|
|
38
|
+
site: "Site",
|
|
39
|
+
openMenu: "Open menu",
|
|
40
|
+
closeMenu: "Close menu"
|
|
38
41
|
};
|
|
39
42
|
var dashboard = {
|
|
40
43
|
title: "Dashboard",
|
|
@@ -74,6 +77,20 @@ var posts = {
|
|
|
74
77
|
tagsPlaceholder: "comma, separated, tags",
|
|
75
78
|
tagsHint: "Used to group posts on tag pages (e.g. /tag/tech).",
|
|
76
79
|
status: "Status",
|
|
80
|
+
noLayout: "No layout",
|
|
81
|
+
noLayoutHint: "Serve this post as bare HTML — 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>…</html> document.",
|
|
82
|
+
formatStaticLabel: "Static (zip / file bundle)",
|
|
83
|
+
"static": {
|
|
84
|
+
pick: "Pick a .zip or one or more files",
|
|
85
|
+
pickHint: "Bundle assets must reference each other with relative paths only (no leading /). The zip's contents are extracted into a directory under your post slug and served verbatim — no theme chrome.",
|
|
86
|
+
currentBundle: "Current bundle: {count} files (entry: {entrypoint})",
|
|
87
|
+
pendingBundle: "Pending upload: {count} files, {size}",
|
|
88
|
+
issuesTitle: "{count} validation issue(s)",
|
|
89
|
+
issuesHint: "Fix the listed paths and re-upload. Absolute (/foo) and protocol-relative (//cdn.example/foo) references break under the bundle's URL prefix.",
|
|
90
|
+
emptyBundle: "No usable files found in the selection.",
|
|
91
|
+
noBundle: "Pick a bundle before saving.",
|
|
92
|
+
previewHint: "Static bundles render as the served HTML at /<slug>/. Preview by saving and visiting the public URL."
|
|
93
|
+
},
|
|
77
94
|
saveChanges: "Save changes",
|
|
78
95
|
createPost: "Create post",
|
|
79
96
|
"delete": "Delete",
|
|
@@ -145,6 +162,25 @@ var sites = {
|
|
|
145
162
|
label: "Site"
|
|
146
163
|
}
|
|
147
164
|
};
|
|
165
|
+
var users = {
|
|
166
|
+
list: {
|
|
167
|
+
title: "Users",
|
|
168
|
+
description: "Promote signed-up users to admin or editor. Sign-ups always start with no role and must be granted access here.",
|
|
169
|
+
columnEmail: "Email",
|
|
170
|
+
columnRole: "Role",
|
|
171
|
+
columnActions: "Actions",
|
|
172
|
+
save: "Save",
|
|
173
|
+
saving: "Saving...",
|
|
174
|
+
saved: "Saved.",
|
|
175
|
+
cannotEditSelf: "You cannot change your own role.",
|
|
176
|
+
empty: "No users yet.",
|
|
177
|
+
loading: "Loading users...",
|
|
178
|
+
error: "Failed to load users",
|
|
179
|
+
roleAdmin: "Admin",
|
|
180
|
+
roleEditor: "Editor",
|
|
181
|
+
roleNone: "None"
|
|
182
|
+
}
|
|
183
|
+
};
|
|
148
184
|
var theme = {
|
|
149
185
|
title: "Theme",
|
|
150
186
|
activeLabel: "Active theme",
|
|
@@ -231,6 +267,7 @@ var en = {
|
|
|
231
267
|
media: media,
|
|
232
268
|
mediaPicker: mediaPicker,
|
|
233
269
|
sites: sites,
|
|
270
|
+
users: users,
|
|
234
271
|
theme: theme,
|
|
235
272
|
editor: editor,
|
|
236
273
|
auth: auth,
|
|
@@ -278,9 +315,12 @@ declare const dictionaries: {
|
|
|
278
315
|
posts: string;
|
|
279
316
|
media: string;
|
|
280
317
|
sites: string;
|
|
318
|
+
users: string;
|
|
281
319
|
viewSite: string;
|
|
282
320
|
signOut: string;
|
|
283
321
|
site: string;
|
|
322
|
+
openMenu: string;
|
|
323
|
+
closeMenu: string;
|
|
284
324
|
};
|
|
285
325
|
dashboard: {
|
|
286
326
|
title: string;
|
|
@@ -320,6 +360,20 @@ declare const dictionaries: {
|
|
|
320
360
|
tagsPlaceholder: string;
|
|
321
361
|
tagsHint: string;
|
|
322
362
|
status: string;
|
|
363
|
+
noLayout: string;
|
|
364
|
+
noLayoutHint: string;
|
|
365
|
+
formatStaticLabel: string;
|
|
366
|
+
static: {
|
|
367
|
+
pick: string;
|
|
368
|
+
pickHint: string;
|
|
369
|
+
currentBundle: string;
|
|
370
|
+
pendingBundle: string;
|
|
371
|
+
issuesTitle: string;
|
|
372
|
+
issuesHint: string;
|
|
373
|
+
emptyBundle: string;
|
|
374
|
+
noBundle: string;
|
|
375
|
+
previewHint: string;
|
|
376
|
+
};
|
|
323
377
|
saveChanges: string;
|
|
324
378
|
createPost: string;
|
|
325
379
|
delete: string;
|
|
@@ -391,6 +445,25 @@ declare const dictionaries: {
|
|
|
391
445
|
label: string;
|
|
392
446
|
};
|
|
393
447
|
};
|
|
448
|
+
users: {
|
|
449
|
+
list: {
|
|
450
|
+
title: string;
|
|
451
|
+
description: string;
|
|
452
|
+
columnEmail: string;
|
|
453
|
+
columnRole: string;
|
|
454
|
+
columnActions: string;
|
|
455
|
+
save: string;
|
|
456
|
+
saving: string;
|
|
457
|
+
saved: string;
|
|
458
|
+
cannotEditSelf: string;
|
|
459
|
+
empty: string;
|
|
460
|
+
loading: string;
|
|
461
|
+
error: string;
|
|
462
|
+
roleAdmin: string;
|
|
463
|
+
roleEditor: string;
|
|
464
|
+
roleNone: string;
|
|
465
|
+
};
|
|
466
|
+
};
|
|
394
467
|
theme: {
|
|
395
468
|
title: string;
|
|
396
469
|
activeLabel: string;
|
|
@@ -511,9 +584,12 @@ declare const dictionaries: {
|
|
|
511
584
|
posts: string;
|
|
512
585
|
media: string;
|
|
513
586
|
sites: string;
|
|
587
|
+
users: string;
|
|
514
588
|
viewSite: string;
|
|
515
589
|
signOut: string;
|
|
516
590
|
site: string;
|
|
591
|
+
openMenu: string;
|
|
592
|
+
closeMenu: string;
|
|
517
593
|
};
|
|
518
594
|
dashboard: {
|
|
519
595
|
title: string;
|
|
@@ -553,6 +629,20 @@ declare const dictionaries: {
|
|
|
553
629
|
tagsPlaceholder: string;
|
|
554
630
|
tagsHint: string;
|
|
555
631
|
status: string;
|
|
632
|
+
noLayout: string;
|
|
633
|
+
noLayoutHint: string;
|
|
634
|
+
formatStaticLabel: string;
|
|
635
|
+
static: {
|
|
636
|
+
pick: string;
|
|
637
|
+
pickHint: string;
|
|
638
|
+
currentBundle: string;
|
|
639
|
+
pendingBundle: string;
|
|
640
|
+
issuesTitle: string;
|
|
641
|
+
issuesHint: string;
|
|
642
|
+
emptyBundle: string;
|
|
643
|
+
noBundle: string;
|
|
644
|
+
previewHint: string;
|
|
645
|
+
};
|
|
556
646
|
saveChanges: string;
|
|
557
647
|
createPost: string;
|
|
558
648
|
delete: string;
|
|
@@ -624,6 +714,25 @@ declare const dictionaries: {
|
|
|
624
714
|
label: string;
|
|
625
715
|
};
|
|
626
716
|
};
|
|
717
|
+
users: {
|
|
718
|
+
list: {
|
|
719
|
+
title: string;
|
|
720
|
+
description: string;
|
|
721
|
+
columnEmail: string;
|
|
722
|
+
columnRole: string;
|
|
723
|
+
columnActions: string;
|
|
724
|
+
save: string;
|
|
725
|
+
saving: string;
|
|
726
|
+
saved: string;
|
|
727
|
+
cannotEditSelf: string;
|
|
728
|
+
empty: string;
|
|
729
|
+
loading: string;
|
|
730
|
+
error: string;
|
|
731
|
+
roleAdmin: string;
|
|
732
|
+
roleEditor: string;
|
|
733
|
+
roleNone: string;
|
|
734
|
+
};
|
|
735
|
+
};
|
|
627
736
|
theme: {
|
|
628
737
|
title: string;
|
|
629
738
|
activeLabel: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Config } from 'ampless';
|
|
2
2
|
import { AmplessOutputs, EffectiveSiteSettings, EffectiveThemeConfig, Ampless } from '@ampless/runtime';
|
|
3
|
-
import { L as Locale, D as Dictionary } from './i18n-
|
|
4
|
-
export { A as AdminLocaleStrings, g as getDictionary, r as resolveLocale, t as translate } from './i18n-
|
|
3
|
+
import { L as Locale, D as Dictionary } from './i18n-DzXXcIQQ.js';
|
|
4
|
+
export { A as AdminLocaleStrings, g as getDictionary, r as resolveLocale, t as translate } from './i18n-DzXXcIQQ.js';
|
|
5
5
|
import * as _aws_amplify_adapter_nextjs from '@aws-amplify/adapter-nextjs';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ADMIN_SITE_COOKIE,
|
|
3
|
-
createMedia
|
|
3
|
+
createMedia
|
|
4
|
+
} from "./chunk-QMVFRT62.js";
|
|
5
|
+
import {
|
|
4
6
|
getDictionary,
|
|
5
7
|
resolveLocale,
|
|
6
8
|
translate
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-OPQ3SAZJ.js";
|
|
8
10
|
|
|
9
11
|
// src/lib/admin-site.ts
|
|
10
12
|
import { cookies } from "next/headers";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Force-invalidate the Next.js fetch cache for a site's settings JSON.
|
|
3
|
+
* Used by the admin theme switcher: writes to KvStore propagate to S3
|
|
4
|
+
* via the trusted processor (~5-10s), and without this call the
|
|
5
|
+
* `revalidate: 60` on the public-side fetch would keep serving the old
|
|
6
|
+
* cached response for up to a minute after the rebuild.
|
|
7
|
+
*
|
|
8
|
+
* The cache tag matches the one used in `theme-active.ts` and
|
|
9
|
+
* `theme-config.ts` (in `@ampless/runtime`): `site-settings:{siteId}`.
|
|
10
|
+
*
|
|
11
|
+
* Uses `updateTag` (Next 16+) — the read-your-own-writes variant of
|
|
12
|
+
* the old `revalidateTag`, which is the right semantics inside a
|
|
13
|
+
* server action (this entire module is `'use server'`).
|
|
14
|
+
*/
|
|
15
|
+
declare function invalidateSiteSettingsCache(siteId: string): Promise<void>;
|
|
16
|
+
|
|
17
|
+
export { invalidateSiteSettingsCache };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Admin home / dashboard. Lists post counts. Marked client-side because
|
|
5
|
+
* it reads from the AppSync client directly (no server-rendered query
|
|
6
|
+
* yet — listed posts come from Amplify SDK at mount time).
|
|
7
|
+
*/
|
|
8
|
+
declare function AdminDashboard(): react_jsx_runtime.JSX.Element;
|
|
9
|
+
|
|
10
|
+
declare function PostsList(): react_jsx_runtime.JSX.Element;
|
|
11
|
+
|
|
12
|
+
declare function NewPostPage(): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
declare function EditPostPage({ params }: {
|
|
15
|
+
params: Promise<{
|
|
16
|
+
postId: string;
|
|
17
|
+
}>;
|
|
18
|
+
}): react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
declare function MediaPage(): react_jsx_runtime.JSX.Element;
|
|
21
|
+
|
|
22
|
+
declare function LoginPage(): react_jsx_runtime.JSX.Element;
|
|
23
|
+
|
|
24
|
+
export { AdminDashboard as A, EditPostPage as E, LoginPage as L, MediaPage as M, NewPostPage as N, PostsList as P };
|