@hszrdm/core 1.0.0 → 1.0.2

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.
@@ -27,7 +27,7 @@ const BankTransferOrderWidget = ({ data: order }) => {
27
27
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
28
28
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
29
29
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Banki átutalás adatai" }),
30
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "A fizetési állapotot a Medusa Payment panel kezeli." })
30
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "A fizetési állapotot a HSZRDM Commerce Payment panel kezeli." })
31
31
  ] }),
32
32
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-2 px-6 py-4 text-sm", children: [
33
33
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { children: [
@@ -264,8 +264,86 @@ const BillingoOrderWidget = ({ data: order }) => {
264
264
  adminSdk.defineWidgetConfig({
265
265
  zone: "order.details.after"
266
266
  });
267
- const brandName = "Webshop Admin";
267
+ const platformName = "HSZRDM Commerce";
268
+ const brandIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><rect width="512" height="512" rx="88" fill="#080b10"/><path d="M96 112h64v112h104V112h64v288h-64V288H160v112H96z" fill="#f0f2f5"/><path d="M400 112h48l-72 288h-48z" fill="#77a9ff"/></svg>';
269
+ const brandIconDataUri = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(brandIconSvg)}`;
270
+ const configuredBrandName = platformName;
271
+ const storeName = configuredBrandName.replace(/\s*[–-]\s*HSZRDM Commerce$/i, "").trim();
272
+ const visibleStoreName = storeName && storeName.toLowerCase() !== platformName.toLowerCase() ? storeName : "";
273
+ const nativeLoginCopy = /* @__PURE__ */ new Map([
274
+ ["Welcome to Medusa", platformName],
275
+ ["Sign in to access the account area", "Jelentkezz be az admin felület eléréséhez"]
276
+ ]);
277
+ function installFavicon() {
278
+ for (const element of Array.from(document.querySelectorAll('link[rel~="icon"]'))) {
279
+ if (element.dataset.hszrdmFavicon !== "true") element.remove();
280
+ }
281
+ let link = document.querySelector('link[data-hszrdm-favicon="true"]');
282
+ if (!link) {
283
+ link = document.createElement("link");
284
+ link.rel = "icon";
285
+ link.type = "image/svg+xml";
286
+ link.dataset.hszrdmFavicon = "true";
287
+ document.head.appendChild(link);
288
+ }
289
+ link.href = brandIconDataUri;
290
+ }
291
+ function installNativeLoginIcon() {
292
+ const title = Array.from(document.querySelectorAll("h1,h2,h3")).find((element) => element.textContent?.trim() === platformName);
293
+ if (!title) return;
294
+ const titleBlock = title.parentElement;
295
+ const possibleHosts = [
296
+ titleBlock?.previousElementSibling,
297
+ titleBlock?.parentElement?.previousElementSibling
298
+ ].filter((element) => element instanceof HTMLElement);
299
+ const host = possibleHosts.find((element) => {
300
+ const rect = element.getBoundingClientRect();
301
+ return rect.width > 0 && rect.height > 0 && rect.width <= 96 && rect.height <= 96;
302
+ });
303
+ if (!host || host.dataset.hszrdmLoginIcon === "true") return;
304
+ host.innerHTML = brandIconSvg;
305
+ host.dataset.hszrdmLoginIcon = "true";
306
+ const svg = host.querySelector("svg");
307
+ if (svg) {
308
+ svg.setAttribute("aria-label", "HSZRDM Commerce");
309
+ svg.setAttribute("role", "img");
310
+ svg.style.display = "block";
311
+ svg.style.width = "100%";
312
+ svg.style.height = "100%";
313
+ }
314
+ }
315
+ function rewriteNativeLoginBranding() {
316
+ document.title = visibleStoreName ? `${visibleStoreName} – ${platformName}` : platformName;
317
+ installFavicon();
318
+ const walker = document.createTreeWalker(
319
+ document.body,
320
+ NodeFilter.SHOW_TEXT
321
+ );
322
+ let current = walker.nextNode();
323
+ while (current) {
324
+ const value = current.nodeValue?.trim();
325
+ const replacement = value ? nativeLoginCopy.get(value) : void 0;
326
+ if (replacement && current.nodeValue) {
327
+ current.nodeValue = current.nodeValue.replace(value, replacement);
328
+ }
329
+ current = walker.nextNode();
330
+ }
331
+ installNativeLoginIcon();
332
+ }
268
333
  const CoreLoginBrand = () => {
334
+ React.useEffect(() => {
335
+ rewriteNativeLoginBranding();
336
+ const observer = new MutationObserver(() => {
337
+ rewriteNativeLoginBranding();
338
+ });
339
+ observer.observe(document.body, {
340
+ childList: true,
341
+ subtree: true,
342
+ characterData: true
343
+ });
344
+ return () => observer.disconnect();
345
+ }, []);
346
+ if (!visibleStoreName) return null;
269
347
  return /* @__PURE__ */ jsxRuntime.jsx(
270
348
  "div",
271
349
  {
@@ -277,7 +355,7 @@ const CoreLoginBrand = () => {
277
355
  letterSpacing: "-0.02em",
278
356
  marginBottom: "8px"
279
357
  },
280
- children: brandName
358
+ children: visibleStoreName
281
359
  }
282
360
  );
283
361
  };
@@ -830,6 +908,9 @@ adminSdk.defineWidgetConfig({
830
908
  const backendUrl$c = (__BACKEND_URL__ || "").replace(/\/+$/, "");
831
909
  const adminBase$9 = (__BASE__ || "/app").replace(/\/+$/, "");
832
910
  const apiUrl$c = (path) => `${backendUrl$c}${path.startsWith("/") ? path : `/${path}`}`;
911
+ const showDeveloperDetails = Boolean(
912
+ false
913
+ );
833
914
  const AnalyticsPage = () => {
834
915
  const initial = React.useMemo(() => presetRange("30d"), []);
835
916
  const [preset, setPreset] = React.useState("30d");
@@ -875,7 +956,7 @@ const AnalyticsPage = () => {
875
956
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-5", children: [
876
957
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
877
958
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Analitika" }),
878
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "A fő forgalmi és viselkedési mérés közvetlenül a webshopból érkezik; a rendelés, vásárló és bevétel forrása a Medusa. A GA4 külön kontrolladat." })
959
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: showDeveloperDetails ? "A fő forgalmi és viselkedési mérés közvetlenül a webshopból érkezik; a rendelés, vásárló és bevétel forrása a HSZRDM Commerce rendelési rendszere. A GA4 külön kontrolladat." : "Forgalom, vásárlói viselkedés, rendelések és bevétel egy helyen." })
879
960
  ] }),
880
961
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Frissítés" })
881
962
  ] }),
@@ -961,7 +1042,7 @@ const AnalyticsPage = () => {
961
1042
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [
962
1043
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
963
1044
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Top termékek" }),
964
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Eladás szerint Medusából, viselkedés szerint a saját webshop-mérésből." })
1045
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: showDeveloperDetails ? "Eladás szerint a HSZRDM Commerce rendelési rendszeréből, viselkedés szerint a saját webshop-mérésből." : "A legjobban teljesítő termékek bevétel és vásárlói viselkedés alapján." })
965
1046
  ] }),
966
1047
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
967
1048
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: productMode === "revenue" ? "primary" : "secondary", onClick: () => setProductMode("revenue"), children: "Bevétel" }),
@@ -1007,7 +1088,7 @@ const AnalyticsPage = () => {
1007
1088
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 flex flex-wrap items-start justify-between gap-2", children: [
1008
1089
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1009
1090
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Google Analytics összehasonlítás" }),
1010
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Kontrolladat; nem ez a webshop üzleti source of truth-ja." })
1091
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: showDeveloperDetails ? "Kontrolladat; nem ez a webshop üzleti source of truth-ja." : "Kiegészítő összehasonlítás a Google Analytics 4 adataival." })
1011
1092
  ] }),
1012
1093
  /* @__PURE__ */ jsxRuntime.jsx(SourceBadge, { source: "ga4" })
1013
1094
  ] }),
@@ -1027,7 +1108,7 @@ const AnalyticsPage = () => {
1027
1108
  data.currency,
1028
1109
  " bevételi összegzésbe."
1029
1110
  ] }) : null,
1030
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-ui-bg-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "A látogató-, session-, forrás-, termékviselkedési és funnel adatok elsődleges forrása a HSZRDM Webshop Analytics. A rendelés, vásárló és bevétel üzleti forrása a Medusa adatbázisa. A GA4 csak külső kontroll és marketing riportforrás." }) })
1111
+ showDeveloperDetails ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-ui-bg-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "A látogató-, session-, forrás-, termékviselkedési és funnel adatok elsődleges forrása a HSZRDM Webshop Analytics. A rendelés, vásárló és bevétel üzleti forrása a HSZRDM Commerce adatbázisa. A GA4 csak külső kontroll és marketing riportforrás." }) }) : null
1031
1112
  ] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-10 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Analitika betöltése…" }) }) : null
1032
1113
  ] });
1033
1114
  };
@@ -1048,7 +1129,8 @@ function KpiCard({ label, metric, compare, format = "number", currency = "HUF" }
1048
1129
  ] });
1049
1130
  }
1050
1131
  function SourceBadge({ source, compact = false }) {
1051
- const label = source === "ga4" ? "GA4" : source === "webshop" ? "Webshop mérés" : source === "combined" ? "Webshop + Medusa" : "Medusa";
1132
+ if (!showDeveloperDetails) return null;
1133
+ const label = source === "ga4" ? "GA4" : source === "webshop" ? "Webshop mérés" : source === "combined" ? "Webshop + HSZRDM Commerce" : "HSZRDM Commerce";
1052
1134
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `rounded-full border bg-ui-bg-subtle text-ui-fg-subtle ${compact ? "px-1.5 py-0.5 text-[10px]" : "px-2 py-1 text-xs"}`, children: label });
1053
1135
  }
1054
1136
  function RevenueChart({ series, currency }) {
@@ -1215,6 +1297,53 @@ function formatNullablePercent(value) {
1215
1297
  return value == null ? "—" : formatPercent(value);
1216
1298
  }
1217
1299
  const config$c = adminSdk.defineRouteConfig({ label: "Analitika" });
1300
+ const adminBase$8 = (__BASE__ || "/app").replace(/\/+$/, "");
1301
+ const links$1 = [
1302
+ {
1303
+ label: "Analitika",
1304
+ description: "Látogatók, vásárlási tölcsér, bevétel, vásárlók, top termékek és checkout állapot egy közös dashboardon.",
1305
+ href: `${adminBase$8}/analytics`
1306
+ },
1307
+ {
1308
+ label: "SEO",
1309
+ description: "Termék-, kategória- és oldal SEO title, description, canonical, robots és Open Graph kezelése.",
1310
+ href: `${adminBase$8}/marketing/seo`
1311
+ },
1312
+ {
1313
+ label: "SEO átirányítások",
1314
+ description: "Régi URL-ek 301/308 átirányítása, be/ki kapcsolás és query paraméter kezelés.",
1315
+ href: `${adminBase$8}/marketing/seo/redirects`
1316
+ },
1317
+ {
1318
+ label: "Google Merchant",
1319
+ description: "Google Merchant Center termékfeed előnézet, diagnosztika és publikus feed URL.",
1320
+ href: `${adminBase$8}/marketing/google-merchant`
1321
+ },
1322
+ {
1323
+ label: "Árukereső",
1324
+ description: "Árukereső.hu XML feed előnézet, diagnosztika és publikus feed URL.",
1325
+ href: `${adminBase$8}/marketing/arukereso`
1326
+ }
1327
+ ];
1328
+ const MarketingPage = () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
1329
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-5", children: [
1330
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Marketing" }),
1331
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Analitika, SEO, termékfeedek és külső marketing/értékesítési csatornák kezelése. Az integrációk technikai alapbeállításai a Settings → Integrációk alatt találhatók." })
1332
+ ] }),
1333
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 p-6 md:grid-cols-2 xl:grid-cols-3", children: links$1.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
1334
+ "a",
1335
+ {
1336
+ href: item.href,
1337
+ className: "rounded-lg border p-5 transition-colors hover:bg-ui-bg-subtle",
1338
+ children: [
1339
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: item.label }),
1340
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: item.description })
1341
+ ]
1342
+ },
1343
+ item.href
1344
+ )) })
1345
+ ] });
1346
+ const config$b = adminSdk.defineRouteConfig({ label: "Marketing" });
1218
1347
  var __defProp$1 = Object.defineProperty;
1219
1348
  var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
1220
1349
  var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
@@ -1332,412 +1461,335 @@ const TruckFast = React__namespace.forwardRef(
1332
1461
  }
1333
1462
  );
1334
1463
  TruckFast.displayName = "TruckFast";
1464
+ const LABEL_FORMAT_STORAGE_KEY = "core.shipping.labelFormat";
1465
+ const DIRECT_PRINT_STORAGE_KEY = "core.shipping.directPrint";
1335
1466
  const backendUrl$b = (__BACKEND_URL__ || "").replace(/\/+$/, "");
1336
- const adminBase$8 = (__BASE__ || "/app").replace(/\/+$/, "");
1337
- const apiUrl$b = (path) => `${backendUrl$b}${path.startsWith("/") ? path : `/${path}`}`;
1338
- const LegalPage = () => {
1339
- const [documents, setDocuments] = React.useState([]);
1340
- const [consents, setConsents] = React.useState([]);
1341
- const [loading, setLoading] = React.useState(true);
1342
- const [busy, setBusy] = React.useState(null);
1467
+ const adminBase$7 = (__BASE__ || "/app").replace(/\/+$/, "");
1468
+ function apiUrl$b(path) {
1469
+ return `${backendUrl$b}${path.startsWith("/") ? path : `/${path}`}`;
1470
+ }
1471
+ const ShippingPage = () => {
1472
+ const [orders, setOrders] = React.useState([]);
1473
+ const [selected, setSelected] = React.useState([]);
1474
+ const [format, setFormat] = React.useState("A6");
1475
+ const [packageSize, setPackageSize] = React.useState("M");
1476
+ const [directPrint, setDirectPrint] = React.useState(false);
1477
+ const [loading, setLoading] = React.useState(null);
1478
+ const [ordersLoading, setOrdersLoading] = React.useState(true);
1343
1479
  const [loadError, setLoadError] = React.useState(null);
1344
- const [title, setTitle] = React.useState("");
1345
- const [key, setKey] = React.useState("");
1346
- const [kind, setKind] = React.useState("custom");
1347
- const [fileName, setFileName] = React.useState("");
1348
- const [fileBase64, setFileBase64] = React.useState("");
1349
- const [enabled, setEnabled] = React.useState(true);
1350
- const [required, setRequired] = React.useState(false);
1480
+ const selectedSet = React.useMemo(() => new Set(selected), [selected]);
1481
+ const selectedMplOrders = React.useMemo(
1482
+ () => orders.filter((order) => selectedSet.has(order.id) && order.carrier === "mpl"),
1483
+ [orders, selectedSet]
1484
+ );
1351
1485
  const load = React.useCallback(async () => {
1352
- setLoading(true);
1486
+ setOrdersLoading(true);
1353
1487
  setLoadError(null);
1354
1488
  try {
1355
- const [documentsResponse, consentsResponse] = await Promise.all([
1356
- fetch(apiUrl$b("/admin/legal/documents"), { credentials: "include" }),
1357
- fetch(apiUrl$b("/admin/legal/consents"), { credentials: "include" })
1358
- ]);
1359
- const documentsPayload = await documentsResponse.json().catch(() => ({}));
1360
- const consentsPayload = await consentsResponse.json().catch(() => ({}));
1361
- if (!documentsResponse.ok) {
1362
- throw new Error(
1363
- documentsPayload.message || "A jogi dokumentumok nem tölthetők be."
1364
- );
1365
- }
1366
- if (!consentsResponse.ok) {
1367
- throw new Error(
1368
- consentsPayload.message || "Az elfogadások nem tölthetők be."
1369
- );
1489
+ const response = await fetch(apiUrl$b("/admin/shipping/orders"), {
1490
+ credentials: "include"
1491
+ });
1492
+ const data = await response.json().catch(() => ({}));
1493
+ if (!response.ok) {
1494
+ throw new Error(data.message || "A szállítási rendelések betöltése nem sikerült.");
1370
1495
  }
1371
- setDocuments(documentsPayload.documents || []);
1372
- setConsents(consentsPayload.consents || []);
1496
+ const nextOrders = data.orders || [];
1497
+ setOrders(nextOrders);
1498
+ setSelected((current) => current.filter((id) => nextOrders.some((order) => order.id === id)));
1373
1499
  } catch (error) {
1374
- setLoadError(
1375
- error instanceof Error ? error.message : "A jogi dokumentumok nem tölthetők be."
1376
- );
1500
+ const message = error instanceof Error ? error.message : "A szállítási rendelések betöltése nem sikerült.";
1501
+ setOrders([]);
1502
+ setLoadError(message);
1377
1503
  } finally {
1378
- setLoading(false);
1504
+ setOrdersLoading(false);
1379
1505
  }
1380
1506
  }, []);
1381
1507
  React.useEffect(() => {
1508
+ setFormat(localStorage.getItem(LABEL_FORMAT_STORAGE_KEY) || "A6");
1509
+ setDirectPrint(localStorage.getItem(DIRECT_PRINT_STORAGE_KEY) === "true");
1382
1510
  void load();
1383
1511
  }, [load]);
1384
- const createDocument = async () => {
1385
- setBusy("create");
1512
+ const setSavedFormat = (value) => {
1513
+ setFormat(value);
1514
+ localStorage.setItem(LABEL_FORMAT_STORAGE_KEY, value);
1515
+ };
1516
+ const setSavedPrint = (value) => {
1517
+ setDirectPrint(value);
1518
+ localStorage.setItem(DIRECT_PRINT_STORAGE_KEY, String(value));
1519
+ };
1520
+ const toggle = (id) => {
1521
+ setSelected((current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id]);
1522
+ };
1523
+ const create = async () => {
1524
+ if (!selected.length) {
1525
+ ui.toast.error("Jelölj ki legalább egy rendelést.");
1526
+ return false;
1527
+ }
1528
+ setLoading("create");
1386
1529
  try {
1387
- if (!title.trim() || !key.trim()) {
1388
- throw new Error("A név és a kulcs kötelező.");
1389
- }
1390
- if (!fileBase64) throw new Error("Válassz PDF fájlt.");
1391
- const response = await fetch(apiUrl$b("/admin/legal/documents"), {
1530
+ const response = await fetch(apiUrl$b("/admin/shipping/bulk/create"), {
1392
1531
  method: "POST",
1393
1532
  credentials: "include",
1394
1533
  headers: { "Content-Type": "application/json" },
1395
- body: JSON.stringify({
1396
- title,
1397
- key,
1398
- kind,
1399
- fileBase64,
1400
- fileName,
1401
- enabled,
1402
- requiredAtCheckout: required
1403
- })
1534
+ body: JSON.stringify({ orderIds: selected, packageSize })
1404
1535
  });
1405
- const payload = await response.json().catch(() => ({}));
1406
- if (!response.ok) {
1407
- throw new Error(
1408
- payload.message || "A dokumentum létrehozása nem sikerült."
1409
- );
1536
+ const data = await response.json().catch(() => ({}));
1537
+ if (!response.ok && response.status !== 207) {
1538
+ throw new Error(data.message || "A tömeges csomagkészítés nem sikerült.");
1410
1539
  }
1411
- ui.toast.success("Jogi PDF létrehozva és verziózva.");
1412
- setTitle("");
1413
- setKey("");
1414
- setKind("custom");
1415
- setFileName("");
1416
- setFileBase64("");
1417
- setEnabled(true);
1418
- setRequired(false);
1540
+ const failed = data.results?.filter((item) => !item.ok) || [];
1541
+ if (failed.length) ui.toast.error(`${failed.length} csomag nem készült el.`);
1542
+ else ui.toast.success(`${selected.length} csomag elkészült.`);
1419
1543
  await load();
1544
+ return failed.length === 0;
1420
1545
  } catch (error) {
1421
- ui.toast.error(
1422
- error instanceof Error ? error.message : "A dokumentum létrehozása nem sikerült."
1423
- );
1546
+ ui.toast.error(error instanceof Error ? error.message : "A tömeges csomagkészítés nem sikerült.");
1547
+ return false;
1424
1548
  } finally {
1425
- setBusy(null);
1549
+ setLoading(null);
1426
1550
  }
1427
1551
  };
1428
- const updateDocument = async (document2, changes) => {
1429
- setBusy(`update:${document2.id}`);
1552
+ const labels = async (print = directPrint) => {
1553
+ if (!selected.length) {
1554
+ ui.toast.error("Jelölj ki legalább egy rendelést.");
1555
+ return;
1556
+ }
1557
+ setLoading("labels");
1430
1558
  try {
1431
- const response = await fetch(
1432
- apiUrl$b(`/admin/legal/documents/${document2.id}`),
1433
- {
1434
- method: "POST",
1435
- credentials: "include",
1436
- headers: { "Content-Type": "application/json" },
1437
- body: JSON.stringify(changes)
1438
- }
1439
- );
1440
- const payload = await response.json().catch(() => ({}));
1559
+ const response = await fetch(apiUrl$b("/admin/shipping/bulk/labels"), {
1560
+ method: "POST",
1561
+ credentials: "include",
1562
+ headers: { "Content-Type": "application/json" },
1563
+ body: JSON.stringify({ orderIds: selected, format })
1564
+ });
1441
1565
  if (!response.ok) {
1442
- throw new Error(payload.message || "A dokumentum mentése nem sikerült.");
1566
+ const data = await response.json().catch(() => ({}));
1567
+ throw new Error(data.message || "A közös PDF nem készíthető el.");
1443
1568
  }
1444
- await load();
1569
+ openPdf(await response.blob(), `shipping-labels-${format}.pdf`, print);
1445
1570
  } catch (error) {
1446
- ui.toast.error(
1447
- error instanceof Error ? error.message : "A dokumentum mentése nem sikerült."
1448
- );
1571
+ ui.toast.error(error instanceof Error ? error.message : "A közös PDF nem készíthető el.");
1449
1572
  } finally {
1450
- setBusy(null);
1573
+ setLoading(null);
1451
1574
  }
1452
1575
  };
1453
- const uploadNewVersion = async (document2, file) => {
1454
- setBusy(`version:${document2.id}`);
1576
+ const closeMpl = async () => {
1577
+ if (!selectedMplOrders.length) {
1578
+ ui.toast.error("Jelölj ki legalább egy MPL rendelést.");
1579
+ return;
1580
+ }
1581
+ setLoading("mpl-close");
1455
1582
  try {
1456
- const response = await fetch(
1457
- apiUrl$b(`/admin/legal/documents/${document2.id}/versions`),
1458
- {
1459
- method: "POST",
1460
- credentials: "include",
1461
- headers: { "Content-Type": "application/json" },
1462
- body: JSON.stringify({
1463
- fileBase64: await fileToBase64(file),
1464
- fileName: file.name
1465
- })
1466
- }
1467
- );
1468
- const payload = await response.json().catch(() => ({}));
1583
+ const response = await fetch(apiUrl$b("/admin/shipping/mpl/close"), {
1584
+ method: "POST",
1585
+ credentials: "include",
1586
+ headers: { "Content-Type": "application/json" },
1587
+ body: JSON.stringify({
1588
+ orderIds: selectedMplOrders.map((order) => order.id),
1589
+ checkList: true
1590
+ })
1591
+ });
1592
+ const data = await response.json().catch(() => ({}));
1469
1593
  if (!response.ok) {
1470
- throw new Error(payload.message || "Az új PDF-verzió mentése nem sikerült.");
1594
+ throw new Error(data.message || "Az MPL jegyzékzárás nem sikerült.");
1471
1595
  }
1472
- ui.toast.success(
1473
- payload.created ? "Új PDF-verzió elmentve." : "Ez a PDF-verzió már el volt mentve."
1474
- );
1596
+ ui.toast.success(`${data.trackingNumbers?.length ?? selectedMplOrders.length} MPL küldemény lezárva.`);
1475
1597
  await load();
1476
1598
  } catch (error) {
1477
- ui.toast.error(
1478
- error instanceof Error ? error.message : "Az új PDF-verzió mentése nem sikerült."
1479
- );
1599
+ ui.toast.error(error instanceof Error ? error.message : "Az MPL jegyzékzárás nem sikerült.");
1480
1600
  } finally {
1481
- setBusy(null);
1601
+ setLoading(null);
1482
1602
  }
1483
1603
  };
1484
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
1604
+ const createAndLabels = async () => {
1605
+ if (await create()) await labels();
1606
+ };
1607
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
1485
1608
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
1486
1609
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1487
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Jogi dokumentumok" }),
1488
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Feltöltött PDF-ek, verziók és checkout-elfogadások. A Fogyasztó Barát ettől külön, opcionális embed." })
1610
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Szállítás" }),
1611
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "FOXPOST, GLS, Packeta, DPD és MPL tömeges csomag- és címkekezelés." })
1489
1612
  ] }),
1490
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1491
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: `${adminBase$8}/settings/integrations`, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", children: "Fogyasztó Barát embed" }) }),
1492
- /* @__PURE__ */ jsxRuntime.jsx(
1493
- ui.Button,
1494
- {
1495
- variant: "secondary",
1496
- isLoading: loading,
1497
- onClick: () => void load(),
1498
- children: "Frissítés"
1499
- }
1500
- )
1613
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { children: [
1614
+ selected.length,
1615
+ " kijelölve"
1501
1616
  ] })
1502
1617
  ] }),
1503
- loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
1504
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "A jogi modul nem tölthető be." }),
1505
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
1506
- ] }) : null,
1507
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-4", children: [
1508
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Új PDF dokumentum" }),
1509
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Mindegy, honnan származik a PDF: a Core ugyanúgy verziózza és SHA-256 hash-sel rögzíti. Dokumentumonként külön állítható, hogy checkoutnál kötelező-e elfogadni." })
1510
- ] }),
1511
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
1512
- /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Dokumentum neve", children: /* @__PURE__ */ jsxRuntime.jsx(
1513
- ui.Input,
1618
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 border-b px-6 py-4", children: [
1619
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1620
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "FOXPOST csomagméret" }),
1621
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: packageSize, onValueChange: setPackageSize, children: [
1622
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Méret" }) }),
1623
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: ["XS", "S", "M", "L", "XL"].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item }, item)) })
1624
+ ] })
1625
+ ] }),
1626
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1627
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Címkeméret" }),
1628
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: format, onValueChange: setSavedFormat, children: [
1629
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-32", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Címkeméret" }) }),
1630
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: ["A6", "A7", "85X85"].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item === "85X85" ? "85×85" : item }, item)) })
1631
+ ] })
1632
+ ] }),
1633
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
1634
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: directPrint, onCheckedChange: setSavedPrint }),
1635
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Közvetlen nyomtatás" })
1636
+ ] }),
1637
+ /* @__PURE__ */ jsxRuntime.jsx(
1638
+ ui.Button,
1514
1639
  {
1515
- value: title,
1516
- onChange: (event) => setTitle(event.target.value),
1517
- placeholder: "Általános Szerződési Feltételek"
1640
+ isLoading: loading === "create",
1641
+ disabled: Boolean(loading),
1642
+ onClick: () => void create(),
1643
+ children: "Csomagok létrehozása"
1518
1644
  }
1519
- ) }),
1520
- /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Kulcs", children: /* @__PURE__ */ jsxRuntime.jsx(
1521
- ui.Input,
1645
+ ),
1646
+ /* @__PURE__ */ jsxRuntime.jsx(
1647
+ ui.Button,
1522
1648
  {
1523
- value: key,
1524
- onChange: (event) => setKey(event.target.value.toLowerCase()),
1525
- placeholder: "terms"
1649
+ variant: "secondary",
1650
+ isLoading: loading === "labels",
1651
+ disabled: Boolean(loading),
1652
+ onClick: () => void labels(false),
1653
+ children: "Közös PDF"
1526
1654
  }
1527
- ) }),
1528
- /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Típus", children: /* @__PURE__ */ jsxRuntime.jsxs(
1529
- "select",
1655
+ ),
1656
+ /* @__PURE__ */ jsxRuntime.jsxs(
1657
+ ui.Button,
1530
1658
  {
1531
- className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm",
1532
- value: kind,
1533
- onChange: (event) => setKind(event.target.value),
1659
+ variant: "secondary",
1660
+ disabled: Boolean(loading),
1661
+ onClick: () => void createAndLabels(),
1534
1662
  children: [
1535
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "terms", children: "ÁSZF" }),
1536
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "privacy", children: "Adatkezelési tájékoztató" }),
1537
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "withdrawal", children: "Elállási nyilatkozat" }),
1538
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "custom", children: "Egyedi nyilatkozat" })
1663
+ "Létrehozás + ",
1664
+ directPrint ? "nyomtatás" : "PDF"
1539
1665
  ]
1540
1666
  }
1541
- ) }),
1542
- /* @__PURE__ */ jsxRuntime.jsxs(Field$4, { label: "PDF fájl (max. 5 MB)", children: [
1543
- /* @__PURE__ */ jsxRuntime.jsx(
1544
- "input",
1545
- {
1546
- type: "file",
1547
- accept: "application/pdf,.pdf",
1548
- onChange: (event) => {
1549
- const file = event.target.files?.[0];
1550
- if (!file) return;
1551
- setFileName(file.name);
1552
- void fileToBase64(file).then(setFileBase64).catch((error) => {
1553
- ui.toast.error(
1554
- error instanceof Error ? error.message : "A PDF nem olvasható."
1555
- );
1556
- });
1557
- }
1558
- }
1559
- ),
1560
- fileName ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: fileName }) : null
1561
- ] }),
1562
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-6", children: [
1563
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
1564
- /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: enabled, onCheckedChange: setEnabled }),
1565
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Aktív" })
1566
- ] }),
1567
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
1568
- /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: required, onCheckedChange: setRequired }),
1569
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Checkoutnál kötelező elfogadni" })
1570
- ] })
1571
- ] }),
1572
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1667
+ ),
1668
+ /* @__PURE__ */ jsxRuntime.jsx(
1573
1669
  ui.Button,
1574
1670
  {
1575
- isLoading: busy === "create",
1576
- disabled: Boolean(busy),
1577
- onClick: () => void createDocument(),
1578
- children: "Dokumentum hozzáadása"
1671
+ variant: "secondary",
1672
+ isLoading: loading === "mpl-close",
1673
+ disabled: Boolean(loading) || !selectedMplOrders.length,
1674
+ onClick: () => void closeMpl(),
1675
+ children: "MPL jegyzék zárása"
1579
1676
  }
1580
- ) })
1677
+ )
1581
1678
  ] }),
1582
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto border-b", children: [
1679
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto", children: [
1583
1680
  /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
1584
1681
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1585
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Dokumentum" }),
1586
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Aktív" }),
1587
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Elfogadás" }),
1588
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Aktuális PDF" }),
1589
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Műveletek" })
1590
- ] }) }),
1591
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: documents.map((document2) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b align-top", children: [
1592
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
1593
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: document2.title }),
1594
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle", children: [
1595
- /* @__PURE__ */ jsxRuntime.jsx("code", { children: document2.key }),
1596
- " · ",
1597
- kindLabel(document2.kind)
1598
- ] })
1599
- ] }),
1600
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1601
- ui.Switch,
1682
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1683
+ ui.Checkbox,
1602
1684
  {
1603
- checked: document2.enabled,
1604
- disabled: Boolean(busy),
1605
- onCheckedChange: (value) => void updateDocument(document2, { enabled: value })
1685
+ checked: orders.length > 0 && selected.length === orders.length,
1686
+ onCheckedChange: () => setSelected(
1687
+ selected.length === orders.length ? [] : orders.map((order) => order.id)
1688
+ )
1606
1689
  }
1607
1690
  ) }),
1608
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1609
- /* @__PURE__ */ jsxRuntime.jsx(
1610
- ui.Switch,
1611
- {
1612
- checked: document2.requiredAtCheckout,
1613
- disabled: !document2.currentVersion || Boolean(busy),
1614
- onCheckedChange: (value) => void updateDocument(document2, {
1615
- requiredAtCheckout: value
1616
- })
1617
- }
1618
- ),
1619
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: document2.requiredAtCheckout ? "Kötelező" : "Nem kötelező" })
1620
- ] }) }),
1621
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: document2.currentVersion ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1622
- /* @__PURE__ */ jsxRuntime.jsx("code", { title: document2.currentVersion.sha256, children: shortHash(document2.currentVersion.sha256) }),
1623
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle", children: [
1624
- formatDate$4(document2.currentVersion.createdAt),
1625
- " ·",
1626
- " ",
1627
- formatBytes(document2.currentVersion.contentLength)
1628
- ] })
1629
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-error", children: "Nincs PDF-verzió" }) }),
1630
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-52 flex-wrap gap-2", children: [
1631
- document2.currentVersion ? /* @__PURE__ */ jsxRuntime.jsx(
1632
- "a",
1691
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Rendelés" }),
1692
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Szolgáltató" }),
1693
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Csomagazonosító" }),
1694
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Státusz" }),
1695
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Utolsó művelet" })
1696
+ ] }) }),
1697
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: orders.map((order) => {
1698
+ const shipment = order.metadata?.[order.carrier] || {};
1699
+ const last = order.operations?.at(-1);
1700
+ return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
1701
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1702
+ ui.Checkbox,
1633
1703
  {
1634
- href: apiUrl$b(
1635
- `/admin/legal/documents/${document2.id}/versions/${document2.currentVersion.id}/pdf`
1636
- ),
1637
- target: "_blank",
1638
- rel: "noreferrer",
1639
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "PDF" })
1704
+ checked: selectedSet.has(order.id),
1705
+ onCheckedChange: () => toggle(order.id)
1640
1706
  }
1641
- ) : null,
1642
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex cursor-pointer items-center rounded-md border px-2.5 py-1 text-xs font-medium", children: [
1643
- "Új PDF-verzió",
1644
- /* @__PURE__ */ jsxRuntime.jsx(
1645
- "input",
1646
- {
1647
- className: "hidden",
1648
- type: "file",
1649
- accept: "application/pdf,.pdf",
1650
- disabled: Boolean(busy),
1651
- onChange: (event) => {
1652
- const file = event.target.files?.[0];
1653
- if (file) void uploadNewVersion(document2, file);
1654
- event.currentTarget.value = "";
1655
- }
1656
- }
1657
- )
1658
- ] })
1659
- ] }) })
1660
- ] }, document2.id)) })
1707
+ ) }),
1708
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
1709
+ /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "text-blue-600", href: `${adminBase$7}/orders/${order.id}`, children: [
1710
+ "#",
1711
+ order.display_id ?? order.id
1712
+ ] }),
1713
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: order.email || "—" })
1714
+ ] }),
1715
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4 font-medium", children: carrierName(order.carrier) }),
1716
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
1717
+ String(
1718
+ shipment.trackingNumber || shipment.parcelNumber || shipment.packetId || shipment.packageId || shipment.shipmentId || "—"
1719
+ ),
1720
+ order.carrier === "mpl" && shipment.closedAt ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "jegyzék lezárva" }) : null
1721
+ ] }),
1722
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: String(shipment.status || "—") }),
1723
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: last ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: last.status === "failed" ? "text-red-600" : "text-green-700", children: last.message }) : "—" })
1724
+ ] }, order.id);
1725
+ }) })
1661
1726
  ] }),
1662
- !loading && !documents.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Még nincs feltöltött jogi dokumentum." }) }) : null
1663
- ] }),
1664
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-4", children: [
1665
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Legutóbbi elfogadások" }),
1666
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "A consent mindig a konkrét PDF-verzióhoz, kosárhoz és később a rendeléshez kapcsolódik." })
1667
- ] }),
1668
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
1669
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1670
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Elfogadva" }),
1671
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Dokumentum" }),
1672
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Rendelés" }),
1673
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Cart" }),
1674
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Verzió" })
1675
- ] }) }),
1676
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: consents.map((consent) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
1677
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: formatDate$4(consent.acceptedAt) }),
1678
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: consent.documentTitle }),
1679
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: consent.orderId ? /* @__PURE__ */ jsxRuntime.jsx(
1680
- "a",
1681
- {
1682
- className: "text-ui-fg-interactive",
1683
- href: `${adminBase$8}/orders/${consent.orderId}`,
1684
- children: consent.orderId
1685
- }
1686
- ) : "Még nincs rendelés" }),
1687
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: consent.cartId }) }),
1688
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: consent.documentVersionId }) })
1689
- ] }, consent.id)) })
1690
- ] }) })
1691
- ] }) });
1692
- };
1693
- function Field$4({
1694
- label,
1695
- children
1696
- }) {
1697
- return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
1698
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: label }),
1699
- children
1727
+ ordersLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Szállítási rendelések betöltése…" }) }) : null,
1728
+ !ordersLoading && loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 flex flex-wrap items-center justify-between gap-4 rounded-lg border border-ui-border-error bg-ui-bg-base p-4", children: [
1729
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1730
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "A szállítási lista nem tölthető be" }),
1731
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
1732
+ ] }),
1733
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => void load(), children: "Újrapróbálás" })
1734
+ ] }) : null,
1735
+ !ordersLoading && !loadError && !orders.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Nincs támogatott Core szállítású rendelés." }) }) : null
1736
+ ] })
1700
1737
  ] });
1738
+ };
1739
+ function carrierName(carrier) {
1740
+ if (carrier === "foxpost") return "FOXPOST";
1741
+ if (carrier === "gls") return "GLS";
1742
+ if (carrier === "packeta") return "Packeta";
1743
+ if (carrier === "dpd") return "DPD";
1744
+ return "MPL";
1701
1745
  }
1702
- function fileToBase64(file) {
1703
- if (file.size > 5 * 1024 * 1024) {
1704
- return Promise.reject(new Error("A PDF legfeljebb 5 MB lehet."));
1746
+ function openPdf(blob, filename, print) {
1747
+ const url = URL.createObjectURL(blob);
1748
+ if (print) {
1749
+ const frame = document.createElement("iframe");
1750
+ frame.style.display = "none";
1751
+ frame.src = url;
1752
+ frame.onload = () => {
1753
+ frame.contentWindow?.print();
1754
+ setTimeout(() => {
1755
+ frame.remove();
1756
+ URL.revokeObjectURL(url);
1757
+ }, 6e4);
1758
+ };
1759
+ document.body.appendChild(frame);
1760
+ } else {
1761
+ const link = document.createElement("a");
1762
+ link.href = url;
1763
+ link.download = filename;
1764
+ link.click();
1765
+ setTimeout(() => URL.revokeObjectURL(url), 1e4);
1705
1766
  }
1706
- return new Promise((resolve, reject) => {
1707
- const reader = new FileReader();
1708
- reader.onload = () => resolve(String(reader.result || ""));
1709
- reader.onerror = () => reject(new Error("A PDF fájl nem olvasható."));
1710
- reader.readAsDataURL(file);
1711
- });
1712
- }
1713
- function kindLabel(value) {
1714
- return value === "terms" ? "ÁSZF" : value === "privacy" ? "Adatkezelés" : value === "withdrawal" ? "Elállás" : "Egyedi";
1715
- }
1716
- function shortHash(value) {
1717
- return value.length > 20 ? `${value.slice(0, 12)}…${value.slice(-8)}` : value;
1718
1767
  }
1719
- function formatBytes(value) {
1720
- if (!Number.isFinite(value)) return "—";
1721
- if (value < 1024) return `${value} B`;
1722
- if (value < 1024 * 1024) return `${Math.round(value / 1024)} kB`;
1723
- return `${(value / 1024 / 1024).toFixed(2)} MB`;
1724
- }
1725
- function formatDate$4(value) {
1726
- if (!value) return "—";
1727
- const date = new Date(value);
1728
- if (Number.isNaN(date.getTime())) return "—";
1729
- return new Intl.DateTimeFormat("hu-HU", {
1730
- dateStyle: "short",
1731
- timeStyle: "short"
1732
- }).format(date);
1733
- }
1734
- const config$b = adminSdk.defineRouteConfig({
1735
- label: "Jogi dokumentumok",
1736
- icon: Newspaper,
1737
- rank: 40
1768
+ const config$a = adminSdk.defineRouteConfig({
1769
+ label: "Szállítás",
1770
+ icon: TruckFast,
1771
+ rank: 35
1738
1772
  });
1773
+ const adminBase$6 = (__BASE__ || "/app").replace(/\/+$/, "");
1774
+ const links = [
1775
+ { label: "Production readiness", description: "Élesítési blokkolók: infrastruktúra, commerce, security, legal, e-mail és SEO.", href: `${adminBase$6}/system-monitoring/readiness` },
1776
+ { label: "Integrációs műveletek", description: "Retry, reconciliation és külső API műveletek kezelése.", href: `${adminBase$6}/system-monitoring/operations` },
1777
+ { label: "Integrációk állapota", description: "Provider állapotok, konfigurációk és hibák áttekintése.", href: `${adminBase$6}/system-monitoring/health` },
1778
+ { label: "Audit napló", description: "Core és integrációs admin események visszakeresése.", href: `${adminBase$6}/system-monitoring/audit` }
1779
+ ];
1780
+ const SystemMonitoringPage = () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
1781
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-5", children: [
1782
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Rendszerfelügyelet" }),
1783
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Technikai állapotok, élesítési feltételek, külső műveletek és audit események." })
1784
+ ] }),
1785
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 p-6 md:grid-cols-2 xl:grid-cols-4", children: links.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.href, className: "rounded-lg border p-5 hover:bg-ui-bg-subtle", children: [
1786
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: item.label }),
1787
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: item.description })
1788
+ ] }, item.href)) })
1789
+ ] });
1790
+ const config$9 = adminSdk.defineRouteConfig({ label: "Rendszerfelügyelet" });
1739
1791
  const backendUrl$a = (__BACKEND_URL__ || "").replace(/\/+$/, "");
1740
- const adminBase$7 = (__BASE__ || "/app").replace(/\/+$/, "");
1792
+ const adminBase$5 = (__BASE__ || "/app").replace(/\/+$/, "");
1741
1793
  function apiUrl$a(path) {
1742
1794
  return `${backendUrl$a}${path.startsWith("/") ? path : `/${path}`}`;
1743
1795
  }
@@ -1900,7 +1952,7 @@ const BillingPage = () => {
1900
1952
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
1901
1953
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1902
1954
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Számlázás" }),
1903
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Billingo számlák, sztornók és teljes jóváírások kezelése a Medusa rendeléseiből." }),
1955
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Billingo számlák, sztornók és teljes jóváírások kezelése a HSZRDM Commerce rendeléseiből." }),
1904
1956
  configuration?.autoInvoice ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
1905
1957
  "Az automatikus számlázás aktív",
1906
1958
  configuration.autoSend ? ", automatikus e-mail küldéssel" : "",
@@ -2005,7 +2057,7 @@ const BillingPage = () => {
2005
2057
  "a",
2006
2058
  {
2007
2059
  className: "text-ui-fg-interactive",
2008
- href: `${adminBase$7}/orders/${order.id}`,
2060
+ href: `${adminBase$5}/orders/${order.id}`,
2009
2061
  children: [
2010
2062
  "#",
2011
2063
  order.display_id ?? order.id
@@ -2123,385 +2175,415 @@ function formatMoney(value, currency) {
2123
2175
  maximumFractionDigits: currency?.toUpperCase() === "HUF" ? 0 : 2
2124
2176
  }).format(value);
2125
2177
  }
2126
- const config$a = adminSdk.defineRouteConfig({
2178
+ const config$8 = adminSdk.defineRouteConfig({
2127
2179
  label: "Számlázás",
2128
2180
  icon: Newspaper,
2129
2181
  rank: 36
2130
2182
  });
2131
- const adminBase$6 = (__BASE__ || "/app").replace(/\/+$/, "");
2132
- const links$1 = [
2133
- {
2134
- label: "Analitika",
2135
- description: "Látogatók, vásárlási tölcsér, bevétel, vásárlók, top termékek és checkout állapot egy közös dashboardon.",
2136
- href: `${adminBase$6}/analytics`
2137
- },
2138
- {
2139
- label: "SEO",
2140
- description: "Termék-, kategória- és oldal SEO title, description, canonical, robots és Open Graph kezelése.",
2141
- href: `${adminBase$6}/marketing/seo`
2142
- },
2143
- {
2144
- label: "SEO átirányítások",
2145
- description: "Régi URL-ek 301/308 átirányítása, be/ki kapcsolás és query paraméter kezelés.",
2146
- href: `${adminBase$6}/marketing/seo/redirects`
2147
- },
2148
- {
2149
- label: "Google Merchant",
2150
- description: "Google Merchant Center termékfeed előnézet, diagnosztika és publikus feed URL.",
2151
- href: `${adminBase$6}/marketing/google-merchant`
2152
- },
2153
- {
2154
- label: "Árukereső",
2155
- description: "Árukereső.hu XML feed előnézet, diagnosztika és publikus feed URL.",
2156
- href: `${adminBase$6}/marketing/arukereso`
2157
- }
2158
- ];
2159
- const MarketingPage = () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
2160
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-5", children: [
2161
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Marketing" }),
2162
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Analitika, SEO, termékfeedek és külső marketing/értékesítési csatornák kezelése. Az integrációk technikai alapbeállításai a Settings → Integrációk alatt találhatók." })
2163
- ] }),
2164
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 p-6 md:grid-cols-2 xl:grid-cols-3", children: links$1.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
2165
- "a",
2166
- {
2167
- href: item.href,
2168
- className: "rounded-lg border p-5 transition-colors hover:bg-ui-bg-subtle",
2169
- children: [
2170
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: item.label }),
2171
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: item.description })
2172
- ]
2173
- },
2174
- item.href
2175
- )) })
2176
- ] });
2177
- const config$9 = adminSdk.defineRouteConfig({ label: "Marketing" });
2178
- const LABEL_FORMAT_STORAGE_KEY = "core.shipping.labelFormat";
2179
- const DIRECT_PRINT_STORAGE_KEY = "core.shipping.directPrint";
2180
2183
  const backendUrl$9 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
2181
- const adminBase$5 = (__BASE__ || "/app").replace(/\/+$/, "");
2182
- function apiUrl$9(path) {
2183
- return `${backendUrl$9}${path.startsWith("/") ? path : `/${path}`}`;
2184
- }
2185
- const ShippingPage = () => {
2186
- const [orders, setOrders] = React.useState([]);
2187
- const [selected, setSelected] = React.useState([]);
2188
- const [format, setFormat] = React.useState("A6");
2189
- const [packageSize, setPackageSize] = React.useState("M");
2190
- const [directPrint, setDirectPrint] = React.useState(false);
2191
- const [loading, setLoading] = React.useState(null);
2192
- const [ordersLoading, setOrdersLoading] = React.useState(true);
2184
+ const adminBase$4 = (__BASE__ || "/app").replace(/\/+$/, "");
2185
+ const apiUrl$9 = (path) => `${backendUrl$9}${path.startsWith("/") ? path : `/${path}`}`;
2186
+ const LegalPage = () => {
2187
+ const [documents, setDocuments] = React.useState([]);
2188
+ const [consents, setConsents] = React.useState([]);
2189
+ const [loading, setLoading] = React.useState(true);
2190
+ const [busy, setBusy] = React.useState(null);
2193
2191
  const [loadError, setLoadError] = React.useState(null);
2194
- const selectedSet = React.useMemo(() => new Set(selected), [selected]);
2195
- const selectedMplOrders = React.useMemo(
2196
- () => orders.filter((order) => selectedSet.has(order.id) && order.carrier === "mpl"),
2197
- [orders, selectedSet]
2198
- );
2192
+ const [title, setTitle] = React.useState("");
2193
+ const [key, setKey] = React.useState("");
2194
+ const [kind, setKind] = React.useState("custom");
2195
+ const [fileName, setFileName] = React.useState("");
2196
+ const [fileBase64, setFileBase64] = React.useState("");
2197
+ const [enabled, setEnabled] = React.useState(true);
2198
+ const [required, setRequired] = React.useState(false);
2199
2199
  const load = React.useCallback(async () => {
2200
- setOrdersLoading(true);
2200
+ setLoading(true);
2201
2201
  setLoadError(null);
2202
2202
  try {
2203
- const response = await fetch(apiUrl$9("/admin/shipping/orders"), {
2204
- credentials: "include"
2205
- });
2206
- const data = await response.json().catch(() => ({}));
2207
- if (!response.ok) {
2208
- throw new Error(data.message || "A szállítási rendelések betöltése nem sikerült.");
2203
+ const [documentsResponse, consentsResponse] = await Promise.all([
2204
+ fetch(apiUrl$9("/admin/legal/documents"), { credentials: "include" }),
2205
+ fetch(apiUrl$9("/admin/legal/consents"), { credentials: "include" })
2206
+ ]);
2207
+ const documentsPayload = await documentsResponse.json().catch(() => ({}));
2208
+ const consentsPayload = await consentsResponse.json().catch(() => ({}));
2209
+ if (!documentsResponse.ok) {
2210
+ throw new Error(
2211
+ documentsPayload.message || "A jogi dokumentumok nem tölthetők be."
2212
+ );
2209
2213
  }
2210
- const nextOrders = data.orders || [];
2211
- setOrders(nextOrders);
2212
- setSelected((current) => current.filter((id) => nextOrders.some((order) => order.id === id)));
2214
+ if (!consentsResponse.ok) {
2215
+ throw new Error(
2216
+ consentsPayload.message || "Az elfogadások nem tölthetők be."
2217
+ );
2218
+ }
2219
+ setDocuments(documentsPayload.documents || []);
2220
+ setConsents(consentsPayload.consents || []);
2213
2221
  } catch (error) {
2214
- const message = error instanceof Error ? error.message : "A szállítási rendelések betöltése nem sikerült.";
2215
- setOrders([]);
2216
- setLoadError(message);
2222
+ setLoadError(
2223
+ error instanceof Error ? error.message : "A jogi dokumentumok nem tölthetők be."
2224
+ );
2217
2225
  } finally {
2218
- setOrdersLoading(false);
2226
+ setLoading(false);
2219
2227
  }
2220
2228
  }, []);
2221
2229
  React.useEffect(() => {
2222
- setFormat(localStorage.getItem(LABEL_FORMAT_STORAGE_KEY) || "A6");
2223
- setDirectPrint(localStorage.getItem(DIRECT_PRINT_STORAGE_KEY) === "true");
2224
2230
  void load();
2225
2231
  }, [load]);
2226
- const setSavedFormat = (value) => {
2227
- setFormat(value);
2228
- localStorage.setItem(LABEL_FORMAT_STORAGE_KEY, value);
2229
- };
2230
- const setSavedPrint = (value) => {
2231
- setDirectPrint(value);
2232
- localStorage.setItem(DIRECT_PRINT_STORAGE_KEY, String(value));
2233
- };
2234
- const toggle = (id) => {
2235
- setSelected((current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id]);
2236
- };
2237
- const create = async () => {
2238
- if (!selected.length) {
2239
- ui.toast.error("Jelölj ki legalább egy rendelést.");
2240
- return false;
2241
- }
2242
- setLoading("create");
2232
+ const createDocument = async () => {
2233
+ setBusy("create");
2243
2234
  try {
2244
- const response = await fetch(apiUrl$9("/admin/shipping/bulk/create"), {
2235
+ if (!title.trim() || !key.trim()) {
2236
+ throw new Error("A név és a kulcs kötelező.");
2237
+ }
2238
+ if (!fileBase64) throw new Error("Válassz PDF fájlt.");
2239
+ const response = await fetch(apiUrl$9("/admin/legal/documents"), {
2245
2240
  method: "POST",
2246
2241
  credentials: "include",
2247
2242
  headers: { "Content-Type": "application/json" },
2248
- body: JSON.stringify({ orderIds: selected, packageSize })
2249
- });
2250
- const data = await response.json().catch(() => ({}));
2251
- if (!response.ok && response.status !== 207) {
2252
- throw new Error(data.message || "A tömeges csomagkészítés nem sikerült.");
2253
- }
2254
- const failed = data.results?.filter((item) => !item.ok) || [];
2255
- if (failed.length) ui.toast.error(`${failed.length} csomag nem készült el.`);
2256
- else ui.toast.success(`${selected.length} csomag elkészült.`);
2243
+ body: JSON.stringify({
2244
+ title,
2245
+ key,
2246
+ kind,
2247
+ fileBase64,
2248
+ fileName,
2249
+ enabled,
2250
+ requiredAtCheckout: required
2251
+ })
2252
+ });
2253
+ const payload = await response.json().catch(() => ({}));
2254
+ if (!response.ok) {
2255
+ throw new Error(
2256
+ payload.message || "A dokumentum létrehozása nem sikerült."
2257
+ );
2258
+ }
2259
+ ui.toast.success("Jogi PDF létrehozva és verziózva.");
2260
+ setTitle("");
2261
+ setKey("");
2262
+ setKind("custom");
2263
+ setFileName("");
2264
+ setFileBase64("");
2265
+ setEnabled(true);
2266
+ setRequired(false);
2257
2267
  await load();
2258
- return failed.length === 0;
2259
2268
  } catch (error) {
2260
- ui.toast.error(error instanceof Error ? error.message : "A tömeges csomagkészítés nem sikerült.");
2261
- return false;
2269
+ ui.toast.error(
2270
+ error instanceof Error ? error.message : "A dokumentum létrehozása nem sikerült."
2271
+ );
2262
2272
  } finally {
2263
- setLoading(null);
2273
+ setBusy(null);
2264
2274
  }
2265
2275
  };
2266
- const labels = async (print = directPrint) => {
2267
- if (!selected.length) {
2268
- ui.toast.error("Jelölj ki legalább egy rendelést.");
2269
- return;
2270
- }
2271
- setLoading("labels");
2276
+ const updateDocument = async (document2, changes) => {
2277
+ setBusy(`update:${document2.id}`);
2272
2278
  try {
2273
- const response = await fetch(apiUrl$9("/admin/shipping/bulk/labels"), {
2274
- method: "POST",
2275
- credentials: "include",
2276
- headers: { "Content-Type": "application/json" },
2277
- body: JSON.stringify({ orderIds: selected, format })
2278
- });
2279
+ const response = await fetch(
2280
+ apiUrl$9(`/admin/legal/documents/${document2.id}`),
2281
+ {
2282
+ method: "POST",
2283
+ credentials: "include",
2284
+ headers: { "Content-Type": "application/json" },
2285
+ body: JSON.stringify(changes)
2286
+ }
2287
+ );
2288
+ const payload = await response.json().catch(() => ({}));
2279
2289
  if (!response.ok) {
2280
- const data = await response.json().catch(() => ({}));
2281
- throw new Error(data.message || "A közös PDF nem készíthető el.");
2290
+ throw new Error(payload.message || "A dokumentum mentése nem sikerült.");
2282
2291
  }
2283
- openPdf(await response.blob(), `shipping-labels-${format}.pdf`, print);
2292
+ await load();
2284
2293
  } catch (error) {
2285
- ui.toast.error(error instanceof Error ? error.message : "A közös PDF nem készíthető el.");
2294
+ ui.toast.error(
2295
+ error instanceof Error ? error.message : "A dokumentum mentése nem sikerült."
2296
+ );
2286
2297
  } finally {
2287
- setLoading(null);
2298
+ setBusy(null);
2288
2299
  }
2289
2300
  };
2290
- const closeMpl = async () => {
2291
- if (!selectedMplOrders.length) {
2292
- ui.toast.error("Jelölj ki legalább egy MPL rendelést.");
2293
- return;
2294
- }
2295
- setLoading("mpl-close");
2301
+ const uploadNewVersion = async (document2, file) => {
2302
+ setBusy(`version:${document2.id}`);
2296
2303
  try {
2297
- const response = await fetch(apiUrl$9("/admin/shipping/mpl/close"), {
2298
- method: "POST",
2299
- credentials: "include",
2300
- headers: { "Content-Type": "application/json" },
2301
- body: JSON.stringify({
2302
- orderIds: selectedMplOrders.map((order) => order.id),
2303
- checkList: true
2304
- })
2305
- });
2306
- const data = await response.json().catch(() => ({}));
2304
+ const response = await fetch(
2305
+ apiUrl$9(`/admin/legal/documents/${document2.id}/versions`),
2306
+ {
2307
+ method: "POST",
2308
+ credentials: "include",
2309
+ headers: { "Content-Type": "application/json" },
2310
+ body: JSON.stringify({
2311
+ fileBase64: await fileToBase64(file),
2312
+ fileName: file.name
2313
+ })
2314
+ }
2315
+ );
2316
+ const payload = await response.json().catch(() => ({}));
2307
2317
  if (!response.ok) {
2308
- throw new Error(data.message || "Az MPL jegyzékzárás nem sikerült.");
2318
+ throw new Error(payload.message || "Az új PDF-verzió mentése nem sikerült.");
2309
2319
  }
2310
- ui.toast.success(`${data.trackingNumbers?.length ?? selectedMplOrders.length} MPL küldemény lezárva.`);
2320
+ ui.toast.success(
2321
+ payload.created ? "Új PDF-verzió elmentve." : "Ez a PDF-verzió már el volt mentve."
2322
+ );
2311
2323
  await load();
2312
2324
  } catch (error) {
2313
- ui.toast.error(error instanceof Error ? error.message : "Az MPL jegyzékzárás nem sikerült.");
2325
+ ui.toast.error(
2326
+ error instanceof Error ? error.message : "Az új PDF-verzió mentése nem sikerült."
2327
+ );
2314
2328
  } finally {
2315
- setLoading(null);
2329
+ setBusy(null);
2316
2330
  }
2317
2331
  };
2318
- const createAndLabels = async () => {
2319
- if (await create()) await labels();
2320
- };
2321
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
2332
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
2322
2333
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
2323
2334
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2324
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Szállítás" }),
2325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "FOXPOST, GLS, Packeta, DPD és MPL tömeges csomag- és címkekezelés." })
2335
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Jogi dokumentumok" }),
2336
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Feltöltött PDF-ek, verziók és checkout-elfogadások. A Fogyasztó Barát ettől külön, opcionális embed." })
2326
2337
  ] }),
2327
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { children: [
2328
- selected.length,
2329
- " kijelölve"
2338
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2339
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: `${adminBase$4}/settings/integrations`, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", children: "Fogyasztó Barát embed" }) }),
2340
+ /* @__PURE__ */ jsxRuntime.jsx(
2341
+ ui.Button,
2342
+ {
2343
+ variant: "secondary",
2344
+ isLoading: loading,
2345
+ onClick: () => void load(),
2346
+ children: "Frissítés"
2347
+ }
2348
+ )
2330
2349
  ] })
2331
2350
  ] }),
2332
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 border-b px-6 py-4", children: [
2333
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2334
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "FOXPOST csomagméret" }),
2335
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: packageSize, onValueChange: setPackageSize, children: [
2336
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Méret" }) }),
2337
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: ["XS", "S", "M", "L", "XL"].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item }, item)) })
2338
- ] })
2339
- ] }),
2340
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2341
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Címkeméret" }),
2342
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: format, onValueChange: setSavedFormat, children: [
2343
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-32", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Címkeméret" }) }),
2344
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: ["A6", "A7", "85X85"].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item === "85X85" ? "85×85" : item }, item)) })
2345
- ] })
2346
- ] }),
2347
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
2348
- /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: directPrint, onCheckedChange: setSavedPrint }),
2349
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Közvetlen nyomtatás" })
2350
- ] }),
2351
- /* @__PURE__ */ jsxRuntime.jsx(
2352
- ui.Button,
2351
+ loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
2352
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "A jogi modul nem tölthető be." }),
2353
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
2354
+ ] }) : null,
2355
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-4", children: [
2356
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Új PDF dokumentum" }),
2357
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Mindegy, honnan származik a PDF: a Core ugyanúgy verziózza és SHA-256 hash-sel rögzíti. Dokumentumonként külön állítható, hogy checkoutnál kötelező-e elfogadni." })
2358
+ ] }),
2359
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
2360
+ /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Dokumentum neve", children: /* @__PURE__ */ jsxRuntime.jsx(
2361
+ ui.Input,
2353
2362
  {
2354
- isLoading: loading === "create",
2355
- disabled: Boolean(loading),
2356
- onClick: () => void create(),
2357
- children: "Csomagok létrehozása"
2363
+ value: title,
2364
+ onChange: (event) => setTitle(event.target.value),
2365
+ placeholder: "Általános Szerződési Feltételek"
2358
2366
  }
2359
- ),
2360
- /* @__PURE__ */ jsxRuntime.jsx(
2361
- ui.Button,
2367
+ ) }),
2368
+ /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Kulcs", children: /* @__PURE__ */ jsxRuntime.jsx(
2369
+ ui.Input,
2362
2370
  {
2363
- variant: "secondary",
2364
- isLoading: loading === "labels",
2365
- disabled: Boolean(loading),
2366
- onClick: () => void labels(false),
2367
- children: "Közös PDF"
2371
+ value: key,
2372
+ onChange: (event) => setKey(event.target.value.toLowerCase()),
2373
+ placeholder: "terms"
2368
2374
  }
2369
- ),
2370
- /* @__PURE__ */ jsxRuntime.jsxs(
2371
- ui.Button,
2375
+ ) }),
2376
+ /* @__PURE__ */ jsxRuntime.jsx(Field$4, { label: "Típus", children: /* @__PURE__ */ jsxRuntime.jsxs(
2377
+ "select",
2372
2378
  {
2373
- variant: "secondary",
2374
- disabled: Boolean(loading),
2375
- onClick: () => void createAndLabels(),
2379
+ className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm",
2380
+ value: kind,
2381
+ onChange: (event) => setKind(event.target.value),
2376
2382
  children: [
2377
- "Létrehozás + ",
2378
- directPrint ? "nyomtatás" : "PDF"
2383
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "terms", children: "ÁSZF" }),
2384
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "privacy", children: "Adatkezelési tájékoztató" }),
2385
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "withdrawal", children: "Elállási nyilatkozat" }),
2386
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "custom", children: "Egyedi nyilatkozat" })
2379
2387
  ]
2380
2388
  }
2381
- ),
2382
- /* @__PURE__ */ jsxRuntime.jsx(
2389
+ ) }),
2390
+ /* @__PURE__ */ jsxRuntime.jsxs(Field$4, { label: "PDF fájl (max. 5 MB)", children: [
2391
+ /* @__PURE__ */ jsxRuntime.jsx(
2392
+ "input",
2393
+ {
2394
+ type: "file",
2395
+ accept: "application/pdf,.pdf",
2396
+ onChange: (event) => {
2397
+ const file = event.target.files?.[0];
2398
+ if (!file) return;
2399
+ setFileName(file.name);
2400
+ void fileToBase64(file).then(setFileBase64).catch((error) => {
2401
+ ui.toast.error(
2402
+ error instanceof Error ? error.message : "A PDF nem olvasható."
2403
+ );
2404
+ });
2405
+ }
2406
+ }
2407
+ ),
2408
+ fileName ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: fileName }) : null
2409
+ ] }),
2410
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-6", children: [
2411
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
2412
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: enabled, onCheckedChange: setEnabled }),
2413
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Aktív" })
2414
+ ] }),
2415
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
2416
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: required, onCheckedChange: setRequired }),
2417
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Checkoutnál kötelező elfogadni" })
2418
+ ] })
2419
+ ] }),
2420
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
2383
2421
  ui.Button,
2384
2422
  {
2385
- variant: "secondary",
2386
- isLoading: loading === "mpl-close",
2387
- disabled: Boolean(loading) || !selectedMplOrders.length,
2388
- onClick: () => void closeMpl(),
2389
- children: "MPL jegyzék zárása"
2423
+ isLoading: busy === "create",
2424
+ disabled: Boolean(busy),
2425
+ onClick: () => void createDocument(),
2426
+ children: "Dokumentum hozzáadása"
2390
2427
  }
2391
- )
2428
+ ) })
2392
2429
  ] }),
2393
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto", children: [
2430
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto border-b", children: [
2394
2431
  /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
2395
2432
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2396
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2397
- ui.Checkbox,
2433
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Dokumentum" }),
2434
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Aktív" }),
2435
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Elfogadás" }),
2436
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Aktuális PDF" }),
2437
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Műveletek" })
2438
+ ] }) }),
2439
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: documents.map((document2) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b align-top", children: [
2440
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
2441
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: document2.title }),
2442
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle", children: [
2443
+ /* @__PURE__ */ jsxRuntime.jsx("code", { children: document2.key }),
2444
+ " · ",
2445
+ kindLabel(document2.kind)
2446
+ ] })
2447
+ ] }),
2448
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2449
+ ui.Switch,
2398
2450
  {
2399
- checked: orders.length > 0 && selected.length === orders.length,
2400
- onCheckedChange: () => setSelected(
2401
- selected.length === orders.length ? [] : orders.map((order) => order.id)
2402
- )
2451
+ checked: document2.enabled,
2452
+ disabled: Boolean(busy),
2453
+ onCheckedChange: (value) => void updateDocument(document2, { enabled: value })
2403
2454
  }
2404
2455
  ) }),
2405
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Rendelés" }),
2406
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Szolgáltató" }),
2407
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Csomagazonosító" }),
2408
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Státusz" }),
2409
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Utolsó művelet" })
2410
- ] }) }),
2411
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: orders.map((order) => {
2412
- const shipment = order.metadata?.[order.carrier] || {};
2413
- const last = order.operations?.at(-1);
2414
- return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
2415
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2416
- ui.Checkbox,
2456
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2457
+ /* @__PURE__ */ jsxRuntime.jsx(
2458
+ ui.Switch,
2417
2459
  {
2418
- checked: selectedSet.has(order.id),
2419
- onCheckedChange: () => toggle(order.id)
2460
+ checked: document2.requiredAtCheckout,
2461
+ disabled: !document2.currentVersion || Boolean(busy),
2462
+ onCheckedChange: (value) => void updateDocument(document2, {
2463
+ requiredAtCheckout: value
2464
+ })
2420
2465
  }
2421
- ) }),
2422
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
2423
- /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "text-blue-600", href: `${adminBase$5}/orders/${order.id}`, children: [
2424
- "#",
2425
- order.display_id ?? order.id
2426
- ] }),
2427
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: order.email || "—" })
2428
- ] }),
2429
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4 font-medium", children: carrierName(order.carrier) }),
2430
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
2431
- String(
2432
- shipment.trackingNumber || shipment.parcelNumber || shipment.packetId || shipment.packageId || shipment.shipmentId || "—"
2433
- ),
2434
- order.carrier === "mpl" && shipment.closedAt ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "jegyzék lezárva" }) : null
2435
- ] }),
2436
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: String(shipment.status || "—") }),
2437
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: last ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: last.status === "failed" ? "text-red-600" : "text-green-700", children: last.message }) : "—" })
2438
- ] }, order.id);
2439
- }) })
2466
+ ),
2467
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: document2.requiredAtCheckout ? "Kötelező" : "Nem kötelező" })
2468
+ ] }) }),
2469
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: document2.currentVersion ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2470
+ /* @__PURE__ */ jsxRuntime.jsx("code", { title: document2.currentVersion.sha256, children: shortHash(document2.currentVersion.sha256) }),
2471
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle", children: [
2472
+ formatDate$4(document2.currentVersion.createdAt),
2473
+ " ·",
2474
+ " ",
2475
+ formatBytes(document2.currentVersion.contentLength)
2476
+ ] })
2477
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-error", children: "Nincs PDF-verzió" }) }),
2478
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-52 flex-wrap gap-2", children: [
2479
+ document2.currentVersion ? /* @__PURE__ */ jsxRuntime.jsx(
2480
+ "a",
2481
+ {
2482
+ href: apiUrl$9(
2483
+ `/admin/legal/documents/${document2.id}/versions/${document2.currentVersion.id}/pdf`
2484
+ ),
2485
+ target: "_blank",
2486
+ rel: "noreferrer",
2487
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "PDF" })
2488
+ }
2489
+ ) : null,
2490
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex cursor-pointer items-center rounded-md border px-2.5 py-1 text-xs font-medium", children: [
2491
+ "Új PDF-verzió",
2492
+ /* @__PURE__ */ jsxRuntime.jsx(
2493
+ "input",
2494
+ {
2495
+ className: "hidden",
2496
+ type: "file",
2497
+ accept: "application/pdf,.pdf",
2498
+ disabled: Boolean(busy),
2499
+ onChange: (event) => {
2500
+ const file = event.target.files?.[0];
2501
+ if (file) void uploadNewVersion(document2, file);
2502
+ event.currentTarget.value = "";
2503
+ }
2504
+ }
2505
+ )
2506
+ ] })
2507
+ ] }) })
2508
+ ] }, document2.id)) })
2440
2509
  ] }),
2441
- ordersLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Szállítási rendelések betöltése…" }) }) : null,
2442
- !ordersLoading && loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 flex flex-wrap items-center justify-between gap-4 rounded-lg border border-ui-border-error bg-ui-bg-base p-4", children: [
2443
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2444
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "A szállítási lista nem tölthető be" }),
2445
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
2446
- ] }),
2447
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => void load(), children: "Újrapróbálás" })
2448
- ] }) : null,
2449
- !ordersLoading && !loadError && !orders.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Nincs támogatott Core szállítású rendelés." }) }) : null
2450
- ] })
2451
- ] });
2510
+ !loading && !documents.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Még nincs feltöltött jogi dokumentum." }) }) : null
2511
+ ] }),
2512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-4", children: [
2513
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Legutóbbi elfogadások" }),
2514
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "A consent mindig a konkrét PDF-verzióhoz, kosárhoz és később a rendeléshez kapcsolódik." })
2515
+ ] }),
2516
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
2517
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2518
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Elfogadva" }),
2519
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Dokumentum" }),
2520
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Rendelés" }),
2521
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Cart" }),
2522
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Verzió" })
2523
+ ] }) }),
2524
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: consents.map((consent) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
2525
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: formatDate$4(consent.acceptedAt) }),
2526
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: consent.documentTitle }),
2527
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: consent.orderId ? /* @__PURE__ */ jsxRuntime.jsx(
2528
+ "a",
2529
+ {
2530
+ className: "text-ui-fg-interactive",
2531
+ href: `${adminBase$4}/orders/${consent.orderId}`,
2532
+ children: consent.orderId
2533
+ }
2534
+ ) : "Még nincs rendelés" }),
2535
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: consent.cartId }) }),
2536
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: consent.documentVersionId }) })
2537
+ ] }, consent.id)) })
2538
+ ] }) })
2539
+ ] }) });
2452
2540
  };
2453
- function carrierName(carrier) {
2454
- if (carrier === "foxpost") return "FOXPOST";
2455
- if (carrier === "gls") return "GLS";
2456
- if (carrier === "packeta") return "Packeta";
2457
- if (carrier === "dpd") return "DPD";
2458
- return "MPL";
2541
+ function Field$4({
2542
+ label,
2543
+ children
2544
+ }) {
2545
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
2546
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: label }),
2547
+ children
2548
+ ] });
2459
2549
  }
2460
- function openPdf(blob, filename, print) {
2461
- const url = URL.createObjectURL(blob);
2462
- if (print) {
2463
- const frame = document.createElement("iframe");
2464
- frame.style.display = "none";
2465
- frame.src = url;
2466
- frame.onload = () => {
2467
- frame.contentWindow?.print();
2468
- setTimeout(() => {
2469
- frame.remove();
2470
- URL.revokeObjectURL(url);
2471
- }, 6e4);
2472
- };
2473
- document.body.appendChild(frame);
2474
- } else {
2475
- const link = document.createElement("a");
2476
- link.href = url;
2477
- link.download = filename;
2478
- link.click();
2479
- setTimeout(() => URL.revokeObjectURL(url), 1e4);
2550
+ function fileToBase64(file) {
2551
+ if (file.size > 5 * 1024 * 1024) {
2552
+ return Promise.reject(new Error("A PDF legfeljebb 5 MB lehet."));
2480
2553
  }
2554
+ return new Promise((resolve, reject) => {
2555
+ const reader = new FileReader();
2556
+ reader.onload = () => resolve(String(reader.result || ""));
2557
+ reader.onerror = () => reject(new Error("A PDF fájl nem olvasható."));
2558
+ reader.readAsDataURL(file);
2559
+ });
2481
2560
  }
2482
- const config$8 = adminSdk.defineRouteConfig({
2483
- label: "Szállítás",
2484
- icon: TruckFast,
2485
- rank: 35
2561
+ function kindLabel(value) {
2562
+ return value === "terms" ? "ÁSZF" : value === "privacy" ? "Adatkezelés" : value === "withdrawal" ? "Elállás" : "Egyedi";
2563
+ }
2564
+ function shortHash(value) {
2565
+ return value.length > 20 ? `${value.slice(0, 12)}…${value.slice(-8)}` : value;
2566
+ }
2567
+ function formatBytes(value) {
2568
+ if (!Number.isFinite(value)) return "—";
2569
+ if (value < 1024) return `${value} B`;
2570
+ if (value < 1024 * 1024) return `${Math.round(value / 1024)} kB`;
2571
+ return `${(value / 1024 / 1024).toFixed(2)} MB`;
2572
+ }
2573
+ function formatDate$4(value) {
2574
+ if (!value) return "—";
2575
+ const date = new Date(value);
2576
+ if (Number.isNaN(date.getTime())) return "—";
2577
+ return new Intl.DateTimeFormat("hu-HU", {
2578
+ dateStyle: "short",
2579
+ timeStyle: "short"
2580
+ }).format(date);
2581
+ }
2582
+ const config$7 = adminSdk.defineRouteConfig({
2583
+ label: "Jogi dokumentumok",
2584
+ icon: Newspaper,
2585
+ rank: 40
2486
2586
  });
2487
- const adminBase$4 = (__BASE__ || "/app").replace(/\/+$/, "");
2488
- const links = [
2489
- { label: "Production readiness", description: "Élesítési blokkolók: infrastruktúra, commerce, security, legal, e-mail és SEO.", href: `${adminBase$4}/system-monitoring/readiness` },
2490
- { label: "Integrációs műveletek", description: "Retry, reconciliation és külső API műveletek kezelése.", href: `${adminBase$4}/system-monitoring/operations` },
2491
- { label: "Integrációk állapota", description: "Provider állapotok, konfigurációk és hibák áttekintése.", href: `${adminBase$4}/system-monitoring/health` },
2492
- { label: "Audit napló", description: "Core és integrációs admin események visszakeresése.", href: `${adminBase$4}/system-monitoring/audit` }
2493
- ];
2494
- const SystemMonitoringPage = () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
2495
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-5", children: [
2496
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Rendszerfelügyelet" }),
2497
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Technikai állapotok, élesítési feltételek, külső műveletek és audit események." })
2498
- ] }),
2499
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 p-6 md:grid-cols-2 xl:grid-cols-4", children: links.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.href, className: "rounded-lg border p-5 hover:bg-ui-bg-subtle", children: [
2500
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: item.label }),
2501
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: item.description })
2502
- ] }, item.href)) })
2503
- ] });
2504
- const config$7 = adminSdk.defineRouteConfig({ label: "Rendszerfelügyelet" });
2505
2587
  const defaults$1 = {
2506
2588
  ARUKERESO_STOREFRONT_URL: "",
2507
2589
  ARUKERESO_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
@@ -3093,197 +3175,167 @@ function normalizeEntity(value) {
3093
3175
  function normalizePage(value) {
3094
3176
  return { ...value, seo: normalizeSeo(value.seo) };
3095
3177
  }
3096
- const defaults = {
3097
- GOOGLE_MERCHANT_COUNTRY_CODE: "HU",
3098
- GOOGLE_MERCHANT_CURRENCY_CODE: "HUF",
3099
- GOOGLE_MERCHANT_STOREFRONT_URL: "",
3100
- GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
3101
- GOOGLE_MERCHANT_SALES_CHANNEL_ID: "",
3102
- GOOGLE_MERCHANT_DEFAULT_BRAND: "",
3103
- GOOGLE_MERCHANT_DEFAULT_CONDITION: "new",
3104
- GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: true,
3105
- GOOGLE_MERCHANT_FEED_TITLE: "",
3106
- GOOGLE_MERCHANT_FEED_DESCRIPTION: ""
3107
- };
3108
3178
  const backendUrl$6 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3109
- const apiUrl$6 = (path) => `${backendUrl$6}${path.startsWith("/") ? path : `/${path}`}`;
3110
- const GoogleMerchantPage = () => {
3111
- const [enabled, setEnabled] = React.useState(false);
3112
- const [draft, setDraft] = React.useState(defaults);
3179
+ function apiUrl$6(path) {
3180
+ return `${backendUrl$6}${path.startsWith("/") ? path : `/${path}`}`;
3181
+ }
3182
+ const CoreAuditPage = () => {
3183
+ const [logs, setLogs] = React.useState([]);
3184
+ const [count, setCount] = React.useState(0);
3185
+ const [integration, setIntegration] = React.useState("all");
3186
+ const [status, setStatus] = React.useState("all");
3187
+ const [query, setQuery] = React.useState("");
3113
3188
  const [loading, setLoading] = React.useState(true);
3114
- const [saving, setSaving] = React.useState(false);
3115
- const [previewing, setPreviewing] = React.useState(false);
3116
- const [preview, setPreview] = React.useState(null);
3117
- const update = (key, value) => {
3118
- setDraft((current) => ({ ...current, [key]: value }));
3119
- };
3189
+ const [loadError, setLoadError] = React.useState(null);
3120
3190
  const load = React.useCallback(async () => {
3121
3191
  setLoading(true);
3192
+ setLoadError(null);
3122
3193
  try {
3123
- const response = await fetch(apiUrl$6("/admin/integrations/google-merchant"), {
3124
- credentials: "include"
3125
- });
3126
- const data = await response.json().catch(() => ({}));
3127
- if (!response.ok || !data.integration) {
3128
- throw new Error(data.message || "A Google Merchant beállítások nem tölthetők be.");
3194
+ const params = new URLSearchParams({ limit: "100" });
3195
+ if (integration !== "all") params.set("integration", integration);
3196
+ if (status !== "all") params.set("status", status);
3197
+ const response = await fetch(
3198
+ apiUrl$6(`/admin/core-audit?${params.toString()}`),
3199
+ { credentials: "include" }
3200
+ );
3201
+ const payload = await response.json().catch(() => ({}));
3202
+ if (!response.ok) {
3203
+ throw new Error(payload.message || "Az audit napló nem tölthető be.");
3129
3204
  }
3130
- const values = data.integration.values || {};
3131
- setEnabled(Boolean(data.integration.enabled));
3132
- setDraft({
3133
- GOOGLE_MERCHANT_COUNTRY_CODE: values.GOOGLE_MERCHANT_COUNTRY_CODE || "HU",
3134
- GOOGLE_MERCHANT_CURRENCY_CODE: values.GOOGLE_MERCHANT_CURRENCY_CODE || "HUF",
3135
- GOOGLE_MERCHANT_STOREFRONT_URL: values.GOOGLE_MERCHANT_STOREFRONT_URL || "",
3136
- GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: values.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE || "/{country_code}/products/{handle}?v_id={variant_id}",
3137
- GOOGLE_MERCHANT_SALES_CHANNEL_ID: values.GOOGLE_MERCHANT_SALES_CHANNEL_ID || "",
3138
- GOOGLE_MERCHANT_DEFAULT_BRAND: values.GOOGLE_MERCHANT_DEFAULT_BRAND || "",
3139
- GOOGLE_MERCHANT_DEFAULT_CONDITION: values.GOOGLE_MERCHANT_DEFAULT_CONDITION || "new",
3140
- GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: values.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK !== "false",
3141
- GOOGLE_MERCHANT_FEED_TITLE: values.GOOGLE_MERCHANT_FEED_TITLE || "",
3142
- GOOGLE_MERCHANT_FEED_DESCRIPTION: values.GOOGLE_MERCHANT_FEED_DESCRIPTION || ""
3143
- });
3205
+ setLogs(payload.logs || []);
3206
+ setCount(payload.count || 0);
3144
3207
  } catch (error) {
3145
- ui.toast.error(error instanceof Error ? error.message : "Betöltési hiba.");
3208
+ setLogs([]);
3209
+ setLoadError(
3210
+ error instanceof Error ? error.message : "Az audit napló nem tölthető be."
3211
+ );
3146
3212
  } finally {
3147
3213
  setLoading(false);
3148
3214
  }
3149
- }, []);
3215
+ }, [integration, status]);
3150
3216
  React.useEffect(() => {
3151
3217
  void load();
3152
3218
  }, [load]);
3153
- const save = async () => {
3154
- setSaving(true);
3155
- try {
3156
- const response = await fetch(apiUrl$6("/admin/integrations/google-merchant"), {
3157
- method: "POST",
3158
- credentials: "include",
3159
- headers: { "Content-Type": "application/json" },
3160
- body: JSON.stringify({ enabled, values: draft })
3161
- });
3162
- const data = await response.json().catch(() => ({}));
3163
- if (!response.ok) throw new Error(data.message || "A mentés nem sikerült.");
3164
- ui.toast.success(data.message || "Google Merchant beállítások mentve.");
3165
- setPreview(null);
3166
- await load();
3167
- } catch (error) {
3168
- ui.toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
3169
- } finally {
3170
- setSaving(false);
3171
- }
3172
- };
3173
- const runPreview = async () => {
3174
- setPreviewing(true);
3175
- try {
3176
- const response = await fetch(apiUrl$6("/admin/google-merchant/preview"), {
3177
- credentials: "include"
3178
- });
3179
- const data = await response.json().catch(() => ({}));
3180
- if (!response.ok) throw new Error(data.message || "A feed nem generálható.");
3181
- setPreview(data);
3182
- ui.toast.success("A Merchant feed ellenőrzése elkészült.");
3183
- } catch (error) {
3184
- ui.toast.error(error instanceof Error ? error.message : "A feed nem generálható.");
3185
- } finally {
3186
- setPreviewing(false);
3187
- }
3188
- };
3189
- const feedUrl = apiUrl$6("/feeds/google-merchant.xml");
3190
- const d = preview?.diagnostics;
3219
+ const visible = React.useMemo(() => {
3220
+ const value = query.trim().toLowerCase();
3221
+ if (!value) return logs;
3222
+ return logs.filter(
3223
+ (log) => [
3224
+ log.action,
3225
+ log.resource_type,
3226
+ log.resource_id,
3227
+ log.integration,
3228
+ log.actor_id,
3229
+ log.summary
3230
+ ].some((item) => String(item || "").toLowerCase().includes(value))
3231
+ );
3232
+ }, [logs, query]);
3191
3233
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
3192
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-4", children: [
3234
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
3193
3235
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3194
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Google Merchant Center" }),
3195
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Google RSS 2.0 feed a Medusa termék-, variant-, régiós ár-, ÁFA- és készletadataiból." })
3236
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Core audit napló" }),
3237
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Admin és integrációs műveletek üzleti auditja, titkok mentése nélkül." })
3196
3238
  ] }),
3197
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
3198
- /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: enabled, onCheckedChange: setEnabled, disabled: loading }),
3199
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
3200
- ] })
3239
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Frissítés" })
3201
3240
  ] }),
3202
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
3203
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Célország", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_COUNTRY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_COUNTRY_CODE", e.target.value.toUpperCase()), placeholder: "HU" }) }),
3204
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Pénznem", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_CURRENCY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_CURRENCY_CODE", e.target.value.toUpperCase()), placeholder: "HUF" }) }),
3205
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Storefront URL", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_STOREFRONT_URL, onChange: (e) => update("GOOGLE_MERCHANT_STOREFRONT_URL", e.target.value), placeholder: "https://shop.hu (üresen STOREFRONT_URL)" }) }),
3206
- /* @__PURE__ */ jsxRuntime.jsxs(Field$1, { label: "Termék URL sablon", children: [
3207
- /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE, onChange: (e) => update("GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE", e.target.value) }),
3208
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-muted text-xs", children: [
3209
- "Helyőrzők: ",
3210
- "{country_code}",
3211
- ", ",
3212
- "{currency_code}",
3213
- ", ",
3214
- "{handle}",
3215
- ", ",
3216
- "{variant_id}",
3217
- "."
3241
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-end gap-3 border-b px-6 py-4", children: [
3242
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3243
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Integráció" }),
3244
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: integration, onValueChange: setIntegration, children: [
3245
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-44", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
3246
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
3247
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "all", children: "Összes" }),
3248
+ [
3249
+ "stripe",
3250
+ "simplepay",
3251
+ "billingo",
3252
+ "bank-transfer",
3253
+ "foxpost",
3254
+ "gls",
3255
+ "packeta",
3256
+ "dpd",
3257
+ "mpl",
3258
+ "sendgrid",
3259
+ "fogyasztobarat"
3260
+ ].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item }, item))
3261
+ ] })
3218
3262
  ] })
3219
3263
  ] }),
3220
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Sales Channel ID", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_SALES_CHANNEL_ID, onChange: (e) => update("GOOGLE_MERCHANT_SALES_CHANNEL_ID", e.target.value), placeholder: "sc_... (opcionális)" }) }),
3221
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Alapértelmezett márka", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_DEFAULT_BRAND, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_BRAND", e.target.value) }) }),
3222
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Alapértelmezett állapot", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm", value: draft.GOOGLE_MERCHANT_DEFAULT_CONDITION, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_CONDITION", e.target.value), children: [
3223
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "new", children: "Új" }),
3224
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "refurbished", children: "Felújított" }),
3225
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "used", children: "Használt" })
3226
- ] }) }),
3227
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Készlethiányos variantok", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-8 items-center gap-2", children: [
3228
- /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK, onCheckedChange: (value) => update("GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK", value) }),
3229
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK ? "Benne maradnak" : "Kimaradnak" })
3230
- ] }) }),
3231
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Feed neve", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_FEED_TITLE, onChange: (e) => update("GOOGLE_MERCHANT_FEED_TITLE", e.target.value), placeholder: "Üresen automatikus" }) }),
3232
- /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Feed leírása", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_FEED_DESCRIPTION, onChange: (e) => update("GOOGLE_MERCHANT_FEED_DESCRIPTION", e.target.value), placeholder: "Üresen automatikus" }) })
3233
- ] }),
3234
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
3235
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3236
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Publikus feed URL" }),
3237
- /* @__PURE__ */ jsxRuntime.jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
3264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3265
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Eredmény" }),
3266
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: status, onValueChange: setStatus, children: [
3267
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
3268
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
3269
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "all", children: "Összes" }),
3270
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "success", children: "Sikeres" }),
3271
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "error", children: "Hiba" })
3272
+ ] })
3273
+ ] })
3238
3274
  ] }),
3239
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
3240
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: previewing, disabled: !enabled || loading || saving || previewing, onClick: () => void runPreview(), children: "Feed ellenőrzése" }),
3241
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { isLoading: saving, disabled: loading || saving || previewing, onClick: () => void save(), children: "Mentés" })
3275
+ /* @__PURE__ */ jsxRuntime.jsx(
3276
+ ui.Input,
3277
+ {
3278
+ className: "max-w-sm",
3279
+ value: query,
3280
+ onChange: (event) => setQuery(event.target.value),
3281
+ placeholder: "Keresés művelet, erőforrás, admin vagy leírás alapján"
3282
+ }
3283
+ ),
3284
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
3285
+ count,
3286
+ " bejegyzés"
3242
3287
  ] })
3243
3288
  ] }),
3244
- d ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3245
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 border-b px-6 py-5 sm:grid-cols-2 lg:grid-cols-4", children: [
3246
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Termékek", value: d.productsScanned }),
3247
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Variantok", value: d.variantsScanned }),
3248
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Feed tételek", value: d.itemsEmitted }),
3249
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Hiányzó identifier", value: d.itemsMissingIdentifiers }),
3250
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs ár", value: d.skippedNoPrice }),
3251
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs kép", value: d.skippedNoImage }),
3252
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs sales channel", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
3253
- /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Érvénytelen GTIN", value: d.invalidGtinsIgnored })
3254
- ] }),
3255
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
3289
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto", children: [
3290
+ /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
3256
3291
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3257
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "ID" }),
3258
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Termék" }),
3259
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Ár" }),
3260
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Készlet" }),
3261
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Identifier" })
3292
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Idő" }),
3293
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Eredmény" }),
3294
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Művelet" }),
3295
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Erőforrás" }),
3296
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Integráció" }),
3297
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Admin / actor" }),
3298
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Leírás" })
3262
3299
  ] }) }),
3263
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: (preview?.sample || []).map((item) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
3264
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: item.id }) }),
3265
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noreferrer", className: "text-ui-fg-interactive hover:underline", children: item.title }) }),
3266
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.salePrice ? `${item.salePrice} (${item.price})` : item.price }),
3267
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.availability }),
3268
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.gtin || item.mpn || item.brand || "—" })
3269
- ] }, item.id)) })
3270
- ] }) })
3271
- ] }) : null
3300
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: visible.map((log) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b align-top", children: [
3301
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap p-4", children: formatDate$3(log.created_at) }),
3302
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: log.status === "error" ? "font-medium text-ui-fg-error" : "font-medium text-ui-fg-success", children: log.status === "error" ? "Hiba" : "Sikeres" }) }),
3303
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: log.action }) }),
3304
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
3305
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: log.resource_type }),
3306
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: log.resource_id || "—" })
3307
+ ] }),
3308
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: log.integration || "—" }),
3309
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: log.actor_id || "system" }),
3310
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "max-w-xl p-4", children: [
3311
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: log.summary }),
3312
+ log.details && Object.keys(log.details).length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-ui-fg-subtle", children: Object.entries(log.details).map(([key, value]) => `${key}: ${String(value)}`).join(" · ") }) : null
3313
+ ] })
3314
+ ] }, log.id)) })
3315
+ ] }),
3316
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Audit napló betöltése…" }) }) : null,
3317
+ !loading && loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
3318
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "Az audit napló nem tölthető be." }),
3319
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
3320
+ ] }) : null,
3321
+ !loading && !loadError && !visible.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Nincs a szűrésnek megfelelő audit bejegyzés." }) }) : null
3322
+ ] })
3272
3323
  ] });
3273
3324
  };
3274
- function Field$1({ label, children }) {
3275
- return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
3276
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: label }),
3277
- children
3278
- ] });
3279
- }
3280
- function Stat({ label, value }) {
3281
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-3", children: [
3282
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted text-xs", children: label }),
3283
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: value })
3284
- ] });
3325
+ function formatDate$3(value) {
3326
+ if (!value) return "—";
3327
+ const date = new Date(value);
3328
+ if (Number.isNaN(date.getTime())) return "—";
3329
+ return new Intl.DateTimeFormat("hu-HU", {
3330
+ dateStyle: "short",
3331
+ timeStyle: "short"
3332
+ }).format(date);
3285
3333
  }
3286
- const config$5 = adminSdk.defineRouteConfig({ label: "Google Merchant", rank: 41 });
3334
+ const config$5 = adminSdk.defineRouteConfig({
3335
+ label: "Audit napló",
3336
+ icon: Newspaper,
3337
+ rank: 39
3338
+ });
3287
3339
  const backendUrl$5 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3288
3340
  const adminBase$3 = (__BASE__ || "/app").replace(/\/+$/, "");
3289
3341
  function apiUrl$5(path) {
@@ -3497,314 +3549,227 @@ function ConnectionText({ integration }) {
3497
3549
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-sm", children: [
3498
3550
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: integration.last_test_status === "ok" ? "OK" : integration.last_test_status === "error" ? "Hiba" : "Nincs hitelesítve" }),
3499
3551
  integration.last_test_message ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: integration.last_test_message }) : null,
3500
- integration.last_test_at ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: formatDate$3(integration.last_test_at) }) : null
3552
+ integration.last_test_at ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: formatDate$2(integration.last_test_at) }) : null
3501
3553
  ] });
3502
3554
  }
3503
3555
  function SummaryCard$1({
3504
3556
  label,
3505
3557
  value,
3506
- danger = false
3507
- }) {
3508
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
3509
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
3510
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: danger ? "text-ui-fg-error text-2xl font-semibold" : "text-2xl font-semibold", children: value })
3511
- ] });
3512
- }
3513
- function formatDate$3(value) {
3514
- const date = new Date(value);
3515
- if (Number.isNaN(date.getTime())) return "—";
3516
- return new Intl.DateTimeFormat("hu-HU", {
3517
- dateStyle: "short",
3518
- timeStyle: "short"
3519
- }).format(date);
3520
- }
3521
- const config$4 = adminSdk.defineRouteConfig({
3522
- label: "Integrációk állapota",
3523
- icon: Newspaper,
3524
- rank: 38
3525
- });
3526
- const backendUrl$4 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3527
- const adminBase$2 = (__BASE__ || "/app").replace(/\/+$/, "");
3528
- const apiUrl$4 = (path) => `${backendUrl$4}${path.startsWith("/") ? path : `/${path}`}`;
3529
- const CATEGORY_LABELS = {
3530
- infrastructure: "Infrastruktúra",
3531
- security: "Biztonság",
3532
- store: "Storefront alapok",
3533
- commerce: "Kereskedelem",
3534
- communication: "Kommunikáció",
3535
- compliance: "Jogi megfelelés",
3536
- marketing: "Mérés és SEO"
3537
- };
3538
- const ProductionReadinessPage = () => {
3539
- const [report, setReport] = React.useState(null);
3540
- const [loading, setLoading] = React.useState(true);
3541
- const [error, setError] = React.useState(null);
3542
- const load = React.useCallback(async () => {
3543
- setLoading(true);
3544
- setError(null);
3545
- try {
3546
- const response = await fetch(apiUrl$4("/admin/production-readiness"), {
3547
- credentials: "include"
3548
- });
3549
- const payload = await response.json().catch(() => ({}));
3550
- if (!response.ok) {
3551
- throw new Error(payload.message || "Az élesítési ellenőrzés nem tölthető be.");
3552
- }
3553
- setReport(payload);
3554
- } catch (cause) {
3555
- setReport(null);
3556
- setError(
3557
- cause instanceof Error ? cause.message : "Az élesítési ellenőrzés nem tölthető be."
3558
- );
3559
- } finally {
3560
- setLoading(false);
3561
- }
3562
- }, []);
3563
- React.useEffect(() => {
3564
- void load();
3565
- }, [load]);
3566
- const groups = React.useMemo(() => {
3567
- const result = /* @__PURE__ */ new Map();
3568
- for (const item of report?.checks || []) {
3569
- result.set(item.category, [...result.get(item.category) || [], item]);
3570
- }
3571
- return Array.from(result.entries());
3572
- }, [report]);
3573
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
3574
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-5", children: [
3575
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3576
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Production readiness" }),
3577
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Élesítés előtti runtime ellenőrzés. A felület státuszokat mutat, secret értéket nem ad vissza." })
3578
- ] }),
3579
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Újraellenőrzés" })
3580
- ] }),
3581
- report ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3582
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 border-b p-6 sm:grid-cols-2 lg:grid-cols-4", children: [
3583
- /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Kész", value: report.score.ready, tone: "ready" }),
3584
- /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Figyelmeztetés", value: report.score.warning, tone: "warning" }),
3585
- /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Blokkoló", value: report.score.blocked, tone: "blocked" }),
3586
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
3587
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Élesítési döntés" }),
3588
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: report.ready ? "mt-1 text-xl font-semibold text-ui-fg-success" : "mt-1 text-xl font-semibold text-ui-fg-error", children: report.ready ? "Élesíthető" : "Még nem élesíthető" }),
3589
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-1 text-ui-fg-subtle", children: report.environment === "production" ? "Production szabályok" : "Nem-production szabályok" })
3590
- ] })
3591
- ] }),
3592
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b px-6 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
3593
- "Utolsó ellenőrzés: ",
3594
- formatDate$2(report.generated_at),
3595
- ". A sárga elemek nem blokkolják az élesítést, a piros elemek igen."
3596
- ] }) }),
3597
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6 p-6", children: groups.map(([category, checks]) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "overflow-hidden rounded-lg border", children: [
3598
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b bg-ui-bg-subtle px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: CATEGORY_LABELS[category] || category }) }),
3599
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: checks.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 p-4 md:grid-cols-[180px_140px_minmax(0,1fr)_auto] md:items-center", children: [
3600
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: item.label }),
3601
- /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: item.status }),
3602
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: item.message }),
3603
- item.action_href && item.action_label ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: normalizeAdminHref(item.action_href), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: item.action_label }) }) : /* @__PURE__ */ jsxRuntime.jsx("span", {})
3604
- ] }, item.key)) })
3605
- ] }, category)) })
3606
- ] }) : null,
3607
- loading && !report ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Élesítési feltételek ellenőrzése…" }) }) : null,
3608
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
3609
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "Az ellenőrzés nem futott le." }),
3610
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: error })
3611
- ] }) : null
3612
- ] });
3613
- };
3614
- function StatusBadge({ status }) {
3615
- const label = status === "ready" ? "Kész" : status === "warning" ? "Figyelmeztetés" : "Blokkoló";
3616
- const className = status === "ready" ? "font-medium text-ui-fg-success" : status === "warning" ? "font-medium text-ui-fg-warning" : "font-medium text-ui-fg-error";
3617
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
3618
- status === "ready" ? "✅" : status === "warning" ? "🟡" : "🔴",
3619
- " ",
3620
- label
3621
- ] });
3622
- }
3623
- function Summary({ label, value, tone }) {
3624
- const valueClass = tone === "ready" ? "text-ui-fg-success" : tone === "warning" ? "text-ui-fg-warning" : "text-ui-fg-error";
3558
+ danger = false
3559
+ }) {
3625
3560
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
3626
3561
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
3627
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mt-1 text-3xl font-semibold ${valueClass}`, children: value })
3562
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: danger ? "text-ui-fg-error text-2xl font-semibold" : "text-2xl font-semibold", children: value })
3628
3563
  ] });
