626 lines
18 KiB
JavaScript
626 lines
18 KiB
JavaScript
import { jsxs as I, jsx as u } from "react/jsx-runtime";
|
||
import { useState as B, useRef as T, useEffect as A, useCallback as D, createContext as U, useMemo as F, useContext as H } from "react";
|
||
import { HStack as S, IconButton as K, Button as j, Input as L, Text as k } from "@chakra-ui/react";
|
||
import { IoChevronForwardOutline as V, IoChevronBackOutline as W } from "react-icons/io5";
|
||
import X from "keycloak-js";
|
||
import { useQuery as Z } from "@tanstack/react-query";
|
||
import P from "axios";
|
||
const we = (e) => new Intl.NumberFormat("fa-IR").format(Number(e)), f = (e) => String(e).replace(/\d/g, (t) => "۰۱۲۳۴۵۶۷۸۹"[Number(t)]), E = (e) => String(e).replace(/[۰-۹]/g, (o) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(o))), ye = ({
|
||
currentPage: e,
|
||
totalPages: t,
|
||
totalCount: o,
|
||
onPageChange: l
|
||
}) => {
|
||
const [d, i] = B(f(e)), [w, r] = B(!1), [s, c] = B(null), m = T(null), y = [.../* @__PURE__ */ new Set([1, e, t])].filter(
|
||
(n) => n >= 1 && n <= t
|
||
);
|
||
A(() => {
|
||
if (s !== null) {
|
||
e === s && (c(null), r(!1), i(f(e)));
|
||
return;
|
||
}
|
||
w || i(f(e));
|
||
}, [e, w, s]), A(() => {
|
||
if (!w || !d || s !== null) return;
|
||
const n = parseInt(E(d), 10);
|
||
if (isNaN(n)) return;
|
||
const p = setTimeout(() => {
|
||
var b;
|
||
const h = Math.min(Math.max(n, 1), t);
|
||
h !== e ? (c(h), i(f(h)), l(h)) : (r(!1), i(f(e))), (b = m.current) == null || b.blur();
|
||
}, 1e3);
|
||
return () => clearTimeout(p);
|
||
}, [
|
||
d,
|
||
w,
|
||
s,
|
||
t,
|
||
e,
|
||
l
|
||
]);
|
||
const v = () => {
|
||
var h, b;
|
||
const n = parseInt(E(d), 10);
|
||
if (isNaN(n)) {
|
||
i(f(e)), r(!1), c(null), (h = m.current) == null || h.blur();
|
||
return;
|
||
}
|
||
const p = Math.min(Math.max(n, 1), t);
|
||
p !== e ? (c(p), i(f(p)), l(p)) : (i(f(e)), r(!1), c(null)), (b = m.current) == null || b.blur();
|
||
};
|
||
return t === 0 || !o ? null : /* @__PURE__ */ I(
|
||
S,
|
||
{
|
||
justifyContent: "space-around",
|
||
backgroundColor: "white",
|
||
py: "10px",
|
||
px: "16px",
|
||
rounded: "lg",
|
||
border: "1px",
|
||
borderColor: "blue.200",
|
||
w: "100%",
|
||
children: [
|
||
/* @__PURE__ */ I(S, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => l(e - 1),
|
||
isDisabled: e === 1,
|
||
icon: /* @__PURE__ */ u(V, {}),
|
||
"aria-label": "صفحه قبلی"
|
||
}
|
||
),
|
||
y.map((n) => /* @__PURE__ */ u(
|
||
j,
|
||
{
|
||
size: "md",
|
||
px: 2,
|
||
bg: e === n ? "#4B49AC" : "#e6e6f1",
|
||
color: e === n ? "#e6e6f1" : "#4B49AC",
|
||
_hover: { bg: e === n ? "#4B49AC" : "#cbcbe8" },
|
||
onClick: () => l(n),
|
||
variant: "soft",
|
||
children: f(n)
|
||
},
|
||
n
|
||
)),
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => l(e + 1),
|
||
isDisabled: e === t,
|
||
icon: /* @__PURE__ */ u(W, {}),
|
||
"aria-label": "صفحه بعدی"
|
||
}
|
||
),
|
||
/* @__PURE__ */ u(
|
||
L,
|
||
{
|
||
ref: m,
|
||
type: "text",
|
||
inputMode: "numeric",
|
||
placeholder: "صفحه",
|
||
w: "56px",
|
||
value: d,
|
||
onFocus: () => {
|
||
r(!0), c(null), i("");
|
||
},
|
||
onChange: (n) => {
|
||
const p = n.target.value, h = E(p).replace(/\D/g, "");
|
||
i(f(h));
|
||
},
|
||
onBlur: () => {
|
||
d || (i(f(e)), r(!1), c(null));
|
||
},
|
||
onKeyDown: (n) => {
|
||
n.key === "Enter" && v();
|
||
},
|
||
textAlign: "center",
|
||
color: "#1D2939",
|
||
px: 1,
|
||
minW: 0,
|
||
dir: "ltr"
|
||
}
|
||
)
|
||
] }),
|
||
/* @__PURE__ */ I(S, { spacing: 2, children: [
|
||
/* @__PURE__ */ u(k, { w: "auto", fontWeight: "bold", whiteSpace: "nowrap", children: "تعداد کل:" }),
|
||
/* @__PURE__ */ u(k, { children: f(o) })
|
||
] })
|
||
]
|
||
}
|
||
);
|
||
}, xe = ({
|
||
currentPage: e,
|
||
totalPages: t,
|
||
totalCount: o,
|
||
onPageChange: l
|
||
}) => {
|
||
const [d, i] = B(f(e)), [w, r] = B(!1), [s, c] = B(null), m = T(null), y = Array.from(
|
||
/* @__PURE__ */ new Set([1, e, e + 1, t])
|
||
).filter((n) => n >= 1 && n <= t).sort((n, p) => n - p);
|
||
A(() => {
|
||
if (s !== null) {
|
||
e === s && (c(null), r(!1), i(f(e)));
|
||
return;
|
||
}
|
||
w || i(f(e));
|
||
}, [e, w, s]), A(() => {
|
||
if (!w || !d || s !== null) return;
|
||
const n = parseInt(E(d), 10);
|
||
if (isNaN(n)) return;
|
||
const p = setTimeout(() => {
|
||
var b;
|
||
const h = Math.min(Math.max(n, 1), t);
|
||
h !== e ? (c(h), i(f(h)), l(h)) : (r(!1), i(f(e))), (b = m.current) == null || b.blur();
|
||
}, 1e3);
|
||
return () => clearTimeout(p);
|
||
}, [
|
||
d,
|
||
w,
|
||
s,
|
||
t,
|
||
e,
|
||
l
|
||
]);
|
||
const v = () => {
|
||
var h, b;
|
||
const n = parseInt(E(d), 10);
|
||
if (isNaN(n)) {
|
||
i(f(e)), r(!1), c(null), (h = m.current) == null || h.blur();
|
||
return;
|
||
}
|
||
const p = Math.min(Math.max(n, 1), t);
|
||
p !== e ? (c(p), i(f(p)), l(p)) : (i(f(e)), r(!1), c(null)), (b = m.current) == null || b.blur();
|
||
};
|
||
return t === 0 || !o ? null : /* @__PURE__ */ I(
|
||
S,
|
||
{
|
||
justifyContent: "space-around",
|
||
backgroundColor: "white",
|
||
py: "10px",
|
||
px: "16px",
|
||
rounded: "lg",
|
||
border: "1px",
|
||
borderColor: "blue.200",
|
||
w: "100%",
|
||
children: [
|
||
/* @__PURE__ */ I(S, { spacing: 2, whiteSpace: "nowrap", children: [
|
||
/* @__PURE__ */ u(k, { fontWeight: "bold", children: "صفحه" }),
|
||
/* @__PURE__ */ u(k, { children: f(e) }),
|
||
/* @__PURE__ */ u(k, { fontWeight: "bold", children: "از" }),
|
||
/* @__PURE__ */ u(k, { children: f(t) })
|
||
] }),
|
||
/* @__PURE__ */ I(S, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => l(e - 1),
|
||
isDisabled: e === 1,
|
||
icon: /* @__PURE__ */ u(V, {}),
|
||
"aria-label": "صفحه قبلی"
|
||
}
|
||
),
|
||
y.map((n) => /* @__PURE__ */ u(
|
||
j,
|
||
{
|
||
size: "md",
|
||
bg: e === n ? "#4B49AC" : "#e6e6f1",
|
||
color: e === n ? "#e6e6f1" : "#4B49AC",
|
||
_hover: { bg: e === n ? "#4B49AC" : "#cbcbe8" },
|
||
onClick: () => l(n),
|
||
variant: "soft",
|
||
children: f(n)
|
||
},
|
||
n
|
||
)),
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => l(e + 1),
|
||
isDisabled: e === t,
|
||
icon: /* @__PURE__ */ u(W, {}),
|
||
"aria-label": "صفحه بعدی"
|
||
}
|
||
),
|
||
/* @__PURE__ */ u(
|
||
L,
|
||
{
|
||
ref: m,
|
||
type: "text",
|
||
inputMode: "numeric",
|
||
placeholder: "صفحه",
|
||
w: "100px",
|
||
value: d,
|
||
onFocus: () => {
|
||
r(!0), c(null), i("");
|
||
},
|
||
onChange: (n) => {
|
||
const p = n.target.value, h = E(p).replace(/\D/g, "");
|
||
i(f(h));
|
||
},
|
||
onBlur: () => {
|
||
d || (i(f(e)), r(!1), c(null));
|
||
},
|
||
onKeyDown: (n) => {
|
||
n.key === "Enter" && v();
|
||
},
|
||
textAlign: "center",
|
||
color: "#1D2939",
|
||
px: 1,
|
||
minW: 0,
|
||
dir: "ltr"
|
||
}
|
||
)
|
||
] }),
|
||
/* @__PURE__ */ I(S, { spacing: 2, whiteSpace: "nowrap", children: [
|
||
/* @__PURE__ */ u(k, { fontWeight: "bold", children: "تعداد کل:" }),
|
||
/* @__PURE__ */ u(k, { children: f(o) })
|
||
] })
|
||
]
|
||
}
|
||
);
|
||
}, ve = ({
|
||
currentPage: e,
|
||
totalPages: t,
|
||
totalCount: o,
|
||
onPageChange: l
|
||
}) => {
|
||
const [d, i] = B(""), [w, r] = B(!1), [s, c] = B(null), m = T(null), y = s ?? e, v = D(
|
||
(x) => {
|
||
const C = Math.min(Math.max(x, 1), t);
|
||
r(!1), i(""), c(null), C !== e && l(C);
|
||
},
|
||
[e, t, l]
|
||
), n = D(() => {
|
||
if (!d) {
|
||
r(!1), i(""), c(null);
|
||
return;
|
||
}
|
||
const x = parseInt(E(d), 10);
|
||
if (isNaN(x)) {
|
||
r(!1), i(""), c(null);
|
||
return;
|
||
}
|
||
const C = Math.min(Math.max(x, 1), t);
|
||
r(!1), i(""), C !== e ? (c(C), l(C)) : c(null);
|
||
}, [d, e, t, l]);
|
||
A(() => {
|
||
var x;
|
||
w && ((x = m.current) == null || x.focus());
|
||
}, [w]), A(() => {
|
||
s !== null && e === s && c(null);
|
||
}, [e, s]), A(() => {
|
||
if (!w || !d) return;
|
||
const x = setTimeout(() => {
|
||
n();
|
||
}, 1e3);
|
||
return () => clearTimeout(x);
|
||
}, [d, w, n]);
|
||
const p = () => {
|
||
c(null), i(""), r(!0);
|
||
}, h = (x, C = !1) => /* @__PURE__ */ u(
|
||
j,
|
||
{
|
||
size: "md",
|
||
bg: C ? "#4B49AC" : "#e6e6f1",
|
||
color: C ? "#e6e6f1" : "#4B49AC",
|
||
_hover: { bg: C ? "#4B49AC" : "#cbcbe8" },
|
||
onClick: C ? p : () => v(x),
|
||
variant: "soft",
|
||
children: f(x)
|
||
},
|
||
x
|
||
);
|
||
if (t === 0 || !o) return null;
|
||
const b = t > 1 && y !== 1, M = t > 1 && y !== t;
|
||
return /* @__PURE__ */ u(
|
||
S,
|
||
{
|
||
justifyContent: "center",
|
||
backgroundColor: "white",
|
||
py: "10px",
|
||
px: "16px",
|
||
rounded: "lg",
|
||
border: "1px",
|
||
borderColor: "blue.200",
|
||
w: "100%",
|
||
children: /* @__PURE__ */ I(S, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => v(y - 1),
|
||
isDisabled: y === 1,
|
||
icon: /* @__PURE__ */ u(V, {}),
|
||
"aria-label": "صفحه قبلی"
|
||
}
|
||
),
|
||
b && h(1),
|
||
w ? /* @__PURE__ */ u(
|
||
L,
|
||
{
|
||
ref: m,
|
||
type: "text",
|
||
inputMode: "numeric",
|
||
placeholder: "صفحه",
|
||
w: "48px",
|
||
value: d,
|
||
onChange: (x) => {
|
||
const C = x.target.value, g = E(C).replace(/\D/g, "");
|
||
i(f(g));
|
||
},
|
||
onBlur: () => {
|
||
d ? n() : (i(""), r(!1), c(null));
|
||
},
|
||
onKeyDown: (x) => {
|
||
x.key === "Enter" && n(), x.key === "Escape" && (i(""), r(!1), c(null));
|
||
},
|
||
textAlign: "center",
|
||
color: "#1D2939",
|
||
px: 1,
|
||
minW: 0,
|
||
dir: "ltr"
|
||
}
|
||
) : h(y, !0),
|
||
M && h(t),
|
||
/* @__PURE__ */ u(
|
||
K,
|
||
{
|
||
size: "md",
|
||
bg: "#e6e6f1",
|
||
color: "#4B49AC",
|
||
_hover: { bg: "#cbcbe8" },
|
||
onClick: () => v(y + 1),
|
||
isDisabled: y === t,
|
||
icon: /* @__PURE__ */ u(W, {}),
|
||
"aria-label": "صفحه بعدی"
|
||
}
|
||
)
|
||
] })
|
||
}
|
||
);
|
||
};
|
||
let a = null, _ = null, R = !1;
|
||
const ee = U(null), te = ({ url: e, realm: t, clientId: o }) => (a || (a = new X({
|
||
url: e,
|
||
realm: t,
|
||
clientId: o
|
||
})), a), G = ({ config: e, initOptions: t = {} }) => {
|
||
const o = te(e);
|
||
return _ || (_ = o.init({
|
||
onLoad: "login-required",
|
||
checkLoginIframe: !1,
|
||
flow: "implicit",
|
||
...t
|
||
}).then((l) => (R = !0, l)).catch((l) => {
|
||
throw R = !0, l;
|
||
})), _;
|
||
}, ne = () => R, $ = () => !!(a != null && a.authenticated), N = () => (a == null ? void 0 : a.token) ?? null, q = async (e = 30) => a ? a.updateToken(e) : !1, J = (e) => a == null ? void 0 : a.logout(e), Ce = (e) => a == null ? void 0 : a.login(e), Be = ({
|
||
children: e,
|
||
config: t,
|
||
initOptions: o,
|
||
loading: l = null
|
||
}) => {
|
||
const [d, i] = B(!1), [w, r] = B(!1), [s, c] = B(null), m = T(!1), y = D(() => {
|
||
a && (r(!!a.authenticated), c(a.token ?? null));
|
||
}, []);
|
||
A(() => (m.current = !0, G({ config: t, initOptions: o }).then((b) => {
|
||
m.current && (r(!!b), c((a == null ? void 0 : a.token) ?? null), i(!0));
|
||
}).catch(() => {
|
||
m.current && (r(!1), c(null), i(!0));
|
||
}), () => {
|
||
m.current = !1;
|
||
}), [t, o]);
|
||
const v = D(() => a == null ? void 0 : a.login(), []), n = D((b) => a == null ? void 0 : a.logout(b), []), p = D(
|
||
async (b = 30) => {
|
||
if (!a) return !1;
|
||
const M = await a.updateToken(b);
|
||
return y(), M;
|
||
},
|
||
[y]
|
||
), h = F(
|
||
() => ({
|
||
initialized: d,
|
||
authenticated: w,
|
||
token: s,
|
||
login: v,
|
||
logout: n,
|
||
updateToken: p
|
||
}),
|
||
[d, w, s, v, n, p]
|
||
);
|
||
return d ? /* @__PURE__ */ u(ee.Provider, { value: h, children: e }) : l;
|
||
}, Q = U(null), z = "permissions", ie = (e) => (e == null ? void 0 : e.storageKey) || z, Ae = ({
|
||
user: e = null,
|
||
children: t,
|
||
config: o,
|
||
loading: l = /* @__PURE__ */ u("div", { children: "Loading permissions..." }),
|
||
errorFallback: d = /* @__PURE__ */ u("div", { children: "Error loading permissions" })
|
||
}) => {
|
||
const i = ie(o), [w, r] = B(
|
||
() => re(i)
|
||
), { data: s, isLoading: c, error: m } = ue(o), y = s ?? w;
|
||
A(() => {
|
||
s && (oe(i, s), r(s));
|
||
}, [s, i]);
|
||
const v = F(
|
||
() => se(y),
|
||
[y]
|
||
), n = D(
|
||
(b = "") => le(v, b),
|
||
[v]
|
||
), p = D((b = "") => !n(b), [n]), h = F(
|
||
() => ({
|
||
user: e,
|
||
can: n,
|
||
cannot: p,
|
||
permissions: y,
|
||
isLoading: c,
|
||
error: m
|
||
}),
|
||
[e, n, p, y, c, m]
|
||
);
|
||
return m && !y ? d : c && !y ? l : /* @__PURE__ */ u(Q.Provider, { value: h, children: t });
|
||
}, re = (e = z) => {
|
||
if (!(typeof window > "u"))
|
||
try {
|
||
const t = localStorage.getItem(e);
|
||
return t ? JSON.parse(t) : void 0;
|
||
} catch {
|
||
return;
|
||
}
|
||
}, oe = (e = z, t) => {
|
||
if (!(typeof window > "u"))
|
||
try {
|
||
localStorage.setItem(e, JSON.stringify(t));
|
||
} catch {
|
||
}
|
||
}, Se = (e = z) => {
|
||
if (!(typeof window > "u"))
|
||
try {
|
||
localStorage.removeItem(e);
|
||
} catch {
|
||
}
|
||
}, se = (e) => e ? new Set(e.map((t) => t.name)) : /* @__PURE__ */ new Set(), le = (e, t = "") => {
|
||
if (!t) return !1;
|
||
if (e.has(t) || [...e].some((l) => l.startsWith(t))) return !0;
|
||
let o = t;
|
||
for (; o.includes(":"); )
|
||
if (o = o.slice(0, o.lastIndexOf(":")), e.has(`${o}:*`)) return !0;
|
||
return !1;
|
||
}, Y = {
|
||
all: ["permissions"],
|
||
list: (e) => [...Y.all, e]
|
||
}, ce = async (e) => {
|
||
if (!(e != null && e.url) || !(e != null && e.clientId))
|
||
throw new Error("Permission config requires url and clientId.");
|
||
const t = N(), o = new URL(e.url);
|
||
o.searchParams.set("client_id", e.clientId);
|
||
const l = await fetch(o.toString(), {
|
||
method: "GET",
|
||
headers: {
|
||
...t ? { Authorization: `Bearer ${t}` } : {}
|
||
}
|
||
});
|
||
if (!l.ok)
|
||
throw new Error("Failed to load permissions");
|
||
return l.json();
|
||
}, O = () => {
|
||
const e = H(Q);
|
||
if (!e)
|
||
throw new Error("usePermission must be used within PermissionProvider");
|
||
return e;
|
||
}, ue = (e) => Z({
|
||
queryKey: Y.list(e == null ? void 0 : e.clientId),
|
||
queryFn: () => ce(e),
|
||
enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && $(),
|
||
staleTime: 1 / 0,
|
||
refetchOnWindowFocus: !1,
|
||
refetchOnReconnect: !1
|
||
}), ke = ({
|
||
perm: e,
|
||
children: t,
|
||
fallback: o = /* @__PURE__ */ u("div", { children: "You are not allowed to do this" })
|
||
}) => {
|
||
const { can: l } = O();
|
||
return l(e) ? t : o;
|
||
}, Ie = ({ children: e }) => {
|
||
const { can: t, permissions: o } = O();
|
||
return o && t("admin") ? e : null;
|
||
}, De = ({ children: e }) => {
|
||
const { can: t, isLoading: o } = O();
|
||
return A(() => {
|
||
o || t("panel_access") || J();
|
||
}, [o, t]), e;
|
||
}, Ee = (e) => {
|
||
const { api: t, keycloak: o } = e, l = P.create({
|
||
baseURL: t.baseUrl
|
||
}), d = async () => {
|
||
(!ne() || !$()) && await G({ config: o });
|
||
}, i = async (r) => {
|
||
await d();
|
||
let s = N();
|
||
if (s) {
|
||
try {
|
||
await q(5), s = N();
|
||
} catch {
|
||
}
|
||
r.headers = {
|
||
...r.headers,
|
||
Authorization: `Bearer ${s}`
|
||
};
|
||
}
|
||
return r;
|
||
}, w = async (r) => {
|
||
var c;
|
||
const s = r.config;
|
||
if (((c = r == null ? void 0 : r.response) == null ? void 0 : c.status) === 401 && !(s != null && s._retry)) {
|
||
s._retry = !0;
|
||
try {
|
||
await q(30);
|
||
const m = N();
|
||
return s.headers = {
|
||
...s.headers,
|
||
Authorization: `Bearer ${m}`
|
||
}, l(s);
|
||
} catch {
|
||
J({ redirectUri: window.location.origin });
|
||
}
|
||
}
|
||
return Promise.reject(r);
|
||
};
|
||
return t.interceptors.request.use(i), t.interceptors.response.use((r) => r, w), {
|
||
api: l
|
||
};
|
||
};
|
||
export {
|
||
Ie as AdminGuard,
|
||
ke as Can,
|
||
Be as KeycloakProvider,
|
||
ye as LightPagination,
|
||
xe as Pagination,
|
||
De as PanelAccessGuard,
|
||
Ae as PermissionProvider,
|
||
ve as SimplePagination,
|
||
le as checkPermission,
|
||
Se as clearCachedPermissions,
|
||
Ee as createApi,
|
||
se as createPermissionSet,
|
||
re as getCachedPermissions,
|
||
N as getKeycloakToken,
|
||
ce as getPermissions,
|
||
G as initKeycloak,
|
||
$ as isKeycloakAuthenticated,
|
||
ne as isKeycloakInitialized,
|
||
Ce as loginKeycloak,
|
||
J as logoutKeycloak,
|
||
Y as permissionKeys,
|
||
oe as setCachedPermissions,
|
||
E as toEnDigits,
|
||
f as toFaDigits,
|
||
we as toFaNumber,
|
||
q as updateKeycloakToken,
|
||
O as usePermission,
|
||
ue as usePermissionsQuery
|
||
};
|