@commercetools-demo/puck-content-manager 0.5.2 → 0.6.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/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
@@ -39,18 +29,8 @@ module.exports = __toCommonJS(index_exports);
39
29
  // src/ContentManager.tsx
40
30
  var import_react2 = require("react");
41
31
  var import_puck_api = require("@commercetools-demo/puck-api");
42
- var import_data_table = __toESM(require("@commercetools-uikit/data-table"));
43
- var import_primary_button = __toESM(require("@commercetools-uikit/primary-button"));
44
- var import_secondary_button = __toESM(require("@commercetools-uikit/secondary-button"));
45
- var import_flat_button = __toESM(require("@commercetools-uikit/flat-button"));
46
- var import_card = __toESM(require("@commercetools-uikit/card"));
47
- var import_spacings = __toESM(require("@commercetools-uikit/spacings"));
48
- var import_text = __toESM(require("@commercetools-uikit/text"));
49
- var import_loading_spinner = __toESM(require("@commercetools-uikit/loading-spinner"));
50
- var import_text_input = __toESM(require("@commercetools-uikit/text-input"));
51
- var import_label = __toESM(require("@commercetools-uikit/label"));
52
- var import_icons = require("@commercetools-uikit/icons");
53
- var import_stamp = __toESM(require("@commercetools-uikit/stamp"));
32
+ var import_nimbus2 = require("@commercetools/nimbus");
33
+ var import_nimbus_icons = require("@commercetools/nimbus-icons");
54
34
 
55
35
  // src/EnsureIntlProvider.tsx
56
36
  var import_react = require("react");
@@ -76,25 +56,28 @@ var EnsureIntlProvider = ({ children }) => {
76
56
  );
77
57
  };
78
58
 
79
- // src/ContentManager.tsx
59
+ // src/EnsureNimbusProvider.tsx
60
+ var import_nimbus = require("@commercetools/nimbus");
80
61
  var import_jsx_runtime2 = require("react/jsx-runtime");
81
- var columns = [
82
- { key: "name", label: "Name" },
83
- { key: "contentType", label: "Content Type" },
84
- { key: "status", label: "Status" },
85
- { key: "updatedAt", label: "Updated" },
86
- { key: "actions", label: "Actions", shouldIgnoreRowClick: true }
87
- ];
62
+ var EnsureNimbusProvider = ({
63
+ locale = "en",
64
+ children
65
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus.NimbusProvider, { locale, children });
66
+
67
+ // src/ContentManager.tsx
68
+ var import_jsx_runtime3 = require("react/jsx-runtime");
88
69
  var ContentList = ({ defaultContentType, onEdit }) => {
89
- const { contents, loading, error, fetchContents, createContent, deleteContent, refresh } = (0, import_puck_api.usePuckContents)(defaultContentType);
90
- const [filterType, setFilterType] = (0, import_react2.useState)(defaultContentType ?? "");
70
+ const { contents, loading, error, createContent, deleteContent } = (0, import_puck_api.usePuckContents)(defaultContentType);
71
+ const { templates } = (0, import_puck_api.usePuckTemplates)("content");
72
+ const [search, setSearch] = (0, import_react2.useState)("");
91
73
  const [showCreate, setShowCreate] = (0, import_react2.useState)(false);
92
74
  const [createName, setCreateName] = (0, import_react2.useState)("");
93
75
  const [createType, setCreateType] = (0, import_react2.useState)(defaultContentType ?? "");
76
+ const [templateKey, setTemplateKey] = (0, import_react2.useState)("");
94
77
  const [createError, setCreateError] = (0, import_react2.useState)(null);
95
78
  const [creating, setCreating] = (0, import_react2.useState)(false);
96
79
  const [deleting, setDeleting] = (0, import_react2.useState)(null);
97
- const handleFilter = () => void fetchContents(filterType || void 0);
80
+ const [pendingDelete, setPendingDelete] = (0, import_react2.useState)(null);
98
81
  const handleCreate = async () => {
99
82
  setCreateError(null);
100
83
  if (!createName.trim()) {
@@ -107,168 +90,231 @@ var ContentList = ({ defaultContentType, onEdit }) => {
107
90
  }
108
91
  setCreating(true);
109
92
  try {
93
+ const template = templateKey ? templates.find((t) => t.key === templateKey) : void 0;
110
94
  const input = {
111
95
  name: createName.trim(),
112
96
  contentType: createType.trim(),
113
- data: { content: [], root: { props: {} } }
97
+ data: template?.value.puckData ?? { content: [], root: { props: {} } }
114
98
  };
115
99
  await createContent(input);
116
100
  setShowCreate(false);
117
101
  setCreateName("");
118
102
  setCreateType(defaultContentType ?? "");
103
+ setTemplateKey("");
119
104
  } catch (err) {
120
105
  setCreateError(err.message);
121
106
  } finally {
122
107
  setCreating(false);
123
108
  }
124
109
  };
125
- const handleDelete = async (key) => {
126
- if (!confirm("Delete this content item and all its versions?")) return;
127
- setDeleting(key);
110
+ const handleDelete = async (item) => {
111
+ setDeleting(item.key);
128
112
  try {
129
- await deleteContent(key);
113
+ await deleteContent(item.key);
114
+ setPendingDelete(null);
130
115
  } finally {
131
116
  setDeleting(null);
132
117
  }
133
118
  };
134
- const rows = contents.map((c) => ({ ...c, id: c.key }));
135
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "32px 24px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Stack, { scale: "l", children: [
136
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Inline, { justifyContent: "space-between", alignItems: "center", children: [
137
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Headline, { as: "h1", children: "Content Items" }),
138
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
139
- import_primary_button.default,
119
+ const term = search.trim().toLowerCase();
120
+ const filteredContents = term ? contents.filter(
121
+ (c) => c.value.name.toLowerCase().includes(term) || c.value.contentType.toLowerCase().includes(term)
122
+ ) : contents;
123
+ const rows = filteredContents.map((c) => ({ ...c, id: c.key }));
124
+ const columns = [
125
+ {
126
+ id: "name",
127
+ header: "Name",
128
+ accessor: (row) => row.value.name,
129
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { fontWeight: "bold", children: row.value.name })
130
+ },
131
+ {
132
+ id: "contentType",
133
+ header: "Content Type",
134
+ accessor: (row) => row.value.contentType,
135
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
136
+ "code",
140
137
  {
141
- label: "New Content",
142
- iconLeft: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.PlusThinIcon, {}),
143
- onClick: () => setShowCreate((v) => !v)
138
+ style: {
139
+ background: "#f4f4f4",
140
+ padding: "2px 6px",
141
+ borderRadius: "4px",
142
+ fontSize: "11px",
143
+ fontFamily: "monospace"
144
+ },
145
+ children: row.value.contentType
144
146
  }
145
147
  )
146
- ] }),
147
- showCreate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_card.default, { insetScale: "l", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Stack, { scale: "m", children: [
148
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Subheadline, { as: "h4", isBold: true, children: "Create Content Item" }),
149
- createError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Body, { tone: "negative", children: createError }),
150
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Inline, { scale: "m", children: [
151
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Stack, { scale: "xs", children: [
152
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_label.default, { htmlFor: "create-name", children: "Name" }),
153
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
154
- import_text_input.default,
155
- {
156
- id: "create-name",
157
- value: createName,
158
- onChange: (e) => setCreateName(e.target.value),
159
- placeholder: "e.g. Homepage Hero"
160
- }
161
- )
162
- ] }) }),
163
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Stack, { scale: "xs", children: [
164
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_label.default, { htmlFor: "create-type", children: "Content Type" }),
165
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
166
- import_text_input.default,
167
- {
168
- id: "create-type",
169
- value: createType,
170
- onChange: (e) => setCreateType(e.target.value),
171
- placeholder: "e.g. hero, banner"
172
- }
173
- )
174
- ] }) })
175
- ] }),
176
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Inline, { scale: "s", children: [
177
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
178
- import_primary_button.default,
148
+ },
149
+ {
150
+ id: "status",
151
+ header: "Status",
152
+ accessor: () => "",
153
+ isSortable: false,
154
+ render: ({ row }) => {
155
+ const hasDraft = !!row.states.draft;
156
+ const hasPublished = !!row.states.published;
157
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "100", wrap: "wrap", children: [
158
+ hasDraft && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Badge, { colorPalette: "warning", size: "xs", children: "Draft" }),
159
+ hasPublished && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Badge, { colorPalette: "positive", size: "xs", children: "Published" }),
160
+ !hasDraft && !hasPublished && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Badge, { colorPalette: "neutral", size: "xs", children: "No state" })
161
+ ] });
162
+ }
163
+ },
164
+ {
165
+ id: "updatedAt",
166
+ header: "Updated",
167
+ accessor: (row) => row.value.updatedAt,
168
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { color: "neutral.11", children: new Date(row.value.updatedAt).toLocaleDateString() })
169
+ },
170
+ {
171
+ id: "actions",
172
+ header: "Actions",
173
+ accessor: () => "",
174
+ isSortable: false,
175
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "100", alignItems: "center", children: [
176
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
177
+ import_nimbus2.IconButton,
179
178
  {
180
- label: creating ? "Creating\u2026" : "Create",
181
- onClick: () => void handleCreate(),
182
- isDisabled: creating
179
+ "aria-label": `Edit ${row.value.name}`,
180
+ variant: "ghost",
181
+ size: "xs",
182
+ onPress: () => onEdit(row),
183
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus_icons.Edit, {})
183
184
  }
184
185
  ),