3629
3564
  }
3630
- function normalizeAdminHref(path) {
3631
- if (!path.startsWith("/app")) return path;
3632
- return `${adminBase$2}${path.slice(4)}`;
3633
- }
3634
3565
  function formatDate$2(value) {
3635
3566
  const date = new Date(value);
3636
3567
  if (Number.isNaN(date.getTime())) return "—";
3637
- return new Intl.DateTimeFormat("hu-HU", { dateStyle: "short", timeStyle: "medium" }).format(date);
3568
+ return new Intl.DateTimeFormat("hu-HU", {
3569
+ dateStyle: "short",
3570
+ timeStyle: "short"
3571
+ }).format(date);
3638
3572
  }
3639
- const config$3 = adminSdk.defineRouteConfig({
3640
- label: "Production readiness",
3641
- rank: 39
3573
+ const config$4 = adminSdk.defineRouteConfig({
3574
+ label: "Integrációk állapota",
3575
+ icon: Newspaper,
3576
+ rank: 38
3642
3577
  });
3643
- const backendUrl$3 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3644
- function apiUrl$3(path) {
3645
- return `${backendUrl$3}${path.startsWith("/") ? path : `/${path}`}`;
3646
- }
3647
- const CoreAuditPage = () => {
3648
- const [logs, setLogs] = React.useState([]);
3649
- const [count, setCount] = React.useState(0);
3650
- const [integration, setIntegration] = React.useState("all");
3651
- const [status, setStatus] = React.useState("all");
3652
- const [query, setQuery] = React.useState("");
3578
+ const defaults = {
3579
+ GOOGLE_MERCHANT_COUNTRY_CODE: "HU",
3580
+ GOOGLE_MERCHANT_CURRENCY_CODE: "HUF",
3581
+ GOOGLE_MERCHANT_STOREFRONT_URL: "",
3582
+ GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
3583
+ GOOGLE_MERCHANT_SALES_CHANNEL_ID: "",
3584
+ GOOGLE_MERCHANT_DEFAULT_BRAND: "",
3585
+ GOOGLE_MERCHANT_DEFAULT_CONDITION: "new",
3586
+ GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: true,
3587
+ GOOGLE_MERCHANT_FEED_TITLE: "",
3588
+ GOOGLE_MERCHANT_FEED_DESCRIPTION: ""
3589
+ };
3590
+ const backendUrl$4 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3591
+ const apiUrl$4 = (path) => `${backendUrl$4}${path.startsWith("/") ? path : `/${path}`}`;
3592
+ const GoogleMerchantPage = () => {
3593
+ const [enabled, setEnabled] = React.useState(false);
3594
+ const [draft, setDraft] = React.useState(defaults);
3653
3595
  const [loading, setLoading] = React.useState(true);
3654
- const [loadError, setLoadError] = React.useState(null);
3596
+ const [saving, setSaving] = React.useState(false);
3597
+ const [previewing, setPreviewing] = React.useState(false);
3598
+ const [preview, setPreview] = React.useState(null);
3599
+ const update = (key, value) => {
3600
+ setDraft((current) => ({ ...current, [key]: value }));
3601
+ };
3655
3602
  const load = React.useCallback(async () => {
3656
3603
  setLoading(true);
3657
- setLoadError(null);
3658
3604
  try {
3659
- const params = new URLSearchParams({ limit: "100" });
3660
- if (integration !== "all") params.set("integration", integration);
3661
- if (status !== "all") params.set("status", status);
3662
- const response = await fetch(
3663
- apiUrl$3(`/admin/core-audit?${params.toString()}`),
3664
- { credentials: "include" }
3665
- );
3666
- const payload = await response.json().catch(() => ({}));
3667
- if (!response.ok) {
3668
- throw new Error(payload.message || "Az audit napló nem tölthető be.");
3605
+ const response = await fetch(apiUrl$4("/admin/integrations/google-merchant"), {
3606
+ credentials: "include"
3607
+ });
3608
+ const data = await response.json().catch(() => ({}));
3609
+ if (!response.ok || !data.integration) {
3610
+ throw new Error(data.message || "A Google Merchant beállítások nem tölthetők be.");
3669
3611
  }
3670
- setLogs(payload.logs || []);
3671
- setCount(payload.count || 0);
3612
+ const values = data.integration.values || {};
3613
+ setEnabled(Boolean(data.integration.enabled));
3614
+ setDraft({
3615
+ GOOGLE_MERCHANT_COUNTRY_CODE: values.GOOGLE_MERCHANT_COUNTRY_CODE || "HU",
3616
+ GOOGLE_MERCHANT_CURRENCY_CODE: values.GOOGLE_MERCHANT_CURRENCY_CODE || "HUF",
3617
+ GOOGLE_MERCHANT_STOREFRONT_URL: values.GOOGLE_MERCHANT_STOREFRONT_URL || "",
3618
+ GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: values.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE || "/{country_code}/products/{handle}?v_id={variant_id}",
3619
+ GOOGLE_MERCHANT_SALES_CHANNEL_ID: values.GOOGLE_MERCHANT_SALES_CHANNEL_ID || "",
3620
+ GOOGLE_MERCHANT_DEFAULT_BRAND: values.GOOGLE_MERCHANT_DEFAULT_BRAND || "",
3621
+ GOOGLE_MERCHANT_DEFAULT_CONDITION: values.GOOGLE_MERCHANT_DEFAULT_CONDITION || "new",
3622
+ GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: values.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK !== "false",
3623
+ GOOGLE_MERCHANT_FEED_TITLE: values.GOOGLE_MERCHANT_FEED_TITLE || "",
3624
+ GOOGLE_MERCHANT_FEED_DESCRIPTION: values.GOOGLE_MERCHANT_FEED_DESCRIPTION || ""
3625
+ });
3672
3626
  } catch (error) {
3673
- setLogs([]);
3674
- setLoadError(
3675
- error instanceof Error ? error.message : "Az audit napló nem tölthető be."
3676
- );
3627
+ ui.toast.error(error instanceof Error ? error.message : "Betöltési hiba.");
3677
3628
  } finally {
3678
3629
  setLoading(false);
3679
3630
  }
3680
- }, [integration, status]);
3631
+ }, []);
3681
3632
  React.useEffect(() => {
3682
3633
  void load();
3683
3634
  }, [load]);
3684
- const visible = React.useMemo(() => {
3685
- const value = query.trim().toLowerCase();
3686
- if (!value) return logs;
3687
- return logs.filter(
3688
- (log) => [
3689
- log.action,
3690
- log.resource_type,
3691
- log.resource_id,
3692
- log.integration,
3693
- log.actor_id,
3694
- log.summary
3695
- ].some((item) => String(item || "").toLowerCase().includes(value))
3696
- );
3697
- }, [logs, query]);
3635
+ const save = async () => {
3636
+ setSaving(true);
3637
+ try {
3638
+ const response = await fetch(apiUrl$4("/admin/integrations/google-merchant"), {
3639
+ method: "POST",
3640
+ credentials: "include",
3641
+ headers: { "Content-Type": "application/json" },
3642
+ body: JSON.stringify({ enabled, values: draft })
3643
+ });
3644
+ const data = await response.json().catch(() => ({}));
3645
+ if (!response.ok) throw new Error(data.message || "A mentés nem sikerült.");
3646
+ ui.toast.success(data.message || "Google Merchant beállítások mentve.");
3647
+ setPreview(null);
3648
+ await load();
3649
+ } catch (error) {
3650
+ ui.toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
3651
+ } finally {
3652
+ setSaving(false);
3653
+ }
3654
+ };
3655
+ const runPreview = async () => {
3656
+ setPreviewing(true);
3657
+ try {
3658
+ const response = await fetch(apiUrl$4("/admin/google-merchant/preview"), {
3659
+ credentials: "include"
3660
+ });
3661
+ const data = await response.json().catch(() => ({}));
3662
+ if (!response.ok) throw new Error(data.message || "A feed nem generálható.");
3663
+ setPreview(data);
3664
+ ui.toast.success("A Merchant feed ellenőrzése elkészült.");
3665
+ } catch (error) {
3666
+ ui.toast.error(error instanceof Error ? error.message : "A feed nem generálható.");
3667
+ } finally {
3668
+ setPreviewing(false);
3669
+ }
3670
+ };
3671
+ const feedUrl = apiUrl$4("/feeds/google-merchant.xml");
3672
+ const d = preview?.diagnostics;
3698
3673
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
3699
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
3674
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-4", children: [
3700
3675
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3701
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Core audit napló" }),
3702
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Admin és integrációs műveletek üzleti auditja, titkok mentése nélkül." })
3676
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Google Merchant Center" }),
3677
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Google RSS 2.0 feed a Medusa termék-, variant-, régiós ár-, ÁFA- és készletadataiból." })
3703
3678
  ] }),
