add update checker

add UiKitProvider
This commit is contained in:
Mohamadzadeh 2026-06-13 18:10:15 +03:30
parent 6c90d80901
commit 99c0c27f9a
4 changed files with 454 additions and 281 deletions

627
dist/index.js vendored
View File

@ -1,55 +1,55 @@
import { jsxs as I, jsx as a } from "react/jsx-runtime"; import { jsxs as B, jsx as a, Fragment as Z } from "react/jsx-runtime";
import { useState as B, useRef as z, useEffect as C, useCallback as E, createContext as G, useMemo as R, useContext as Z } from "react"; import { useState as v, useRef as N, useEffect as C, useCallback as E, createContext as $, useMemo as z, useContext as P } from "react";
import { HStack as k, IconButton as D, Button as V, Input as W, Text as S } from "@chakra-ui/react"; import { HStack as I, IconButton as D, Button as L, Input as U, Text as S, Spinner as ee } from "@chakra-ui/react";
import { IoChevronForwardOutline as O, IoChevronBackOutline as q } from "react-icons/io5"; import { IoChevronForwardOutline as g, IoChevronBackOutline as O } from "react-icons/io5";
import P from "keycloak-js"; import te from "keycloak-js";
import { useQuery as ee } from "@tanstack/react-query"; import { useQuery as ne } from "@tanstack/react-query";
import te from "axios"; import re from "axios";
const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => String(e).replace(/\d/g, (t) => "۰۱۲۳۴۵۶۷۸۹"[Number(t)]), K = (e) => String(e).replace(/[۰-۹]/g, (r) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(r))), Ce = ({ const Ee = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => String(e).replace(/\d/g, (t) => "۰۱۲۳۴۵۶۷۸۹"[Number(t)]), K = (e) => String(e).replace(/[۰-۹]/g, (n) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(n))), Ke = ({
currentPage: e, currentPage: e,
totalPages: t, totalPages: t,
totalCount: r, totalCount: n,
onPageChange: l onPageChange: s
}) => { }) => {
const [c, i] = B(p(e)), [u, o] = B(!1), [f, s] = B(null), w = z(null), y = [.../* @__PURE__ */ new Set([1, e, t])].filter( const [c, l] = v(p(e)), [i, o] = v(!1), [f, u] = v(null), w = N(null), y = [.../* @__PURE__ */ new Set([1, e, t])].filter(
(n) => n >= 1 && n <= t (r) => r >= 1 && r <= t
); );
C(() => { C(() => {
if (f !== null) { if (f !== null) {
e === f && (s(null), o(!1), i(p(e))); e === f && (u(null), o(!1), l(p(e)));
return; return;
} }
u || i(p(e)); i || l(p(e));
}, [e, u, f]), C(() => { }, [e, i, f]), C(() => {
if (!u || !c || f !== null) return; if (!i || !c || f !== null) return;
const n = parseInt(K(c), 10); const r = parseInt(K(c), 10);
if (isNaN(n)) return; if (isNaN(r)) return;
const h = setTimeout(() => { const h = setTimeout(() => {
var b; var b;
const m = Math.min(Math.max(n, 1), t); const m = Math.min(Math.max(r, 1), t);
m !== e ? (s(m), i(p(m)), l(m)) : (o(!1), i(p(e))), (b = w.current) == null || b.blur(); m !== e ? (u(m), l(p(m)), s(m)) : (o(!1), l(p(e))), (b = w.current) == null || b.blur();
}, 1e3); }, 1e3);
return () => clearTimeout(h); return () => clearTimeout(h);
}, [ }, [
c, c,
u, i,
f, f,
t, t,
e, e,
l s
]); ]);
const v = () => { const A = () => {
var m, b; var m, b;
const n = parseInt(K(c), 10); const r = parseInt(K(c), 10);
if (isNaN(n)) { if (isNaN(r)) {
i(p(e)), o(!1), s(null), (m = w.current) == null || m.blur(); l(p(e)), o(!1), u(null), (m = w.current) == null || m.blur();
return; return;
} }
const h = Math.min(Math.max(n, 1), t); const h = Math.min(Math.max(r, 1), t);
h !== e ? (s(h), i(p(h)), l(h)) : (i(p(e)), o(!1), s(null)), (b = w.current) == null || b.blur(); h !== e ? (u(h), l(p(h)), s(h)) : (l(p(e)), o(!1), u(null)), (b = w.current) == null || b.blur();
}; };
return t === 0 || !r ? null : /* @__PURE__ */ I( return t === 0 || !n ? null : /* @__PURE__ */ B(
k, I,
{ {
justifyContent: "space-around", justifyContent: "space-around",
backgroundColor: "white", backgroundColor: "white",
@ -60,7 +60,7 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
borderColor: "blue.200", borderColor: "blue.200",
w: "100%", w: "100%",
children: [ children: [
/* @__PURE__ */ I(k, { spacing: 2, alignItems: "center", justifyContent: "center", children: [ /* @__PURE__ */ B(I, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
{ {
@ -68,25 +68,25 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => l(e - 1), onClick: () => s(e - 1),
isDisabled: e === 1, isDisabled: e === 1,
icon: /* @__PURE__ */ a(O, {}), icon: /* @__PURE__ */ a(g, {}),
"aria-label": "صفحه قبلی" "aria-label": "صفحه قبلی"
} }
), ),
y.map((n) => /* @__PURE__ */ a( y.map((r) => /* @__PURE__ */ a(
V, L,
{ {
size: "md", size: "md",
px: 2, px: 2,
bg: e === n ? "#4B49AC" : "#e6e6f1", bg: e === r ? "#4B49AC" : "#e6e6f1",
color: e === n ? "#e6e6f1" : "#4B49AC", color: e === r ? "#e6e6f1" : "#4B49AC",
_hover: { bg: e === n ? "#4B49AC" : "#cbcbe8" }, _hover: { bg: e === r ? "#4B49AC" : "#cbcbe8" },
onClick: () => l(n), onClick: () => s(r),
variant: "soft", variant: "soft",
children: p(n) children: p(r)
}, },
n r
)), )),
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
@ -95,14 +95,14 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => l(e + 1), onClick: () => s(e + 1),
isDisabled: e === t, isDisabled: e === t,
icon: /* @__PURE__ */ a(q, {}), icon: /* @__PURE__ */ a(O, {}),
"aria-label": "صفحه بعدی" "aria-label": "صفحه بعدی"
} }
), ),
/* @__PURE__ */ a( /* @__PURE__ */ a(
W, U,
{ {
ref: w, ref: w,
type: "text", type: "text",
@ -111,17 +111,17 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
w: "56px", w: "56px",
value: c, value: c,
onFocus: () => { onFocus: () => {
o(!0), s(null), i(""); o(!0), u(null), l("");
}, },
onChange: (n) => { onChange: (r) => {
const h = n.target.value, m = K(h).replace(/\D/g, ""); const h = r.target.value, m = K(h).replace(/\D/g, "");
i(p(m)); l(p(m));
}, },
onBlur: () => { onBlur: () => {
c || (i(p(e)), o(!1), s(null)); c || (l(p(e)), o(!1), u(null));
}, },
onKeyDown: (n) => { onKeyDown: (r) => {
n.key === "Enter" && v(); r.key === "Enter" && A();
}, },
textAlign: "center", textAlign: "center",
color: "#1D2939", color: "#1D2939",
@ -131,58 +131,58 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
} }
) )
] }), ] }),
/* @__PURE__ */ I(k, { spacing: 2, children: [ /* @__PURE__ */ B(I, { spacing: 2, children: [
/* @__PURE__ */ a(S, { w: "auto", fontWeight: "bold", whiteSpace: "nowrap", children: "تعداد کل:" }), /* @__PURE__ */ a(S, { w: "auto", fontWeight: "bold", whiteSpace: "nowrap", children: "تعداد کل:" }),
/* @__PURE__ */ a(S, { children: p(r) }) /* @__PURE__ */ a(S, { children: p(n) })
] }) ] })
] ]
} }
); );
}, ke = ({ }, De = ({
currentPage: e, currentPage: e,
totalPages: t, totalPages: t,
totalCount: r, totalCount: n,
onPageChange: l onPageChange: s
}) => { }) => {
const [c, i] = B(p(e)), [u, o] = B(!1), [f, s] = B(null), w = z(null), y = Array.from( const [c, l] = v(p(e)), [i, o] = v(!1), [f, u] = v(null), w = N(null), y = Array.from(
/* @__PURE__ */ new Set([1, e, e + 1, t]) /* @__PURE__ */ new Set([1, e, e + 1, t])
).filter((n) => n >= 1 && n <= t).sort((n, h) => n - h); ).filter((r) => r >= 1 && r <= t).sort((r, h) => r - h);
C(() => { C(() => {
if (f !== null) { if (f !== null) {
e === f && (s(null), o(!1), i(p(e))); e === f && (u(null), o(!1), l(p(e)));
return; return;
} }
u || i(p(e)); i || l(p(e));
}, [e, u, f]), C(() => { }, [e, i, f]), C(() => {
if (!u || !c || f !== null) return; if (!i || !c || f !== null) return;
const n = parseInt(K(c), 10); const r = parseInt(K(c), 10);
if (isNaN(n)) return; if (isNaN(r)) return;
const h = setTimeout(() => { const h = setTimeout(() => {
var b; var b;
const m = Math.min(Math.max(n, 1), t); const m = Math.min(Math.max(r, 1), t);
m !== e ? (s(m), i(p(m)), l(m)) : (o(!1), i(p(e))), (b = w.current) == null || b.blur(); m !== e ? (u(m), l(p(m)), s(m)) : (o(!1), l(p(e))), (b = w.current) == null || b.blur();
}, 1e3); }, 1e3);
return () => clearTimeout(h); return () => clearTimeout(h);
}, [ }, [
c, c,
u, i,
f, f,
t, t,
e, e,
l s
]); ]);
const v = () => { const A = () => {
var m, b; var m, b;
const n = parseInt(K(c), 10); const r = parseInt(K(c), 10);
if (isNaN(n)) { if (isNaN(r)) {
i(p(e)), o(!1), s(null), (m = w.current) == null || m.blur(); l(p(e)), o(!1), u(null), (m = w.current) == null || m.blur();
return; return;
} }
const h = Math.min(Math.max(n, 1), t); const h = Math.min(Math.max(r, 1), t);
h !== e ? (s(h), i(p(h)), l(h)) : (i(p(e)), o(!1), s(null)), (b = w.current) == null || b.blur(); h !== e ? (u(h), l(p(h)), s(h)) : (l(p(e)), o(!1), u(null)), (b = w.current) == null || b.blur();
}; };
return t === 0 || !r ? null : /* @__PURE__ */ I( return t === 0 || !n ? null : /* @__PURE__ */ B(
k, I,
{ {
justifyContent: "space-around", justifyContent: "space-around",
backgroundColor: "white", backgroundColor: "white",
@ -193,13 +193,13 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
borderColor: "blue.200", borderColor: "blue.200",
w: "100%", w: "100%",
children: [ children: [
/* @__PURE__ */ I(k, { spacing: 2, whiteSpace: "nowrap", children: [ /* @__PURE__ */ B(I, { spacing: 2, whiteSpace: "nowrap", children: [
/* @__PURE__ */ a(S, { fontWeight: "bold", children: "صفحه" }), /* @__PURE__ */ a(S, { fontWeight: "bold", children: "صفحه" }),
/* @__PURE__ */ a(S, { children: p(e) }), /* @__PURE__ */ a(S, { children: p(e) }),
/* @__PURE__ */ a(S, { fontWeight: "bold", children: "از" }), /* @__PURE__ */ a(S, { fontWeight: "bold", children: "از" }),
/* @__PURE__ */ a(S, { children: p(t) }) /* @__PURE__ */ a(S, { children: p(t) })
] }), ] }),
/* @__PURE__ */ I(k, { spacing: 2, alignItems: "center", justifyContent: "center", children: [ /* @__PURE__ */ B(I, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
{ {
@ -207,24 +207,24 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => l(e - 1), onClick: () => s(e - 1),
isDisabled: e === 1, isDisabled: e === 1,
icon: /* @__PURE__ */ a(O, {}), icon: /* @__PURE__ */ a(g, {}),
"aria-label": "صفحه قبلی" "aria-label": "صفحه قبلی"
} }
), ),
y.map((n) => /* @__PURE__ */ a( y.map((r) => /* @__PURE__ */ a(
V, L,
{ {
size: "md", size: "md",
bg: e === n ? "#4B49AC" : "#e6e6f1", bg: e === r ? "#4B49AC" : "#e6e6f1",
color: e === n ? "#e6e6f1" : "#4B49AC", color: e === r ? "#e6e6f1" : "#4B49AC",
_hover: { bg: e === n ? "#4B49AC" : "#cbcbe8" }, _hover: { bg: e === r ? "#4B49AC" : "#cbcbe8" },
onClick: () => l(n), onClick: () => s(r),
variant: "soft", variant: "soft",
children: p(n) children: p(r)
}, },
n r
)), )),
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
@ -233,14 +233,14 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => l(e + 1), onClick: () => s(e + 1),
isDisabled: e === t, isDisabled: e === t,
icon: /* @__PURE__ */ a(q, {}), icon: /* @__PURE__ */ a(O, {}),
"aria-label": "صفحه بعدی" "aria-label": "صفحه بعدی"
} }
), ),
/* @__PURE__ */ a( /* @__PURE__ */ a(
W, U,
{ {
ref: w, ref: w,
type: "text", type: "text",
@ -249,17 +249,17 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
w: "100px", w: "100px",
value: c, value: c,
onFocus: () => { onFocus: () => {
o(!0), s(null), i(""); o(!0), u(null), l("");
}, },
onChange: (n) => { onChange: (r) => {
const h = n.target.value, m = K(h).replace(/\D/g, ""); const h = r.target.value, m = K(h).replace(/\D/g, "");
i(p(m)); l(p(m));
}, },
onBlur: () => { onBlur: () => {
c || (i(p(e)), o(!1), s(null)); c || (l(p(e)), o(!1), u(null));
}, },
onKeyDown: (n) => { onKeyDown: (r) => {
n.key === "Enter" && v(); r.key === "Enter" && A();
}, },
textAlign: "center", textAlign: "center",
color: "#1D2939", color: "#1D2939",
@ -269,69 +269,69 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
} }
) )
] }), ] }),
/* @__PURE__ */ I(k, { spacing: 2, whiteSpace: "nowrap", children: [ /* @__PURE__ */ B(I, { spacing: 2, whiteSpace: "nowrap", children: [
/* @__PURE__ */ a(S, { fontWeight: "bold", children: "تعداد کل:" }), /* @__PURE__ */ a(S, { fontWeight: "bold", children: "تعداد کل:" }),
/* @__PURE__ */ a(S, { children: p(r) }) /* @__PURE__ */ a(S, { children: p(n) })
] }) ] })
] ]
} }
); );
}, Se = ({ }, Ne = ({
currentPage: e, currentPage: e,
totalPages: t, totalPages: t,
totalCount: r, totalCount: n,
onPageChange: l onPageChange: s
}) => { }) => {
const [c, i] = B(""), [u, o] = B(!1), [f, s] = B(null), w = z(null), y = f ?? e, v = E( const [c, l] = v(""), [i, o] = v(!1), [f, u] = v(null), w = N(null), y = f ?? e, A = E(
(x) => { (x) => {
const A = Math.min(Math.max(x, 1), t); const k = Math.min(Math.max(x, 1), t);
o(!1), i(""), s(null), A !== e && l(A); o(!1), l(""), u(null), k !== e && s(k);
}, },
[e, t, l] [e, t, s]
), n = E(() => { ), r = E(() => {
if (!c) { if (!c) {
o(!1), i(""), s(null); o(!1), l(""), u(null);
return; return;
} }
const x = parseInt(K(c), 10); const x = parseInt(K(c), 10);
if (isNaN(x)) { if (isNaN(x)) {
o(!1), i(""), s(null); o(!1), l(""), u(null);
return; return;
} }
const A = Math.min(Math.max(x, 1), t); const k = Math.min(Math.max(x, 1), t);
o(!1), i(""), A !== e ? (s(A), l(A)) : s(null); o(!1), l(""), k !== e ? (u(k), s(k)) : u(null);
}, [c, e, t, l]); }, [c, e, t, s]);
C(() => { C(() => {
var x; var x;
u && ((x = w.current) == null || x.focus()); i && ((x = w.current) == null || x.focus());
}, [u]), C(() => { }, [i]), C(() => {
f !== null && e === f && s(null); f !== null && e === f && u(null);
}, [e, f]), C(() => { }, [e, f]), C(() => {
if (!u || !c) return; if (!i || !c) return;
const x = setTimeout(() => { const x = setTimeout(() => {
n(); r();
}, 1e3); }, 1e3);
return () => clearTimeout(x); return () => clearTimeout(x);
}, [c, u, n]); }, [c, i, r]);
const h = () => { const h = () => {
s(null), i(""), o(!0); u(null), l(""), o(!0);
}, m = (x, A = !1) => /* @__PURE__ */ a( }, m = (x, k = !1) => /* @__PURE__ */ a(
V, L,
{ {
size: "md", size: "md",
bg: A ? "#4B49AC" : "#e6e6f1", bg: k ? "#4B49AC" : "#e6e6f1",
color: A ? "#e6e6f1" : "#4B49AC", color: k ? "#e6e6f1" : "#4B49AC",
_hover: { bg: A ? "#4B49AC" : "#cbcbe8" }, _hover: { bg: k ? "#4B49AC" : "#cbcbe8" },
onClick: A ? h : () => v(x), onClick: k ? h : () => A(x),
variant: "soft", variant: "soft",
children: p(x) children: p(x)
}, },
x x
); );
if (t === 0 || !r) return null; if (t === 0 || !n) return null;
const b = t > 1 && y !== 1, _ = t > 1 && y !== t; const b = t > 1 && y !== 1, F = t > 1 && y !== t;
return /* @__PURE__ */ a( return /* @__PURE__ */ a(
k, I,
{ {
justifyContent: "center", justifyContent: "center",
backgroundColor: "white", backgroundColor: "white",
@ -341,7 +341,7 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
border: "1px", border: "1px",
borderColor: "blue.200", borderColor: "blue.200",
w: "100%", w: "100%",
children: /* @__PURE__ */ I(k, { spacing: 2, alignItems: "center", justifyContent: "center", children: [ children: /* @__PURE__ */ B(I, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
{ {
@ -349,15 +349,15 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => v(y - 1), onClick: () => A(y - 1),
isDisabled: y === 1, isDisabled: y === 1,
icon: /* @__PURE__ */ a(O, {}), icon: /* @__PURE__ */ a(g, {}),
"aria-label": "صفحه قبلی" "aria-label": "صفحه قبلی"
} }
), ),
b && m(1), b && m(1),
u ? /* @__PURE__ */ a( i ? /* @__PURE__ */ a(
W, U,
{ {
ref: w, ref: w,
type: "text", type: "text",
@ -366,14 +366,14 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
w: "48px", w: "48px",
value: c, value: c,
onChange: (x) => { onChange: (x) => {
const A = x.target.value, X = K(A).replace(/\D/g, ""); const k = x.target.value, X = K(k).replace(/\D/g, "");
i(p(X)); l(p(X));
}, },
onBlur: () => { onBlur: () => {
c ? n() : (i(""), o(!1), s(null)); c ? r() : (l(""), o(!1), u(null));
}, },
onKeyDown: (x) => { onKeyDown: (x) => {
x.key === "Enter" && n(), x.key === "Escape" && (i(""), o(!1), s(null)); x.key === "Enter" && r(), x.key === "Escape" && (l(""), o(!1), u(null));
}, },
textAlign: "center", textAlign: "center",
color: "#1D2939", color: "#1D2939",
@ -382,7 +382,7 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
dir: "ltr" dir: "ltr"
} }
) : m(y, !0), ) : m(y, !0),
_ && m(t), F && m(t),
/* @__PURE__ */ a( /* @__PURE__ */ a(
D, D,
{ {
@ -390,9 +390,9 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
bg: "#e6e6f1", bg: "#e6e6f1",
color: "#4B49AC", color: "#4B49AC",
_hover: { bg: "#cbcbe8" }, _hover: { bg: "#cbcbe8" },
onClick: () => v(y + 1), onClick: () => A(y + 1),
isDisabled: y === t, isDisabled: y === t,
icon: /* @__PURE__ */ a(q, {}), icon: /* @__PURE__ */ a(O, {}),
"aria-label": "صفحه بعدی" "aria-label": "صفحه بعدی"
} }
) )
@ -400,92 +400,92 @@ const Be = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), p = (e) => S
} }
); );
}; };
let j = null, d = null, F = null, L = !1; let R = null, d = null, V = null, j = !1;
const ne = G(null), re = ({ url: e, realm: t, clientId: r }) => (d || (d = new P({ const ie = $(null), oe = ({ url: e, realm: t, clientId: n }) => (d || (d = new te({
url: e, url: e,
realm: t, realm: t,
clientId: r clientId: n
})), d), ie = (e) => (j = e, j), oe = () => L, $ = () => !!(d != null && d.authenticated), N = () => (d == null ? void 0 : d.token) ?? null, U = async (e = 30) => d ? d.updateToken(e) : !1, J = (e) => d == null ? void 0 : d.logout(e), Ie = (e) => d == null ? void 0 : d.login(e), Q = ({ config: e, initOptions: t = {} } = {}) => { })), d), se = (e) => (R = e, R), le = () => j, G = () => !!(d != null && d.authenticated), T = () => (d == null ? void 0 : d.token) ?? null, q = async (e = 30) => d ? d.updateToken(e) : !1, H = (e) => d == null ? void 0 : d.logout(e), Te = (e) => d == null ? void 0 : d.login(e), J = ({ config: e, initOptions: t = {} } = {}) => {
const r = e ?? j; const n = e ?? R;
if (!(r != null && r.url) || !(r != null && r.realm) || !(r != null && r.clientId)) if (!(n != null && n.url) || !(n != null && n.realm) || !(n != null && n.clientId))
throw new Error("Keycloak config is required."); throw new Error("Keycloak config is required.");
ie(r); se(n);
const l = re(r); const s = oe(n);
return F || (F = l.init({ return V || (V = s.init({
onLoad: "login-required", onLoad: "login-required",
checkLoginIframe: !1, checkLoginIframe: !1,
flow: "implicit", flow: "implicit",
...t ...t
}).then((c) => (L = !0, c)).catch((c) => { }).then((c) => (j = !0, c)).catch((c) => {
throw L = !0, c; throw j = !0, c;
})), F; })), V;
}, Ee = ({ }, ce = ({
children: e, children: e,
config: t, config: t,
initOptions: r, initOptions: n,
loading: l = null loading: s = null
}) => { }) => {
const [c, i] = B(!1), [u, o] = B(!1), [f, s] = B(null), w = z(!1), y = E(() => { const [c, l] = v(!1), [i, o] = v(!1), [f, u] = v(null), w = N(!1), y = E(() => {
d && (o(!!d.authenticated), s(d.token ?? null)); d && (o(!!d.authenticated), u(d.token ?? null));
}, []); }, []);
C(() => (w.current = !0, Q({ config: t, initOptions: r }).then((b) => { C(() => (w.current = !0, J({ config: t, initOptions: n }).then((b) => {
w.current && (o(!!b), s((d == null ? void 0 : d.token) ?? null), i(!0)); w.current && (o(!!b), u((d == null ? void 0 : d.token) ?? null), l(!0));
}).catch(() => { }).catch(() => {
w.current && (o(!1), s(null), i(!0)); w.current && (o(!1), u(null), l(!0));
}), () => { }), () => {
w.current = !1; w.current = !1;
}), [t, r]); }), [t, n]);
const v = E(() => d == null ? void 0 : d.login(), []), n = E((b) => d == null ? void 0 : d.logout(b), []), h = E( const A = E(() => d == null ? void 0 : d.login(), []), r = E((b) => d == null ? void 0 : d.logout(b), []), h = E(
async (b = 30) => { async (b = 30) => {
if (!d) return !1; if (!d) return !1;
const _ = await d.updateToken(b); const F = await d.updateToken(b);
return y(), _; return y(), F;
}, },
[y] [y]
), m = R( ), m = z(
() => ({ () => ({
initialized: c, initialized: c,
authenticated: u, authenticated: i,
token: f, token: f,
login: v, login: A,
logout: n, logout: r,
updateToken: h updateToken: h
}), }),
[c, u, f, v, n, h] [c, i, f, A, r, h]
); );
return c ? /* @__PURE__ */ a(ne.Provider, { value: m, children: e }) : l; return c ? /* @__PURE__ */ a(ie.Provider, { value: m, children: e }) : s;
}, Y = G(null), M = "permissions", se = (e) => (e == null ? void 0 : e.storageKey) || M, Ke = ({ }, Q = $(null), M = "permissions", ue = (e) => (e == null ? void 0 : e.storageKey) || M, ze = ({
user: e = null, user: e = null,
children: t, children: t,
config: r, config: n,
loading: l = /* @__PURE__ */ a("div", { children: "Loading permissions..." }), loading: s = /* @__PURE__ */ a("div", { children: "Loading permissions..." }),
errorFallback: c = /* @__PURE__ */ a("div", { children: "Error loading permissions" }) errorFallback: c = /* @__PURE__ */ a("div", { children: "Error loading permissions" })
}) => { }) => {
const i = se(r), [u, o] = B( const l = ue(n), [i, o] = v(
() => le(i) () => ae(l)
), { data: f, isLoading: s, error: w } = fe(r), y = f ?? u; ), { data: f, isLoading: u, error: w } = me(n), y = f ?? i;
C(() => { C(() => {
f && (ce(i, f), o(f)); f && (de(l, f), o(f));
}, [f, i]); }, [f, l]);
const v = R( const A = z(
() => ue(y), () => fe(y),
[y] [y]
), n = E( ), r = E(
(b = "") => ae(v, b), (b = "") => pe(A, b),
[v] [A]
), h = E((b = "") => !n(b), [n]), m = R( ), h = E((b = "") => !r(b), [r]), m = z(
() => ({ () => ({
user: e, user: e,
can: n, can: r,
cannot: h, cannot: h,
permissions: y, permissions: y,
isLoading: s, isLoading: u,
error: w error: w
}), }),
[e, n, h, y, s, w] [e, r, h, y, u, w]
); );
return w && !y ? c : s && !y ? l : /* @__PURE__ */ a(Y.Provider, { value: m, children: t }); return w && !y ? c : u && !y ? s : /* @__PURE__ */ a(Q.Provider, { value: m, children: t });
}, le = (e = M) => { }, ae = (e = M) => {
if (!(typeof window > "u")) if (!(typeof window > "u"))
try { try {
const t = localStorage.getItem(e); const t = localStorage.getItem(e);
@ -493,156 +493,221 @@ const ne = G(null), re = ({ url: e, realm: t, clientId: r }) => (d || (d = new P
} catch { } catch {
return; return;
} }
}, ce = (e = M, t) => { }, de = (e = M, t) => {
if (!(typeof window > "u")) if (!(typeof window > "u"))
try { try {
localStorage.setItem(e, JSON.stringify(t)); localStorage.setItem(e, JSON.stringify(t));
} catch { } catch {
} }
}, De = (e = M) => { }, _e = (e = M) => {
if (!(typeof window > "u")) if (!(typeof window > "u"))
try { try {
localStorage.removeItem(e); localStorage.removeItem(e);
} catch { } catch {
} }
}, ue = (e) => e ? new Set(e.map((t) => t.name)) : /* @__PURE__ */ new Set(), ae = (e, t = "") => { }, fe = (e) => e ? new Set(e.map((t) => t.name)) : /* @__PURE__ */ new Set(), pe = (e, t = "") => {
if (!t) return !1; if (!t) return !1;
if (e.has(t) || [...e].some((l) => l.startsWith(t))) return !0; if (e.has(t) || [...e].some((s) => s.startsWith(t))) return !0;
let r = t; let n = t;
for (; r.includes(":"); ) for (; n.includes(":"); )
if (r = r.slice(0, r.lastIndexOf(":")), e.has(`${r}:*`)) return !0; if (n = n.slice(0, n.lastIndexOf(":")), e.has(`${n}:*`)) return !0;
return !1; return !1;
}, H = { }, Y = {
all: ["permissions"], all: ["permissions"],
list: (e) => [...H.all, e] list: (e) => [...Y.all, e]
}, de = async (e) => { }, he = async (e) => {
if (!(e != null && e.url) || !(e != null && e.clientId)) if (!(e != null && e.url) || !(e != null && e.clientId))
throw new Error("Permission config requires url and clientId."); throw new Error("Permission config requires url and clientId.");
const t = N(), r = new URL(e.url); const t = T(), n = new URL(e.url);
r.searchParams.set("client_id", e.clientId); n.searchParams.set("client_id", e.clientId);
const l = await fetch(r.toString(), { const s = await fetch(n.toString(), {
method: "GET", method: "GET",
headers: { headers: {
...t ? { Authorization: `Bearer ${t}` } : {} ...t ? { Authorization: `Bearer ${t}` } : {}
} }
}); });
if (!l.ok) if (!s.ok)
throw new Error("Failed to load permissions"); throw new Error("Failed to load permissions");
return l.json(); return s.json();
}, g = () => { }, W = () => {
const e = Z(Y); const e = P(Q);
if (!e) if (!e)
throw new Error("usePermission must be used within PermissionProvider"); throw new Error("usePermission must be used within PermissionProvider");
return e; return e;
}, fe = (e) => ee({ }, me = (e) => ne({
queryKey: H.list(e == null ? void 0 : e.clientId), queryKey: Y.list(e == null ? void 0 : e.clientId),
queryFn: () => de(e), queryFn: () => he(e),
enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && $(), enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && G(),
staleTime: 1 / 0, staleTime: 1 / 0,
refetchOnWindowFocus: !1, refetchOnWindowFocus: !1,
refetchOnReconnect: !1 refetchOnReconnect: !1
}), Ne = ({ }), Me = ({
perm: e, perm: e,
children: t, children: t,
fallback: r = /* @__PURE__ */ a("div", { children: "You are not allowed to do this" }) fallback: n = /* @__PURE__ */ a("div", { children: "You are not allowed to do this" })
}) => { }) => {
const { can: l } = g(); const { can: s } = W();
return l(e) ? t : r; return s(e) ? t : n;
}, Te = ({ children: e }) => { }, Fe = ({ children: e }) => {
const { can: t, permissions: r } = g(); const { can: t, permissions: n } = W();
return r && t("admin") ? e : null; return n && t("admin") ? e : null;
}, ze = ({ children: e }) => { }, Ve = ({ children: e }) => {
const { can: t, isLoading: r } = g(); const { can: t, isLoading: n } = W();
return C(() => { return C(() => {
r || t("panel_access") || J(); n || t("panel_access") || H();
}, [r, t]), e; }, [n, t]), e;
}; };
let T = null; let _ = null;
const pe = (e) => { const be = (e) => {
const { api: t } = e, r = te.create({ const { api: t } = e, n = re.create({
baseURL: t.baseUrl baseURL: t.baseUrl
}), l = async () => { }), s = async () => {
(!oe() || !$()) && await Q(); (!le() || !G()) && await J();
}, c = async (u) => { }, c = async (i) => {
await l(); await s();
let o = N(); let o = T();
if (o) { if (o) {
try { try {
await U(5), o = N(); await q(5), o = T();
} catch { } catch {
} }
u.headers = { i.headers = {
...u.headers, ...i.headers,
Authorization: `Bearer ${o}` Authorization: `Bearer ${o}`
}; };
} }
return u; return i;
}, i = async (u) => { }, l = async (i) => {
var f; var f;
const o = u.config; const o = i.config;
if (((f = u == null ? void 0 : u.response) == null ? void 0 : f.status) === 401 && !(o != null && o._retry)) { if (((f = i == null ? void 0 : i.response) == null ? void 0 : f.status) === 401 && !(o != null && o._retry)) {
o._retry = !0; o._retry = !0;
try { try {
await U(30); await q(30);
const s = N(); const u = T();
return o.headers = { return o.headers = {
...o.headers, ...o.headers,
Authorization: `Bearer ${s}` Authorization: `Bearer ${u}`
}, r(o); }, n(o);
} catch { } catch {
J({ redirectUri: window.location.origin }); H({ redirectUri: window.location.origin });
} }
} }
return Promise.reject(u); return Promise.reject(i);
}; };
return r.interceptors.request.use(c), r.interceptors.response.use( return n.interceptors.request.use(c), n.interceptors.response.use(
(u) => u, (i) => i,
i l
), { ), {
api: r api: n
}; };
}, Me = (e) => (T = pe(e), T), he = () => { }, we = (e) => (_ = be(e), _), ye = () => {
if (!T) if (!_)
throw new Error("api is not configured. Call configureApi(config) first."); throw new Error("api is not configured. Call configureApi(config) first.");
return T.api; return _.api;
}, _e = new Proxy( }, Re = new Proxy(
{}, {},
{ {
get(e, t) { get(e, t) {
return he()[t]; return ye()[t];
} }
} }
); );
function xe() {
const [e, t] = v(!1), n = N(null);
return C(() => {
if (process.env.NODE_ENV !== "production") return;
let s;
const c = async () => {
const i = await fetch(`/version.json?t=${Date.now()}`, {
cache: "no-store"
});
if (!i.ok)
throw new Error(`Failed to fetch version: ${i.status}`);
const o = await i.json();
return String(o.version);
};
return (async () => {
try {
n.current = await c(), s = setInterval(async () => {
try {
const i = await c();
n.current && i !== n.current && (t(!0), clearInterval(s));
} catch (i) {
console.error("Update check failed:", i);
}
}, 3e4);
} catch (i) {
console.error("Initial version fetch failed:", i);
}
})(), () => {
s && clearInterval(s);
};
}, []), e ? /* @__PURE__ */ a(
"div",
{
style: {
position: "fixed",
bottom: "16px",
right: "16px",
background: "#111",
color: "#fff",
padding: "12px 16px",
borderRadius: "8px",
zIndex: 9999,
cursor: "pointer"
},
onClick: () => window.location.reload(),
children: "نسخه جدید سامانه در دسترس است"
}
) : null;
}
function je({
children: e,
config: t,
loading: n = /* @__PURE__ */ a(ee, {}),
updateChecker: s = !0,
updateCheckerProps: c
}) {
return z(() => {
we(t);
}, [t]), /* @__PURE__ */ B(Z, { children: [
s && /* @__PURE__ */ a(xe, { ...c }),
/* @__PURE__ */ a(ce, { config: t.keycloak, loading: n, children: e })
] });
}
export { export {
Te as AdminGuard, Fe as AdminGuard,
Ne as Can, Me as Can,
Ee as KeycloakProvider, ce as KeycloakProvider,
Ce as LightPagination, Ke as LightPagination,
ke as Pagination, De as Pagination,
ze as PanelAccessGuard, Ve as PanelAccessGuard,
Ke as PermissionProvider, ze as PermissionProvider,
Se as SimplePagination, Ne as SimplePagination,
_e as api, je as UiKitProvider,
ae as checkPermission, xe as UpdateChecker,
De as clearCachedPermissions, Re as api,
Me as configureApi, pe as checkPermission,
pe as createApi, _e as clearCachedPermissions,
ue as createPermissionSet, we as configureApi,
he as getApi, be as createApi,
le as getCachedPermissions, fe as createPermissionSet,
N as getKeycloakToken, ye as getApi,
de as getPermissions, ae as getCachedPermissions,
Q as initKeycloak, T as getKeycloakToken,
$ as isKeycloakAuthenticated, he as getPermissions,
oe as isKeycloakInitialized, J as initKeycloak,
Ie as loginKeycloak, G as isKeycloakAuthenticated,
J as logoutKeycloak, le as isKeycloakInitialized,
H as permissionKeys, Te as loginKeycloak,
ce as setCachedPermissions, H as logoutKeycloak,
Y as permissionKeys,
de as setCachedPermissions,
K as toEnDigits, K as toEnDigits,
p as toFaDigits, p as toFaDigits,
Be as toFaNumber, Ee as toFaNumber,
U as updateKeycloakToken, q as updateKeycloakToken,
g as usePermission, W as usePermission,
fe as usePermissionsQuery me as usePermissionsQuery
}; };

View File

@ -0,0 +1,78 @@
"use client";
import { useEffect, useRef, useState } from "react";
export function UpdateChecker() {
const [hasUpdate, setHasUpdate] = useState(false);
const currentVersionRef = useRef(null);
useEffect(() => {
if (process.env.NODE_ENV !== "production") return;
let intervalId;
const fetchVersion = async () => {
const res = await fetch(`/version.json?t=${Date.now()}`, {
cache: "no-store",
});
if (!res.ok) {
throw new Error(`Failed to fetch version: ${res.status}`);
}
const data = await res.json();
return String(data.version);
};
const init = async () => {
try {
currentVersionRef.current = await fetchVersion();
intervalId = setInterval(async () => {
try {
const latestVersion = await fetchVersion();
if (
currentVersionRef.current &&
latestVersion !== currentVersionRef.current
) {
setHasUpdate(true);
clearInterval(intervalId);
}
} catch (err) {
console.error("Update check failed:", err);
}
}, 30000);
} catch (err) {
console.error("Initial version fetch failed:", err);
}
};
init();
return () => {
if (intervalId) clearInterval(intervalId);
};
}, []);
if (!hasUpdate) return null;
return (
<div
style={{
position: "fixed",
bottom: "16px",
right: "16px",
background: "#111",
color: "#fff",
padding: "12px 16px",
borderRadius: "8px",
zIndex: 9999,
cursor: "pointer",
}}
onClick={() => window.location.reload()}
>
نسخه جدید سامانه در دسترس است
</div>
);
}

View File

@ -0,0 +1,27 @@
import { useMemo } from "react";
import { Spinner } from "@chakra-ui/react";
import { KeycloakProvider } from "./keycloak.jsx";
import { UpdateChecker } from "../components/UpdateChecker.jsx";
import { configureApi } from "./api.js";
export function UiKitProvider({
children,
config,
loading = <Spinner />,
updateChecker = true,
updateCheckerProps,
}) {
useMemo(() => {
configureApi(config);
}, [config]);
return (
<>
{updateChecker && <UpdateChecker {...updateCheckerProps} />}
<KeycloakProvider config={config.keycloak} loading={loading}>
{children}
</KeycloakProvider>
</>
);
}

View File

@ -32,3 +32,6 @@ export {
} from "./core/permission.jsx"; } from "./core/permission.jsx";
export { createApi, configureApi, getApi, api } from "./core/api.js"; export { createApi, configureApi, getApi, api } from "./core/api.js";
export { UiKitProvider } from "./core/UiKitProvider.jsx";
export { UpdateChecker } from "./components/UpdateChecker.jsx";