@hszrdm/core 1.0.1 → 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.
|
@@ -1770,283 +1770,400 @@ const SystemMonitoringPage = () => /* @__PURE__ */ jsxs(Container, { className:
|
|
|
1770
1770
|
] }, item.href)) })
|
|
1771
1771
|
] });
|
|
1772
1772
|
const config$9 = defineRouteConfig({ label: "Rendszerfelügyelet" });
|
|
1773
|
-
const defaults$1 = {
|
|
1774
|
-
ARUKERESO_STOREFRONT_URL: "",
|
|
1775
|
-
ARUKERESO_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
1776
|
-
ARUKERESO_SALES_CHANNEL_ID: "",
|
|
1777
|
-
ARUKERESO_DEFAULT_MANUFACTURER: "",
|
|
1778
|
-
ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER: false,
|
|
1779
|
-
ARUKERESO_INCLUDE_OUT_OF_STOCK: true,
|
|
1780
|
-
ARUKERESO_DEFAULT_DELIVERY_TIME: "",
|
|
1781
|
-
ARUKERESO_DEFAULT_DELIVERY_COST: ""
|
|
1782
|
-
};
|
|
1783
1773
|
const backendUrl$a = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
1784
|
-
const
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
const [
|
|
1790
|
-
const [
|
|
1791
|
-
const [
|
|
1792
|
-
const
|
|
1793
|
-
|
|
1794
|
-
|
|
1774
|
+
const adminBase$5 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
1775
|
+
function apiUrl$a(path) {
|
|
1776
|
+
return `${backendUrl$a}${path.startsWith("/") ? path : `/${path}`}`;
|
|
1777
|
+
}
|
|
1778
|
+
const BillingPage = () => {
|
|
1779
|
+
const [orders, setOrders] = useState([]);
|
|
1780
|
+
const [configuration, setConfiguration] = useState(null);
|
|
1781
|
+
const [selected, setSelected] = useState([]);
|
|
1782
|
+
const [query, setQuery] = useState("");
|
|
1783
|
+
const [loading, setLoading] = useState(null);
|
|
1784
|
+
const [listLoading, setListLoading] = useState(true);
|
|
1785
|
+
const [loadError, setLoadError] = useState(null);
|
|
1795
1786
|
const load = useCallback(async () => {
|
|
1796
|
-
|
|
1787
|
+
setListLoading(true);
|
|
1788
|
+
setLoadError(null);
|
|
1797
1789
|
try {
|
|
1798
|
-
const response = await fetch(apiUrl$a("/admin/
|
|
1790
|
+
const response = await fetch(apiUrl$a("/admin/billingo/orders"), {
|
|
1799
1791
|
credentials: "include"
|
|
1800
1792
|
});
|
|
1801
|
-
const
|
|
1802
|
-
if (!response.ok
|
|
1803
|
-
throw new Error(
|
|
1793
|
+
const payload = await response.json().catch(() => ({}));
|
|
1794
|
+
if (!response.ok) {
|
|
1795
|
+
throw new Error(payload.message || "A számlázási lista nem tölthető be.");
|
|
1804
1796
|
}
|
|
1805
|
-
const
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
ARUKERESO_DEFAULT_MANUFACTURER: values.ARUKERESO_DEFAULT_MANUFACTURER || "",
|
|
1812
|
-
ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER: values.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER === "true",
|
|
1813
|
-
ARUKERESO_INCLUDE_OUT_OF_STOCK: values.ARUKERESO_INCLUDE_OUT_OF_STOCK !== "false",
|
|
1814
|
-
ARUKERESO_DEFAULT_DELIVERY_TIME: values.ARUKERESO_DEFAULT_DELIVERY_TIME || "",
|
|
1815
|
-
ARUKERESO_DEFAULT_DELIVERY_COST: values.ARUKERESO_DEFAULT_DELIVERY_COST || ""
|
|
1816
|
-
});
|
|
1797
|
+
const nextOrders = payload.orders || [];
|
|
1798
|
+
setOrders(nextOrders);
|
|
1799
|
+
setConfiguration(payload.configuration || null);
|
|
1800
|
+
setSelected(
|
|
1801
|
+
(current) => current.filter((id) => nextOrders.some((order) => order.id === id))
|
|
1802
|
+
);
|
|
1817
1803
|
} catch (error) {
|
|
1818
|
-
|
|
1804
|
+
setOrders([]);
|
|
1805
|
+
setLoadError(
|
|
1806
|
+
error instanceof Error ? error.message : "A számlázási lista nem tölthető be."
|
|
1807
|
+
);
|
|
1819
1808
|
} finally {
|
|
1820
|
-
|
|
1809
|
+
setListLoading(false);
|
|
1821
1810
|
}
|
|
1822
1811
|
}, []);
|
|
1823
1812
|
useEffect(() => {
|
|
1824
1813
|
void load();
|
|
1825
1814
|
}, [load]);
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1815
|
+
const visible = useMemo(() => {
|
|
1816
|
+
const value = query.trim().toLowerCase();
|
|
1817
|
+
if (!value) return orders;
|
|
1818
|
+
return orders.filter(
|
|
1819
|
+
(order) => [
|
|
1820
|
+
order.display_id,
|
|
1821
|
+
order.email,
|
|
1822
|
+
order.invoice?.invoiceNumber,
|
|
1823
|
+
order.invoice?.modificationInvoiceNumber
|
|
1824
|
+
].some(
|
|
1825
|
+
(item) => String(item || "").toLowerCase().includes(value)
|
|
1826
|
+
)
|
|
1827
|
+
);
|
|
1828
|
+
}, [orders, query]);
|
|
1829
|
+
const selectedSet = useMemo(() => new Set(selected), [selected]);
|
|
1830
|
+
const toggle = (id) => {
|
|
1831
|
+
setSelected(
|
|
1832
|
+
(current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id]
|
|
1833
|
+
);
|
|
1834
|
+
};
|
|
1835
|
+
const bulkCreate = async () => {
|
|
1836
|
+
if (!selected.length) {
|
|
1837
|
+
toast.error("Jelölj ki legalább egy rendelést.");
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
setLoading("bulk");
|
|
1828
1841
|
try {
|
|
1829
|
-
const response = await fetch(apiUrl$a("/admin/
|
|
1842
|
+
const response = await fetch(apiUrl$a("/admin/billingo/bulk/create"), {
|
|
1830
1843
|
method: "POST",
|
|
1831
1844
|
credentials: "include",
|
|
1832
1845
|
headers: { "Content-Type": "application/json" },
|
|
1833
|
-
body: JSON.stringify({
|
|
1846
|
+
body: JSON.stringify({ orderIds: selected })
|
|
1834
1847
|
});
|
|
1835
|
-
const
|
|
1836
|
-
if (!response.ok
|
|
1837
|
-
|
|
1838
|
-
|
|
1848
|
+
const payload = await response.json().catch(() => ({}));
|
|
1849
|
+
if (!response.ok && response.status !== 207) {
|
|
1850
|
+
throw new Error(payload.message || "A tömeges számlázás nem sikerült.");
|
|
1851
|
+
}
|
|
1852
|
+
const failed = payload.results?.filter((item) => !item.ok).length || 0;
|
|
1853
|
+
const created = payload.results?.filter(
|
|
1854
|
+
(item) => item.ok && !item.alreadyExisted
|
|
1855
|
+
).length || 0;
|
|
1856
|
+
if (failed) {
|
|
1857
|
+
toast.error(`${failed} számla nem készült el; ${created} sikeres.`);
|
|
1858
|
+
} else {
|
|
1859
|
+
toast.success(`${created} új számla elkészült.`);
|
|
1860
|
+
}
|
|
1839
1861
|
await load();
|
|
1840
1862
|
} catch (error) {
|
|
1841
|
-
toast.error(
|
|
1863
|
+
toast.error(
|
|
1864
|
+
error instanceof Error ? error.message : "A tömeges számlázás nem sikerült."
|
|
1865
|
+
);
|
|
1842
1866
|
} finally {
|
|
1843
|
-
|
|
1867
|
+
setLoading(null);
|
|
1844
1868
|
}
|
|
1845
1869
|
};
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1870
|
+
const action = async (order, value) => {
|
|
1871
|
+
if (value === "cancel" && !confirm(
|
|
1872
|
+
`Biztosan sztornózod a(z) ${order.invoice?.invoiceNumber || order.invoice?.documentId} számlát?`
|
|
1873
|
+
)) {
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
if (value === "modify" && !confirm(
|
|
1877
|
+
`Biztosan teljes jóváíró/módosító bizonylatot készítesz a(z) ${order.invoice?.invoiceNumber || order.invoice?.documentId} számlához? Ez a teljes számla összegét jóváírja.`
|
|
1878
|
+
)) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
setLoading(`${order.id}:${value}`);
|
|
1882
|
+
try {
|
|
1883
|
+
const response = await fetch(apiUrl$a(`/admin/orders/${order.id}/billingo`), {
|
|
1884
|
+
method: "POST",
|
|
1885
|
+
credentials: "include",
|
|
1886
|
+
headers: { "Content-Type": "application/json" },
|
|
1887
|
+
body: JSON.stringify({ action: value })
|
|
1888
|
+
});
|
|
1889
|
+
const payload = await response.json().catch(() => ({}));
|
|
1890
|
+
if (!response.ok) {
|
|
1891
|
+
throw new Error(payload.message || "A Billingo művelet nem sikerült.");
|
|
1892
|
+
}
|
|
1893
|
+
const messages = {
|
|
1894
|
+
create: "A számla elkészült.",
|
|
1895
|
+
sync: "A számla frissítve.",
|
|
1896
|
+
send: "A számla elküldve.",
|
|
1897
|
+
cancel: "A számla sztornózva.",
|
|
1898
|
+
modify: "A teljes jóváíró/módosító bizonylat elkészült."
|
|
1899
|
+
};
|
|
1900
|
+
toast.success(messages[value]);
|
|
1901
|
+
if (value === "modify" && payload.sendError) {
|
|
1902
|
+
toast.error(`A jóváírás elkészült, de az e-mail küldése sikertelen: ${payload.sendError}`);
|
|
1903
|
+
}
|
|
1904
|
+
await load();
|
|
1905
|
+
} catch (error) {
|
|
1906
|
+
toast.error(
|
|
1907
|
+
error instanceof Error ? error.message : "A Billingo művelet nem sikerült."
|
|
1908
|
+
);
|
|
1909
|
+
} finally {
|
|
1910
|
+
setLoading(null);
|
|
1911
|
+
}
|
|
1912
|
+
};
|
|
1913
|
+
const testConnection = async () => {
|
|
1914
|
+
setLoading("connection");
|
|
1848
1915
|
try {
|
|
1849
|
-
const response = await fetch(apiUrl$a("/admin/
|
|
1916
|
+
const response = await fetch(apiUrl$a("/admin/billingo/connection"), {
|
|
1917
|
+
method: "POST",
|
|
1850
1918
|
credentials: "include"
|
|
1851
1919
|
});
|
|
1852
|
-
const
|
|
1853
|
-
if (!response.ok)
|
|
1854
|
-
|
|
1855
|
-
|
|
1920
|
+
const payload = await response.json().catch(() => ({}));
|
|
1921
|
+
if (!response.ok) {
|
|
1922
|
+
throw new Error(payload.message || "A Billingo kapcsolat nem működik.");
|
|
1923
|
+
}
|
|
1924
|
+
toast.success(payload.message || "A Billingo kapcsolat működik.");
|
|
1856
1925
|
} catch (error) {
|
|
1857
|
-
toast.error(
|
|
1926
|
+
toast.error(
|
|
1927
|
+
error instanceof Error ? error.message : "A Billingo kapcsolat nem működik."
|
|
1928
|
+
);
|
|
1858
1929
|
} finally {
|
|
1859
|
-
|
|
1930
|
+
setLoading(null);
|
|
1860
1931
|
}
|
|
1861
1932
|
};
|
|
1862
|
-
const feedUrl = apiUrl$a("/feeds/arukereso.xml");
|
|
1863
|
-
const d = preview?.diagnostics;
|
|
1864
1933
|
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
1865
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-
|
|
1934
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
|
|
1866
1935
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1867
|
-
/* @__PURE__ */ jsx(Heading, { children: "
|
|
1868
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "
|
|
1936
|
+
/* @__PURE__ */ jsx(Heading, { children: "Számlázás" }),
|
|
1937
|
+
/* @__PURE__ */ jsx(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." }),
|
|
1938
|
+
configuration?.autoInvoice ? /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1939
|
+
"Az automatikus számlázás aktív",
|
|
1940
|
+
configuration.autoSend ? ", automatikus e-mail küldéssel" : "",
|
|
1941
|
+
"."
|
|
1942
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-warning", children: "Az automatikus számlázás ki van kapcsolva." })
|
|
1869
1943
|
] }),
|
|
1870
|
-
/* @__PURE__ */ jsxs("
|
|
1871
|
-
/* @__PURE__ */
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
|
|
1876
|
-
/* @__PURE__ */ jsx(Field$4, { label: "Storefront URL", children: /* @__PURE__ */ jsx(
|
|
1877
|
-
Input,
|
|
1878
|
-
{
|
|
1879
|
-
value: draft.ARUKERESO_STOREFRONT_URL,
|
|
1880
|
-
onChange: (e) => update("ARUKERESO_STOREFRONT_URL", e.target.value),
|
|
1881
|
-
placeholder: "https://shop.hu (üresen STOREFRONT_URL)"
|
|
1882
|
-
}
|
|
1883
|
-
) }),
|
|
1884
|
-
/* @__PURE__ */ jsxs(Field$4, { label: "Termék URL sablon", children: [
|
|
1944
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1945
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1946
|
+
selected.length,
|
|
1947
|
+
" kijelölve"
|
|
1948
|
+
] }),
|
|
1885
1949
|
/* @__PURE__ */ jsx(
|
|
1886
|
-
|
|
1950
|
+
Button,
|
|
1887
1951
|
{
|
|
1888
|
-
|
|
1889
|
-
|
|
1952
|
+
variant: "secondary",
|
|
1953
|
+
isLoading: loading === "connection",
|
|
1954
|
+
onClick: () => void testConnection(),
|
|
1955
|
+
children: "Kapcsolat tesztelése"
|
|
1890
1956
|
}
|
|
1891
|
-
)
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
"
|
|
1900
|
-
"
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
] })
|
|
1904
|
-
|
|
1957
|
+
)
|
|
1958
|
+
] })
|
|
1959
|
+
] }),
|
|
1960
|
+
configuration && !configuration.configured ? /* @__PURE__ */ jsxs("div", { className: "border-b border-ui-border-error bg-ui-bg-base px-6 py-4", children: [
|
|
1961
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "A Billingo még nincs teljesen beállítva." }),
|
|
1962
|
+
/* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-subtle", children: [
|
|
1963
|
+
"Hiányzik: ",
|
|
1964
|
+
[
|
|
1965
|
+
!configuration.apiKey && "API kulcs",
|
|
1966
|
+
!configuration.documentBlockId && "számlatömb azonosító"
|
|
1967
|
+
].filter(Boolean).join(", "),
|
|
1968
|
+
". Állítsd be a Settings → Integrációk → Billingo oldalon, majd indítsd újra a backendet."
|
|
1969
|
+
] })
|
|
1970
|
+
] }) : null,
|
|
1971
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 border-b px-6 py-4", children: [
|
|
1972
|
+
/* @__PURE__ */ jsx(
|
|
1905
1973
|
Input,
|
|
1906
1974
|
{
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1975
|
+
className: "max-w-sm",
|
|
1976
|
+
value: query,
|
|
1977
|
+
onChange: (event) => setQuery(event.target.value),
|
|
1978
|
+
placeholder: "Rendelés, e-mail vagy számlaszám keresése"
|
|
1910
1979
|
}
|
|
1911
|
-
)
|
|
1912
|
-
/* @__PURE__ */ jsx(
|
|
1913
|
-
|
|
1914
|
-
{
|
|
1915
|
-
value: draft.ARUKERESO_DEFAULT_MANUFACTURER,
|
|
1916
|
-
onChange: (e) => update("ARUKERESO_DEFAULT_MANUFACTURER", e.target.value),
|
|
1917
|
-
placeholder: "Csak ha minden termékre tényleg igaz"
|
|
1918
|
-
}
|
|
1919
|
-
) }),
|
|
1920
|
-
/* @__PURE__ */ jsx(Field$4, { label: "SKU mint gyártói cikkszám", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
1921
|
-
/* @__PURE__ */ jsx(
|
|
1922
|
-
Switch,
|
|
1923
|
-
{
|
|
1924
|
-
checked: draft.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER,
|
|
1925
|
-
onCheckedChange: (value) => update("ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER", value)
|
|
1926
|
-
}
|
|
1927
|
-
),
|
|
1928
|
-
/* @__PURE__ */ jsx(Text, { children: draft.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER ? "Igen" : "Nem" })
|
|
1929
|
-
] }) }),
|
|
1930
|
-
/* @__PURE__ */ jsx(Field$4, { label: "Készlethiányos termékek", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
1931
|
-
/* @__PURE__ */ jsx(
|
|
1932
|
-
Switch,
|
|
1933
|
-
{
|
|
1934
|
-
checked: draft.ARUKERESO_INCLUDE_OUT_OF_STOCK,
|
|
1935
|
-
onCheckedChange: (value) => update("ARUKERESO_INCLUDE_OUT_OF_STOCK", value)
|
|
1936
|
-
}
|
|
1937
|
-
),
|
|
1938
|
-
/* @__PURE__ */ jsx(Text, { children: draft.ARUKERESO_INCLUDE_OUT_OF_STOCK ? "DeliveryTime=NO" : "Kimaradnak" })
|
|
1939
|
-
] }) }),
|
|
1940
|
-
/* @__PURE__ */ jsx(Field$4, { label: "Alap szállítási idő", children: /* @__PURE__ */ jsx(
|
|
1941
|
-
Input,
|
|
1980
|
+
),
|
|
1981
|
+
/* @__PURE__ */ jsx(
|
|
1982
|
+
Button,
|
|
1942
1983
|
{
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1984
|
+
disabled: Boolean(loading) || !configuration?.configured,
|
|
1985
|
+
isLoading: loading === "bulk",
|
|
1986
|
+
onClick: () => void bulkCreate(),
|
|
1987
|
+
children: "Kijelöltek számlázása"
|
|
1946
1988
|
}
|
|
1947
|
-
)
|
|
1948
|
-
/* @__PURE__ */ jsx(
|
|
1949
|
-
|
|
1989
|
+
),
|
|
1990
|
+
/* @__PURE__ */ jsx(
|
|
1991
|
+
Button,
|
|
1950
1992
|
{
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1993
|
+
variant: "secondary",
|
|
1994
|
+
disabled: Boolean(loading),
|
|
1995
|
+
onClick: () => void load(),
|
|
1996
|
+
children: "Frissítés"
|
|
1954
1997
|
}
|
|
1955
|
-
)
|
|
1956
|
-
] }),
|
|
1957
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
|
|
1958
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1959
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Publikus feed URL" }),
|
|
1960
|
-
/* @__PURE__ */ jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
|
|
1961
|
-
] }),
|
|
1962
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1963
|
-
/* @__PURE__ */ jsx(
|
|
1964
|
-
Button,
|
|
1965
|
-
{
|
|
1966
|
-
variant: "secondary",
|
|
1967
|
-
isLoading: previewing,
|
|
1968
|
-
disabled: !enabled || loading || saving || previewing,
|
|
1969
|
-
onClick: () => void runPreview(),
|
|
1970
|
-
children: "Feed ellenőrzése"
|
|
1971
|
-
}
|
|
1972
|
-
),
|
|
1973
|
-
/* @__PURE__ */ jsx(
|
|
1974
|
-
Button,
|
|
1975
|
-
{
|
|
1976
|
-
isLoading: saving,
|
|
1977
|
-
disabled: loading || saving || previewing,
|
|
1978
|
-
onClick: () => void save(),
|
|
1979
|
-
children: "Mentés"
|
|
1980
|
-
}
|
|
1981
|
-
)
|
|
1982
|
-
] })
|
|
1998
|
+
)
|
|
1983
1999
|
] }),
|
|
1984
|
-
|
|
1985
|
-
/* @__PURE__ */ jsxs("
|
|
1986
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Termékek", value: d.productsScanned }),
|
|
1987
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Variantok", value: d.variantsScanned }),
|
|
1988
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Feed tételek", value: d.itemsEmitted }),
|
|
1989
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs gyártó", value: d.skippedNoManufacturer }),
|
|
1990
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs kategória", value: d.skippedNoCategory }),
|
|
1991
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs ár", value: d.skippedNoPrice }),
|
|
1992
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs ProductNumber", value: d.itemsMissingProductNumber }),
|
|
1993
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs kép", value: d.itemsMissingImage }),
|
|
1994
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Készlethiány miatt kimaradt", value: d.skippedOutOfStock }),
|
|
1995
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Sales channel hiba", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
|
|
1996
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Hibás delivery time", value: d.invalidDeliveryTime }),
|
|
1997
|
-
/* @__PURE__ */ jsx(Stat$1, { label: "Hibás delivery cost", value: d.invalidDeliveryCost })
|
|
1998
|
-
] }),
|
|
1999
|
-
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
2000
|
+
/* @__PURE__ */ jsxs("div", { className: "overflow-x-auto", children: [
|
|
2001
|
+
/* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
2000
2002
|
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2001
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children:
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2003
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: /* @__PURE__ */ jsx(
|
|
2004
|
+
Checkbox,
|
|
2005
|
+
{
|
|
2006
|
+
checked: visible.length > 0 && visible.every((order) => selectedSet.has(order.id)),
|
|
2007
|
+
onCheckedChange: () => setSelected(
|
|
2008
|
+
visible.every((order) => selectedSet.has(order.id)) ? selected.filter(
|
|
2009
|
+
(id) => !visible.some((order) => order.id === id)
|
|
2010
|
+
) : [
|
|
2011
|
+
.../* @__PURE__ */ new Set([
|
|
2012
|
+
...selected,
|
|
2013
|
+
...visible.map((order) => order.id)
|
|
2014
|
+
])
|
|
2015
|
+
]
|
|
2016
|
+
)
|
|
2017
|
+
}
|
|
2018
|
+
) }),
|
|
2019
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Rendelés" }),
|
|
2020
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Fizetés" }),
|
|
2021
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Számla" }),
|
|
2022
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Billingo státusz" }),
|
|
2023
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Műveletek" })
|
|
2007
2024
|
] }) }),
|
|
2008
|
-
/* @__PURE__ */ jsx("tbody", { children:
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2025
|
+
/* @__PURE__ */ jsx("tbody", { children: visible.map((order) => {
|
|
2026
|
+
const invoice = order.invoice;
|
|
2027
|
+
const last = order.operations?.at(-1);
|
|
2028
|
+
const modified = Boolean(invoice?.modificationDocumentId);
|
|
2029
|
+
return /* @__PURE__ */ jsxs("tr", { className: "border-b align-top", children: [
|
|
2030
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx(
|
|
2031
|
+
Checkbox,
|
|
2032
|
+
{
|
|
2033
|
+
checked: selectedSet.has(order.id),
|
|
2034
|
+
onCheckedChange: () => toggle(order.id)
|
|
2035
|
+
}
|
|
2036
|
+
) }),
|
|
2037
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2038
|
+
/* @__PURE__ */ jsxs(
|
|
2039
|
+
"a",
|
|
2040
|
+
{
|
|
2041
|
+
className: "text-ui-fg-interactive",
|
|
2042
|
+
href: `${adminBase$5}/orders/${order.id}`,
|
|
2043
|
+
children: [
|
|
2044
|
+
"#",
|
|
2045
|
+
order.display_id ?? order.id
|
|
2046
|
+
]
|
|
2047
|
+
}
|
|
2048
|
+
),
|
|
2049
|
+
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: order.email || "—" }),
|
|
2050
|
+
/* @__PURE__ */ jsx("div", { children: formatMoney(order.total, order.currency_code) })
|
|
2051
|
+
] }),
|
|
2052
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: order.payment_status === "captured" ? "Fizetve" : order.payment_status === "refunded" ? "Visszatérítve" : order.payment_status === "partially_refunded" ? "Részben visszatérítve" : order.payment_status || "—" }),
|
|
2053
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2054
|
+
/* @__PURE__ */ jsx("strong", { children: invoice?.invoiceNumber || (invoice ? `#${invoice.documentId}` : "Még nincs") }),
|
|
2055
|
+
invoice?.cancelled ? /* @__PURE__ */ jsx("div", { className: "text-ui-fg-error", children: "Sztornózva" }) : null,
|
|
2056
|
+
modified ? /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-interactive", children: [
|
|
2057
|
+
"Jóváírva: ",
|
|
2058
|
+
invoice?.modificationInvoiceNumber || `#${invoice?.modificationDocumentId}`
|
|
2059
|
+
] }) : null,
|
|
2060
|
+
last?.status === "failed" ? /* @__PURE__ */ jsx("div", { className: "max-w-xs text-ui-fg-error", children: last.message }) : null
|
|
2061
|
+
] }),
|
|
2062
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: invoice ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2063
|
+
/* @__PURE__ */ jsx("div", { children: invoice.paymentStatus || "—" }),
|
|
2064
|
+
/* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle", children: [
|
|
2065
|
+
"NAV: ",
|
|
2066
|
+
invoice.onlineSzamlaStatus || "—"
|
|
2067
|
+
] }),
|
|
2068
|
+
/* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle", children: [
|
|
2069
|
+
"E-mail: ",
|
|
2070
|
+
invoice.notificationStatus || "—"
|
|
2071
|
+
] })
|
|
2072
|
+
] }) : "—" }),
|
|
2073
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("div", { className: "flex max-w-lg flex-wrap gap-2", children: !invoice ? /* @__PURE__ */ jsx(
|
|
2074
|
+
Button,
|
|
2075
|
+
{
|
|
2076
|
+
size: "small",
|
|
2077
|
+
disabled: !configuration?.configured || Boolean(loading),
|
|
2078
|
+
isLoading: loading === `${order.id}:create`,
|
|
2079
|
+
onClick: () => void action(order, "create"),
|
|
2080
|
+
children: "Számla készítése"
|
|
2081
|
+
}
|
|
2082
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2083
|
+
/* @__PURE__ */ jsx(
|
|
2084
|
+
Button,
|
|
2085
|
+
{
|
|
2086
|
+
size: "small",
|
|
2087
|
+
variant: "secondary",
|
|
2088
|
+
disabled: Boolean(loading),
|
|
2089
|
+
isLoading: loading === `${order.id}:sync`,
|
|
2090
|
+
onClick: () => void action(order, "sync"),
|
|
2091
|
+
children: "Frissítés"
|
|
2092
|
+
}
|
|
2093
|
+
),
|
|
2094
|
+
/* @__PURE__ */ jsx(
|
|
2095
|
+
"a",
|
|
2096
|
+
{
|
|
2097
|
+
href: apiUrl$a(`/admin/orders/${order.id}/billingo/pdf`),
|
|
2098
|
+
target: "_blank",
|
|
2099
|
+
rel: "noreferrer",
|
|
2100
|
+
children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "PDF" })
|
|
2101
|
+
}
|
|
2102
|
+
),
|
|
2103
|
+
/* @__PURE__ */ jsx(
|
|
2104
|
+
Button,
|
|
2105
|
+
{
|
|
2106
|
+
size: "small",
|
|
2107
|
+
variant: "secondary",
|
|
2108
|
+
disabled: Boolean(loading) || invoice.cancelled,
|
|
2109
|
+
isLoading: loading === `${order.id}:send`,
|
|
2110
|
+
onClick: () => void action(order, "send"),
|
|
2111
|
+
children: "E-mail"
|
|
2112
|
+
}
|
|
2113
|
+
),
|
|
2114
|
+
/* @__PURE__ */ jsx(
|
|
2115
|
+
Button,
|
|
2116
|
+
{
|
|
2117
|
+
size: "small",
|
|
2118
|
+
variant: "secondary",
|
|
2119
|
+
disabled: Boolean(loading) || invoice.cancelled || modified,
|
|
2120
|
+
isLoading: loading === `${order.id}:modify`,
|
|
2121
|
+
onClick: () => void action(order, "modify"),
|
|
2122
|
+
children: "Teljes jóváírás"
|
|
2123
|
+
}
|
|
2124
|
+
),
|
|
2125
|
+
/* @__PURE__ */ jsx(
|
|
2126
|
+
Button,
|
|
2127
|
+
{
|
|
2128
|
+
size: "small",
|
|
2129
|
+
variant: "danger",
|
|
2130
|
+
disabled: Boolean(loading) || invoice.cancelled || modified,
|
|
2131
|
+
isLoading: loading === `${order.id}:cancel`,
|
|
2132
|
+
onClick: () => void action(order, "cancel"),
|
|
2133
|
+
children: "Sztornó"
|
|
2134
|
+
}
|
|
2135
|
+
)
|
|
2136
|
+
] }) }) })
|
|
2137
|
+
] }, order.id);
|
|
2138
|
+
}) })
|
|
2139
|
+
] }),
|
|
2140
|
+
listLoading ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Számlázási rendelések betöltése…" }) }) : null,
|
|
2141
|
+
!listLoading && loadError ? /* @__PURE__ */ jsxs("div", { className: "m-6 flex items-center justify-between gap-4 rounded-lg border border-ui-border-error p-4", children: [
|
|
2142
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2143
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "Betöltési hiba." }),
|
|
2144
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: loadError })
|
|
2145
|
+
] }),
|
|
2146
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => void load(), children: "Újrapróbálás" })
|
|
2147
|
+
] }) : null,
|
|
2148
|
+
!listLoading && !loadError && !visible.length ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Nincs megjeleníthető rendelés." }) }) : null
|
|
2149
|
+
] })
|
|
2033
2150
|
] });
|
|
2034
2151
|
};
|
|
2035
|
-
function
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-3", children: [
|
|
2043
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: label }),
|
|
2044
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: value })
|
|
2045
|
-
] });
|
|
2152
|
+
function formatMoney(value, currency) {
|
|
2153
|
+
if (typeof value !== "number") return "—";
|
|
2154
|
+
return new Intl.NumberFormat("hu-HU", {
|
|
2155
|
+
style: "currency",
|
|
2156
|
+
currency: (currency || "HUF").toUpperCase(),
|
|
2157
|
+
maximumFractionDigits: currency?.toUpperCase() === "HUF" ? 0 : 2
|
|
2158
|
+
}).format(value);
|
|
2046
2159
|
}
|
|
2047
|
-
const config$8 = defineRouteConfig({
|
|
2160
|
+
const config$8 = defineRouteConfig({
|
|
2161
|
+
label: "Számlázás",
|
|
2162
|
+
icon: Newspaper,
|
|
2163
|
+
rank: 36
|
|
2164
|
+
});
|
|
2048
2165
|
const backendUrl$9 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
2049
|
-
const adminBase$
|
|
2166
|
+
const adminBase$4 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
2050
2167
|
const apiUrl$9 = (path) => `${backendUrl$9}${path.startsWith("/") ? path : `/${path}`}`;
|
|
2051
2168
|
const LegalPage = () => {
|
|
2052
2169
|
const [documents, setDocuments] = useState([]);
|
|
@@ -2201,7 +2318,7 @@ const LegalPage = () => {
|
|
|
2201
2318
|
/* @__PURE__ */ jsx(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." })
|
|
2202
2319
|
] }),
|
|
2203
2320
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
2204
|
-
/* @__PURE__ */ jsx("a", { href: `${adminBase$
|
|
2321
|
+
/* @__PURE__ */ jsx("a", { href: `${adminBase$4}/settings/integrations`, children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Fogyasztó Barát embed" }) }),
|
|
2205
2322
|
/* @__PURE__ */ jsx(
|
|
2206
2323
|
Button,
|
|
2207
2324
|
{
|
|
@@ -2222,7 +2339,7 @@ const LegalPage = () => {
|
|
|
2222
2339
|
/* @__PURE__ */ jsx(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." })
|
|
2223
2340
|
] }),
|
|
2224
2341
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
|
|
2225
|
-
/* @__PURE__ */ jsx(Field$
|
|
2342
|
+
/* @__PURE__ */ jsx(Field$4, { label: "Dokumentum neve", children: /* @__PURE__ */ jsx(
|
|
2226
2343
|
Input,
|
|
2227
2344
|
{
|
|
2228
2345
|
value: title,
|
|
@@ -2230,7 +2347,7 @@ const LegalPage = () => {
|
|
|
2230
2347
|
placeholder: "Általános Szerződési Feltételek"
|
|
2231
2348
|
}
|
|
2232
2349
|
) }),
|
|
2233
|
-
/* @__PURE__ */ jsx(Field$
|
|
2350
|
+
/* @__PURE__ */ jsx(Field$4, { label: "Kulcs", children: /* @__PURE__ */ jsx(
|
|
2234
2351
|
Input,
|
|
2235
2352
|
{
|
|
2236
2353
|
value: key,
|
|
@@ -2238,7 +2355,7 @@ const LegalPage = () => {
|
|
|
2238
2355
|
placeholder: "terms"
|
|
2239
2356
|
}
|
|
2240
2357
|
) }),
|
|
2241
|
-
/* @__PURE__ */ jsx(Field$
|
|
2358
|
+
/* @__PURE__ */ jsx(Field$4, { label: "Típus", children: /* @__PURE__ */ jsxs(
|
|
2242
2359
|
"select",
|
|
2243
2360
|
{
|
|
2244
2361
|
className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm",
|
|
@@ -2252,7 +2369,7 @@ const LegalPage = () => {
|
|
|
2252
2369
|
]
|
|
2253
2370
|
}
|
|
2254
2371
|
) }),
|
|
2255
|
-
/* @__PURE__ */ jsxs(Field$
|
|
2372
|
+
/* @__PURE__ */ jsxs(Field$4, { label: "PDF fájl (max. 5 MB)", children: [
|
|
2256
2373
|
/* @__PURE__ */ jsx(
|
|
2257
2374
|
"input",
|
|
2258
2375
|
{
|
|
@@ -2393,7 +2510,7 @@ const LegalPage = () => {
|
|
|
2393
2510
|
"a",
|
|
2394
2511
|
{
|
|
2395
2512
|
className: "text-ui-fg-interactive",
|
|
2396
|
-
href: `${adminBase$
|
|
2513
|
+
href: `${adminBase$4}/orders/${consent.orderId}`,
|
|
2397
2514
|
children: consent.orderId
|
|
2398
2515
|
}
|
|
2399
2516
|
) : "Még nincs rendelés" }),
|
|
@@ -2403,7 +2520,7 @@ const LegalPage = () => {
|
|
|
2403
2520
|
] }) })
|
|
2404
2521
|
] }) });
|
|
2405
2522
|
};
|
|
2406
|
-
function Field$
|
|
2523
|
+
function Field$4({
|
|
2407
2524
|
label,
|
|
2408
2525
|
children
|
|
2409
2526
|
}) {
|
|
@@ -2449,398 +2566,281 @@ const config$7 = defineRouteConfig({
|
|
|
2449
2566
|
icon: Newspaper,
|
|
2450
2567
|
rank: 40
|
|
2451
2568
|
});
|
|
2569
|
+
const defaults$1 = {
|
|
2570
|
+
ARUKERESO_STOREFRONT_URL: "",
|
|
2571
|
+
ARUKERESO_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
2572
|
+
ARUKERESO_SALES_CHANNEL_ID: "",
|
|
2573
|
+
ARUKERESO_DEFAULT_MANUFACTURER: "",
|
|
2574
|
+
ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER: false,
|
|
2575
|
+
ARUKERESO_INCLUDE_OUT_OF_STOCK: true,
|
|
2576
|
+
ARUKERESO_DEFAULT_DELIVERY_TIME: "",
|
|
2577
|
+
ARUKERESO_DEFAULT_DELIVERY_COST: ""
|
|
2578
|
+
};
|
|
2452
2579
|
const backendUrl$8 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
2453
|
-
const
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
const
|
|
2458
|
-
const [
|
|
2459
|
-
const [
|
|
2460
|
-
const [
|
|
2461
|
-
const
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
const [loadError, setLoadError] = useState(null);
|
|
2580
|
+
const apiUrl$8 = (path) => `${backendUrl$8}${path.startsWith("/") ? path : `/${path}`}`;
|
|
2581
|
+
const ArukeresoPage = () => {
|
|
2582
|
+
const [enabled, setEnabled] = useState(false);
|
|
2583
|
+
const [draft, setDraft] = useState(defaults$1);
|
|
2584
|
+
const [loading, setLoading] = useState(true);
|
|
2585
|
+
const [saving, setSaving] = useState(false);
|
|
2586
|
+
const [previewing, setPreviewing] = useState(false);
|
|
2587
|
+
const [preview, setPreview] = useState(null);
|
|
2588
|
+
const update = (key, value) => {
|
|
2589
|
+
setDraft((current) => ({ ...current, [key]: value }));
|
|
2590
|
+
};
|
|
2465
2591
|
const load = useCallback(async () => {
|
|
2466
|
-
|
|
2467
|
-
setLoadError(null);
|
|
2592
|
+
setLoading(true);
|
|
2468
2593
|
try {
|
|
2469
|
-
const response = await fetch(apiUrl$8("/admin/
|
|
2594
|
+
const response = await fetch(apiUrl$8("/admin/integrations/arukereso"), {
|
|
2470
2595
|
credentials: "include"
|
|
2471
2596
|
});
|
|
2472
|
-
const
|
|
2473
|
-
if (!response.ok) {
|
|
2474
|
-
throw new Error(
|
|
2597
|
+
const data = await response.json().catch(() => ({}));
|
|
2598
|
+
if (!response.ok || !data.integration) {
|
|
2599
|
+
throw new Error(data.message || "Az Árukereső beállítások nem tölthetők be.");
|
|
2475
2600
|
}
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2601
|
+
const values = data.integration.values || {};
|
|
2602
|
+
setEnabled(Boolean(data.integration.enabled));
|
|
2603
|
+
setDraft({
|
|
2604
|
+
ARUKERESO_STOREFRONT_URL: values.ARUKERESO_STOREFRONT_URL || "",
|
|
2605
|
+
ARUKERESO_PRODUCT_PATH_TEMPLATE: values.ARUKERESO_PRODUCT_PATH_TEMPLATE || "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
2606
|
+
ARUKERESO_SALES_CHANNEL_ID: values.ARUKERESO_SALES_CHANNEL_ID || "",
|
|
2607
|
+
ARUKERESO_DEFAULT_MANUFACTURER: values.ARUKERESO_DEFAULT_MANUFACTURER || "",
|
|
2608
|
+
ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER: values.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER === "true",
|
|
2609
|
+
ARUKERESO_INCLUDE_OUT_OF_STOCK: values.ARUKERESO_INCLUDE_OUT_OF_STOCK !== "false",
|
|
2610
|
+
ARUKERESO_DEFAULT_DELIVERY_TIME: values.ARUKERESO_DEFAULT_DELIVERY_TIME || "",
|
|
2611
|
+
ARUKERESO_DEFAULT_DELIVERY_COST: values.ARUKERESO_DEFAULT_DELIVERY_COST || ""
|
|
2612
|
+
});
|
|
2482
2613
|
} catch (error) {
|
|
2483
|
-
|
|
2484
|
-
setLoadError(
|
|
2485
|
-
error instanceof Error ? error.message : "A számlázási lista nem tölthető be."
|
|
2486
|
-
);
|
|
2614
|
+
toast.error(error instanceof Error ? error.message : "Betöltési hiba.");
|
|
2487
2615
|
} finally {
|
|
2488
|
-
|
|
2616
|
+
setLoading(false);
|
|
2489
2617
|
}
|
|
2490
2618
|
}, []);
|
|
2491
2619
|
useEffect(() => {
|
|
2492
2620
|
void load();
|
|
2493
2621
|
}, [load]);
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2496
|
-
if (!value) return orders;
|
|
2497
|
-
return orders.filter(
|
|
2498
|
-
(order) => [
|
|
2499
|
-
order.display_id,
|
|
2500
|
-
order.email,
|
|
2501
|
-
order.invoice?.invoiceNumber,
|
|
2502
|
-
order.invoice?.modificationInvoiceNumber
|
|
2503
|
-
].some(
|
|
2504
|
-
(item) => String(item || "").toLowerCase().includes(value)
|
|
2505
|
-
)
|
|
2506
|
-
);
|
|
2507
|
-
}, [orders, query]);
|
|
2508
|
-
const selectedSet = useMemo(() => new Set(selected), [selected]);
|
|
2509
|
-
const toggle = (id) => {
|
|
2510
|
-
setSelected(
|
|
2511
|
-
(current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id]
|
|
2512
|
-
);
|
|
2513
|
-
};
|
|
2514
|
-
const bulkCreate = async () => {
|
|
2515
|
-
if (!selected.length) {
|
|
2516
|
-
toast.error("Jelölj ki legalább egy rendelést.");
|
|
2517
|
-
return;
|
|
2518
|
-
}
|
|
2519
|
-
setLoading("bulk");
|
|
2520
|
-
try {
|
|
2521
|
-
const response = await fetch(apiUrl$8("/admin/billingo/bulk/create"), {
|
|
2522
|
-
method: "POST",
|
|
2523
|
-
credentials: "include",
|
|
2524
|
-
headers: { "Content-Type": "application/json" },
|
|
2525
|
-
body: JSON.stringify({ orderIds: selected })
|
|
2526
|
-
});
|
|
2527
|
-
const payload = await response.json().catch(() => ({}));
|
|
2528
|
-
if (!response.ok && response.status !== 207) {
|
|
2529
|
-
throw new Error(payload.message || "A tömeges számlázás nem sikerült.");
|
|
2530
|
-
}
|
|
2531
|
-
const failed = payload.results?.filter((item) => !item.ok).length || 0;
|
|
2532
|
-
const created = payload.results?.filter(
|
|
2533
|
-
(item) => item.ok && !item.alreadyExisted
|
|
2534
|
-
).length || 0;
|
|
2535
|
-
if (failed) {
|
|
2536
|
-
toast.error(`${failed} számla nem készült el; ${created} sikeres.`);
|
|
2537
|
-
} else {
|
|
2538
|
-
toast.success(`${created} új számla elkészült.`);
|
|
2539
|
-
}
|
|
2540
|
-
await load();
|
|
2541
|
-
} catch (error) {
|
|
2542
|
-
toast.error(
|
|
2543
|
-
error instanceof Error ? error.message : "A tömeges számlázás nem sikerült."
|
|
2544
|
-
);
|
|
2545
|
-
} finally {
|
|
2546
|
-
setLoading(null);
|
|
2547
|
-
}
|
|
2548
|
-
};
|
|
2549
|
-
const action = async (order, value) => {
|
|
2550
|
-
if (value === "cancel" && !confirm(
|
|
2551
|
-
`Biztosan sztornózod a(z) ${order.invoice?.invoiceNumber || order.invoice?.documentId} számlát?`
|
|
2552
|
-
)) {
|
|
2553
|
-
return;
|
|
2554
|
-
}
|
|
2555
|
-
if (value === "modify" && !confirm(
|
|
2556
|
-
`Biztosan teljes jóváíró/módosító bizonylatot készítesz a(z) ${order.invoice?.invoiceNumber || order.invoice?.documentId} számlához? Ez a teljes számla összegét jóváírja.`
|
|
2557
|
-
)) {
|
|
2558
|
-
return;
|
|
2559
|
-
}
|
|
2560
|
-
setLoading(`${order.id}:${value}`);
|
|
2622
|
+
const save = async () => {
|
|
2623
|
+
setSaving(true);
|
|
2561
2624
|
try {
|
|
2562
|
-
const response = await fetch(apiUrl$8(
|
|
2625
|
+
const response = await fetch(apiUrl$8("/admin/integrations/arukereso"), {
|
|
2563
2626
|
method: "POST",
|
|
2564
2627
|
credentials: "include",
|
|
2565
2628
|
headers: { "Content-Type": "application/json" },
|
|
2566
|
-
body: JSON.stringify({
|
|
2629
|
+
body: JSON.stringify({ enabled, values: draft })
|
|
2567
2630
|
});
|
|
2568
|
-
const
|
|
2569
|
-
if (!response.ok)
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
const messages = {
|
|
2573
|
-
create: "A számla elkészült.",
|
|
2574
|
-
sync: "A számla frissítve.",
|
|
2575
|
-
send: "A számla elküldve.",
|
|
2576
|
-
cancel: "A számla sztornózva.",
|
|
2577
|
-
modify: "A teljes jóváíró/módosító bizonylat elkészült."
|
|
2578
|
-
};
|
|
2579
|
-
toast.success(messages[value]);
|
|
2580
|
-
if (value === "modify" && payload.sendError) {
|
|
2581
|
-
toast.error(`A jóváírás elkészült, de az e-mail küldése sikertelen: ${payload.sendError}`);
|
|
2582
|
-
}
|
|
2631
|
+
const data = await response.json().catch(() => ({}));
|
|
2632
|
+
if (!response.ok) throw new Error(data.message || "A mentés nem sikerült.");
|
|
2633
|
+
toast.success(data.message || "Árukereső beállítások mentve.");
|
|
2634
|
+
setPreview(null);
|
|
2583
2635
|
await load();
|
|
2584
2636
|
} catch (error) {
|
|
2585
|
-
toast.error(
|
|
2586
|
-
error instanceof Error ? error.message : "A Billingo művelet nem sikerült."
|
|
2587
|
-
);
|
|
2637
|
+
toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
|
|
2588
2638
|
} finally {
|
|
2589
|
-
|
|
2639
|
+
setSaving(false);
|
|
2590
2640
|
}
|
|
2591
2641
|
};
|
|
2592
|
-
const
|
|
2593
|
-
|
|
2642
|
+
const runPreview = async () => {
|
|
2643
|
+
setPreviewing(true);
|
|
2594
2644
|
try {
|
|
2595
|
-
const response = await fetch(apiUrl$8("/admin/
|
|
2596
|
-
method: "POST",
|
|
2645
|
+
const response = await fetch(apiUrl$8("/admin/arukereso/preview"), {
|
|
2597
2646
|
credentials: "include"
|
|
2598
2647
|
});
|
|
2599
|
-
const
|
|
2600
|
-
if (!response.ok)
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
toast.success(payload.message || "A Billingo kapcsolat működik.");
|
|
2648
|
+
const data = await response.json().catch(() => ({}));
|
|
2649
|
+
if (!response.ok) throw new Error(data.message || "A feed nem generálható.");
|
|
2650
|
+
setPreview(data);
|
|
2651
|
+
toast.success("Az Árukereső feed ellenőrzése elkészült.");
|
|
2604
2652
|
} catch (error) {
|
|
2605
|
-
toast.error(
|
|
2606
|
-
error instanceof Error ? error.message : "A Billingo kapcsolat nem működik."
|
|
2607
|
-
);
|
|
2653
|
+
toast.error(error instanceof Error ? error.message : "A feed nem generálható.");
|
|
2608
2654
|
} finally {
|
|
2609
|
-
|
|
2655
|
+
setPreviewing(false);
|
|
2610
2656
|
}
|
|
2611
2657
|
};
|
|
2658
|
+
const feedUrl = apiUrl$8("/feeds/arukereso.xml");
|
|
2659
|
+
const d = preview?.diagnostics;
|
|
2612
2660
|
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
2613
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-
|
|
2661
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-4", children: [
|
|
2614
2662
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2615
|
-
/* @__PURE__ */ jsx(Heading, { children: "
|
|
2616
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "
|
|
2617
|
-
configuration?.autoInvoice ? /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
2618
|
-
"Az automatikus számlázás aktív",
|
|
2619
|
-
configuration.autoSend ? ", automatikus e-mail küldéssel" : "",
|
|
2620
|
-
"."
|
|
2621
|
-
] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-warning", children: "Az automatikus számlázás ki van kapcsolva." })
|
|
2663
|
+
/* @__PURE__ */ jsx(Heading, { children: "Árukereső.hu" }),
|
|
2664
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Árukereső XML feed a Medusa termék-, variant-, HU/HUF ár-, ÁFA- és készletadataiból." })
|
|
2622
2665
|
] }),
|
|
2623
|
-
/* @__PURE__ */ jsxs("
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2666
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
2667
|
+
/* @__PURE__ */ jsx(Switch, { checked: enabled, onCheckedChange: setEnabled, disabled: loading }),
|
|
2668
|
+
/* @__PURE__ */ jsx(Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
|
|
2669
|
+
] })
|
|
2670
|
+
] }),
|
|
2671
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
|
|
2672
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Storefront URL", children: /* @__PURE__ */ jsx(
|
|
2673
|
+
Input,
|
|
2674
|
+
{
|
|
2675
|
+
value: draft.ARUKERESO_STOREFRONT_URL,
|
|
2676
|
+
onChange: (e) => update("ARUKERESO_STOREFRONT_URL", e.target.value),
|
|
2677
|
+
placeholder: "https://shop.hu (üresen STOREFRONT_URL)"
|
|
2678
|
+
}
|
|
2679
|
+
) }),
|
|
2680
|
+
/* @__PURE__ */ jsxs(Field$3, { label: "Termék URL sablon", children: [
|
|
2628
2681
|
/* @__PURE__ */ jsx(
|
|
2629
|
-
|
|
2682
|
+
Input,
|
|
2630
2683
|
{
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
onClick: () => void testConnection(),
|
|
2634
|
-
children: "Kapcsolat tesztelése"
|
|
2684
|
+
value: draft.ARUKERESO_PRODUCT_PATH_TEMPLATE,
|
|
2685
|
+
onChange: (e) => update("ARUKERESO_PRODUCT_PATH_TEMPLATE", e.target.value)
|
|
2635
2686
|
}
|
|
2636
|
-
)
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
] })
|
|
2649
|
-
|
|
2650
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 border-b px-6 py-4", children: [
|
|
2651
|
-
/* @__PURE__ */ jsx(
|
|
2687
|
+
),
|
|
2688
|
+
/* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-xs", children: [
|
|
2689
|
+
"Helyőrzők: ",
|
|
2690
|
+
"{country_code}",
|
|
2691
|
+
", ",
|
|
2692
|
+
"{currency_code}",
|
|
2693
|
+
", ",
|
|
2694
|
+
"{handle}",
|
|
2695
|
+
", ",
|
|
2696
|
+
"{variant_id}",
|
|
2697
|
+
"."
|
|
2698
|
+
] })
|
|
2699
|
+
] }),
|
|
2700
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Sales Channel ID", children: /* @__PURE__ */ jsx(
|
|
2652
2701
|
Input,
|
|
2653
2702
|
{
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
placeholder: "Rendelés, e-mail vagy számlaszám keresése"
|
|
2703
|
+
value: draft.ARUKERESO_SALES_CHANNEL_ID,
|
|
2704
|
+
onChange: (e) => update("ARUKERESO_SALES_CHANNEL_ID", e.target.value),
|
|
2705
|
+
placeholder: "sc_... (opcionális)"
|
|
2658
2706
|
}
|
|
2659
|
-
),
|
|
2660
|
-
/* @__PURE__ */ jsx(
|
|
2661
|
-
|
|
2707
|
+
) }),
|
|
2708
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Alapértelmezett gyártó", children: /* @__PURE__ */ jsx(
|
|
2709
|
+
Input,
|
|
2662
2710
|
{
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
children: "Kijelöltek számlázása"
|
|
2711
|
+
value: draft.ARUKERESO_DEFAULT_MANUFACTURER,
|
|
2712
|
+
onChange: (e) => update("ARUKERESO_DEFAULT_MANUFACTURER", e.target.value),
|
|
2713
|
+
placeholder: "Csak ha minden termékre tényleg igaz"
|
|
2667
2714
|
}
|
|
2668
|
-
),
|
|
2669
|
-
/* @__PURE__ */ jsx(
|
|
2670
|
-
|
|
2715
|
+
) }),
|
|
2716
|
+
/* @__PURE__ */ jsx(Field$3, { label: "SKU mint gyártói cikkszám", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
2717
|
+
/* @__PURE__ */ jsx(
|
|
2718
|
+
Switch,
|
|
2719
|
+
{
|
|
2720
|
+
checked: draft.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER,
|
|
2721
|
+
onCheckedChange: (value) => update("ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER", value)
|
|
2722
|
+
}
|
|
2723
|
+
),
|
|
2724
|
+
/* @__PURE__ */ jsx(Text, { children: draft.ARUKERESO_USE_SKU_AS_PRODUCT_NUMBER ? "Igen" : "Nem" })
|
|
2725
|
+
] }) }),
|
|
2726
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Készlethiányos termékek", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
2727
|
+
/* @__PURE__ */ jsx(
|
|
2728
|
+
Switch,
|
|
2729
|
+
{
|
|
2730
|
+
checked: draft.ARUKERESO_INCLUDE_OUT_OF_STOCK,
|
|
2731
|
+
onCheckedChange: (value) => update("ARUKERESO_INCLUDE_OUT_OF_STOCK", value)
|
|
2732
|
+
}
|
|
2733
|
+
),
|
|
2734
|
+
/* @__PURE__ */ jsx(Text, { children: draft.ARUKERESO_INCLUDE_OUT_OF_STOCK ? "DeliveryTime=NO" : "Kimaradnak" })
|
|
2735
|
+
] }) }),
|
|
2736
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Alap szállítási idő", children: /* @__PURE__ */ jsx(
|
|
2737
|
+
Input,
|
|
2671
2738
|
{
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
children: "Frissítés"
|
|
2739
|
+
value: draft.ARUKERESO_DEFAULT_DELIVERY_TIME,
|
|
2740
|
+
onChange: (e) => update("ARUKERESO_DEFAULT_DELIVERY_TIME", e.target.value),
|
|
2741
|
+
placeholder: "1 vagy 3"
|
|
2676
2742
|
}
|
|
2677
|
-
)
|
|
2743
|
+
) }),
|
|
2744
|
+
/* @__PURE__ */ jsx(Field$3, { label: "Alap szállítási költség", children: /* @__PURE__ */ jsx(
|
|
2745
|
+
Input,
|
|
2746
|
+
{
|
|
2747
|
+
value: draft.ARUKERESO_DEFAULT_DELIVERY_COST,
|
|
2748
|
+
onChange: (e) => update("ARUKERESO_DEFAULT_DELIVERY_COST", e.target.value),
|
|
2749
|
+
placeholder: "1990 vagy FREE"
|
|
2750
|
+
}
|
|
2751
|
+
) })
|
|
2678
2752
|
] }),
|
|
2679
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2680
|
-
/* @__PURE__ */ jsxs("
|
|
2681
|
-
/* @__PURE__ */ jsx(
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
className: "text-ui-fg-interactive",
|
|
2721
|
-
href: `${adminBase$4}/orders/${order.id}`,
|
|
2722
|
-
children: [
|
|
2723
|
-
"#",
|
|
2724
|
-
order.display_id ?? order.id
|
|
2725
|
-
]
|
|
2726
|
-
}
|
|
2727
|
-
),
|
|
2728
|
-
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: order.email || "—" }),
|
|
2729
|
-
/* @__PURE__ */ jsx("div", { children: formatMoney(order.total, order.currency_code) })
|
|
2730
|
-
] }),
|
|
2731
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: order.payment_status === "captured" ? "Fizetve" : order.payment_status === "refunded" ? "Visszatérítve" : order.payment_status === "partially_refunded" ? "Részben visszatérítve" : order.payment_status || "—" }),
|
|
2732
|
-
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2733
|
-
/* @__PURE__ */ jsx("strong", { children: invoice?.invoiceNumber || (invoice ? `#${invoice.documentId}` : "Még nincs") }),
|
|
2734
|
-
invoice?.cancelled ? /* @__PURE__ */ jsx("div", { className: "text-ui-fg-error", children: "Sztornózva" }) : null,
|
|
2735
|
-
modified ? /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-interactive", children: [
|
|
2736
|
-
"Jóváírva: ",
|
|
2737
|
-
invoice?.modificationInvoiceNumber || `#${invoice?.modificationDocumentId}`
|
|
2738
|
-
] }) : null,
|
|
2739
|
-
last?.status === "failed" ? /* @__PURE__ */ jsx("div", { className: "max-w-xs text-ui-fg-error", children: last.message }) : null
|
|
2740
|
-
] }),
|
|
2741
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: invoice ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2742
|
-
/* @__PURE__ */ jsx("div", { children: invoice.paymentStatus || "—" }),
|
|
2743
|
-
/* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle", children: [
|
|
2744
|
-
"NAV: ",
|
|
2745
|
-
invoice.onlineSzamlaStatus || "—"
|
|
2746
|
-
] }),
|
|
2747
|
-
/* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle", children: [
|
|
2748
|
-
"E-mail: ",
|
|
2749
|
-
invoice.notificationStatus || "—"
|
|
2750
|
-
] })
|
|
2751
|
-
] }) : "—" }),
|
|
2752
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("div", { className: "flex max-w-lg flex-wrap gap-2", children: !invoice ? /* @__PURE__ */ jsx(
|
|
2753
|
-
Button,
|
|
2754
|
-
{
|
|
2755
|
-
size: "small",
|
|
2756
|
-
disabled: !configuration?.configured || Boolean(loading),
|
|
2757
|
-
isLoading: loading === `${order.id}:create`,
|
|
2758
|
-
onClick: () => void action(order, "create"),
|
|
2759
|
-
children: "Számla készítése"
|
|
2760
|
-
}
|
|
2761
|
-
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2762
|
-
/* @__PURE__ */ jsx(
|
|
2763
|
-
Button,
|
|
2764
|
-
{
|
|
2765
|
-
size: "small",
|
|
2766
|
-
variant: "secondary",
|
|
2767
|
-
disabled: Boolean(loading),
|
|
2768
|
-
isLoading: loading === `${order.id}:sync`,
|
|
2769
|
-
onClick: () => void action(order, "sync"),
|
|
2770
|
-
children: "Frissítés"
|
|
2771
|
-
}
|
|
2772
|
-
),
|
|
2773
|
-
/* @__PURE__ */ jsx(
|
|
2774
|
-
"a",
|
|
2775
|
-
{
|
|
2776
|
-
href: apiUrl$8(`/admin/orders/${order.id}/billingo/pdf`),
|
|
2777
|
-
target: "_blank",
|
|
2778
|
-
rel: "noreferrer",
|
|
2779
|
-
children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "PDF" })
|
|
2780
|
-
}
|
|
2781
|
-
),
|
|
2782
|
-
/* @__PURE__ */ jsx(
|
|
2783
|
-
Button,
|
|
2784
|
-
{
|
|
2785
|
-
size: "small",
|
|
2786
|
-
variant: "secondary",
|
|
2787
|
-
disabled: Boolean(loading) || invoice.cancelled,
|
|
2788
|
-
isLoading: loading === `${order.id}:send`,
|
|
2789
|
-
onClick: () => void action(order, "send"),
|
|
2790
|
-
children: "E-mail"
|
|
2791
|
-
}
|
|
2792
|
-
),
|
|
2793
|
-
/* @__PURE__ */ jsx(
|
|
2794
|
-
Button,
|
|
2795
|
-
{
|
|
2796
|
-
size: "small",
|
|
2797
|
-
variant: "secondary",
|
|
2798
|
-
disabled: Boolean(loading) || invoice.cancelled || modified,
|
|
2799
|
-
isLoading: loading === `${order.id}:modify`,
|
|
2800
|
-
onClick: () => void action(order, "modify"),
|
|
2801
|
-
children: "Teljes jóváírás"
|
|
2802
|
-
}
|
|
2803
|
-
),
|
|
2804
|
-
/* @__PURE__ */ jsx(
|
|
2805
|
-
Button,
|
|
2806
|
-
{
|
|
2807
|
-
size: "small",
|
|
2808
|
-
variant: "danger",
|
|
2809
|
-
disabled: Boolean(loading) || invoice.cancelled || modified,
|
|
2810
|
-
isLoading: loading === `${order.id}:cancel`,
|
|
2811
|
-
onClick: () => void action(order, "cancel"),
|
|
2812
|
-
children: "Sztornó"
|
|
2813
|
-
}
|
|
2814
|
-
)
|
|
2815
|
-
] }) }) })
|
|
2816
|
-
] }, order.id);
|
|
2817
|
-
}) })
|
|
2753
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
|
|
2754
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2755
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Publikus feed URL" }),
|
|
2756
|
+
/* @__PURE__ */ jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
|
|
2757
|
+
] }),
|
|
2758
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
2759
|
+
/* @__PURE__ */ jsx(
|
|
2760
|
+
Button,
|
|
2761
|
+
{
|
|
2762
|
+
variant: "secondary",
|
|
2763
|
+
isLoading: previewing,
|
|
2764
|
+
disabled: !enabled || loading || saving || previewing,
|
|
2765
|
+
onClick: () => void runPreview(),
|
|
2766
|
+
children: "Feed ellenőrzése"
|
|
2767
|
+
}
|
|
2768
|
+
),
|
|
2769
|
+
/* @__PURE__ */ jsx(
|
|
2770
|
+
Button,
|
|
2771
|
+
{
|
|
2772
|
+
isLoading: saving,
|
|
2773
|
+
disabled: loading || saving || previewing,
|
|
2774
|
+
onClick: () => void save(),
|
|
2775
|
+
children: "Mentés"
|
|
2776
|
+
}
|
|
2777
|
+
)
|
|
2778
|
+
] })
|
|
2779
|
+
] }),
|
|
2780
|
+
d ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2781
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b px-6 py-5 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
2782
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Termékek", value: d.productsScanned }),
|
|
2783
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Variantok", value: d.variantsScanned }),
|
|
2784
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Feed tételek", value: d.itemsEmitted }),
|
|
2785
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs gyártó", value: d.skippedNoManufacturer }),
|
|
2786
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs kategória", value: d.skippedNoCategory }),
|
|
2787
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs ár", value: d.skippedNoPrice }),
|
|
2788
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs ProductNumber", value: d.itemsMissingProductNumber }),
|
|
2789
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Nincs kép", value: d.itemsMissingImage }),
|
|
2790
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Készlethiány miatt kimaradt", value: d.skippedOutOfStock }),
|
|
2791
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Sales channel hiba", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
|
|
2792
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Hibás delivery time", value: d.invalidDeliveryTime }),
|
|
2793
|
+
/* @__PURE__ */ jsx(Stat$1, { label: "Hibás delivery cost", value: d.invalidDeliveryCost })
|
|
2818
2794
|
] }),
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
/* @__PURE__ */ jsx(
|
|
2823
|
-
/* @__PURE__ */ jsx(
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2795
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
2796
|
+
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2797
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Identifier" }),
|
|
2798
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Termék" }),
|
|
2799
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Gyártó" }),
|
|
2800
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Kategória" }),
|
|
2801
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Bruttó / nettó" }),
|
|
2802
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Szállítás" })
|
|
2803
|
+
] }) }),
|
|
2804
|
+
/* @__PURE__ */ jsx("tbody", { children: (preview?.sample || []).map((item) => /* @__PURE__ */ jsxs("tr", { className: "border-b", children: [
|
|
2805
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("code", { children: item.identifier }) }),
|
|
2806
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2807
|
+
/* @__PURE__ */ jsx("a", { href: item.productUrl, target: "_blank", rel: "noreferrer", className: "text-ui-fg-interactive hover:underline", children: item.name }),
|
|
2808
|
+
item.productNumber ? /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted text-xs", children: [
|
|
2809
|
+
"PN: ",
|
|
2810
|
+
item.productNumber
|
|
2811
|
+
] }) : null
|
|
2812
|
+
] }),
|
|
2813
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.manufacturer }),
|
|
2814
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.category }),
|
|
2815
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2816
|
+
item.price,
|
|
2817
|
+
" / ",
|
|
2818
|
+
item.netPrice,
|
|
2819
|
+
" HUF"
|
|
2820
|
+
] }),
|
|
2821
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
2822
|
+
item.deliveryTime || "—",
|
|
2823
|
+
" · ",
|
|
2824
|
+
item.deliveryCost || "—"
|
|
2825
|
+
] })
|
|
2826
|
+
] }, item.identifier)) })
|
|
2827
|
+
] }) })
|
|
2828
|
+
] }) : null
|
|
2829
2829
|
] });
|
|
2830
2830
|
};
|
|
2831
|
-
function
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
maximumFractionDigits: currency?.toUpperCase() === "HUF" ? 0 : 2
|
|
2837
|
-
}).format(value);
|
|
2831
|
+
function Field$3({ label, children }) {
|
|
2832
|
+
return /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
2833
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
2834
|
+
children
|
|
2835
|
+
] });
|
|
2838
2836
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
});
|
|
2837
|
+
function Stat$1({ label, value }) {
|
|
2838
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-3", children: [
|
|
2839
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: label }),
|
|
2840
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: value })
|
|
2841
|
+
] });
|
|
2842
|
+
}
|
|
2843
|
+
const config$6 = defineRouteConfig({ label: "Árukereső", rank: 42 });
|
|
2844
2844
|
const EMPTY_SEO = {
|
|
2845
2845
|
title: "",
|
|
2846
2846
|
description: "",
|
|
@@ -3106,251 +3106,60 @@ ${selectedPage.path}`)) return;
|
|
|
3106
3106
|
/* @__PURE__ */ jsx(Text, { className: "mt-2 text-ui-fg-subtle", children: previewDescription })
|
|
3107
3107
|
] }),
|
|
3108
3108
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 border-t pt-5", children: [
|
|
3109
|
-
/* @__PURE__ */ jsx(Button, { isLoading: saving, disabled: saving || deleting || mode === "page" && !pagePath.trim(), onClick: () => void save(), children: "Mentés" }),
|
|
3110
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: saving || deleting, onClick: () => setForm({ ...EMPTY_SEO }), children: "SEO felülírások ürítése" }),
|
|
3111
|
-
mode === "page" && selectedPage ? /* @__PURE__ */ jsx(Button, { className: "ml-auto", variant: "secondary", isLoading: deleting, disabled: saving || deleting, onClick: () => void removePage(), children: "Oldal törlése" }) : null
|
|
3112
|
-
] })
|
|
3113
|
-
] }) : /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Válassz egy elemet a SEO szerkesztéséhez." }) })
|
|
3114
|
-
] })
|
|
3115
|
-
] });
|
|
3116
|
-
};
|
|
3117
|
-
const ModeButton = ({ active, onClick, children }) => /* @__PURE__ */ jsx(Button, { size: "small", variant: active ? "primary" : "secondary", onClick, children });
|
|
3118
|
-
const ListButton = ({ active, title, subtitle, onClick }) => /* @__PURE__ */ jsxs("button", { type: "button", onClick, className: `mb-2 w-full rounded-lg border p-3 text-left transition-colors hover:bg-ui-bg-subtle ${active ? "bg-ui-bg-subtle" : "bg-ui-bg-base"}`, children: [
|
|
3119
|
-
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: title }),
|
|
3120
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1 truncate text-xs text-ui-fg-subtle", children: subtitle })
|
|
3121
|
-
] });
|
|
3122
|
-
const Field$2 = ({ label, help, children }) => /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
3123
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
3124
|
-
children,
|
|
3125
|
-
help ? /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: help }) : null
|
|
3126
|
-
] });
|
|
3127
|
-
const Counter = ({ value, recommended }) => {
|
|
3128
|
-
const length = value.length;
|
|
3129
|
-
return /* @__PURE__ */ jsxs(Text, { className: `text-xs ${length > recommended ? "text-ui-fg-warning" : "text-ui-fg-muted"}`, children: [
|
|
3130
|
-
length,
|
|
3131
|
-
" karakter",
|
|
3132
|
-
length > recommended ? ` · ajánlott maximum kb. ${recommended}` : ""
|
|
3133
|
-
] });
|
|
3134
|
-
};
|
|
3135
|
-
const ToggleCard = ({ label, description, checked, onCheckedChange }) => /* @__PURE__ */ jsxs("label", { className: "flex items-start justify-between gap-4 rounded-lg border p-4", children: [
|
|
3136
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3137
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
3138
|
-
/* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-subtle", children: description })
|
|
3139
|
-
] }),
|
|
3140
|
-
/* @__PURE__ */ jsx(Switch, { checked, onCheckedChange })
|
|
3141
|
-
] });
|
|
3142
|
-
function normalizeSeo(value) {
|
|
3143
|
-
return {
|
|
3144
|
-
title: value?.title || "",
|
|
3145
|
-
description: value?.description || "",
|
|
3146
|
-
canonical: value?.canonical || "",
|
|
3147
|
-
noindex: Boolean(value?.noindex),
|
|
3148
|
-
nofollow: Boolean(value?.nofollow),
|
|
3149
|
-
ogTitle: value?.ogTitle || "",
|
|
3150
|
-
ogDescription: value?.ogDescription || "",
|
|
3151
|
-
ogImage: value?.ogImage || ""
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
function normalizeEntity(value) {
|
|
3155
|
-
return { ...value, seo: normalizeSeo(value.seo) };
|
|
3156
|
-
}
|
|
3157
|
-
function normalizePage(value) {
|
|
3158
|
-
return { ...value, seo: normalizeSeo(value.seo) };
|
|
3159
|
-
}
|
|
3160
|
-
const defaults = {
|
|
3161
|
-
GOOGLE_MERCHANT_COUNTRY_CODE: "HU",
|
|
3162
|
-
GOOGLE_MERCHANT_CURRENCY_CODE: "HUF",
|
|
3163
|
-
GOOGLE_MERCHANT_STOREFRONT_URL: "",
|
|
3164
|
-
GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
3165
|
-
GOOGLE_MERCHANT_SALES_CHANNEL_ID: "",
|
|
3166
|
-
GOOGLE_MERCHANT_DEFAULT_BRAND: "",
|
|
3167
|
-
GOOGLE_MERCHANT_DEFAULT_CONDITION: "new",
|
|
3168
|
-
GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: true,
|
|
3169
|
-
GOOGLE_MERCHANT_FEED_TITLE: "",
|
|
3170
|
-
GOOGLE_MERCHANT_FEED_DESCRIPTION: ""
|
|
3171
|
-
};
|
|
3172
|
-
const backendUrl$6 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3173
|
-
const apiUrl$6 = (path) => `${backendUrl$6}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3174
|
-
const GoogleMerchantPage = () => {
|
|
3175
|
-
const [enabled, setEnabled] = useState(false);
|
|
3176
|
-
const [draft, setDraft] = useState(defaults);
|
|
3177
|
-
const [loading, setLoading] = useState(true);
|
|
3178
|
-
const [saving, setSaving] = useState(false);
|
|
3179
|
-
const [previewing, setPreviewing] = useState(false);
|
|
3180
|
-
const [preview, setPreview] = useState(null);
|
|
3181
|
-
const update = (key, value) => {
|
|
3182
|
-
setDraft((current) => ({ ...current, [key]: value }));
|
|
3183
|
-
};
|
|
3184
|
-
const load = useCallback(async () => {
|
|
3185
|
-
setLoading(true);
|
|
3186
|
-
try {
|
|
3187
|
-
const response = await fetch(apiUrl$6("/admin/integrations/google-merchant"), {
|
|
3188
|
-
credentials: "include"
|
|
3189
|
-
});
|
|
3190
|
-
const data = await response.json().catch(() => ({}));
|
|
3191
|
-
if (!response.ok || !data.integration) {
|
|
3192
|
-
throw new Error(data.message || "A Google Merchant beállítások nem tölthetők be.");
|
|
3193
|
-
}
|
|
3194
|
-
const values = data.integration.values || {};
|
|
3195
|
-
setEnabled(Boolean(data.integration.enabled));
|
|
3196
|
-
setDraft({
|
|
3197
|
-
GOOGLE_MERCHANT_COUNTRY_CODE: values.GOOGLE_MERCHANT_COUNTRY_CODE || "HU",
|
|
3198
|
-
GOOGLE_MERCHANT_CURRENCY_CODE: values.GOOGLE_MERCHANT_CURRENCY_CODE || "HUF",
|
|
3199
|
-
GOOGLE_MERCHANT_STOREFRONT_URL: values.GOOGLE_MERCHANT_STOREFRONT_URL || "",
|
|
3200
|
-
GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: values.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE || "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
3201
|
-
GOOGLE_MERCHANT_SALES_CHANNEL_ID: values.GOOGLE_MERCHANT_SALES_CHANNEL_ID || "",
|
|
3202
|
-
GOOGLE_MERCHANT_DEFAULT_BRAND: values.GOOGLE_MERCHANT_DEFAULT_BRAND || "",
|
|
3203
|
-
GOOGLE_MERCHANT_DEFAULT_CONDITION: values.GOOGLE_MERCHANT_DEFAULT_CONDITION || "new",
|
|
3204
|
-
GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: values.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK !== "false",
|
|
3205
|
-
GOOGLE_MERCHANT_FEED_TITLE: values.GOOGLE_MERCHANT_FEED_TITLE || "",
|
|
3206
|
-
GOOGLE_MERCHANT_FEED_DESCRIPTION: values.GOOGLE_MERCHANT_FEED_DESCRIPTION || ""
|
|
3207
|
-
});
|
|
3208
|
-
} catch (error) {
|
|
3209
|
-
toast.error(error instanceof Error ? error.message : "Betöltési hiba.");
|
|
3210
|
-
} finally {
|
|
3211
|
-
setLoading(false);
|
|
3212
|
-
}
|
|
3213
|
-
}, []);
|
|
3214
|
-
useEffect(() => {
|
|
3215
|
-
void load();
|
|
3216
|
-
}, [load]);
|
|
3217
|
-
const save = async () => {
|
|
3218
|
-
setSaving(true);
|
|
3219
|
-
try {
|
|
3220
|
-
const response = await fetch(apiUrl$6("/admin/integrations/google-merchant"), {
|
|
3221
|
-
method: "POST",
|
|
3222
|
-
credentials: "include",
|
|
3223
|
-
headers: { "Content-Type": "application/json" },
|
|
3224
|
-
body: JSON.stringify({ enabled, values: draft })
|
|
3225
|
-
});
|
|
3226
|
-
const data = await response.json().catch(() => ({}));
|
|
3227
|
-
if (!response.ok) throw new Error(data.message || "A mentés nem sikerült.");
|
|
3228
|
-
toast.success(data.message || "Google Merchant beállítások mentve.");
|
|
3229
|
-
setPreview(null);
|
|
3230
|
-
await load();
|
|
3231
|
-
} catch (error) {
|
|
3232
|
-
toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
|
|
3233
|
-
} finally {
|
|
3234
|
-
setSaving(false);
|
|
3235
|
-
}
|
|
3236
|
-
};
|
|
3237
|
-
const runPreview = async () => {
|
|
3238
|
-
setPreviewing(true);
|
|
3239
|
-
try {
|
|
3240
|
-
const response = await fetch(apiUrl$6("/admin/google-merchant/preview"), {
|
|
3241
|
-
credentials: "include"
|
|
3242
|
-
});
|
|
3243
|
-
const data = await response.json().catch(() => ({}));
|
|
3244
|
-
if (!response.ok) throw new Error(data.message || "A feed nem generálható.");
|
|
3245
|
-
setPreview(data);
|
|
3246
|
-
toast.success("A Merchant feed ellenőrzése elkészült.");
|
|
3247
|
-
} catch (error) {
|
|
3248
|
-
toast.error(error instanceof Error ? error.message : "A feed nem generálható.");
|
|
3249
|
-
} finally {
|
|
3250
|
-
setPreviewing(false);
|
|
3251
|
-
}
|
|
3252
|
-
};
|
|
3253
|
-
const feedUrl = apiUrl$6("/feeds/google-merchant.xml");
|
|
3254
|
-
const d = preview?.diagnostics;
|
|
3255
|
-
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
3256
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-4", children: [
|
|
3257
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3258
|
-
/* @__PURE__ */ jsx(Heading, { children: "Google Merchant Center" }),
|
|
3259
|
-
/* @__PURE__ */ jsx(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." })
|
|
3260
|
-
] }),
|
|
3261
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
3262
|
-
/* @__PURE__ */ jsx(Switch, { checked: enabled, onCheckedChange: setEnabled, disabled: loading }),
|
|
3263
|
-
/* @__PURE__ */ jsx(Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
|
|
3264
|
-
] })
|
|
3265
|
-
] }),
|
|
3266
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
|
|
3267
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Célország", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_COUNTRY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_COUNTRY_CODE", e.target.value.toUpperCase()), placeholder: "HU" }) }),
|
|
3268
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Pénznem", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_CURRENCY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_CURRENCY_CODE", e.target.value.toUpperCase()), placeholder: "HUF" }) }),
|
|
3269
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Storefront URL", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_STOREFRONT_URL, onChange: (e) => update("GOOGLE_MERCHANT_STOREFRONT_URL", e.target.value), placeholder: "https://shop.hu (üresen STOREFRONT_URL)" }) }),
|
|
3270
|
-
/* @__PURE__ */ jsxs(Field$1, { label: "Termék URL sablon", children: [
|
|
3271
|
-
/* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE, onChange: (e) => update("GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE", e.target.value) }),
|
|
3272
|
-
/* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-xs", children: [
|
|
3273
|
-
"Helyőrzők: ",
|
|
3274
|
-
"{country_code}",
|
|
3275
|
-
", ",
|
|
3276
|
-
"{currency_code}",
|
|
3277
|
-
", ",
|
|
3278
|
-
"{handle}",
|
|
3279
|
-
", ",
|
|
3280
|
-
"{variant_id}",
|
|
3281
|
-
"."
|
|
3109
|
+
/* @__PURE__ */ jsx(Button, { isLoading: saving, disabled: saving || deleting || mode === "page" && !pagePath.trim(), onClick: () => void save(), children: "Mentés" }),
|
|
3110
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: saving || deleting, onClick: () => setForm({ ...EMPTY_SEO }), children: "SEO felülírások ürítése" }),
|
|
3111
|
+
mode === "page" && selectedPage ? /* @__PURE__ */ jsx(Button, { className: "ml-auto", variant: "secondary", isLoading: deleting, disabled: saving || deleting, onClick: () => void removePage(), children: "Oldal törlése" }) : null
|
|
3282
3112
|
] })
|
|
3283
|
-
] }),
|
|
3284
|
-
|
|
3285
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Alapértelmezett márka", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_DEFAULT_BRAND, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_BRAND", e.target.value) }) }),
|
|
3286
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Alapértelmezett állapot", children: /* @__PURE__ */ 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: [
|
|
3287
|
-
/* @__PURE__ */ jsx("option", { value: "new", children: "Új" }),
|
|
3288
|
-
/* @__PURE__ */ jsx("option", { value: "refurbished", children: "Felújított" }),
|
|
3289
|
-
/* @__PURE__ */ jsx("option", { value: "used", children: "Használt" })
|
|
3290
|
-
] }) }),
|
|
3291
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Készlethiányos variantok", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
3292
|
-
/* @__PURE__ */ jsx(Switch, { checked: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK, onCheckedChange: (value) => update("GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK", value) }),
|
|
3293
|
-
/* @__PURE__ */ jsx(Text, { children: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK ? "Benne maradnak" : "Kimaradnak" })
|
|
3294
|
-
] }) }),
|
|
3295
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Feed neve", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_FEED_TITLE, onChange: (e) => update("GOOGLE_MERCHANT_FEED_TITLE", e.target.value), placeholder: "Üresen automatikus" }) }),
|
|
3296
|
-
/* @__PURE__ */ jsx(Field$1, { label: "Feed leírása", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_FEED_DESCRIPTION, onChange: (e) => update("GOOGLE_MERCHANT_FEED_DESCRIPTION", e.target.value), placeholder: "Üresen automatikus" }) })
|
|
3297
|
-
] }),
|
|
3298
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
|
|
3299
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3300
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Publikus feed URL" }),
|
|
3301
|
-
/* @__PURE__ */ jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
|
|
3302
|
-
] }),
|
|
3303
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
3304
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", isLoading: previewing, disabled: !enabled || loading || saving || previewing, onClick: () => void runPreview(), children: "Feed ellenőrzése" }),
|
|
3305
|
-
/* @__PURE__ */ jsx(Button, { isLoading: saving, disabled: loading || saving || previewing, onClick: () => void save(), children: "Mentés" })
|
|
3306
|
-
] })
|
|
3307
|
-
] }),
|
|
3308
|
-
d ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3309
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b px-6 py-5 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
3310
|
-
/* @__PURE__ */ jsx(Stat, { label: "Termékek", value: d.productsScanned }),
|
|
3311
|
-
/* @__PURE__ */ jsx(Stat, { label: "Variantok", value: d.variantsScanned }),
|
|
3312
|
-
/* @__PURE__ */ jsx(Stat, { label: "Feed tételek", value: d.itemsEmitted }),
|
|
3313
|
-
/* @__PURE__ */ jsx(Stat, { label: "Hiányzó identifier", value: d.itemsMissingIdentifiers }),
|
|
3314
|
-
/* @__PURE__ */ jsx(Stat, { label: "Nincs ár", value: d.skippedNoPrice }),
|
|
3315
|
-
/* @__PURE__ */ jsx(Stat, { label: "Nincs kép", value: d.skippedNoImage }),
|
|
3316
|
-
/* @__PURE__ */ jsx(Stat, { label: "Nincs sales channel", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
|
|
3317
|
-
/* @__PURE__ */ jsx(Stat, { label: "Érvénytelen GTIN", value: d.invalidGtinsIgnored })
|
|
3318
|
-
] }),
|
|
3319
|
-
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
3320
|
-
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
3321
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "ID" }),
|
|
3322
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Termék" }),
|
|
3323
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Ár" }),
|
|
3324
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Készlet" }),
|
|
3325
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Identifier" })
|
|
3326
|
-
] }) }),
|
|
3327
|
-
/* @__PURE__ */ jsx("tbody", { children: (preview?.sample || []).map((item) => /* @__PURE__ */ jsxs("tr", { className: "border-b", children: [
|
|
3328
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("code", { children: item.id }) }),
|
|
3329
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("a", { href: item.link, target: "_blank", rel: "noreferrer", className: "text-ui-fg-interactive hover:underline", children: item.title }) }),
|
|
3330
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.salePrice ? `${item.salePrice} (${item.price})` : item.price }),
|
|
3331
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.availability }),
|
|
3332
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.gtin || item.mpn || item.brand || "—" })
|
|
3333
|
-
] }, item.id)) })
|
|
3334
|
-
] }) })
|
|
3335
|
-
] }) : null
|
|
3113
|
+
] }) : /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Válassz egy elemet a SEO szerkesztéséhez." }) })
|
|
3114
|
+
] })
|
|
3336
3115
|
] });
|
|
3337
3116
|
};
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3117
|
+
const ModeButton = ({ active, onClick, children }) => /* @__PURE__ */ jsx(Button, { size: "small", variant: active ? "primary" : "secondary", onClick, children });
|
|
3118
|
+
const ListButton = ({ active, title, subtitle, onClick }) => /* @__PURE__ */ jsxs("button", { type: "button", onClick, className: `mb-2 w-full rounded-lg border p-3 text-left transition-colors hover:bg-ui-bg-subtle ${active ? "bg-ui-bg-subtle" : "bg-ui-bg-base"}`, children: [
|
|
3119
|
+
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: title }),
|
|
3120
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 truncate text-xs text-ui-fg-subtle", children: subtitle })
|
|
3121
|
+
] });
|
|
3122
|
+
const Field$2 = ({ label, help, children }) => /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
3123
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
3124
|
+
children,
|
|
3125
|
+
help ? /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: help }) : null
|
|
3126
|
+
] });
|
|
3127
|
+
const Counter = ({ value, recommended }) => {
|
|
3128
|
+
const length = value.length;
|
|
3129
|
+
return /* @__PURE__ */ jsxs(Text, { className: `text-xs ${length > recommended ? "text-ui-fg-warning" : "text-ui-fg-muted"}`, children: [
|
|
3130
|
+
length,
|
|
3131
|
+
" karakter",
|
|
3132
|
+
length > recommended ? ` · ajánlott maximum kb. ${recommended}` : ""
|
|
3342
3133
|
] });
|
|
3134
|
+
};
|
|
3135
|
+
const ToggleCard = ({ label, description, checked, onCheckedChange }) => /* @__PURE__ */ jsxs("label", { className: "flex items-start justify-between gap-4 rounded-lg border p-4", children: [
|
|
3136
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3137
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
3138
|
+
/* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-subtle", children: description })
|
|
3139
|
+
] }),
|
|
3140
|
+
/* @__PURE__ */ jsx(Switch, { checked, onCheckedChange })
|
|
3141
|
+
] });
|
|
3142
|
+
function normalizeSeo(value) {
|
|
3143
|
+
return {
|
|
3144
|
+
title: value?.title || "",
|
|
3145
|
+
description: value?.description || "",
|
|
3146
|
+
canonical: value?.canonical || "",
|
|
3147
|
+
noindex: Boolean(value?.noindex),
|
|
3148
|
+
nofollow: Boolean(value?.nofollow),
|
|
3149
|
+
ogTitle: value?.ogTitle || "",
|
|
3150
|
+
ogDescription: value?.ogDescription || "",
|
|
3151
|
+
ogImage: value?.ogImage || ""
|
|
3152
|
+
};
|
|
3343
3153
|
}
|
|
3344
|
-
function
|
|
3345
|
-
return
|
|
3346
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: label }),
|
|
3347
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: value })
|
|
3348
|
-
] });
|
|
3154
|
+
function normalizeEntity(value) {
|
|
3155
|
+
return { ...value, seo: normalizeSeo(value.seo) };
|
|
3349
3156
|
}
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3157
|
+
function normalizePage(value) {
|
|
3158
|
+
return { ...value, seo: normalizeSeo(value.seo) };
|
|
3159
|
+
}
|
|
3160
|
+
const backendUrl$6 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3161
|
+
function apiUrl$6(path) {
|
|
3162
|
+
return `${backendUrl$6}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3354
3163
|
}
|
|
3355
3164
|
const CoreAuditPage = () => {
|
|
3356
3165
|
const [logs, setLogs] = useState([]);
|
|
@@ -3368,7 +3177,7 @@ const CoreAuditPage = () => {
|
|
|
3368
3177
|
if (integration !== "all") params.set("integration", integration);
|
|
3369
3178
|
if (status !== "all") params.set("status", status);
|
|
3370
3179
|
const response = await fetch(
|
|
3371
|
-
apiUrl$
|
|
3180
|
+
apiUrl$6(`/admin/core-audit?${params.toString()}`),
|
|
3372
3181
|
{ credentials: "include" }
|
|
3373
3182
|
);
|
|
3374
3183
|
const payload = await response.json().catch(() => ({}));
|
|
@@ -3504,15 +3313,15 @@ function formatDate$3(value) {
|
|
|
3504
3313
|
timeStyle: "short"
|
|
3505
3314
|
}).format(date);
|
|
3506
3315
|
}
|
|
3507
|
-
const config$
|
|
3316
|
+
const config$5 = defineRouteConfig({
|
|
3508
3317
|
label: "Audit napló",
|
|
3509
3318
|
icon: Newspaper,
|
|
3510
3319
|
rank: 39
|
|
3511
3320
|
});
|
|
3512
|
-
const backendUrl$
|
|
3321
|
+
const backendUrl$5 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3513
3322
|
const adminBase$3 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
3514
|
-
function apiUrl$
|
|
3515
|
-
return `${backendUrl$
|
|
3323
|
+
function apiUrl$5(path) {
|
|
3324
|
+
return `${backendUrl$5}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3516
3325
|
}
|
|
3517
3326
|
const IntegrationHealthPage = () => {
|
|
3518
3327
|
const [integrations, setIntegrations] = useState([]);
|
|
@@ -3525,8 +3334,8 @@ const IntegrationHealthPage = () => {
|
|
|
3525
3334
|
setLoadError(null);
|
|
3526
3335
|
try {
|
|
3527
3336
|
const [integrationsResponse, operationsResponse] = await Promise.all([
|
|
3528
|
-
fetch(apiUrl$
|
|
3529
|
-
fetch(apiUrl$
|
|
3337
|
+
fetch(apiUrl$5("/admin/integrations"), { credentials: "include" }),
|
|
3338
|
+
fetch(apiUrl$5("/admin/integration-operations?status=problems&limit=100"), {
|
|
3530
3339
|
credentials: "include"
|
|
3531
3340
|
})
|
|
3532
3341
|
]);
|
|
@@ -3590,7 +3399,7 @@ const IntegrationHealthPage = () => {
|
|
|
3590
3399
|
setTesting(integration.key);
|
|
3591
3400
|
try {
|
|
3592
3401
|
const response = await fetch(
|
|
3593
|
-
apiUrl$
|
|
3402
|
+
apiUrl$5(`/admin/integrations/${integration.key}/test`),
|
|
3594
3403
|
{
|
|
3595
3404
|
method: "POST",
|
|
3596
3405
|
credentials: "include"
|
|
@@ -3738,206 +3547,66 @@ function SummaryCard$1({
|
|
|
3738
3547
|
function formatDate$2(value) {
|
|
3739
3548
|
const date = new Date(value);
|
|
3740
3549
|
if (Number.isNaN(date.getTime())) return "—";
|
|
3741
|
-
return new Intl.DateTimeFormat("hu-HU", {
|
|
3742
|
-
dateStyle: "short",
|
|
3743
|
-
timeStyle: "short"
|
|
3744
|
-
}).format(date);
|
|
3745
|
-
}
|
|
3746
|
-
const config$
|
|
3747
|
-
label: "Integrációk állapota",
|
|
3748
|
-
icon: Newspaper,
|
|
3749
|
-
rank: 38
|
|
3750
|
-
});
|
|
3751
|
-
const
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
};
|
|
3763
|
-
const ProductionReadinessPage = () => {
|
|
3764
|
-
const [report, setReport] = useState(null);
|
|
3765
|
-
const [loading, setLoading] = useState(true);
|
|
3766
|
-
const [error, setError] = useState(null);
|
|
3767
|
-
const load = useCallback(async () => {
|
|
3768
|
-
setLoading(true);
|
|
3769
|
-
setError(null);
|
|
3770
|
-
try {
|
|
3771
|
-
const response = await fetch(apiUrl$3("/admin/production-readiness"), {
|
|
3772
|
-
credentials: "include"
|
|
3773
|
-
});
|
|
3774
|
-
const payload = await response.json().catch(() => ({}));
|
|
3775
|
-
if (!response.ok) {
|
|
3776
|
-
throw new Error(payload.message || "Az élesítési ellenőrzés nem tölthető be.");
|
|
3777
|
-
}
|
|
3778
|
-
setReport(payload);
|
|
3779
|
-
} catch (cause) {
|
|
3780
|
-
setReport(null);
|
|
3781
|
-
setError(
|
|
3782
|
-
cause instanceof Error ? cause.message : "Az élesítési ellenőrzés nem tölthető be."
|
|
3783
|
-
);
|
|
3784
|
-
} finally {
|
|
3785
|
-
setLoading(false);
|
|
3786
|
-
}
|
|
3787
|
-
}, []);
|
|
3788
|
-
useEffect(() => {
|
|
3789
|
-
void load();
|
|
3790
|
-
}, [load]);
|
|
3791
|
-
const groups = useMemo(() => {
|
|
3792
|
-
const result = /* @__PURE__ */ new Map();
|
|
3793
|
-
for (const item of report?.checks || []) {
|
|
3794
|
-
result.set(item.category, [...result.get(item.category) || [], item]);
|
|
3795
|
-
}
|
|
3796
|
-
return Array.from(result.entries());
|
|
3797
|
-
}, [report]);
|
|
3798
|
-
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
3799
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-5", children: [
|
|
3800
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3801
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Production readiness" }),
|
|
3802
|
-
/* @__PURE__ */ jsx(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." })
|
|
3803
|
-
] }),
|
|
3804
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Újraellenőrzés" })
|
|
3805
|
-
] }),
|
|
3806
|
-
report ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3807
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b p-6 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
3808
|
-
/* @__PURE__ */ jsx(Summary, { label: "Kész", value: report.score.ready, tone: "ready" }),
|
|
3809
|
-
/* @__PURE__ */ jsx(Summary, { label: "Figyelmeztetés", value: report.score.warning, tone: "warning" }),
|
|
3810
|
-
/* @__PURE__ */ jsx(Summary, { label: "Blokkoló", value: report.score.blocked, tone: "blocked" }),
|
|
3811
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
3812
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Élesítési döntés" }),
|
|
3813
|
-
/* @__PURE__ */ 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ő" }),
|
|
3814
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-1 text-ui-fg-subtle", children: report.environment === "production" ? "Production szabályok" : "Nem-production szabályok" })
|
|
3815
|
-
] })
|
|
3816
|
-
] }),
|
|
3817
|
-
/* @__PURE__ */ jsx("div", { className: "border-b px-6 py-3", children: /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
3818
|
-
"Utolsó ellenőrzés: ",
|
|
3819
|
-
formatDate$1(report.generated_at),
|
|
3820
|
-
". A sárga elemek nem blokkolják az élesítést, a piros elemek igen."
|
|
3821
|
-
] }) }),
|
|
3822
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-6 p-6", children: groups.map(([category, checks]) => /* @__PURE__ */ jsxs("section", { className: "overflow-hidden rounded-lg border", children: [
|
|
3823
|
-
/* @__PURE__ */ jsx("div", { className: "border-b bg-ui-bg-subtle px-4 py-3", children: /* @__PURE__ */ jsx(Heading, { level: "h2", children: CATEGORY_LABELS[category] || category }) }),
|
|
3824
|
-
/* @__PURE__ */ jsx("div", { className: "divide-y", children: checks.map((item) => /* @__PURE__ */ jsxs("div", { className: "grid gap-3 p-4 md:grid-cols-[180px_140px_minmax(0,1fr)_auto] md:items-center", children: [
|
|
3825
|
-
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
3826
|
-
/* @__PURE__ */ jsx(StatusBadge, { status: item.status }),
|
|
3827
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: item.message }),
|
|
3828
|
-
item.action_href && item.action_label ? /* @__PURE__ */ jsx("a", { href: normalizeAdminHref(item.action_href), children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: item.action_label }) }) : /* @__PURE__ */ jsx("span", {})
|
|
3829
|
-
] }, item.key)) })
|
|
3830
|
-
] }, category)) })
|
|
3831
|
-
] }) : null,
|
|
3832
|
-
loading && !report ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Élesítési feltételek ellenőrzése…" }) }) : null,
|
|
3833
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
|
|
3834
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "Az ellenőrzés nem futott le." }),
|
|
3835
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: error })
|
|
3836
|
-
] }) : null
|
|
3837
|
-
] });
|
|
3838
|
-
};
|
|
3839
|
-
function StatusBadge({ status }) {
|
|
3840
|
-
const label = status === "ready" ? "Kész" : status === "warning" ? "Figyelmeztetés" : "Blokkoló";
|
|
3841
|
-
const className = status === "ready" ? "font-medium text-ui-fg-success" : status === "warning" ? "font-medium text-ui-fg-warning" : "font-medium text-ui-fg-error";
|
|
3842
|
-
return /* @__PURE__ */ jsxs("span", { className, children: [
|
|
3843
|
-
status === "ready" ? "✅" : status === "warning" ? "🟡" : "🔴",
|
|
3844
|
-
" ",
|
|
3845
|
-
label
|
|
3846
|
-
] });
|
|
3847
|
-
}
|
|
3848
|
-
function Summary({ label, value, tone }) {
|
|
3849
|
-
const valueClass = tone === "ready" ? "text-ui-fg-success" : tone === "warning" ? "text-ui-fg-warning" : "text-ui-fg-error";
|
|
3850
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
3851
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
|
|
3852
|
-
/* @__PURE__ */ jsx("div", { className: `mt-1 text-3xl font-semibold ${valueClass}`, children: value })
|
|
3853
|
-
] });
|
|
3854
|
-
}
|
|
3855
|
-
function normalizeAdminHref(path) {
|
|
3856
|
-
if (!path.startsWith("/app")) return path;
|
|
3857
|
-
return `${adminBase$2}${path.slice(4)}`;
|
|
3858
|
-
}
|
|
3859
|
-
function formatDate$1(value) {
|
|
3860
|
-
const date = new Date(value);
|
|
3861
|
-
if (Number.isNaN(date.getTime())) return "—";
|
|
3862
|
-
return new Intl.DateTimeFormat("hu-HU", { dateStyle: "short", timeStyle: "medium" }).format(date);
|
|
3863
|
-
}
|
|
3864
|
-
const config$2 = defineRouteConfig({
|
|
3865
|
-
label: "Production readiness",
|
|
3866
|
-
rank: 39
|
|
3867
|
-
});
|
|
3868
|
-
const backendUrl$2 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3869
|
-
const adminBase$1 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
3870
|
-
const apiUrl$2 = (path) => `${backendUrl$2}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3871
|
-
const CATEGORY_ORDER = [
|
|
3872
|
-
"payment",
|
|
3873
|
-
"invoicing",
|
|
3874
|
-
"shipping",
|
|
3875
|
-
"notification",
|
|
3876
|
-
"legal",
|
|
3877
|
-
"marketing"
|
|
3878
|
-
];
|
|
3879
|
-
const CATEGORY_LABEL = {
|
|
3880
|
-
payment: "Fizetés",
|
|
3881
|
-
invoicing: "Számlázás",
|
|
3882
|
-
shipping: "Szállítás",
|
|
3883
|
-
notification: "Értesítés",
|
|
3884
|
-
legal: "Jogi integráció",
|
|
3885
|
-
marketing: "Marketing"
|
|
3550
|
+
return new Intl.DateTimeFormat("hu-HU", {
|
|
3551
|
+
dateStyle: "short",
|
|
3552
|
+
timeStyle: "short"
|
|
3553
|
+
}).format(date);
|
|
3554
|
+
}
|
|
3555
|
+
const config$4 = defineRouteConfig({
|
|
3556
|
+
label: "Integrációk állapota",
|
|
3557
|
+
icon: Newspaper,
|
|
3558
|
+
rank: 38
|
|
3559
|
+
});
|
|
3560
|
+
const defaults = {
|
|
3561
|
+
GOOGLE_MERCHANT_COUNTRY_CODE: "HU",
|
|
3562
|
+
GOOGLE_MERCHANT_CURRENCY_CODE: "HUF",
|
|
3563
|
+
GOOGLE_MERCHANT_STOREFRONT_URL: "",
|
|
3564
|
+
GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
3565
|
+
GOOGLE_MERCHANT_SALES_CHANNEL_ID: "",
|
|
3566
|
+
GOOGLE_MERCHANT_DEFAULT_BRAND: "",
|
|
3567
|
+
GOOGLE_MERCHANT_DEFAULT_CONDITION: "new",
|
|
3568
|
+
GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: true,
|
|
3569
|
+
GOOGLE_MERCHANT_FEED_TITLE: "",
|
|
3570
|
+
GOOGLE_MERCHANT_FEED_DESCRIPTION: ""
|
|
3886
3571
|
};
|
|
3887
|
-
const
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
const [draft, setDraft] = useState({});
|
|
3891
|
-
const [clearSecrets, setClearSecrets] = useState([]);
|
|
3572
|
+
const backendUrl$4 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3573
|
+
const apiUrl$4 = (path) => `${backendUrl$4}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3574
|
+
const GoogleMerchantPage = () => {
|
|
3892
3575
|
const [enabled, setEnabled] = useState(false);
|
|
3576
|
+
const [draft, setDraft] = useState(defaults);
|
|
3893
3577
|
const [loading, setLoading] = useState(true);
|
|
3894
3578
|
const [saving, setSaving] = useState(false);
|
|
3895
|
-
const [
|
|
3896
|
-
const [
|
|
3897
|
-
const
|
|
3898
|
-
() =>
|
|
3899
|
-
|
|
3900
|
-
);
|
|
3901
|
-
const selected = useMemo(
|
|
3902
|
-
() => visibleItems.find((item) => item.key === selectedKey) || null,
|
|
3903
|
-
[visibleItems, selectedKey]
|
|
3904
|
-
);
|
|
3905
|
-
const hasUnsavedChanges = useMemo(() => {
|
|
3906
|
-
if (!selected) return false;
|
|
3907
|
-
if (enabled !== selected.enabled || clearSecrets.length > 0) return true;
|
|
3908
|
-
return selected.fields.some((field) => {
|
|
3909
|
-
const value = draft[field.name];
|
|
3910
|
-
if (field.type === "secret") {
|
|
3911
|
-
return Boolean(String(value || "").trim());
|
|
3912
|
-
}
|
|
3913
|
-
if (field.type === "boolean") {
|
|
3914
|
-
return Boolean(value) !== (selected.values[field.name] === "true");
|
|
3915
|
-
}
|
|
3916
|
-
return String(value || "").trim() !== String(selected.values[field.name] || "").trim();
|
|
3917
|
-
});
|
|
3918
|
-
}, [selected, enabled, draft, clearSecrets]);
|
|
3579
|
+
const [previewing, setPreviewing] = useState(false);
|
|
3580
|
+
const [preview, setPreview] = useState(null);
|
|
3581
|
+
const update = (key, value) => {
|
|
3582
|
+
setDraft((current) => ({ ...current, [key]: value }));
|
|
3583
|
+
};
|
|
3919
3584
|
const load = useCallback(async () => {
|
|
3920
3585
|
setLoading(true);
|
|
3921
3586
|
try {
|
|
3922
|
-
const response = await fetch(apiUrl$
|
|
3587
|
+
const response = await fetch(apiUrl$4("/admin/integrations/google-merchant"), {
|
|
3923
3588
|
credentials: "include"
|
|
3924
3589
|
});
|
|
3925
3590
|
const data = await response.json().catch(() => ({}));
|
|
3926
|
-
if (!response.ok) {
|
|
3927
|
-
throw new Error(data.message || "
|
|
3591
|
+
if (!response.ok || !data.integration) {
|
|
3592
|
+
throw new Error(data.message || "A Google Merchant beállítások nem tölthetők be.");
|
|
3928
3593
|
}
|
|
3929
|
-
const
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3594
|
+
const values = data.integration.values || {};
|
|
3595
|
+
setEnabled(Boolean(data.integration.enabled));
|
|
3596
|
+
setDraft({
|
|
3597
|
+
GOOGLE_MERCHANT_COUNTRY_CODE: values.GOOGLE_MERCHANT_COUNTRY_CODE || "HU",
|
|
3598
|
+
GOOGLE_MERCHANT_CURRENCY_CODE: values.GOOGLE_MERCHANT_CURRENCY_CODE || "HUF",
|
|
3599
|
+
GOOGLE_MERCHANT_STOREFRONT_URL: values.GOOGLE_MERCHANT_STOREFRONT_URL || "",
|
|
3600
|
+
GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE: values.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE || "/{country_code}/products/{handle}?v_id={variant_id}",
|
|
3601
|
+
GOOGLE_MERCHANT_SALES_CHANNEL_ID: values.GOOGLE_MERCHANT_SALES_CHANNEL_ID || "",
|
|
3602
|
+
GOOGLE_MERCHANT_DEFAULT_BRAND: values.GOOGLE_MERCHANT_DEFAULT_BRAND || "",
|
|
3603
|
+
GOOGLE_MERCHANT_DEFAULT_CONDITION: values.GOOGLE_MERCHANT_DEFAULT_CONDITION || "new",
|
|
3604
|
+
GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK: values.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK !== "false",
|
|
3605
|
+
GOOGLE_MERCHANT_FEED_TITLE: values.GOOGLE_MERCHANT_FEED_TITLE || "",
|
|
3606
|
+
GOOGLE_MERCHANT_FEED_DESCRIPTION: values.GOOGLE_MERCHANT_FEED_DESCRIPTION || ""
|
|
3607
|
+
});
|
|
3937
3608
|
} catch (error) {
|
|
3938
|
-
toast.error(
|
|
3939
|
-
error instanceof Error ? error.message : "Az integrációk nem tölthetők be."
|
|
3940
|
-
);
|
|
3609
|
+
toast.error(error instanceof Error ? error.message : "Betöltési hiba.");
|
|
3941
3610
|
} finally {
|
|
3942
3611
|
setLoading(false);
|
|
3943
3612
|
}
|
|
@@ -3945,641 +3614,972 @@ const IntegrationsPage = () => {
|
|
|
3945
3614
|
useEffect(() => {
|
|
3946
3615
|
void load();
|
|
3947
3616
|
}, [load]);
|
|
3948
|
-
useEffect(() => {
|
|
3949
|
-
if (!selected) return;
|
|
3950
|
-
const next = {};
|
|
3951
|
-
for (const field of selected.fields) {
|
|
3952
|
-
if (field.type === "secret") next[field.name] = "";
|
|
3953
|
-
else if (field.type === "boolean") {
|
|
3954
|
-
next[field.name] = selected.values[field.name] === "true";
|
|
3955
|
-
} else {
|
|
3956
|
-
next[field.name] = selected.values[field.name] || "";
|
|
3957
|
-
}
|
|
3958
|
-
}
|
|
3959
|
-
setDraft(next);
|
|
3960
|
-
setClearSecrets([]);
|
|
3961
|
-
setEnabled(selected.enabled);
|
|
3962
|
-
setRestartNotice(false);
|
|
3963
|
-
}, [selected?.key, selected?.values, selected?.enabled]);
|
|
3964
3617
|
const save = async () => {
|
|
3965
|
-
if (!selected) return;
|
|
3966
3618
|
setSaving(true);
|
|
3967
3619
|
try {
|
|
3968
|
-
const
|
|
3969
|
-
for (const field of selected.fields) {
|
|
3970
|
-
const value = draft[field.name];
|
|
3971
|
-
if (field.type === "secret" && !String(value || "").trim()) continue;
|
|
3972
|
-
values[field.name] = value;
|
|
3973
|
-
}
|
|
3974
|
-
const response = await fetch(apiUrl$2(`/admin/integrations/${selected.key}`), {
|
|
3620
|
+
const response = await fetch(apiUrl$4("/admin/integrations/google-merchant"), {
|
|
3975
3621
|
method: "POST",
|
|
3976
3622
|
credentials: "include",
|
|
3977
3623
|
headers: { "Content-Type": "application/json" },
|
|
3978
|
-
body: JSON.stringify({
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3624
|
+
body: JSON.stringify({ enabled, values: draft })
|
|
3625
|
+
});
|
|
3626
|
+
const data = await response.json().catch(() => ({}));
|
|
3627
|
+
if (!response.ok) throw new Error(data.message || "A mentés nem sikerült.");
|
|
3628
|
+
toast.success(data.message || "Google Merchant beállítások mentve.");
|
|
3629
|
+
setPreview(null);
|
|
3630
|
+
await load();
|
|
3631
|
+
} catch (error) {
|
|
3632
|
+
toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
|
|
3633
|
+
} finally {
|
|
3634
|
+
setSaving(false);
|
|
3635
|
+
}
|
|
3636
|
+
};
|
|
3637
|
+
const runPreview = async () => {
|
|
3638
|
+
setPreviewing(true);
|
|
3639
|
+
try {
|
|
3640
|
+
const response = await fetch(apiUrl$4("/admin/google-merchant/preview"), {
|
|
3641
|
+
credentials: "include"
|
|
3642
|
+
});
|
|
3643
|
+
const data = await response.json().catch(() => ({}));
|
|
3644
|
+
if (!response.ok) throw new Error(data.message || "A feed nem generálható.");
|
|
3645
|
+
setPreview(data);
|
|
3646
|
+
toast.success("A Merchant feed ellenőrzése elkészült.");
|
|
3647
|
+
} catch (error) {
|
|
3648
|
+
toast.error(error instanceof Error ? error.message : "A feed nem generálható.");
|
|
3649
|
+
} finally {
|
|
3650
|
+
setPreviewing(false);
|
|
3651
|
+
}
|
|
3652
|
+
};
|
|
3653
|
+
const feedUrl = apiUrl$4("/feeds/google-merchant.xml");
|
|
3654
|
+
const d = preview?.diagnostics;
|
|
3655
|
+
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
3656
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-4", children: [
|
|
3657
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3658
|
+
/* @__PURE__ */ jsx(Heading, { children: "Google Merchant Center" }),
|
|
3659
|
+
/* @__PURE__ */ jsx(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." })
|
|
3660
|
+
] }),
|
|
3661
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
3662
|
+
/* @__PURE__ */ jsx(Switch, { checked: enabled, onCheckedChange: setEnabled, disabled: loading }),
|
|
3663
|
+
/* @__PURE__ */ jsx(Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
|
|
3664
|
+
] })
|
|
3665
|
+
] }),
|
|
3666
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 border-b px-6 py-5 md:grid-cols-2", children: [
|
|
3667
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Célország", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_COUNTRY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_COUNTRY_CODE", e.target.value.toUpperCase()), placeholder: "HU" }) }),
|
|
3668
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Pénznem", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_CURRENCY_CODE, onChange: (e) => update("GOOGLE_MERCHANT_CURRENCY_CODE", e.target.value.toUpperCase()), placeholder: "HUF" }) }),
|
|
3669
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Storefront URL", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_STOREFRONT_URL, onChange: (e) => update("GOOGLE_MERCHANT_STOREFRONT_URL", e.target.value), placeholder: "https://shop.hu (üresen STOREFRONT_URL)" }) }),
|
|
3670
|
+
/* @__PURE__ */ jsxs(Field$1, { label: "Termék URL sablon", children: [
|
|
3671
|
+
/* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE, onChange: (e) => update("GOOGLE_MERCHANT_PRODUCT_PATH_TEMPLATE", e.target.value) }),
|
|
3672
|
+
/* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-xs", children: [
|
|
3673
|
+
"Helyőrzők: ",
|
|
3674
|
+
"{country_code}",
|
|
3675
|
+
", ",
|
|
3676
|
+
"{currency_code}",
|
|
3677
|
+
", ",
|
|
3678
|
+
"{handle}",
|
|
3679
|
+
", ",
|
|
3680
|
+
"{variant_id}",
|
|
3681
|
+
"."
|
|
3682
|
+
] })
|
|
3683
|
+
] }),
|
|
3684
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Sales Channel ID", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_SALES_CHANNEL_ID, onChange: (e) => update("GOOGLE_MERCHANT_SALES_CHANNEL_ID", e.target.value), placeholder: "sc_... (opcionális)" }) }),
|
|
3685
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Alapértelmezett márka", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_DEFAULT_BRAND, onChange: (e) => update("GOOGLE_MERCHANT_DEFAULT_BRAND", e.target.value) }) }),
|
|
3686
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Alapértelmezett állapot", children: /* @__PURE__ */ 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: [
|
|
3687
|
+
/* @__PURE__ */ jsx("option", { value: "new", children: "Új" }),
|
|
3688
|
+
/* @__PURE__ */ jsx("option", { value: "refurbished", children: "Felújított" }),
|
|
3689
|
+
/* @__PURE__ */ jsx("option", { value: "used", children: "Használt" })
|
|
3690
|
+
] }) }),
|
|
3691
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Készlethiányos variantok", children: /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
3692
|
+
/* @__PURE__ */ jsx(Switch, { checked: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK, onCheckedChange: (value) => update("GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK", value) }),
|
|
3693
|
+
/* @__PURE__ */ jsx(Text, { children: draft.GOOGLE_MERCHANT_INCLUDE_OUT_OF_STOCK ? "Benne maradnak" : "Kimaradnak" })
|
|
3694
|
+
] }) }),
|
|
3695
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Feed neve", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_FEED_TITLE, onChange: (e) => update("GOOGLE_MERCHANT_FEED_TITLE", e.target.value), placeholder: "Üresen automatikus" }) }),
|
|
3696
|
+
/* @__PURE__ */ jsx(Field$1, { label: "Feed leírása", children: /* @__PURE__ */ jsx(Input, { value: draft.GOOGLE_MERCHANT_FEED_DESCRIPTION, onChange: (e) => update("GOOGLE_MERCHANT_FEED_DESCRIPTION", e.target.value), placeholder: "Üresen automatikus" }) })
|
|
3697
|
+
] }),
|
|
3698
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b px-6 py-4", children: [
|
|
3699
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3700
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Publikus feed URL" }),
|
|
3701
|
+
/* @__PURE__ */ jsx("a", { className: "break-all text-ui-fg-interactive hover:underline", href: feedUrl, target: "_blank", rel: "noreferrer", children: feedUrl })
|
|
3702
|
+
] }),
|
|
3703
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
3704
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", isLoading: previewing, disabled: !enabled || loading || saving || previewing, onClick: () => void runPreview(), children: "Feed ellenőrzése" }),
|
|
3705
|
+
/* @__PURE__ */ jsx(Button, { isLoading: saving, disabled: loading || saving || previewing, onClick: () => void save(), children: "Mentés" })
|
|
3706
|
+
] })
|
|
3707
|
+
] }),
|
|
3708
|
+
d ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3709
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b px-6 py-5 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
3710
|
+
/* @__PURE__ */ jsx(Stat, { label: "Termékek", value: d.productsScanned }),
|
|
3711
|
+
/* @__PURE__ */ jsx(Stat, { label: "Variantok", value: d.variantsScanned }),
|
|
3712
|
+
/* @__PURE__ */ jsx(Stat, { label: "Feed tételek", value: d.itemsEmitted }),
|
|
3713
|
+
/* @__PURE__ */ jsx(Stat, { label: "Hiányzó identifier", value: d.itemsMissingIdentifiers }),
|
|
3714
|
+
/* @__PURE__ */ jsx(Stat, { label: "Nincs ár", value: d.skippedNoPrice }),
|
|
3715
|
+
/* @__PURE__ */ jsx(Stat, { label: "Nincs kép", value: d.skippedNoImage }),
|
|
3716
|
+
/* @__PURE__ */ jsx(Stat, { label: "Nincs sales channel", value: d.skippedNoSalesChannel + d.skippedNotInSalesChannel }),
|
|
3717
|
+
/* @__PURE__ */ jsx(Stat, { label: "Érvénytelen GTIN", value: d.invalidGtinsIgnored })
|
|
3718
|
+
] }),
|
|
3719
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
3720
|
+
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
3721
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "ID" }),
|
|
3722
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Termék" }),
|
|
3723
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Ár" }),
|
|
3724
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Készlet" }),
|
|
3725
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Identifier" })
|
|
3726
|
+
] }) }),
|
|
3727
|
+
/* @__PURE__ */ jsx("tbody", { children: (preview?.sample || []).map((item) => /* @__PURE__ */ jsxs("tr", { className: "border-b", children: [
|
|
3728
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("code", { children: item.id }) }),
|
|
3729
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("a", { href: item.link, target: "_blank", rel: "noreferrer", className: "text-ui-fg-interactive hover:underline", children: item.title }) }),
|
|
3730
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.salePrice ? `${item.salePrice} (${item.price})` : item.price }),
|
|
3731
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.availability }),
|
|
3732
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: item.gtin || item.mpn || item.brand || "—" })
|
|
3733
|
+
] }, item.id)) })
|
|
3734
|
+
] }) })
|
|
3735
|
+
] }) : null
|
|
3736
|
+
] });
|
|
3737
|
+
};
|
|
3738
|
+
function Field$1({ label, children }) {
|
|
3739
|
+
return /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
3740
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: label }),
|
|
3741
|
+
children
|
|
3742
|
+
] });
|
|
3743
|
+
}
|
|
3744
|
+
function Stat({ label, value }) {
|
|
3745
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-3", children: [
|
|
3746
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: label }),
|
|
3747
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: value })
|
|
3748
|
+
] });
|
|
3749
|
+
}
|
|
3750
|
+
const config$3 = defineRouteConfig({ label: "Google Merchant", rank: 41 });
|
|
3751
|
+
const backendUrl$3 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
3752
|
+
const adminBase$2 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
3753
|
+
function apiUrl$3(path) {
|
|
3754
|
+
return `${backendUrl$3}${path.startsWith("/") ? path : `/${path}`}`;
|
|
3755
|
+
}
|
|
3756
|
+
const IntegrationOperationsPage = () => {
|
|
3757
|
+
const [operations, setOperations] = useState([]);
|
|
3758
|
+
const [summary, setSummary] = useState({
|
|
3759
|
+
failed: 0,
|
|
3760
|
+
needsReconciliation: 0,
|
|
3761
|
+
processing: 0
|
|
3762
|
+
});
|
|
3763
|
+
const [count, setCount] = useState(0);
|
|
3764
|
+
const [status, setStatus] = useState("problems");
|
|
3765
|
+
const [provider, setProvider] = useState("all");
|
|
3766
|
+
const [query, setQuery] = useState("");
|
|
3767
|
+
const [loading, setLoading] = useState(false);
|
|
3768
|
+
const [actionLoading, setActionLoading] = useState(null);
|
|
3769
|
+
const [loadError, setLoadError] = useState(null);
|
|
3770
|
+
const load = useCallback(async () => {
|
|
3771
|
+
setLoading(true);
|
|
3772
|
+
setLoadError(null);
|
|
3773
|
+
try {
|
|
3774
|
+
const params = new URLSearchParams({
|
|
3775
|
+
limit: "100",
|
|
3776
|
+
status
|
|
3983
3777
|
});
|
|
3984
|
-
|
|
3778
|
+
if (provider !== "all") params.set("provider", provider);
|
|
3779
|
+
const response = await fetch(
|
|
3780
|
+
apiUrl$3(`/admin/integration-operations?${params.toString()}`),
|
|
3781
|
+
{ credentials: "include" }
|
|
3782
|
+
);
|
|
3783
|
+
const payload = await response.json().catch(() => ({}));
|
|
3985
3784
|
if (!response.ok) {
|
|
3986
|
-
throw new Error(
|
|
3785
|
+
throw new Error(
|
|
3786
|
+
payload.message || "Az integrációs műveletek nem tölthetők be."
|
|
3787
|
+
);
|
|
3987
3788
|
}
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3789
|
+
setOperations(payload.operations || []);
|
|
3790
|
+
setCount(payload.count || 0);
|
|
3791
|
+
setSummary(
|
|
3792
|
+
payload.summary || {
|
|
3793
|
+
failed: 0,
|
|
3794
|
+
needsReconciliation: 0,
|
|
3795
|
+
processing: 0
|
|
3796
|
+
}
|
|
3797
|
+
);
|
|
3992
3798
|
} catch (error) {
|
|
3993
|
-
|
|
3799
|
+
setOperations([]);
|
|
3800
|
+
setLoadError(
|
|
3801
|
+
error instanceof Error ? error.message : "Az integrációs műveletek nem tölthetők be."
|
|
3802
|
+
);
|
|
3994
3803
|
} finally {
|
|
3995
|
-
|
|
3804
|
+
setLoading(false);
|
|
3996
3805
|
}
|
|
3997
|
-
};
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
3806
|
+
}, [provider, status]);
|
|
3807
|
+
useEffect(() => {
|
|
3808
|
+
void load();
|
|
3809
|
+
}, [load]);
|
|
3810
|
+
const visible = useMemo(() => {
|
|
3811
|
+
const value = query.trim().toLowerCase();
|
|
3812
|
+
if (!value) return operations;
|
|
3813
|
+
return operations.filter(
|
|
3814
|
+
(operation) => [
|
|
3815
|
+
operation.provider,
|
|
3816
|
+
operation.operation_type,
|
|
3817
|
+
operation.entity_type,
|
|
3818
|
+
operation.entity_id,
|
|
3819
|
+
operation.external_id,
|
|
3820
|
+
operation.error_summary
|
|
3821
|
+
].some(
|
|
3822
|
+
(item) => String(item || "").toLowerCase().includes(value)
|
|
3823
|
+
)
|
|
3824
|
+
);
|
|
3825
|
+
}, [operations, query]);
|
|
3826
|
+
const reconcile = async (operation, decision) => {
|
|
3827
|
+
const confirmed = confirm(
|
|
3828
|
+
decision === "confirmed_succeeded" ? "Megerősíted, hogy a külső szolgáltatónál ez a művelet valóban sikeresen megtörtént?" : "Megerősíted, hogy a külső szolgáltatónál ez a művelet biztosan NEM történt meg? Ez engedélyezi a normál művelet későbbi újrapróbálását."
|
|
3829
|
+
);
|
|
3830
|
+
if (!confirmed) return;
|
|
3831
|
+
let externalId = operation.external_id || void 0;
|
|
3832
|
+
if (decision === "confirmed_succeeded" && !externalId) {
|
|
3833
|
+
externalId = prompt(
|
|
3834
|
+
"Add meg a külső szolgáltató azonosítóját (pl. Billingo document ID vagy shipment ID):"
|
|
3835
|
+
)?.trim() || void 0;
|
|
3836
|
+
if (!externalId) {
|
|
3837
|
+
toast.error("A sikeres lezáráshoz külső azonosító szükséges.");
|
|
3838
|
+
return;
|
|
4010
3839
|
}
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
3840
|
+
}
|
|
3841
|
+
const note = prompt(
|
|
3842
|
+
"Opcionális megjegyzés az egyeztetéshez:",
|
|
3843
|
+
""
|
|
3844
|
+
)?.trim();
|
|
3845
|
+
setActionLoading(operation.id);
|
|
3846
|
+
try {
|
|
3847
|
+
const response = await fetch(
|
|
3848
|
+
apiUrl$3(`/admin/integration-operations/${operation.id}/reconcile`),
|
|
3849
|
+
{
|
|
3850
|
+
method: "POST",
|
|
3851
|
+
credentials: "include",
|
|
3852
|
+
headers: { "Content-Type": "application/json" },
|
|
3853
|
+
body: JSON.stringify({ decision, externalId, note })
|
|
3854
|
+
}
|
|
3855
|
+
);
|
|
3856
|
+
const payload = await response.json().catch(() => ({}));
|
|
3857
|
+
if (!response.ok) {
|
|
3858
|
+
throw new Error(
|
|
3859
|
+
payload.message || "Az egyeztetés lezárása nem sikerült."
|
|
3860
|
+
);
|
|
4015
3861
|
}
|
|
3862
|
+
toast.success(
|
|
3863
|
+
decision === "confirmed_succeeded" ? "A művelet sikeresként lezárva." : "A művelet újrapróbálhatóvá téve."
|
|
3864
|
+
);
|
|
3865
|
+
await load();
|
|
4016
3866
|
} catch (error) {
|
|
4017
3867
|
toast.error(
|
|
4018
|
-
error instanceof Error ? error.message : "
|
|
3868
|
+
error instanceof Error ? error.message : "Az egyeztetés lezárása nem sikerült."
|
|
4019
3869
|
);
|
|
4020
|
-
void load();
|
|
4021
3870
|
} finally {
|
|
4022
|
-
|
|
3871
|
+
setActionLoading(null);
|
|
4023
3872
|
}
|
|
4024
3873
|
};
|
|
4025
|
-
const replaceIntegration = (integration) => {
|
|
4026
|
-
setItems(
|
|
4027
|
-
(current) => current.map(
|
|
4028
|
-
(item) => item.key === integration.key ? integration : item
|
|
4029
|
-
)
|
|
4030
|
-
);
|
|
4031
|
-
};
|
|
4032
|
-
const detailHref = selected ? detailPageForIntegration(selected.key) : null;
|
|
4033
|
-
const connection = selected ? connectionPresentation(selected) : null;
|
|
4034
3874
|
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
4035
|
-
/* @__PURE__ */ jsxs("div", { className: "border-b px-6 py-
|
|
4036
|
-
/* @__PURE__ */
|
|
4037
|
-
|
|
3875
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b px-6 py-4", children: [
|
|
3876
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3877
|
+
/* @__PURE__ */ jsx(Heading, { children: "Integrációs műveletek" }),
|
|
3878
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Külső API műveletek, hibák és kézi reconciliation kezelése." })
|
|
3879
|
+
] }),
|
|
3880
|
+
/* @__PURE__ */ jsx(
|
|
3881
|
+
Button,
|
|
3882
|
+
{
|
|
3883
|
+
variant: "secondary",
|
|
3884
|
+
isLoading: loading,
|
|
3885
|
+
onClick: () => void load(),
|
|
3886
|
+
children: "Frissítés"
|
|
3887
|
+
}
|
|
3888
|
+
)
|
|
4038
3889
|
] }),
|
|
4039
|
-
|
|
4040
|
-
/* @__PURE__ */ jsx(
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
}) })
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
/* @__PURE__ */ jsx(
|
|
4076
|
-
/* @__PURE__ */ jsx(
|
|
3890
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b px-6 py-4 md:grid-cols-3", children: [
|
|
3891
|
+
/* @__PURE__ */ jsx(
|
|
3892
|
+
SummaryCard,
|
|
3893
|
+
{
|
|
3894
|
+
label: "Egyeztetést igényel",
|
|
3895
|
+
value: summary.needsReconciliation,
|
|
3896
|
+
danger: summary.needsReconciliation > 0
|
|
3897
|
+
}
|
|
3898
|
+
),
|
|
3899
|
+
/* @__PURE__ */ jsx(
|
|
3900
|
+
SummaryCard,
|
|
3901
|
+
{
|
|
3902
|
+
label: "Sikertelen",
|
|
3903
|
+
value: summary.failed,
|
|
3904
|
+
danger: summary.failed > 0
|
|
3905
|
+
}
|
|
3906
|
+
),
|
|
3907
|
+
/* @__PURE__ */ jsx(SummaryCard, { label: "Folyamatban", value: summary.processing })
|
|
3908
|
+
] }),
|
|
3909
|
+
summary.needsReconciliation > 0 ? /* @__PURE__ */ jsxs("div", { className: "border-b border-ui-border-warning bg-ui-bg-base px-6 py-4", children: [
|
|
3910
|
+
/* @__PURE__ */ jsxs(Text, { className: "font-medium text-ui-fg-warning", children: [
|
|
3911
|
+
summary.needsReconciliation,
|
|
3912
|
+
" műveletnél nem dönthető el automatikusan, hogy a külső szolgáltató végrehajtotta-e a kérést."
|
|
3913
|
+
] }),
|
|
3914
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Ellenőrizd a szolgáltatónál, majd csak ezután jelöld sikeresnek vagy újrapróbálhatónak. Így elkerülhető a duplikált számla, csomag vagy fizetés." })
|
|
3915
|
+
] }) : null,
|
|
3916
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-3 border-b px-6 py-4", children: [
|
|
3917
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3918
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Státusz" }),
|
|
3919
|
+
/* @__PURE__ */ jsxs(Select, { value: status, onValueChange: setStatus, children: [
|
|
3920
|
+
/* @__PURE__ */ jsx(Select.Trigger, { className: "w-52", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
|
|
3921
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
3922
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "problems", children: "Hibák + egyeztetés" }),
|
|
3923
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "needs_reconciliation", children: "Egyeztetést igényel" }),
|
|
3924
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "failed", children: "Sikertelen" }),
|
|
3925
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "processing", children: "Folyamatban" }),
|
|
3926
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "pending", children: "Várakozik" }),
|
|
3927
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "succeeded", children: "Sikeres" }),
|
|
3928
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "all", children: "Összes" })
|
|
3929
|
+
] })
|
|
3930
|
+
] })
|
|
3931
|
+
] }),
|
|
3932
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3933
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Provider" }),
|
|
3934
|
+
/* @__PURE__ */ jsxs(Select, { value: provider, onValueChange: setProvider, children: [
|
|
3935
|
+
/* @__PURE__ */ jsx(Select.Trigger, { className: "w-44", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
|
|
3936
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
3937
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "all", children: "Összes" }),
|
|
3938
|
+
[
|
|
3939
|
+
"stripe",
|
|
3940
|
+
"simplepay",
|
|
3941
|
+
"billingo",
|
|
3942
|
+
"foxpost",
|
|
3943
|
+
"gls",
|
|
3944
|
+
"packeta",
|
|
3945
|
+
"dpd",
|
|
3946
|
+
"mpl"
|
|
3947
|
+
].map((item) => /* @__PURE__ */ jsx(Select.Item, { value: item, children: providerLabel(item) }, item))
|
|
3948
|
+
] })
|
|
3949
|
+
] })
|
|
3950
|
+
] }),
|
|
3951
|
+
/* @__PURE__ */ jsx(
|
|
3952
|
+
Input,
|
|
3953
|
+
{
|
|
3954
|
+
className: "max-w-sm",
|
|
3955
|
+
value: query,
|
|
3956
|
+
onChange: (event) => setQuery(event.target.value),
|
|
3957
|
+
placeholder: "Keresés művelet, rendelés, külső ID vagy hiba alapján"
|
|
3958
|
+
}
|
|
3959
|
+
),
|
|
3960
|
+
/* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
3961
|
+
count,
|
|
3962
|
+
" találat"
|
|
3963
|
+
] })
|
|
3964
|
+
] }),
|
|
3965
|
+
/* @__PURE__ */ jsxs("div", { className: "overflow-x-auto", children: [
|
|
3966
|
+
/* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
3967
|
+
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
3968
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Státusz" }),
|
|
3969
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Provider / művelet" }),
|
|
3970
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Entitás" }),
|
|
3971
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Külső ID" }),
|
|
3972
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Próbálkozás" }),
|
|
3973
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Hiba / idő" }),
|
|
3974
|
+
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Műveletek" })
|
|
3975
|
+
] }) }),
|
|
3976
|
+
/* @__PURE__ */ jsx("tbody", { children: visible.map((operation) => /* @__PURE__ */ jsxs("tr", { className: "border-b align-top", children: [
|
|
3977
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx(StatusText, { status: operation.status }) }),
|
|
3978
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
3979
|
+
/* @__PURE__ */ jsx("strong", { children: providerLabel(operation.provider) }),
|
|
3980
|
+
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: operation.operation_type })
|
|
4077
3981
|
] }),
|
|
4078
|
-
/* @__PURE__ */ jsxs("
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
/* @__PURE__ */ jsx(StatusBox, { label: "Konfigurálva", value: selected.configured ? "Igen" : "Nem", state: selected.configured ? "success" : "neutral" }),
|
|
4089
|
-
/* @__PURE__ */ jsx(StatusBox, { label: "Aktív", value: selected.enabled ? "Igen" : "Nem", state: selected.enabled ? "success" : "neutral" }),
|
|
4090
|
-
/* @__PURE__ */ jsx(StatusBox, { label: "Kapcsolat", value: connection.label, state: connection.state })
|
|
4091
|
-
] }),
|
|
4092
|
-
selected.category === "shipping" ? /* @__PURE__ */ 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,
|
|
4093
|
-
selected.category === "legal" ? /* @__PURE__ */ 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,
|
|
4094
|
-
selected.category === "marketing" ? /* @__PURE__ */ 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,
|
|
4095
|
-
restartNotice ? /* @__PURE__ */ 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,
|
|
4096
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
4097
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", children: "Beállítások" }),
|
|
4098
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 grid gap-4 sm:grid-cols-2", children: selected.fields.map((field) => /* @__PURE__ */ jsx(
|
|
4099
|
-
FieldEditor,
|
|
4100
|
-
{
|
|
4101
|
-
field,
|
|
4102
|
-
value: draft[field.name],
|
|
4103
|
-
hasSecret: Boolean(selected.secrets[field.name]),
|
|
4104
|
-
clearPending: clearSecrets.includes(field.name),
|
|
4105
|
-
onChange: (value) => {
|
|
4106
|
-
setDraft((current) => ({ ...current, [field.name]: value }));
|
|
4107
|
-
if (field.type === "secret" && String(value || "").trim()) {
|
|
4108
|
-
setClearSecrets(
|
|
4109
|
-
(current) => current.filter((name) => name !== field.name)
|
|
4110
|
-
);
|
|
4111
|
-
}
|
|
4112
|
-
},
|
|
4113
|
-
onClearSecret: () => {
|
|
4114
|
-
setDraft((current) => ({ ...current, [field.name]: "" }));
|
|
4115
|
-
setClearSecrets(
|
|
4116
|
-
(current) => current.includes(field.name) ? current : [...current, field.name]
|
|
4117
|
-
);
|
|
4118
|
-
},
|
|
4119
|
-
onRestoreSecret: () => setClearSecrets(
|
|
4120
|
-
(current) => current.filter((name) => name !== field.name)
|
|
4121
|
-
)
|
|
4122
|
-
},
|
|
4123
|
-
field.name
|
|
4124
|
-
)) })
|
|
4125
|
-
] }),
|
|
4126
|
-
selected.last_test_message ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
4127
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
4128
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Utolsó kapcsolat-teszt" }),
|
|
4129
|
-
/* @__PURE__ */ jsx(Text, { className: connectionTextClass(connection.state), children: connection.label })
|
|
3982
|
+
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
3983
|
+
operation.entity_type === "order" ? /* @__PURE__ */ jsx(
|
|
3984
|
+
"a",
|
|
3985
|
+
{
|
|
3986
|
+
href: `${adminBase$2}/orders/${operation.entity_id}`,
|
|
3987
|
+
className: "text-ui-fg-interactive",
|
|
3988
|
+
children: operation.entity_id
|
|
3989
|
+
}
|
|
3990
|
+
) : /* @__PURE__ */ jsx("span", { children: operation.entity_id }),
|
|
3991
|
+
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: operation.entity_type })
|
|
4130
3992
|
] }),
|
|
4131
|
-
/* @__PURE__ */ jsx(
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
3993
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: operation.external_id || "—" }),
|
|
3994
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: operation.attempts }),
|
|
3995
|
+
/* @__PURE__ */ jsxs("td", { className: "max-w-md p-4", children: [
|
|
3996
|
+
operation.error_summary ? /* @__PURE__ */ jsx("div", { className: "text-ui-fg-error", children: operation.error_summary }) : null,
|
|
3997
|
+
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: formatDate$1(operation.updated_at) })
|
|
3998
|
+
] }),
|
|
3999
|
+
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx("div", { className: "flex min-w-52 flex-wrap gap-2", children: operation.status === "needs_reconciliation" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4136
4000
|
/* @__PURE__ */ jsx(
|
|
4137
4001
|
Button,
|
|
4138
4002
|
{
|
|
4139
|
-
|
|
4140
|
-
disabled:
|
|
4141
|
-
|
|
4142
|
-
|
|
4003
|
+
size: "small",
|
|
4004
|
+
disabled: Boolean(actionLoading),
|
|
4005
|
+
isLoading: actionLoading === operation.id,
|
|
4006
|
+
onClick: () => void reconcile(operation, "confirmed_succeeded"),
|
|
4007
|
+
children: "Megtörtént"
|
|
4143
4008
|
}
|
|
4144
4009
|
),
|
|
4145
4010
|
/* @__PURE__ */ jsx(
|
|
4146
4011
|
Button,
|
|
4147
4012
|
{
|
|
4013
|
+
size: "small",
|
|
4148
4014
|
variant: "secondary",
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
children: "Kapcsolat tesztelése"
|
|
4015
|
+
disabled: Boolean(actionLoading),
|
|
4016
|
+
onClick: () => void reconcile(operation, "confirmed_not_executed"),
|
|
4017
|
+
children: "Nem történt meg"
|
|
4153
4018
|
}
|
|
4154
|
-
)
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4019
|
+
)
|
|
4020
|
+
] }) : operation.status === "failed" ? /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "A normál rendelési művelet újraindítható." }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "—" }) }) })
|
|
4021
|
+
] }, operation.id)) })
|
|
4022
|
+
] }),
|
|
4023
|
+
loading ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Műveletek betöltése…" }) }) : null,
|
|
4024
|
+
!loading && loadError ? /* @__PURE__ */ jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
|
|
4025
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "Az integrációs műveletek nem tölthetők be." }),
|
|
4026
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: loadError })
|
|
4027
|
+
] }) : null,
|
|
4028
|
+
!loading && !loadError && !visible.length ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Nincs a szűrésnek megfelelő integrációs művelet." }) }) : null
|
|
4160
4029
|
] })
|
|
4161
4030
|
] });
|
|
4162
4031
|
};
|
|
4163
|
-
function
|
|
4164
|
-
|
|
4165
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: title }),
|
|
4166
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children })
|
|
4167
|
-
] });
|
|
4168
|
-
}
|
|
4169
|
-
function FieldEditor({
|
|
4170
|
-
field,
|
|
4032
|
+
function SummaryCard({
|
|
4033
|
+
label,
|
|
4171
4034
|
value,
|
|
4172
|
-
|
|
4173
|
-
clearPending,
|
|
4174
|
-
onChange,
|
|
4175
|
-
onClearSecret,
|
|
4176
|
-
onRestoreSecret
|
|
4035
|
+
danger = false
|
|
4177
4036
|
}) {
|
|
4178
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
4179
|
-
/* @__PURE__ */
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4037
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
4038
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
|
|
4039
|
+
/* @__PURE__ */ jsx("div", { className: danger ? "text-ui-fg-error text-2xl font-semibold" : "text-2xl font-semibold", children: value })
|
|
4040
|
+
] });
|
|
4041
|
+
}
|
|
4042
|
+
function StatusText({ status }) {
|
|
4043
|
+
const labels = {
|
|
4044
|
+
pending: "Várakozik",
|
|
4045
|
+
processing: "Folyamatban",
|
|
4046
|
+
succeeded: "Sikeres",
|
|
4047
|
+
failed: "Sikertelen",
|
|
4048
|
+
needs_reconciliation: "Egyeztetést igényel"
|
|
4049
|
+
};
|
|
4050
|
+
const className = status === "failed" || status === "needs_reconciliation" ? "font-medium text-ui-fg-error" : status === "succeeded" ? "font-medium text-ui-fg-success" : "font-medium";
|
|
4051
|
+
return /* @__PURE__ */ jsx("span", { className, children: labels[status] });
|
|
4052
|
+
}
|
|
4053
|
+
function providerLabel(value) {
|
|
4054
|
+
const labels = {
|
|
4055
|
+
stripe: "Stripe",
|
|
4056
|
+
simplepay: "SimplePay",
|
|
4057
|
+
billingo: "Billingo",
|
|
4058
|
+
foxpost: "FOXPOST",
|
|
4059
|
+
gls: "GLS",
|
|
4060
|
+
packeta: "Packeta",
|
|
4061
|
+
dpd: "DPD",
|
|
4062
|
+
mpl: "MPL"
|
|
4063
|
+
};
|
|
4064
|
+
return labels[value] || value;
|
|
4065
|
+
}
|
|
4066
|
+
function formatDate$1(value) {
|
|
4067
|
+
if (!value) return "—";
|
|
4068
|
+
const date = new Date(value);
|
|
4069
|
+
if (Number.isNaN(date.getTime())) return "—";
|
|
4070
|
+
return new Intl.DateTimeFormat("hu-HU", {
|
|
4071
|
+
dateStyle: "short",
|
|
4072
|
+
timeStyle: "short"
|
|
4073
|
+
}).format(date);
|
|
4074
|
+
}
|
|
4075
|
+
const config$2 = defineRouteConfig({
|
|
4076
|
+
label: "Integrációs műveletek",
|
|
4077
|
+
icon: Newspaper,
|
|
4078
|
+
rank: 37
|
|
4079
|
+
});
|
|
4080
|
+
const backendUrl$2 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
4081
|
+
const adminBase$1 = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
4082
|
+
const apiUrl$2 = (path) => `${backendUrl$2}${path.startsWith("/") ? path : `/${path}`}`;
|
|
4083
|
+
const CATEGORY_LABELS = {
|
|
4084
|
+
infrastructure: "Infrastruktúra",
|
|
4085
|
+
security: "Biztonság",
|
|
4086
|
+
store: "Storefront alapok",
|
|
4087
|
+
commerce: "Kereskedelem",
|
|
4088
|
+
communication: "Kommunikáció",
|
|
4089
|
+
compliance: "Jogi megfelelés",
|
|
4090
|
+
marketing: "Mérés és SEO"
|
|
4091
|
+
};
|
|
4092
|
+
const ProductionReadinessPage = () => {
|
|
4093
|
+
const [report, setReport] = useState(null);
|
|
4094
|
+
const [loading, setLoading] = useState(true);
|
|
4095
|
+
const [error, setError] = useState(null);
|
|
4096
|
+
const load = useCallback(async () => {
|
|
4097
|
+
setLoading(true);
|
|
4098
|
+
setError(null);
|
|
4099
|
+
try {
|
|
4100
|
+
const response = await fetch(apiUrl$2("/admin/production-readiness"), {
|
|
4101
|
+
credentials: "include"
|
|
4102
|
+
});
|
|
4103
|
+
const payload = await response.json().catch(() => ({}));
|
|
4104
|
+
if (!response.ok) {
|
|
4105
|
+
throw new Error(payload.message || "Az élesítési ellenőrzés nem tölthető be.");
|
|
4204
4106
|
}
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
"
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4107
|
+
setReport(payload);
|
|
4108
|
+
} catch (cause) {
|
|
4109
|
+
setReport(null);
|
|
4110
|
+
setError(
|
|
4111
|
+
cause instanceof Error ? cause.message : "Az élesítési ellenőrzés nem tölthető be."
|
|
4112
|
+
);
|
|
4113
|
+
} finally {
|
|
4114
|
+
setLoading(false);
|
|
4115
|
+
}
|
|
4116
|
+
}, []);
|
|
4117
|
+
useEffect(() => {
|
|
4118
|
+
void load();
|
|
4119
|
+
}, [load]);
|
|
4120
|
+
const groups = useMemo(() => {
|
|
4121
|
+
const result = /* @__PURE__ */ new Map();
|
|
4122
|
+
for (const item of report?.checks || []) {
|
|
4123
|
+
result.set(item.category, [...result.get(item.category) || [], item]);
|
|
4124
|
+
}
|
|
4125
|
+
return Array.from(result.entries());
|
|
4126
|
+
}, [report]);
|
|
4127
|
+
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
4128
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b px-6 py-5", children: [
|
|
4129
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4130
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Production readiness" }),
|
|
4131
|
+
/* @__PURE__ */ jsx(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." })
|
|
4132
|
+
] }),
|
|
4133
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", isLoading: loading, onClick: () => void load(), children: "Újraellenőrzés" })
|
|
4134
|
+
] }),
|
|
4135
|
+
report ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4136
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-b p-6 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
4137
|
+
/* @__PURE__ */ jsx(Summary, { label: "Kész", value: report.score.ready, tone: "ready" }),
|
|
4138
|
+
/* @__PURE__ */ jsx(Summary, { label: "Figyelmeztetés", value: report.score.warning, tone: "warning" }),
|
|
4139
|
+
/* @__PURE__ */ jsx(Summary, { label: "Blokkoló", value: report.score.blocked, tone: "blocked" }),
|
|
4140
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
4141
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Élesítési döntés" }),
|
|
4142
|
+
/* @__PURE__ */ 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ő" }),
|
|
4143
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-1 text-ui-fg-subtle", children: report.environment === "production" ? "Production szabályok" : "Nem-production szabályok" })
|
|
4144
|
+
] })
|
|
4145
|
+
] }),
|
|
4146
|
+
/* @__PURE__ */ jsx("div", { className: "border-b px-6 py-3", children: /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
4147
|
+
"Utolsó ellenőrzés: ",
|
|
4148
|
+
formatDate(report.generated_at),
|
|
4149
|
+
". A sárga elemek nem blokkolják az élesítést, a piros elemek igen."
|
|
4150
|
+
] }) }),
|
|
4151
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-6 p-6", children: groups.map(([category, checks]) => /* @__PURE__ */ jsxs("section", { className: "overflow-hidden rounded-lg border", children: [
|
|
4152
|
+
/* @__PURE__ */ jsx("div", { className: "border-b bg-ui-bg-subtle px-4 py-3", children: /* @__PURE__ */ jsx(Heading, { level: "h2", children: CATEGORY_LABELS[category] || category }) }),
|
|
4153
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y", children: checks.map((item) => /* @__PURE__ */ jsxs("div", { className: "grid gap-3 p-4 md:grid-cols-[180px_140px_minmax(0,1fr)_auto] md:items-center", children: [
|
|
4154
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
4155
|
+
/* @__PURE__ */ jsx(StatusBadge, { status: item.status }),
|
|
4156
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: item.message }),
|
|
4157
|
+
item.action_href && item.action_label ? /* @__PURE__ */ jsx("a", { href: normalizeAdminHref(item.action_href), children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: item.action_label }) }) : /* @__PURE__ */ jsx("span", {})
|
|
4158
|
+
] }, item.key)) })
|
|
4159
|
+
] }, category)) })
|
|
4160
|
+
] }) : null,
|
|
4161
|
+
loading && !report ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Élesítési feltételek ellenőrzése…" }) }) : null,
|
|
4162
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "m-6 rounded-lg border border-ui-border-error p-4", children: [
|
|
4163
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "Az ellenőrzés nem futott le." }),
|
|
4164
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: error })
|
|
4165
|
+
] }) : null
|
|
4218
4166
|
] });
|
|
4219
|
-
}
|
|
4220
|
-
function
|
|
4221
|
-
label
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
/* @__PURE__ */ jsx(Text, { className: connectionTextClass(state), children: value })
|
|
4167
|
+
};
|
|
4168
|
+
function StatusBadge({ status }) {
|
|
4169
|
+
const label = status === "ready" ? "Kész" : status === "warning" ? "Figyelmeztetés" : "Blokkoló";
|
|
4170
|
+
const className = status === "ready" ? "font-medium text-ui-fg-success" : status === "warning" ? "font-medium text-ui-fg-warning" : "font-medium text-ui-fg-error";
|
|
4171
|
+
return /* @__PURE__ */ jsxs("span", { className, children: [
|
|
4172
|
+
status === "ready" ? "✅" : status === "warning" ? "🟡" : "🔴",
|
|
4173
|
+
" ",
|
|
4174
|
+
label
|
|
4228
4175
|
] });
|
|
4229
4176
|
}
|
|
4230
|
-
function
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4177
|
+
function Summary({ label, value, tone }) {
|
|
4178
|
+
const valueClass = tone === "ready" ? "text-ui-fg-success" : tone === "warning" ? "text-ui-fg-warning" : "text-ui-fg-error";
|
|
4179
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
4180
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: label }),
|
|
4181
|
+
/* @__PURE__ */ jsx("div", { className: `mt-1 text-3xl font-semibold ${valueClass}`, children: value })
|
|
4182
|
+
] });
|
|
4234
4183
|
}
|
|
4235
|
-
function
|
|
4236
|
-
if (
|
|
4237
|
-
|
|
4238
|
-
}
|
|
4239
|
-
if (item.last_test_status === "error") {
|
|
4240
|
-
return { label: "Hiba", state: "error" };
|
|
4241
|
-
}
|
|
4242
|
-
if (item.last_test_at) {
|
|
4243
|
-
return { label: "Részleges ellenőrzés", state: "warning" };
|
|
4244
|
-
}
|
|
4245
|
-
return { label: "Nem ellenőrzött", state: "neutral" };
|
|
4184
|
+
function normalizeAdminHref(path) {
|
|
4185
|
+
if (!path.startsWith("/app")) return path;
|
|
4186
|
+
return `${adminBase$1}${path.slice(4)}`;
|
|
4246
4187
|
}
|
|
4247
|
-
function
|
|
4248
|
-
|
|
4249
|
-
if (
|
|
4250
|
-
|
|
4251
|
-
return "font-medium";
|
|
4188
|
+
function formatDate(value) {
|
|
4189
|
+
const date = new Date(value);
|
|
4190
|
+
if (Number.isNaN(date.getTime())) return "—";
|
|
4191
|
+
return new Intl.DateTimeFormat("hu-HU", { dateStyle: "short", timeStyle: "medium" }).format(date);
|
|
4252
4192
|
}
|
|
4253
|
-
const config$1 = defineRouteConfig({
|
|
4193
|
+
const config$1 = defineRouteConfig({
|
|
4194
|
+
label: "Production readiness",
|
|
4195
|
+
rank: 39
|
|
4196
|
+
});
|
|
4254
4197
|
const backendUrl$1 = (__BACKEND_URL__ || "").replace(/\/+$/, "");
|
|
4255
4198
|
const adminBase = (__BASE__ || "/app").replace(/\/+$/, "");
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4199
|
+
const apiUrl$1 = (path) => `${backendUrl$1}${path.startsWith("/") ? path : `/${path}`}`;
|
|
4200
|
+
const CATEGORY_ORDER = [
|
|
4201
|
+
"payment",
|
|
4202
|
+
"invoicing",
|
|
4203
|
+
"shipping",
|
|
4204
|
+
"notification",
|
|
4205
|
+
"legal",
|
|
4206
|
+
"marketing"
|
|
4207
|
+
];
|
|
4208
|
+
const CATEGORY_LABEL = {
|
|
4209
|
+
payment: "Fizetés",
|
|
4210
|
+
invoicing: "Számlázás",
|
|
4211
|
+
shipping: "Szállítás",
|
|
4212
|
+
notification: "Értesítés",
|
|
4213
|
+
legal: "Jogi integráció",
|
|
4214
|
+
marketing: "Marketing"
|
|
4215
|
+
};
|
|
4216
|
+
const IntegrationsPage = () => {
|
|
4217
|
+
const [items, setItems] = useState([]);
|
|
4218
|
+
const [selectedKey, setSelectedKey] = useState(null);
|
|
4219
|
+
const [draft, setDraft] = useState({});
|
|
4220
|
+
const [clearSecrets, setClearSecrets] = useState([]);
|
|
4221
|
+
const [enabled, setEnabled] = useState(false);
|
|
4222
|
+
const [loading, setLoading] = useState(true);
|
|
4223
|
+
const [saving, setSaving] = useState(false);
|
|
4224
|
+
const [testing, setTesting] = useState(false);
|
|
4225
|
+
const [restartNotice, setRestartNotice] = useState(false);
|
|
4226
|
+
const visibleItems = useMemo(
|
|
4227
|
+
() => items.filter((item) => CATEGORY_ORDER.includes(item.category)),
|
|
4228
|
+
[items]
|
|
4229
|
+
);
|
|
4230
|
+
const selected = useMemo(
|
|
4231
|
+
() => visibleItems.find((item) => item.key === selectedKey) || null,
|
|
4232
|
+
[visibleItems, selectedKey]
|
|
4233
|
+
);
|
|
4234
|
+
const hasUnsavedChanges = useMemo(() => {
|
|
4235
|
+
if (!selected) return false;
|
|
4236
|
+
if (enabled !== selected.enabled || clearSecrets.length > 0) return true;
|
|
4237
|
+
return selected.fields.some((field) => {
|
|
4238
|
+
const value = draft[field.name];
|
|
4239
|
+
if (field.type === "secret") {
|
|
4240
|
+
return Boolean(String(value || "").trim());
|
|
4241
|
+
}
|
|
4242
|
+
if (field.type === "boolean") {
|
|
4243
|
+
return Boolean(value) !== (selected.values[field.name] === "true");
|
|
4244
|
+
}
|
|
4245
|
+
return String(value || "").trim() !== String(selected.values[field.name] || "").trim();
|
|
4246
|
+
});
|
|
4247
|
+
}, [selected, enabled, draft, clearSecrets]);
|
|
4273
4248
|
const load = useCallback(async () => {
|
|
4274
4249
|
setLoading(true);
|
|
4275
|
-
setLoadError(null);
|
|
4276
4250
|
try {
|
|
4277
|
-
const
|
|
4278
|
-
|
|
4279
|
-
status
|
|
4251
|
+
const response = await fetch(apiUrl$1("/admin/integrations"), {
|
|
4252
|
+
credentials: "include"
|
|
4280
4253
|
});
|
|
4281
|
-
|
|
4282
|
-
const response = await fetch(
|
|
4283
|
-
apiUrl$1(`/admin/integration-operations?${params.toString()}`),
|
|
4284
|
-
{ credentials: "include" }
|
|
4285
|
-
);
|
|
4286
|
-
const payload = await response.json().catch(() => ({}));
|
|
4254
|
+
const data = await response.json().catch(() => ({}));
|
|
4287
4255
|
if (!response.ok) {
|
|
4288
|
-
throw new Error(
|
|
4289
|
-
payload.message || "Az integrációs műveletek nem tölthetők be."
|
|
4290
|
-
);
|
|
4256
|
+
throw new Error(data.message || "Az integrációk nem tölthetők be.");
|
|
4291
4257
|
}
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
}
|
|
4258
|
+
const integrations = data.integrations || [];
|
|
4259
|
+
setItems(integrations);
|
|
4260
|
+
const eligible = integrations.filter(
|
|
4261
|
+
(item) => CATEGORY_ORDER.includes(item.category)
|
|
4262
|
+
);
|
|
4263
|
+
setSelectedKey(
|
|
4264
|
+
(current) => current && eligible.some((item) => item.key === current) ? current : eligible[0]?.key || null
|
|
4300
4265
|
);
|
|
4301
4266
|
} catch (error) {
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
error instanceof Error ? error.message : "Az integrációs műveletek nem tölthetők be."
|
|
4267
|
+
toast.error(
|
|
4268
|
+
error instanceof Error ? error.message : "Az integrációk nem tölthetők be."
|
|
4305
4269
|
);
|
|
4306
4270
|
} finally {
|
|
4307
4271
|
setLoading(false);
|
|
4308
4272
|
}
|
|
4309
|
-
}, [
|
|
4273
|
+
}, []);
|
|
4310
4274
|
useEffect(() => {
|
|
4311
4275
|
void load();
|
|
4312
4276
|
}, [load]);
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
(
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
);
|
|
4328
|
-
}, [
|
|
4329
|
-
const
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4277
|
+
useEffect(() => {
|
|
4278
|
+
if (!selected) return;
|
|
4279
|
+
const next = {};
|
|
4280
|
+
for (const field of selected.fields) {
|
|
4281
|
+
if (field.type === "secret") next[field.name] = "";
|
|
4282
|
+
else if (field.type === "boolean") {
|
|
4283
|
+
next[field.name] = selected.values[field.name] === "true";
|
|
4284
|
+
} else {
|
|
4285
|
+
next[field.name] = selected.values[field.name] || "";
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
setDraft(next);
|
|
4289
|
+
setClearSecrets([]);
|
|
4290
|
+
setEnabled(selected.enabled);
|
|
4291
|
+
setRestartNotice(false);
|
|
4292
|
+
}, [selected?.key, selected?.values, selected?.enabled]);
|
|
4293
|
+
const save = async () => {
|
|
4294
|
+
if (!selected) return;
|
|
4295
|
+
setSaving(true);
|
|
4296
|
+
try {
|
|
4297
|
+
const values = {};
|
|
4298
|
+
for (const field of selected.fields) {
|
|
4299
|
+
const value = draft[field.name];
|
|
4300
|
+
if (field.type === "secret" && !String(value || "").trim()) continue;
|
|
4301
|
+
values[field.name] = value;
|
|
4302
|
+
}
|
|
4303
|
+
const response = await fetch(apiUrl$1(`/admin/integrations/${selected.key}`), {
|
|
4304
|
+
method: "POST",
|
|
4305
|
+
credentials: "include",
|
|
4306
|
+
headers: { "Content-Type": "application/json" },
|
|
4307
|
+
body: JSON.stringify({
|
|
4308
|
+
enabled,
|
|
4309
|
+
values,
|
|
4310
|
+
clear_secrets: clearSecrets
|
|
4311
|
+
})
|
|
4312
|
+
});
|
|
4313
|
+
const data = await response.json().catch(() => ({}));
|
|
4314
|
+
if (!response.ok) {
|
|
4315
|
+
throw new Error(data.message || "A mentés nem sikerült.");
|
|
4342
4316
|
}
|
|
4317
|
+
if (data.integration) replaceIntegration(data.integration);
|
|
4318
|
+
setClearSecrets([]);
|
|
4319
|
+
setRestartNotice(Boolean(data.integration?.restart_required));
|
|
4320
|
+
toast.success(data.message || "Beállítások mentve.");
|
|
4321
|
+
} catch (error) {
|
|
4322
|
+
toast.error(error instanceof Error ? error.message : "A mentés nem sikerült.");
|
|
4323
|
+
} finally {
|
|
4324
|
+
setSaving(false);
|
|
4343
4325
|
}
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
setActionLoading(operation.id);
|
|
4326
|
+
};
|
|
4327
|
+
const test = async () => {
|
|
4328
|
+
if (!selected || hasUnsavedChanges) return;
|
|
4329
|
+
setTesting(true);
|
|
4349
4330
|
try {
|
|
4350
|
-
const response = await fetch(
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
);
|
|
4331
|
+
const response = await fetch(apiUrl$1(`/admin/integrations/${selected.key}/test`), {
|
|
4332
|
+
method: "POST",
|
|
4333
|
+
credentials: "include"
|
|
4334
|
+
});
|
|
4335
|
+
const data = await response.json().catch(() => ({}));
|
|
4336
|
+
if (data.integration) replaceIntegration(data.integration);
|
|
4337
|
+
if (!response.ok || !data.ok) {
|
|
4338
|
+
throw new Error(data.message || "A kapcsolat tesztelése nem sikerült.");
|
|
4339
|
+
}
|
|
4340
|
+
if (data.verified) {
|
|
4341
|
+
toast.success(data.message || "Kapcsolat ellenőrizve.");
|
|
4342
|
+
} else {
|
|
4343
|
+
toast.success(data.message || "Részleges ellenőrzés sikeres.");
|
|
4364
4344
|
}
|
|
4365
|
-
toast.success(
|
|
4366
|
-
decision === "confirmed_succeeded" ? "A művelet sikeresként lezárva." : "A művelet újrapróbálhatóvá téve."
|
|
4367
|
-
);
|
|
4368
|
-
await load();
|
|
4369
4345
|
} catch (error) {
|
|
4370
4346
|
toast.error(
|
|
4371
|
-
error instanceof Error ? error.message : "
|
|
4347
|
+
error instanceof Error ? error.message : "A kapcsolat tesztelése nem sikerült."
|
|
4372
4348
|
);
|
|
4349
|
+
void load();
|
|
4373
4350
|
} finally {
|
|
4374
|
-
|
|
4351
|
+
setTesting(false);
|
|
4375
4352
|
}
|
|
4376
4353
|
};
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Külső API műveletek, hibák és kézi reconciliation kezelése." })
|
|
4382
|
-
] }),
|
|
4383
|
-
/* @__PURE__ */ jsx(
|
|
4384
|
-
Button,
|
|
4385
|
-
{
|
|
4386
|
-
variant: "secondary",
|
|
4387
|
-
isLoading: loading,
|
|
4388
|
-
onClick: () => void load(),
|
|
4389
|
-
children: "Frissítés"
|
|
4390
|
-
}
|
|
4354
|
+
const replaceIntegration = (integration) => {
|
|
4355
|
+
setItems(
|
|
4356
|
+
(current) => current.map(
|
|
4357
|
+
(item) => item.key === integration.key ? integration : item
|
|
4391
4358
|
)
|
|
4359
|
+
);
|
|
4360
|
+
};
|
|
4361
|
+
const detailHref = selected ? detailPageForIntegration(selected.key) : null;
|
|
4362
|
+
const connection = selected ? connectionPresentation(selected) : null;
|
|
4363
|
+
return /* @__PURE__ */ jsxs(Container, { className: "p-0", children: [
|
|
4364
|
+
/* @__PURE__ */ jsxs("div", { className: "border-b px-6 py-5", children: [
|
|
4365
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Integrációk" }),
|
|
4366
|
+
/* @__PURE__ */ jsx(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." })
|
|
4392
4367
|
] }),
|
|
4393
|
-
/* @__PURE__ */
|
|
4394
|
-
/* @__PURE__ */ jsx(
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
label: "Sikertelen",
|
|
4406
|
-
value: summary.failed,
|
|
4407
|
-
danger: summary.failed > 0
|
|
4408
|
-
}
|
|
4409
|
-
),
|
|
4410
|
-
/* @__PURE__ */ jsx(SummaryCard, { label: "Folyamatban", value: summary.processing })
|
|
4411
|
-
] }),
|
|
4412
|
-
summary.needsReconciliation > 0 ? /* @__PURE__ */ jsxs("div", { className: "border-b border-ui-border-warning bg-ui-bg-base px-6 py-4", children: [
|
|
4413
|
-
/* @__PURE__ */ jsxs(Text, { className: "font-medium text-ui-fg-warning", children: [
|
|
4414
|
-
summary.needsReconciliation,
|
|
4415
|
-
" műveletnél nem dönthető el automatikusan, hogy a külső szolgáltató végrehajtotta-e a kérést."
|
|
4416
|
-
] }),
|
|
4417
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Ellenőrizd a szolgáltatónál, majd csak ezután jelöld sikeresnek vagy újrapróbálhatónak. Így elkerülhető a duplikált számla, csomag vagy fizetés." })
|
|
4418
|
-
] }) : null,
|
|
4419
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-3 border-b px-6 py-4", children: [
|
|
4420
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4421
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Státusz" }),
|
|
4422
|
-
/* @__PURE__ */ jsxs(Select, { value: status, onValueChange: setStatus, children: [
|
|
4423
|
-
/* @__PURE__ */ jsx(Select.Trigger, { className: "w-52", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
|
|
4424
|
-
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
4425
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "problems", children: "Hibák + egyeztetés" }),
|
|
4426
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "needs_reconciliation", children: "Egyeztetést igényel" }),
|
|
4427
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "failed", children: "Sikertelen" }),
|
|
4428
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "processing", children: "Folyamatban" }),
|
|
4429
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "pending", children: "Várakozik" }),
|
|
4430
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "succeeded", children: "Sikeres" }),
|
|
4431
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "all", children: "Összes" })
|
|
4432
|
-
] })
|
|
4433
|
-
] })
|
|
4434
|
-
] }),
|
|
4435
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4436
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Provider" }),
|
|
4437
|
-
/* @__PURE__ */ jsxs(Select, { value: provider, onValueChange: setProvider, children: [
|
|
4438
|
-
/* @__PURE__ */ jsx(Select.Trigger, { className: "w-44", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
|
|
4439
|
-
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
4440
|
-
/* @__PURE__ */ jsx(Select.Item, { value: "all", children: "Összes" }),
|
|
4441
|
-
[
|
|
4442
|
-
"stripe",
|
|
4443
|
-
"simplepay",
|
|
4444
|
-
"billingo",
|
|
4445
|
-
"foxpost",
|
|
4446
|
-
"gls",
|
|
4447
|
-
"packeta",
|
|
4448
|
-
"dpd",
|
|
4449
|
-
"mpl"
|
|
4450
|
-
].map((item) => /* @__PURE__ */ jsx(Select.Item, { value: item, children: providerLabel(item) }, item))
|
|
4451
|
-
] })
|
|
4452
|
-
] })
|
|
4453
|
-
] }),
|
|
4454
|
-
/* @__PURE__ */ jsx(
|
|
4455
|
-
Input,
|
|
4456
|
-
{
|
|
4457
|
-
className: "max-w-sm",
|
|
4458
|
-
value: query,
|
|
4459
|
-
onChange: (event) => setQuery(event.target.value),
|
|
4460
|
-
placeholder: "Keresés művelet, rendelés, külső ID vagy hiba alapján"
|
|
4461
|
-
}
|
|
4462
|
-
),
|
|
4463
|
-
/* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
4464
|
-
count,
|
|
4465
|
-
" találat"
|
|
4466
|
-
] })
|
|
4467
|
-
] }),
|
|
4468
|
-
/* @__PURE__ */ jsxs("div", { className: "overflow-x-auto", children: [
|
|
4469
|
-
/* @__PURE__ */ jsxs("table", { className: "w-full text-left text-sm", children: [
|
|
4470
|
-
/* @__PURE__ */ jsx("thead", { className: "border-b bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
4471
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Státusz" }),
|
|
4472
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Provider / művelet" }),
|
|
4473
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Entitás" }),
|
|
4474
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Külső ID" }),
|
|
4475
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Próbálkozás" }),
|
|
4476
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Hiba / idő" }),
|
|
4477
|
-
/* @__PURE__ */ jsx("th", { className: "p-4", children: "Műveletek" })
|
|
4478
|
-
] }) }),
|
|
4479
|
-
/* @__PURE__ */ jsx("tbody", { children: visible.map((operation) => /* @__PURE__ */ jsxs("tr", { className: "border-b align-top", children: [
|
|
4480
|
-
/* @__PURE__ */ jsx("td", { className: "p-4", children: /* @__PURE__ */ jsx(StatusText, { status: operation.status }) }),
|
|
4481
|
-
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
4482
|
-
/* @__PURE__ */ jsx("strong", { children: providerLabel(operation.provider) }),
|
|
4483
|
-
/* @__PURE__ */ jsx("div", { className: "text-ui-fg-subtle", children: operation.operation_type })
|
|
4484
|
-
] }),
|
|
4485
|
-
/* @__PURE__ */ jsxs("td", { className: "p-4", children: [
|
|
4486
|
-
operation.entity_type === "order" ? /* @__PURE__ */ jsx(
|
|
4487
|
-
"a",
|
|
4368
|
+
loading ? /* @__PURE__ */ jsx("div", { className: "p-6", children: /* @__PURE__ */ jsx(Text, { children: "Betöltés…" }) }) : /* @__PURE__ */ jsxs("div", { className: "grid lg:grid-cols-[320px_minmax(0,1fr)]", children: [
|
|
4369
|
+
/* @__PURE__ */ jsx("aside", { className: "border-r p-4", children: CATEGORY_ORDER.map((category) => {
|
|
4370
|
+
const categoryItems = visibleItems.filter(
|
|
4371
|
+
(item) => item.category === category
|
|
4372
|
+
);
|
|
4373
|
+
if (!categoryItems.length) return null;
|
|
4374
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6 last:mb-0", children: [
|
|
4375
|
+
/* @__PURE__ */ jsx(Text, { className: "mb-2 px-1 text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: CATEGORY_LABEL[category] }),
|
|
4376
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: categoryItems.map((item) => {
|
|
4377
|
+
const itemConnection = connectionPresentation(item);
|
|
4378
|
+
return /* @__PURE__ */ jsxs(
|
|
4379
|
+
"button",
|
|
4488
4380
|
{
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4381
|
+
type: "button",
|
|
4382
|
+
onClick: () => setSelectedKey(item.key),
|
|
4383
|
+
className: `rounded-lg border p-3 text-left transition-colors hover:bg-ui-bg-subtle ${selectedKey === item.key ? "bg-ui-bg-subtle" : "bg-ui-bg-base"}`,
|
|
4384
|
+
children: [
|
|
4385
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
4386
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: item.label }),
|
|
4387
|
+
/* @__PURE__ */ jsx("span", { className: item.enabled ? "text-xs font-medium text-ui-fg-success" : "text-xs text-ui-fg-muted", children: item.enabled ? "Aktív" : "Kikapcsolva" })
|
|
4388
|
+
] }),
|
|
4389
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: [
|
|
4390
|
+
item.configured ? "Konfigurálva" : "Beállítás szükséges",
|
|
4391
|
+
" · ",
|
|
4392
|
+
itemConnection.label
|
|
4393
|
+
] })
|
|
4394
|
+
]
|
|
4395
|
+
},
|
|
4396
|
+
item.key
|
|
4397
|
+
);
|
|
4398
|
+
}) })
|
|
4399
|
+
] }, category);
|
|
4400
|
+
}) }),
|
|
4401
|
+
/* @__PURE__ */ jsx("main", { className: "min-w-0 p-6", children: selected && connection ? /* @__PURE__ */ jsxs("div", { className: "flex max-w-4xl flex-col gap-6", children: [
|
|
4402
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
|
|
4403
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
4404
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", children: selected.label }),
|
|
4405
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 text-ui-fg-subtle", children: selected.description })
|
|
4495
4406
|
] }),
|
|
4496
|
-
/* @__PURE__ */
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4407
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-1", children: [
|
|
4408
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
4409
|
+
/* @__PURE__ */ jsx(Switch, { checked: enabled, onCheckedChange: setEnabled }),
|
|
4410
|
+
/* @__PURE__ */ jsx(Text, { children: enabled ? "Bekapcsolva" : "Kikapcsolva" })
|
|
4411
|
+
] }),
|
|
4412
|
+
hasUnsavedChanges ? /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-warning", children: "Nem mentett módosítások" }) : null
|
|
4413
|
+
] })
|
|
4414
|
+
] }),
|
|
4415
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-4", children: [
|
|
4416
|
+
/* @__PURE__ */ jsx(StatusBox, { label: "Telepítve", value: selected.installed ? "Igen" : "Nem", state: selected.installed ? "success" : "neutral" }),
|
|
4417
|
+
/* @__PURE__ */ jsx(StatusBox, { label: "Konfigurálva", value: selected.configured ? "Igen" : "Nem", state: selected.configured ? "success" : "neutral" }),
|
|
4418
|
+
/* @__PURE__ */ jsx(StatusBox, { label: "Aktív", value: selected.enabled ? "Igen" : "Nem", state: selected.enabled ? "success" : "neutral" }),
|
|
4419
|
+
/* @__PURE__ */ jsx(StatusBox, { label: "Kapcsolat", value: connection.label, state: connection.state })
|
|
4420
|
+
] }),
|
|
4421
|
+
selected.category === "shipping" ? /* @__PURE__ */ 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,
|
|
4422
|
+
selected.category === "legal" ? /* @__PURE__ */ 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,
|
|
4423
|
+
selected.category === "marketing" ? /* @__PURE__ */ 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,
|
|
4424
|
+
restartNotice ? /* @__PURE__ */ 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,
|
|
4425
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4426
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", children: "Beállítások" }),
|
|
4427
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 grid gap-4 sm:grid-cols-2", children: selected.fields.map((field) => /* @__PURE__ */ jsx(
|
|
4428
|
+
FieldEditor,
|
|
4429
|
+
{
|
|
4430
|
+
field,
|
|
4431
|
+
value: draft[field.name],
|
|
4432
|
+
hasSecret: Boolean(selected.secrets[field.name]),
|
|
4433
|
+
clearPending: clearSecrets.includes(field.name),
|
|
4434
|
+
onChange: (value) => {
|
|
4435
|
+
setDraft((current) => ({ ...current, [field.name]: value }));
|
|
4436
|
+
if (field.type === "secret" && String(value || "").trim()) {
|
|
4437
|
+
setClearSecrets(
|
|
4438
|
+
(current) => current.filter((name) => name !== field.name)
|
|
4439
|
+
);
|
|
4440
|
+
}
|
|
4441
|
+
},
|
|
4442
|
+
onClearSecret: () => {
|
|
4443
|
+
setDraft((current) => ({ ...current, [field.name]: "" }));
|
|
4444
|
+
setClearSecrets(
|
|
4445
|
+
(current) => current.includes(field.name) ? current : [...current, field.name]
|
|
4446
|
+
);
|
|
4447
|
+
},
|
|
4448
|
+
onRestoreSecret: () => setClearSecrets(
|
|
4449
|
+
(current) => current.filter((name) => name !== field.name)
|
|
4450
|
+
)
|
|
4451
|
+
},
|
|
4452
|
+
field.name
|
|
4453
|
+
)) })
|
|
4454
|
+
] }),
|
|
4455
|
+
selected.last_test_message ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
|
|
4456
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
4457
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Utolsó kapcsolat-teszt" }),
|
|
4458
|
+
/* @__PURE__ */ jsx(Text, { className: connectionTextClass(connection.state), children: connection.label })
|
|
4501
4459
|
] }),
|
|
4502
|
-
/* @__PURE__ */ jsx(
|
|
4460
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 text-ui-fg-subtle", children: selected.last_test_message }),
|
|
4461
|
+
selected.last_test_at ? /* @__PURE__ */ jsx(Text, { className: "mt-1 text-xs text-ui-fg-muted", children: new Date(selected.last_test_at).toLocaleString("hu-HU") }) : null
|
|
4462
|
+
] }) : null,
|
|
4463
|
+
/* @__PURE__ */ jsxs("div", { className: "border-t pt-5", children: [
|
|
4464
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4503
4465
|
/* @__PURE__ */ jsx(
|
|
4504
4466
|
Button,
|
|
4505
4467
|
{
|
|
4506
|
-
|
|
4507
|
-
disabled:
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
children: "Megtörtént"
|
|
4468
|
+
isLoading: saving,
|
|
4469
|
+
disabled: saving || testing || !hasUnsavedChanges,
|
|
4470
|
+
onClick: () => void save(),
|
|
4471
|
+
children: "Mentés"
|
|
4511
4472
|
}
|
|
4512
4473
|
),
|
|
4513
4474
|
/* @__PURE__ */ jsx(
|
|
4514
4475
|
Button,
|
|
4515
4476
|
{
|
|
4516
|
-
size: "small",
|
|
4517
4477
|
variant: "secondary",
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4478
|
+
isLoading: testing,
|
|
4479
|
+
disabled: saving || testing || hasUnsavedChanges || !selected.configured || !selected.enabled,
|
|
4480
|
+
onClick: () => void test(),
|
|
4481
|
+
children: "Kapcsolat tesztelése"
|
|
4521
4482
|
}
|
|
4522
|
-
)
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium text-ui-fg-error", children: "Az integrációs műveletek nem tölthetők be." }),
|
|
4529
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: loadError })
|
|
4530
|
-
] }) : null,
|
|
4531
|
-
!loading && !loadError && !visible.length ? /* @__PURE__ */ jsx("div", { className: "p-8 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Nincs a szűrésnek megfelelő integrációs művelet." }) }) : null
|
|
4483
|
+
),
|
|
4484
|
+
detailHref ? /* @__PURE__ */ jsx("a", { href: detailHref, className: "ml-auto", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Részletes nézet" }) }) : null
|
|
4485
|
+
] }),
|
|
4486
|
+
hasUnsavedChanges ? /* @__PURE__ */ jsx(Text, { className: "mt-2 text-xs text-ui-fg-warning", children: "A kapcsolat-teszt mindig a mentett konfigurációt használja. Mentsd a módosításokat a teszt előtt." }) : !selected.enabled ? /* @__PURE__ */ jsx(Text, { className: "mt-2 text-xs text-ui-fg-muted", children: "Kapcsolat-teszt csak bekapcsolt integráción futtatható." }) : !selected.configured ? /* @__PURE__ */ jsx(Text, { className: "mt-2 text-xs text-ui-fg-muted", children: "Töltsd ki a kötelező mezőket és mentsd az integrációt a teszteléshez." }) : null
|
|
4487
|
+
] })
|
|
4488
|
+
] }) : /* @__PURE__ */ jsx(Text, { children: "Nincs kiválasztott integráció." }) })
|
|
4532
4489
|
] })
|
|
4533
4490
|
] });
|
|
4534
4491
|
};
|
|
4535
|
-
function
|
|
4492
|
+
function Notice({ title, children }) {
|
|
4493
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-ui-bg-subtle p-4", children: [
|
|
4494
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: title }),
|
|
4495
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children })
|
|
4496
|
+
] });
|
|
4497
|
+
}
|
|
4498
|
+
function FieldEditor({
|
|
4499
|
+
field,
|
|
4500
|
+
value,
|
|
4501
|
+
hasSecret,
|
|
4502
|
+
clearPending,
|
|
4503
|
+
onChange,
|
|
4504
|
+
onClearSecret,
|
|
4505
|
+
onRestoreSecret
|
|
4506
|
+
}) {
|
|
4507
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
4508
|
+
/* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
|
|
4509
|
+
field.label,
|
|
4510
|
+
field.required ? " *" : ""
|
|
4511
|
+
] }),
|
|
4512
|
+
field.type === "boolean" ? /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-2", children: [
|
|
4513
|
+
/* @__PURE__ */ jsx(Switch, { checked: Boolean(value), onCheckedChange: onChange }),
|
|
4514
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: value ? "Igen" : "Nem" })
|
|
4515
|
+
] }) : field.type === "select" ? /* @__PURE__ */ jsxs(
|
|
4516
|
+
"select",
|
|
4517
|
+
{
|
|
4518
|
+
className: "h-8 rounded-md border bg-ui-bg-field px-2 text-sm",
|
|
4519
|
+
value: String(value || ""),
|
|
4520
|
+
onChange: (event) => onChange(event.target.value),
|
|
4521
|
+
children: [
|
|
4522
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "—" }),
|
|
4523
|
+
(field.options || []).map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
4524
|
+
]
|
|
4525
|
+
}
|
|
4526
|
+
) : /* @__PURE__ */ jsx(
|
|
4527
|
+
Input,
|
|
4528
|
+
{
|
|
4529
|
+
type: field.type === "secret" ? "password" : field.type === "number" ? "number" : "text",
|
|
4530
|
+
value: String(value || ""),
|
|
4531
|
+
placeholder: field.type === "secret" && hasSecret && !clearPending ? "•••••••• (beállítva – hagyd üresen a megtartáshoz)" : field.help,
|
|
4532
|
+
onChange: (event) => onChange(event.target.value)
|
|
4533
|
+
}
|
|
4534
|
+
),
|
|
4535
|
+
field.type === "secret" && hasSecret ? /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
4536
|
+
/* @__PURE__ */ jsx(Text, { className: `text-xs ${clearPending ? "text-ui-fg-error" : "text-ui-fg-muted"}`, children: clearPending ? "A mentett titok a következő mentéskor törlődik." : "Titkos érték beállítva." }),
|
|
4537
|
+
/* @__PURE__ */ jsx(
|
|
4538
|
+
"button",
|
|
4539
|
+
{
|
|
4540
|
+
type: "button",
|
|
4541
|
+
className: "shrink-0 text-xs font-medium text-ui-fg-interactive hover:underline",
|
|
4542
|
+
onClick: clearPending ? onRestoreSecret : onClearSecret,
|
|
4543
|
+
children: clearPending ? "Törlés visszavonása" : "Titok törlése"
|
|
4544
|
+
}
|
|
4545
|
+
)
|
|
4546
|
+
] }) : field.help ? /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: field.help }) : null
|
|
4547
|
+
] });
|
|
4548
|
+
}
|
|
4549
|
+
function StatusBox({
|
|
4536
4550
|
label,
|
|
4537
4551
|
value,
|
|
4538
|
-
|
|
4552
|
+
state
|
|
4539
4553
|
}) {
|
|
4540
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-
|
|
4541
|
-
/* @__PURE__ */ jsx(Text, {
|
|
4542
|
-
/* @__PURE__ */ jsx(
|
|
4554
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-3", children: [
|
|
4555
|
+
/* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: label }),
|
|
4556
|
+
/* @__PURE__ */ jsx(Text, { className: connectionTextClass(state), children: value })
|
|
4543
4557
|
] });
|
|
4544
4558
|
}
|
|
4545
|
-
function
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
succeeded: "Sikeres",
|
|
4550
|
-
failed: "Sikertelen",
|
|
4551
|
-
needs_reconciliation: "Egyeztetést igényel"
|
|
4552
|
-
};
|
|
4553
|
-
const className = status === "failed" || status === "needs_reconciliation" ? "font-medium text-ui-fg-error" : status === "succeeded" ? "font-medium text-ui-fg-success" : "font-medium";
|
|
4554
|
-
return /* @__PURE__ */ jsx("span", { className, children: labels[status] });
|
|
4559
|
+
function detailPageForIntegration(key) {
|
|
4560
|
+
if (key === "google-merchant") return `${adminBase}/marketing/google-merchant`;
|
|
4561
|
+
if (key === "arukereso") return `${adminBase}/marketing/arukereso`;
|
|
4562
|
+
return null;
|
|
4555
4563
|
}
|
|
4556
|
-
function
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
};
|
|
4567
|
-
return labels[value] || value;
|
|
4564
|
+
function connectionPresentation(item) {
|
|
4565
|
+
if (item.last_test_status === "ok") {
|
|
4566
|
+
return { label: "Ellenőrizve", state: "success" };
|
|
4567
|
+
}
|
|
4568
|
+
if (item.last_test_status === "error") {
|
|
4569
|
+
return { label: "Hiba", state: "error" };
|
|
4570
|
+
}
|
|
4571
|
+
if (item.last_test_at) {
|
|
4572
|
+
return { label: "Részleges ellenőrzés", state: "warning" };
|
|
4573
|
+
}
|
|
4574
|
+
return { label: "Nem ellenőrzött", state: "neutral" };
|
|
4568
4575
|
}
|
|
4569
|
-
function
|
|
4570
|
-
if (
|
|
4571
|
-
|
|
4572
|
-
if (
|
|
4573
|
-
return
|
|
4574
|
-
dateStyle: "short",
|
|
4575
|
-
timeStyle: "short"
|
|
4576
|
-
}).format(date);
|
|
4576
|
+
function connectionTextClass(state) {
|
|
4577
|
+
if (state === "success") return "font-medium text-ui-fg-success";
|
|
4578
|
+
if (state === "warning") return "font-medium text-ui-fg-warning";
|
|
4579
|
+
if (state === "error") return "font-medium text-ui-fg-error";
|
|
4580
|
+
return "font-medium";
|
|
4577
4581
|
}
|
|
4578
|
-
const config = defineRouteConfig({
|
|
4579
|
-
label: "Integrációs műveletek",
|
|
4580
|
-
icon: Newspaper,
|
|
4581
|
-
rank: 37
|
|
4582
|
-
});
|
|
4582
|
+
const config = defineRouteConfig({ label: "Integrációk" });
|
|
4583
4583
|
const EMPTY = {
|
|
4584
4584
|
sourcePath: "",
|
|
4585
4585
|
targetPath: "",
|
|
@@ -4916,8 +4916,8 @@ const routeModule = {
|
|
|
4916
4916
|
handle: { label: config$9.label, translationNs: config$9.translationNs }
|
|
4917
4917
|
},
|
|
4918
4918
|
{
|
|
4919
|
-
Component:
|
|
4920
|
-
path: "/
|
|
4919
|
+
Component: BillingPage,
|
|
4920
|
+
path: "/billing",
|
|
4921
4921
|
handle: { label: config$8.label, translationNs: config$8.translationNs }
|
|
4922
4922
|
},
|
|
4923
4923
|
{
|
|
@@ -4926,42 +4926,42 @@ const routeModule = {
|
|
|
4926
4926
|
handle: { label: config$7.label, translationNs: config$7.translationNs }
|
|
4927
4927
|
},
|
|
4928
4928
|
{
|
|
4929
|
-
Component:
|
|
4930
|
-
path: "/
|
|
4929
|
+
Component: ArukeresoPage,
|
|
4930
|
+
path: "/marketing/arukereso",
|
|
4931
4931
|
handle: { label: config$6.label, translationNs: config$6.translationNs }
|
|
4932
4932
|
},
|
|
4933
4933
|
{
|
|
4934
4934
|
Component: SeoAdminPage,
|
|
4935
4935
|
path: "/marketing/seo"
|
|
4936
4936
|
},
|
|
4937
|
-
{
|
|
4938
|
-
Component: GoogleMerchantPage,
|
|
4939
|
-
path: "/marketing/google-merchant",
|
|
4940
|
-
handle: { label: config$5.label, translationNs: config$5.translationNs }
|
|
4941
|
-
},
|
|
4942
4937
|
{
|
|
4943
4938
|
Component: CoreAuditPage,
|
|
4944
4939
|
path: "/system-monitoring/audit",
|
|
4945
|
-
handle: { label: config$
|
|
4940
|
+
handle: { label: config$5.label, translationNs: config$5.translationNs }
|
|
4946
4941
|
},
|
|
4947
4942
|
{
|
|
4948
4943
|
Component: IntegrationHealthPage,
|
|
4949
4944
|
path: "/system-monitoring/health",
|
|
4945
|
+
handle: { label: config$4.label, translationNs: config$4.translationNs }
|
|
4946
|
+
},
|
|
4947
|
+
{
|
|
4948
|
+
Component: GoogleMerchantPage,
|
|
4949
|
+
path: "/marketing/google-merchant",
|
|
4950
4950
|
handle: { label: config$3.label, translationNs: config$3.translationNs }
|
|
4951
4951
|
},
|
|
4952
4952
|
{
|
|
4953
|
-
Component:
|
|
4954
|
-
path: "/system-monitoring/
|
|
4953
|
+
Component: IntegrationOperationsPage,
|
|
4954
|
+
path: "/system-monitoring/operations",
|
|
4955
4955
|
handle: { label: config$2.label, translationNs: config$2.translationNs }
|
|
4956
4956
|
},
|
|
4957
4957
|
{
|
|
4958
|
-
Component:
|
|
4959
|
-
path: "/
|
|
4958
|
+
Component: ProductionReadinessPage,
|
|
4959
|
+
path: "/system-monitoring/readiness",
|
|
4960
4960
|
handle: { label: config$1.label, translationNs: config$1.translationNs }
|
|
4961
4961
|
},
|
|
4962
4962
|
{
|
|
4963
|
-
Component:
|
|
4964
|
-
path: "/
|
|
4963
|
+
Component: IntegrationsPage,
|
|
4964
|
+
path: "/settings/integrations",
|
|
4965
4965
|
handle: { label: config.label, translationNs: config.translationNs }
|
|
4966
4966
|
},
|
|
4967
4967
|
{
|
|
@@ -4981,8 +4981,8 @@ const menuItemModule = {
|
|
|
4981
4981
|
translationNs: void 0
|
|
4982
4982
|
},
|
|
4983
4983
|
{
|
|
4984
|
-
label: config$
|
|
4985
|
-
icon: config$
|
|
4984
|
+
label: config$8.label,
|
|
4985
|
+
icon: config$8.icon,
|
|
4986
4986
|
path: "/billing",
|
|
4987
4987
|
nested: void 0,
|
|
4988
4988
|
rank: 36,
|
|
@@ -5004,6 +5004,14 @@ const menuItemModule = {
|
|
|
5004
5004
|
rank: void 0,
|
|
5005
5005
|
translationNs: void 0
|
|
5006
5006
|
},
|
|
5007
|
+
{
|
|
5008
|
+
label: config$a.label,
|
|
5009
|
+
icon: config$a.icon,
|
|
5010
|
+
path: "/shipping",
|
|
5011
|
+
nested: void 0,
|
|
5012
|
+
rank: 35,
|
|
5013
|
+
translationNs: void 0
|
|
5014
|
+
},
|
|
5007
5015
|
{
|
|
5008
5016
|
label: config$9.label,
|
|
5009
5017
|
icon: void 0,
|
|
@@ -5013,23 +5021,23 @@ const menuItemModule = {
|
|
|
5013
5021
|
translationNs: void 0
|
|
5014
5022
|
},
|
|
5015
5023
|
{
|
|
5016
|
-
label: config
|
|
5017
|
-
icon:
|
|
5018
|
-
path: "/
|
|
5024
|
+
label: config.label,
|
|
5025
|
+
icon: void 0,
|
|
5026
|
+
path: "/settings/integrations",
|
|
5019
5027
|
nested: void 0,
|
|
5020
|
-
rank:
|
|
5028
|
+
rank: void 0,
|
|
5021
5029
|
translationNs: void 0
|
|
5022
5030
|
},
|
|
5023
5031
|
{
|
|
5024
|
-
label: config$
|
|
5032
|
+
label: config$3.label,
|
|
5025
5033
|
icon: void 0,
|
|
5026
|
-
path: "/
|
|
5034
|
+
path: "/marketing/google-merchant",
|
|
5027
5035
|
nested: void 0,
|
|
5028
|
-
rank:
|
|
5036
|
+
rank: 41,
|
|
5029
5037
|
translationNs: void 0
|
|
5030
5038
|
},
|
|
5031
5039
|
{
|
|
5032
|
-
label: config$
|
|
5040
|
+
label: config$6.label,
|
|
5033
5041
|
icon: void 0,
|
|
5034
5042
|
path: "/marketing/arukereso",
|
|
5035
5043
|
nested: void 0,
|
|
@@ -5038,43 +5046,35 @@ const menuItemModule = {
|
|
|
5038
5046
|
},
|
|
5039
5047
|
{
|
|
5040
5048
|
label: config$5.label,
|
|
5041
|
-
icon:
|
|
5042
|
-
path: "/
|
|
5049
|
+
icon: config$5.icon,
|
|
5050
|
+
path: "/system-monitoring/audit",
|
|
5043
5051
|
nested: void 0,
|
|
5044
|
-
rank:
|
|
5052
|
+
rank: 39,
|
|
5045
5053
|
translationNs: void 0
|
|
5046
5054
|
},
|
|
5047
5055
|
{
|
|
5048
5056
|
label: config$4.label,
|
|
5049
5057
|
icon: config$4.icon,
|
|
5050
|
-
path: "/system-monitoring/
|
|
5058
|
+
path: "/system-monitoring/health",
|
|
5051
5059
|
nested: void 0,
|
|
5052
|
-
rank:
|
|
5060
|
+
rank: 38,
|
|
5053
5061
|
translationNs: void 0
|
|
5054
5062
|
},
|
|
5055
5063
|
{
|
|
5056
|
-
label: config.label,
|
|
5057
|
-
icon: config.icon,
|
|
5064
|
+
label: config$2.label,
|
|
5065
|
+
icon: config$2.icon,
|
|
5058
5066
|
path: "/system-monitoring/operations",
|
|
5059
5067
|
nested: void 0,
|
|
5060
5068
|
rank: 37,
|
|
5061
5069
|
translationNs: void 0
|
|
5062
5070
|
},
|
|
5063
5071
|
{
|
|
5064
|
-
label: config$
|
|
5072
|
+
label: config$1.label,
|
|
5065
5073
|
icon: void 0,
|
|
5066
5074
|
path: "/system-monitoring/readiness",
|
|
5067
5075
|
nested: void 0,
|
|
5068
5076
|
rank: 39,
|
|
5069
5077
|
translationNs: void 0
|
|
5070
|
-
},
|
|
5071
|
-
{
|
|
5072
|
-
label: config$3.label,
|
|
5073
|
-
icon: config$3.icon,
|
|
5074
|
-
path: "/system-monitoring/health",
|
|
5075
|
-
nested: void 0,
|
|
5076
|
-
rank: 38,
|
|
5077
|
-
translationNs: void 0
|
|
5078
5078
|
}
|
|
5079
5079
|
]
|
|
5080
5080
|
};
|