3704
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Frissítés" })
3679
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
3680
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: enabled, onCheckedChange: setEnabled, disabled: loading }),
3681
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
3682
+ ] })
3705
3683
  ] }),
3706
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-end gap-3 border-b px-6 py-4", children: [
3707
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3708
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Integráció" }),
3709
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: integration, onValueChange: setIntegration, children: [
3710
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-44", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
3711
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
3712
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "all", children: "Összes" }),
3713
- [
3714
- "stripe",
3715
- "simplepay",
3716
- "billingo",
3717
- "bank-transfer",
3718
- "foxpost",
3719
- "gls",
3720
- "packeta",
3721
- "dpd",
3722
- "mpl",
3723
- "sendgrid",
3724
- "fogyasztobarat"
3725
- ].map((item) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: item, children: item }, item))
3726
- ] })
3727
- ] })
3728
- ] }),
3729
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3730
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Eredmény" }),
3731
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: status, onValueChange: setStatus, children: [
3732
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
3733
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
3734
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "all", children: "Összes" }),
3735
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "success", children: "Sikeres" }),
3736
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "error", children: "Hiba" })
3737
- ] })
3684
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
3685
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Célország", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_COUNTRY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_COUNTRY_CODE", e.target.value.toUpperCase()), placeholder: "HU" }) }),
3686
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Pénznem", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_CURRENCY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_CURRENCY_CODE", e.target.value.toUpperCase()), placeholder: "HUF" }) }),
3687
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Storefront URL", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_STOREFRONT_URL, onChange: (e) => update("GOOGLE_MERCHANT_STOREFRONT_URL", e.target.value), placeholder: "https://shop.hu (üresen STOREFRONT_URL)" }) }),
3688
+ /* @__PURE__ */ jsxRuntime.jsxs(Field$1, { label: "Termék URL sablon", children: [
3689
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE, onChange: (e) => update("GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE", e.target.value) }),
3690
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-ui-fg-muted text-xs", children: [
3691
+ "Helyőrzők: ",
3692
+ "{country_code}",
3693
+ ", ",
3694
+ "{currency_code}",
3695
+ ", ",
3696
+ "{handle}",
3697
+ ", ",
3698
+ "{variant_id}",
3699
+ "."
3738
3700
  ] })