185
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_secondary_button.default, { label: "Cancel", onClick: () => setShowCreate(false) })
186
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
187
+ import_nimbus2.IconButton,
188
+ {
189
+ "aria-label": `Delete ${row.value.name}`,
190
+ variant: "ghost",
191
+ colorPalette: "critical",
192
+ size: "xs",
193
+ isDisabled: deleting === row.key,
194
+ onPress: () => setPendingDelete(row),
195
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus_icons.Delete, {})
196
+ }
197
+ )
186
198
  ] })
187
- ] }) }),
188
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_spacings.default.Inline, { scale: "s", alignItems: "center", children: [
189
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1, maxWidth: "280px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
190
- import_text_input.default,
199
+ }
200
+ ];
201
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "32px 24px" }, children: [
202
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "column", gap: "600", children: [
203
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [
204
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { as: "h1", fontSize: "2xl", fontWeight: "700", children: "Content Items" }),
205
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Button, { variant: "solid", onPress: () => setShowCreate((v) => !v), children: [
206
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Icon, { as: import_nimbus_icons.Add }),
207
+ " New Content"
208
+ ] })
209
+ ] }),
210
+ showCreate && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Card.Root, { variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Card.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "column", gap: "400", children: [
211
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Create Content Item" }),
212
+ createError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { color: "critical.11", children: createError }),
213
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "400", children: [
214
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.FormField.Root, { children: [
215
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Label, { children: "Name" }),
216
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
217
+ import_nimbus2.TextInput,
218
+ {
219
+ value: createName,
220
+ onChange: (v) => setCreateName(v),
221
+ placeholder: "e.g. Homepage Hero"
222
+ }
223
+ ) })
224
+ ] }) }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.FormField.Root, { children: [
226
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Label, { children: "Content Type" }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
228
+ import_nimbus2.TextInput,
229
+ {
230
+ value: createType,
231
+ onChange: (v) => setCreateType(v),
232
+ placeholder: "e.g. hero, banner"
233
+ }
234
+ ) })
235
+ ] }) })
236
+ ] }),
237
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.FormField.Root, { children: [
238
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Label, { children: "Template" }),
239
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
240
+ import_nimbus2.Select.Root,
241
+ {
242
+ "aria-label": "Template",
243
+ selectedKey: templateKey || "empty",
244
+ onSelectionChange: (key) => setTemplateKey(key == null || key === "empty" ? "" : String(key)),
245
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Select.Options, { children: [
246
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Select.Option, { id: "empty", children: "Empty" }),
247
+ templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Select.Option, { id: t.key, children: t.value.name }, t.key))
248
+ ] })
249
+ }
250
+ ) })
251
+ ] }),
252
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "200", children: [
253
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Button, { variant: "solid", onPress: () => void handleCreate(), isDisabled: creating, children: creating ? "Creating\u2026" : "Create" }),
254
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Button, { variant: "outline", onPress: () => setShowCreate(false), children: "Cancel" })
255
+ ] })
256
+ ] }) }) }),
257
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { maxWidth: 360 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
258
+ import_nimbus2.TextInput,
191
259
  {
192
- value: filterType,
193
- onChange: (e) => setFilterType(e.target.value),
194
- placeholder: "Filter by content type\u2026"
260
+ "aria-label": "Search content",
261
+ placeholder: "Search by name or content type\u2026",
262
+ value: search,
263
+ onChange: (v) => setSearch(v),
264
+ width: "100%",
265
+ trailingElement: search !== "" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
266
+ import_nimbus2.IconButton,
267
+ {
268
+ "aria-label": "Clear search",
269
+ variant: "ghost",
270
+ colorPalette: "neutral",
271
+ size: "2xs",
272
+ onPress: () => setSearch(""),
273
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus_icons.Close, {})
274
+ }
275
+ ) : void 0
195
276
  }
196
277
  ) }),
197
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
198
- import_secondary_button.default,
199
- {
200
- label: "Filter",
201
- iconLeft: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.SearchIcon, {}),
202
- onClick: handleFilter
203
- }
204
- ),
205
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
206
- import_flat_button.default,
207
- {
208
- label: "Clear",
209
- onClick: () => {
210
- setFilterType("");
211
- void fetchContents(void 0);
212
- }
213
- }
214
- ),
215
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_flat_button.default, { label: "Refresh", onClick: () => void refresh() })
278
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { color: "critical.11", children: error }),
279
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.LoadingSpinner, {}) }) : contents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Stack, { direction: "column", gap: "400", alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { color: "neutral.11", children: "No content items found." }) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.DataTable, { columns, rows, "aria-label": "Content items" })
216
280
  ] }),
217
- error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Body, { tone: "negative", children: error }),
218
- loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_loading_spinner.default, {}) }) : contents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_spacings.default.Stack, { scale: "m", alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Body, { tone: "secondary", children: "No content items found." }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
219
- import_data_table.default,
281
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
282
+ import_nimbus2.Dialog.Root,
220
283
  {
221
- columns,
222
- rows,
223
- itemRenderer: (row, column) => {
224
- switch (column.key) {
225
- case "name":
226
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Body, { fontWeight: "bold", children: row.value.name });
227
- case "contentType":
228
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
229
- "code",
230
- {
231
- style: {
232
- background: "var(--color-neutral-95)",
233
- padding: "2px 6px",
234
- borderRadius: "var(--border-radius-4)",
235
- fontSize: "var(--font-size-10)",
236
- fontFamily: "monospace"
237
- },
238
- children: row.value.contentType
239
- }
240
- );
241
- case "status": {
242
- const hasDraft = !!row.states.draft;
243
- const hasPublished = !!row.states.published;
244
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { display: "inline-flex", gap: "4px", flexWrap: "wrap" }, children: [
245
- hasDraft && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_stamp.default, { tone: "warning", label: "Draft", isCondensed: true }),
246
- hasPublished && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_stamp.default, { tone: "positive", label: "Published", isCondensed: true }),
247
- !hasDraft && !hasPublished && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_stamp.default, { tone: "secondary", label: "No state", isCondensed: true })
248
- ] });
249
- }
250
- case "updatedAt":
251
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_text.default.Body, { tone: "secondary", children: new Date(row.value.updatedAt).toLocaleDateString() });
252
- case "actions":
253
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
254
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primary_button.default, { label: "Edit", size: "20", onClick: () => onEdit(row) }),
255
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
256
- import_flat_button.default,
257
- {
258
- tone: "critical",
259
- label: deleting === row.key ? "\u2026" : "Delete",
260
- isDisabled: deleting === row.key,
261
- onClick: () => void handleDelete(row.key)
262
- }
263
- )
264
- ] });
265
- default:
266
- return null;
267
- }
268
- }
284
+ isOpen: pendingDelete !== null,
285
+ onOpenChange: (open) => {
286
+ if (!open) setPendingDelete(null);
287
+ },
288
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Dialog.Content, { children: [
289
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Dialog.Header, { children: [
290
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Dialog.Title, { children: "Delete content item?" }),
291
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Dialog.CloseTrigger, {})
292
+ ] }),
293
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Text, { children: [
294
+ "Are you sure you want to delete",
295
+ " ",
296
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Text, { as: "span", fontWeight: "700", children: pendingDelete?.value.name }),
297
+ " ",
298
+ "and all its versions? This cannot be undone."
299
+ ] }) }),
300
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_nimbus2.Dialog.Footer, { children: [
301
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_nimbus2.Button, { slot: "close", variant: "outline", isDisabled: deleting !== null, children: "Cancel" }),
302
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
303
+ import_nimbus2.Button,
304
+ {
305
+ colorPalette: "critical",
306
+ isDisabled: deleting !== null,
307
+ onPress: () => {
308
+ if (pendingDelete) void handleDelete(pendingDelete);
309
+ },
310
+ children: deleting !== null ? "Deleting\u2026" : "Delete"
311
+ }
312
+ )
313
+ ] })
314
+ ] })
269
315
  }
