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