3739
3701
  ] }),
3740
- /* @__PURE__ */ jsxRuntime.jsx(
3741
- ui.Input,
3742
- {
3743
- className: "max-w-sm",
3744
- value: query,
3745
- onChange: (event) => setQuery(event.target.value),
3746
- placeholder: "Keresés művelet, erőforrás, admin vagy leírás alapján"
3747
- }
3748
- ),
3749
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
3750
- count,
3751
- " bejegyzés"
3752
- ] })
3702
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Sales Channel ID", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_SALES_CHANNEL_ID, onChange: (e) => update("GOOGLE_MERCHANT_SALES_CHANNEL_ID", e.target.value), placeholder: "sc_... (opcionális)" }) }),
3703
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Alapértelmezett márka", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_DEFAULT_BRAND, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_BRAND", e.target.value) }) }),
3704
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Alapértelmezett állapot", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm", value: draft.GOOGLE_MERCHANT_DEFAULT_CONDITION, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_CONDITION", e.target.value), children: [
3705
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "new", children: "Új" }),
3706
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "refurbished", children: "Felújított" }),
3707
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "used", children: "Használt" })
3708
+ ] }) }),
3709
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Készlethiányos variantok", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-8 items-center gap-2", children: [
3710
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK, onCheckedChange: (value) => update("GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK", value) }),
3711
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK ? "Benne maradnak" : "Kimaradnak" })
3712
+ ] }) }),
3713
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Feed neve", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_FEED_TITLE, onChange: (e) => update("GOOGLE_MERCHANT_FEED_TITLE", e.target.value), placeholder: "Üresen automatikus" }) }),
3714
+ /* @__PURE__ */ jsxRuntime.jsx(Field$1, { label: "Feed leírása", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: draft.GOOGLE_MERCHANT_FEED_DESCRIPTION, onChange: (e) => update("GOOGLE_MERCHANT_FEED_DESCRIPTION", e.target.value), placeholder: "Üresen automatikus" }) })
3753
3715
  ] }),