270
316
  )
271
- ] }) });
317
+ ] });
272
318
  };
273
319
  var ContentManagerList = ({
274
320
  baseURL,
@@ -277,16 +323,16 @@ var ContentManagerList = ({
277
323
  jwtToken,
278
324
  defaultContentType,
279
325
  onEdit
280
- }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
326
+ }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EnsureNimbusProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
281
327
  import_puck_api.PuckApiProvider,
282
328
  {
283
329
  baseURL,
284
330
  projectKey,
285
331
  businessUnitKey,
286
332
  jwtToken,
287
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ContentList, { defaultContentType, onEdit })
333
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ContentList, { defaultContentType, onEdit })
288
334
  }
289
- ) });
335
+ ) }) });
290
336
 
291
337
  // src/ContentEditor.tsx
292
338
  var import_react3 = require("react");
@@ -295,10 +341,8 @@ var import_puck2 = require("@measured/puck/puck.css");
295
341
  var import_puck_api2 = require("@commercetools-demo/puck-api");
296
342
  var import_puck_editor = require("@commercetools-demo/puck-editor");
297
343
  var import_puck_version_history = require("@commercetools-demo/puck-version-history");
298
- var import_loading_spinner2 = __toESM(require("@commercetools-uikit/loading-spinner"));
299
- var import_text2 = __toESM(require("@commercetools-uikit/text"));
300
- var import_spacings2 = __toESM(require("@commercetools-uikit/spacings"));
301
- var import_jsx_runtime3 = require("react/jsx-runtime");
344
+ var import_nimbus3 = require("@commercetools/nimbus");
345
+ var import_jsx_runtime4 = require("react/jsx-runtime");
302
346
  var ContentEditorInner = ({
303
347
  contentKey,
304
348
  config,
@@ -318,9 +362,12 @@ var ContentEditorInner = ({
318
362
  revertToPublished,
319
363
  loadVersions
320
364
  } = (0, import_puck_api2.usePuckContent)(contentKey);
365
+ const { createTemplate } = (0, import_puck_api2.usePuckTemplates)("content");
321
366
  const latestDataRef = (0, import_react3.useRef)(null);
322
- const [hasUnsavedChanges, setHasUnsavedChanges] = (0, import_react3.useState)(false);
323
367
  const [isApplyingVersion, setIsApplyingVersion] = (0, import_react3.useState)(false);
368
+ const [reloadNonce, setReloadNonce] = (0, import_react3.useState)(0);
369
+ const [templateDialogOpen, setTemplateDialogOpen] = (0, import_react3.useState)(false);
370
+ const [templateSaving, setTemplateSaving] = (0, import_react3.useState)(false);
324
371
  const currentData = states.draft?.data ?? content?.data ?? {
325
372
  content: [],
326
373
  root: { props: {} }
@@ -336,39 +383,44 @@ var ContentEditorInner = ({
336
383
  );
337
384
  const isPreviewingRef = (0, import_react3.useRef)(false);
338
385
  isPreviewingRef.current = versionHistory.isPreviewingHistory;
339
- const handleChange = (0, import_react3.useCallback)((data) => {
340
- if (isPreviewingRef.current) return;
341
- latestDataRef.current = data;
342
- setHasUnsavedChanges(true);
343
- }, []);
386
+ const canvasKey = `${contentKey}:${versionHistory.selectedVersionId ?? "current"}:${reloadNonce}`;
387
+ const { isDirty: hasUnsavedChanges, markChange, markSaved } = (0, import_puck_editor.useDirtyState)(canvasKey);
388
+ const handleChange = (0, import_react3.useCallback)(
389
+ (data) => {
390
+ if (isPreviewingRef.current) return;
391
+ latestDataRef.current = data;
392
+ markChange(data);
393
+ },
394
+ [markChange]
395
+ );
344
396
  const handleSave = (0, import_react3.useCallback)(async () => {
345
397
  const data = latestDataRef.current;
346
398
  if (!data) return;
347
399
  try {
348
400
  await saveDraft(data);
349
- setHasUnsavedChanges(false);
401
+ markSaved(data);
350
402
  onSave?.(data);
351
403
  } catch (err) {
352
404
  onError?.(err);
353
405
  }
354
- }, [saveDraft, onSave, onError]);
406
+ }, [saveDraft, onSave, onError, markSaved]);
355
407
  const handlePublish = (0, import_react3.useCallback)(
356
408
  async (data) => {
357
409
  try {
358
410
  await saveDraft(data);
359
- setHasUnsavedChanges(false);
411
+ markSaved(data);
360
412
  await publish(false);
361
413
  onPublish?.(data);
362
414
  } catch (err) {
363
415
  onError?.(err);
364
416
  }
365
417
  },
366
- [saveDraft, publish, onPublish, onError]
418
+ [saveDraft, publish, onPublish, onError, markSaved]
367
419
  );
368
420
  const handleRevert = (0, import_react3.useCallback)(async () => {
369
421
  try {
370
422
  await revertToPublished();
371
- setHasUnsavedChanges(false);
423
+ setReloadNonce((n) => n + 1);
372
424
  } catch (err) {
373
425
  onError?.(err);
374
426
  }
@@ -379,7 +431,7 @@ var ContentEditorInner = ({
379
431
  setIsApplyingVersion(true);
380
432
  try {
381
433
  await saveDraft(versionData);
382
- setHasUnsavedChanges(false);
434
+ markSaved(versionData);
383
435
  onSave?.(versionData);
384
436
  versionHistory.clearSelection();
385
437
  } catch (err) {
@@ -387,7 +439,7 @@ var ContentEditorInner = ({
387
439
  } finally {
388
440
  setIsApplyingVersion(false);
389
441
  }
390
- }, [versionHistory, saveDraft, onSave, onError]);
442
+ }, [versionHistory, saveDraft, onSave, onError, markSaved]);
391
443
  const contentConfig = (0, import_react3.useMemo)(() => {
392
444
  const otherRootFields = Object.fromEntries(
393
445
  Object.entries(config.root?.fields ?? {}).filter(([k]) => k !== "title")
@@ -409,22 +461,38 @@ var ContentEditorInner = ({
409
461
  }
410
462
  };
411
463
  }, [config]);
464
+ const handleCreateTemplate = (0, import_react3.useCallback)(
465
+ async (name, withoutData) => {
466
+ const source = latestDataRef.current ?? currentData;
467
+ const puckData = withoutData ? (0, import_puck_editor.stripPuckDataToTemplate)(source, contentConfig) : source;
468
+ setTemplateSaving(true);
469
+ try {
470
+ await createTemplate({ name, kind: "content", puckData });
471
+ setTemplateDialogOpen(false);
472
+ } catch (err) {
473
+ onError?.(err);
474
+ } finally {
475
+ setTemplateSaving(false);
476
+ }
477
+ },
478
+ [createTemplate, currentData, contentConfig, onError]
479
+ );
412
480
  if (loading) {
413
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_spacings2.default.Stack, { scale: "m", alignItems: "center", children: [
414
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_loading_spinner2.default, {}),
415
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_text2.default.Body, { tone: "secondary", children: "Loading editor\u2026" })
481
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_nimbus3.Stack, { direction: "column", gap: "400", alignItems: "center", children: [
482
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_nimbus3.LoadingSpinner, {}),
483
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_nimbus3.Text, { color: "neutral.11", children: "Loading editor\u2026" })
416
484
  ] }) });
417
485
  }
418
486
  if (error) {
419
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_text2.default.Body, { tone: "negative", children: [
420
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "Error loading content:" }),
487
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_nimbus3.Text, { color: "critical.11", children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Error loading content:" }),
421
489
  " ",
422
490
  error
423
491
  ] }) });
