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