3754
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-x-auto", children: [
3755
- /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
3756
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3757
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Idő" }),
3758
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Eredmény" }),
3759
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Művelet" }),
3760
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Erőforrás" }),
3761
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Integráció" }),
3762
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Admin / actor" }),
3763
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Leírás" })
3764
- ] }) }),
3765
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: visible.map((log) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b align-top", children: [
3766
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "whitespace-nowrap p-4", children: formatDate$1(log.created_at) }),
3767
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: log.status === "error" ? "font-medium text-ui-fg-error" : "font-medium text-ui-fg-success", children: log.status === "error" ? "Hiba" : "Sikeres" }) }),
3768
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: log.action }) }),
3769
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "p-4", children: [
3770
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: log.resource_type }),
3771
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: log.resource_id || "—" })
3772
- ] }),
3773
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: log.integration || "—" }),
3774
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: log.actor_id || "system" }),
3775
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "max-w-xl p-4", children: [
3776
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: log.summary }),
3777
- log.details && Object.keys(log.details).length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-ui-fg-subtle", children: Object.entries(log.details).map(([key, value]) => `${key}: ${String(value)}`).join(" · ") }) : null
3778
- ] })
3779
- ] }, log.id)) })
3716
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
3717
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3718
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Publikus feed URL" }),
3719
+ /* @__PURE__ */ jsxRuntime.jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
3720
+ ] }),
3721
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
3722
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: previewing, disabled: !enabled || loading || saving || previewing, onClick: () => void runPreview(), children: "Feed ellenőrzése" }),
3723
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { isLoading: saving, disabled: loading || saving || previewing, onClick: () => void save(), children: "Mentés" })
3724
+ ] })
3725
+ ] }),
3726
+ d ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3727
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 border-b px-6 py-5 sm:grid-cols-2 lg:grid-cols-4", children: [
3728
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Termékek", value: d.productsScanned }),
3729
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Variantok", value: d.variantsScanned }),
3730
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Feed tételek", value: d.itemsEmitted }),
3731
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Hiányzó identifier", value: d.itemsMissingIdentifiers }),
3732
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs ár", value: d.skippedNoPrice }),
3733
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs kép", value: d.skippedNoImage }),
3734
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Nincs sales channel", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
3735
+ /* @__PURE__ */ jsxRuntime.jsx(Stat, { label: "Érvénytelen GTIN", value: d.invalidGtinsIgnored })
3780
3736
  ] }),