424
492
  }
425
493
  const activeData = versionHistory.previewData ?? currentData;
426
494
  const toolbarStates = states;
427
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
495
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
428
496
  import_puck_version_history.VersionHistoryProvider,
429
497
  {
430
498
  diff,
@@ -437,44 +505,70 @@ var ContentEditorInner = ({
437
505
  onApply: () => void handleApplyVersion(),
438
506
  onDiscard: versionHistory.clearSelection,
439
507
  onLoadVersions: versionHistory.openPanel,
440
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_puck_editor.ComponentSearchProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
441
- import_puck.Puck,
442
- {
443
- config: contentConfig,
444
- data: activeData,
445
- onChange: handleChange,
446
- onPublish: handlePublish,
447
- overrides: {
448
- headerActions: () => versionHistory.isPreviewingHistory ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_spacings2.default.Inline, { scale: "s", alignItems: "center", children: [
449
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
450
- import_puck_version_history.VersionPreviewBanner,
508
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_puck_editor.ComponentSearchProvider, { children: [
509
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
510
+ import_puck.Puck,
511
+ {
512
+ config: contentConfig,
513
+ data: activeData,
514
+ onChange: handleChange,
515
+ onPublish: handlePublish,
516
+ overrides: {
517
+ fieldTypes: import_puck_editor.nimbusFieldTypes,
518
+ header: () => versionHistory.isPreviewingHistory ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
519
+ import_nimbus3.Stack,
520
+ {
521
+ gridArea: "header",
522
+ direction: "row",
523
+ gap: "200",
524
+ alignItems: "center",
525
+ justifyContent: "flex-end",
526
+ padding: "200",
527
+ children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
529
+ import_puck_version_history.VersionPreviewBanner,
530
+ {
531
+ timestamp: versionHistory.selectedVersion.timestamp,
532
+ onApply: () => void handleApplyVersion(),
533
+ onDiscard: versionHistory.clearSelection,
534
+ isApplying: isApplyingVersion
535
+ }
536
+ ),
537
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_version_history.VersionHistoryButton, { disabled: isApplyingVersion })
538
+ ]
539
+ }
540
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
541
+ import_puck_editor.EditorToolbar,
451
542
  {
452
- timestamp: versionHistory.selectedVersion.timestamp,
453
- onApply: () => void handleApplyVersion(),
454
- onDiscard: versionHistory.clearSelection,
455
- isApplying: isApplyingVersion
543
+ title: content?.name ?? "Content",
544
+ saving,
545
+ isDirty: hasUnsavedChanges,
546
+ states: toolbarStates,
547
+ onSave: () => void handleSave(),
548
+ onPublish: () => void handlePublish(activeData),
549
+ onRevert: () => void handleRevert(),
550
+ onCreateTemplate: () => setTemplateDialogOpen(true),
551
+ createTemplateLabel: "Create a template from this content",
552
+ showPublishButton: true
456
553
  }
457
554
  ),
458
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_puck_version_history.VersionHistoryButton, { disabled: isApplyingVersion })
459
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
460
- import_puck_editor.EditorToolbar,
461
- {
462
- saving,
463
- isDirty: hasUnsavedChanges,
464
- states: toolbarStates,
465
- onSave: () => void handleSave(),
466
- onPublish: () => void handlePublish(activeData),
467
- onRevert: () => void handleRevert(),
468
- showPublishButton: true
469
- }
470
- ),
471
- components: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_puck_editor.ComponentsPanel, { children }),
472
- componentItem: ({ children, name }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_puck_editor.ComponentItemFilter, { name, children }),
473
- fields: ({ children, isLoading }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_puck_version_history.VersionAwareFieldsPanel, { isLoading, children })
555
+ components: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_editor.ComponentsPanel, { children }),
556
+ componentItem: ({ children, name }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_editor.ComponentItemFilter, { name, children }),
557
+ fields: ({ children, isLoading }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_version_history.VersionAwareFieldsPanel, { isLoading, children })
558
+ }
559
+ },
560
+ `${versionHistory.selectedVersionId ?? "current"}:${reloadNonce}`
561
+ ),
562
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
563
+ import_puck_editor.CreateTemplateDialog,
564
+ {
565
+ isOpen: templateDialogOpen,
566
+ onOpenChange: (open) => setTemplateDialogOpen(open),
567
+ onConfirm: handleCreateTemplate,
568
+ saving: templateSaving
474
569
  }
475
- },
476
- versionHistory.selectedVersionId ?? "current"
477
- ) })
570
+ )
571
+ ] })
478
572
  }
479
573
  );
480
574
  };
@@ -483,19 +577,21 @@ var ContentEditor = ({
483
577
  projectKey,
484
578
  businessUnitKey,
485
579
  jwtToken,
580
+ locale,
486
581
  contentKey,
487
582
  config,
488
583
  onPublish,
489
584
  onSave,
490
585
  onError
491
- }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
586
+ }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EnsureNimbusProvider, { locale, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
492
587
  import_puck_api2.PuckApiProvider,
493
588
  {
494
589
  baseURL,
495
590
  projectKey,
496
591
  businessUnitKey,
497
592
  jwtToken,
498
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
593
+ locale,
594
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
499
595
  ContentEditorInner,
500
596
  {
501
597
  contentKey,
@@ -506,7 +602,7 @@ var ContentEditor = ({
506
602
  }
507
603
  )
508
604
  }
509
- ) });
605
+ ) }) });
510
606
 
511
607
  // src/ContentManagerRouter.tsx
512
608
  var import_react4 = require("react");
@@ -514,21 +610,12 @@ var import_react_router_dom = require("react-router-dom");
514
610
  var import_puck3 = require("@measured/puck");
515
611
  var import_puck4 = require("@measured/puck/puck.css");
516
612
  var import_puck_editor2 = require("@commercetools-demo/puck-editor");
613
+ var import_puck_renderer = require("@commercetools-demo/puck-renderer");
517
614
  var import_puck_version_history2 = require("@commercetools-demo/puck-version-history");
518
615
  var import_puck_api3 = require("@commercetools-demo/puck-api");
