@ampless/admin 0.2.0-alpha.10 → 0.2.0-alpha.12
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/{chunk-QMVFRT62.js → chunk-2ITWLRYF.js} +1 -5
- package/dist/chunk-4YEBIBFG.js +48 -0
- package/dist/chunk-5OIPGVGG.js +198 -0
- package/dist/chunk-7IJDOT2K.js +1197 -0
- package/dist/chunk-7IR4F7GA.js +6 -0
- package/dist/chunk-BFZODSUT.js +71 -0
- package/dist/chunk-BYLCQYEQ.js +21 -0
- package/dist/chunk-GDQC5X46.js +250 -0
- package/dist/chunk-QVUTNQZH.js +21 -0
- package/dist/chunk-TZWSXAHD.js +32 -0
- package/dist/chunk-XHWECTED.js +1125 -0
- package/dist/chunk-XXJDT6FF.js +335 -0
- package/dist/chunk-XZQRPXKN.js +41 -0
- package/dist/components/admin-dashboard.d.ts +10 -0
- package/dist/components/admin-dashboard.js +9 -0
- package/dist/components/edit-post-view.d.ts +9 -0
- package/dist/components/edit-post-view.js +14 -0
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.js +23 -25
- package/dist/components/login-view.d.ts +5 -0
- package/dist/components/login-view.js +9 -0
- package/dist/components/media-view.d.ts +5 -0
- package/dist/components/media-view.js +12 -0
- package/dist/components/new-post-view.d.ts +5 -0
- package/dist/components/new-post-view.js +14 -0
- package/dist/components/posts-list-view.d.ts +5 -0
- package/dist/components/posts-list-view.js +11 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +15 -9
- package/dist/metafile-esm.json +1 -1
- package/dist/pages/index.d.ts +6 -1
- package/dist/pages/index.js +28 -11
- package/package.json +1 -1
- package/dist/chunk-PAL62MXF.js +0 -3228
- package/dist/login-view-BKrSZLJu.d.ts +0 -24
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
readAdminSiteIdFromCookie
|
|
4
|
+
} from "./chunk-TZWSXAHD.js";
|
|
5
|
+
import {
|
|
6
|
+
useT
|
|
7
|
+
} from "./chunk-OFHKZNZS.js";
|
|
8
|
+
|
|
9
|
+
// src/components/posts-list-view.tsx
|
|
10
|
+
import { useEffect, useState } from "react";
|
|
11
|
+
import Link from "next/link";
|
|
12
|
+
import { listPosts } from "ampless";
|
|
13
|
+
import {
|
|
14
|
+
Button,
|
|
15
|
+
Table,
|
|
16
|
+
TableBody,
|
|
17
|
+
TableCell,
|
|
18
|
+
TableHead,
|
|
19
|
+
TableHeader,
|
|
20
|
+
TableRow
|
|
21
|
+
} from "@ampless/runtime/ui";
|
|
22
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
23
|
+
function PostsList() {
|
|
24
|
+
const t = useT();
|
|
25
|
+
const [posts, setPosts] = useState([]);
|
|
26
|
+
const [loading, setLoading] = useState(true);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const siteId = readAdminSiteIdFromCookie();
|
|
29
|
+
listPosts({ status: "all", siteId }).then(setPosts).finally(() => setLoading(false));
|
|
30
|
+
}, []);
|
|
31
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
32
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3 md:mb-8", children: [
|
|
33
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold md:text-3xl", children: t("posts.list.title") }),
|
|
34
|
+
/* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/admin/posts/new", children: t("posts.list.newButton") }) })
|
|
35
|
+
] }),
|
|
36
|
+
loading ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("common.loading") }) : posts.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border p-12 text-center", children: [
|
|
37
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("posts.list.empty") }),
|
|
38
|
+
/* @__PURE__ */ jsx(Button, { asChild: true, className: "mt-4", children: /* @__PURE__ */ jsx(Link, { href: "/admin/posts/new", children: t("posts.list.createFirst") }) })
|
|
39
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
40
|
+
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
41
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("posts.list.columnTitle") }),
|
|
42
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("posts.list.columnStatus") }),
|
|
43
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("posts.list.columnSlug") }),
|
|
44
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("posts.list.columnUpdated") })
|
|
45
|
+
] }) }),
|
|
46
|
+
/* @__PURE__ */ jsx(TableBody, { children: posts.map((post) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
47
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
48
|
+
Link,
|
|
49
|
+
{
|
|
50
|
+
href: `/admin/posts/${post.postId}`,
|
|
51
|
+
className: "font-medium hover:underline",
|
|
52
|
+
children: post.title
|
|
53
|
+
}
|
|
54
|
+
) }),
|
|
55
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
56
|
+
"span",
|
|
57
|
+
{
|
|
58
|
+
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",
|
|
59
|
+
children: t(`common.${post.status}`)
|
|
60
|
+
}
|
|
61
|
+
) }),
|
|
62
|
+
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-xs text-muted-foreground", children: post.slug }),
|
|
63
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-sm text-muted-foreground", children: post.publishedAt ? new Date(post.publishedAt).toLocaleDateString() : "\u2014" })
|
|
64
|
+
] }, post.postId)) })
|
|
65
|
+
] }) })
|
|
66
|
+
] });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
PostsList
|
|
71
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
MediaUploader
|
|
4
|
+
} from "./chunk-GDQC5X46.js";
|
|
5
|
+
import {
|
|
6
|
+
useT
|
|
7
|
+
} from "./chunk-OFHKZNZS.js";
|
|
8
|
+
|
|
9
|
+
// src/components/media-view.tsx
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
function MediaPage() {
|
|
12
|
+
const t = useT();
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
14
|
+
/* @__PURE__ */ jsx("h1", { className: "mb-6 text-2xl font-bold md:mb-8 md:text-3xl", children: t("media.title") }),
|
|
15
|
+
/* @__PURE__ */ jsx(MediaUploader, {})
|
|
16
|
+
] });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
MediaPage
|
|
21
|
+
};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
ImageUploadDialog,
|
|
4
|
+
getMediaProcessingDefaults
|
|
5
|
+
} from "./chunk-XXJDT6FF.js";
|
|
6
|
+
import {
|
|
7
|
+
publicMediaUrl
|
|
8
|
+
} from "./chunk-2ITWLRYF.js";
|
|
9
|
+
import {
|
|
10
|
+
useT
|
|
11
|
+
} from "./chunk-OFHKZNZS.js";
|
|
12
|
+
|
|
13
|
+
// src/components/media-uploader.tsx
|
|
14
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
15
|
+
import { uploadData, list, remove, isCancelError } from "aws-amplify/storage";
|
|
16
|
+
import { processImage } from "ampless/media";
|
|
17
|
+
import { Button, Input } from "@ampless/runtime/ui";
|
|
18
|
+
import { Trash2, Copy, Check, FileText, Code2 } from "lucide-react";
|
|
19
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
20
|
+
var IMAGE_EXT_RE = /\.(jpe?g|png|gif|webp|avif|svg|bmp|tiff?)$/i;
|
|
21
|
+
var STYLESHEET_EXT_RE = /\.css$/i;
|
|
22
|
+
var SCRIPT_EXT_RE = /\.m?js$/i;
|
|
23
|
+
function getExtension(path) {
|
|
24
|
+
const dot = path.lastIndexOf(".");
|
|
25
|
+
return dot >= 0 ? path.slice(dot + 1).toUpperCase() : "FILE";
|
|
26
|
+
}
|
|
27
|
+
function snippetFor(url, path) {
|
|
28
|
+
if (IMAGE_EXT_RE.test(path)) {
|
|
29
|
+
return `<img src="${url}" alt="" />`;
|
|
30
|
+
}
|
|
31
|
+
if (STYLESHEET_EXT_RE.test(path)) {
|
|
32
|
+
return `<link rel="stylesheet" href="${url}" />`;
|
|
33
|
+
}
|
|
34
|
+
if (SCRIPT_EXT_RE.test(path)) {
|
|
35
|
+
return `<script src="${url}"></script>`;
|
|
36
|
+
}
|
|
37
|
+
return url;
|
|
38
|
+
}
|
|
39
|
+
function sanitizeName(name) {
|
|
40
|
+
return name.replace(/[ -]/g, "").replace(/[\\/:*?"<>|]/g, "_").replace(/\s+/g, "_").replace(/^\.+/, "_").slice(0, 200) || "upload";
|
|
41
|
+
}
|
|
42
|
+
function MediaUploader() {
|
|
43
|
+
const t = useT();
|
|
44
|
+
const [items, setItems] = useState([]);
|
|
45
|
+
const [queue, setQueue] = useState([]);
|
|
46
|
+
const [uploading, setUploading] = useState(false);
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
const [copiedPath, setCopiedPath] = useState(null);
|
|
49
|
+
const uploadTaskRef = useRef(null);
|
|
50
|
+
const cancelTokenRef = useRef({ cancelled: false });
|
|
51
|
+
const refresh = useCallback(async () => {
|
|
52
|
+
try {
|
|
53
|
+
const result = await list({ path: "public/media/" });
|
|
54
|
+
setItems(
|
|
55
|
+
result.items.map((item) => ({
|
|
56
|
+
path: item.path,
|
|
57
|
+
url: publicMediaUrl(item.path)
|
|
58
|
+
}))
|
|
59
|
+
);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
62
|
+
}
|
|
63
|
+
}, []);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
refresh();
|
|
66
|
+
}, [refresh]);
|
|
67
|
+
function handleFiles(e) {
|
|
68
|
+
const files = Array.from(e.target.files ?? []);
|
|
69
|
+
e.target.value = "";
|
|
70
|
+
if (files.length === 0) return;
|
|
71
|
+
setError(null);
|
|
72
|
+
setQueue((prev) => [...prev, ...files]);
|
|
73
|
+
}
|
|
74
|
+
async function handleDialogConfirm(file, options) {
|
|
75
|
+
const token = { cancelled: false };
|
|
76
|
+
cancelTokenRef.current = token;
|
|
77
|
+
setUploading(true);
|
|
78
|
+
setError(null);
|
|
79
|
+
let advance = true;
|
|
80
|
+
try {
|
|
81
|
+
const processed = await processImage(file, options);
|
|
82
|
+
if (token.cancelled) {
|
|
83
|
+
advance = false;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const safeName = sanitizeName(processed.suggestedName);
|
|
87
|
+
const now = /* @__PURE__ */ new Date();
|
|
88
|
+
const yyyy = now.getFullYear();
|
|
89
|
+
const mm = String(now.getMonth() + 1).padStart(2, "0");
|
|
90
|
+
const path = `public/media/${yyyy}/${mm}/${Date.now()}-${safeName}`;
|
|
91
|
+
const task = uploadData({
|
|
92
|
+
path,
|
|
93
|
+
data: processed.blob,
|
|
94
|
+
options: { contentType: processed.mime }
|
|
95
|
+
});
|
|
96
|
+
uploadTaskRef.current = task;
|
|
97
|
+
await task.result;
|
|
98
|
+
await refresh();
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (isCancelError(err) || token.cancelled) {
|
|
101
|
+
advance = false;
|
|
102
|
+
} else {
|
|
103
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
104
|
+
}
|
|
105
|
+
} finally {
|
|
106
|
+
uploadTaskRef.current = null;
|
|
107
|
+
setUploading(false);
|
|
108
|
+
if (advance) {
|
|
109
|
+
setQueue((prev) => prev.slice(1));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function handleDialogSkip() {
|
|
114
|
+
if (uploading) return;
|
|
115
|
+
setQueue((prev) => prev.slice(1));
|
|
116
|
+
}
|
|
117
|
+
function handleDialogCancel() {
|
|
118
|
+
cancelTokenRef.current.cancelled = true;
|
|
119
|
+
uploadTaskRef.current?.cancel();
|
|
120
|
+
setQueue([]);
|
|
121
|
+
}
|
|
122
|
+
async function handleDelete(path) {
|
|
123
|
+
if (!confirm(t("media.deleteConfirm"))) return;
|
|
124
|
+
try {
|
|
125
|
+
await remove({ path });
|
|
126
|
+
await refresh();
|
|
127
|
+
} catch (err) {
|
|
128
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function handleCopy(item, mode) {
|
|
132
|
+
const text = mode === "url" ? item.url : snippetFor(item.url, item.path);
|
|
133
|
+
await navigator.clipboard.writeText(text);
|
|
134
|
+
const key = `${item.path}:${mode}`;
|
|
135
|
+
setCopiedPath(key);
|
|
136
|
+
setTimeout(() => setCopiedPath((p) => p === key ? null : p), 1500);
|
|
137
|
+
}
|
|
138
|
+
const currentFile = queue[0] ?? null;
|
|
139
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
140
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-md border p-4", children: [
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
Input,
|
|
143
|
+
{
|
|
144
|
+
type: "file",
|
|
145
|
+
multiple: true,
|
|
146
|
+
onChange: handleFiles,
|
|
147
|
+
disabled: uploading
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
uploading && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t("media.uploading") }),
|
|
151
|
+
!uploading && queue.length > 0 && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t("media.queued", { count: queue.length }) })
|
|
152
|
+
] }),
|
|
153
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
154
|
+
/* @__PURE__ */ jsx(
|
|
155
|
+
ImageUploadDialog,
|
|
156
|
+
{
|
|
157
|
+
file: currentFile,
|
|
158
|
+
remaining: queue.length,
|
|
159
|
+
busy: uploading,
|
|
160
|
+
defaults: getMediaProcessingDefaults(),
|
|
161
|
+
onConfirm: handleDialogConfirm,
|
|
162
|
+
onSkip: handleDialogSkip,
|
|
163
|
+
onCancel: handleDialogCancel
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4", children: items.map((item) => {
|
|
167
|
+
const isImage = IMAGE_EXT_RE.test(item.path);
|
|
168
|
+
const isStylesheet = STYLESHEET_EXT_RE.test(item.path);
|
|
169
|
+
const isScript = SCRIPT_EXT_RE.test(item.path);
|
|
170
|
+
const filename = item.path.split("/").pop() ?? "";
|
|
171
|
+
const ext = getExtension(item.path);
|
|
172
|
+
const tagSnippet = snippetFor(item.url, item.path);
|
|
173
|
+
const tagDiffersFromUrl = tagSnippet !== item.url;
|
|
174
|
+
const urlCopied = copiedPath === `${item.path}:url`;
|
|
175
|
+
const tagCopied = copiedPath === `${item.path}:tag`;
|
|
176
|
+
return /* @__PURE__ */ jsxs(
|
|
177
|
+
"div",
|
|
178
|
+
{
|
|
179
|
+
className: "group relative overflow-hidden rounded-md border bg-[var(--card)]",
|
|
180
|
+
children: [
|
|
181
|
+
isImage ? (
|
|
182
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
183
|
+
/* @__PURE__ */ jsx(
|
|
184
|
+
"img",
|
|
185
|
+
{
|
|
186
|
+
src: item.url,
|
|
187
|
+
alt: item.path,
|
|
188
|
+
className: "aspect-square w-full object-cover"
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex aspect-square w-full flex-col items-center justify-center gap-2 bg-muted text-muted-foreground", children: [
|
|
192
|
+
isStylesheet || isScript ? /* @__PURE__ */ jsx(Code2, { className: "h-8 w-8" }) : /* @__PURE__ */ jsx(FileText, { className: "h-8 w-8" }),
|
|
193
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-semibold", children: [
|
|
194
|
+
".",
|
|
195
|
+
ext.toLowerCase()
|
|
196
|
+
] })
|
|
197
|
+
] }),
|
|
198
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t px-2 py-1 text-xs", children: [
|
|
199
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", title: filename, children: filename }),
|
|
200
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
Button,
|
|
203
|
+
{
|
|
204
|
+
type: "button",
|
|
205
|
+
variant: "ghost",
|
|
206
|
+
size: "icon",
|
|
207
|
+
className: "h-6 w-6",
|
|
208
|
+
onClick: () => handleCopy(item, "url"),
|
|
209
|
+
title: t("media.copyUrl"),
|
|
210
|
+
children: urlCopied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3" })
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
tagDiffersFromUrl && /* @__PURE__ */ jsx(
|
|
214
|
+
Button,
|
|
215
|
+
{
|
|
216
|
+
type: "button",
|
|
217
|
+
variant: "ghost",
|
|
218
|
+
size: "icon",
|
|
219
|
+
className: "h-6 w-6",
|
|
220
|
+
onClick: () => handleCopy(item, "tag"),
|
|
221
|
+
title: t("media.copyTag"),
|
|
222
|
+
children: tagCopied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Code2, { className: "h-3 w-3" })
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
/* @__PURE__ */ jsx(
|
|
226
|
+
Button,
|
|
227
|
+
{
|
|
228
|
+
type: "button",
|
|
229
|
+
variant: "ghost",
|
|
230
|
+
size: "icon",
|
|
231
|
+
className: "h-6 w-6",
|
|
232
|
+
onClick: () => handleDelete(item.path),
|
|
233
|
+
title: t("media.delete"),
|
|
234
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3" })
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
] })
|
|
238
|
+
] })
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
item.path
|
|
242
|
+
);
|
|
243
|
+
}) }),
|
|
244
|
+
items.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-center text-sm text-muted-foreground", children: t("media.empty") })
|
|
245
|
+
] });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export {
|
|
249
|
+
MediaUploader
|
|
250
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
PostForm
|
|
4
|
+
} from "./chunk-7IJDOT2K.js";
|
|
5
|
+
import {
|
|
6
|
+
useT
|
|
7
|
+
} from "./chunk-OFHKZNZS.js";
|
|
8
|
+
|
|
9
|
+
// src/components/new-post-view.tsx
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
function NewPostPage() {
|
|
12
|
+
const t = useT();
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl p-4 md:p-8", children: [
|
|
14
|
+
/* @__PURE__ */ jsx("h1", { className: "mb-6 text-2xl font-bold md:mb-8 md:text-3xl", children: t("posts.form.newTitle") }),
|
|
15
|
+
/* @__PURE__ */ jsx(PostForm, {})
|
|
16
|
+
] });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
NewPostPage
|
|
21
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
ADMIN_SITE_COOKIE
|
|
4
|
+
} from "./chunk-7IR4F7GA.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/admin-site-client.ts
|
|
7
|
+
import { DEFAULT_SITE_ID, isMultiSite } from "ampless";
|
|
8
|
+
var cmsConfig = null;
|
|
9
|
+
function setAdminCmsConfig(config) {
|
|
10
|
+
cmsConfig = config;
|
|
11
|
+
}
|
|
12
|
+
function readAdminSiteIdFromCookie() {
|
|
13
|
+
if (!cmsConfig) return DEFAULT_SITE_ID;
|
|
14
|
+
if (!isMultiSite(cmsConfig)) return DEFAULT_SITE_ID;
|
|
15
|
+
const sites = cmsConfig.sites ?? {};
|
|
16
|
+
if (typeof document !== "undefined") {
|
|
17
|
+
const match = document.cookie.match(
|
|
18
|
+
new RegExp(`(?:^|;\\s*)${ADMIN_SITE_COOKIE}=([^;]+)`)
|
|
19
|
+
);
|
|
20
|
+
if (match) {
|
|
21
|
+
const v = decodeURIComponent(match[1]);
|
|
22
|
+
if (sites[v]) return v;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const first = Object.keys(sites)[0];
|
|
26
|
+
return first ?? DEFAULT_SITE_ID;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
setAdminCmsConfig,
|
|
31
|
+
readAdminSiteIdFromCookie
|
|
32
|
+
};
|