3781
- loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Audit napló betöltése…" }) }) : null,
3782
- !loading && loadError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
3783
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "Az audit napló nem tölthető be." }),
3784
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: loadError })
3785
- ] }) : null,
3786
- !loading && !loadError && !visible.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Nincs a szűrésnek megfelelő audit bejegyzés." }) }) : null
3787
- ] })
3737
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left text-sm", children: [
3738
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3739
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "ID" }),
3740
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Termék" }),
3741
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Ár" }),
3742
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Készlet" }),
3743
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "p-4", children: "Identifier" })
3744
+ ] }) }),
3745
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: (preview?.sample || []).map((item) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b", children: [
3746
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: item.id }) }),
3747
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noreferrer", className: "text-ui-fg-interactive hover:underline", children: item.title }) }),
3748
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.salePrice ? `${item.salePrice} (${item.price})` : item.price }),
3749
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.availability }),
3750
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: item.gtin || item.mpn || item.brand || "—" })
3751
+ ] }, item.id)) })
3752
+ ] }) })
3753
+ ] }) : null
3788
3754
  ] });
3789
3755
  };
3790
- function formatDate$1(value) {
3791
- if (!value) return "—";
3792
- const date = new Date(value);
3793
- if (Number.isNaN(date.getTime())) return "—";
3794
- return new Intl.DateTimeFormat("hu-HU", {
3795
- dateStyle: "short",
3796
- timeStyle: "short"
3797
- }).format(date);
3756
+ function Field$1({ label, children }) {
3757
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
3758
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: label }),
3759
+ children
3760
+ ] });
3798
3761
  }