519
- var import_data_table2 = __toESM(require("@commercetools-uikit/data-table"));
520
- var import_primary_button2 = __toESM(require("@commercetools-uikit/primary-button"));
521
- var import_secondary_button2 = __toESM(require("@commercetools-uikit/secondary-button"));
522
- var import_flat_button2 = __toESM(require("@commercetools-uikit/flat-button"));
523
- var import_card2 = __toESM(require("@commercetools-uikit/card"));
524
- var import_spacings3 = __toESM(require("@commercetools-uikit/spacings"));
525
- var import_text3 = __toESM(require("@commercetools-uikit/text"));
526
- var import_loading_spinner3 = __toESM(require("@commercetools-uikit/loading-spinner"));
527
- var import_text_input2 = __toESM(require("@commercetools-uikit/text-input"));
528
- var import_label2 = __toESM(require("@commercetools-uikit/label"));
529
- var import_stamp2 = __toESM(require("@commercetools-uikit/stamp"));
530
- var import_icons2 = require("@commercetools-uikit/icons");
531
- var import_jsx_runtime4 = require("react/jsx-runtime");
616
+ var import_nimbus4 = require("@commercetools/nimbus");
617
+ var import_nimbus_icons2 = require("@commercetools/nimbus-icons");
618
+ var import_jsx_runtime5 = require("react/jsx-runtime");
532
619
  var DEFAULT_CONFIG = {
533
620
  ...import_puck_editor2.defaultPuckConfig,
534
621
  components: { ...import_puck_editor2.defaultPuckConfig.components }
@@ -541,28 +628,23 @@ var NAV_BAR_STYLE = {
541
628
  gap: "12px",
542
629
  padding: "8px 16px",
543
630
  background: "var(--color-surface, #fff)",
544
- borderBottom: "1px solid var(--color-neutral-90)",
631
+ borderBottom: "1px solid var(--color-neutral-90, #e0e0e0)",
545
632
  zIndex: 200,
546
633
  flexShrink: 0
547
634
  };
548
- var COLUMNS = [
549
- { key: "name", label: "Name" },
550
- { key: "contentType", label: "Content Type" },
551
- { key: "status", label: "Status" },
552
- { key: "updatedAt", label: "Updated" },
553
- { key: "actions", label: "Actions", shouldIgnoreRowClick: true }
554
- ];
555
635
  var ContentListRoute = ({ defaultContentType, backButton }) => {
556
636
  const history = (0, import_react_router_dom.useHistory)();
557
- const { contents, loading, error, fetchContents, createContent, deleteContent, refresh } = (0, import_puck_api3.usePuckContents)(defaultContentType);
558
- const [filterType, setFilterType] = (0, import_react4.useState)(defaultContentType ?? "");
637
+ const { contents, loading, error, createContent, deleteContent } = (0, import_puck_api3.usePuckContents)(defaultContentType);
638
+ const { templates } = (0, import_puck_api3.usePuckTemplates)("content");
639
+ const [search, setSearch] = (0, import_react4.useState)("");
559
640
  const [showCreate, setShowCreate] = (0, import_react4.useState)(false);
560
641
  const [createName, setCreateName] = (0, import_react4.useState)("");
561
642
  const [createType, setCreateType] = (0, import_react4.useState)(defaultContentType ?? "");
643
+ const [templateKey, setTemplateKey] = (0, import_react4.useState)("");
562
644
  const [createError, setCreateError] = (0, import_react4.useState)(null);
563
645
  const [creating, setCreating] = (0, import_react4.useState)(false);
564
646
  const [deleting, setDeleting] = (0, import_react4.useState)(null);
565
- const handleFilter = () => void fetchContents(filterType || void 0);
647
+ const [pendingDelete, setPendingDelete] = (0, import_react4.useState)(null);
566
648
  const handleCreate = async () => {
567
649
  setCreateError(null);
568
650
  if (!createName.trim()) {
@@ -575,15 +657,17 @@ var ContentListRoute = ({ defaultContentType, backButton }) => {
575
657
  }
576
658
  setCreating(true);
577
659
  try {
660
+ const template = templateKey ? templates.find((t) => t.key === templateKey) : void 0;
578
661
  const input = {
579
662
  name: createName.trim(),
580
663
  contentType: createType.trim(),
581
- data: { content: [], root: { props: {} } }
664
+ data: template?.value.puckData ?? { content: [], root: { props: {} } }
582
665
  };
583
666
  const created = await createContent(input);
584
667
  setShowCreate(false);
585
668
  setCreateName("");
586
669
  setCreateType(defaultContentType ?? "");
670
+ setTemplateKey("");
587
671
  history.push(`/${created.key}`, { contentName: created.value.name });
588
672
  } catch (err) {
589
673
  setCreateError(err.message);
@@ -591,163 +675,227 @@ var ContentListRoute = ({ defaultContentType, backButton }) => {
591
675
  setCreating(false);
592
676
  }
593
677
  };
594
- const handleDelete = async (key) => {
595
- if (!confirm("Delete this content item and all its versions?")) return;
596
- setDeleting(key);
678
+ const handleDelete = async (item) => {
679
+ setDeleting(item.key);
597
680
  try {
598
- await deleteContent(key);
681
+ await deleteContent(item.key);
682
+ setPendingDelete(null);
599
683
  } finally {
600
684
  setDeleting(null);
601
685
  }
602
686
  };
603
- const rows = contents.map((c) => ({ ...c, id: c.key }));
604
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "32px 24px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Stack, { scale: "l", children: [
605
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { justifyContent: "space-between", alignItems: "center", children: [
606
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "m", alignItems: "center", children: [
607
- backButton,
608
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Headline, { as: "h1", children: "Content Items" })
609
- ] }),
610
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
611
- import_primary_button2.default,
687
+ const term = search.trim().toLowerCase();
688
+ const filteredContents = term ? contents.filter(
689
+ (c) => c.value.name.toLowerCase().includes(term) || c.value.contentType.toLowerCase().includes(term)
690
+ ) : contents;
691
+ const rows = filteredContents.map((c) => ({ ...c, id: c.key }));
692
+ const columns = [
693
+ {
694
+ id: "name",
695
+ header: "Name",
696
+ accessor: (row) => row.value.name,
697
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { fontWeight: "bold", children: row.value.name })
698
+ },
699
+ {
700
+ id: "contentType",
701
+ header: "Content Type",
702
+ accessor: (row) => row.value.contentType,
703
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
704
+ "code",
612
705
  {
613
- label: "New Content",
614
- iconLeft: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons2.PlusThinIcon, {}),
615
- onClick: () => setShowCreate((v) => !v)
706
+ style: {
707
+ background: "#f4f4f4",
708
+ padding: "2px 6px",
709
+ borderRadius: "4px",
710
+ fontSize: "11px",
711
+ fontFamily: "monospace"
712
+ },
713
+ children: row.value.contentType
616
714
  }
617
715
  )
618
- ] }),
619
- showCreate && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_card2.default, { insetScale: "l", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Stack, { scale: "m", children: [
620
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Subheadline, { as: "h4", isBold: true, children: "Create Content Item" }),
621
- createError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "negative", children: createError }),
622
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "m", children: [
623
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Stack, { scale: "xs", children: [
624
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_label2.default, { htmlFor: "create-content-name", children: "Name" }),
625
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
626
- import_text_input2.default,
627
- {
628
- id: "create-content-name",
629
- value: createName,
630
- onChange: (e) => setCreateName(e.target.value),
631
- placeholder: "e.g. Homepage Hero"
632
- }
633
- )
634
- ] }) }),
635
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Stack, { scale: "xs", children: [
636
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_label2.default, { htmlFor: "create-content-type", children: "Content Type" }),
637
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
638
- import_text_input2.default,
639
- {
640
- id: "create-content-type",
641
- value: createType,
642
- onChange: (e) => setCreateType(e.target.value),
643
- placeholder: "e.g. hero, banner"
644
- }
645
- )
646
- ] }) })
647
- ] }),
648
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "s", children: [
649
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
650
- import_primary_button2.default,
716
+ },
717
+ {
718
+ id: "status",
719
+ header: "Status",
720
+ accessor: () => "",
721
+ isSortable: false,
722
+ render: ({ row }) => {
723
+ const hasDraft = !!row.states.draft;
724
+ const hasPublished = !!row.states.published;
725
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", gap: "100", wrap: "wrap", children: [
726
+ hasDraft && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Badge, { colorPalette: "warning", size: "xs", children: "Draft" }),
727
+ hasPublished && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Badge, { colorPalette: "positive", size: "xs", children: "Published" }),
728
+ !hasDraft && !hasPublished && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Badge, { colorPalette: "neutral", size: "xs", children: "No state" })
729
+ ] });
730
+ }
731
+ },
732
+ {
733
+ id: "updatedAt",
734
+ header: "Updated",
735
+ accessor: (row) => row.value.updatedAt,
736
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: new Date(row.value.updatedAt).toLocaleDateString() })
737
+ },
738
+ {
739
+ id: "actions",
740
+ header: "Actions",
741
+ accessor: () => "",
742
+ isSortable: false,
743
+ render: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", gap: "100", alignItems: "center", children: [
744
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
745
+ import_nimbus4.IconButton,
746
+ {
747
+ "aria-label": `Edit ${row.value.name}`,
748
+ variant: "ghost",
749
+ size: "xs",
750
+ onPress: () => history.push(`/${row.key}`, { contentName: row.value.name }),
751
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus_icons2.Edit, {})
752
+ }
753
+ ),
754
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
755
+ import_nimbus4.IconButton,
651
756
  {
652
- label: creating ? "Creating\u2026" : "Create",
653
- onClick: () => void handleCreate(),
654
- isDisabled: creating
757
+ "aria-label": `Preview ${row.value.name}`,
758
+ variant: "ghost",
759
+ size: "xs",
760
+ onPress: () => history.push(`/${row.key}/preview`, { contentName: row.value.name }),
761
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus_icons2.Visibility, {})
655
762
  }
656
763
  ),