3799
- const config$2 = adminSdk.defineRouteConfig({
3800
- label: "Audit napló",
3801
- icon: Newspaper,
3802
- rank: 39
3803
- });
3804
- const backendUrl$2 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3805
- const adminBase$1 = (__BASE__ || "/app").replace(/\/+$/, "");
3806
- function apiUrl$2(path) {
3807
- return `${backendUrl$2}${path.startsWith("/") ? path : `/${path}`}`;
3762
+ function Stat({ label, value }) {
3763
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-3", children: [
3764
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted text-xs", children: label }),
3765
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: value })
3766
+ ] });
3767
+ }
3768
+ const config$3 = adminSdk.defineRouteConfig({ label: "Google Merchant", rank: 41 });
3769
+ const backendUrl$3 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
3770
+ const adminBase$2 = (__BASE__ || "/app").replace(/\/+$/, "");
3771
+ function apiUrl$3(path) {
3772
+ return `${backendUrl$3}${path.startsWith("/") ? path : `/${path}`}`;
3808
3773
  }
3809
3774
  const IntegrationOperationsPage = () => {
3810
3775
  const [operations, setOperations] = React.useState([]);
@@ -3830,7 +3795,7 @@ const IntegrationOperationsPage = () => {
3830
3795
  });
3831
3796
  if (provider !== "all") params.set("provider", provider);
3832
3797
  const response = await fetch(
3833
- apiUrl$2(`/admin/integration-operations?${params.toString()}`),
3798
+ apiUrl$3(`/admin/integration-operations?${params.toString()}`),
3834
3799
  { credentials: "include" }
3835
3800
  );
3836
3801
  const payload = await response.json().catch(() => ({}));
@@ -3898,7 +3863,7 @@ const IntegrationOperationsPage = () => {
3898
3863
  setActionLoading(operation.id);
3899
3864
  try {
3900
3865
  const response = await fetch(
3901
- apiUrl$2(`/admin/integration-operations/${operation.id}/reconcile`),
3866
+ apiUrl$3(`/admin/integration-operations/${operation.id}/reconcile`),
3902
3867
  {
3903
3868
  method: "POST",
3904
3869
  credentials: "include",
@@ -4036,7 +4001,7 @@ const IntegrationOperationsPage = () => {
4036
4001
  operation.entity_type === "order" ? /* @__PURE__ */ jsxRuntime.jsx(
4037
4002
  "a",
4038
4003
  {
4039
- href: `${adminBase$1}/orders/${operation.entity_id}`,
4004
+ href: `${adminBase$2}/orders/${operation.entity_id}`,
4040
4005
  className: "text-ui-fg-interactive",
4041
4006
  children: operation.entity_id
4042
4007
  }
@@ -4047,7 +4012,7 @@ const IntegrationOperationsPage = () => {
4047
4012
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: operation.attempts }),
4048
4013
  /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "max-w-md p-4", children: [
4049
4014
  operation.error_summary ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-error", children: operation.error_summary }) : null,
4050
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: formatDate(operation.updated_at) })
4015
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: formatDate$1(operation.updated_at) })
4051
4016
  ] }),
4052
4017
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-52 flex-wrap gap-2", children: operation.status === "needs_reconciliation" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4053
4018
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4116,7 +4081,7 @@ function providerLabel(value) {
4116
4081
  };