657
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_secondary_button2.default, { label: "Cancel", onClick: () => setShowCreate(false) })
764
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
765
+ import_nimbus4.IconButton,
766
+ {
767
+ "aria-label": `Delete ${row.value.name}`,
768
+ variant: "ghost",
769
+ colorPalette: "critical",
770
+ size: "xs",
771
+ isDisabled: deleting === row.key,
772
+ onPress: () => setPendingDelete(row),
773
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus_icons2.Delete, {})
774
+ }
775
+ )
658
776
  ] })
659
- ] }) }),
660
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "s", alignItems: "center", children: [
661
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: 1, maxWidth: "280px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
662
- import_text_input2.default,
777
+ }
778
+ ];
779
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "32px 24px" }, children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "column", gap: "600", children: [
781
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [
782
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", gap: "400", alignItems: "center", children: [
783
+ backButton,
784
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { as: "h1", fontSize: "2xl", fontWeight: "700", children: "Content Items" })
785
+ ] }),
786
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Button, { variant: "solid", onPress: () => setShowCreate((v) => !v), children: [
787
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Icon, { as: import_nimbus_icons2.Add }),
788
+ " New Content"
789
+ ] })
790
+ ] }),
791
+ showCreate && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Card.Root, { variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Card.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "column", gap: "400", children: [
792
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Create Content Item" }),
793
+ createError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "critical.11", children: createError }),
794
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", gap: "400", children: [
795
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.FormField.Root, { children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Label, { children: "Name" }),
797
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
798
+ import_nimbus4.TextInput,
799
+ {
800
+ value: createName,
801
+ onChange: (v) => setCreateName(v),
802
+ placeholder: "e.g. Homepage Hero"
803
+ }
804
+ ) })
805
+ ] }) }),
806
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.FormField.Root, { children: [
807
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Label, { children: "Content Type" }),
808
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
809
+ import_nimbus4.TextInput,
810
+ {
811
+ value: createType,
812
+ onChange: (v) => setCreateType(v),
813
+ placeholder: "e.g. hero, banner"
814
+ }
815
+ ) })
816
+ ] }) })
817
+ ] }),
818
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.FormField.Root, { children: [
819
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Label, { children: "Template" }),
820
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
821
+ import_nimbus4.Select.Root,
822
+ {
823
+ "aria-label": "Template",
824
+ selectedKey: templateKey || "empty",
825
+ onSelectionChange: (key) => setTemplateKey(key == null || key === "empty" ? "" : String(key)),
826
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Select.Options, { children: [
827
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Select.Option, { id: "empty", children: "Empty" }),
828
+ templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Select.Option, { id: t.key, children: t.value.name }, t.key))
829
+ ] })
830
+ }
831
+ ) })
832
+ ] }),
833
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "row", gap: "200", children: [
834
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Button, { variant: "solid", onPress: () => void handleCreate(), isDisabled: creating, children: creating ? "Creating\u2026" : "Create" }),
835
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Button, { variant: "outline", onPress: () => setShowCreate(false), children: "Cancel" })
836
+ ] })
837
+ ] }) }) }),
838
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { maxWidth: 360 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
839
+ import_nimbus4.TextInput,
663
840
  {
664
- value: filterType,
665
- onChange: (e) => setFilterType(e.target.value),
666
- placeholder: "Filter by content type\u2026"
841
+ "aria-label": "Search content",
842
+ placeholder: "Search by name or content type\u2026",
843
+ value: search,
844
+ onChange: (v) => setSearch(v),
845
+ width: "100%",
846
+ trailingElement: search !== "" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
847
+ import_nimbus4.IconButton,
848
+ {
849
+ "aria-label": "Clear search",
850
+ variant: "ghost",
851
+ colorPalette: "neutral",
852
+ size: "2xs",
853
+ onPress: () => setSearch(""),
854
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus_icons2.Close, {})
855
+ }
856
+ ) : void 0
667
857
  }
668
858
  ) }),
669
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
670
- import_secondary_button2.default,
671
- {
672
- label: "Filter",
673
- iconLeft: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons2.SearchIcon, {}),
674
- onClick: handleFilter
675
- }
676
- ),
677
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
678
- import_flat_button2.default,
679
- {
680
- label: "Clear",
681
- onClick: () => {
682
- setFilterType("");
683
- void fetchContents(void 0);
684
- }
685
- }
686
- ),
687
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_flat_button2.default, { label: "Refresh", onClick: () => void refresh() })
859
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "critical.11", children: error }),
860
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.LoadingSpinner, {}) }) : contents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Stack, { direction: "column", gap: "400", alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "No content items found." }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.DataTable, { columns, rows, "aria-label": "Content items" })
688
861
  ] }),
689
- error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "negative", children: error }),
690
- loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_loading_spinner3.default, {}) }) : contents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_spacings3.default.Stack, { scale: "m", alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "secondary", children: "No content items found." }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
691
- import_data_table2.default,
862
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
863
+ import_nimbus4.Dialog.Root,
692
864
  {
693
- columns: COLUMNS,
694
- rows,
695
- itemRenderer: (row, column) => {
696
- switch (column.key) {
697
- case "name":
698
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { fontWeight: "bold", children: row.value.name });
699
- case "contentType":
700
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
701
- "code",
702
- {
703
- style: {
704
- background: "var(--color-neutral-95)",
705
- padding: "2px 6px",
706
- borderRadius: "var(--border-radius-4)",
707
- fontSize: "var(--font-size-10)",
708
- fontFamily: "monospace"
709
- },
710
- children: row.value.contentType
711
- }
712
- );
713
- case "status": {
714
- const hasDraft = !!row.states.draft;
715
- const hasPublished = !!row.states.published;
716
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { display: "inline-flex", gap: "4px", flexWrap: "wrap" }, children: [
717
- hasDraft && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_stamp2.default, { tone: "warning", label: "Draft", isCondensed: true }),
718
- hasPublished && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_stamp2.default, { tone: "positive", label: "Published", isCondensed: true }),
719
- !hasDraft && !hasPublished && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_stamp2.default, { tone: "secondary", label: "No state", isCondensed: true })
720
- ] });
721
- }
722
- case "updatedAt":
723
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "secondary", children: new Date(row.value.updatedAt).toLocaleDateString() });
724
- case "actions":
725
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "s", alignItems: "center", children: [
726
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
727
- import_primary_button2.default,
728
- {
729
- label: "Edit",
730
- size: "20",
731
- onClick: () => history.push(`/${row.key}`, { contentName: row.value.name })
732
- }
733
- ),
734
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
735
- import_flat_button2.default,
736
- {
737
- tone: "critical",
738
- label: deleting === row.key ? "\u2026" : "Delete",
739
- isDisabled: deleting === row.key,
740
- onClick: () => void handleDelete(row.key)
741
- }
742
- )
743
- ] });
744
- default:
745
- return null;
746
- }
747
- }
865
+ isOpen: pendingDelete !== null,
866
+ onOpenChange: (open) => {
867
+ if (!open) setPendingDelete(null);
868
+ },
869
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Dialog.Content, { children: [
870
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Dialog.Header, { children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Dialog.Title, { children: "Delete content item?" }),
872
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Dialog.CloseTrigger, {})
873
+ ] }),
874
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Text, { children: [
875
+ "Are you sure you want to delete",
876
+ " ",
877
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { as: "span", fontWeight: "700", children: pendingDelete?.value.name }),
878
+ " ",
879
+ "and all its versions? This cannot be undone."
880
+ ] }) }),
881
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Dialog.Footer, { children: [
882
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Button, { slot: "close", variant: "outline", isDisabled: deleting !== null, children: "Cancel" }),
883
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
884
+ import_nimbus4.Button,
885
+ {
886
+ colorPalette: "critical",
887
+ isDisabled: deleting !== null,
888
+ onPress: () => {
889
+ if (pendingDelete) void handleDelete(pendingDelete);
890
+ },
891
+ children: deleting !== null ? "Deleting\u2026" : "Delete"
892
+ }
893
+ )
894
+ ] })
895
+ ] })
748
896
  }
749
897
  )
750
- ] }) });
898
+ ] });
751
899
  };