4117
4082
  return labels[value] || value;
4118
4083
  }
4119
- function formatDate(value) {
4084
+ function formatDate$1(value) {
4120
4085
  if (!value) return "—";
4121
4086
  const date = new Date(value);
4122
4087
  if (Number.isNaN(date.getTime())) return "—";
@@ -4125,11 +4090,128 @@ function formatDate(value) {
4125
4090
  timeStyle: "short"
4126
4091
  }).format(date);
4127
4092
  }
4128
- const config$1 = adminSdk.defineRouteConfig({
4093
+ const config$2 = adminSdk.defineRouteConfig({
4129
4094
  label: "Integrációs műveletek",
4130
4095
  icon: Newspaper,
4131
4096
  rank: 37
4132
4097
  });
4098
+ const backendUrl$2 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
4099
+ const adminBase$1 = (__BASE__ || "/app").replace(/\/+$/, "");
4100
+ const apiUrl$2 = (path) => `${backendUrl$2}${path.startsWith("/") ? path : `/${path}`}`;
4101
+ const CATEGORY_LABELS = {
4102
+ infrastructure: "Infrastruktúra",
4103
+ security: "Biztonság",
4104
+ store: "Storefront alapok",
4105
+ commerce: "Kereskedelem",
4106
+ communication: "Kommunikáció",
4107
+ compliance: "Jogi megfelelés",
4108
+ marketing: "Mérés és SEO"
4109
+ };
4110
+ const ProductionReadinessPage = () => {
4111
+ const [report, setReport] = React.useState(null);
4112
+ const [loading, setLoading] = React.useState(true);
4113
+ const [error, setError] = React.useState(null);
4114
+ const load = React.useCallback(async () => {
4115
+ setLoading(true);
4116
+ setError(null);
4117
+ try {
4118
+ const response = await fetch(apiUrl$2("/admin/production-readiness"), {
4119
+ credentials: "include"
4120
+ });
4121
+ const payload = await response.json().catch(() => ({}));
4122
+ if (!response.ok) {
4123
+ throw new Error(payload.message || "Az élesítési ellenőrzés nem tölthető be.");
4124
+ }
4125
+ setReport(payload);
4126
+ } catch (cause) {
4127
+ setReport(null);
4128
+ setError(
4129
+ cause instanceof Error ? cause.message : "Az élesítési ellenőrzés nem tölthető be."
4130
+ );
4131
+ } finally {
4132
+ setLoading(false);
4133
+ }
4134
+ }, []);
4135
+ React.useEffect(() => {
4136
+ void load();
4137
+ }, [load]);
4138
+ const groups = React.useMemo(() => {
4139
+ const result = /* @__PURE__ */ new Map();
4140
+ for (const item of report?.checks || []) {
4141
+ result.set(item.category, [...result.get(item.category) || [], item]);
4142
+ }
4143
+ return Array.from(result.entries());
4144
+ }, [report]);
4145
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
4146
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-5", children: [
4147
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4148
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Production readiness" }),
4149
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Élesítés előtti runtime ellenőrzés. A felület státuszokat mutat, secret értéket nem ad vissza." })
4150
+ ] }),
4151
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Újraellenőrzés" })
4152
+ ] }),
4153
+ report ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4154
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 border-b p-6 sm:grid-cols-2 lg:grid-cols-4", children: [
4155
+ /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Kész", value: report.score.ready, tone: "ready" }),
4156
+ /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Figyelmeztetés", value: report.score.warning, tone: "warning" }),
4157
+ /* @__PURE__ */ jsxRuntime.jsx(Summary, { label: "Blokkoló", value: report.score.blocked, tone: "blocked" }),
4158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
4159
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Élesítési döntés" }),
4160
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: report.ready ? "mt-1 text-xl font-semibold text-ui-fg-success" : "mt-1 text-xl font-semibold text-ui-fg-error", children: report.ready ? "Élesíthető" : "Még nem élesíthető" }),
4161
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-1 text-ui-fg-subtle", children: report.environment === "production" ? "Production szabályok" : "Nem-production szabályok" })
4162
+ ] })
4163
+ ] }),
4164
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b px-6 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
4165
+ "Utolsó ellenőrzés: ",
4166
+ formatDate(report.generated_at),
4167
+ ". A sárga elemek nem blokkolják az élesítést, a piros elemek igen."
4168
+ ] }) }),
4169
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6 p-6", children: groups.map(([category, checks]) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "overflow-hidden rounded-lg border", children: [
4170
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b bg-ui-bg-subtle px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: CATEGORY_LABELS[category] || category }) }),
4171
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: checks.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 p-4 md:grid-cols-[180px_140px_minmax(0,1fr)_auto] md:items-center", children: [
4172
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: item.label }),
4173
+ /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: item.status }),
4174
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: item.message }),
4175
+ item.action_href && item.action_label ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: normalizeAdminHref(item.action_href), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: item.action_label }) }) : /* @__PURE__ */ jsxRuntime.jsx("span", {})
4176
+ ] }, item.key)) })
4177
+ ] }, category)) })
4178
+ ] }) : null,
4179
+ loading && !report ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Élesítési feltételek ellenőrzése…" }) }) : null,
4180
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
4181
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium text-ui-fg-error", children: "Az ellenőrzés nem futott le." }),
4182
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: error })
4183
+ ] }) : null
4184
+ ] });
4185
+ };
4186
+ function StatusBadge({ status }) {
4187
+ const label = status === "ready" ? "Kész" : status === "warning" ? "Figyelmeztetés" : "Blokkoló";
4188
+ const className = status === "ready" ? "font-medium text-ui-fg-success" : status === "warning" ? "font-medium text-ui-fg-warning" : "font-medium text-ui-fg-error";
4189
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
4190
+ status === "ready" ? "✅" : status === "warning" ? "🟡" : "🔴",
4191
+ " ",
4192
+ label
4193
+ ] });
4194
+ }
4195
+ function Summary({ label, value, tone }) {
4196
+ const valueClass = tone === "ready" ? "text-ui-fg-success" : tone === "warning" ? "text-ui-fg-warning" : "text-ui-fg-error";
4197
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
4198
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
4199
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mt-1 text-3xl font-semibold ${valueClass}`, children: value })
4200
+ ] });
4201
+ }
4202
+ function normalizeAdminHref(path) {
4203
+ if (!path.startsWith("/app")) return path;
4204
+ return `${adminBase$1}${path.slice(4)}`;
4205
+ }
4206
+ function formatDate(value) {
4207
+ const date = new Date(value);
4208
+ if (Number.isNaN(date.getTime())) return "—";
4209
+ return new Intl.DateTimeFormat("hu-HU", { dateStyle: "short", timeStyle: "medium" }).format(date);
4210
+ }
4211
+ const config$1 = adminSdk.defineRouteConfig({
4212
+ label: "Production readiness",
4213
+ rank: 39
4214
+ });
4133
4215
  const backendUrl$1 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
4134
4216
  const adminBase = (__BASE__ || "/app").replace(/\/+$/, "");
4135
4217
  const apiUrl$1 = (path) => `${backendUrl$1}${path.startsWith("/") ? path : `/${path}`}`;
@@ -4299,7 +4381,7 @@ const IntegrationsPage = () => {
4299
4381
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-0", children: [
4300
4382
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b px-6 py-5", children: [
4301
4383
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Integrációk" }),
4302
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Külső szolgáltatások és provider kapcsolatok központi beállítása. A secret értékek nem kerülnek vissza a böngészőbe, a provider-hozzárendelés pedig továbbra is a Medusa natív felületein történik." })
4384
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 text-ui-fg-subtle", children: "Külső szolgáltatások és provider kapcsolatok központi beállítása. A secret értékek nem kerülnek vissza a böngészőbe, a provider-hozzárendelés pedig továbbra is a HSZRDM Commerce Admin natív felületein történik." })
4303
4385
  ] }),
4304
4386
  loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Betöltés…" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[320px_minmax(0,1fr)]", children: [
4305
4387
  /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "border-r p-4", children: CATEGORY_ORDER.map((category) => {
@@ -4354,10 +4436,10 @@ const IntegrationsPage = () => {
4354
4436
  /* @__PURE__ */ jsxRuntime.jsx(StatusBox, { label: "Aktív", value: selected.enabled ? "Igen" : "Nem", state: selected.enabled ? "success" : "neutral" }),
4355
4437
  /* @__PURE__ */ jsxRuntime.jsx(StatusBox, { label: "Kapcsolat", value: connection.label, state: connection.state })
4356
4438
  ] }),
4357
- selected.category === "shipping" ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "Medusa provider hozzárendelés", children: "Mentés és backend restart után a providert a Medusa Settings → Locations & Shipping alatt rendeld locationhöz." }) : null,
4439
+ selected.category === "shipping" ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "HSZRDM Commerce provider hozzárendelés", children: "Mentés és backend restart után a providert a HSZRDM Commerce Admin Settings → Locations & Shipping alatt rendeld locationhöz." }) : null,
4358
4440
  selected.category === "legal" ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "Fogyasztó Barát EMBED", children: "Ez csak az opcionális Fogyasztó Barát embed konfigurációja. A PDF-ek és checkout elfogadások a főoldali Jogi dokumentumok menüpontban kezelhetők." }) : null,
4359
4441
  selected.category === "marketing" ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "Marketing feed", children: "Itt az integráció alapbeállításait módosítod. A feed előnézet, diagnosztika és publikus URL a főoldali Marketing menüpontban található." }) : null,
4360
- restartNotice ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "Újraindítás szükséges", children: "A beállítások elmentve. Indítsd újra a Medusa backendet az új provider-konfiguráció betöltéséhez." }) : null,
4442
+ restartNotice ? /* @__PURE__ */ jsxRuntime.jsx(Notice, { title: "Újraindítás szükséges", children: "A beállítások elmentve. Indítsd újra a HSZRDM Commerce backendet az új provider-konfiguráció betöltéséhez." }) : null,
4361
4443
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4362
4444
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Beállítások" }),
4363
4445
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 grid gap-4 sm:grid-cols-2", children: selected.fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -4837,28 +4919,28 @@ const routeModule = {
4837
4919
  handle: { label: config$c.label, translationNs: config$c.translationNs }
4838
4920
  },
4839
4921
  {
4840
- Component: LegalPage,
4841
- path: "/legal-documents",
4922
+ Component: MarketingPage,
4923
+ path: "/marketing",
4842
4924
  handle: { label: config$b.label, translationNs: config$b.translationNs }
4843
4925
  },
4844
4926
  {
4845
- Component: BillingPage,
4846
- path: "/billing",
4927
+ Component: ShippingPage,
4928
+ path: "/shipping",
4847
4929
  handle: { label: config$a.label, translationNs: config$a.translationNs }
4848
4930
  },
4849
4931
  {
4850
- Component: MarketingPage,
4851
- path: "/marketing",
4932
+ Component: SystemMonitoringPage,
4933
+ path: "/system-monitoring",
4852
4934
  handle: { label: config$9.label, translationNs: config$9.translationNs }
4853
4935
  },
4854
4936
  {
4855
- Component: ShippingPage,
4856
- path: "/shipping",
4937
+ Component: BillingPage,
4938
+ path: "/billing",
4857
4939
  handle: { label: config$8.label, translationNs: config$8.translationNs }
4858
4940
  },
4859
4941
  {
4860
- Component: SystemMonitoringPage,
4861
- path: "/system-monitoring",
4942
+ Component: LegalPage,
4943
+ path: "/legal-documents",
4862
4944
  handle: { label: config$7.label, translationNs: config$7.translationNs }
4863
4945
  },
4864
4946
  {
@@ -4871,8 +4953,8 @@ const routeModule = {
4871
4953
  path: "/marketing/seo"
4872
4954
  },
4873
4955
  {
4874
- Component: GoogleMerchantPage,
4875
- path: "/marketing/google-merchant",
4956
+ Component: CoreAuditPage,
4957
+ path: "/system-monitoring/audit",
4876
4958
  handle: { label: config$5.label, translationNs: config$5.translationNs }
4877
4959
  },
4878
4960
  {
@@ -4881,18 +4963,18 @@ const routeModule = {
4881
4963
  handle: { label: config$4.label, translationNs: config$4.translationNs }
4882
4964
  },
4883
4965
  {
4884
- Component: ProductionReadinessPage,
4885
- path: "/system-monitoring/readiness",
4966
+ Component: GoogleMerchantPage,
4967
+ path: "/marketing/google-merchant",
4886
4968
  handle: { label: config$3.label, translationNs: config$3.translationNs }
4887
4969
  },
4888
4970
  {
4889
- Component: CoreAuditPage,
4890
- path: "/system-monitoring/audit",
4971
+ Component: IntegrationOperationsPage,
4972
+ path: "/system-monitoring/operations",
4891
4973
  handle: { label: config$2.label, translationNs: config$2.translationNs }
4892
4974
  },
4893
4975
  {
4894
- Component: IntegrationOperationsPage,
4895
- path: "/system-monitoring/operations",
4976
+ Component: ProductionReadinessPage,
4977
+ path: "/system-monitoring/readiness",
4896
4978
  handle: { label: config$1.label, translationNs: config$1.translationNs }
4897
4979
  },
4898
4980
  {
@@ -4917,23 +4999,23 @@ const menuItemModule = {
4917
4999
  translationNs: void 0
4918
5000
  },
4919
5001
  {
4920
- label: config$a.label,
4921
- icon: config$a.icon,
5002
+ label: config$8.label,
5003
+ icon: config$8.icon,
4922
5004
  path: "/billing",
4923
5005
  nested: void 0,
4924
5006
  rank: 36,
4925
5007
  translationNs: void 0
4926
5008
  },
4927
5009
  {
4928
- label: config$b.label,
4929
- icon: config$b.icon,
5010
+ label: config$7.label,
5011
+ icon: config$7.icon,
4930
5012
  path: "/legal-documents",
4931
5013
  nested: void 0,
4932
5014
  rank: 40,
4933
5015
  translationNs: void 0
4934
5016
  },
4935
5017
  {
4936
- label: config$9.label,
5018
+ label: config$b.label,
4937
5019
  icon: void 0,
4938
5020
  path: "/marketing",
4939
5021
  nested: void 0,
@@ -4941,15 +5023,15 @@ const menuItemModule = {
4941
5023
  translationNs: void 0
4942
5024
  },
4943
5025
  {
4944
- label: config$8.label,
4945
- icon: config$8.icon,
5026
+ label: config$a.label,
5027
+ icon: config$a.icon,
4946
5028
  path: "/shipping",
4947
5029
  nested: void 0,
4948
5030
  rank: 35,
4949
5031
  translationNs: void 0
4950
5032
  },
4951
5033
  {
4952
- label: config$7.label,
5034
+ label: config$9.label,
4953
5035
  icon: void 0,
4954
5036
  path: "/system-monitoring",
4955
5037
  nested: void 0,
@@ -4957,15 +5039,15 @@ const menuItemModule = {
4957
5039
  translationNs: void 0
4958
5040
  },
4959
5041
  {
4960
- label: config$6.label,
5042
+ label: config.label,
4961
5043
  icon: void 0,
4962
- path: "/marketing/arukereso",
5044
+ path: "/settings/integrations",
4963
5045
  nested: void 0,
4964
- rank: 42,
5046
+ rank: void 0,
4965
5047
  translationNs: void 0
4966
5048
  },
4967
5049
  {
4968
- label: config$5.label,
5050
+ label: config$3.label,
4969
5051
  icon: void 0,
4970
5052
  path: "/marketing/google-merchant",
4971
5053
  nested: void 0,
@@ -4973,16 +5055,16 @@ const menuItemModule = {
4973
5055
  translationNs: void 0
4974
5056
  },
4975
5057
  {
4976
- label: config.label,
5058
+ label: config$6.label,
4977
5059
  icon: void 0,
4978
- path: "/settings/integrations",
5060
+ path: "/marketing/arukereso",
4979
5061
  nested: void 0,
4980
- rank: void 0,
5062
+ rank: 42,
4981
5063
  translationNs: void 0
4982
5064
  },
4983
5065
  {
4984
- label: config$2.label,
4985
- icon: config$2.icon,
5066
+ label: config$5.label,
5067
+ icon: config$5.icon,
4986
5068
  path: "/system-monitoring/audit",
4987
5069
  nested: void 0,
4988
5070
  rank: 39,
@@ -4997,15 +5079,15 @@ const menuItemModule = {
4997
5079
  translationNs: void 0
4998
5080
  },
4999
5081
  {
5000
- label: config$1.label,
5001
- icon: config$1.icon,
5082
+ label: config$2.label,
5083
+ icon: config$2.icon,
5002
5084
  path: "/system-monitoring/operations",
5003
5085
  nested: void 0,
5004
5086
  rank: 37,
5005
5087
  translationNs: void 0
5006
5088
  },
5007
5089
  {
5008
- label: config$3.label,
5090
+ label: config$1.label,
5009
5091
  icon: void 0,
5010
5092
  path: "/system-monitoring/readiness",
5011
5093
  nested: void 0,