752
900
  var ContentEditorRoute = ({ config, backButton }) => {
753
901
  const { contentKey } = (0, import_react_router_dom.useParams)();
@@ -766,9 +914,13 @@ var ContentEditorRoute = ({ config, backButton }) => {
766
914
  revertToPublished,
767
915
  loadVersions
768
916
  } = (0, import_puck_api3.usePuckContent)(contentKey);
917
+ const { createTemplate } = (0, import_puck_api3.usePuckTemplates)("content");
769
918
  const latestDataRef = (0, import_react4.useRef)(null);
770
- const [hasUnsavedChanges, setHasUnsavedChanges] = (0, import_react4.useState)(false);
771
919
  const [isApplyingVersion, setIsApplyingVersion] = (0, import_react4.useState)(false);
920
+ const [reloadNonce, setReloadNonce] = (0, import_react4.useState)(0);
921
+ const [pendingNav, setPendingNav] = (0, import_react4.useState)(null);
922
+ const [templateDialogOpen, setTemplateDialogOpen] = (0, import_react4.useState)(false);
923
+ const [templateSaving, setTemplateSaving] = (0, import_react4.useState)(false);
772
924
  const currentData = states.draft?.data ?? content?.data ?? { content: [], root: { props: {} } };
773
925
  const versionHistory = (0, import_puck_version_history2.useVersionHistoryPanel)({
774
926
  versions,
@@ -778,37 +930,52 @@ var ContentEditorRoute = ({ config, backButton }) => {
778
930
  const diff = (0, import_puck_version_history2.useVersionDiff)(versionHistory.previewData, currentData);
779
931
  const isPreviewingRef = (0, import_react4.useRef)(false);
780
932
  isPreviewingRef.current = versionHistory.isPreviewingHistory;
781
- const handleChange = (0, import_react4.useCallback)((data) => {
782
- if (isPreviewingRef.current) return;
783
- latestDataRef.current = data;
784
- setHasUnsavedChanges(true);
785
- }, []);
933
+ const canvasKey = `${contentKey}:${versionHistory.selectedVersionId ?? "current"}:${reloadNonce}`;
934
+ const { isDirty: hasUnsavedChanges, markChange, markSaved } = (0, import_puck_editor2.useDirtyState)(canvasKey);
935
+ const guardedNavigate = (0, import_react4.useCallback)(
936
+ (navFn) => {
937
+ if (hasUnsavedChanges) {
938
+ setPendingNav(() => navFn);
939
+ } else {
940
+ navFn();
941
+ }
942
+ },
943
+ [hasUnsavedChanges]
944
+ );
945
+ const handleChange = (0, import_react4.useCallback)(
946
+ (data) => {
947
+ if (isPreviewingRef.current) return;
948
+ latestDataRef.current = data;
949
+ markChange(data);
950
+ },
951
+ [markChange]
952
+ );
786
953
  const handleSave = (0, import_react4.useCallback)(async () => {
787
954
  const data = latestDataRef.current;
788
955
  if (!data) return;
789
956
  try {
790
957
  await saveDraft(data);
791
- setHasUnsavedChanges(false);
958
+ markSaved(data);
792
959
  } catch (err) {
793
960
  console.error("[ContentManagerRouter] save error:", err);
794
961
  }
795
- }, [saveDraft]);
962
+ }, [saveDraft, markSaved]);
796
963
  const handlePublish = (0, import_react4.useCallback)(
797
964
  async (data) => {
798
965
  try {
799
966
  await saveDraft(data);
800
- setHasUnsavedChanges(false);
967
+ markSaved(data);
801
968
  await publish(false);
802
969
  } catch (err) {
803
970
  console.error("[ContentManagerRouter] publish error:", err);
804
971
  }
805
972
  },
806
- [saveDraft, publish]
973
+ [saveDraft, publish, markSaved]
807
974
  );
808
975
  const handleRevert = (0, import_react4.useCallback)(async () => {
809
976
  try {
810
977
  await revertToPublished();
811
- setHasUnsavedChanges(false);
978
+ setReloadNonce((n) => n + 1);
812
979
  } catch (err) {
813
980
  console.error("[ContentManagerRouter] revert error:", err);
814
981
  }
@@ -819,14 +986,14 @@ var ContentEditorRoute = ({ config, backButton }) => {
819
986
  setIsApplyingVersion(true);
820
987
  try {
821
988
  await saveDraft(versionData);
822
- setHasUnsavedChanges(false);
989
+ markSaved(versionData);
823
990
  versionHistory.clearSelection();
824
991
  } catch (err) {
825
992
  console.error("[ContentManagerRouter] apply version error:", err);
826
993
  } finally {
827
994
  setIsApplyingVersion(false);
828
995
  }
829
- }, [versionHistory, saveDraft]);
996
+ }, [versionHistory, saveDraft, markSaved]);
830
997
  const contentConfig = (0, import_react4.useMemo)(() => {
831
998
  const otherRootFields = Object.fromEntries(
832
999
  Object.entries(config.root?.fields ?? {}).filter(([k]) => k !== "title")
@@ -848,22 +1015,38 @@ var ContentEditorRoute = ({ config, backButton }) => {
848
1015
  }
849
1016
  };
850
1017
  }, [config]);
1018
+ const handleCreateTemplate = (0, import_react4.useCallback)(
1019
+ async (name, withoutData) => {
1020
+ const source = latestDataRef.current ?? currentData;
1021
+ const puckData = withoutData ? (0, import_puck_editor2.stripPuckDataToTemplate)(source, contentConfig) : source;
1022
+ setTemplateSaving(true);
1023
+ try {
1024
+ await createTemplate({ name, kind: "content", puckData });
1025
+ setTemplateDialogOpen(false);
1026
+ } catch (err) {
1027
+ console.error("[ContentManagerRouter] create template error:", err);
1028
+ } finally {
1029
+ setTemplateSaving(false);
1030
+ }
1031
+ },
1032
+ [createTemplate, currentData, contentConfig]
1033
+ );
851
1034
  if (loading) {
852
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Stack, { scale: "m", alignItems: "center", children: [
853
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_loading_spinner3.default, {}),
854
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "secondary", children: "Loading editor\u2026" })
1035
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Stack, { direction: "column", gap: "400", alignItems: "center", children: [
1036
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.LoadingSpinner, {}),
1037
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "Loading editor\u2026" })
855
1038
  ] }) });
856
1039
  }
857
1040
  if (error) {
858
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_text3.default.Body, { tone: "negative", children: [
859
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Error loading content:" }),
1041
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Text, { color: "critical.11", children: [
1042
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Error loading content:" }),
860
1043
  " ",
861
1044
  error
862
1045
  ] }) });
863
1046
  }
864
1047
  const activeData = versionHistory.previewData ?? currentData;
865
1048
  const toolbarStates = states;
866
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1049
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
867
1050
  import_puck_version_history2.VersionHistoryProvider,
868
1051
  {
869
1052
  diff,
@@ -876,82 +1059,164 @@ var ContentEditorRoute = ({ config, backButton }) => {
876
1059
  onApply: () => void handleApplyVersion(),
877
1060
  onDiscard: versionHistory.clearSelection,
878
1061
  onLoadVersions: versionHistory.openPanel,
879
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
880
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: NAV_BAR_STYLE, children: [
881
- backButton,
882
- backButton && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "secondary", children: "/" }),
883
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
884
- import_flat_button2.default,
885
- {
886
- label: "Content Items",
887
- icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons2.AngleLeftIcon, {}),
888
- iconPosition: "left",
889
- onClick: () => history.push("/")
890
- }
891
- ),
892
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { tone: "secondary", children: "/" }),
893
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_text3.default.Body, { fontWeight: "bold", children: contentName })
1062
+ children: [
1063
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
1064
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: NAV_BAR_STYLE, children: [
1065
+ backButton,
1066
+ backButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "/" }),
1067
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1068
+ import_nimbus4.Button,
1069
+ {
1070
+ variant: "ghost",
1071
+ onPress: () => guardedNavigate(() => history.push("/")),
1072
+ children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Icon, { as: import_nimbus_icons2.ChevronLeft }),
1074
+ " Content Items"
1075
+ ]
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "/" }),
1079
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { fontWeight: "bold", children: contentName })
1080
+ ] }),
1081
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "puck-editor-fill", style: { flex: 1, overflow: "hidden" }, children: [
1082
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_editor2.ComponentSearchProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1083
+ import_puck3.Puck,
1084
+ {
1085
+ config: contentConfig,
1086
+ data: activeData,
1087
+ onChange: handleChange,
1088
+ onPublish: handlePublish,
1089
+ overrides: {
1090
+ fieldTypes: import_puck_editor2.nimbusFieldTypes,
1091
+ header: () => versionHistory.isPreviewingHistory ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1092
+ import_nimbus4.Stack,
1093
+ {
1094
+ gridArea: "header",
1095
+ direction: "row",
1096
+ gap: "200",
1097
+ alignItems: "center",
1098
+ justifyContent: "flex-end",
1099
+ padding: "200",
1100
+ children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1102
+ import_puck_version_history2.VersionPreviewBanner,
1103
+ {
1104
+ timestamp: versionHistory.selectedVersion.timestamp,
1105
+ onApply: () => void handleApplyVersion(),
1106
+ onDiscard: versionHistory.clearSelection,
1107
+ isApplying: isApplyingVersion
1108
+ }
1109
+ ),
1110
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_version_history2.VersionHistoryButton, { disabled: isApplyingVersion })
1111
+ ]
1112
+ }
1113
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1114
+ import_puck_editor2.EditorToolbar,
1115
+ {
1116
+ title: content?.name ?? contentName,
1117
+ saving,
1118
+ isDirty: hasUnsavedChanges,
1119
+ states: toolbarStates,
1120
+ onSave: () => void handleSave(),
1121
+ onPublish: () => void handlePublish(activeData),
1122
+ onRevert: () => void handleRevert(),
1123
+ onPreview: () => guardedNavigate(
1124
+ () => history.push(`/${contentKey}/preview`, { contentName })
1125
+ ),
1126
+ onCreateTemplate: () => setTemplateDialogOpen(true),
1127
+ createTemplateLabel: "Create a template from this content",
1128
+ showPublishButton: true
1129
+ }
1130
+ ),
1131
+ components: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_editor2.ComponentsPanel, { children }),
1132
+ componentItem: ({ children, name }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_editor2.ComponentItemFilter, { name, children }),
1133
+ fields: ({ children, isLoading }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_version_history2.VersionAwareFieldsPanel, { isLoading, children })
1134
+ }
1135
+ },
1136
+ `${versionHistory.selectedVersionId ?? "current"}:${reloadNonce}`
1137
+ ) }),
1138
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_editor2.PropertiesResizer, {})
1139
+ ] })
894
1140
  ] }),
895
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_editor2.ComponentSearchProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
896
- import_puck3.Puck,
1141
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1142
+ import_puck_editor2.UnsavedChangesDialog,
897
1143
  {
898
- config: contentConfig,
899
- data: activeData,
900
- onChange: handleChange,
901
- onPublish: handlePublish,
902
- overrides: {
903
- headerActions: () => versionHistory.isPreviewingHistory ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_spacings3.default.Inline, { scale: "s", alignItems: "center", children: [
904
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
905
- import_puck_version_history2.VersionPreviewBanner,
906
- {
907
- timestamp: versionHistory.selectedVersion.timestamp,
908
- onApply: () => void handleApplyVersion(),
909
- onDiscard: versionHistory.clearSelection,
910
- isApplying: isApplyingVersion
911
- }
912
- ),
913
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_version_history2.VersionHistoryButton, { disabled: isApplyingVersion })
914
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
915
- import_puck_editor2.EditorToolbar,
916
- {
917
- saving,
918
- isDirty: hasUnsavedChanges,
919
- states: toolbarStates,
920
- onSave: () => void handleSave(),
921
- onPublish: () => void handlePublish(activeData),
922
- onRevert: () => void handleRevert(),
923
- showPublishButton: true
924
- }
925
- ),
926
- components: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_editor2.ComponentsPanel, { children }),
927
- componentItem: ({ children, name }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_editor2.ComponentItemFilter, { name, children }),
928
- fields: ({ children, isLoading }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_puck_version_history2.VersionAwareFieldsPanel, { isLoading, children })
929
- }
930
- },
931
- versionHistory.selectedVersionId ?? "current"
932
- ) }) })
933
- ] })
1144
+ isOpen: pendingNav !== null,
1145
+ onOpenChange: (open) => {
1146
+ if (!open) setPendingNav(null);
1147
+ },
1148
+ onConfirm: () => pendingNav?.()
1149
+ }
1150
+ ),
1151
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1152
+ import_puck_editor2.CreateTemplateDialog,
1153
+ {
1154
+ isOpen: templateDialogOpen,
1155
+ onOpenChange: (open) => setTemplateDialogOpen(open),
1156
+ onConfirm: handleCreateTemplate,
1157
+ saving: templateSaving
1158
+ }
1159
+ )
1160
+ ]
934
1161
  }
935
1162
  );
936
1163
  };
1164
+ var ContentPreviewRoute = ({ config, backButton }) => {
1165
+ const { contentKey } = (0, import_react_router_dom.useParams)();
1166
+ const history = (0, import_react_router_dom.useHistory)();
1167
+ const location = (0, import_react_router_dom.useLocation)();
1168
+ const contentName = location.state?.contentName ?? contentKey ?? "Content";
1169
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: NAV_BAR_STYLE, children: [
1171
+ backButton,
1172
+ backButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "/" }),
1173
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Button, { variant: "ghost", onPress: () => history.push("/"), children: [
1174
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Icon, { as: import_nimbus_icons2.ChevronLeft }),
1175
+ " Content Items"
1176
+ ] }),
1177
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Text, { color: "neutral.11", children: "/" }),
1178
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1179
+ import_nimbus4.Button,
1180
+ {
1181
+ variant: "ghost",
1182
+ onPress: () => history.push(`/${contentKey}`, { contentName }),
1183
+ children: contentName
1184
+ }
1185
+ ),
1186
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Badge, { colorPalette: "primary", size: "xs", children: "Preview" }),
1187
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginLeft: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_nimbus4.Button, { variant: "outline", size: "xs", onPress: () => history.goBack(), children: [
1188
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_nimbus4.Icon, { as: import_nimbus_icons2.Close }),
1189
+ " Close preview"
1190
+ ] }) })
1191
+ ] }),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_puck_renderer.PuckRenderer, { type: "content", contentKey, mode: "preview", config })
1193
+ ] });
1194
+ };
937
1195
  var ContentManagerRouterInner = ({
938
1196
  config,
939
1197
  defaultContentType,
940
1198
  backButton
941
- }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_router_dom.Switch, { children: [
942
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1199
+ }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_router_dom.Switch, { children: [
1200
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
943
1201
  import_react_router_dom.Route,
944
1202
  {
945
1203
  exact: true,
946
1204
  path: "/",
947
- render: () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContentListRoute, { defaultContentType, backButton })
1205
+ render: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ContentListRoute, { defaultContentType, backButton })
1206
+ }
1207
+ ),
1208
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1209
+ import_react_router_dom.Route,
1210
+ {
1211
+ path: "/:contentKey/preview",
1212
+ render: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ContentPreviewRoute, { config, backButton })
948
1213
  }
949
1214
  ),
950
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1215
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
951
1216
  import_react_router_dom.Route,
952
1217
  {
953
1218
  path: "/:contentKey",
954
- render: () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContentEditorRoute, { config, backButton })
1219
+ render: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ContentEditorRoute, { config, backButton })
955
1220
  }
956
1221
  )
957
1222
  ] });
@@ -961,17 +1226,19 @@ var ContentManager = ({
961
1226
  projectKey,
962
1227
  businessUnitKey,
963
1228
  jwtToken,
1229
+ locale,
964
1230
  config = DEFAULT_CONFIG,
965
1231
  defaultContentType,
966
1232
  backButton
967
- }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1233
+ }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EnsureNimbusProvider, { locale, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EnsureIntlProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
968
1234
  import_puck_api3.PuckApiProvider,
969
1235
  {
970
1236
  baseURL,
971
1237
  projectKey,
972
1238
  businessUnitKey,
973
1239
  jwtToken,
974
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_router_dom.BrowserRouter, { basename: parentUrl, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1240
+ locale,
1241
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_router_dom.BrowserRouter, { basename: parentUrl, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
975
1242
  ContentManagerRouterInner,
976
1243
  {
977
1244
  config,
@@ -980,7 +1247,7 @@ var ContentManager = ({
980
1247
  }
981
1248
  ) })
982
1249
  }
983
- ) });
1250
+ ) }) });
984
1251
  // Annotate the CommonJS export names for ESM import in node:
985
1252
  0 && (module.exports = {
986
1253
  ContentEditor,