uibee 3.3.0 → 3.3.1
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.
- package/dist/components/alert/alert.d.ts +15 -0
- package/dist/components/alert/alert.js +29 -0
- package/dist/components/badge/badge.d.ts +16 -0
- package/dist/components/badge/badge.js +26 -0
- package/dist/components/buttons/button.d.ts +25 -0
- package/dist/components/buttons/button.js +44 -0
- package/dist/components/code/code.d.ts +23 -0
- package/dist/components/code/code.js +39 -0
- package/dist/components/confirm/confirmPopup.d.ts +23 -0
- package/dist/components/confirm/confirmPopup.js +52 -0
- package/dist/components/container/accordion.d.ts +25 -0
- package/dist/components/container/accordion.js +41 -0
- package/dist/components/container/card.d.ts +13 -0
- package/dist/components/container/card.js +10 -0
- package/dist/components/container/expandableCard.d.ts +32 -0
- package/dist/components/container/expandableCard.js +70 -0
- package/dist/components/container/glassCard.d.ts +13 -0
- package/dist/components/container/glassCard.js +10 -0
- package/dist/components/container/highlight.d.ts +10 -0
- package/dist/components/container/highlight.js +10 -0
- package/dist/components/container/iconBubble.d.ts +25 -0
- package/dist/components/container/iconBubble.js +21 -0
- package/dist/components/container/leftBarPanel.d.ts +15 -0
- package/dist/components/container/leftBarPanel.js +10 -0
- package/dist/components/container/page.d.ts +15 -0
- package/dist/components/container/page.js +16 -0
- package/dist/components/container/pulseDot.d.ts +12 -0
- package/dist/components/container/pulseDot.js +23 -0
- package/dist/components/container/statCard.d.ts +18 -0
- package/dist/components/container/statCard.js +25 -0
- package/dist/components/container/tabs.d.ts +35 -0
- package/dist/components/container/tabs.js +36 -0
- package/dist/components/empty/emptyState.d.ts +19 -0
- package/dist/components/empty/emptyState.js +27 -0
- package/dist/components/footer/footer.d.ts +49 -0
- package/dist/components/footer/footer.js +109 -0
- package/dist/components/footer/loginContent.d.ts +18 -0
- package/dist/components/footer/loginContent.js +138 -0
- package/dist/components/inputs/checkbox.d.ts +20 -0
- package/dist/components/inputs/checkbox.js +76 -0
- package/dist/components/inputs/fileInput.d.ts +19 -0
- package/dist/components/inputs/fileInput.js +108 -0
- package/dist/components/inputs/input.d.ts +16 -0
- package/dist/components/inputs/input.js +157 -0
- package/dist/components/inputs/multiSelect.d.ts +37 -0
- package/dist/components/inputs/multiSelect.js +99 -0
- package/dist/components/inputs/radio.d.ts +20 -0
- package/dist/components/inputs/radio.js +70 -0
- package/dist/components/inputs/range.d.ts +14 -0
- package/dist/components/inputs/range.js +60 -0
- package/dist/components/inputs/searchInput.d.ts +11 -0
- package/dist/components/inputs/searchInput.js +56 -0
- package/dist/components/inputs/select.d.ts +42 -0
- package/dist/components/inputs/select.js +164 -0
- package/dist/components/inputs/shared/colorPickerPopup.js +293 -0
- package/dist/components/inputs/shared/dateTimePickerPopup.js +225 -0
- package/dist/components/inputs/shared/fieldWrapper.js +33 -0
- package/dist/components/inputs/shared/index.js +6 -0
- package/dist/components/inputs/shared/inputError.js +17 -0
- package/dist/components/inputs/shared/inputInfo.js +13 -0
- package/dist/components/inputs/shared/inputLabel.js +19 -0
- package/dist/components/inputs/switch.d.ts +14 -0
- package/dist/components/inputs/switch.js +37 -0
- package/dist/components/inputs/tagInput.d.ts +31 -0
- package/dist/components/inputs/tagInput.js +72 -0
- package/dist/components/inputs/textarea.d.ts +14 -0
- package/dist/components/inputs/textarea.js +76 -0
- package/dist/components/inputs/toggle.d.ts +21 -0
- package/dist/components/inputs/toggle.js +33 -0
- package/dist/components/login/loginPage.d.ts +15 -0
- package/dist/components/login/loginPage.js +80 -0
- package/dist/components/logo/logo.d.ts +9 -0
- package/dist/components/logo/logo.js +138 -0
- package/dist/components/logo/logoSmall.d.ts +4 -0
- package/dist/components/logo/logoSmall.js +56 -0
- package/dist/components/markdownrender/markdownRender.d.ts +16 -0
- package/dist/components/markdownrender/markdownRender.js +59 -0
- package/dist/components/modal/modal.d.ts +22 -0
- package/dist/components/modal/modal.js +59 -0
- package/dist/components/navbar/bubble.js +36 -0
- package/dist/components/navbar/navbar.d.ts +50 -0
- package/dist/components/navbar/navbar.js +99 -0
- package/dist/components/navbar/navbarDropdown.d.ts +15 -0
- package/dist/components/navbar/navbarDropdown.js +63 -0
- package/dist/components/navbar/navbarItem.d.ts +23 -0
- package/dist/components/navbar/navbarItem.js +38 -0
- package/dist/components/sidebar/sidebar.d.ts +34 -0
- package/dist/components/sidebar/sidebar.js +135 -0
- package/dist/components/spinner/spinner.d.ts +11 -0
- package/dist/components/spinner/spinner.js +16 -0
- package/dist/components/table/body.js +253 -0
- package/dist/components/table/constants.js +58 -0
- package/dist/components/table/empty.js +24 -0
- package/dist/components/table/format.js +39 -0
- package/dist/components/table/header.js +109 -0
- package/dist/components/table/menu.d.ts +18 -0
- package/dist/components/table/menu.js +76 -0
- package/dist/components/table/pagination.d.ts +14 -0
- package/dist/components/table/pagination.js +130 -0
- package/dist/components/table/skeleton.js +39 -0
- package/dist/components/table/table.d.ts +7 -0
- package/dist/components/table/table.js +213 -0
- package/dist/components/table/types.d.ts +52 -0
- package/dist/components/table/utils.js +9 -0
- package/dist/components/toast/toastItem.js +61 -0
- package/dist/components/toast/toaster.d.ts +13 -0
- package/dist/components/toast/toaster.js +117 -0
- package/dist/components/toggle/language.d.ts +10 -0
- package/dist/components/toggle/language.js +34 -0
- package/dist/components/toggle/theme.d.ts +8 -0
- package/dist/components/toggle/theme.js +135 -0
- package/dist/components/version/version.d.ts +13 -0
- package/dist/components/version/version.js +19 -0
- package/dist/components/vulnerability/constants.d.ts +4 -0
- package/dist/components/vulnerability/constants.js +17 -0
- package/dist/components/vulnerability/severityPill.d.ts +15 -0
- package/dist/components/vulnerability/severityPill.js +20 -0
- package/dist/{style.css → globals.css} +152 -226
- package/dist/hooks/useClickOutside.d.ts +6 -0
- package/dist/{useClickOutside-Cmp-RsP3.js → hooks/useClickOutside.js} +1 -1
- package/dist/hooks/useDarkMode.d.ts +4 -0
- package/dist/hooks/useDarkMode.js +19 -0
- package/dist/hooks/useVisibility.d.ts +7 -0
- package/dist/hooks/useVisibility.js +25 -0
- package/dist/icons/icons.d.ts +420 -0
- package/dist/{icons-lZYQ6Vlr.js → icons/icons.js} +1 -1
- package/dist/src/components/index.d.ts +51 -905
- package/dist/src/components/index.js +49 -4179
- package/dist/src/hooks/index.d.ts +3 -14
- package/dist/src/hooks/index.js +3 -42
- package/dist/src/icons/index.d.ts +1 -419
- package/dist/src/icons/index.js +1 -1
- package/dist/src/styles/index.js +1 -1
- package/dist/src/utils/index.d.ts +5 -37
- package/dist/src/utils/index.js +5 -124
- package/dist/utils/auth/callback.d.ts +14 -0
- package/dist/utils/auth/callback.js +53 -0
- package/dist/utils/auth/getDomain.js +6 -0
- package/dist/utils/auth/login.d.ts +12 -0
- package/dist/utils/auth/login.js +17 -0
- package/dist/utils/auth/logout.d.ts +10 -0
- package/dist/utils/auth/logout.js +20 -0
- package/dist/utils/auth/token.d.ts +10 -0
- package/dist/utils/auth/token.js +30 -0
- package/dist/utils/logoConsoleOutput/logoConsoleOutput.d.ts +4 -0
- package/dist/utils/logoConsoleOutput/logoConsoleOutput.js +11 -0
- package/package.json +1 -1
- package/src/components/buttons/button.tsx +2 -0
- package/src/components/footer/footer.tsx +60 -42
- package/src/components/index.ts +0 -1
- package/src/components/inputs/checkbox.tsx +2 -0
- package/src/components/inputs/input.tsx +2 -0
- package/src/components/inputs/radio.tsx +2 -0
- package/src/components/inputs/range.tsx +2 -0
- package/src/components/inputs/shared/colorPickerPopup.tsx +2 -0
- package/src/components/inputs/shared/dateTimePickerPopup.tsx +2 -0
- package/src/components/inputs/textarea.tsx +2 -0
- package/src/components/inputs/toggle.tsx +2 -0
- package/src/components/toast/toastItem.tsx +2 -0
- package/src/globals.css +5 -0
- package/tsdown.config.ts +1 -0
|
@@ -1,4180 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
role: "alert",
|
|
51
|
-
title: error,
|
|
52
|
-
children: error
|
|
53
|
-
})
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
//#endregion
|
|
57
|
-
//#region src/components/markdownrender/markdownRender.tsx
|
|
58
|
-
function makeDefaultComponents() {
|
|
59
|
-
return {
|
|
60
|
-
h1: ({ ...props }) => /* @__PURE__ */ jsx("h2", { ...props }),
|
|
61
|
-
input({ type, checked }) {
|
|
62
|
-
if (type !== "checkbox") return /* @__PURE__ */ jsx("input", { type });
|
|
63
|
-
return /* @__PURE__ */ jsx("span", {
|
|
64
|
-
"data-task-checkbox": true,
|
|
65
|
-
className: `inline-flex items-center justify-center w-4 h-4 rounded-xs border-2 shrink-0 align-middle
|
|
66
|
-
${checked ? "bg-login border-login" : "border-login/50"}`,
|
|
67
|
-
children: checked && /* @__PURE__ */ jsx("svg", {
|
|
68
|
-
viewBox: "0 0 10 8",
|
|
69
|
-
className: "w-2.5 h-2.5 fill-none stroke-white stroke-2",
|
|
70
|
-
children: /* @__PURE__ */ jsx("polyline", {
|
|
71
|
-
points: "1,4 4,7 9,1",
|
|
72
|
-
strokeLinecap: "round",
|
|
73
|
-
strokeLinejoin: "round"
|
|
74
|
-
})
|
|
75
|
-
})
|
|
76
|
-
});
|
|
77
|
-
},
|
|
78
|
-
a({ href, children }) {
|
|
79
|
-
return /* @__PURE__ */ jsxs("a", {
|
|
80
|
-
href,
|
|
81
|
-
target: "_blank",
|
|
82
|
-
rel: "noopener noreferrer",
|
|
83
|
-
className: "inline-flex items-center gap-1 text-login hover:text-login/80 underline underline-offset-2 transition-colors",
|
|
84
|
-
children: [children, /* @__PURE__ */ jsx(ExternalLink, { className: "w-3 h-3 shrink-0 opacity-70" })]
|
|
85
|
-
});
|
|
86
|
-
},
|
|
87
|
-
pre({ children }) {
|
|
88
|
-
return /* @__PURE__ */ jsx("pre", {
|
|
89
|
-
className: "block rounded-lg overflow-auto whitespace-pre-wrap wrap-break-word w-full",
|
|
90
|
-
children
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
function MarkdownRender({ MDstr, components, className, size }) {
|
|
96
|
-
return /* @__PURE__ */ jsx("div", {
|
|
97
|
-
className: className ?? `prose ${size === "sm" ? "prose-sm" : size === "lg" ? "prose-lg" : size === "xl" ? "prose-xl" : ""} prose-custom max-w-none`,
|
|
98
|
-
children: /* @__PURE__ */ jsx(Markdown, {
|
|
99
|
-
components: {
|
|
100
|
-
...makeDefaultComponents(),
|
|
101
|
-
...components
|
|
102
|
-
},
|
|
103
|
-
remarkPlugins: [remarkGfm],
|
|
104
|
-
rehypePlugins: [rehypeHighlight],
|
|
105
|
-
children: MDstr.replace(/\\n/g, "\n")
|
|
106
|
-
})
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/components/inputs/shared/fieldWrapper.tsx
|
|
111
|
-
function FieldWrapper({ label, name, required, info, error, description, textSize = "sm", children, className }) {
|
|
112
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
113
|
-
className: `flex flex-col gap-1 w-full relative ${className || ""}`,
|
|
114
|
-
children: [
|
|
115
|
-
(label || info) && /* @__PURE__ */ jsxs("div", {
|
|
116
|
-
className: "flex items-center justify-between mb-1",
|
|
117
|
-
children: [label && /* @__PURE__ */ jsx(InputLabel, {
|
|
118
|
-
label,
|
|
119
|
-
name,
|
|
120
|
-
required,
|
|
121
|
-
className: `ml-1 ${textSize === "sm" ? "text-sm!" : "text-base!"}`
|
|
122
|
-
}), info && /* @__PURE__ */ jsx(InputInfo, { info })]
|
|
123
|
-
}),
|
|
124
|
-
description && /* @__PURE__ */ jsx("div", {
|
|
125
|
-
className: "text-login-100 **:text-xs! ml-1 mb-1",
|
|
126
|
-
children: /* @__PURE__ */ jsx(MarkdownRender, { MDstr: String(description || "") })
|
|
127
|
-
}),
|
|
128
|
-
children,
|
|
129
|
-
/* @__PURE__ */ jsx(InputError, {
|
|
130
|
-
error,
|
|
131
|
-
id: `${name}-error`
|
|
132
|
-
})
|
|
133
|
-
]
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
//#endregion
|
|
137
|
-
//#region src/components/inputs/shared/colorPickerPopup.tsx
|
|
138
|
-
function hexToHsv(hex) {
|
|
139
|
-
hex = hex.replace("#", "");
|
|
140
|
-
let r = 0, g = 0, b = 0;
|
|
141
|
-
if (hex.length === 3) {
|
|
142
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
143
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
144
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
145
|
-
} else if (hex.length === 6) {
|
|
146
|
-
r = parseInt(hex.substring(0, 2), 16);
|
|
147
|
-
g = parseInt(hex.substring(2, 4), 16);
|
|
148
|
-
b = parseInt(hex.substring(4, 6), 16);
|
|
149
|
-
}
|
|
150
|
-
r /= 255;
|
|
151
|
-
g /= 255;
|
|
152
|
-
b /= 255;
|
|
153
|
-
const max = Math.max(r, g, b);
|
|
154
|
-
const min = Math.min(r, g, b);
|
|
155
|
-
const d = max - min;
|
|
156
|
-
let h = 0;
|
|
157
|
-
const s = max === 0 ? 0 : d / max;
|
|
158
|
-
const v = max;
|
|
159
|
-
if (max !== min) {
|
|
160
|
-
switch (max) {
|
|
161
|
-
case r:
|
|
162
|
-
h = (g - b) / d + (g < b ? 6 : 0);
|
|
163
|
-
break;
|
|
164
|
-
case g:
|
|
165
|
-
h = (b - r) / d + 2;
|
|
166
|
-
break;
|
|
167
|
-
case b:
|
|
168
|
-
h = (r - g) / d + 4;
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
h /= 6;
|
|
172
|
-
}
|
|
173
|
-
return {
|
|
174
|
-
h: h * 360,
|
|
175
|
-
s: s * 100,
|
|
176
|
-
v: v * 100
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function hsvToRgb(h, s, v) {
|
|
180
|
-
let r = 0, g = 0, b = 0;
|
|
181
|
-
const i = Math.floor(h * 6);
|
|
182
|
-
const f = h * 6 - i;
|
|
183
|
-
const p = v * (1 - s);
|
|
184
|
-
const q = v * (1 - f * s);
|
|
185
|
-
const t = v * (1 - (1 - f) * s);
|
|
186
|
-
switch (i % 6) {
|
|
187
|
-
case 0:
|
|
188
|
-
r = v;
|
|
189
|
-
g = t;
|
|
190
|
-
b = p;
|
|
191
|
-
break;
|
|
192
|
-
case 1:
|
|
193
|
-
r = q;
|
|
194
|
-
g = v;
|
|
195
|
-
b = p;
|
|
196
|
-
break;
|
|
197
|
-
case 2:
|
|
198
|
-
r = p;
|
|
199
|
-
g = v;
|
|
200
|
-
b = t;
|
|
201
|
-
break;
|
|
202
|
-
case 3:
|
|
203
|
-
r = p;
|
|
204
|
-
g = q;
|
|
205
|
-
b = v;
|
|
206
|
-
break;
|
|
207
|
-
case 4:
|
|
208
|
-
r = t;
|
|
209
|
-
g = p;
|
|
210
|
-
b = v;
|
|
211
|
-
break;
|
|
212
|
-
case 5:
|
|
213
|
-
r = v;
|
|
214
|
-
g = p;
|
|
215
|
-
b = q;
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
return {
|
|
219
|
-
r: Math.round(r * 255),
|
|
220
|
-
g: Math.round(g * 255),
|
|
221
|
-
b: Math.round(b * 255)
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
function hsvToHex(h, s, v) {
|
|
225
|
-
const { r, g, b } = hsvToRgb(h / 360, s / 100, v / 100);
|
|
226
|
-
function toHex(x) {
|
|
227
|
-
const hex = x.toString(16);
|
|
228
|
-
return hex.length === 1 ? "0" + hex : hex;
|
|
229
|
-
}
|
|
230
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
231
|
-
}
|
|
232
|
-
const PRESET_COLORS = [
|
|
233
|
-
"#f87171",
|
|
234
|
-
"#fd8738",
|
|
235
|
-
"#fbbf24",
|
|
236
|
-
"#facc15",
|
|
237
|
-
"#a3e635",
|
|
238
|
-
"#4ade80",
|
|
239
|
-
"#34d399",
|
|
240
|
-
"#2dd4bf",
|
|
241
|
-
"#38bdf8",
|
|
242
|
-
"#60a5fa",
|
|
243
|
-
"#818cf8",
|
|
244
|
-
"#a78bfa",
|
|
245
|
-
"#c084fc",
|
|
246
|
-
"#e879f9",
|
|
247
|
-
"#f472b6",
|
|
248
|
-
"#fb7185"
|
|
249
|
-
];
|
|
250
|
-
function SaturationPicker({ hsv, onChange }) {
|
|
251
|
-
const containerRef = useRef(null);
|
|
252
|
-
function handleMove(e) {
|
|
253
|
-
if (!containerRef.current) return;
|
|
254
|
-
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
|
|
255
|
-
const x = Math.min(Math.max((e.clientX - left) / width, 0), 1);
|
|
256
|
-
const y = Math.min(Math.max((e.clientY - top) / height, 0), 1);
|
|
257
|
-
onChange(x * 100, (1 - y) * 100);
|
|
258
|
-
}
|
|
259
|
-
function handleMouseDown(e) {
|
|
260
|
-
handleMove(e);
|
|
261
|
-
function moveHandler(e) {
|
|
262
|
-
handleMove(e);
|
|
263
|
-
}
|
|
264
|
-
function upHandler() {
|
|
265
|
-
window.removeEventListener("mousemove", moveHandler);
|
|
266
|
-
window.removeEventListener("mouseup", upHandler);
|
|
267
|
-
}
|
|
268
|
-
window.addEventListener("mousemove", moveHandler);
|
|
269
|
-
window.addEventListener("mouseup", upHandler);
|
|
270
|
-
}
|
|
271
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
272
|
-
ref: containerRef,
|
|
273
|
-
className: "w-full h-32 relative rounded-md overflow-hidden cursor-crosshair mb-3 select-none",
|
|
274
|
-
style: { backgroundColor: hsvToHex(hsv.h, 100, 100) },
|
|
275
|
-
onMouseDown: handleMouseDown,
|
|
276
|
-
children: [
|
|
277
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-r from-white to-transparent" }),
|
|
278
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-t from-black to-transparent" }),
|
|
279
|
-
/* @__PURE__ */ jsx("div", {
|
|
280
|
-
className: `
|
|
281
|
-
absolute w-3 h-3 border-2 border-white rounded-full
|
|
282
|
-
shadow-md -translate-x-1/2 -translate-y-1/2 pointer-events-none
|
|
283
|
-
`,
|
|
284
|
-
style: {
|
|
285
|
-
left: `${hsv.s}%`,
|
|
286
|
-
top: `${100 - hsv.v}%`
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
]
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
function HuePicker({ hue, onChange }) {
|
|
293
|
-
const containerRef = useRef(null);
|
|
294
|
-
function handleMove(e) {
|
|
295
|
-
if (!containerRef.current) return;
|
|
296
|
-
const { left, width } = containerRef.current.getBoundingClientRect();
|
|
297
|
-
onChange(Math.min(Math.max((e.clientX - left) / width, 0), 1) * 360);
|
|
298
|
-
}
|
|
299
|
-
function handleMouseDown(e) {
|
|
300
|
-
handleMove(e);
|
|
301
|
-
function moveHandler(e) {
|
|
302
|
-
handleMove(e);
|
|
303
|
-
}
|
|
304
|
-
function upHandler() {
|
|
305
|
-
window.removeEventListener("mousemove", moveHandler);
|
|
306
|
-
window.removeEventListener("mouseup", upHandler);
|
|
307
|
-
}
|
|
308
|
-
window.addEventListener("mousemove", moveHandler);
|
|
309
|
-
window.addEventListener("mouseup", upHandler);
|
|
310
|
-
}
|
|
311
|
-
return /* @__PURE__ */ jsx("div", {
|
|
312
|
-
ref: containerRef,
|
|
313
|
-
className: "w-full h-3 relative rounded-full cursor-pointer mb-4 select-none",
|
|
314
|
-
style: { background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)" },
|
|
315
|
-
onMouseDown: handleMouseDown,
|
|
316
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
317
|
-
className: `
|
|
318
|
-
absolute w-4 h-4 bg-white border border-gray-200
|
|
319
|
-
rounded-full shadow-sm -translate-x-1/2 -translate-y-1/2
|
|
320
|
-
top-1/2 pointer-events-none
|
|
321
|
-
`,
|
|
322
|
-
style: { left: `${hue / 360 * 100}%` }
|
|
323
|
-
})
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
function ColorPickerPopup({ value, onChange, onClose, anchorName }) {
|
|
327
|
-
const [hsv, setHsv] = useState(() => hexToHsv(value || "#000000"));
|
|
328
|
-
const [hexInput, setHexInput] = useState(value || "#000000");
|
|
329
|
-
useEffect(() => {
|
|
330
|
-
if (value && value !== hexInput) {
|
|
331
|
-
setHsv(hexToHsv(value));
|
|
332
|
-
setHexInput(value);
|
|
333
|
-
}
|
|
334
|
-
}, [value]);
|
|
335
|
-
function handleColorChange(newHsv) {
|
|
336
|
-
setHsv(newHsv);
|
|
337
|
-
const hex = hsvToHex(newHsv.h, newHsv.s, newHsv.v);
|
|
338
|
-
setHexInput(hex);
|
|
339
|
-
onChange(hex);
|
|
340
|
-
}
|
|
341
|
-
function handleSaturationChange(s, v) {
|
|
342
|
-
handleColorChange({
|
|
343
|
-
...hsv,
|
|
344
|
-
s,
|
|
345
|
-
v
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
function handleHueChange(h) {
|
|
349
|
-
handleColorChange({
|
|
350
|
-
...hsv,
|
|
351
|
-
h
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
function manualHexChange(e) {
|
|
355
|
-
const val = e.target.value;
|
|
356
|
-
setHexInput(val);
|
|
357
|
-
if (/^#[0-9A-F]{6}$/i.test(val)) {
|
|
358
|
-
setHsv(hexToHsv(val));
|
|
359
|
-
onChange(val);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
363
|
-
className: "fixed z-50 bg-login-700 border border-login-500/50 rounded-md shadow-xl p-3 w-64 select-none anchor-popup",
|
|
364
|
-
style: {
|
|
365
|
-
positionAnchor: anchorName,
|
|
366
|
-
positionArea: "bottom span-right",
|
|
367
|
-
insetArea: "bottom span-right",
|
|
368
|
-
positionTryFallbacks: "flip-block",
|
|
369
|
-
margin: "0.25rem 0"
|
|
370
|
-
},
|
|
371
|
-
children: [
|
|
372
|
-
/* @__PURE__ */ jsx(SaturationPicker, {
|
|
373
|
-
hsv,
|
|
374
|
-
onChange: handleSaturationChange
|
|
375
|
-
}),
|
|
376
|
-
/* @__PURE__ */ jsx(HuePicker, {
|
|
377
|
-
hue: hsv.h,
|
|
378
|
-
onChange: handleHueChange
|
|
379
|
-
}),
|
|
380
|
-
/* @__PURE__ */ jsxs("div", {
|
|
381
|
-
className: "flex items-center gap-2 mb-3",
|
|
382
|
-
children: [
|
|
383
|
-
/* @__PURE__ */ jsx("div", {
|
|
384
|
-
className: "text-xs text-login-200 font-mono",
|
|
385
|
-
children: "HEX"
|
|
386
|
-
}),
|
|
387
|
-
/* @__PURE__ */ jsx("input", {
|
|
388
|
-
type: "text",
|
|
389
|
-
value: hexInput,
|
|
390
|
-
onChange: manualHexChange,
|
|
391
|
-
className: `
|
|
392
|
-
flex-1 min-w-0 bg-login-600 border border-login-500/50 rounded
|
|
393
|
-
px-2 py-1 text-sm text-login-text focus:outline-none
|
|
394
|
-
focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
395
|
-
`,
|
|
396
|
-
spellCheck: false
|
|
397
|
-
}),
|
|
398
|
-
/* @__PURE__ */ jsx("div", {
|
|
399
|
-
className: "w-8 h-8 rounded border border-login-500/50 shrink-0",
|
|
400
|
-
style: { backgroundColor: hexInput }
|
|
401
|
-
})
|
|
402
|
-
]
|
|
403
|
-
}),
|
|
404
|
-
/* @__PURE__ */ jsx("div", {
|
|
405
|
-
className: "grid grid-cols-8 gap-1.5 pt-3 border-t border-login-500/25",
|
|
406
|
-
children: PRESET_COLORS.map((color) => /* @__PURE__ */ jsx("button", {
|
|
407
|
-
type: "button",
|
|
408
|
-
className: `
|
|
409
|
-
w-6 h-6 rounded-sm cursor-pointer hover:scale-110
|
|
410
|
-
hover:zIndex-10 transition-transform ring-1 ring-inset ring-black/10
|
|
411
|
-
`,
|
|
412
|
-
style: { backgroundColor: color },
|
|
413
|
-
onClick: () => {
|
|
414
|
-
setHsv(hexToHsv(color));
|
|
415
|
-
setHexInput(color);
|
|
416
|
-
onChange(color);
|
|
417
|
-
onClose();
|
|
418
|
-
},
|
|
419
|
-
title: color
|
|
420
|
-
}, color))
|
|
421
|
-
})
|
|
422
|
-
]
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
//#endregion
|
|
426
|
-
//#region src/components/inputs/shared/dateTimePickerPopup.tsx
|
|
427
|
-
const DAYS = [
|
|
428
|
-
"Mo",
|
|
429
|
-
"Tu",
|
|
430
|
-
"We",
|
|
431
|
-
"Th",
|
|
432
|
-
"Fr",
|
|
433
|
-
"Sa",
|
|
434
|
-
"Su"
|
|
435
|
-
];
|
|
436
|
-
const MONTHS = [
|
|
437
|
-
"January",
|
|
438
|
-
"February",
|
|
439
|
-
"March",
|
|
440
|
-
"April",
|
|
441
|
-
"May",
|
|
442
|
-
"June",
|
|
443
|
-
"July",
|
|
444
|
-
"August",
|
|
445
|
-
"September",
|
|
446
|
-
"October",
|
|
447
|
-
"November",
|
|
448
|
-
"December"
|
|
449
|
-
];
|
|
450
|
-
function DateTimePickerPopup({ value, onChange, type, onClose, anchorName }) {
|
|
451
|
-
const [currentDate, setCurrentDate] = useState(/* @__PURE__ */ new Date());
|
|
452
|
-
const [timeInput, setTimeInput] = useState({
|
|
453
|
-
hours: value ? value.getHours().toString() : "0",
|
|
454
|
-
minutes: value ? value.getMinutes().toString() : "0"
|
|
455
|
-
});
|
|
456
|
-
useEffect(() => {
|
|
457
|
-
if (value) {
|
|
458
|
-
setCurrentDate(value);
|
|
459
|
-
setTimeInput((prev) => ({
|
|
460
|
-
hours: prev.hours === "" && value.getHours() === 0 ? "" : value.getHours().toString(),
|
|
461
|
-
minutes: prev.minutes === "" && value.getMinutes() === 0 ? "" : value.getMinutes().toString()
|
|
462
|
-
}));
|
|
463
|
-
}
|
|
464
|
-
}, [value]);
|
|
465
|
-
function handleDateSelect(day) {
|
|
466
|
-
const newDate = new Date(currentDate);
|
|
467
|
-
newDate.setDate(day);
|
|
468
|
-
if (value) {
|
|
469
|
-
newDate.setHours(value.getHours());
|
|
470
|
-
newDate.setMinutes(value.getMinutes());
|
|
471
|
-
} else newDate.setHours(0, 0, 0, 0);
|
|
472
|
-
onChange(newDate);
|
|
473
|
-
if (type === "date" && onClose) onClose();
|
|
474
|
-
}
|
|
475
|
-
function handleTimeChange(timeUnit, val) {
|
|
476
|
-
const newDate = value ? new Date(value) : /* @__PURE__ */ new Date();
|
|
477
|
-
if (!value) newDate.setHours(0, 0, 0, 0);
|
|
478
|
-
if (timeUnit === "hours") {
|
|
479
|
-
if (val < 0 || val > 23) return;
|
|
480
|
-
newDate.setHours(val);
|
|
481
|
-
}
|
|
482
|
-
if (timeUnit === "minutes") {
|
|
483
|
-
if (val < 0 || val > 59) return;
|
|
484
|
-
newDate.setMinutes(val);
|
|
485
|
-
}
|
|
486
|
-
onChange(newDate);
|
|
487
|
-
}
|
|
488
|
-
function onTimeInputChange(unit, val) {
|
|
489
|
-
if (val === "") {
|
|
490
|
-
setTimeInput((prev) => ({
|
|
491
|
-
...prev,
|
|
492
|
-
[unit]: ""
|
|
493
|
-
}));
|
|
494
|
-
handleTimeChange(unit, 0);
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
if (!/^\d+$/.test(val)) return;
|
|
498
|
-
const num = parseInt(val);
|
|
499
|
-
if (unit === "hours" && num > 23) return;
|
|
500
|
-
if (unit === "minutes" && num > 59) return;
|
|
501
|
-
setTimeInput((prev) => ({
|
|
502
|
-
...prev,
|
|
503
|
-
[unit]: val
|
|
504
|
-
}));
|
|
505
|
-
handleTimeChange(unit, num);
|
|
506
|
-
}
|
|
507
|
-
function onTimeInputBlur(unit) {
|
|
508
|
-
if (timeInput[unit] === "") {
|
|
509
|
-
const num = unit === "hours" ? value?.getHours() ?? 0 : value?.getMinutes() ?? 0;
|
|
510
|
-
setTimeInput((prev) => ({
|
|
511
|
-
...prev,
|
|
512
|
-
[unit]: num.toString()
|
|
513
|
-
}));
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
function getDaysInMonth(year, month) {
|
|
517
|
-
return new Date(year, month + 1, 0).getDate();
|
|
518
|
-
}
|
|
519
|
-
function getFirstDayOfMonth(year, month) {
|
|
520
|
-
return new Date(year, month, 1).getDay();
|
|
521
|
-
}
|
|
522
|
-
function renderCalendar() {
|
|
523
|
-
const year = currentDate.getFullYear();
|
|
524
|
-
const month = currentDate.getMonth();
|
|
525
|
-
const daysInMonth = getDaysInMonth(year, month);
|
|
526
|
-
const firstDay = getFirstDayOfMonth(year, month);
|
|
527
|
-
const days = [];
|
|
528
|
-
const adjustedFirstDay = firstDay === 0 ? 6 : firstDay - 1;
|
|
529
|
-
for (let i = 0; i < adjustedFirstDay; i++) days.push(/* @__PURE__ */ jsx("div", { className: "w-8 h-8" }, `empty-${i}`));
|
|
530
|
-
for (let i = 1; i <= daysInMonth; i++) {
|
|
531
|
-
const isSelected = value && value.getDate() === i && value.getMonth() === month && value.getFullYear() === year;
|
|
532
|
-
const isToday = (/* @__PURE__ */ new Date()).getDate() === i && (/* @__PURE__ */ new Date()).getMonth() === month && (/* @__PURE__ */ new Date()).getFullYear() === year;
|
|
533
|
-
days.push(/* @__PURE__ */ jsx("button", {
|
|
534
|
-
type: "button",
|
|
535
|
-
onClick: () => handleDateSelect(i),
|
|
536
|
-
className: `
|
|
537
|
-
w-8 h-8 flex items-center justify-center rounded-full text-sm
|
|
538
|
-
hover:bg-login-600 transition-colors
|
|
539
|
-
${isSelected ? "bg-login! text-white! hover:bg-login!" : ""}
|
|
540
|
-
${!isSelected && isToday ? "text-login! font-bold" : ""}
|
|
541
|
-
${!isSelected && !isToday ? "text-login-text!" : ""}
|
|
542
|
-
`,
|
|
543
|
-
children: i
|
|
544
|
-
}, i));
|
|
545
|
-
}
|
|
546
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
547
|
-
className: "p-2",
|
|
548
|
-
children: [
|
|
549
|
-
/* @__PURE__ */ jsxs("div", {
|
|
550
|
-
className: "flex items-center justify-between mb-2",
|
|
551
|
-
children: [
|
|
552
|
-
/* @__PURE__ */ jsx("button", {
|
|
553
|
-
type: "button",
|
|
554
|
-
onClick: () => setCurrentDate(new Date(year, month - 1)),
|
|
555
|
-
className: "p-1 hover:bg-login-600 rounded-full text-login-text transition-colors",
|
|
556
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4" })
|
|
557
|
-
}),
|
|
558
|
-
/* @__PURE__ */ jsxs("span", {
|
|
559
|
-
className: "font-medium text-login-text",
|
|
560
|
-
children: [
|
|
561
|
-
MONTHS[month],
|
|
562
|
-
" ",
|
|
563
|
-
year
|
|
564
|
-
]
|
|
565
|
-
}),
|
|
566
|
-
/* @__PURE__ */ jsx("button", {
|
|
567
|
-
type: "button",
|
|
568
|
-
onClick: () => setCurrentDate(new Date(year, month + 1)),
|
|
569
|
-
className: "p-1 hover:bg-login-600 rounded-full text-login-text transition-colors",
|
|
570
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4" })
|
|
571
|
-
})
|
|
572
|
-
]
|
|
573
|
-
}),
|
|
574
|
-
/* @__PURE__ */ jsx("div", {
|
|
575
|
-
className: "grid grid-cols-7 gap-1 mb-1",
|
|
576
|
-
children: DAYS.map((d) => /* @__PURE__ */ jsx("div", {
|
|
577
|
-
className: "w-8 text-center text-xs text-login-200 font-medium",
|
|
578
|
-
children: d
|
|
579
|
-
}, d))
|
|
580
|
-
}),
|
|
581
|
-
/* @__PURE__ */ jsx("div", {
|
|
582
|
-
className: "grid grid-cols-7 gap-1",
|
|
583
|
-
children: days
|
|
584
|
-
})
|
|
585
|
-
]
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
function renderTimePicker() {
|
|
589
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
590
|
-
className: "p-2 border-t border-login-500/25 flex justify-center gap-2",
|
|
591
|
-
children: [
|
|
592
|
-
/* @__PURE__ */ jsxs("div", {
|
|
593
|
-
className: "flex flex-col items-center",
|
|
594
|
-
children: [/* @__PURE__ */ jsx("label", {
|
|
595
|
-
className: "text-xs text-login-200 mb-1",
|
|
596
|
-
children: "Hour"
|
|
597
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
598
|
-
type: "text",
|
|
599
|
-
inputMode: "numeric",
|
|
600
|
-
value: timeInput.hours,
|
|
601
|
-
onChange: (e) => onTimeInputChange("hours", e.target.value),
|
|
602
|
-
onBlur: () => onTimeInputBlur("hours"),
|
|
603
|
-
className: `
|
|
604
|
-
w-16 p-1 bg-login-600 rounded text-center text-login-text text-sm
|
|
605
|
-
border border-login-500/50 focus:border-login/60 focus:ring-1 focus:ring-login/30 outline-none
|
|
606
|
-
`
|
|
607
|
-
})]
|
|
608
|
-
}),
|
|
609
|
-
/* @__PURE__ */ jsx("div", {
|
|
610
|
-
className: "flex items-end pb-2 text-login-text",
|
|
611
|
-
children: ":"
|
|
612
|
-
}),
|
|
613
|
-
/* @__PURE__ */ jsxs("div", {
|
|
614
|
-
className: "flex flex-col items-center",
|
|
615
|
-
children: [/* @__PURE__ */ jsx("label", {
|
|
616
|
-
className: "text-xs text-login-200 mb-1",
|
|
617
|
-
children: "Minute"
|
|
618
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
619
|
-
type: "text",
|
|
620
|
-
inputMode: "numeric",
|
|
621
|
-
value: timeInput.minutes,
|
|
622
|
-
onChange: (e) => onTimeInputChange("minutes", e.target.value),
|
|
623
|
-
onBlur: () => onTimeInputBlur("minutes"),
|
|
624
|
-
className: `
|
|
625
|
-
w-16 p-1 bg-login-600 rounded text-center text-login-text text-sm
|
|
626
|
-
border border-login-500/50 focus:border-login/60 focus:ring-1 focus:ring-login/30 outline-none
|
|
627
|
-
`
|
|
628
|
-
})]
|
|
629
|
-
})
|
|
630
|
-
]
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
634
|
-
className: "fixed z-50 bg-login-700 border border-login-500/50 rounded-md shadow-xl p-1 min-w-70 anchor-popup",
|
|
635
|
-
style: {
|
|
636
|
-
positionAnchor: anchorName,
|
|
637
|
-
positionArea: "bottom span-right",
|
|
638
|
-
insetArea: "bottom span-right",
|
|
639
|
-
positionTryFallbacks: "flip-block",
|
|
640
|
-
margin: "0.25rem 0"
|
|
641
|
-
},
|
|
642
|
-
children: [type !== "time" && renderCalendar(), (type === "time" || type === "datetime-local") && renderTimePicker()]
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
//#endregion
|
|
646
|
-
//#region src/components/inputs/input.tsx
|
|
647
|
-
function Input(props) {
|
|
648
|
-
const { name, label, error, className, icon, info, description, textSize = "sm", ...inputProps } = props;
|
|
649
|
-
const { type = "text", value } = inputProps;
|
|
650
|
-
const localRef = useRef(null);
|
|
651
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
652
|
-
const anchorName = `--input-${useId().replace(/:/g, "")}`;
|
|
653
|
-
const containerRef = useRef(null);
|
|
654
|
-
useClickOutside$1(containerRef, () => setIsOpen(false));
|
|
655
|
-
const isDateType = [
|
|
656
|
-
"date",
|
|
657
|
-
"datetime-local",
|
|
658
|
-
"time"
|
|
659
|
-
].includes(type);
|
|
660
|
-
const isColorType = type === "color";
|
|
661
|
-
const isClickableType = isDateType || isColorType;
|
|
662
|
-
function handleIconClick() {
|
|
663
|
-
if (isClickableType && !inputProps.disabled) setIsOpen(!isOpen);
|
|
664
|
-
else if (localRef.current && !inputProps.disabled) localRef.current.focus();
|
|
665
|
-
}
|
|
666
|
-
function pad(n) {
|
|
667
|
-
return n.toString().padStart(2, "0");
|
|
668
|
-
}
|
|
669
|
-
function handleDateChange(date) {
|
|
670
|
-
const onChange = inputProps.onChange;
|
|
671
|
-
if (!onChange) return;
|
|
672
|
-
const yyyy = date.getFullYear();
|
|
673
|
-
const MM = pad(date.getMonth() + 1);
|
|
674
|
-
const dd = pad(date.getDate());
|
|
675
|
-
const hh = pad(date.getHours());
|
|
676
|
-
const mm = pad(date.getMinutes());
|
|
677
|
-
let newValue = "";
|
|
678
|
-
if (type === "date") newValue = `${yyyy}-${MM}-${dd}`;
|
|
679
|
-
else if (type === "time") newValue = `${hh}:${mm}`;
|
|
680
|
-
else if (type === "datetime-local") newValue = `${yyyy}-${MM}-${dd}T${hh}:${mm}`;
|
|
681
|
-
onChange({ target: {
|
|
682
|
-
name,
|
|
683
|
-
value: newValue,
|
|
684
|
-
type
|
|
685
|
-
} });
|
|
686
|
-
}
|
|
687
|
-
function handleColorChange(color) {
|
|
688
|
-
const onChange = inputProps.onChange;
|
|
689
|
-
if (!onChange) return;
|
|
690
|
-
onChange({ target: {
|
|
691
|
-
name,
|
|
692
|
-
value: color,
|
|
693
|
-
type
|
|
694
|
-
} });
|
|
695
|
-
}
|
|
696
|
-
let displayIcon = icon;
|
|
697
|
-
if (!displayIcon && isDateType) if (type === "time") displayIcon = /* @__PURE__ */ jsx(Clock, { className: "w-4 h-4" });
|
|
698
|
-
else displayIcon = /* @__PURE__ */ jsx(Calendar, { className: "w-4 h-4" });
|
|
699
|
-
else if (!displayIcon && isColorType) displayIcon = /* @__PURE__ */ jsx("div", {
|
|
700
|
-
className: "w-4 h-4 rounded border border-login-200",
|
|
701
|
-
style: { backgroundColor: value || "#000000" }
|
|
702
|
-
});
|
|
703
|
-
function getDateValue() {
|
|
704
|
-
if (!value) return null;
|
|
705
|
-
if (type === "time") {
|
|
706
|
-
const date = /* @__PURE__ */ new Date(`2000-01-01T${value}`);
|
|
707
|
-
return isNaN(date.getTime()) ? null : date;
|
|
708
|
-
}
|
|
709
|
-
const date = new Date(value);
|
|
710
|
-
return isNaN(date.getTime()) ? null : date;
|
|
711
|
-
}
|
|
712
|
-
function getDateDisplayValue() {
|
|
713
|
-
if (!value || !isDateType) return value;
|
|
714
|
-
const date = getDateValue();
|
|
715
|
-
if (!date) return value;
|
|
716
|
-
const yyyy = date.getFullYear();
|
|
717
|
-
const MM = pad(date.getMonth() + 1);
|
|
718
|
-
const dd = pad(date.getDate());
|
|
719
|
-
const hh = pad(date.getHours());
|
|
720
|
-
const mm = pad(date.getMinutes());
|
|
721
|
-
if (type === "date") return `${dd}.${MM}.${yyyy}`;
|
|
722
|
-
if (type === "time") return `${hh}:${mm}`;
|
|
723
|
-
if (type === "datetime-local") return `${dd}.${MM}.${yyyy} ${hh}:${mm}`;
|
|
724
|
-
return value;
|
|
725
|
-
}
|
|
726
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
727
|
-
label,
|
|
728
|
-
name,
|
|
729
|
-
required: inputProps.required,
|
|
730
|
-
info,
|
|
731
|
-
error,
|
|
732
|
-
description,
|
|
733
|
-
textSize,
|
|
734
|
-
className,
|
|
735
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
736
|
-
className: "relative flex items-center",
|
|
737
|
-
ref: containerRef,
|
|
738
|
-
children: [
|
|
739
|
-
displayIcon && /* @__PURE__ */ jsx("div", {
|
|
740
|
-
className: `
|
|
741
|
-
absolute left-3 text-login-200
|
|
742
|
-
${isClickableType && !inputProps.disabled ? "cursor-pointer hover:text-login-text" : "pointer-events-none"}
|
|
743
|
-
`,
|
|
744
|
-
onClick: handleIconClick,
|
|
745
|
-
children: displayIcon
|
|
746
|
-
}),
|
|
747
|
-
/* @__PURE__ */ jsx("input", {
|
|
748
|
-
...inputProps,
|
|
749
|
-
ref: localRef,
|
|
750
|
-
id: name,
|
|
751
|
-
name: isClickableType ? void 0 : name,
|
|
752
|
-
type: isClickableType ? "text" : type,
|
|
753
|
-
value: isDateType ? getDateDisplayValue() : value,
|
|
754
|
-
readOnly: isClickableType,
|
|
755
|
-
onClick: () => isClickableType && !inputProps.disabled && setIsOpen(true),
|
|
756
|
-
"aria-describedby": error ? `${name}-error` : void 0,
|
|
757
|
-
style: { anchorName },
|
|
758
|
-
className: `
|
|
759
|
-
w-full rounded-md bg-login-500/50 border border-login-500
|
|
760
|
-
text-login-text placeholder-login-200 text-sm
|
|
761
|
-
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
762
|
-
disabled:opacity-40 disabled:cursor-not-allowed
|
|
763
|
-
h-10 py-2 ${displayIcon ? "pl-10 pr-3" : "px-3"}
|
|
764
|
-
transition-all duration-150
|
|
765
|
-
input-reset
|
|
766
|
-
${error ? "border-red-500/70 focus:border-red-500/70 focus:ring-red-500/30" : ""}
|
|
767
|
-
${isClickableType && !inputProps.disabled ? "cursor-pointer" : ""}
|
|
768
|
-
`
|
|
769
|
-
}),
|
|
770
|
-
isClickableType && /* @__PURE__ */ jsx("input", {
|
|
771
|
-
type: "hidden",
|
|
772
|
-
name,
|
|
773
|
-
value
|
|
774
|
-
}),
|
|
775
|
-
isOpen && isDateType && !inputProps.disabled && /* @__PURE__ */ jsx(DateTimePickerPopup, {
|
|
776
|
-
value: getDateValue(),
|
|
777
|
-
onChange: handleDateChange,
|
|
778
|
-
type,
|
|
779
|
-
onClose: () => setIsOpen(false),
|
|
780
|
-
anchorName
|
|
781
|
-
}),
|
|
782
|
-
isOpen && isColorType && !inputProps.disabled && /* @__PURE__ */ jsx(ColorPickerPopup, {
|
|
783
|
-
value: value || "",
|
|
784
|
-
onChange: handleColorChange,
|
|
785
|
-
onClose: () => setIsOpen(false),
|
|
786
|
-
anchorName
|
|
787
|
-
})
|
|
788
|
-
]
|
|
789
|
-
})
|
|
790
|
-
});
|
|
791
|
-
}
|
|
792
|
-
//#endregion
|
|
793
|
-
//#region src/components/inputs/searchInput.tsx
|
|
794
|
-
function SearchInput({ placeholder = "Search...", variant = "default" }) {
|
|
795
|
-
const router = useRouter();
|
|
796
|
-
const pathname = usePathname();
|
|
797
|
-
const searchParams = useSearchParams();
|
|
798
|
-
const [searchValue, setSearchValue] = useState(searchParams.get("q") || "");
|
|
799
|
-
useEffect(() => {
|
|
800
|
-
setSearchValue(searchParams.get("q") || "");
|
|
801
|
-
}, [searchParams]);
|
|
802
|
-
function handleSearch(value) {
|
|
803
|
-
setSearchValue(value);
|
|
804
|
-
const params = new URLSearchParams(searchParams.toString());
|
|
805
|
-
if (value.trim()) params.set("q", value.trim());
|
|
806
|
-
else params.delete("q");
|
|
807
|
-
params.delete("page");
|
|
808
|
-
router.push(`${pathname}?${params.toString()}`);
|
|
809
|
-
}
|
|
810
|
-
function handleKeyDown(e) {
|
|
811
|
-
if (e.key === "Enter") handleSearch(searchValue);
|
|
812
|
-
}
|
|
813
|
-
function handleChange(e) {
|
|
814
|
-
setSearchValue(e.target.value);
|
|
815
|
-
}
|
|
816
|
-
if (variant === "minimal") return /* @__PURE__ */ jsxs("div", {
|
|
817
|
-
className: "relative",
|
|
818
|
-
children: [/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5" }), /* @__PURE__ */ jsx("input", {
|
|
819
|
-
type: "text",
|
|
820
|
-
value: searchValue,
|
|
821
|
-
onChange: (e) => setSearchValue(e.target.value),
|
|
822
|
-
onKeyDown: handleKeyDown,
|
|
823
|
-
onBlur: () => handleSearch(searchValue),
|
|
824
|
-
placeholder,
|
|
825
|
-
className: "pl-10 pr-4 py-2 border-b outline-none w-64"
|
|
826
|
-
})]
|
|
827
|
-
});
|
|
828
|
-
else return /* @__PURE__ */ jsx("div", {
|
|
829
|
-
className: "w-fit min-w-48",
|
|
830
|
-
children: /* @__PURE__ */ jsx(Input, {
|
|
831
|
-
name: "search",
|
|
832
|
-
icon: /* @__PURE__ */ jsx(Search, { className: "w-5 h-5" }),
|
|
833
|
-
value: searchValue,
|
|
834
|
-
onChange: handleChange,
|
|
835
|
-
onKeyDown: handleKeyDown,
|
|
836
|
-
onBlur: () => handleSearch(searchValue),
|
|
837
|
-
placeholder
|
|
838
|
-
})
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
//#endregion
|
|
842
|
-
//#region src/components/inputs/textarea.tsx
|
|
843
|
-
function isValidJson(str) {
|
|
844
|
-
try {
|
|
845
|
-
JSON.parse(str);
|
|
846
|
-
return null;
|
|
847
|
-
} catch (error) {
|
|
848
|
-
return error.message;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
function Textarea(props) {
|
|
852
|
-
const { name, label, error, className, info, description, type = "text", rows = 4, textSize = "sm", ...textareaProps } = props;
|
|
853
|
-
const { value } = textareaProps;
|
|
854
|
-
const [preview, setPreview] = useState(false);
|
|
855
|
-
const displayError = (type === "json" && value ? isValidJson(value) : void 0) || error;
|
|
856
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
857
|
-
label,
|
|
858
|
-
name,
|
|
859
|
-
required: textareaProps.required,
|
|
860
|
-
info,
|
|
861
|
-
description,
|
|
862
|
-
error: displayError,
|
|
863
|
-
textSize,
|
|
864
|
-
className,
|
|
865
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
866
|
-
className: "relative",
|
|
867
|
-
children: [
|
|
868
|
-
type === "markdown" && /* @__PURE__ */ jsx("div", {
|
|
869
|
-
className: "absolute right-2 top-2 z-10 flex gap-2",
|
|
870
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
871
|
-
type: "button",
|
|
872
|
-
onClick: () => setPreview(!preview),
|
|
873
|
-
className: "p-1 rounded hover:bg-login-500/50 text-login-text transition-colors",
|
|
874
|
-
title: preview ? "Edit" : "Preview",
|
|
875
|
-
children: preview ? /* @__PURE__ */ jsx(Pencil, { size: 16 }) : /* @__PURE__ */ jsx(Eye, { size: 16 })
|
|
876
|
-
})
|
|
877
|
-
}),
|
|
878
|
-
type === "markdown" && preview && /* @__PURE__ */ jsx("div", {
|
|
879
|
-
className: `
|
|
880
|
-
w-full rounded-md bg-login-500/50 border border-login-500
|
|
881
|
-
p-3 overflow-y-auto ${error ? "border-red-500/70" : ""}
|
|
882
|
-
`,
|
|
883
|
-
children: /* @__PURE__ */ jsx(MarkdownRender, { MDstr: String(value || "") })
|
|
884
|
-
}),
|
|
885
|
-
/* @__PURE__ */ jsx("textarea", {
|
|
886
|
-
...textareaProps,
|
|
887
|
-
id: name,
|
|
888
|
-
name,
|
|
889
|
-
rows,
|
|
890
|
-
title: label,
|
|
891
|
-
"aria-invalid": !!error,
|
|
892
|
-
"aria-describedby": error ? `${name}-error` : void 0,
|
|
893
|
-
className: `
|
|
894
|
-
${type === "markdown" && preview ? "hidden" : ""}
|
|
895
|
-
w-full rounded-md bg-login-500/50 border border-login-500
|
|
896
|
-
text-login-text placeholder-login-200 text-sm
|
|
897
|
-
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
898
|
-
disabled:opacity-40 disabled:cursor-not-allowed
|
|
899
|
-
p-3 pr-10
|
|
900
|
-
transition-all duration-150
|
|
901
|
-
resize-y
|
|
902
|
-
${error ? "border-red-500/70 focus:border-red-500/70 focus:ring-red-500/30" : ""}
|
|
903
|
-
`
|
|
904
|
-
})
|
|
905
|
-
]
|
|
906
|
-
})
|
|
907
|
-
});
|
|
908
|
-
}
|
|
909
|
-
//#endregion
|
|
910
|
-
//#region src/components/inputs/checkbox.tsx
|
|
911
|
-
function Checkbox(props) {
|
|
912
|
-
const { options, onChange, value, label, description, error, info, name, className, textSize = "sm", ...rest } = props;
|
|
913
|
-
const selectedValues = Array.isArray(value) ? value : [];
|
|
914
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
915
|
-
label,
|
|
916
|
-
name,
|
|
917
|
-
required: rest.required,
|
|
918
|
-
info,
|
|
919
|
-
description,
|
|
920
|
-
error,
|
|
921
|
-
textSize,
|
|
922
|
-
className,
|
|
923
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
924
|
-
className: "flex flex-col gap-2",
|
|
925
|
-
children: options.map((option) => /* @__PURE__ */ jsx(CheckboxItem, {
|
|
926
|
-
name,
|
|
927
|
-
value: option.value,
|
|
928
|
-
label: option.label,
|
|
929
|
-
checked: selectedValues.includes(option.value),
|
|
930
|
-
disabled: rest.disabled,
|
|
931
|
-
onChange: (e) => {
|
|
932
|
-
if (!onChange) return;
|
|
933
|
-
const isChecked = e.target.checked;
|
|
934
|
-
let newValues = [...selectedValues];
|
|
935
|
-
if (isChecked) newValues.push(option.value);
|
|
936
|
-
else newValues = newValues.filter((v) => v !== option.value);
|
|
937
|
-
onChange(newValues);
|
|
938
|
-
},
|
|
939
|
-
className: "mb-0"
|
|
940
|
-
}, option.value))
|
|
941
|
-
})
|
|
942
|
-
});
|
|
943
|
-
}
|
|
944
|
-
function CheckboxItem(props) {
|
|
945
|
-
const { name, label, error, ...inputProps } = props;
|
|
946
|
-
const id = inputProps.value ? `${name}-${inputProps.value}` : name;
|
|
947
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
948
|
-
className: "flex items-center gap-2",
|
|
949
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
950
|
-
className: "relative w-5 h-5 shrink-0",
|
|
951
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
952
|
-
...inputProps,
|
|
953
|
-
id,
|
|
954
|
-
name,
|
|
955
|
-
type: "checkbox",
|
|
956
|
-
className: `
|
|
957
|
-
peer appearance-none rounded border border-login-500 bg-login-500/50
|
|
958
|
-
checked:bg-login checked:border-login
|
|
959
|
-
focus:outline-none focus:ring-1 focus:ring-login/30
|
|
960
|
-
disabled:opacity-40 disabled:cursor-not-allowed
|
|
961
|
-
cursor-pointer transition-all duration-150
|
|
962
|
-
w-5 h-5 absolute inset-0
|
|
963
|
-
${error ? "border-red-500/70" : ""}
|
|
964
|
-
`
|
|
965
|
-
}), /* @__PURE__ */ jsx(Check, { className: `
|
|
966
|
-
absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
|
|
967
|
-
w-3.5 h-3.5 pointer-events-none text-white opacity-0
|
|
968
|
-
peer-checked:opacity-100 transition-opacity duration-200
|
|
969
|
-
` })]
|
|
970
|
-
}), label && /* @__PURE__ */ jsx(InputLabel, {
|
|
971
|
-
label,
|
|
972
|
-
name,
|
|
973
|
-
disabled: inputProps.disabled,
|
|
974
|
-
className: "select-none cursor-pointer"
|
|
975
|
-
})]
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
//#endregion
|
|
979
|
-
//#region src/components/inputs/select.tsx
|
|
980
|
-
function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder = "Select an option", info, description, clearable = true, searchable = true, textSize = "sm" }) {
|
|
981
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
982
|
-
const [searchTerm, setSearchTerm] = useState("");
|
|
983
|
-
const [selectedOption, setSelectedOption] = useState(options.find((opt) => opt.value === value));
|
|
984
|
-
useEffect(() => {
|
|
985
|
-
if (!isOpen) setSearchTerm("");
|
|
986
|
-
}, [isOpen]);
|
|
987
|
-
useEffect(() => {
|
|
988
|
-
setSelectedOption(options.find((opt) => opt.value === value));
|
|
989
|
-
}, [value, options]);
|
|
990
|
-
const containerRef = useRef(null);
|
|
991
|
-
useClickOutside$1(containerRef, () => setIsOpen(false));
|
|
992
|
-
function handleSelect(option) {
|
|
993
|
-
if (disabled) return;
|
|
994
|
-
setSelectedOption(option);
|
|
995
|
-
setIsOpen(false);
|
|
996
|
-
if (onChange) onChange(option.value);
|
|
997
|
-
}
|
|
998
|
-
function handleClear(e) {
|
|
999
|
-
e.stopPropagation();
|
|
1000
|
-
if (disabled) return;
|
|
1001
|
-
setSelectedOption(void 0);
|
|
1002
|
-
if (onChange) onChange(null);
|
|
1003
|
-
}
|
|
1004
|
-
const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
1005
|
-
return /* @__PURE__ */ jsxs(FieldWrapper, {
|
|
1006
|
-
label,
|
|
1007
|
-
name,
|
|
1008
|
-
required,
|
|
1009
|
-
info,
|
|
1010
|
-
description,
|
|
1011
|
-
error,
|
|
1012
|
-
textSize,
|
|
1013
|
-
className,
|
|
1014
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1015
|
-
className: "relative",
|
|
1016
|
-
ref: containerRef,
|
|
1017
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
1018
|
-
type: "button",
|
|
1019
|
-
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
1020
|
-
disabled,
|
|
1021
|
-
"aria-haspopup": "listbox",
|
|
1022
|
-
"aria-expanded": isOpen,
|
|
1023
|
-
"aria-labelledby": label ? void 0 : name,
|
|
1024
|
-
className: `
|
|
1025
|
-
w-full rounded-md bg-login-500/50 border border-login-500
|
|
1026
|
-
text-login-text text-left text-sm
|
|
1027
|
-
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
1028
|
-
disabled:opacity-40 disabled:cursor-not-allowed
|
|
1029
|
-
h-10 py-2 pl-3 pr-10
|
|
1030
|
-
transition-all duration-150
|
|
1031
|
-
flex items-center justify-between
|
|
1032
|
-
${error ? "border-red-500/70 focus:border-red-500/70 focus:ring-red-500/30" : ""}
|
|
1033
|
-
${!selectedOption ? "text-login-200" : ""}
|
|
1034
|
-
`,
|
|
1035
|
-
title: label,
|
|
1036
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1037
|
-
className: "flex items-center gap-2 truncate",
|
|
1038
|
-
children: [selectedOption?.image && /* @__PURE__ */ jsx(Image, {
|
|
1039
|
-
src: selectedOption.image,
|
|
1040
|
-
alt: "",
|
|
1041
|
-
width: 30,
|
|
1042
|
-
height: 20,
|
|
1043
|
-
className: "rounded-xs object-cover shrink-0"
|
|
1044
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
1045
|
-
className: "truncate",
|
|
1046
|
-
children: selectedOption ? selectedOption.label : placeholder
|
|
1047
|
-
})]
|
|
1048
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1049
|
-
className: "absolute inset-y-0 right-0 flex items-center px-2 gap-1",
|
|
1050
|
-
children: [clearable && selectedOption && !disabled && /* @__PURE__ */ jsx("div", {
|
|
1051
|
-
role: "button",
|
|
1052
|
-
onClick: handleClear,
|
|
1053
|
-
className: `
|
|
1054
|
-
p-1 hover:bg-login-500 rounded-full text-login-200
|
|
1055
|
-
hover:text-red-400 transition-colors cursor-pointer
|
|
1056
|
-
`,
|
|
1057
|
-
title: "Clear selection",
|
|
1058
|
-
children: /* @__PURE__ */ jsx(X, { className: "w-3 h-3" })
|
|
1059
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1060
|
-
className: `
|
|
1061
|
-
text-login-200 pointer-events-none
|
|
1062
|
-
transition-transform duration-200
|
|
1063
|
-
${isOpen ? "rotate-180" : ""}
|
|
1064
|
-
`,
|
|
1065
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className: "w-4 h-4" })
|
|
1066
|
-
})]
|
|
1067
|
-
})]
|
|
1068
|
-
}), isOpen && /* @__PURE__ */ jsxs("div", {
|
|
1069
|
-
className: `
|
|
1070
|
-
absolute z-50 w-full mt-1 bg-login-700 border border-login-500/50
|
|
1071
|
-
rounded-md shadow-xl max-h-60 overflow-hidden flex flex-col
|
|
1072
|
-
`,
|
|
1073
|
-
children: [searchable && /* @__PURE__ */ jsx("div", {
|
|
1074
|
-
className: "p-2 sticky top-0 bg-login-700 border-b border-login-500/20 z-10",
|
|
1075
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1076
|
-
className: "relative",
|
|
1077
|
-
children: [/* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-login-200" }), /* @__PURE__ */ jsx("input", {
|
|
1078
|
-
type: "text",
|
|
1079
|
-
value: searchTerm,
|
|
1080
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
1081
|
-
placeholder: "Search...",
|
|
1082
|
-
autoFocus: true,
|
|
1083
|
-
className: `
|
|
1084
|
-
w-full bg-login-600 border border-login-500/50 rounded-md
|
|
1085
|
-
py-1.5 pl-9 pr-3 text-sm text-login-text
|
|
1086
|
-
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
1087
|
-
`
|
|
1088
|
-
})]
|
|
1089
|
-
})
|
|
1090
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1091
|
-
className: "overflow-auto noscroll",
|
|
1092
|
-
children: filteredOptions.length > 0 ? /* @__PURE__ */ jsx("ul", {
|
|
1093
|
-
className: "py-1",
|
|
1094
|
-
role: "listbox",
|
|
1095
|
-
children: filteredOptions.map((option) => /* @__PURE__ */ jsx("li", {
|
|
1096
|
-
role: "option",
|
|
1097
|
-
"aria-selected": selectedOption?.value === option.value,
|
|
1098
|
-
children: /* @__PURE__ */ jsxs("button", {
|
|
1099
|
-
type: "button",
|
|
1100
|
-
onClick: () => handleSelect(option),
|
|
1101
|
-
className: `
|
|
1102
|
-
w-full text-left px-3 py-2 text-sm
|
|
1103
|
-
hover:bg-login-600 transition-colors duration-150
|
|
1104
|
-
flex items-center gap-2
|
|
1105
|
-
${selectedOption?.value === option.value ? "bg-login/15 text-login" : "text-login-text"}
|
|
1106
|
-
`,
|
|
1107
|
-
children: [option.image && /* @__PURE__ */ jsx(Image, {
|
|
1108
|
-
src: option.image,
|
|
1109
|
-
alt: "",
|
|
1110
|
-
width: 75,
|
|
1111
|
-
height: 25,
|
|
1112
|
-
className: "rounded-md object-cover shrink-0"
|
|
1113
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
1114
|
-
className: "truncate",
|
|
1115
|
-
children: option.label
|
|
1116
|
-
})]
|
|
1117
|
-
})
|
|
1118
|
-
}, option.value))
|
|
1119
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
1120
|
-
className: "px-3 py-2 text-sm text-login-200",
|
|
1121
|
-
children: searchTerm ? "No results found" : "No options available"
|
|
1122
|
-
})
|
|
1123
|
-
})]
|
|
1124
|
-
})]
|
|
1125
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
1126
|
-
type: "hidden",
|
|
1127
|
-
name,
|
|
1128
|
-
value: selectedOption?.value || "",
|
|
1129
|
-
required
|
|
1130
|
-
})]
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
|
-
//#endregion
|
|
1134
|
-
//#region src/components/inputs/tagInput.tsx
|
|
1135
|
-
function TagInput({ label, name, value = [], onChange, placeholder = "Add...", error, className, disabled, required, info, description, textSize = "sm" }) {
|
|
1136
|
-
const [inputValue, setInputValue] = useState("");
|
|
1137
|
-
function handleKeyDown(e) {
|
|
1138
|
-
if ((e.key === "Enter" || e.key === ",") && inputValue.trim()) {
|
|
1139
|
-
e.preventDefault();
|
|
1140
|
-
const val = inputValue.trim().replace(/,$/, "");
|
|
1141
|
-
if (val && !value.includes(val)) {
|
|
1142
|
-
const newValue = [...value, val];
|
|
1143
|
-
if (onChange) onChange(newValue);
|
|
1144
|
-
}
|
|
1145
|
-
setInputValue("");
|
|
1146
|
-
} else if (e.key === "Backspace" && !inputValue && value.length > 0) {
|
|
1147
|
-
const newValue = value.slice(0, -1);
|
|
1148
|
-
if (onChange) onChange(newValue);
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
function removeTag(index) {
|
|
1152
|
-
if (disabled) return;
|
|
1153
|
-
const newValue = value.filter((_, i) => i !== index);
|
|
1154
|
-
if (onChange) onChange(newValue);
|
|
1155
|
-
}
|
|
1156
|
-
return /* @__PURE__ */ jsxs(FieldWrapper, {
|
|
1157
|
-
label,
|
|
1158
|
-
name,
|
|
1159
|
-
required,
|
|
1160
|
-
info,
|
|
1161
|
-
description,
|
|
1162
|
-
error,
|
|
1163
|
-
className,
|
|
1164
|
-
textSize,
|
|
1165
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1166
|
-
className: `
|
|
1167
|
-
flex flex-wrap gap-2 p-2 rounded-md bg-login-500/50 border border-login-500
|
|
1168
|
-
text-login-text min-h-10
|
|
1169
|
-
focus-within:border-login/60 focus-within:ring-1 focus-within:ring-login/30
|
|
1170
|
-
transition-all duration-150
|
|
1171
|
-
${error ? "border-red-500/70 focus-within:border-red-500/70 focus-within:ring-red-500/30" : ""}
|
|
1172
|
-
`,
|
|
1173
|
-
children: [value.map((tag, index) => /* @__PURE__ */ jsxs("span", {
|
|
1174
|
-
className: "flex items-center gap-1 px-2 py-0.5 bg-login-600 text-login-100 border border-login-500 rounded text-sm",
|
|
1175
|
-
children: [tag, !disabled && /* @__PURE__ */ jsx("button", {
|
|
1176
|
-
type: "button",
|
|
1177
|
-
onClick: () => removeTag(index),
|
|
1178
|
-
className: "hover:text-red-200 transition-colors",
|
|
1179
|
-
children: /* @__PURE__ */ jsx(X, { size: 14 })
|
|
1180
|
-
})]
|
|
1181
|
-
}, index)), /* @__PURE__ */ jsx("input", {
|
|
1182
|
-
type: "text",
|
|
1183
|
-
value: inputValue,
|
|
1184
|
-
required: required && value.length === 0,
|
|
1185
|
-
onChange: (e) => setInputValue(e.target.value),
|
|
1186
|
-
onKeyDown: handleKeyDown,
|
|
1187
|
-
disabled,
|
|
1188
|
-
placeholder: value.length === 0 ? placeholder : "",
|
|
1189
|
-
className: "flex-1 bg-transparent outline-none min-w-30 text-login-text placeholder:text-login-200"
|
|
1190
|
-
})]
|
|
1191
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
1192
|
-
type: "hidden",
|
|
1193
|
-
name,
|
|
1194
|
-
value: value.join(",")
|
|
1195
|
-
})]
|
|
1196
|
-
});
|
|
1197
|
-
}
|
|
1198
|
-
//#endregion
|
|
1199
|
-
//#region src/components/inputs/multiSelect.tsx
|
|
1200
|
-
function MultiSelect({ label, name, options, value = [], onChange, placeholder = "Select…", error, className, disabled, required, info, description, textSize = "sm" }) {
|
|
1201
|
-
const [open, setOpen] = useState(false);
|
|
1202
|
-
const containerRef = useRef(null);
|
|
1203
|
-
useClickOutside$1(containerRef, () => setOpen(false));
|
|
1204
|
-
function toggleOption(optionValue) {
|
|
1205
|
-
if (!onChange) return;
|
|
1206
|
-
if (value.includes(optionValue)) onChange(value.filter((v) => v !== optionValue));
|
|
1207
|
-
else onChange([...value, optionValue]);
|
|
1208
|
-
}
|
|
1209
|
-
function removeOption(optionValue) {
|
|
1210
|
-
if (!onChange) return;
|
|
1211
|
-
onChange(value.filter((v) => v !== optionValue));
|
|
1212
|
-
}
|
|
1213
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
1214
|
-
label,
|
|
1215
|
-
name,
|
|
1216
|
-
required,
|
|
1217
|
-
info,
|
|
1218
|
-
description,
|
|
1219
|
-
error,
|
|
1220
|
-
className,
|
|
1221
|
-
textSize,
|
|
1222
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1223
|
-
ref: containerRef,
|
|
1224
|
-
className: "relative w-full",
|
|
1225
|
-
children: [
|
|
1226
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1227
|
-
onClick: () => !disabled && setOpen((o) => !o),
|
|
1228
|
-
className: `
|
|
1229
|
-
flex min-h-10 cursor-pointer items-center justify-between gap-2
|
|
1230
|
-
rounded-md bg-login-500/50 border border-login-500 px-3 py-1.5
|
|
1231
|
-
transition-all duration-150 select-none
|
|
1232
|
-
${open ? "border-login/60 ring-1 ring-login/30" : ""}
|
|
1233
|
-
${error ? "border-red-500/70" : ""}
|
|
1234
|
-
${disabled ? "opacity-40 cursor-not-allowed" : ""}
|
|
1235
|
-
`,
|
|
1236
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1237
|
-
className: "flex flex-wrap gap-1.5",
|
|
1238
|
-
children: [value.length === 0 && /* @__PURE__ */ jsx("span", {
|
|
1239
|
-
className: "text-sm text-login-200",
|
|
1240
|
-
children: placeholder
|
|
1241
|
-
}), value.map((val) => {
|
|
1242
|
-
const option = options.find((o) => o.value === val);
|
|
1243
|
-
if (!option) return null;
|
|
1244
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
1245
|
-
className: "\n flex items-center gap-1 rounded px-2 py-0.5 text-sm\n border border-login-500 bg-login-600 text-login-100\n ",
|
|
1246
|
-
children: [option.label, !disabled && /* @__PURE__ */ jsx("button", {
|
|
1247
|
-
type: "button",
|
|
1248
|
-
onClick: (e) => {
|
|
1249
|
-
e.stopPropagation();
|
|
1250
|
-
removeOption(val);
|
|
1251
|
-
},
|
|
1252
|
-
className: "hover:text-red-300 transition-colors",
|
|
1253
|
-
children: /* @__PURE__ */ jsx(X, { size: 13 })
|
|
1254
|
-
})]
|
|
1255
|
-
}, val);
|
|
1256
|
-
})]
|
|
1257
|
-
}), /* @__PURE__ */ jsx(ChevronDown, {
|
|
1258
|
-
size: 16,
|
|
1259
|
-
className: `shrink-0 text-login-200 transition-transform duration-150 ${open ? "rotate-180" : ""}`
|
|
1260
|
-
})]
|
|
1261
|
-
}),
|
|
1262
|
-
open && options.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
1263
|
-
className: "\n absolute z-50 mt-1 w-full max-h-60 overflow-auto\n rounded-md border border-login-500/50 bg-login-800 shadow-lg\n ",
|
|
1264
|
-
children: options.map((option) => {
|
|
1265
|
-
const selected = value.includes(option.value);
|
|
1266
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1267
|
-
onClick: () => toggleOption(option.value),
|
|
1268
|
-
className: `
|
|
1269
|
-
flex cursor-pointer items-center justify-between px-3 py-2 text-sm
|
|
1270
|
-
hover:bg-login-700 transition-colors select-none
|
|
1271
|
-
${selected ? "text-login-50" : "text-login-100"}
|
|
1272
|
-
`,
|
|
1273
|
-
children: [/* @__PURE__ */ jsx("span", { children: option.label }), selected && /* @__PURE__ */ jsx(Check, {
|
|
1274
|
-
size: 14,
|
|
1275
|
-
className: "text-login shrink-0"
|
|
1276
|
-
})]
|
|
1277
|
-
}, option.value);
|
|
1278
|
-
})
|
|
1279
|
-
}),
|
|
1280
|
-
/* @__PURE__ */ jsx("input", {
|
|
1281
|
-
type: "hidden",
|
|
1282
|
-
name,
|
|
1283
|
-
value: value.join(",")
|
|
1284
|
-
})
|
|
1285
|
-
]
|
|
1286
|
-
})
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
//#endregion
|
|
1290
|
-
//#region src/components/inputs/switch.tsx
|
|
1291
|
-
function Switch(props) {
|
|
1292
|
-
const { name, label, error, info, description, className, switchOnly, textSize = "sm", ...inputProps } = props;
|
|
1293
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
1294
|
-
label,
|
|
1295
|
-
name,
|
|
1296
|
-
required: inputProps.required,
|
|
1297
|
-
info,
|
|
1298
|
-
error,
|
|
1299
|
-
description,
|
|
1300
|
-
textSize,
|
|
1301
|
-
className,
|
|
1302
|
-
children: /* @__PURE__ */ jsxs("label", {
|
|
1303
|
-
className: `group/sw inline-flex items-center cursor-pointer ${switchOnly ? "h-fit" : "h-10"}`,
|
|
1304
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
1305
|
-
...inputProps,
|
|
1306
|
-
type: "checkbox",
|
|
1307
|
-
id: name,
|
|
1308
|
-
name,
|
|
1309
|
-
className: "sr-only"
|
|
1310
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1311
|
-
className: `
|
|
1312
|
-
relative flex items-center w-11 h-6 rounded-full transition-colors
|
|
1313
|
-
bg-login-600 group-has-[input:checked]/sw:bg-login
|
|
1314
|
-
${inputProps.disabled ? "opacity-40 cursor-not-allowed" : ""}
|
|
1315
|
-
${error ? "ring-1 ring-red-500/60" : ""}
|
|
1316
|
-
`,
|
|
1317
|
-
children: /* @__PURE__ */ jsx("span", { className: "\n absolute inset-y-0 my-auto left-0.5 h-5 w-5\n rounded-full bg-white shadow-sm transition-all\n group-has-[input:checked]/sw:translate-x-full\n " })
|
|
1318
|
-
})]
|
|
1319
|
-
})
|
|
1320
|
-
});
|
|
1321
|
-
}
|
|
1322
|
-
//#endregion
|
|
1323
|
-
//#region src/components/inputs/radio.tsx
|
|
1324
|
-
function Radio(props) {
|
|
1325
|
-
const { options, onChange, value, label, description, error, info, name, className, textSize = "sm", ...rest } = props;
|
|
1326
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
1327
|
-
label,
|
|
1328
|
-
name,
|
|
1329
|
-
required: rest.required,
|
|
1330
|
-
info,
|
|
1331
|
-
description,
|
|
1332
|
-
error,
|
|
1333
|
-
textSize,
|
|
1334
|
-
className,
|
|
1335
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
1336
|
-
className: "flex flex-col gap-2",
|
|
1337
|
-
children: options.map((option) => /* @__PURE__ */ jsx(RadioItem, {
|
|
1338
|
-
name,
|
|
1339
|
-
value: option.value,
|
|
1340
|
-
label: option.label,
|
|
1341
|
-
checked: value === option.value,
|
|
1342
|
-
disabled: rest.disabled,
|
|
1343
|
-
onChange: () => {
|
|
1344
|
-
if (onChange) onChange(option.value);
|
|
1345
|
-
},
|
|
1346
|
-
className: "mb-0"
|
|
1347
|
-
}, option.value))
|
|
1348
|
-
})
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
|
-
function RadioItem(props) {
|
|
1352
|
-
const { name, label, error, ...inputProps } = props;
|
|
1353
|
-
const { value } = inputProps;
|
|
1354
|
-
const id = `${name}-${value}`;
|
|
1355
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1356
|
-
className: "flex items-center gap-2",
|
|
1357
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1358
|
-
className: "relative w-5 h-5 shrink-0",
|
|
1359
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
1360
|
-
...inputProps,
|
|
1361
|
-
id,
|
|
1362
|
-
name,
|
|
1363
|
-
type: "radio",
|
|
1364
|
-
className: `
|
|
1365
|
-
peer appearance-none rounded-full border border-login-500 bg-login-500/50
|
|
1366
|
-
checked:bg-login checked:border-login
|
|
1367
|
-
focus:outline-none focus:ring-1 focus:ring-login/30
|
|
1368
|
-
disabled:opacity-40 disabled:cursor-not-allowed
|
|
1369
|
-
cursor-pointer transition-all duration-150
|
|
1370
|
-
w-5 h-5 absolute inset-0
|
|
1371
|
-
${error ? "border-red-500/70" : ""}
|
|
1372
|
-
`
|
|
1373
|
-
}), /* @__PURE__ */ jsx("div", { className: `
|
|
1374
|
-
absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
|
|
1375
|
-
w-2 h-2 rounded-full bg-white pointer-events-none opacity-0
|
|
1376
|
-
peer-checked:opacity-100 transition-opacity duration-200
|
|
1377
|
-
` })]
|
|
1378
|
-
}), label && /* @__PURE__ */ jsx(InputLabel, {
|
|
1379
|
-
label,
|
|
1380
|
-
name,
|
|
1381
|
-
disabled: inputProps.disabled,
|
|
1382
|
-
className: "select-none cursor-pointer"
|
|
1383
|
-
})]
|
|
1384
|
-
});
|
|
1385
|
-
}
|
|
1386
|
-
//#endregion
|
|
1387
|
-
//#region src/components/inputs/range.tsx
|
|
1388
|
-
function Range(props) {
|
|
1389
|
-
const { name, label, error, className, info, description, showValue = true, textSize = "sm", ...inputProps } = props;
|
|
1390
|
-
const { min = 0, max = 100, step = 1, value, defaultValue, onChange, ...restInputProps } = inputProps;
|
|
1391
|
-
const displayValue = value ?? defaultValue ?? 0;
|
|
1392
|
-
return /* @__PURE__ */ jsx(FieldWrapper, {
|
|
1393
|
-
label,
|
|
1394
|
-
name,
|
|
1395
|
-
required: restInputProps.required,
|
|
1396
|
-
info,
|
|
1397
|
-
description,
|
|
1398
|
-
error,
|
|
1399
|
-
textSize,
|
|
1400
|
-
className,
|
|
1401
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1402
|
-
className: "flex items-center gap-4",
|
|
1403
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
1404
|
-
...restInputProps,
|
|
1405
|
-
id: name,
|
|
1406
|
-
name,
|
|
1407
|
-
type: "range",
|
|
1408
|
-
min,
|
|
1409
|
-
max,
|
|
1410
|
-
step,
|
|
1411
|
-
...onChange ? {
|
|
1412
|
-
value,
|
|
1413
|
-
onChange
|
|
1414
|
-
} : { defaultValue: value ?? defaultValue ?? 0 },
|
|
1415
|
-
title: label,
|
|
1416
|
-
"aria-invalid": !!error,
|
|
1417
|
-
"aria-describedby": error ? `${name}-error` : void 0,
|
|
1418
|
-
className: `
|
|
1419
|
-
flex-1 h-2 bg-login-500 rounded-lg appearance-none cursor-pointer
|
|
1420
|
-
accent-login
|
|
1421
|
-
[&::-webkit-slider-thumb]:appearance-none
|
|
1422
|
-
[&::-webkit-slider-thumb]:w-4
|
|
1423
|
-
[&::-webkit-slider-thumb]:h-4
|
|
1424
|
-
[&::-webkit-slider-thumb]:rounded-full
|
|
1425
|
-
[&::-webkit-slider-thumb]:bg-login
|
|
1426
|
-
[&::-moz-range-thumb]:w-4
|
|
1427
|
-
[&::-moz-range-thumb]:h-4
|
|
1428
|
-
[&::-moz-range-thumb]:rounded-full
|
|
1429
|
-
[&::-moz-range-thumb]:bg-login
|
|
1430
|
-
[&::-moz-range-thumb]:border-none
|
|
1431
|
-
disabled:opacity-50 disabled:cursor-not-allowed
|
|
1432
|
-
${error ? "accent-red-500" : ""}
|
|
1433
|
-
`
|
|
1434
|
-
}), showValue && /* @__PURE__ */ jsx("span", {
|
|
1435
|
-
className: "text-login-text text-sm font-medium min-w-10 text-right",
|
|
1436
|
-
children: displayValue
|
|
1437
|
-
})]
|
|
1438
|
-
})
|
|
1439
|
-
});
|
|
1440
|
-
}
|
|
1441
|
-
//#endregion
|
|
1442
|
-
//#region src/components/logo/logo.tsx
|
|
1443
|
-
function Logo({ className }) {
|
|
1444
|
-
const corner = "fill-[var(--foreground)] transition-all duration-1000";
|
|
1445
|
-
const letter = "fill-none stroke-[var(--color-login)] stroke-[3.5px]";
|
|
1446
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
1447
|
-
className: `block w-full max-w-2xl mx-auto ${className || ""}`,
|
|
1448
|
-
viewBox: "0 0 147.02299 59.20511",
|
|
1449
|
-
children: [
|
|
1450
|
-
/* @__PURE__ */ jsx("path", {
|
|
1451
|
-
className: corner,
|
|
1452
|
-
d: "m 28.77713,58.37738 v 0.76465 H 25.531 v -5.61816 h 0.91309 v 4.85351 z"
|
|
1453
|
-
}),
|
|
1454
|
-
/* @__PURE__ */ jsx("path", {
|
|
1455
|
-
className: corner,
|
|
1456
|
-
d: "m 30.47831,59.142 h -0.917 v -5.61813 h 0.917 z"
|
|
1457
|
-
}),
|
|
1458
|
-
/* @__PURE__ */ jsx("path", {
|
|
1459
|
-
className: corner,
|
|
1460
|
-
d: "M 36.46268,53.52387 V 59.142 H 35.99881 A 0.36347,0.36347 0 0 1 35.6785,58.98185 L 32.59256,55.018 c 0.0078,0.07617 0.01368,0.15039 0.01758,0.22461 0.0039,0.07422 0.0059,0.14258 0.0059,0.20508 V 59.142 h -0.80371 v -5.61813 h 0.47656 a 0.71321,0.71321 0 0 1 0.09864,0.0059 0.3128,0.3128 0 0 1 0.07617,0.02148 0.22919,0.22919 0 0 1 0.0664,0.04688 0.63781,0.63781 0 0 1 0.06641,0.07812 l 3.08984,3.96779 c -0.0078,-0.08105 -0.01367,-0.16015 -0.01757,-0.23828 -0.0039,-0.07813 -0.0059,-0.15039 -0.0059,-0.21875 v -3.6631 z"
|
|
1461
|
-
}),
|
|
1462
|
-
/* @__PURE__ */ jsx("path", {
|
|
1463
|
-
className: corner,
|
|
1464
|
-
d: "m 39.84549,57.1684 a 2.91264,2.91264 0 0 1 -0.11523,0.84765 1.748,1.748 0 0 1 -0.34375,0.64063 1.52483,1.52483 0 0 1 -0.56543,0.40527 2.00691,2.00691 0 0 1 -0.78223,0.14258 3.23707,3.23707 0 0 1 -0.40234,-0.0254 3.44454,3.44454 0 0 1 -0.41309,-0.0801 l 0.04688,-0.5459 a 0.2079,0.2079 0 0 1 0.06055,-0.125 0.19754,0.19754 0 0 1 0.14257,-0.0469 0.74035,0.74035 0 0 1 0.18067,0.0293 1.36468,1.36468 0 0 0 0.71387,-0.041 0.74722,0.74722 0 0 0 0.3125,-0.2207 0.9864,0.9864 0 0 0 0.1914,-0.38574 2.19551,2.19551 0 0 0 0.06445,-0.57227 v -3.667 h 0.90918 z"
|
|
1465
|
-
}),
|
|
1466
|
-
/* @__PURE__ */ jsx("path", {
|
|
1467
|
-
className: corner,
|
|
1468
|
-
d: "m 44.6326,58.40473 -0.0039,0.7373 h -3.50391 v -5.61816 h 3.50391 v 0.7373 h -2.58692 v 1.69336 h 2.06739 v 0.71387 h -2.06739 v 1.73633 z"
|
|
1469
|
-
}),
|
|
1470
|
-
/* @__PURE__ */ jsx("path", {
|
|
1471
|
-
className: corner,
|
|
1472
|
-
d: "M 46.53592,54.26117 V 56.06 h 2.19629 v 0.7373 h -2.19629 v 2.3447 h -0.917 v -5.61813 h 3.50391 v 0.7373 z"
|
|
1473
|
-
}),
|
|
1474
|
-
/* @__PURE__ */ jsx("path", {
|
|
1475
|
-
className: corner,
|
|
1476
|
-
d: "m 55.25956,56.33344 a 3.18179,3.18179 0 0 1 -0.20215,1.15039 2.6634,2.6634 0 0 1 -0.57227,0.90722 2.59685,2.59685 0 0 1 -0.88476,0.59473 3.17156,3.17156 0 0 1 -2.29492,0 2.62415,2.62415 0 0 1 -0.88672,-0.59473 2.65327,2.65327 0 0 1 -0.57422,-0.90722 3.37717,3.37717 0 0 1 0,-2.30176 2.67118,2.67118 0 0 1 0.57422,-0.90918 2.61491,2.61491 0 0 1 0.88672,-0.59668 3.1717,3.1717 0 0 1 2.29492,0 2.58781,2.58781 0 0 1 0.88476,0.59668 2.68144,2.68144 0 0 1 0.57227,0.90918 3.1871,3.1871 0 0 1 0.20215,1.15137 z m -0.93164,0 a 2.706,2.706 0 0 0 -0.13086,-0.87012 1.821,1.821 0 0 0 -0.375,-0.65527 1.63008,1.63008 0 0 0 -0.59082,-0.41407 2.16795,2.16795 0 0 0 -1.55664,0 1.65415,1.65415 0 0 0 -0.59278,0.41407 1.84212,1.84212 0 0 0 -0.3789,0.65527 2.92611,2.92611 0 0 0 0,1.74316 1.83766,1.83766 0 0 0 0.3789,0.6543 1.64222,1.64222 0 0 0 0.59278,0.40918 2.19564,2.19564 0 0 0 1.55664,0 1.61838,1.61838 0 0 0 0.59082,-0.40918 1.81652,1.81652 0 0 0 0.375,-0.6543 2.71589,2.71589 0 0 0 0.13086,-0.87304 z"
|
|
1477
|
-
}),
|
|
1478
|
-
/* @__PURE__ */ jsx("path", {
|
|
1479
|
-
className: corner,
|
|
1480
|
-
d: "m 60.534,59.142 h -0.81543 a 0.377,0.377 0 0 1 -0.35156,-0.1875 l -1.31055,-1.8916 a 0.4267,0.4267 0 0 0 -0.14453,-0.14063 0.50286,0.50286 0 0 0 -0.23437,-0.043 H 57.17072 V 59.142 H 56.2576 v -5.61813 h 1.6543 a 3.54427,3.54427 0 0 1 0.9541,0.11328 1.80649,1.80649 0 0 1 0.65723,0.32226 1.25606,1.25606 0 0 1 0.37988,0.501 1.76427,1.76427 0 0 1 0.03516,1.19727 1.50418,1.50418 0 0 1 -0.25293,0.46093 1.61283,1.61283 0 0 1 -0.40821,0.3584 2.04861,2.04861 0 0 1 -0.5498,0.23828 0.92346,0.92346 0 0 1 0.28906,0.28516 z m -2.64551,-2.92578 a 1.763,1.763 0 0 0 0.5459,-0.07617 1.11007,1.11007 0 0 0 0.39063,-0.21289 0.87892,0.87892 0 0 0 0.23437,-0.3252 1.10093,1.10093 0 0 0 0.07715,-0.41992 0.84276,0.84276 0 0 0 -0.30371,-0.70215 1.46527,1.46527 0 0 0 -0.9209,-0.24219 h -0.74121 v 1.97852 z"
|
|
1481
|
-
}),
|
|
1482
|
-
/* @__PURE__ */ jsx("path", {
|
|
1483
|
-
className: corner,
|
|
1484
|
-
d: "m 64.72049,58.40473 -0.0039,0.7373 h -3.50391 v -5.61816 h 3.50391 v 0.7373 h -2.58692 v 1.69336 h 2.06739 v 0.71387 h -2.06739 v 1.73633 z"
|
|
1485
|
-
}),
|
|
1486
|
-
/* @__PURE__ */ jsx("path", {
|
|
1487
|
-
className: corner,
|
|
1488
|
-
d: "M 70.35721,53.52387 V 59.142 H 69.89335 A 0.36347,0.36347 0 0 1 69.57303,58.98185 L 66.4871,55.018 c 0.0078,0.07617 0.01367,0.15039 0.01757,0.22461 0.0039,0.07422 0.0059,0.14258 0.0059,0.20508 V 59.142 h -0.80371 v -5.61813 h 0.47656 a 0.71321,0.71321 0 0 1 0.09864,0.0059 0.3128,0.3128 0 0 1 0.07617,0.02148 0.22936,0.22936 0 0 1 0.06641,0.04688 0.63869,0.63869 0 0 1 0.0664,0.07812 l 3.08985,3.96777 c -0.008,-0.08105 -0.0137,-0.16015 -0.0176,-0.23828 -0.004,-0.07813 -0.006,-0.15039 -0.006,-0.21875 v -3.66308 z"
|
|
1489
|
-
}),
|
|
1490
|
-
/* @__PURE__ */ jsx("path", {
|
|
1491
|
-
className: corner,
|
|
1492
|
-
d: "m 72.6121,59.142 h -0.917 v -5.61813 h 0.917 z"
|
|
1493
|
-
}),
|
|
1494
|
-
/* @__PURE__ */ jsx("path", {
|
|
1495
|
-
className: corner,
|
|
1496
|
-
d: "M 78.59794,53.52387 V 59.142 H 78.13358 A 0.36344,0.36344 0 0 1 77.81327,58.98185 L 74.72733,55.018 c 0.008,0.07617 0.0137,0.15039 0.0176,0.22461 0.004,0.07422 0.006,0.14258 0.006,0.20508 V 59.142 h -0.80371 v -5.61813 h 0.47656 a 0.713,0.713 0 0 1 0.0986,0.0059 0.31254,0.31254 0 0 1 0.0762,0.02148 0.22936,0.22936 0 0 1 0.0664,0.04688 0.63869,0.63869 0 0 1 0.0664,0.07812 l 3.08984,3.96777 c -0.008,-0.08105 -0.0137,-0.16015 -0.0176,-0.23828 -0.004,-0.07813 -0.006,-0.15039 -0.006,-0.21875 v -3.66308 z"
|
|
1497
|
-
}),
|
|
1498
|
-
/* @__PURE__ */ jsx("path", {
|
|
1499
|
-
className: corner,
|
|
1500
|
-
d: "M 84.53544,56.37641 V 58.6 a 3.24425,3.24425 0 0 1 -1.9502,0.60449 3.419,3.419 0 0 1 -1.23535,-0.21289 2.7275,2.7275 0 0 1 -0.94141,-0.59277 2.59231,2.59231 0 0 1 -0.60156,-0.90723 3.08634,3.08634 0 0 1 -0.21,-1.1582 3.23536,3.23536 0 0 1 0.20215,-1.165 2.5484,2.5484 0 0 1 1.49414,-1.498 3.29189,3.29189 0 0 1 1.20215,-0.209 3.52605,3.52605 0 0 1 0.62988,0.05273 3.11559,3.11559 0 0 1 0.54,0.14649 2.535,2.535 0 0 1 0.84668,0.52246 l -0.26074,0.418 a 0.26545,0.26545 0 0 1 -0.16016,0.12109 0.27377,0.27377 0 0 1 -0.21094,-0.04688 c -0.0752,-0.04492 -0.15527,-0.09082 -0.24023,-0.14062 a 2.01137,2.01137 0 0 0 -0.29,-0.13867 2.127,2.127 0 0 0 -0.37891,-0.10547 2.72656,2.72656 0 0 0 -0.50683,-0.041 2.09434,2.09434 0 0 0 -0.80176,0.14649 1.70173,1.70173 0 0 0 -0.61035,0.418 1.84692,1.84692 0 0 0 -0.39063,0.65722 2.5766,2.5766 0 0 0 -0.13672,0.86231 2.62333,2.62333 0 0 0 0.14453,0.89844 1.88731,1.88731 0 0 0 0.41016,0.67187 1.74772,1.74772 0 0 0 0.6416,0.419 2.55647,2.55647 0 0 0 1.459,0.0703 2.80344,2.80344 0 0 0 0.53222,-0.207 V 57.07074 H 82.928 a 0.19287,0.19287 0 0 1 -0.13964,-0.04883 0.16848,0.16848 0 0 1 -0.0508,-0.12695 v -0.51855 z"
|
|
1501
|
-
}),
|
|
1502
|
-
/* @__PURE__ */ jsx("path", {
|
|
1503
|
-
className: corner,
|
|
1504
|
-
d: "m 89.1243,58.40473 -0.004,0.7373 h -3.50391 v -5.61816 h 3.50391 v 0.7373 h -2.58692 v 1.69336 h 2.06739 v 0.71387 h -2.06739 v 1.73633 z"
|
|
1505
|
-
}),
|
|
1506
|
-
/* @__PURE__ */ jsx("path", {
|
|
1507
|
-
className: corner,
|
|
1508
|
-
d: "M 94.761,53.52387 V 59.142 H 94.29713 A 0.36347,0.36347 0 0 1 93.97682,58.98185 L 90.8909,55.018 c 0.008,0.07617 0.0137,0.15039 0.0176,0.22461 0.004,0.07422 0.006,0.14258 0.006,0.20508 V 59.142 h -0.80371 v -5.61813 h 0.47656 a 0.71321,0.71321 0 0 1 0.0986,0.0059 0.3128,0.3128 0 0 1 0.0762,0.02148 0.22919,0.22919 0 0 1 0.0664,0.04688 0.63781,0.63781 0 0 1 0.0664,0.07812 l 3.08984,3.96777 c -0.008,-0.08105 -0.0137,-0.16015 -0.0176,-0.23828 -0.004,-0.07813 -0.006,-0.15039 -0.006,-0.21875 v -3.66308 z"
|
|
1509
|
-
}),
|
|
1510
|
-
/* @__PURE__ */ jsx("path", {
|
|
1511
|
-
className: corner,
|
|
1512
|
-
d: "M 98.95829,54.26117 V 56.06 h 2.19629 v 0.7373 h -2.19629 v 2.3447 h -0.917 v -5.61813 h 3.5039 v 0.7373 z"
|
|
1513
|
-
}),
|
|
1514
|
-
/* @__PURE__ */ jsx("path", {
|
|
1515
|
-
className: corner,
|
|
1516
|
-
d: "m 107.68192,56.33344 a 3.18158,3.18158 0 0 1 -0.20215,1.15039 2.66353,2.66353 0 0 1 -0.57226,0.90722 2.597,2.597 0 0 1 -0.88477,0.59473 3.17156,3.17156 0 0 1 -2.29492,0 2.62415,2.62415 0 0 1 -0.88672,-0.59473 2.65327,2.65327 0 0 1 -0.57422,-0.90722 3.37717,3.37717 0 0 1 0,-2.30176 2.67118,2.67118 0 0 1 0.57422,-0.90918 2.61491,2.61491 0 0 1 0.88672,-0.59668 3.1717,3.1717 0 0 1 2.29492,0 2.588,2.588 0 0 1 0.88477,0.59668 2.68157,2.68157 0 0 1 0.57226,0.90918 3.18689,3.18689 0 0 1 0.20215,1.15137 z m -0.93164,0 a 2.706,2.706 0 0 0 -0.13086,-0.87012 1.82066,1.82066 0 0 0 -0.375,-0.65527 1.63,1.63 0 0 0 -0.59082,-0.41407 2.16795,2.16795 0 0 0 -1.55664,0 1.65411,1.65411 0 0 0 -0.59277,0.41407 1.84214,1.84214 0 0 0 -0.37891,0.65527 2.92632,2.92632 0 0 0 0,1.74316 1.83768,1.83768 0 0 0 0.37891,0.6543 1.64218,1.64218 0 0 0 0.59277,0.40918 2.19564,2.19564 0 0 0 1.55664,0 1.61829,1.61829 0 0 0 0.59082,-0.40918 1.81623,1.81623 0 0 0 0.375,-0.6543 2.71589,2.71589 0 0 0 0.13086,-0.87304 z"
|
|
1517
|
-
}),
|
|
1518
|
-
/* @__PURE__ */ jsx("path", {
|
|
1519
|
-
className: corner,
|
|
1520
|
-
d: "m 112.95731,59.142 h -0.81543 a 0.377,0.377 0 0 1 -0.35156,-0.1875 l -1.31055,-1.8916 a 0.4267,0.4267 0 0 0 -0.14453,-0.14063 0.50286,0.50286 0 0 0 -0.23437,-0.043 H 109.594 V 59.142 h -0.91309 v -5.61813 h 1.6543 a 3.54427,3.54427 0 0 1 0.9541,0.11328 1.80649,1.80649 0 0 1 0.65723,0.32226 1.25606,1.25606 0 0 1 0.37988,0.501 1.76427,1.76427 0 0 1 0.0352,1.19727 1.50418,1.50418 0 0 1 -0.25293,0.46093 1.61283,1.61283 0 0 1 -0.40821,0.3584 2.04861,2.04861 0 0 1 -0.5498,0.23828 0.92346,0.92346 0 0 1 0.28906,0.28516 z m -2.64551,-2.92578 a 1.763,1.763 0 0 0 0.5459,-0.07617 1.11007,1.11007 0 0 0 0.39063,-0.21289 0.87892,0.87892 0 0 0 0.23437,-0.3252 1.10093,1.10093 0 0 0 0.0772,-0.41992 0.84276,0.84276 0 0 0 -0.30371,-0.70215 1.46527,1.46527 0 0 0 -0.9209,-0.24219 H 109.594 v 1.97852 z"
|
|
1521
|
-
}),
|
|
1522
|
-
/* @__PURE__ */ jsx("path", {
|
|
1523
|
-
className: corner,
|
|
1524
|
-
d: "m 116.4954,59.142 h -0.917 v -5.61813 h 0.917 z"
|
|
1525
|
-
}),
|
|
1526
|
-
/* @__PURE__ */ jsx("path", {
|
|
1527
|
-
className: corner,
|
|
1528
|
-
d: "m 121.69559,54.28461 h -1.75195 V 59.142 h -0.9082 v -4.85739 h -1.75586 v -0.76074 h 4.416 z"
|
|
1529
|
-
}),
|
|
1530
|
-
/* @__PURE__ */ jsx("polyline", {
|
|
1531
|
-
className: letter,
|
|
1532
|
-
style: { strokeMiterlimit: 10 },
|
|
1533
|
-
points: "47.871 98.1 33.189 98.1 33.189 83.418",
|
|
1534
|
-
transform: "translate(-31.392,-41.894)"
|
|
1535
|
-
}),
|
|
1536
|
-
/* @__PURE__ */ jsx("polyline", {
|
|
1537
|
-
className: letter,
|
|
1538
|
-
style: { strokeMiterlimit: 10 },
|
|
1539
|
-
points: "33.142 58.326 33.142 43.644 47.824 43.644",
|
|
1540
|
-
transform: "translate(-31.392,-41.894)"
|
|
1541
|
-
}),
|
|
1542
|
-
/* @__PURE__ */ jsx("polyline", {
|
|
1543
|
-
className: letter,
|
|
1544
|
-
style: { strokeMiterlimit: 10 },
|
|
1545
|
-
points: "161.983 98.122 176.665 98.122 176.665 83.44",
|
|
1546
|
-
transform: "translate(-31.392,-41.894)"
|
|
1547
|
-
}),
|
|
1548
|
-
/* @__PURE__ */ jsx("polyline", {
|
|
1549
|
-
className: letter,
|
|
1550
|
-
style: { strokeMiterlimit: 10 },
|
|
1551
|
-
points: "176.665 58.372 176.665 43.69 161.983 43.69",
|
|
1552
|
-
transform: "translate(-31.392,-41.894)"
|
|
1553
|
-
}),
|
|
1554
|
-
/* @__PURE__ */ jsx("path", {
|
|
1555
|
-
className: corner,
|
|
1556
|
-
d: "m 30.02449,40.19351 v 4.12842 H 12.4991 V 13.99038 h 4.92871 v 26.20313 z"
|
|
1557
|
-
}),
|
|
1558
|
-
/* @__PURE__ */ jsx("path", {
|
|
1559
|
-
className: corner,
|
|
1560
|
-
d: "m 61.53523,29.1564 a 17.15942,17.15942 0 0 1 -1.09473,6.21338 14.35971,14.35971 0 0 1 -3.08593,4.89746 14.091,14.091 0 0 1 -4.78125,3.21191 17.1289,17.1289 0 0 1 -12.38575,0 13.98317,13.98317 0 0 1 -7.88867,-8.10937 18.18161,18.18161 0 0 1 0,-12.42725 14.39119,14.39119 0 0 1 3.09668,-4.90771 14.13157,14.13157 0 0 1 4.792,-3.22315 17.13565,17.13565 0 0 1 12.38575,0 14.02046,14.02046 0 0 1 4.78125,3.22315 14.47032,14.47032 0 0 1 3.08593,4.90771 17.16209,17.16209 0 0 1 1.09472,6.21387 z m -5.03418,0 a 14.62587,14.62587 0 0 0 -0.70508,-4.69727 9.9446,9.9446 0 0 0 -2.02246,-3.53906 8.80545,8.80545 0 0 0 -3.1914,-2.23242 11.719,11.719 0 0 0 -8.4043,0 8.90077,8.90077 0 0 0 -3.20117,2.23242 9.96735,9.96735 0 0 0 -2.043,3.53906 15.81644,15.81644 0 0 0 0,9.415 9.847,9.847 0 0 0 2.043,3.52832 8.85094,8.85094 0 0 0 3.20117,2.21192 11.87213,11.87213 0 0 0 8.4043,0 8.75623,8.75623 0 0 0 3.1914,-2.21192 9.82454,9.82454 0 0 0 2.02249,-3.52828 14.69371,14.69371 0 0 0 0.70505,-4.71777 z"
|
|
1561
|
-
}),
|
|
1562
|
-
/* @__PURE__ */ jsx("path", {
|
|
1563
|
-
className: corner,
|
|
1564
|
-
d: "m 91.76082,29.38784 v 12.00635 a 17.5354,17.5354 0 0 1 -10.53125,3.26465 18.41512,18.41512 0 0 1 -6.667,-1.148 14.80254,14.80254 0 0 1 -5.08691,-3.20166 14.0148,14.0148 0 0 1 -3.24316,-4.897 16.691,16.691 0 0 1 -1.1377,-6.25586 17.42935,17.42935 0 0 1 1.09473,-6.2876 13.74023,13.74023 0 0 1 8.06738,-8.08838 17.7222,17.7222 0 0 1 6.48828,-1.127 19.10354,19.10354 0 0 1 3.40137,0.28418 16.85244,16.85244 0 0 1 2.917,0.79 13.68442,13.68442 0 0 1 2.48633,1.22168 13.95372,13.95372 0 0 1 2.085,1.60058 l -1.41113,2.25391 a 1.40229,1.40229 0 0 1 -0.86426,0.65283 1.47784,1.47784 0 0 1 -1.13672,-0.25244 q -0.6123,-0.35816 -1.2959,-0.7583 a 11.33129,11.33129 0 0 0 -1.56933,-0.748 11.53387,11.53387 0 0 0 -2.043,-0.56836 14.78335,14.78335 0 0 0 -2.73828,-0.22119 11.32128,11.32128 0 0 0 -4.32813,0.78955 9.26752,9.26752 0 0 0 -3.29687,2.25391 9.99164,9.99164 0 0 0 -2.10645,3.54931 13.90267,13.90267 0 0 0 -0.7373,4.65528 14.11731,14.11731 0 0 0 0.77929,4.855 10.1425,10.1425 0 0 0 2.21192,3.62305 9.43419,9.43419 0 0 0 3.46484,2.26416 13.81975,13.81975 0 0 0 7.87793,0.3789 15.14816,15.14816 0 0 0 2.875,-1.11621 v -6.02383 h -4.2334 a 1.04883,1.04883 0 0 1 -0.75879,-0.26367 0.90553,0.90553 0 0 1 -0.27343,-0.68457 v -2.80127 z"
|
|
1565
|
-
}),
|
|
1566
|
-
/* @__PURE__ */ jsx("path", {
|
|
1567
|
-
className: corner,
|
|
1568
|
-
d: "M 102.546,44.32193 H 97.59581 V 13.99038 h 4.95019 z"
|
|
1569
|
-
}),
|
|
1570
|
-
/* @__PURE__ */ jsx("path", {
|
|
1571
|
-
className: corner,
|
|
1572
|
-
d: "m 134.8575,13.99038 v 30.33155 h -2.50684 a 2.14219,2.14219 0 0 1 -0.96875,-0.2002 2.26108,2.26108 0 0 1 -0.75879,-0.66357 L 113.962,22.05777 q 0.063,0.61083 0.0947,1.21093 0.0322,0.60058 0.0322,1.106 v 19.94723 h -4.3398 V 13.99038 h 2.57031 a 3.89092,3.89092 0 0 1 0.53711,0.03174 1.53328,1.53328 0 0 1 0.41016,0.11572 1.18964,1.18964 0 0 1 0.35839,0.25293 4.01792,4.01792 0 0 1 0.3584,0.4209 l 16.68164,21.42188 q -0.063,-0.65259 -0.0947,-1.28467 -0.0308,-0.63208 -0.0312,-1.17969 V 13.99038 Z"
|
|
1573
|
-
})
|
|
1574
|
-
]
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
//#endregion
|
|
1578
|
-
//#region src/components/logo/logoSmall.tsx
|
|
1579
|
-
function LogoSmall() {
|
|
1580
|
-
const corner = "fill-login";
|
|
1581
|
-
const letter = "fill-[var(--foreground)] transition-all duration-1000";
|
|
1582
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
1583
|
-
className: "block h-full",
|
|
1584
|
-
viewBox: "0 0 100 100",
|
|
1585
|
-
fill: "none",
|
|
1586
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1587
|
-
children: [
|
|
1588
|
-
/* @__PURE__ */ jsx("path", {
|
|
1589
|
-
className: corner,
|
|
1590
|
-
d: "M0 0H6.6667V28.3333H0V0Z"
|
|
1591
|
-
}),
|
|
1592
|
-
/* @__PURE__ */ jsx("path", {
|
|
1593
|
-
className: corner,
|
|
1594
|
-
d: "M28.3333 0V6.6667H0V0H28.3333Z"
|
|
1595
|
-
}),
|
|
1596
|
-
/* @__PURE__ */ jsx("path", {
|
|
1597
|
-
className: corner,
|
|
1598
|
-
d: "M100 0V6.6667H71.6667V0H100Z"
|
|
1599
|
-
}),
|
|
1600
|
-
/* @__PURE__ */ jsx("path", {
|
|
1601
|
-
className: corner,
|
|
1602
|
-
d: "M100 28.3333H93.3333V0H100V28.3333Z"
|
|
1603
|
-
}),
|
|
1604
|
-
/* @__PURE__ */ jsx("path", {
|
|
1605
|
-
className: corner,
|
|
1606
|
-
d: "M0 100V93.3333H28.3333V100H0Z"
|
|
1607
|
-
}),
|
|
1608
|
-
/* @__PURE__ */ jsx("path", {
|
|
1609
|
-
className: corner,
|
|
1610
|
-
d: "M0 71.6667H6.6667V100H0V71.6667Z"
|
|
1611
|
-
}),
|
|
1612
|
-
/* @__PURE__ */ jsx("path", {
|
|
1613
|
-
className: corner,
|
|
1614
|
-
d: "M100 100H93.3333V71.6667H100V100Z"
|
|
1615
|
-
}),
|
|
1616
|
-
/* @__PURE__ */ jsx("path", {
|
|
1617
|
-
className: corner,
|
|
1618
|
-
d: "M71.6667 100V93.3333H100V100H71.6667Z"
|
|
1619
|
-
}),
|
|
1620
|
-
/* @__PURE__ */ jsx("path", {
|
|
1621
|
-
className: letter,
|
|
1622
|
-
d: "M31.6667 18.3333H43.3334V81.6666H31.6667V18.3333Z"
|
|
1623
|
-
}),
|
|
1624
|
-
/* @__PURE__ */ jsx("path", {
|
|
1625
|
-
className: letter,
|
|
1626
|
-
d: "M31.6667 70H68.3334V81.6667H31.6667V70Z"
|
|
1627
|
-
})
|
|
1628
|
-
]
|
|
1629
|
-
});
|
|
1630
|
-
}
|
|
1631
|
-
//#endregion
|
|
1632
|
-
//#region src/components/toggle/theme.tsx
|
|
1633
|
-
function ThemeToggle({ className }) {
|
|
1634
|
-
const router = useRouter();
|
|
1635
|
-
const [theme, setTheme] = useState("dark");
|
|
1636
|
-
useEffect(() => {
|
|
1637
|
-
const savedTheme = getCookie("theme");
|
|
1638
|
-
if (savedTheme) setTheme(savedTheme);
|
|
1639
|
-
document.documentElement.classList.remove("dark", "light");
|
|
1640
|
-
document.documentElement.classList.add(theme);
|
|
1641
|
-
}, [theme]);
|
|
1642
|
-
function toggleTheme() {
|
|
1643
|
-
const newTheme = theme === "dark" ? "light" : "dark";
|
|
1644
|
-
setCookie("theme", newTheme);
|
|
1645
|
-
setTheme(newTheme);
|
|
1646
|
-
router.refresh();
|
|
1647
|
-
}
|
|
1648
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1649
|
-
className: `grid place-items-center justify-end rounded-md hover:bg-login-300/20 w-fit ${className}`,
|
|
1650
|
-
children: /* @__PURE__ */ jsxs("label", {
|
|
1651
|
-
className: "cursor-pointer",
|
|
1652
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
1653
|
-
type: "checkbox",
|
|
1654
|
-
checked: theme === "light",
|
|
1655
|
-
onChange: toggleTheme,
|
|
1656
|
-
className: "sr-only"
|
|
1657
|
-
}), /* @__PURE__ */ jsx(ThemeIcon, { theme })]
|
|
1658
|
-
})
|
|
1659
|
-
});
|
|
1660
|
-
}
|
|
1661
|
-
function ThemeIcon({ theme }) {
|
|
1662
|
-
const sunrayClass = `fill-white transition-opacity duration-400 ${theme === "light" ? "opacity-0" : "opacity-100"}`;
|
|
1663
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
1664
|
-
className: "h-12 p-3",
|
|
1665
|
-
viewBox: "0 0 100 100",
|
|
1666
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1667
|
-
children: [
|
|
1668
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", {
|
|
1669
|
-
id: "theme-toggle_clip-path",
|
|
1670
|
-
children: [/* @__PURE__ */ jsx("rect", {
|
|
1671
|
-
x: "0",
|
|
1672
|
-
y: "0",
|
|
1673
|
-
width: "100",
|
|
1674
|
-
height: "100",
|
|
1675
|
-
fill: "white"
|
|
1676
|
-
}), /* @__PURE__ */ jsx("circle", {
|
|
1677
|
-
className: `transition-transform duration-400 ${theme === "dark" ? "translate-x-8 -translate-y-4" : ""}`,
|
|
1678
|
-
cx: "68",
|
|
1679
|
-
cy: "40",
|
|
1680
|
-
r: "18"
|
|
1681
|
-
})]
|
|
1682
|
-
}) }),
|
|
1683
|
-
/* @__PURE__ */ jsx("circle", {
|
|
1684
|
-
className: `origin-center transition-all duration-400 ${theme === "light" ? "scale-[1.9] fill-black" : "scale-100 fill-white"}`,
|
|
1685
|
-
mask: "url(#theme-toggle_clip-path)",
|
|
1686
|
-
cx: "50",
|
|
1687
|
-
cy: "50",
|
|
1688
|
-
r: "23"
|
|
1689
|
-
}),
|
|
1690
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1691
|
-
className: sunrayClass,
|
|
1692
|
-
x: "86",
|
|
1693
|
-
y: "47",
|
|
1694
|
-
width: "14",
|
|
1695
|
-
height: "6",
|
|
1696
|
-
rx: "3"
|
|
1697
|
-
}),
|
|
1698
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1699
|
-
className: sunrayClass,
|
|
1700
|
-
y: "47",
|
|
1701
|
-
width: "14",
|
|
1702
|
-
height: "6",
|
|
1703
|
-
rx: "3"
|
|
1704
|
-
}),
|
|
1705
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1706
|
-
className: sunrayClass,
|
|
1707
|
-
x: "47",
|
|
1708
|
-
y: "86",
|
|
1709
|
-
width: "6",
|
|
1710
|
-
height: "14",
|
|
1711
|
-
rx: "3"
|
|
1712
|
-
}),
|
|
1713
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1714
|
-
className: sunrayClass,
|
|
1715
|
-
x: "75",
|
|
1716
|
-
y: "75",
|
|
1717
|
-
width: "6",
|
|
1718
|
-
height: "14",
|
|
1719
|
-
rx: "3",
|
|
1720
|
-
transform: "rotate(-45 78 78)"
|
|
1721
|
-
}),
|
|
1722
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1723
|
-
className: sunrayClass,
|
|
1724
|
-
x: "84.8995",
|
|
1725
|
-
y: "12",
|
|
1726
|
-
width: "6",
|
|
1727
|
-
height: "14",
|
|
1728
|
-
rx: "3",
|
|
1729
|
-
transform: "rotate(45 84.8995 12)"
|
|
1730
|
-
}),
|
|
1731
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1732
|
-
className: sunrayClass,
|
|
1733
|
-
x: "22.8995",
|
|
1734
|
-
y: "74",
|
|
1735
|
-
width: "6",
|
|
1736
|
-
height: "14",
|
|
1737
|
-
rx: "3",
|
|
1738
|
-
transform: "rotate(45 22.8995 74)"
|
|
1739
|
-
}),
|
|
1740
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1741
|
-
className: sunrayClass,
|
|
1742
|
-
x: "13",
|
|
1743
|
-
y: "16.2426",
|
|
1744
|
-
width: "6",
|
|
1745
|
-
height: "14",
|
|
1746
|
-
rx: "3",
|
|
1747
|
-
transform: "rotate(-45 13 16.2426)"
|
|
1748
|
-
}),
|
|
1749
|
-
/* @__PURE__ */ jsx("rect", {
|
|
1750
|
-
className: sunrayClass,
|
|
1751
|
-
x: "47",
|
|
1752
|
-
y: "0",
|
|
1753
|
-
width: "6",
|
|
1754
|
-
height: "14",
|
|
1755
|
-
rx: "3"
|
|
1756
|
-
})
|
|
1757
|
-
]
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
//#endregion
|
|
1761
|
-
//#region src/components/toggle/language.tsx
|
|
1762
|
-
function LanguageToggle({ language }) {
|
|
1763
|
-
const [lang, setLang] = useState(language || "en");
|
|
1764
|
-
const [jump, setJump] = useState(false);
|
|
1765
|
-
const router = useRouter();
|
|
1766
|
-
useEffect(() => {
|
|
1767
|
-
const savedLang = getCookie("lang");
|
|
1768
|
-
if (savedLang) setLang(savedLang);
|
|
1769
|
-
}, []);
|
|
1770
|
-
function handleClick() {
|
|
1771
|
-
const newLang = lang === "no" ? "en" : "no";
|
|
1772
|
-
setCookie("lang", newLang);
|
|
1773
|
-
setLang(newLang);
|
|
1774
|
-
language = newLang;
|
|
1775
|
-
setJump(true);
|
|
1776
|
-
setTimeout(() => setJump(false), 400);
|
|
1777
|
-
router.refresh();
|
|
1778
|
-
}
|
|
1779
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
1780
|
-
value: lang,
|
|
1781
|
-
onClick: handleClick,
|
|
1782
|
-
className: `cursor-pointer p-2 leading-8 text-base w-[4.3rem] text-center rounded
|
|
1783
|
-
bg-transparent border-none hover:bg-gray-400/10 flex flex-row items-center justify-center gap-1`,
|
|
1784
|
-
children: [/* @__PURE__ */ jsx(Globe, { className: `text-xl leading-8 -mt-0.5 ${jump ? "animate-jump" : ""}` }), " " + lang]
|
|
1785
|
-
});
|
|
1786
|
-
}
|
|
1787
|
-
//#endregion
|
|
1788
|
-
//#region src/components/navbar/bubble.tsx
|
|
1789
|
-
function Bubble({ bubble }) {
|
|
1790
|
-
if (bubble.hide) return null;
|
|
1791
|
-
return /* @__PURE__ */ jsxs("a", {
|
|
1792
|
-
href: bubble.href,
|
|
1793
|
-
className: `absolute top-13 min-w-40 ${bubble.className}`,
|
|
1794
|
-
children: [/* @__PURE__ */ jsxs("svg", {
|
|
1795
|
-
viewBox: "0 0 24 12",
|
|
1796
|
-
className: "absolute -top-3 h-3 w-6",
|
|
1797
|
-
"aria-hidden": "true",
|
|
1798
|
-
children: [/* @__PURE__ */ jsx("path", {
|
|
1799
|
-
d: "M12 0 24 12H0Z",
|
|
1800
|
-
fill: bubble.fill,
|
|
1801
|
-
stroke: bubble.stroke,
|
|
1802
|
-
strokeWidth: "1.5",
|
|
1803
|
-
strokeLinejoin: "round"
|
|
1804
|
-
}), /* @__PURE__ */ jsx("path", {
|
|
1805
|
-
d: "M12 0 24 12H0Z",
|
|
1806
|
-
fill: bubble.fill
|
|
1807
|
-
})]
|
|
1808
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1809
|
-
className: "flex justify-between",
|
|
1810
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1811
|
-
className: "min-w-40",
|
|
1812
|
-
children: bubble.text
|
|
1813
|
-
}), /* @__PURE__ */ jsx(X, {
|
|
1814
|
-
onClick: bubble.handleHide,
|
|
1815
|
-
className: bubble.x
|
|
1816
|
-
})]
|
|
1817
|
-
})]
|
|
1818
|
-
});
|
|
1819
|
-
}
|
|
1820
|
-
//#endregion
|
|
1821
|
-
//#region src/components/navbar/navbar.tsx
|
|
1822
|
-
function Navbar({ children, bubble, className, disableLanguageToggle, disableThemeToggle, innerClassName, lang, loginPath, logoutPath, onlyLogo, profilePath, token }) {
|
|
1823
|
-
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
1824
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1825
|
-
className: `${isMobileMenuOpen ? "bg-[#181818f0]" : "bg-[#18181899]"} backdrop-blur-xl fixed top-0 z-900 w-full ${className}`,
|
|
1826
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1827
|
-
className: `flex w-full max-w-6xl m-auto p-2 transition duration-500 800px:justify-between 800px:p-4 ${isMobileMenuOpen ? "h-screen bg-login-900/20 800px:h-20" : ""} ${innerClassName}
|
|
1828
|
-
`,
|
|
1829
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
1830
|
-
className: "block h-12 p-1 800px:p-0",
|
|
1831
|
-
children: /* @__PURE__ */ jsx(Link, {
|
|
1832
|
-
href: "/",
|
|
1833
|
-
onClick: () => setIsMobileMenuOpen(false),
|
|
1834
|
-
children: /* @__PURE__ */ jsx(LogoSmall, {})
|
|
1835
|
-
})
|
|
1836
|
-
}), onlyLogo ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1837
|
-
/* @__PURE__ */ jsx("nav", {
|
|
1838
|
-
className: "hidden 800px:flex 800px:justify-between 800px:items-center 800px:w-fill max-w-200",
|
|
1839
|
-
children
|
|
1840
|
-
}),
|
|
1841
|
-
/* @__PURE__ */ jsxs("nav", {
|
|
1842
|
-
className: "flex w-[calc(100vw-8rem)] justify-end h-12 800px:w-fit",
|
|
1843
|
-
children: [
|
|
1844
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1845
|
-
className: "relative grid gap-2",
|
|
1846
|
-
children: [!disableThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, {}), bubble?.theme?.condition && /* @__PURE__ */ jsx(Bubble, { bubble: bubble.theme })]
|
|
1847
|
-
}),
|
|
1848
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1849
|
-
className: "relative grid gap-2",
|
|
1850
|
-
children: [!disableLanguageToggle && /* @__PURE__ */ jsx(LanguageToggle, { language: lang }), bubble?.lang?.condition && /* @__PURE__ */ jsx(Bubble, { bubble: bubble.lang })]
|
|
1851
|
-
}),
|
|
1852
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1853
|
-
className: "relative grid gap-2",
|
|
1854
|
-
children: [loginPath && logoutPath && /* @__PURE__ */ jsx(AuthButton, {
|
|
1855
|
-
profilePath,
|
|
1856
|
-
token,
|
|
1857
|
-
loginPath,
|
|
1858
|
-
logoutPath
|
|
1859
|
-
}), bubble?.login?.condition && /* @__PURE__ */ jsx(Bubble, { bubble: bubble.login })]
|
|
1860
|
-
})
|
|
1861
|
-
]
|
|
1862
|
-
}),
|
|
1863
|
-
/* @__PURE__ */ jsxs("button", {
|
|
1864
|
-
className: "w-12 h-12 relative cursor-pointer bg-none border-none 800px:hidden",
|
|
1865
|
-
onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen),
|
|
1866
|
-
children: [/* @__PURE__ */ jsx("div", { className: hamburgerStyle(isMobileMenuOpen) }), /* @__PURE__ */ jsx("div", { className: hamburgerStyle(isMobileMenuOpen, true) })]
|
|
1867
|
-
}),
|
|
1868
|
-
/* @__PURE__ */ jsx("nav", {
|
|
1869
|
-
className: `fixed top-16 w-[calc(100%-2rem)] max-w-140 mx-auto left-0 right-0 800px:hidden
|
|
1870
|
-
transition-all duration-500 ease-in-out overflow-hidden
|
|
1871
|
-
${isMobileMenuOpen ? "max-h-[calc(100vh-4rem)] opacity-100" : "max-h-0 opacity-0"}`,
|
|
1872
|
-
onClick: () => setIsMobileMenuOpen(false),
|
|
1873
|
-
children: React.Children.map(children, (child, index) => /* @__PURE__ */ jsx("div", {
|
|
1874
|
-
className: `transition-all duration-500 ease-out ${isMobileMenuOpen ? "opacity-100 transform translate-y-0" : "opacity-0 transform -translate-y-4"}`,
|
|
1875
|
-
style: { transitionDelay: isMobileMenuOpen ? `${index * 80}ms` : "0ms" },
|
|
1876
|
-
children: child
|
|
1877
|
-
}, index))
|
|
1878
|
-
})
|
|
1879
|
-
] })]
|
|
1880
|
-
})
|
|
1881
|
-
});
|
|
1882
|
-
}
|
|
1883
|
-
function AuthButton({ profilePath, logoutPath, loginPath, token }) {
|
|
1884
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1885
|
-
className: "rounded-[0.3rem] hover:bg-login-300/20 h-12 w-12",
|
|
1886
|
-
children: token ? /* @__PURE__ */ jsxs(Fragment, { children: [logoutPath && /* @__PURE__ */ jsx(Link, {
|
|
1887
|
-
href: logoutPath,
|
|
1888
|
-
prefetch: false,
|
|
1889
|
-
onClick: (e) => {
|
|
1890
|
-
e.preventDefault();
|
|
1891
|
-
window.location.href = logoutPath;
|
|
1892
|
-
},
|
|
1893
|
-
className: "grid items-center justify-center h-full w-full",
|
|
1894
|
-
children: /* @__PURE__ */ jsx(LogOut, { size: 24 })
|
|
1895
|
-
}), profilePath && /* @__PURE__ */ jsx(Link, {
|
|
1896
|
-
href: profilePath,
|
|
1897
|
-
className: "grid items-center justify-center h-full w-full",
|
|
1898
|
-
children: /* @__PURE__ */ jsx(User, { size: 24 })
|
|
1899
|
-
})] }) : /* @__PURE__ */ jsx(Link, {
|
|
1900
|
-
href: loginPath,
|
|
1901
|
-
className: "grid items-center justify-center h-full w-full",
|
|
1902
|
-
children: /* @__PURE__ */ jsx(User, { size: 24 })
|
|
1903
|
-
})
|
|
1904
|
-
});
|
|
1905
|
-
}
|
|
1906
|
-
function hamburgerStyle(isOpen, isSecond) {
|
|
1907
|
-
return `bg-login-50 h-0.5 absolute w-8 transition-all duration-[400ms] left-2 ${isOpen ? `top-6 ${isSecond ? "rotate-45" : "-rotate-45"}` : isSecond ? "top-7" : "top-4"}`;
|
|
1908
|
-
}
|
|
1909
|
-
//#endregion
|
|
1910
|
-
//#region src/components/navbar/navbarItem.tsx
|
|
1911
|
-
const commonStyling = "list-none flex no-underline items-center gap-2 whitespace-nowrap cursor-pointer";
|
|
1912
|
-
function NavItem({ href, children, external = false, target, rel, title, icon }) {
|
|
1913
|
-
const linkProps = {
|
|
1914
|
-
href,
|
|
1915
|
-
target,
|
|
1916
|
-
rel,
|
|
1917
|
-
title
|
|
1918
|
-
};
|
|
1919
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Link, {
|
|
1920
|
-
...linkProps,
|
|
1921
|
-
className: "hidden 800px:flex",
|
|
1922
|
-
children: /* @__PURE__ */ jsxs("li", {
|
|
1923
|
-
className: `${commonStyling} text-base leading-4 p-3 font-bold transition-colors link-corner-hover
|
|
1924
|
-
group-[.dropdown]:p-2.5 group-[.dropdown]:pr-3 group-[.dropdown]:pl-1`,
|
|
1925
|
-
children: [
|
|
1926
|
-
icon,
|
|
1927
|
-
children,
|
|
1928
|
-
external && /* @__PURE__ */ jsx(ArrowUpRight, { className: "w-6 h-6 stroke-login" })
|
|
1929
|
-
]
|
|
1930
|
-
})
|
|
1931
|
-
}), /* @__PURE__ */ jsx(Link, {
|
|
1932
|
-
...linkProps,
|
|
1933
|
-
className: "800px:hidden",
|
|
1934
|
-
children: /* @__PURE__ */ jsxs("li", {
|
|
1935
|
-
className: `${commonStyling} text-2xl leading-6 overflow-hidden w-auto pl-4 rounded-[0.3rem] transition-all
|
|
1936
|
-
duration-600 opacity-100 h-16 py-5 group-[.dropdown]:p-0 group-[.dropdown]:text-lg group-[.dropdown]:h-auto
|
|
1937
|
-
group-[.dropdown]:py-2.5 group-[.dropdown]:pl-4`,
|
|
1938
|
-
children: [children, external && /* @__PURE__ */ jsx(ArrowUpRight, { className: "w-6 h-6 stroke-login" })]
|
|
1939
|
-
})
|
|
1940
|
-
})] });
|
|
1941
|
-
}
|
|
1942
|
-
//#endregion
|
|
1943
|
-
//#region src/components/navbar/navbarDropdown.tsx
|
|
1944
|
-
function NavDropdown({ children, title, className }) {
|
|
1945
|
-
const [isMobileDropdownOpen, setIsMobileDropdownOpen] = useState(false);
|
|
1946
|
-
const [isDesktopOpen, setIsDesktopOpen] = useState(false);
|
|
1947
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
1948
|
-
className: "relative hidden 800px:block",
|
|
1949
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1950
|
-
className: "outline-none",
|
|
1951
|
-
tabIndex: 0,
|
|
1952
|
-
ref: useRef(null),
|
|
1953
|
-
onMouseEnter: () => setIsDesktopOpen(true),
|
|
1954
|
-
onMouseLeave: () => setIsDesktopOpen(false),
|
|
1955
|
-
onFocus: () => setIsDesktopOpen(true),
|
|
1956
|
-
onBlur: () => setIsDesktopOpen(false),
|
|
1957
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1958
|
-
className: `list-none no-underline text-base leading-4 p-3 font-bold cursor-pointer flex flex-row items-center
|
|
1959
|
-
transition-colors`,
|
|
1960
|
-
children: [title, /* @__PURE__ */ jsx(ChevronDown, { className: "w-6 h-6 stroke-login ml-1 text-2xl transition-transform duration-300 ease-in-out" })]
|
|
1961
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1962
|
-
className: `absolute pt-2 -ml-4 transition-all duration-200 ease-in-out z-10 ${isDesktopOpen ? "opacity-100 pointer-events-auto translate-y-0" : "opacity-0 pointer-events-none -translate-y-4"}`,
|
|
1963
|
-
children: /* @__PURE__ */ jsx("ul", {
|
|
1964
|
-
className: `p-3 px-6 pb-4 rounded-[0.4rem] shadow-[0_0.1rem_0.5rem_rgba(3,3,3,0.5)] bg-login-700/98 ${className || ""}`,
|
|
1965
|
-
onClick: () => setIsDesktopOpen(false),
|
|
1966
|
-
children: React.Children.map(children, (child, index) => /* @__PURE__ */ jsx("div", {
|
|
1967
|
-
onClick: () => setIsDesktopOpen(false),
|
|
1968
|
-
className: "group dropdown",
|
|
1969
|
-
children: child
|
|
1970
|
-
}, index))
|
|
1971
|
-
})
|
|
1972
|
-
})]
|
|
1973
|
-
})
|
|
1974
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1975
|
-
className: "block 800px:hidden!",
|
|
1976
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
1977
|
-
className: "bg-none border-none cursor-pointer w-full text-left",
|
|
1978
|
-
onClick: (e) => {
|
|
1979
|
-
e.stopPropagation();
|
|
1980
|
-
setIsMobileDropdownOpen(!isMobileDropdownOpen);
|
|
1981
|
-
},
|
|
1982
|
-
children: /* @__PURE__ */ jsxs("li", {
|
|
1983
|
-
className: `list-none no-underline text-2xl leading-6 overflow-hidden
|
|
1984
|
-
w-full pl-4 pr-4 rounded-[0.3rem] transition-all duration-600
|
|
1985
|
-
flex items-center gap-2 opacity-100 min-h-16 py-5 `,
|
|
1986
|
-
children: [/* @__PURE__ */ jsx("span", { children: title }), /* @__PURE__ */ jsx(ChevronDown, { className: `w-6 h-6 transition-transform duration-400 shrink-0
|
|
1987
|
-
${isMobileDropdownOpen ? "rotate-180" : ""}` })]
|
|
1988
|
-
})
|
|
1989
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1990
|
-
className: `list-none no-underline text-xl px-6 ${isMobileDropdownOpen ? "pb-4" : ""}`,
|
|
1991
|
-
children: React.Children.map(children, (child, index) => /* @__PURE__ */ jsx("div", {
|
|
1992
|
-
className: `leading-6 transition-all duration-500 group dropdown
|
|
1993
|
-
${isMobileDropdownOpen ? "h-11 opacity-100" : "h-0 opacity-0"}
|
|
1994
|
-
`,
|
|
1995
|
-
children: child
|
|
1996
|
-
}, index))
|
|
1997
|
-
})]
|
|
1998
|
-
})] });
|
|
1999
|
-
}
|
|
2000
|
-
//#endregion
|
|
2001
|
-
//#region src/components/version/version.tsx
|
|
2002
|
-
function VersionTag({ version, url, className }) {
|
|
2003
|
-
if (!version) return;
|
|
2004
|
-
const style = `w-fit bg-login-700 text-login-100 border border-login-500/40 text-xs font-mono px-2 py-0.5 rounded ${className || ""}`;
|
|
2005
|
-
if (url) return /* @__PURE__ */ jsxs(Link, {
|
|
2006
|
-
className: style,
|
|
2007
|
-
target: "_blank",
|
|
2008
|
-
href: url,
|
|
2009
|
-
children: ["v", version]
|
|
2010
|
-
});
|
|
2011
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2012
|
-
className: style,
|
|
2013
|
-
children: ["v", version]
|
|
2014
|
-
});
|
|
2015
|
-
}
|
|
2016
|
-
//#endregion
|
|
2017
|
-
//#region src/components/footer/footer.tsx
|
|
2018
|
-
function t(s, lang) {
|
|
2019
|
-
return typeof s === "string" ? s : s[lang];
|
|
2020
|
-
}
|
|
2021
|
-
function Footer({ logo, sponsor, columns, socialLinks, copyright, version, lang = "no", className }) {
|
|
2022
|
-
const year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
2023
|
-
const hasRight = columns && columns.length > 0 || socialLinks && socialLinks.length > 0;
|
|
2024
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2025
|
-
className: `mt-24 bg-login-950 md:mt-40 ${className || ""}`,
|
|
2026
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
2027
|
-
className: `
|
|
2028
|
-
mx-auto w-full px-4 pt-16 pb-24 md:max-w-304 md:px-12 md:pt-20 md:pb-4
|
|
2029
|
-
${hasRight ? "md:grid md:grid-cols-[18rem_1fr] md:gap-x-12" : ""}
|
|
2030
|
-
`,
|
|
2031
|
-
children: [
|
|
2032
|
-
/* @__PURE__ */ jsxs("div", {
|
|
2033
|
-
className: "mx-auto grid w-full max-w-60 gap-16 md:row-span-2 md:max-w-72 md:gap-20",
|
|
2034
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
2035
|
-
className: "block w-full",
|
|
2036
|
-
children: logo
|
|
2037
|
-
}), sponsor && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
2038
|
-
className: "block w-full",
|
|
2039
|
-
children: sponsor.node
|
|
2040
|
-
}), sponsor.label && /* @__PURE__ */ jsx("p", {
|
|
2041
|
-
className: "pt-8 text-center text-login-100",
|
|
2042
|
-
children: t(sponsor.label, lang)
|
|
2043
|
-
})] })]
|
|
2044
|
-
}),
|
|
2045
|
-
columns && columns.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
2046
|
-
className: `
|
|
2047
|
-
mt-12 grid w-full max-w-60 gap-8
|
|
2048
|
-
sm:max-w-88 sm:justify-items-end sm:justify-self-end
|
|
2049
|
-
md:col-start-2 md:row-start-1 md:mt-0 md:max-w-136 md:gap-0 md:justify-self-end
|
|
2050
|
-
${columns.length > 1 ? "sm:grid-cols-2" : ""}
|
|
2051
|
-
`,
|
|
2052
|
-
children: columns.map((col, i) => /* @__PURE__ */ jsxs("div", {
|
|
2053
|
-
className: "sm:justify-self-center md:justify-self-end",
|
|
2054
|
-
children: [/* @__PURE__ */ jsx("h4", {
|
|
2055
|
-
className: "pb-2 text-sm font-medium tracking-widest text-login-100",
|
|
2056
|
-
children: t(col.heading, lang)
|
|
2057
|
-
}), col.items.map((item, j) => item.href ? item.href.startsWith("/") ? /* @__PURE__ */ jsx(Link, {
|
|
2058
|
-
className: "link--underscore-hover block text-login-100",
|
|
2059
|
-
href: item.href,
|
|
2060
|
-
children: t(item.label, lang)
|
|
2061
|
-
}, j) : /* @__PURE__ */ jsx("a", {
|
|
2062
|
-
className: "link--underscore-hover block text-login-100",
|
|
2063
|
-
href: item.href,
|
|
2064
|
-
children: t(item.label, lang)
|
|
2065
|
-
}, j) : /* @__PURE__ */ jsx("p", {
|
|
2066
|
-
className: "text-login-100",
|
|
2067
|
-
children: t(item.label, lang)
|
|
2068
|
-
}, j))]
|
|
2069
|
-
}, i))
|
|
2070
|
-
}),
|
|
2071
|
-
socialLinks && socialLinks.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
2072
|
-
className: "md:col-start-2 md:row-start-2 md:justify-self-end",
|
|
2073
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2074
|
-
className: "mx-auto mt-20 mb-12 flex w-fit flex-wrap justify-center gap-6",
|
|
2075
|
-
children: socialLinks.map((link, i) => /* @__PURE__ */ jsx("a", {
|
|
2076
|
-
className: `block size-8 text-login-100 transition-all duration-200 group
|
|
2077
|
-
${link.hoverClass ?? "hover:text-login-50"}`,
|
|
2078
|
-
title: link.title,
|
|
2079
|
-
href: link.href,
|
|
2080
|
-
target: "_blank",
|
|
2081
|
-
rel: "noreferrer",
|
|
2082
|
-
children: link.icon
|
|
2083
|
-
}, i))
|
|
2084
|
-
})
|
|
2085
|
-
}),
|
|
2086
|
-
/* @__PURE__ */ jsxs("div", {
|
|
2087
|
-
className: "mt-16 flex flex-col items-start gap-4 md:col-span-2 md:row-start-3 md:mt-24 md:grid\n md:grid-cols-[auto_min-content] md:items-end md:gap-8",
|
|
2088
|
-
children: [/* @__PURE__ */ jsxs("p", {
|
|
2089
|
-
className: "text-xs wrap-break-word text-login-100",
|
|
2090
|
-
children: [
|
|
2091
|
-
lang === "no" ? "Opphavsrett" : "Copyright",
|
|
2092
|
-
" © ",
|
|
2093
|
-
year,
|
|
2094
|
-
" ",
|
|
2095
|
-
t(copyright, lang)
|
|
2096
|
-
]
|
|
2097
|
-
}), version && /* @__PURE__ */ jsx(VersionTag, {
|
|
2098
|
-
version: version.tag,
|
|
2099
|
-
url: version.href
|
|
2100
|
-
})]
|
|
2101
|
-
})
|
|
2102
|
-
]
|
|
2103
|
-
})
|
|
2104
|
-
});
|
|
2105
|
-
}
|
|
2106
|
-
//#endregion
|
|
2107
|
-
//#region src/components/footer/loginContent.tsx
|
|
2108
|
-
const INSTAGRAM_PATH = "M512 960Q408 960 375.0 959.5Q342 959 301 957Q260 955 230.5 949.0Q201 943 177 933Q151 923 129.0 909.0Q107 895 86 874Q65 853 51.0 831.0Q37 809 27 783Q17 759 11.0 729.5Q5 700 3 659Q1 618 0.5 585.0Q0 552 0 448Q0 344 0.5 311.0Q1 278 3 237Q5 196 11.0 166.5Q17 137 27 113Q37 87 51.0 65.0Q65 43 86 22Q107 1 129.0 -13.0Q151 -27 177 -37Q201 -47 230.5 -53.0Q260 -59 301 -61Q342 -63 375.0 -63.5Q408 -64 512 -64Q616 -64 649.0 -63.5Q682 -63 723 -61Q764 -59 793.5 -53.0Q823 -47 847 -37Q873 -27 895.0 -13.0Q917 1 938 22Q959 43 973.0 65.0Q987 87 997 113Q1007 137 1013.0 166.5Q1019 196 1021 237Q1023 278 1023.5 311.0Q1024 344 1024 448Q1024 552 1023.5 585.0Q1023 618 1021 659Q1019 700 1013.0 729.5Q1007 759 997 783Q987 809 973.0 831.0Q959 853 938 874Q917 895 895.0 909.0Q873 923 847 933Q823 943 793.5 949.0Q764 955 723 957Q682 959 649.0 959.5Q616 960 512 960ZM512 868Q614 868 646.0 867.5Q678 867 719 865Q756 863 778.0 857.5Q800 852 814 847Q832 840 845.5 831.0Q859 822 873 809Q886 795 895.0 781.5Q904 768 911 750Q916 736 921.5 714.0Q927 692 929 655Q931 614 931.5 582.5Q932 551 932 448Q932 345 931.0 313.5Q930 282 929 241Q927 204 921.5 182.0Q916 160 911 146Q903 128 894.5 114.5Q886 101 872 87Q859 74 845.0 65.0Q831 56 813 49Q800 44 777.5 38.5Q755 33 718 31Q677 29 645.0 28.5Q613 28 511 28Q408 28 376.0 29.0Q344 30 303 31Q266 33 243.5 38.5Q221 44 208 49Q190 57 176.5 65.5Q163 74 149 88Q136 101 126.5 115.0Q117 129 111 147Q105 160 100.0 182.5Q95 205 93 242Q91 282 90.5 314.0Q90 346 90 449Q90 551 90.5 583.0Q91 615 93 656Q95 693 100.0 715.5Q105 738 111 751Q117 770 126.5 783.5Q136 797 149 810Q163 824 176.5 833.0Q190 842 208 849Q221 854 243.0 859.5Q265 865 303 867Q344 868 375.5 868.5Q407 869 510 869ZM512 711Q458 711 410 690Q362 670 326.0 634.0Q290 598 270 550Q249 502 249 448Q249 394 270 346Q290 298 326.0 262.0Q362 226 410 206Q458 185 512 185Q566 185 614 206Q662 226 698.0 262.0Q734 298 754 346Q775 394 775 448Q775 502 754 550Q734 598 698.0 634.0Q662 670 614 690Q566 711 512 711ZM512 277Q441 277 391.0 327.0Q341 377 341 448Q341 519 391.0 569.0Q441 619 512 619Q583 619 633.0 569.0Q683 519 683 448Q683 377 633.0 327.0Q583 277 512 277ZM847 721Q847 696 829.0 678.0Q811 660 785 660Q760 660 742.0 678.0Q724 696 724 721Q724 747 742.0 765.0Q760 783 785 783Q811 783 829.0 765.0Q847 747 847 721Z";
|
|
2109
|
-
function InstagramIcon({ size = 24 }) {
|
|
2110
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
2111
|
-
className: "relative block",
|
|
2112
|
-
style: {
|
|
2113
|
-
width: size,
|
|
2114
|
-
height: size
|
|
2115
|
-
},
|
|
2116
|
-
children: [/* @__PURE__ */ jsx("svg", {
|
|
2117
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2118
|
-
viewBox: "0 0 1024 1024",
|
|
2119
|
-
width: size,
|
|
2120
|
-
height: size,
|
|
2121
|
-
"aria-hidden": "true",
|
|
2122
|
-
className: "absolute inset-0 transition-opacity duration-200 opacity-100 group-hover:opacity-0",
|
|
2123
|
-
children: /* @__PURE__ */ jsx("g", {
|
|
2124
|
-
transform: "translate(0 960) scale(1 -1)",
|
|
2125
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
2126
|
-
fill: "currentColor",
|
|
2127
|
-
d: INSTAGRAM_PATH
|
|
2128
|
-
})
|
|
2129
|
-
})
|
|
2130
|
-
}), /* @__PURE__ */ jsxs("svg", {
|
|
2131
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2132
|
-
viewBox: "0 0 1024 1024",
|
|
2133
|
-
width: size,
|
|
2134
|
-
height: size,
|
|
2135
|
-
"aria-hidden": "true",
|
|
2136
|
-
className: "absolute inset-0 transition-opacity duration-200 opacity-0 group-hover:opacity-100",
|
|
2137
|
-
children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", {
|
|
2138
|
-
id: "ig-grad",
|
|
2139
|
-
x1: "0%",
|
|
2140
|
-
y1: "100%",
|
|
2141
|
-
x2: "100%",
|
|
2142
|
-
y2: "0%",
|
|
2143
|
-
children: [
|
|
2144
|
-
/* @__PURE__ */ jsx("stop", {
|
|
2145
|
-
offset: "0%",
|
|
2146
|
-
stopColor: "#fff695"
|
|
2147
|
-
}),
|
|
2148
|
-
/* @__PURE__ */ jsx("stop", {
|
|
2149
|
-
offset: "45%",
|
|
2150
|
-
stopColor: "#ff5445"
|
|
2151
|
-
}),
|
|
2152
|
-
/* @__PURE__ */ jsx("stop", {
|
|
2153
|
-
offset: "60%",
|
|
2154
|
-
stopColor: "#ff37c0"
|
|
2155
|
-
}),
|
|
2156
|
-
/* @__PURE__ */ jsx("stop", {
|
|
2157
|
-
offset: "90%",
|
|
2158
|
-
stopColor: "#3d6dff"
|
|
2159
|
-
})
|
|
2160
|
-
]
|
|
2161
|
-
}) }), /* @__PURE__ */ jsx("g", {
|
|
2162
|
-
transform: "translate(0 960) scale(1 -1)",
|
|
2163
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
2164
|
-
fill: "url(#ig-grad)",
|
|
2165
|
-
d: INSTAGRAM_PATH
|
|
2166
|
-
})
|
|
2167
|
-
})]
|
|
2168
|
-
})]
|
|
2169
|
-
});
|
|
2170
|
-
}
|
|
2171
|
-
const loginAddress = {
|
|
2172
|
-
heading: {
|
|
2173
|
-
no: "Adresse",
|
|
2174
|
-
en: "Address"
|
|
2175
|
-
},
|
|
2176
|
-
items: [
|
|
2177
|
-
{ label: "Teknologivegen 22" },
|
|
2178
|
-
{ label: {
|
|
2179
|
-
no: "Bygg A, rom 155",
|
|
2180
|
-
en: "Building A, room 155"
|
|
2181
|
-
} },
|
|
2182
|
-
{ label: "2815 GJØVIK" }
|
|
2183
|
-
]
|
|
2184
|
-
};
|
|
2185
|
-
const loginEmail = (email) => ({
|
|
2186
|
-
heading: {
|
|
2187
|
-
no: "E-post",
|
|
2188
|
-
en: "Email"
|
|
2189
|
-
},
|
|
2190
|
-
items: [{
|
|
2191
|
-
label: email,
|
|
2192
|
-
href: `mailto:${email}`
|
|
2193
|
-
}]
|
|
2194
|
-
});
|
|
2195
|
-
const loginCopyright = {
|
|
2196
|
-
no: "Login - Linjeforeningen for IT, NO 811 940 372",
|
|
2197
|
-
en: "Login - Association for IT, NO 811 940 372"
|
|
2198
|
-
};
|
|
2199
|
-
const loginSponsor = { label: {
|
|
2200
|
-
no: "Hovedsamarbeidspartner",
|
|
2201
|
-
en: "Main partner"
|
|
2202
|
-
} };
|
|
2203
|
-
const loginSocialLinks = [
|
|
2204
|
-
{
|
|
2205
|
-
title: "Discord",
|
|
2206
|
-
href: "https://discord.gg/login-ntnu",
|
|
2207
|
-
icon: /* @__PURE__ */ jsx(Discord, { size: 24 }),
|
|
2208
|
-
hoverClass: "hover:text-[#6571fd]"
|
|
2209
|
-
},
|
|
2210
|
-
{
|
|
2211
|
-
title: "Instagram",
|
|
2212
|
-
href: "https://www.instagram.com/login_linjeforening/",
|
|
2213
|
-
icon: /* @__PURE__ */ jsx(InstagramIcon, { size: 24 })
|
|
2214
|
-
},
|
|
2215
|
-
{
|
|
2216
|
-
title: "Facebook",
|
|
2217
|
-
href: "https://facebook.com/LogNTNU",
|
|
2218
|
-
icon: /* @__PURE__ */ jsx(Facebook, { size: 24 }),
|
|
2219
|
-
hoverClass: "hover:text-[#2c87ff]"
|
|
2220
|
-
},
|
|
2221
|
-
{
|
|
2222
|
-
title: "LinkedIn",
|
|
2223
|
-
href: "https://www.linkedin.com/company/linjeforeningen-login/about",
|
|
2224
|
-
icon: /* @__PURE__ */ jsx(Linkedin, { size: 24 }),
|
|
2225
|
-
hoverClass: "hover:text-[#1a7bdd]"
|
|
2226
|
-
},
|
|
2227
|
-
{
|
|
2228
|
-
title: "GitHub",
|
|
2229
|
-
href: "https://github.com/login-linjeforeningen-for-it",
|
|
2230
|
-
icon: /* @__PURE__ */ jsx(Github, { size: 24 }),
|
|
2231
|
-
hoverClass: "hover:text-white"
|
|
2232
|
-
},
|
|
2233
|
-
{
|
|
2234
|
-
title: "Wiki",
|
|
2235
|
-
href: "https://outline.login.no/s/doc",
|
|
2236
|
-
icon: /* @__PURE__ */ jsx(Wikijs, { size: 24 }),
|
|
2237
|
-
hoverClass: "hover:text-login-50"
|
|
2238
|
-
}
|
|
2239
|
-
];
|
|
2240
|
-
//#endregion
|
|
2241
|
-
//#region src/components/container/page.tsx
|
|
2242
|
-
function PageContainer({ title, children, className, innerClassName }) {
|
|
2243
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2244
|
-
className: `w-full page-container ${className}`,
|
|
2245
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
2246
|
-
className: `flex flex-col col-start-3 ${innerClassName}`,
|
|
2247
|
-
children: [/* @__PURE__ */ jsx("h1", {
|
|
2248
|
-
className: "heading",
|
|
2249
|
-
children: title
|
|
2250
|
-
}), children]
|
|
2251
|
-
})
|
|
2252
|
-
});
|
|
2253
|
-
}
|
|
2254
|
-
//#endregion
|
|
2255
|
-
//#region src/components/container/highlight.tsx
|
|
2256
|
-
function Highlight({ children, className }) {
|
|
2257
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2258
|
-
className: `highlighted-section ${className ?? ""}`,
|
|
2259
|
-
children
|
|
2260
|
-
});
|
|
2261
|
-
}
|
|
2262
|
-
//#endregion
|
|
2263
|
-
//#region src/components/container/leftBarPanel.tsx
|
|
2264
|
-
function LeftBarPanel({ color, children, className = "" }) {
|
|
2265
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2266
|
-
className: `bg-login-500/50 border border-login-500/30 border-l-2 rounded-sm ${color} ${className}`,
|
|
2267
|
-
children
|
|
2268
|
-
});
|
|
2269
|
-
}
|
|
2270
|
-
//#endregion
|
|
2271
|
-
//#region src/components/container/card.tsx
|
|
2272
|
-
function Card({ children, className = "" }) {
|
|
2273
|
-
return /* @__PURE__ */ jsx("section", {
|
|
2274
|
-
className: `rounded-xl border border-login-500/30 bg-login-500/50 ${className}`,
|
|
2275
|
-
children
|
|
2276
|
-
});
|
|
2277
|
-
}
|
|
2278
|
-
//#endregion
|
|
2279
|
-
//#region src/components/container/iconBubble.tsx
|
|
2280
|
-
const tones = {
|
|
2281
|
-
amber: "bg-amber-500/10 text-amber-400",
|
|
2282
|
-
blue: "bg-sky-500/10 text-sky-400",
|
|
2283
|
-
emerald: "bg-emerald-500/10 text-emerald-400",
|
|
2284
|
-
rose: "bg-rose-500/10 text-rose-400",
|
|
2285
|
-
slate: "bg-login-600 text-login-100",
|
|
2286
|
-
violet: "bg-violet-500/10 text-violet-400",
|
|
2287
|
-
orange: "bg-login/10 text-login"
|
|
2288
|
-
};
|
|
2289
|
-
function IconBubble({ icon: Icon, tone = "slate", size = "md" }) {
|
|
2290
|
-
const sizeClass = size === "sm" ? "h-7 w-7" : size === "lg" ? "h-11 w-11" : "h-9 w-9";
|
|
2291
|
-
const iconSize = size === "sm" ? "h-3.5 w-3.5" : size === "lg" ? "h-5 w-5" : "h-4 w-4";
|
|
2292
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2293
|
-
className: `flex shrink-0 items-center justify-center rounded-lg ${sizeClass} ${tones[tone]}`,
|
|
2294
|
-
children: /* @__PURE__ */ jsx(Icon, { className: iconSize })
|
|
2295
|
-
});
|
|
2296
|
-
}
|
|
2297
|
-
//#endregion
|
|
2298
|
-
//#region src/components/container/statCard.tsx
|
|
2299
|
-
function StatCard({ label, value, icon, tone = "slate" }) {
|
|
2300
|
-
return /* @__PURE__ */ jsxs(Card, {
|
|
2301
|
-
className: "p-4",
|
|
2302
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
2303
|
-
className: "mb-3 flex items-center gap-3",
|
|
2304
|
-
children: [/* @__PURE__ */ jsx(IconBubble, {
|
|
2305
|
-
icon,
|
|
2306
|
-
tone
|
|
2307
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
2308
|
-
className: "text-sm font-medium text-login-200",
|
|
2309
|
-
children: label
|
|
2310
|
-
})]
|
|
2311
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2312
|
-
className: "truncate text-lg font-semibold text-login-50",
|
|
2313
|
-
title: value,
|
|
2314
|
-
children: value
|
|
2315
|
-
})]
|
|
2316
|
-
});
|
|
2317
|
-
}
|
|
2318
|
-
//#endregion
|
|
2319
|
-
//#region src/components/container/tabs.tsx
|
|
2320
|
-
function Tabs({ tabs, defaultTab, activeTab: controlledTab, onTabChange, children, className = "" }) {
|
|
2321
|
-
const [internalTab, setInternalTab] = useState(defaultTab ?? tabs[0]?.id ?? "");
|
|
2322
|
-
const activeTab = controlledTab ?? internalTab;
|
|
2323
|
-
function handleTabChange(id) {
|
|
2324
|
-
if (!controlledTab) setInternalTab(id);
|
|
2325
|
-
onTabChange?.(id);
|
|
2326
|
-
}
|
|
2327
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2328
|
-
className,
|
|
2329
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
2330
|
-
className: "flex gap-1 rounded-md bg-login-500/50 border border-login-500/40 p-1 w-fit",
|
|
2331
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
|
|
2332
|
-
type: "button",
|
|
2333
|
-
onClick: () => handleTabChange(tab.id),
|
|
2334
|
-
className: `
|
|
2335
|
-
px-3 py-1.5 rounded text-sm font-medium transition-all duration-150 cursor-pointer select-none
|
|
2336
|
-
${activeTab === tab.id ? "bg-login text-white shadow-sm" : "text-login-200 hover:text-login-50 hover:bg-login-600"}
|
|
2337
|
-
`,
|
|
2338
|
-
children: tab.label
|
|
2339
|
-
}, tab.id))
|
|
2340
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2341
|
-
className: "mt-3",
|
|
2342
|
-
children
|
|
2343
|
-
})]
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
function TabPanel({ id, activeTab, children }) {
|
|
2347
|
-
if (activeTab !== id) return null;
|
|
2348
|
-
return /* @__PURE__ */ jsx("div", { children });
|
|
2349
|
-
}
|
|
2350
|
-
//#endregion
|
|
2351
|
-
//#region src/components/container/accordion.tsx
|
|
2352
|
-
const GroupContext = createContext(false);
|
|
2353
|
-
function AccordionGroup({ children, className = "" }) {
|
|
2354
|
-
return /* @__PURE__ */ jsx(GroupContext.Provider, {
|
|
2355
|
-
value: true,
|
|
2356
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2357
|
-
className: `rounded-lg border border-login-500/40 overflow-hidden divide-y divide-login-500/25 ${className}`,
|
|
2358
|
-
children
|
|
2359
|
-
})
|
|
2360
|
-
});
|
|
2361
|
-
}
|
|
2362
|
-
function Accordion({ title, children, defaultOpen = false, className = "" }) {
|
|
2363
|
-
const [open, setOpen] = useState(defaultOpen);
|
|
2364
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2365
|
-
className: useContext(GroupContext) ? className : `rounded-lg border border-login-500/40 overflow-hidden ${className}`,
|
|
2366
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
2367
|
-
type: "button",
|
|
2368
|
-
onClick: () => setOpen((o) => !o),
|
|
2369
|
-
className: "\n flex w-full cursor-pointer items-center justify-between\n bg-login-800 px-4 py-3 text-left select-none\n transition-colors duration-150 hover:bg-login-700\n ",
|
|
2370
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
2371
|
-
className: "text-sm font-medium text-login-50",
|
|
2372
|
-
children: title
|
|
2373
|
-
}), /* @__PURE__ */ jsx(ChevronDown, {
|
|
2374
|
-
size: 16,
|
|
2375
|
-
className: `shrink-0 text-login-300 transition-transform duration-200 ${open ? "rotate-180" : ""}`
|
|
2376
|
-
})]
|
|
2377
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2378
|
-
className: `overflow-hidden bg-login-900 transition-all duration-200 ${open ? "max-h-[9999px]" : "max-h-0"}`,
|
|
2379
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2380
|
-
className: "px-4 py-3 text-sm text-login-100",
|
|
2381
|
-
children
|
|
2382
|
-
})
|
|
2383
|
-
})]
|
|
2384
|
-
});
|
|
2385
|
-
}
|
|
2386
|
-
//#endregion
|
|
2387
|
-
//#region src/components/container/pulseDot.tsx
|
|
2388
|
-
const variantColor = {
|
|
2389
|
-
online: "bg-green-500",
|
|
2390
|
-
offline: "bg-red-500",
|
|
2391
|
-
warning: "bg-login",
|
|
2392
|
-
unknown: "bg-login-400"
|
|
2393
|
-
};
|
|
2394
|
-
const sizeClass = {
|
|
2395
|
-
sm: "w-1.5 h-1.5",
|
|
2396
|
-
md: "w-2 h-2",
|
|
2397
|
-
lg: "w-3 h-3"
|
|
2398
|
-
};
|
|
2399
|
-
function PulseDot({ variant = "online", size = "md" }) {
|
|
2400
|
-
const color = variantColor[variant];
|
|
2401
|
-
const dotSize = sizeClass[size];
|
|
2402
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2403
|
-
className: `relative grid place-items-center ${dotSize}`,
|
|
2404
|
-
children: [/* @__PURE__ */ jsx("span", { className: `absolute inline-flex h-full w-full rounded-full ${color} opacity-50 animate-ping` }), /* @__PURE__ */ jsx("span", { className: `relative inline-flex rounded-full ${dotSize} ${color}` })]
|
|
2405
|
-
});
|
|
2406
|
-
}
|
|
2407
|
-
//#endregion
|
|
2408
|
-
//#region src/components/login/loginPage.tsx
|
|
2409
|
-
function LoginPage({ title, description, redirectPath, version, btg, handleSubmit, guestRedirectPath, guestText }) {
|
|
2410
|
-
return /* @__PURE__ */ jsx("main", {
|
|
2411
|
-
className: "w-full h-full flex items-center justify-center bg-login-800 p-8",
|
|
2412
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
2413
|
-
className: "flex flex-col justify-center items-center bg-login-600 px-4 py-12 rounded-xl w-full max-w-md gap-4 md:gap-6",
|
|
2414
|
-
children: [
|
|
2415
|
-
/* @__PURE__ */ jsx("div", {
|
|
2416
|
-
className: "relative aspect-3/1 w-full",
|
|
2417
|
-
children: /* @__PURE__ */ jsx(Logo, { className: "object-contain px-6 sm:px-12" })
|
|
2418
|
-
}),
|
|
2419
|
-
/* @__PURE__ */ jsxs("h1", {
|
|
2420
|
-
className: "text-3xl font-extrabold text-login text-center tracking-tight",
|
|
2421
|
-
children: [
|
|
2422
|
-
title,
|
|
2423
|
-
" ",
|
|
2424
|
-
btg ? " - Break the Glass" : ""
|
|
2425
|
-
]
|
|
2426
|
-
}),
|
|
2427
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
2428
|
-
className: "text-center font-medium text-lg mb-2 max-w-xs",
|
|
2429
|
-
children: description
|
|
2430
|
-
}),
|
|
2431
|
-
btg ? /* @__PURE__ */ jsxs("form", {
|
|
2432
|
-
className: "w-full flex flex-col gap-3 max-w-xs",
|
|
2433
|
-
onSubmit: (e) => {
|
|
2434
|
-
e.preventDefault();
|
|
2435
|
-
handleSubmit?.(new FormData(e.currentTarget));
|
|
2436
|
-
e.currentTarget.reset();
|
|
2437
|
-
},
|
|
2438
|
-
children: [
|
|
2439
|
-
/* @__PURE__ */ jsx("input", {
|
|
2440
|
-
type: "text",
|
|
2441
|
-
name: "name",
|
|
2442
|
-
placeholder: "Name",
|
|
2443
|
-
className: "py-2 px-3 rounded bg-login-900 font-medium focus:outline-none",
|
|
2444
|
-
required: true
|
|
2445
|
-
}),
|
|
2446
|
-
/* @__PURE__ */ jsx("input", {
|
|
2447
|
-
type: "password",
|
|
2448
|
-
name: "token",
|
|
2449
|
-
placeholder: "Token",
|
|
2450
|
-
className: "py-2 px-3 rounded bg-login-900 font-medium focus:outline-none",
|
|
2451
|
-
required: true
|
|
2452
|
-
}),
|
|
2453
|
-
/* @__PURE__ */ jsx("button", {
|
|
2454
|
-
type: "submit",
|
|
2455
|
-
className: "py-2 px-4 rounded-xl bg-login font-bold text-lg hover:bg-login/80 transition-all duration-200 mt-2",
|
|
2456
|
-
children: "Login"
|
|
2457
|
-
})
|
|
2458
|
-
]
|
|
2459
|
-
}) : /* @__PURE__ */ jsxs(Link, {
|
|
2460
|
-
href: redirectPath,
|
|
2461
|
-
className: `
|
|
2462
|
-
flex items-center justify-center gap-2 w-full
|
|
2463
|
-
max-w-xs py-3 px-6 rounded-xl bg-login font-bold
|
|
2464
|
-
text-lg hover:bg-login/80 transition-all
|
|
2465
|
-
duration-200 mb-2 mt-2 cursor-pointer
|
|
2466
|
-
`,
|
|
2467
|
-
children: ["Login", /* @__PURE__ */ jsx(LogIn, { className: "w-6 h-6" })]
|
|
2468
|
-
}),
|
|
2469
|
-
guestRedirectPath && /* @__PURE__ */ jsx(Link, {
|
|
2470
|
-
href: guestRedirectPath,
|
|
2471
|
-
className: "text-sm font-semibold cursor-pointer opacity-50",
|
|
2472
|
-
children: guestText || "Continue as guest"
|
|
2473
|
-
}),
|
|
2474
|
-
/* @__PURE__ */ jsxs("span", {
|
|
2475
|
-
className: "text-sm mt-2",
|
|
2476
|
-
children: ["v", version]
|
|
2477
|
-
})
|
|
2478
|
-
]
|
|
2479
|
-
})
|
|
2480
|
-
});
|
|
2481
|
-
}
|
|
2482
|
-
//#endregion
|
|
2483
|
-
//#region src/components/toast/toastItem.tsx
|
|
2484
|
-
function ToastItem({ toast, index, expanded, onRemove, onHeight, offset, frontHeight }) {
|
|
2485
|
-
const [mounted, setMounted] = useState(false);
|
|
2486
|
-
const ref = useRef(null);
|
|
2487
|
-
useEffect(() => {
|
|
2488
|
-
requestAnimationFrame(() => setMounted(true));
|
|
2489
|
-
}, []);
|
|
2490
|
-
useLayoutEffect(() => {
|
|
2491
|
-
if (ref.current) onHeight(toast.id, ref.current.offsetHeight);
|
|
2492
|
-
}, [
|
|
2493
|
-
toast.message,
|
|
2494
|
-
onHeight,
|
|
2495
|
-
toast.id,
|
|
2496
|
-
expanded
|
|
2497
|
-
]);
|
|
2498
|
-
const isVisible = mounted && !toast.exiting;
|
|
2499
|
-
const isFront = index === 0;
|
|
2500
|
-
const collapsedOffset = index * 10 + (index > 0 ? frontHeight - 60 : 0);
|
|
2501
|
-
return /* @__PURE__ */ jsx("li", {
|
|
2502
|
-
ref,
|
|
2503
|
-
className: "absolute bottom-0 right-0 w-full transition-all duration-300 ease-out pointer-events-auto",
|
|
2504
|
-
style: {
|
|
2505
|
-
transform: isVisible ? `translateY(${expanded ? -offset : -collapsedOffset}px) scale(${expanded ? 1 : 1 - index * .05})` : "translateY(20px) scale(0.9)",
|
|
2506
|
-
opacity: isVisible ? 1 : 0,
|
|
2507
|
-
zIndex: toast.id
|
|
2508
|
-
},
|
|
2509
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
2510
|
-
className: "flex items-center space-x-4 rounded-lg p-4 shadow-lg border-2 border-login-400 bg-login-700",
|
|
2511
|
-
children: [
|
|
2512
|
-
/* @__PURE__ */ jsx("div", {
|
|
2513
|
-
className: "shrink-0",
|
|
2514
|
-
children: Icon(toast.type)
|
|
2515
|
-
}),
|
|
2516
|
-
/* @__PURE__ */ jsx("p", {
|
|
2517
|
-
className: `flex-1 text-sm font-semibold text-login-800 dark:text-login-100 min-w-0
|
|
2518
|
-
${!expanded && !isFront ? "truncate" : ""}`,
|
|
2519
|
-
children: toast.message
|
|
2520
|
-
}),
|
|
2521
|
-
/* @__PURE__ */ jsx("button", {
|
|
2522
|
-
onClick: onRemove,
|
|
2523
|
-
className: "hover:text-login-200 text-login-400",
|
|
2524
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-5 w-5" })
|
|
2525
|
-
})
|
|
2526
|
-
]
|
|
2527
|
-
})
|
|
2528
|
-
});
|
|
2529
|
-
}
|
|
2530
|
-
function Icon(type) {
|
|
2531
|
-
switch (type) {
|
|
2532
|
-
case "info": return /* @__PURE__ */ jsx(Info, { className: "h-6 w-6 text-blue-500" });
|
|
2533
|
-
case "success": return /* @__PURE__ */ jsx(CheckCircle, { className: "h-6 w-6 text-green-500" });
|
|
2534
|
-
case "warning": return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-6 w-6 text-yellow-500" });
|
|
2535
|
-
case "error": return /* @__PURE__ */ jsx(AlertCircle, { className: "h-6 w-6 text-red-500" });
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
//#endregion
|
|
2539
|
-
//#region src/components/toast/toaster.tsx
|
|
2540
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
2541
|
-
let idCounter = 0;
|
|
2542
|
-
function toast(message, type, duration = 4e3) {
|
|
2543
|
-
const id = ++idCounter;
|
|
2544
|
-
listeners.forEach((listener) => listener({
|
|
2545
|
-
id,
|
|
2546
|
-
message,
|
|
2547
|
-
type,
|
|
2548
|
-
expiresAt: Date.now() + duration
|
|
2549
|
-
}));
|
|
2550
|
-
}
|
|
2551
|
-
toast.info = (message, duration) => toast(message, "info", duration);
|
|
2552
|
-
toast.success = (message, duration) => toast(message, "success", duration);
|
|
2553
|
-
toast.warning = (message, duration) => toast(message, "warning", duration);
|
|
2554
|
-
toast.error = (message, duration) => toast(message, "error", duration);
|
|
2555
|
-
function Toaster() {
|
|
2556
|
-
const [toasts, setToasts] = useState([]);
|
|
2557
|
-
const [expanded, setExpanded] = useState(false);
|
|
2558
|
-
const [heights, setHeights] = useState({});
|
|
2559
|
-
useEffect(() => {
|
|
2560
|
-
function addToast(toast) {
|
|
2561
|
-
setToasts((prev) => [toast, ...prev]);
|
|
2562
|
-
}
|
|
2563
|
-
listeners.add(addToast);
|
|
2564
|
-
return () => {
|
|
2565
|
-
listeners.delete(addToast);
|
|
2566
|
-
};
|
|
2567
|
-
}, []);
|
|
2568
|
-
useEffect(() => {
|
|
2569
|
-
const now = Date.now();
|
|
2570
|
-
setToasts((prev) => prev.map((toast) => {
|
|
2571
|
-
if (expanded) return {
|
|
2572
|
-
...toast,
|
|
2573
|
-
pausedAt: toast.pausedAt || now
|
|
2574
|
-
};
|
|
2575
|
-
if (!toast.pausedAt) return toast;
|
|
2576
|
-
return {
|
|
2577
|
-
...toast,
|
|
2578
|
-
expiresAt: toast.expiresAt + (now - toast.pausedAt),
|
|
2579
|
-
pausedAt: void 0
|
|
2580
|
-
};
|
|
2581
|
-
}));
|
|
2582
|
-
}, [expanded]);
|
|
2583
|
-
function removeToast(id) {
|
|
2584
|
-
setToasts((prev) => prev.map((toast) => toast.id === id ? {
|
|
2585
|
-
...toast,
|
|
2586
|
-
exiting: true
|
|
2587
|
-
} : toast));
|
|
2588
|
-
setTimeout(() => {
|
|
2589
|
-
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
|
2590
|
-
}, 300);
|
|
2591
|
-
}
|
|
2592
|
-
useEffect(() => {
|
|
2593
|
-
const timer = setInterval(() => {
|
|
2594
|
-
if (expanded) return;
|
|
2595
|
-
const now = Date.now();
|
|
2596
|
-
setToasts((prev) => {
|
|
2597
|
-
const toastsToExit = prev.filter((toast) => !toast.exiting && !toast.pausedAt && toast.expiresAt <= now);
|
|
2598
|
-
if (toastsToExit.length === 0) return prev;
|
|
2599
|
-
toastsToExit.forEach((toast) => {
|
|
2600
|
-
setTimeout(() => {
|
|
2601
|
-
setToasts((current) => current.filter((item) => item.id !== toast.id));
|
|
2602
|
-
}, 300);
|
|
2603
|
-
});
|
|
2604
|
-
return prev.map((toast) => toastsToExit.find((exitToast) => exitToast.id === toast.id) ? {
|
|
2605
|
-
...toast,
|
|
2606
|
-
exiting: true
|
|
2607
|
-
} : toast);
|
|
2608
|
-
});
|
|
2609
|
-
}, 100);
|
|
2610
|
-
return () => clearInterval(timer);
|
|
2611
|
-
}, [expanded]);
|
|
2612
|
-
function onHeight(id, height) {
|
|
2613
|
-
setHeights((prev) => {
|
|
2614
|
-
if (prev[id] === height) return prev;
|
|
2615
|
-
return {
|
|
2616
|
-
...prev,
|
|
2617
|
-
[id]: height
|
|
2618
|
-
};
|
|
2619
|
-
});
|
|
2620
|
-
}
|
|
2621
|
-
const visibleToasts = toasts.slice(0, expanded ? 10 : 3);
|
|
2622
|
-
const frontHeight = heights[visibleToasts[0]?.id] || 60;
|
|
2623
|
-
const offsets = useMemo(() => {
|
|
2624
|
-
let currentOffset = 0;
|
|
2625
|
-
return visibleToasts.map((toast) => {
|
|
2626
|
-
const height = heights[toast.id] || 60;
|
|
2627
|
-
const offset = currentOffset;
|
|
2628
|
-
currentOffset += height + 16;
|
|
2629
|
-
return offset;
|
|
2630
|
-
});
|
|
2631
|
-
}, [visibleToasts, heights]);
|
|
2632
|
-
const totalHeight = offsets.length > 0 ? offsets[offsets.length - 1] + (heights[visibleToasts[visibleToasts.length - 1]?.id] || 60) : 0;
|
|
2633
|
-
return /* @__PURE__ */ jsx("ul", {
|
|
2634
|
-
className: `fixed bottom-4 right-4 z-9999 w-full max-w-sm flex flex-col items-end transition-all duration-300 ease-out
|
|
2635
|
-
${expanded ? "pointer-events-auto" : "pointer-events-none"}`,
|
|
2636
|
-
style: { height: expanded ? totalHeight + "px" : "auto" },
|
|
2637
|
-
onMouseEnter: () => setExpanded(true),
|
|
2638
|
-
onMouseLeave: () => setExpanded(false),
|
|
2639
|
-
children: visibleToasts.map((toast, index) => /* @__PURE__ */ jsx(ToastItem, {
|
|
2640
|
-
toast,
|
|
2641
|
-
index,
|
|
2642
|
-
expanded,
|
|
2643
|
-
onRemove: () => removeToast(toast.id),
|
|
2644
|
-
onHeight,
|
|
2645
|
-
offset: offsets[index],
|
|
2646
|
-
frontHeight
|
|
2647
|
-
}, toast.id))
|
|
2648
|
-
});
|
|
2649
|
-
}
|
|
2650
|
-
//#endregion
|
|
2651
|
-
//#region src/components/buttons/button.tsx
|
|
2652
|
-
const variants$1 = {
|
|
2653
|
-
primary: "bg-login text-white hover:brightness-110",
|
|
2654
|
-
secondary: "bg-login-500 text-login-50 hover:bg-login-400",
|
|
2655
|
-
warning: "bg-yellow-500 text-black hover:brightness-110",
|
|
2656
|
-
danger: "bg-red-600 text-white hover:brightness-110",
|
|
2657
|
-
success: "bg-green-600 text-white hover:brightness-110",
|
|
2658
|
-
info: "bg-blue-600 text-white hover:brightness-110"
|
|
2659
|
-
};
|
|
2660
|
-
const base = "cursor-pointer rounded-md h-9 flex items-center justify-center gap-2 select-none text-sm font-medium transition-all duration-150";
|
|
2661
|
-
const withText = "px-4 w-fit";
|
|
2662
|
-
const iconOnly = "w-9";
|
|
2663
|
-
const disabledCls = "opacity-40 cursor-not-allowed pointer-events-none";
|
|
2664
|
-
const iconWrap = (icon) => icon ? /* @__PURE__ */ jsx("span", {
|
|
2665
|
-
className: "[&>svg]:w-4 [&>svg]:h-4 flex items-center",
|
|
2666
|
-
children: icon
|
|
2667
|
-
}) : null;
|
|
2668
|
-
function Button({ text, className, icon, path, variant = "primary", type, onClick, disabled }) {
|
|
2669
|
-
const color = variants$1[variant];
|
|
2670
|
-
const sizing = icon && !text ? iconOnly : withText;
|
|
2671
|
-
const cls = `${base} ${sizing} ${color} ${disabled ? disabledCls : ""} ${className || ""}`;
|
|
2672
|
-
if (!path) return /* @__PURE__ */ jsxs("button", {
|
|
2673
|
-
type: type || "button",
|
|
2674
|
-
disabled,
|
|
2675
|
-
onClick,
|
|
2676
|
-
"aria-label": text,
|
|
2677
|
-
className: cls,
|
|
2678
|
-
children: [iconWrap(icon), text]
|
|
2679
|
-
});
|
|
2680
|
-
if (disabled) return /* @__PURE__ */ jsxs("div", {
|
|
2681
|
-
className: cls,
|
|
2682
|
-
children: [iconWrap(icon), text]
|
|
2683
|
-
});
|
|
2684
|
-
return /* @__PURE__ */ jsxs(Link, {
|
|
2685
|
-
href: path,
|
|
2686
|
-
className: `${base} ${sizing} ${color} ${className || ""}`,
|
|
2687
|
-
children: [iconWrap(icon), text]
|
|
2688
|
-
});
|
|
2689
|
-
}
|
|
2690
|
-
//#endregion
|
|
2691
|
-
//#region src/components/alert/alert.tsx
|
|
2692
|
-
const styles = {
|
|
2693
|
-
warning: {
|
|
2694
|
-
color: "border-l-red-500",
|
|
2695
|
-
iconClass: "w-4 h-4 shrink-0 stroke-red-400 mr-3 mt-0.5",
|
|
2696
|
-
Icon: CircleAlert
|
|
2697
|
-
},
|
|
2698
|
-
info: {
|
|
2699
|
-
color: "border-l-blue-500",
|
|
2700
|
-
iconClass: "w-4 h-4 shrink-0 stroke-blue-400 mr-3 mt-0.5",
|
|
2701
|
-
Icon: Info
|
|
2702
|
-
}
|
|
2703
|
-
};
|
|
2704
|
-
function Alert({ children, variant = "warning", className = "" }) {
|
|
2705
|
-
const { color, iconClass, Icon } = styles[variant] ?? styles.warning;
|
|
2706
|
-
return /* @__PURE__ */ jsxs(LeftBarPanel, {
|
|
2707
|
-
color,
|
|
2708
|
-
className: `flex items-start px-4 py-3 text-sm text-login-100 ${className}`,
|
|
2709
|
-
children: [/* @__PURE__ */ jsx(Icon, { className: iconClass }), /* @__PURE__ */ jsx("div", {
|
|
2710
|
-
className: "leading-relaxed",
|
|
2711
|
-
children
|
|
2712
|
-
})]
|
|
2713
|
-
});
|
|
2714
|
-
}
|
|
2715
|
-
//#endregion
|
|
2716
|
-
//#region src/components/table/constants.ts
|
|
2717
|
-
const HIGHLIGHT = {
|
|
2718
|
-
green: "bg-green-500/15 text-green-400 ring-1 ring-green-500/25",
|
|
2719
|
-
yellow: "bg-yellow-500/15 text-yellow-400 ring-1 ring-yellow-500/25",
|
|
2720
|
-
red: "bg-red-500/15 text-red-400 ring-1 ring-red-500/25",
|
|
2721
|
-
blue: "bg-blue-500/15 text-blue-400 ring-1 ring-blue-500/25",
|
|
2722
|
-
gray: "bg-gray-500/15 text-gray-400 ring-1 ring-gray-500/25",
|
|
2723
|
-
orange: "bg-orange-500/15 text-orange-400 ring-1 ring-orange-500/25",
|
|
2724
|
-
purple: "bg-purple-500/15 text-purple-400 ring-1 ring-purple-500/25"
|
|
2725
|
-
};
|
|
2726
|
-
const DENSITY_TH = {
|
|
2727
|
-
compact: "px-4 py-2",
|
|
2728
|
-
comfortable: "px-6 py-3",
|
|
2729
|
-
spacious: "px-8 py-4"
|
|
2730
|
-
};
|
|
2731
|
-
const DENSITY_TD = {
|
|
2732
|
-
compact: "px-4 py-1.5",
|
|
2733
|
-
comfortable: "px-6 py-3.5",
|
|
2734
|
-
spacious: "px-8 py-5"
|
|
2735
|
-
};
|
|
2736
|
-
const VARIANT_CONTAINER = {
|
|
2737
|
-
original: "bg-login-500/50 rounded-lg border border-login-600 shadow",
|
|
2738
|
-
modern: "bg-transparent"
|
|
2739
|
-
};
|
|
2740
|
-
const VARIANT_THEAD = {
|
|
2741
|
-
original: "bg-login-700",
|
|
2742
|
-
modern: "bg-transparent"
|
|
2743
|
-
};
|
|
2744
|
-
const VARIANT_HEAD_BG = {
|
|
2745
|
-
original: "bg-login-700",
|
|
2746
|
-
modern: ""
|
|
2747
|
-
};
|
|
2748
|
-
const VARIANT_HEAD_BORDER = {
|
|
2749
|
-
original: "border-b border-login-600",
|
|
2750
|
-
modern: "border-b border-login-500/40"
|
|
2751
|
-
};
|
|
2752
|
-
const VARIANT_ROW_BORDER = {
|
|
2753
|
-
original: "border-b border-login-600",
|
|
2754
|
-
modern: "border-b border-login-600/15"
|
|
2755
|
-
};
|
|
2756
|
-
const VARIANT_THEAD_TH = {
|
|
2757
|
-
original: "text-login-200",
|
|
2758
|
-
modern: "text-login-300"
|
|
2759
|
-
};
|
|
2760
|
-
const VARIANT_TBODY = {
|
|
2761
|
-
original: "bg-login-500/50 divide-login-600",
|
|
2762
|
-
modern: "divide-login-600/15"
|
|
2763
|
-
};
|
|
2764
|
-
const VARIANT_ROW_HOVER = {
|
|
2765
|
-
original: "hover:bg-login-600/30",
|
|
2766
|
-
modern: "hover:bg-login-700/50"
|
|
2767
|
-
};
|
|
2768
|
-
const VARIANT_ROW_STRIPED = {
|
|
2769
|
-
original: "even:bg-login-600/40",
|
|
2770
|
-
modern: "even:bg-login-800/40"
|
|
2771
|
-
};
|
|
2772
|
-
//#endregion
|
|
2773
|
-
//#region src/components/table/header.tsx
|
|
2774
|
-
function formatLabel(key, label) {
|
|
2775
|
-
if (label) return label;
|
|
2776
|
-
if (key.length <= 2) return key.toUpperCase();
|
|
2777
|
-
return key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll("_", " ").replaceAll("-", " ").split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
2778
|
-
}
|
|
2779
|
-
function Header({ columns, sort, onSort, hasMenu, hasSelect, hasExpand, allSelected, someSelected, onSelectAll, variant, density }) {
|
|
2780
|
-
function handleSort(key) {
|
|
2781
|
-
onSort({
|
|
2782
|
-
column: key,
|
|
2783
|
-
order: sort?.column === key && sort?.order === "asc" ? "desc" : "asc"
|
|
2784
|
-
});
|
|
2785
|
-
}
|
|
2786
|
-
return /* @__PURE__ */ jsx("thead", {
|
|
2787
|
-
className: VARIANT_THEAD[variant],
|
|
2788
|
-
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2789
|
-
hasSelect && /* @__PURE__ */ jsx("th", {
|
|
2790
|
-
className: `sticky top-0 z-10 ${VARIANT_HEAD_BG[variant]} ${VARIANT_HEAD_BORDER[variant]}`,
|
|
2791
|
-
style: {
|
|
2792
|
-
width: "3rem",
|
|
2793
|
-
minWidth: "3rem"
|
|
2794
|
-
},
|
|
2795
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2796
|
-
className: "flex items-center justify-center",
|
|
2797
|
-
children: /* @__PURE__ */ jsxs("button", {
|
|
2798
|
-
type: "button",
|
|
2799
|
-
"aria-label": allSelected ? "Deselect all" : "Select all",
|
|
2800
|
-
onClick: onSelectAll,
|
|
2801
|
-
className: `
|
|
2802
|
-
h-4 w-4 rounded border flex items-center justify-center transition-colors cursor-pointer
|
|
2803
|
-
${allSelected || someSelected ? "bg-login border-login text-white" : "border-login-400 bg-transparent hover:border-login-200"}
|
|
2804
|
-
`,
|
|
2805
|
-
children: [someSelected && !allSelected && /* @__PURE__ */ jsx("span", { className: "block h-0.5 w-2 bg-white rounded-full" }), allSelected && /* @__PURE__ */ jsx("svg", {
|
|
2806
|
-
className: "h-3 w-3",
|
|
2807
|
-
viewBox: "0 0 12 12",
|
|
2808
|
-
fill: "none",
|
|
2809
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
2810
|
-
d: "M2 6l3 3 5-5",
|
|
2811
|
-
stroke: "currentColor",
|
|
2812
|
-
strokeWidth: "1.5",
|
|
2813
|
-
strokeLinecap: "round",
|
|
2814
|
-
strokeLinejoin: "round"
|
|
2815
|
-
})
|
|
2816
|
-
})]
|
|
2817
|
-
})
|
|
2818
|
-
})
|
|
2819
|
-
}),
|
|
2820
|
-
columns.map((col) => {
|
|
2821
|
-
const sortable = col.sortable !== false;
|
|
2822
|
-
const isActive = sort?.column === col.key;
|
|
2823
|
-
const ariaSort = isActive ? sort.order === "asc" ? "ascending" : "descending" : "none";
|
|
2824
|
-
const alignClass = col.align === "right" ? "justify-end" : col.align === "center" ? "justify-center" : "";
|
|
2825
|
-
return /* @__PURE__ */ jsx("th", {
|
|
2826
|
-
"aria-sort": sortable ? ariaSort : void 0,
|
|
2827
|
-
style: col.width ? { width: col.width } : void 0,
|
|
2828
|
-
className: `
|
|
2829
|
-
sticky top-0 z-10 ${VARIANT_HEAD_BG[variant]} ${VARIANT_HEAD_BORDER[variant]}
|
|
2830
|
-
text-xs font-medium uppercase tracking-wider
|
|
2831
|
-
${DENSITY_TH[density]} ${VARIANT_THEAD_TH[variant]}
|
|
2832
|
-
`,
|
|
2833
|
-
children: sortable ? /* @__PURE__ */ jsxs("button", {
|
|
2834
|
-
type: "button",
|
|
2835
|
-
className: `group inline-flex items-center gap-1.5 w-full cursor-pointer ${alignClass}`,
|
|
2836
|
-
onClick: () => handleSort(col.key),
|
|
2837
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
2838
|
-
className: "whitespace-nowrap",
|
|
2839
|
-
children: formatLabel(col.key, col.label)
|
|
2840
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
2841
|
-
className: "shrink-0 text-current",
|
|
2842
|
-
children: isActive ? sort.order === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-3.5 w-3.5 opacity-0 group-hover:opacity-35 transition-opacity" })
|
|
2843
|
-
})]
|
|
2844
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
2845
|
-
className: `flex w-full whitespace-nowrap ${alignClass}`,
|
|
2846
|
-
children: formatLabel(col.key, col.label)
|
|
2847
|
-
})
|
|
2848
|
-
}, col.key);
|
|
2849
|
-
}),
|
|
2850
|
-
hasExpand && /* @__PURE__ */ jsx("th", {
|
|
2851
|
-
className: `sticky top-0 z-10 ${VARIANT_HEAD_BG[variant]} ${VARIANT_HEAD_BORDER[variant]}`,
|
|
2852
|
-
style: {
|
|
2853
|
-
width: "2.5rem",
|
|
2854
|
-
minWidth: "2.5rem"
|
|
2855
|
-
},
|
|
2856
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
2857
|
-
className: `
|
|
2858
|
-
flex items-center justify-center
|
|
2859
|
-
text-xs font-medium tracking-wider uppercase opacity-50
|
|
2860
|
-
${VARIANT_THEAD_TH[variant]}
|
|
2861
|
-
`,
|
|
2862
|
-
children: "+"
|
|
2863
|
-
})
|
|
2864
|
-
}),
|
|
2865
|
-
hasMenu && /* @__PURE__ */ jsx("th", {
|
|
2866
|
-
"aria-hidden": "true",
|
|
2867
|
-
className: `sticky top-0 z-10 ${VARIANT_HEAD_BG[variant]} ${VARIANT_HEAD_BORDER[variant]}`,
|
|
2868
|
-
style: {
|
|
2869
|
-
width: "3.5rem",
|
|
2870
|
-
minWidth: "3.5rem"
|
|
2871
|
-
}
|
|
2872
|
-
})
|
|
2873
|
-
] })
|
|
2874
|
-
});
|
|
2875
|
-
}
|
|
2876
|
-
//#endregion
|
|
2877
|
-
//#region src/components/table/format.ts
|
|
2878
|
-
const nullableTimeKeys = /* @__PURE__ */ new Set([
|
|
2879
|
-
"date",
|
|
2880
|
-
"last_sent",
|
|
2881
|
-
"sent_at",
|
|
2882
|
-
"time"
|
|
2883
|
-
]);
|
|
2884
|
-
const RX_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
|
|
2885
|
-
const RX_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
2886
|
-
const RX_TIME = /^\d{2}:\d{2}(:\d{2})?$/;
|
|
2887
|
-
function formatValue(key, value) {
|
|
2888
|
-
if (value === null || value === void 0) return nullableTimeKeys.has(key) ? "Never" : "-";
|
|
2889
|
-
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
2890
|
-
if (typeof value === "number") {
|
|
2891
|
-
if (key.includes("capacity") && value === 0) return "Unlimited";
|
|
2892
|
-
return value;
|
|
2893
|
-
}
|
|
2894
|
-
if (typeof value === "string") {
|
|
2895
|
-
if (RX_DATETIME.test(value)) return new Date(value).toLocaleString("nb-NO", {
|
|
2896
|
-
timeZone: "Europe/Oslo",
|
|
2897
|
-
year: "numeric",
|
|
2898
|
-
month: "2-digit",
|
|
2899
|
-
day: "2-digit",
|
|
2900
|
-
hour: "2-digit",
|
|
2901
|
-
minute: "2-digit"
|
|
2902
|
-
});
|
|
2903
|
-
if (RX_DATE.test(value)) return new Date(value).toLocaleDateString("nb-NO", { timeZone: "Europe/Oslo" });
|
|
2904
|
-
if (RX_TIME.test(value)) return (/* @__PURE__ */ new Date(`1970-01-01T${value}`)).toLocaleTimeString("nb-NO", {
|
|
2905
|
-
timeZone: "Europe/Oslo",
|
|
2906
|
-
hour: "2-digit",
|
|
2907
|
-
minute: "2-digit"
|
|
2908
|
-
});
|
|
2909
|
-
return value;
|
|
2910
|
-
}
|
|
2911
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
2912
|
-
return String(value);
|
|
2913
|
-
}
|
|
2914
|
-
//#endregion
|
|
2915
|
-
//#region src/components/table/utils.ts
|
|
2916
|
-
function resolveId(row, idKey, columns) {
|
|
2917
|
-
if (idKey && row[idKey] !== void 0) return String(row[idKey]);
|
|
2918
|
-
if (row["id"] !== void 0) return String(row["id"]);
|
|
2919
|
-
const firstKey = columns[0]?.key ?? Object.keys(row)[0];
|
|
2920
|
-
return String(row[firstKey] ?? "");
|
|
2921
|
-
}
|
|
2922
|
-
//#endregion
|
|
2923
|
-
//#region src/components/table/menu.tsx
|
|
2924
|
-
const MenuCtx = createContext({});
|
|
2925
|
-
function Menu({ ref, children, anchor, onClose }) {
|
|
2926
|
-
useEffect(() => {
|
|
2927
|
-
function handleKey(e) {
|
|
2928
|
-
if (e.key === "Escape") onClose?.();
|
|
2929
|
-
}
|
|
2930
|
-
window.addEventListener("keydown", handleKey);
|
|
2931
|
-
return () => window.removeEventListener("keydown", handleKey);
|
|
2932
|
-
}, [onClose]);
|
|
2933
|
-
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
2934
|
-
ref,
|
|
2935
|
-
role: "menu",
|
|
2936
|
-
"aria-orientation": "vertical",
|
|
2937
|
-
style: {
|
|
2938
|
-
top: anchor.top,
|
|
2939
|
-
right: anchor.right
|
|
2940
|
-
},
|
|
2941
|
-
className: "fixed z-[9999] w-44 overflow-hidden rounded-lg border border-login-500/60 bg-login-600 shadow-xl shadow-black/40",
|
|
2942
|
-
children: /* @__PURE__ */ jsx(MenuCtx.Provider, {
|
|
2943
|
-
value: { onClose },
|
|
2944
|
-
children
|
|
2945
|
-
})
|
|
2946
|
-
}), document.body);
|
|
2947
|
-
}
|
|
2948
|
-
function MenuButton({ icon, text, hotKey, onClick, className = "" }) {
|
|
2949
|
-
const { onClose } = useContext(MenuCtx);
|
|
2950
|
-
useEffect(() => {
|
|
2951
|
-
if (!hotKey) return;
|
|
2952
|
-
function handleKey(e) {
|
|
2953
|
-
const tag = e.target.tagName;
|
|
2954
|
-
if (tag === "INPUT" || tag === "TEXTAREA") return;
|
|
2955
|
-
if (e.key.toLowerCase() === hotKey.toLowerCase()) {
|
|
2956
|
-
e.preventDefault();
|
|
2957
|
-
onClick();
|
|
2958
|
-
onClose?.();
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
window.addEventListener("keydown", handleKey);
|
|
2962
|
-
return () => window.removeEventListener("keydown", handleKey);
|
|
2963
|
-
}, [
|
|
2964
|
-
hotKey,
|
|
2965
|
-
onClick,
|
|
2966
|
-
onClose
|
|
2967
|
-
]);
|
|
2968
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
2969
|
-
role: "menuitem",
|
|
2970
|
-
onClick: () => {
|
|
2971
|
-
onClick();
|
|
2972
|
-
onClose?.();
|
|
2973
|
-
},
|
|
2974
|
-
className: `
|
|
2975
|
-
flex w-full items-center justify-between px-3 py-2 text-sm
|
|
2976
|
-
text-login-75 transition-colors duration-100
|
|
2977
|
-
hover:bg-login-500 focus:bg-login-500 focus:outline-none
|
|
2978
|
-
first:rounded-t-lg last:rounded-b-lg
|
|
2979
|
-
${className}
|
|
2980
|
-
`,
|
|
2981
|
-
children: [/* @__PURE__ */ jsxs("span", {
|
|
2982
|
-
className: "flex items-center gap-2",
|
|
2983
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
2984
|
-
className: "h-4 w-4 shrink-0 flex items-center justify-center",
|
|
2985
|
-
children: icon
|
|
2986
|
-
}), text]
|
|
2987
|
-
}), hotKey && /* @__PURE__ */ jsx("kbd", {
|
|
2988
|
-
className: "font-mono text-xs opacity-40",
|
|
2989
|
-
children: hotKey
|
|
2990
|
-
})]
|
|
2991
|
-
});
|
|
2992
|
-
}
|
|
2993
|
-
//#endregion
|
|
2994
|
-
//#region src/components/table/body.tsx
|
|
2995
|
-
function useClickOutside(ref, cb, enabled) {
|
|
2996
|
-
useEffect(() => {
|
|
2997
|
-
if (!enabled) return;
|
|
2998
|
-
function handler(e) {
|
|
2999
|
-
if (ref.current && !ref.current.contains(e.target)) cb();
|
|
3000
|
-
}
|
|
3001
|
-
document.addEventListener("mousedown", handler);
|
|
3002
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
3003
|
-
}, [
|
|
3004
|
-
ref,
|
|
3005
|
-
cb,
|
|
3006
|
-
enabled
|
|
3007
|
-
]);
|
|
3008
|
-
}
|
|
3009
|
-
function resolveRedirectUrl(redirectPath, row, id) {
|
|
3010
|
-
if (!redirectPath) return null;
|
|
3011
|
-
const cfg = typeof redirectPath === "string" ? {
|
|
3012
|
-
path: redirectPath,
|
|
3013
|
-
key: void 0
|
|
3014
|
-
} : redirectPath;
|
|
3015
|
-
if (!cfg.path) return null;
|
|
3016
|
-
const rid = cfg.key ? String(row[cfg.key] ?? id) : id;
|
|
3017
|
-
return cfg.path.includes("?") ? `${cfg.path}${rid}` : `${cfg.path}/${rid}`;
|
|
3018
|
-
}
|
|
3019
|
-
function Cell({ col, row, density, variant }) {
|
|
3020
|
-
const value = row[col.key];
|
|
3021
|
-
const shouldTruncate = col.truncate === true;
|
|
3022
|
-
const align = col.align ?? "left";
|
|
3023
|
-
const wrapperAlign = align === "right" ? "text-right" : align === "center" ? "text-center" : "";
|
|
3024
|
-
let content;
|
|
3025
|
-
if (col.render) content = col.render(value, row);
|
|
3026
|
-
else if (col.highlight) {
|
|
3027
|
-
const colorName = col.highlight[String(value)] ?? col.highlight["default"];
|
|
3028
|
-
const formatted = String(formatValue(col.key, value));
|
|
3029
|
-
if (colorName) content = /* @__PURE__ */ jsx("span", {
|
|
3030
|
-
className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${HIGHLIGHT[colorName]}`,
|
|
3031
|
-
children: formatted
|
|
3032
|
-
});
|
|
3033
|
-
else content = /* @__PURE__ */ jsx("span", {
|
|
3034
|
-
className: shouldTruncate ? "block truncate" : "whitespace-nowrap",
|
|
3035
|
-
children: formatted
|
|
3036
|
-
});
|
|
3037
|
-
} else {
|
|
3038
|
-
const formatted = formatValue(col.key, value);
|
|
3039
|
-
content = /* @__PURE__ */ jsx("span", {
|
|
3040
|
-
className: shouldTruncate ? "block truncate" : "whitespace-nowrap",
|
|
3041
|
-
children: formatted === null || formatted === void 0 ? "-" : String(formatted)
|
|
3042
|
-
});
|
|
3043
|
-
}
|
|
3044
|
-
return /* @__PURE__ */ jsx("td", {
|
|
3045
|
-
style: col.width ? {
|
|
3046
|
-
width: col.width,
|
|
3047
|
-
maxWidth: col.width
|
|
3048
|
-
} : void 0,
|
|
3049
|
-
className: `
|
|
3050
|
-
align-middle text-sm text-login-75 ${wrapperAlign}
|
|
3051
|
-
${DENSITY_TD[density]} ${VARIANT_ROW_BORDER[variant]}
|
|
3052
|
-
`,
|
|
3053
|
-
children: content
|
|
3054
|
-
});
|
|
3055
|
-
}
|
|
3056
|
-
function Body({ data, columns, idKey, variant, density, striped, redirectPath, onRowClick, renderExpandedRow, selectable, selectedIds, onSelectionChange, menuItems }) {
|
|
3057
|
-
const router = useRouter();
|
|
3058
|
-
const [openMenuId, setOpenMenuId] = useState(null);
|
|
3059
|
-
const [anchor, setAnchor] = useState(null);
|
|
3060
|
-
const [expandedId, setExpandedId] = useState(null);
|
|
3061
|
-
const menuRef = useRef(null);
|
|
3062
|
-
const menuWasOpenOnMouseDown = useRef(false);
|
|
3063
|
-
const closeMenu = useCallback(() => setOpenMenuId(null), []);
|
|
3064
|
-
useClickOutside(menuRef, closeMenu, openMenuId !== null);
|
|
3065
|
-
useEffect(() => {
|
|
3066
|
-
if (openMenuId === null) return;
|
|
3067
|
-
document.addEventListener("scroll", closeMenu, true);
|
|
3068
|
-
return () => document.removeEventListener("scroll", closeMenu, true);
|
|
3069
|
-
}, [closeMenu, openMenuId]);
|
|
3070
|
-
function openMenu(id, coords) {
|
|
3071
|
-
setAnchor(coords);
|
|
3072
|
-
setOpenMenuId(id);
|
|
3073
|
-
}
|
|
3074
|
-
const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
|
|
3075
|
-
function toggleSelect(id) {
|
|
3076
|
-
onSelectionChange(selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]);
|
|
3077
|
-
}
|
|
3078
|
-
const hasMenu = Boolean(menuItems);
|
|
3079
|
-
const hasExpand = Boolean(renderExpandedRow);
|
|
3080
|
-
return /* @__PURE__ */ jsx("tbody", {
|
|
3081
|
-
className: VARIANT_TBODY[variant],
|
|
3082
|
-
children: data.map((row, rowIdx) => {
|
|
3083
|
-
const id = resolveId(row, idKey, columns);
|
|
3084
|
-
const url = resolveRedirectUrl(redirectPath, row, id);
|
|
3085
|
-
const isClickable = Boolean(url || onRowClick || hasExpand);
|
|
3086
|
-
const isMenuOpen = openMenuId === id;
|
|
3087
|
-
const isExpanded = expandedId === id;
|
|
3088
|
-
const isSelected = selectable && selectedSet.has(id);
|
|
3089
|
-
const expandedContent = renderExpandedRow?.(row);
|
|
3090
|
-
const rowClass = [
|
|
3091
|
-
"transition-colors duration-100",
|
|
3092
|
-
isClickable ? "cursor-pointer" : "",
|
|
3093
|
-
VARIANT_ROW_HOVER[variant],
|
|
3094
|
-
striped ? VARIANT_ROW_STRIPED[variant] : "",
|
|
3095
|
-
isSelected ? "bg-login/5" : ""
|
|
3096
|
-
].filter(Boolean).join(" ");
|
|
3097
|
-
return /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsxs("tr", {
|
|
3098
|
-
className: rowClass,
|
|
3099
|
-
onMouseEnter: () => {
|
|
3100
|
-
if (url) router.prefetch(url);
|
|
3101
|
-
},
|
|
3102
|
-
onMouseDown: () => {
|
|
3103
|
-
menuWasOpenOnMouseDown.current = openMenuId !== null;
|
|
3104
|
-
},
|
|
3105
|
-
onClick: () => {
|
|
3106
|
-
if (menuWasOpenOnMouseDown.current) {
|
|
3107
|
-
menuWasOpenOnMouseDown.current = false;
|
|
3108
|
-
return;
|
|
3109
|
-
}
|
|
3110
|
-
if (hasExpand) {
|
|
3111
|
-
setExpandedId(isExpanded ? null : id);
|
|
3112
|
-
return;
|
|
3113
|
-
}
|
|
3114
|
-
if (onRowClick) {
|
|
3115
|
-
onRowClick(row, id);
|
|
3116
|
-
return;
|
|
3117
|
-
}
|
|
3118
|
-
if (url) router.push(url);
|
|
3119
|
-
},
|
|
3120
|
-
onContextMenu: (e) => {
|
|
3121
|
-
if (!hasMenu) return;
|
|
3122
|
-
e.preventDefault();
|
|
3123
|
-
openMenu(id, {
|
|
3124
|
-
top: e.clientY,
|
|
3125
|
-
right: window.innerWidth - e.clientX
|
|
3126
|
-
});
|
|
3127
|
-
},
|
|
3128
|
-
children: [
|
|
3129
|
-
selectable && /* @__PURE__ */ jsx("td", {
|
|
3130
|
-
className: `align-middle ${VARIANT_ROW_BORDER[variant]}`,
|
|
3131
|
-
style: {
|
|
3132
|
-
width: "3rem",
|
|
3133
|
-
minWidth: "3rem"
|
|
3134
|
-
},
|
|
3135
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
3136
|
-
className: "flex items-center justify-center",
|
|
3137
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
3138
|
-
type: "button",
|
|
3139
|
-
"aria-label": isSelected ? "Deselect row" : "Select row",
|
|
3140
|
-
"aria-checked": isSelected,
|
|
3141
|
-
role: "checkbox",
|
|
3142
|
-
onClick: (e) => {
|
|
3143
|
-
e.stopPropagation();
|
|
3144
|
-
toggleSelect(id);
|
|
3145
|
-
},
|
|
3146
|
-
className: `
|
|
3147
|
-
h-4 w-4 rounded border flex items-center justify-center transition-colors cursor-pointer
|
|
3148
|
-
${isSelected ? "bg-login border-login text-white" : "border-login-400 bg-transparent hover:border-login-100"}
|
|
3149
|
-
`,
|
|
3150
|
-
children: isSelected && /* @__PURE__ */ jsx("svg", {
|
|
3151
|
-
className: "h-3 w-3",
|
|
3152
|
-
viewBox: "0 0 12 12",
|
|
3153
|
-
fill: "none",
|
|
3154
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
3155
|
-
d: "M2 6l3 3 5-5",
|
|
3156
|
-
stroke: "currentColor",
|
|
3157
|
-
strokeWidth: "1.5",
|
|
3158
|
-
strokeLinecap: "round",
|
|
3159
|
-
strokeLinejoin: "round"
|
|
3160
|
-
})
|
|
3161
|
-
})
|
|
3162
|
-
})
|
|
3163
|
-
})
|
|
3164
|
-
}),
|
|
3165
|
-
columns.map((col) => /* @__PURE__ */ jsx(Cell, {
|
|
3166
|
-
col,
|
|
3167
|
-
row,
|
|
3168
|
-
density,
|
|
3169
|
-
variant
|
|
3170
|
-
}, col.key)),
|
|
3171
|
-
hasExpand && /* @__PURE__ */ jsx("td", {
|
|
3172
|
-
className: `align-middle ${VARIANT_ROW_BORDER[variant]}`,
|
|
3173
|
-
style: {
|
|
3174
|
-
width: "2.5rem",
|
|
3175
|
-
minWidth: "2.5rem"
|
|
3176
|
-
},
|
|
3177
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
3178
|
-
className: "flex items-center justify-center",
|
|
3179
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className: `
|
|
3180
|
-
h-4 w-4 transition-transform duration-200
|
|
3181
|
-
${isExpanded ? "rotate-180 text-login" : "text-login-400"}
|
|
3182
|
-
` })
|
|
3183
|
-
})
|
|
3184
|
-
}),
|
|
3185
|
-
hasMenu && /* @__PURE__ */ jsx("td", {
|
|
3186
|
-
className: `align-middle pr-3 ${VARIANT_ROW_BORDER[variant]}`,
|
|
3187
|
-
style: {
|
|
3188
|
-
width: "3.5rem",
|
|
3189
|
-
minWidth: "3.5rem"
|
|
3190
|
-
},
|
|
3191
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
3192
|
-
className: "relative flex items-center justify-end",
|
|
3193
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
3194
|
-
type: "button",
|
|
3195
|
-
"aria-label": "Row actions",
|
|
3196
|
-
"aria-expanded": isMenuOpen,
|
|
3197
|
-
"aria-haspopup": "menu",
|
|
3198
|
-
onMouseDown: (e) => e.nativeEvent.stopImmediatePropagation(),
|
|
3199
|
-
onClick: (e) => {
|
|
3200
|
-
e.stopPropagation();
|
|
3201
|
-
if (isMenuOpen) setOpenMenuId(null);
|
|
3202
|
-
else {
|
|
3203
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
3204
|
-
openMenu(id, {
|
|
3205
|
-
top: rect.bottom + 4,
|
|
3206
|
-
right: window.innerWidth - rect.right
|
|
3207
|
-
});
|
|
3208
|
-
}
|
|
3209
|
-
},
|
|
3210
|
-
className: `
|
|
3211
|
-
p-1.5 rounded flex items-center justify-center transition-colors
|
|
3212
|
-
${isMenuOpen ? "bg-login-500 text-login-75" : "text-login-300 hover:bg-login-500/60 hover:text-login-75"}
|
|
3213
|
-
`,
|
|
3214
|
-
children: /* @__PURE__ */ jsx(EllipsisVertical, { className: "h-4 w-4" })
|
|
3215
|
-
}), isMenuOpen && anchor && /* @__PURE__ */ jsx(Menu, {
|
|
3216
|
-
ref: menuRef,
|
|
3217
|
-
anchor,
|
|
3218
|
-
onClose: closeMenu,
|
|
3219
|
-
children: menuItems(row, id)
|
|
3220
|
-
})]
|
|
3221
|
-
})
|
|
3222
|
-
})
|
|
3223
|
-
]
|
|
3224
|
-
}), hasExpand && isExpanded && /* @__PURE__ */ jsx("tr", {
|
|
3225
|
-
className: "bg-login-700/25",
|
|
3226
|
-
children: /* @__PURE__ */ jsx("td", {
|
|
3227
|
-
colSpan: 999,
|
|
3228
|
-
className: "px-6 py-4 border-b border-login-600/20",
|
|
3229
|
-
onClick: (e) => e.stopPropagation(),
|
|
3230
|
-
children: expandedContent
|
|
3231
|
-
})
|
|
3232
|
-
})] }, id + rowIdx);
|
|
3233
|
-
})
|
|
3234
|
-
});
|
|
3235
|
-
}
|
|
3236
|
-
//#endregion
|
|
3237
|
-
//#region src/components/table/skeleton.tsx
|
|
3238
|
-
function Skeleton({ columns, rows, variant, density, hasMenu, hasSelect }) {
|
|
3239
|
-
return /* @__PURE__ */ jsx("tbody", {
|
|
3240
|
-
className: VARIANT_TBODY[variant],
|
|
3241
|
-
children: Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
3242
|
-
hasSelect && /* @__PURE__ */ jsx("td", {
|
|
3243
|
-
className: `align-middle ${VARIANT_ROW_BORDER[variant]}`,
|
|
3244
|
-
style: {
|
|
3245
|
-
width: "3rem",
|
|
3246
|
-
minWidth: "3rem"
|
|
3247
|
-
},
|
|
3248
|
-
children: /* @__PURE__ */ jsx("span", { className: "block h-4 w-4 mx-auto rounded animate-shimmer" })
|
|
3249
|
-
}),
|
|
3250
|
-
columns.map((col, colIdx) => /* @__PURE__ */ jsx("td", {
|
|
3251
|
-
style: col.width ? { width: col.width } : void 0,
|
|
3252
|
-
className: `align-middle ${DENSITY_TD[density]} ${VARIANT_ROW_BORDER[variant]}`,
|
|
3253
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
3254
|
-
className: "block h-4 rounded animate-shimmer",
|
|
3255
|
-
style: {
|
|
3256
|
-
width: colIdx === 0 ? `${8 + (rowIdx * 17 + colIdx * 31) % 5}rem` : `${5 + (rowIdx * 13 + colIdx * 23) % 5}rem`,
|
|
3257
|
-
animationDelay: `${(rowIdx * columns.length + colIdx) * 40}ms`
|
|
3258
|
-
}
|
|
3259
|
-
})
|
|
3260
|
-
}, col.key)),
|
|
3261
|
-
hasMenu && /* @__PURE__ */ jsx("td", {
|
|
3262
|
-
className: `align-middle pr-3 ${VARIANT_ROW_BORDER[variant]}`,
|
|
3263
|
-
style: {
|
|
3264
|
-
width: "3.5rem",
|
|
3265
|
-
minWidth: "3.5rem"
|
|
3266
|
-
},
|
|
3267
|
-
children: /* @__PURE__ */ jsx("span", { className: "block h-5 w-5 ml-auto rounded animate-shimmer" })
|
|
3268
|
-
})
|
|
3269
|
-
] }, rowIdx))
|
|
3270
|
-
});
|
|
3271
|
-
}
|
|
3272
|
-
//#endregion
|
|
3273
|
-
//#region src/components/table/empty.tsx
|
|
3274
|
-
function Empty({ emptyState }) {
|
|
3275
|
-
if (emptyState) return /* @__PURE__ */ jsx("tbody", { children: /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
3276
|
-
colSpan: 999,
|
|
3277
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
3278
|
-
className: "flex items-center justify-center min-h-[160px] py-8 px-6",
|
|
3279
|
-
children: emptyState
|
|
3280
|
-
})
|
|
3281
|
-
}) }) });
|
|
3282
|
-
return /* @__PURE__ */ jsx("tbody", { children: /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
3283
|
-
colSpan: 999,
|
|
3284
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
3285
|
-
className: "flex flex-col items-center justify-center gap-3 min-h-[160px] py-8 text-login-300",
|
|
3286
|
-
children: [/* @__PURE__ */ jsx(TableIcon, { className: "h-10 w-10 opacity-30" }), /* @__PURE__ */ jsx("span", {
|
|
3287
|
-
className: "text-sm",
|
|
3288
|
-
children: "No data found"
|
|
3289
|
-
})]
|
|
3290
|
-
})
|
|
3291
|
-
}) }) });
|
|
3292
|
-
}
|
|
3293
|
-
//#endregion
|
|
3294
|
-
//#region src/components/table/pagination.tsx
|
|
3295
|
-
function computeTotalPages(totalRows, pageSize) {
|
|
3296
|
-
return Math.max(1, pageSize > 0 ? Math.ceil(totalRows / pageSize) : 1);
|
|
3297
|
-
}
|
|
3298
|
-
function pageRange(current, total) {
|
|
3299
|
-
const delta = 2;
|
|
3300
|
-
const left = Math.max(1, current - delta);
|
|
3301
|
-
const right = Math.min(total, current + delta);
|
|
3302
|
-
const pages = [];
|
|
3303
|
-
if (left > 1) {
|
|
3304
|
-
pages.push(1);
|
|
3305
|
-
if (left > 2) pages.push("…");
|
|
3306
|
-
}
|
|
3307
|
-
for (let i = left; i <= right; i++) pages.push(i);
|
|
3308
|
-
if (right < total) {
|
|
3309
|
-
if (right < total - 1) pages.push("…");
|
|
3310
|
-
pages.push(total);
|
|
3311
|
-
}
|
|
3312
|
-
return pages;
|
|
3313
|
-
}
|
|
3314
|
-
function PaginationShell({ page, totalPages, totalRows, pageSize, onPageChange, variant }) {
|
|
3315
|
-
const start = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
3316
|
-
const end = Math.min(page * pageSize, totalRows);
|
|
3317
|
-
const pages = pageRange(page, totalPages);
|
|
3318
|
-
const btnBase = `
|
|
3319
|
-
flex items-center justify-center rounded-md border text-sm transition-colors duration-100
|
|
3320
|
-
disabled:opacity-35 disabled:cursor-not-allowed
|
|
3321
|
-
`;
|
|
3322
|
-
const btnStyle = variant === "original" ? "border-login-500/50 bg-login-700 hover:bg-login-600 text-login-100" : "border-login-500/40 bg-transparent hover:bg-login-700/60 text-login-100";
|
|
3323
|
-
const pageActive = variant === "original" ? "border-login bg-login/10 text-login" : "border-login text-login bg-transparent";
|
|
3324
|
-
const pageInactive = variant === "original" ? "border-login-500/50 bg-login-700 text-login-100 hover:bg-login-600" : "border-transparent bg-transparent text-login-200 hover:text-login-75 hover:bg-login-700/60";
|
|
3325
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3326
|
-
className: "flex items-center justify-between w-full gap-4 flex-wrap",
|
|
3327
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3328
|
-
className: "text-xs text-login-300 tabular-nums",
|
|
3329
|
-
children: totalRows === 0 ? "No results" : `${start}-${end} of ${totalRows}`
|
|
3330
|
-
}), /* @__PURE__ */ jsxs("nav", {
|
|
3331
|
-
className: "flex items-center gap-1.5",
|
|
3332
|
-
"aria-label": "Pagination",
|
|
3333
|
-
children: [
|
|
3334
|
-
/* @__PURE__ */ jsx("button", {
|
|
3335
|
-
type: "button",
|
|
3336
|
-
"aria-label": "Previous page",
|
|
3337
|
-
disabled: page <= 1,
|
|
3338
|
-
onClick: () => onPageChange(page - 1),
|
|
3339
|
-
className: `${btnBase} ${btnStyle} h-8 w-8`,
|
|
3340
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
3341
|
-
}),
|
|
3342
|
-
pages.map((p, i) => p === "…" ? /* @__PURE__ */ jsx("span", {
|
|
3343
|
-
className: "w-8 text-center text-sm text-login-400 select-none",
|
|
3344
|
-
children: "…"
|
|
3345
|
-
}, `ellipsis-${i}`) : /* @__PURE__ */ jsx("button", {
|
|
3346
|
-
type: "button",
|
|
3347
|
-
"aria-current": p === page ? "page" : void 0,
|
|
3348
|
-
onClick: () => onPageChange(p),
|
|
3349
|
-
className: `${btnBase} h-8 min-w-8 px-2 tabular-nums ${p === page ? pageActive : pageInactive}`,
|
|
3350
|
-
children: p
|
|
3351
|
-
}, p)),
|
|
3352
|
-
/* @__PURE__ */ jsx("button", {
|
|
3353
|
-
type: "button",
|
|
3354
|
-
"aria-label": "Next page",
|
|
3355
|
-
disabled: page >= totalPages,
|
|
3356
|
-
onClick: () => onPageChange(page + 1),
|
|
3357
|
-
className: `${btnBase} ${btnStyle} h-8 w-8`,
|
|
3358
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
3359
|
-
})
|
|
3360
|
-
]
|
|
3361
|
-
})]
|
|
3362
|
-
});
|
|
3363
|
-
}
|
|
3364
|
-
function PaginationLocalState({ totalRows, pageSize, variant = "original" }) {
|
|
3365
|
-
const [page, setPage] = useState(1);
|
|
3366
|
-
return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3367
|
-
page,
|
|
3368
|
-
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3369
|
-
totalRows,
|
|
3370
|
-
pageSize,
|
|
3371
|
-
onPageChange: setPage,
|
|
3372
|
-
variant
|
|
3373
|
-
});
|
|
3374
|
-
}
|
|
3375
|
-
function PaginationURLState({ totalRows, pageSize, variant = "original" }) {
|
|
3376
|
-
const router = useRouter();
|
|
3377
|
-
const pathname = usePathname();
|
|
3378
|
-
const searchParams = useSearchParams();
|
|
3379
|
-
const page = Math.max(1, parseInt(searchParams.get("page") ?? "1", 10) || 1);
|
|
3380
|
-
function onPageChange(p) {
|
|
3381
|
-
const params = new URLSearchParams(searchParams.toString());
|
|
3382
|
-
params.set("page", String(p));
|
|
3383
|
-
router.replace(`${pathname}?${params.toString()}`);
|
|
3384
|
-
}
|
|
3385
|
-
return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3386
|
-
page,
|
|
3387
|
-
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3388
|
-
totalRows,
|
|
3389
|
-
pageSize,
|
|
3390
|
-
onPageChange,
|
|
3391
|
-
variant
|
|
3392
|
-
});
|
|
3393
|
-
}
|
|
3394
|
-
function Pagination(props) {
|
|
3395
|
-
const { totalRows, pageSize, variant = "original", urlState, page, onPageChange } = props;
|
|
3396
|
-
if (urlState) return /* @__PURE__ */ jsx(Suspense, {
|
|
3397
|
-
fallback: /* @__PURE__ */ jsx(PaginationShell, {
|
|
3398
|
-
page: 1,
|
|
3399
|
-
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3400
|
-
totalRows,
|
|
3401
|
-
pageSize,
|
|
3402
|
-
onPageChange: () => {},
|
|
3403
|
-
variant
|
|
3404
|
-
}),
|
|
3405
|
-
children: /* @__PURE__ */ jsx(PaginationURLState, { ...props })
|
|
3406
|
-
});
|
|
3407
|
-
if (page !== void 0 && onPageChange !== void 0) return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3408
|
-
page,
|
|
3409
|
-
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3410
|
-
totalRows,
|
|
3411
|
-
pageSize,
|
|
3412
|
-
onPageChange,
|
|
3413
|
-
variant
|
|
3414
|
-
});
|
|
3415
|
-
return /* @__PURE__ */ jsx(PaginationLocalState, { ...props });
|
|
3416
|
-
}
|
|
3417
|
-
//#endregion
|
|
3418
|
-
//#region src/components/table/table.tsx
|
|
3419
|
-
function TableShell({ data, columns, idKey, variant, density, striped, loading, loadingRows, emptyState, redirectPath, onRowClick, renderExpandedRow, selectable, selectedIds, onSelectionChange, sort, onSort, page, onPageChange, totalRows, pageSize, hidePagination, menuItems, className }) {
|
|
3420
|
-
const allIds = data.map((row) => resolveId(row, idKey, columns));
|
|
3421
|
-
const allIdsSet = useMemo(() => new Set(allIds), [allIds]);
|
|
3422
|
-
const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.includes(id));
|
|
3423
|
-
const someSelected = !allSelected && allIds.some((id) => selectedIds.includes(id));
|
|
3424
|
-
function handleSelectAll() {
|
|
3425
|
-
if (allSelected) onSelectionChange(selectedIds.filter((id) => !allIdsSet.has(id)));
|
|
3426
|
-
else onSelectionChange([.../* @__PURE__ */ new Set([...selectedIds, ...allIds])]);
|
|
3427
|
-
}
|
|
3428
|
-
const isEmpty = !loading && data.length === 0;
|
|
3429
|
-
const showPagination = !hidePagination && pageSize > 0 && totalRows > 0;
|
|
3430
|
-
const hasMenu = Boolean(menuItems);
|
|
3431
|
-
const hasSelect = Boolean(selectable);
|
|
3432
|
-
const hasExpand = Boolean(renderExpandedRow);
|
|
3433
|
-
const paginationPad = variant === "original" ? "px-4 pb-4 pt-3" : "pt-4";
|
|
3434
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3435
|
-
className: [
|
|
3436
|
-
"flex flex-col min-h-0 w-full",
|
|
3437
|
-
VARIANT_CONTAINER[variant],
|
|
3438
|
-
className
|
|
3439
|
-
].filter(Boolean).join(" "),
|
|
3440
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3441
|
-
className: "flex-1 min-h-0 overflow-auto",
|
|
3442
|
-
children: /* @__PURE__ */ jsxs("table", {
|
|
3443
|
-
className: "min-w-full table-auto border-separate border-spacing-0",
|
|
3444
|
-
children: [/* @__PURE__ */ jsx(Header, {
|
|
3445
|
-
columns,
|
|
3446
|
-
sort,
|
|
3447
|
-
onSort,
|
|
3448
|
-
hasMenu,
|
|
3449
|
-
hasSelect,
|
|
3450
|
-
hasExpand,
|
|
3451
|
-
allSelected,
|
|
3452
|
-
someSelected,
|
|
3453
|
-
onSelectAll: handleSelectAll,
|
|
3454
|
-
variant,
|
|
3455
|
-
density
|
|
3456
|
-
}), loading ? /* @__PURE__ */ jsx(Skeleton, {
|
|
3457
|
-
columns,
|
|
3458
|
-
rows: loadingRows,
|
|
3459
|
-
variant,
|
|
3460
|
-
density,
|
|
3461
|
-
hasMenu,
|
|
3462
|
-
hasSelect
|
|
3463
|
-
}) : isEmpty ? /* @__PURE__ */ jsx(Empty, { emptyState }) : /* @__PURE__ */ jsx(Body, {
|
|
3464
|
-
data,
|
|
3465
|
-
columns,
|
|
3466
|
-
idKey,
|
|
3467
|
-
variant,
|
|
3468
|
-
density,
|
|
3469
|
-
striped,
|
|
3470
|
-
redirectPath,
|
|
3471
|
-
onRowClick,
|
|
3472
|
-
renderExpandedRow,
|
|
3473
|
-
selectable,
|
|
3474
|
-
selectedIds,
|
|
3475
|
-
onSelectionChange,
|
|
3476
|
-
menuItems
|
|
3477
|
-
})]
|
|
3478
|
-
})
|
|
3479
|
-
}), showPagination && /* @__PURE__ */ jsx("div", {
|
|
3480
|
-
className: paginationPad,
|
|
3481
|
-
children: /* @__PURE__ */ jsx(Pagination, {
|
|
3482
|
-
page,
|
|
3483
|
-
totalRows,
|
|
3484
|
-
pageSize,
|
|
3485
|
-
onPageChange,
|
|
3486
|
-
variant
|
|
3487
|
-
})
|
|
3488
|
-
})]
|
|
3489
|
-
});
|
|
3490
|
-
}
|
|
3491
|
-
function useInternalSelection(props) {
|
|
3492
|
-
const [internal, setInternal] = useState([]);
|
|
3493
|
-
return {
|
|
3494
|
-
selectedIds: props.selectedIds ?? internal,
|
|
3495
|
-
onSelectionChange: props.onSelectionChange ?? setInternal
|
|
3496
|
-
};
|
|
3497
|
-
}
|
|
3498
|
-
function applyDefaults(props) {
|
|
3499
|
-
return {
|
|
3500
|
-
variant: props.variant ?? "original",
|
|
3501
|
-
density: props.density ?? "comfortable",
|
|
3502
|
-
selectable: props.selectable ?? false,
|
|
3503
|
-
loading: props.loading ?? false,
|
|
3504
|
-
loadingRows: props.loadingRows ?? props.pageSize ?? 5,
|
|
3505
|
-
striped: props.striped ?? false,
|
|
3506
|
-
hidePagination: props.hidePagination ?? false,
|
|
3507
|
-
pageSize: props.pageSize ?? 0
|
|
3508
|
-
};
|
|
3509
|
-
}
|
|
3510
|
-
function TableLocalState(props) {
|
|
3511
|
-
const defaults = applyDefaults(props);
|
|
3512
|
-
const selection = useInternalSelection(props);
|
|
3513
|
-
const [sort, setSort] = useState(void 0);
|
|
3514
|
-
const [page, setPage] = useState(1);
|
|
3515
|
-
const ps = defaults.pageSize;
|
|
3516
|
-
const allRows = props.data.length;
|
|
3517
|
-
const sorted = useMemo(() => {
|
|
3518
|
-
if (!sort) return props.data;
|
|
3519
|
-
return [...props.data].sort((a, b) => {
|
|
3520
|
-
const av = a[sort.column];
|
|
3521
|
-
const bv = b[sort.column];
|
|
3522
|
-
const cmp = String(av ?? "").localeCompare(String(bv ?? ""), void 0, {
|
|
3523
|
-
numeric: true,
|
|
3524
|
-
sensitivity: "base"
|
|
3525
|
-
});
|
|
3526
|
-
return sort.order === "asc" ? cmp : -cmp;
|
|
3527
|
-
});
|
|
3528
|
-
}, [props.data, sort]);
|
|
3529
|
-
const displayData = ps > 0 ? sorted.slice((page - 1) * ps, page * ps) : sorted;
|
|
3530
|
-
function handleSort(newSort) {
|
|
3531
|
-
setSort(newSort);
|
|
3532
|
-
setPage(1);
|
|
3533
|
-
}
|
|
3534
|
-
return /* @__PURE__ */ jsx(TableShell, {
|
|
3535
|
-
...props,
|
|
3536
|
-
...defaults,
|
|
3537
|
-
...selection,
|
|
3538
|
-
data: displayData,
|
|
3539
|
-
sort,
|
|
3540
|
-
onSort: handleSort,
|
|
3541
|
-
page,
|
|
3542
|
-
onPageChange: setPage,
|
|
3543
|
-
totalRows: ps > 0 ? allRows : props.totalRows ?? allRows
|
|
3544
|
-
});
|
|
3545
|
-
}
|
|
3546
|
-
function TableURLState(props) {
|
|
3547
|
-
const defaults = applyDefaults(props);
|
|
3548
|
-
const selection = useInternalSelection(props);
|
|
3549
|
-
const router = useRouter();
|
|
3550
|
-
const pathname = usePathname();
|
|
3551
|
-
const searchParams = useSearchParams();
|
|
3552
|
-
const urlColumn = searchParams.get("column") ?? "";
|
|
3553
|
-
const urlOrder = searchParams.get("order") ?? "asc";
|
|
3554
|
-
const urlPage = Math.max(1, parseInt(searchParams.get("page") ?? "1", 10) || 1);
|
|
3555
|
-
const sort = urlColumn ? {
|
|
3556
|
-
column: urlColumn,
|
|
3557
|
-
order: urlOrder
|
|
3558
|
-
} : void 0;
|
|
3559
|
-
function handleSort(newSort) {
|
|
3560
|
-
const p = new URLSearchParams(searchParams.toString());
|
|
3561
|
-
p.set("column", newSort.column);
|
|
3562
|
-
p.set("order", newSort.order);
|
|
3563
|
-
p.set("page", "1");
|
|
3564
|
-
router.replace(`${pathname}?${p.toString()}`);
|
|
3565
|
-
}
|
|
3566
|
-
function handlePageChange(newPage) {
|
|
3567
|
-
const p = new URLSearchParams(searchParams.toString());
|
|
3568
|
-
p.set("page", String(newPage));
|
|
3569
|
-
router.replace(`${pathname}?${p.toString()}`);
|
|
3570
|
-
}
|
|
3571
|
-
return /* @__PURE__ */ jsx(TableShell, {
|
|
3572
|
-
...props,
|
|
3573
|
-
...defaults,
|
|
3574
|
-
...selection,
|
|
3575
|
-
sort,
|
|
3576
|
-
onSort: handleSort,
|
|
3577
|
-
page: urlPage,
|
|
3578
|
-
onPageChange: handlePageChange,
|
|
3579
|
-
totalRows: props.totalRows ?? props.data.length
|
|
3580
|
-
});
|
|
3581
|
-
}
|
|
3582
|
-
function TableControlled(props) {
|
|
3583
|
-
const defaults = applyDefaults(props);
|
|
3584
|
-
const selection = useInternalSelection(props);
|
|
3585
|
-
return /* @__PURE__ */ jsx(TableShell, {
|
|
3586
|
-
...props,
|
|
3587
|
-
...defaults,
|
|
3588
|
-
...selection,
|
|
3589
|
-
sort: props.sort,
|
|
3590
|
-
onSort: props.onSort,
|
|
3591
|
-
page: props.page ?? 1,
|
|
3592
|
-
onPageChange: props.onPageChange ?? (() => {}),
|
|
3593
|
-
totalRows: props.totalRows ?? props.data.length
|
|
3594
|
-
});
|
|
3595
|
-
}
|
|
3596
|
-
function Table(props) {
|
|
3597
|
-
if (props.sort !== void 0 || props.onSort !== void 0) return /* @__PURE__ */ jsx(TableControlled, { ...props });
|
|
3598
|
-
if (props.urlState) {
|
|
3599
|
-
const defaults = applyDefaults(props);
|
|
3600
|
-
return /* @__PURE__ */ jsx(Suspense, {
|
|
3601
|
-
fallback: /* @__PURE__ */ jsx(TableShell, {
|
|
3602
|
-
...props,
|
|
3603
|
-
...defaults,
|
|
3604
|
-
selectedIds: props.selectedIds ?? [],
|
|
3605
|
-
onSelectionChange: props.onSelectionChange ?? (() => {}),
|
|
3606
|
-
sort: void 0,
|
|
3607
|
-
onSort: () => {},
|
|
3608
|
-
page: 1,
|
|
3609
|
-
onPageChange: () => {},
|
|
3610
|
-
totalRows: props.totalRows ?? props.data.length
|
|
3611
|
-
}),
|
|
3612
|
-
children: /* @__PURE__ */ jsx(TableURLState, { ...props })
|
|
3613
|
-
});
|
|
3614
|
-
}
|
|
3615
|
-
return /* @__PURE__ */ jsx(TableLocalState, { ...props });
|
|
3616
|
-
}
|
|
3617
|
-
//#endregion
|
|
3618
|
-
//#region src/components/confirm/confirmPopup.tsx
|
|
3619
|
-
function ConfirmPopup({ isOpen, header, description, confirmText = "Confirm", cancelText = "Cancel", onConfirm, onCancel, variant = "default" }) {
|
|
3620
|
-
if (!isOpen) return null;
|
|
3621
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3622
|
-
role: "dialog",
|
|
3623
|
-
"aria-modal": "true",
|
|
3624
|
-
"aria-labelledby": "confirm-popup-header",
|
|
3625
|
-
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
3626
|
-
onClick: onCancel,
|
|
3627
|
-
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm" }), /* @__PURE__ */ jsxs("div", {
|
|
3628
|
-
className: "\n relative z-10 w-full max-w-md mx-4\n bg-login-800 border border-login-500/50 rounded-xl\n shadow-2xl p-6 flex flex-col gap-4\n ",
|
|
3629
|
-
onClick: (e) => e.stopPropagation(),
|
|
3630
|
-
children: [
|
|
3631
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3632
|
-
className: "flex items-start gap-3",
|
|
3633
|
-
children: [variant !== "default" && /* @__PURE__ */ jsx(TriangleAlert, { className: `w-5 h-5 shrink-0 mt-0.5 ${variant === "danger" ? "stroke-red-400" : "stroke-yellow-400"}` }), /* @__PURE__ */ jsx("h2", {
|
|
3634
|
-
id: "confirm-popup-header",
|
|
3635
|
-
className: "text-login-50 text-base font-semibold leading-snug",
|
|
3636
|
-
children: header
|
|
3637
|
-
})]
|
|
3638
|
-
}),
|
|
3639
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
3640
|
-
className: "text-login-200 text-sm leading-relaxed",
|
|
3641
|
-
children: description
|
|
3642
|
-
}),
|
|
3643
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3644
|
-
className: "flex justify-end gap-2 mt-1",
|
|
3645
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
3646
|
-
type: "button",
|
|
3647
|
-
onClick: onCancel,
|
|
3648
|
-
className: "\n cursor-pointer px-4 py-1.5 rounded-md text-sm font-medium\n bg-login-600 hover:bg-login-500 text-login-100\n transition-colors duration-150 select-none\n ",
|
|
3649
|
-
children: cancelText
|
|
3650
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
3651
|
-
type: "button",
|
|
3652
|
-
onClick: onConfirm,
|
|
3653
|
-
className: `
|
|
3654
|
-
cursor-pointer px-4 py-1.5 rounded-md text-sm font-medium
|
|
3655
|
-
transition-all duration-150 select-none
|
|
3656
|
-
${variant === "danger" ? "bg-red-600 hover:brightness-110 text-white" : variant === "warning" ? "bg-yellow-500 hover:brightness-110 text-black" : "bg-login hover:brightness-110 text-white"}
|
|
3657
|
-
`,
|
|
3658
|
-
children: confirmText
|
|
3659
|
-
})]
|
|
3660
|
-
})
|
|
3661
|
-
]
|
|
3662
|
-
})]
|
|
3663
|
-
});
|
|
3664
|
-
}
|
|
3665
|
-
//#endregion
|
|
3666
|
-
//#region src/components/vulnerability/constants.ts
|
|
3667
|
-
const severityLabel = {
|
|
3668
|
-
critical: "Critical",
|
|
3669
|
-
high: "High",
|
|
3670
|
-
medium: "Medium",
|
|
3671
|
-
low: "Low",
|
|
3672
|
-
unknown: "Unknown"
|
|
3673
|
-
};
|
|
3674
|
-
const severityClasses = {
|
|
3675
|
-
critical: "border-l-red-500",
|
|
3676
|
-
high: "border-l-orange-500",
|
|
3677
|
-
medium: "border-l-amber-500",
|
|
3678
|
-
low: "border-l-green-500",
|
|
3679
|
-
unknown: "border-l-login-400"
|
|
3680
|
-
};
|
|
3681
|
-
//#endregion
|
|
3682
|
-
//#region src/components/vulnerability/severityPill.tsx
|
|
3683
|
-
function SeverityPill({ severity, count, compact = false }) {
|
|
3684
|
-
if (count === 0) return null;
|
|
3685
|
-
return /* @__PURE__ */ jsxs(LeftBarPanel, {
|
|
3686
|
-
color: severityClasses[severity],
|
|
3687
|
-
className: `flex items-center gap-2.5 ${compact ? "px-2.5 py-1.5" : "px-3 py-2"}`,
|
|
3688
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3689
|
-
className: `${compact ? "text-sm" : "text-base"} font-bold text-login-50`,
|
|
3690
|
-
children: count
|
|
3691
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
3692
|
-
className: "text-[10px] font-semibold uppercase tracking-[0.15em] text-login-300",
|
|
3693
|
-
children: severityLabel[severity]
|
|
3694
|
-
})]
|
|
3695
|
-
});
|
|
3696
|
-
}
|
|
3697
|
-
//#endregion
|
|
3698
|
-
//#region src/components/inputs/toggle.tsx
|
|
3699
|
-
function Toggle({ value, onChange, left, right }) {
|
|
3700
|
-
const active = "bg-login text-white shadow-sm";
|
|
3701
|
-
const idle = "text-login-200 hover:text-login-50 hover:bg-login-500/50";
|
|
3702
|
-
const base = "flex items-center justify-center rounded-md px-3 h-7 transition-all duration-150 gap-1.5 text-sm";
|
|
3703
|
-
function renderContent(opt) {
|
|
3704
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [opt.icon, opt.text && /* @__PURE__ */ jsx("span", { children: opt.text })] });
|
|
3705
|
-
}
|
|
3706
|
-
const isLeftActive = value === left.value;
|
|
3707
|
-
const isRightActive = value === right.value;
|
|
3708
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3709
|
-
className: "flex items-center w-fit bg-login-500/50 border border-login-500 rounded-lg p-1 gap-0.5",
|
|
3710
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
3711
|
-
type: "button",
|
|
3712
|
-
onClick: () => onChange(left.value),
|
|
3713
|
-
"aria-label": left.label ?? left.text,
|
|
3714
|
-
"aria-pressed": isLeftActive,
|
|
3715
|
-
className: `${base} ${isLeftActive ? active : idle}`,
|
|
3716
|
-
children: renderContent(left)
|
|
3717
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
3718
|
-
type: "button",
|
|
3719
|
-
onClick: () => onChange(right.value),
|
|
3720
|
-
"aria-label": right.label ?? right.text,
|
|
3721
|
-
"aria-pressed": isRightActive,
|
|
3722
|
-
className: `${base} ${isRightActive ? active : idle}`,
|
|
3723
|
-
children: renderContent(right)
|
|
3724
|
-
})]
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
//#endregion
|
|
3728
|
-
//#region src/components/inputs/fileInput.tsx
|
|
3729
|
-
function FileInput({ name, label, accept, multiple = false, onChange, className = "" }) {
|
|
3730
|
-
const [files, setFiles] = useState([]);
|
|
3731
|
-
const [dragging, setDragging] = useState(false);
|
|
3732
|
-
const inputRef = useRef(null);
|
|
3733
|
-
function handleFiles(incoming) {
|
|
3734
|
-
if (!incoming) return;
|
|
3735
|
-
const arr = multiple ? Array.from(incoming) : [incoming[0]];
|
|
3736
|
-
setFiles(arr);
|
|
3737
|
-
onChange(arr);
|
|
3738
|
-
}
|
|
3739
|
-
function removeFile(index) {
|
|
3740
|
-
const next = files.filter((_, i) => i !== index);
|
|
3741
|
-
setFiles(next);
|
|
3742
|
-
onChange(next);
|
|
3743
|
-
if (inputRef.current) inputRef.current.value = "";
|
|
3744
|
-
}
|
|
3745
|
-
function onDrop(e) {
|
|
3746
|
-
e.preventDefault();
|
|
3747
|
-
setDragging(false);
|
|
3748
|
-
handleFiles(e.dataTransfer.files);
|
|
3749
|
-
}
|
|
3750
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3751
|
-
className: `flex flex-col gap-2 ${className}`,
|
|
3752
|
-
children: [
|
|
3753
|
-
label && /* @__PURE__ */ jsx("label", {
|
|
3754
|
-
className: "text-sm font-medium text-login-200",
|
|
3755
|
-
children: label
|
|
3756
|
-
}),
|
|
3757
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3758
|
-
role: "button",
|
|
3759
|
-
tabIndex: 0,
|
|
3760
|
-
onClick: () => inputRef.current?.click(),
|
|
3761
|
-
onKeyDown: (e) => {
|
|
3762
|
-
if (e.key === "Enter" || e.key === " ") inputRef.current?.click();
|
|
3763
|
-
},
|
|
3764
|
-
onDragOver: (e) => {
|
|
3765
|
-
e.preventDefault();
|
|
3766
|
-
setDragging(true);
|
|
3767
|
-
},
|
|
3768
|
-
onDragLeave: () => setDragging(false),
|
|
3769
|
-
onDrop,
|
|
3770
|
-
className: `
|
|
3771
|
-
flex cursor-pointer flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed p-6
|
|
3772
|
-
transition-all duration-150
|
|
3773
|
-
${dragging ? "scale-[1.01] border-login bg-login/5" : "border-login-500/50 bg-login-800/30 hover:border-login/50 hover:bg-login/5"}
|
|
3774
|
-
`,
|
|
3775
|
-
children: [
|
|
3776
|
-
/* @__PURE__ */ jsx("input", {
|
|
3777
|
-
ref: inputRef,
|
|
3778
|
-
type: "file",
|
|
3779
|
-
name,
|
|
3780
|
-
accept,
|
|
3781
|
-
multiple,
|
|
3782
|
-
className: "hidden",
|
|
3783
|
-
onChange: (e) => handleFiles(e.target.files)
|
|
3784
|
-
}),
|
|
3785
|
-
/* @__PURE__ */ jsx(UploadCloud, { className: "h-7 w-7 text-login-400" }),
|
|
3786
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3787
|
-
className: "text-center",
|
|
3788
|
-
children: [/* @__PURE__ */ jsxs("p", {
|
|
3789
|
-
className: "text-sm text-login-200",
|
|
3790
|
-
children: ["Drop files here or ", /* @__PURE__ */ jsx("span", {
|
|
3791
|
-
className: "text-login",
|
|
3792
|
-
children: "browse"
|
|
3793
|
-
})]
|
|
3794
|
-
}), accept && /* @__PURE__ */ jsx("p", {
|
|
3795
|
-
className: "mt-0.5 text-xs text-login-400",
|
|
3796
|
-
children: accept
|
|
3797
|
-
})]
|
|
3798
|
-
})
|
|
3799
|
-
]
|
|
3800
|
-
}),
|
|
3801
|
-
files.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
3802
|
-
className: "flex flex-col gap-1.5",
|
|
3803
|
-
children: files.map((file, i) => /* @__PURE__ */ jsxs("li", {
|
|
3804
|
-
className: "\n flex items-center gap-2 rounded-lg\n border border-login-500/25 bg-login-800/50 px-3 py-2 text-sm\n ",
|
|
3805
|
-
children: [
|
|
3806
|
-
/* @__PURE__ */ jsx(FileIcon, { className: "h-4 w-4 shrink-0 text-login-400" }),
|
|
3807
|
-
/* @__PURE__ */ jsx("span", {
|
|
3808
|
-
className: "flex-1 truncate text-login-200",
|
|
3809
|
-
children: file.name
|
|
3810
|
-
}),
|
|
3811
|
-
/* @__PURE__ */ jsxs("span", {
|
|
3812
|
-
className: "shrink-0 text-xs text-login-400",
|
|
3813
|
-
children: [(file.size / 1024).toFixed(1), " KB"]
|
|
3814
|
-
}),
|
|
3815
|
-
/* @__PURE__ */ jsx("button", {
|
|
3816
|
-
type: "button",
|
|
3817
|
-
onClick: (e) => {
|
|
3818
|
-
e.stopPropagation();
|
|
3819
|
-
removeFile(i);
|
|
3820
|
-
},
|
|
3821
|
-
className: "cursor-pointer text-login-400 transition-colors hover:text-red-400",
|
|
3822
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
3823
|
-
})
|
|
3824
|
-
]
|
|
3825
|
-
}, i))
|
|
3826
|
-
})
|
|
3827
|
-
]
|
|
3828
|
-
});
|
|
3829
|
-
}
|
|
3830
|
-
//#endregion
|
|
3831
|
-
//#region src/components/container/glassCard.tsx
|
|
3832
|
-
function GlassCard({ children, className = "" }) {
|
|
3833
|
-
return /* @__PURE__ */ jsx("div", {
|
|
3834
|
-
className: `rounded-xl border border-login-500/20 bg-login-800/60 backdrop-blur-sm ${className}`,
|
|
3835
|
-
children
|
|
3836
|
-
});
|
|
3837
|
-
}
|
|
3838
|
-
//#endregion
|
|
3839
|
-
//#region src/components/container/expandableCard.tsx
|
|
3840
|
-
function ExpandableCard({ icon, iconTone = "orange", title, subtitle, pulse, trailing, isExpanded, onToggle, children }) {
|
|
3841
|
-
return /* @__PURE__ */ jsxs(Card, { children: [/* @__PURE__ */ jsxs("div", {
|
|
3842
|
-
role: "button",
|
|
3843
|
-
tabIndex: 0,
|
|
3844
|
-
onClick: onToggle,
|
|
3845
|
-
onKeyDown: (e) => {
|
|
3846
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
3847
|
-
e.preventDefault();
|
|
3848
|
-
onToggle();
|
|
3849
|
-
}
|
|
3850
|
-
},
|
|
3851
|
-
"aria-expanded": isExpanded,
|
|
3852
|
-
className: "group flex cursor-pointer select-none items-center gap-4 px-5 py-4",
|
|
3853
|
-
children: [
|
|
3854
|
-
/* @__PURE__ */ jsx(IconBubble, {
|
|
3855
|
-
icon,
|
|
3856
|
-
tone: iconTone,
|
|
3857
|
-
size: "sm"
|
|
3858
|
-
}),
|
|
3859
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3860
|
-
className: "min-w-0 flex-1",
|
|
3861
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
3862
|
-
className: "flex flex-wrap items-center gap-3",
|
|
3863
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3864
|
-
className: "font-semibold text-login-50 transition group-hover:text-login",
|
|
3865
|
-
children: title
|
|
3866
|
-
}), pulse && /* @__PURE__ */ jsxs("span", {
|
|
3867
|
-
className: "flex items-center gap-2 text-xs text-login-300",
|
|
3868
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3869
|
-
className: "flex h-3 w-3 shrink-0 items-center justify-center",
|
|
3870
|
-
children: /* @__PURE__ */ jsx(PulseDot, {
|
|
3871
|
-
variant: pulse.variant,
|
|
3872
|
-
size: "sm"
|
|
3873
|
-
})
|
|
3874
|
-
}), pulse.label]
|
|
3875
|
-
})]
|
|
3876
|
-
}), subtitle && /* @__PURE__ */ jsx("div", {
|
|
3877
|
-
className: "mt-0.5 text-xs text-login-300",
|
|
3878
|
-
children: subtitle
|
|
3879
|
-
})]
|
|
3880
|
-
}),
|
|
3881
|
-
trailing && /* @__PURE__ */ jsx("div", {
|
|
3882
|
-
className: "flex shrink-0 items-center gap-3",
|
|
3883
|
-
onClick: (e) => e.stopPropagation(),
|
|
3884
|
-
children: trailing
|
|
3885
|
-
}),
|
|
3886
|
-
/* @__PURE__ */ jsx(Button, {
|
|
3887
|
-
variant: "secondary",
|
|
3888
|
-
icon: /* @__PURE__ */ jsx(ChevronDown, { className: `h-4 w-4 transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}` }),
|
|
3889
|
-
onClick: (e) => {
|
|
3890
|
-
e.stopPropagation();
|
|
3891
|
-
onToggle();
|
|
3892
|
-
}
|
|
3893
|
-
})
|
|
3894
|
-
]
|
|
3895
|
-
}), isExpanded && children && /* @__PURE__ */ jsx("div", {
|
|
3896
|
-
className: "border-t border-white/5 px-5 pb-5 pt-4",
|
|
3897
|
-
children
|
|
3898
|
-
})] });
|
|
3899
|
-
}
|
|
3900
|
-
//#endregion
|
|
3901
|
-
//#region src/components/modal/modal.tsx
|
|
3902
|
-
const sizes$2 = {
|
|
3903
|
-
sm: "max-w-sm",
|
|
3904
|
-
md: "max-w-md",
|
|
3905
|
-
lg: "max-w-lg"
|
|
3906
|
-
};
|
|
3907
|
-
function Modal({ isOpen, onClose, title, children, footer, size = "md" }) {
|
|
3908
|
-
useEffect(() => {
|
|
3909
|
-
if (!isOpen) return;
|
|
3910
|
-
const handler = (e) => {
|
|
3911
|
-
if (e.key === "Escape") onClose();
|
|
3912
|
-
};
|
|
3913
|
-
document.addEventListener("keydown", handler);
|
|
3914
|
-
return () => document.removeEventListener("keydown", handler);
|
|
3915
|
-
}, [isOpen, onClose]);
|
|
3916
|
-
if (!isOpen) return null;
|
|
3917
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3918
|
-
role: "dialog",
|
|
3919
|
-
"aria-modal": "true",
|
|
3920
|
-
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
3921
|
-
onClick: onClose,
|
|
3922
|
-
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm" }), /* @__PURE__ */ jsxs("div", {
|
|
3923
|
-
className: `
|
|
3924
|
-
relative z-10 mx-4 w-full ${sizes$2[size]}
|
|
3925
|
-
flex flex-col rounded-xl border border-login-500/50
|
|
3926
|
-
bg-login-800 shadow-2xl
|
|
3927
|
-
`,
|
|
3928
|
-
onClick: (e) => e.stopPropagation(),
|
|
3929
|
-
children: [
|
|
3930
|
-
title && /* @__PURE__ */ jsxs("div", {
|
|
3931
|
-
className: "flex items-center justify-between px-6 pt-5 pb-4 border-b border-login-500/25",
|
|
3932
|
-
children: [/* @__PURE__ */ jsx("h2", {
|
|
3933
|
-
className: "text-login-50 text-base font-semibold leading-snug",
|
|
3934
|
-
children: title
|
|
3935
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
3936
|
-
type: "button",
|
|
3937
|
-
onClick: onClose,
|
|
3938
|
-
className: "\n cursor-pointer rounded-md p-1.5\n text-login-400 hover:text-login-100 hover:bg-login-600\n transition-colors\n ",
|
|
3939
|
-
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
|
|
3940
|
-
})]
|
|
3941
|
-
}),
|
|
3942
|
-
/* @__PURE__ */ jsx("div", {
|
|
3943
|
-
className: "p-6",
|
|
3944
|
-
children
|
|
3945
|
-
}),
|
|
3946
|
-
footer && /* @__PURE__ */ jsx("div", {
|
|
3947
|
-
className: "px-6 pb-5 pt-4 border-t border-login-500/25",
|
|
3948
|
-
children: footer
|
|
3949
|
-
})
|
|
3950
|
-
]
|
|
3951
|
-
})]
|
|
3952
|
-
});
|
|
3953
|
-
}
|
|
3954
|
-
//#endregion
|
|
3955
|
-
//#region src/components/sidebar/sidebar.tsx
|
|
3956
|
-
const ITEM_HEIGHT = 48;
|
|
3957
|
-
const GAP = 4;
|
|
3958
|
-
const SUB_STRIDE = 40;
|
|
3959
|
-
function Sidebar({ items, header, bottomAction, mobile = false, initialExpanded = true, onExpandedChange, className = "" }) {
|
|
3960
|
-
const [expanded, setExpanded] = useState(initialExpanded);
|
|
3961
|
-
const pathname = usePathname();
|
|
3962
|
-
const searchParams = useSearchParams();
|
|
3963
|
-
const fullPath = pathname + (searchParams.toString() ? `?${searchParams.toString()}` : "");
|
|
3964
|
-
function toggleExpanded() {
|
|
3965
|
-
const next = !expanded;
|
|
3966
|
-
setExpanded(next);
|
|
3967
|
-
onExpandedChange?.(next);
|
|
3968
|
-
}
|
|
3969
|
-
function isSubActive(sub) {
|
|
3970
|
-
return sub.path.includes("?") ? fullPath.startsWith(sub.path) : pathname === sub.path;
|
|
3971
|
-
}
|
|
3972
|
-
function isItemActive(item) {
|
|
3973
|
-
return pathname === item.path || !!item.items?.some((sub) => sub.path.includes("?") ? fullPath.startsWith(sub.path) : pathname === sub.path || pathname.startsWith(sub.path + "/"));
|
|
3974
|
-
}
|
|
3975
|
-
const activeIndex = items.findIndex(isItemActive);
|
|
3976
|
-
const activeOffset = items.slice(0, Math.max(activeIndex, 0)).reduce((acc, item) => acc + ITEM_HEIGHT + (item.items ? GAP : 0) + GAP, 0);
|
|
3977
|
-
return /* @__PURE__ */ jsxs("aside", {
|
|
3978
|
-
className: `
|
|
3979
|
-
flex flex-col border-r border-login-100/10 bg-login-900
|
|
3980
|
-
transition-all duration-300 ease-in-out
|
|
3981
|
-
${mobile ? "w-full" : `h-full ${expanded ? "w-64" : "w-20"}`}
|
|
3982
|
-
${className}
|
|
3983
|
-
`,
|
|
3984
|
-
children: [
|
|
3985
|
-
!mobile && /* @__PURE__ */ jsxs("div", {
|
|
3986
|
-
className: `relative mb-2 p-4 transition-all duration-300 ${expanded ? "h-16" : "h-20"}`,
|
|
3987
|
-
children: [header && /* @__PURE__ */ jsx("div", {
|
|
3988
|
-
className: `
|
|
3989
|
-
absolute top-4 flex items-center transition-all duration-300
|
|
3990
|
-
${expanded ? "left-4 gap-3" : "left-1/2 -translate-x-1/2 gap-0"}
|
|
3991
|
-
`,
|
|
3992
|
-
children: typeof header === "function" ? header(expanded) : header
|
|
3993
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
3994
|
-
onClick: toggleExpanded,
|
|
3995
|
-
className: `
|
|
3996
|
-
absolute cursor-pointer rounded-lg p-1.5
|
|
3997
|
-
text-login-200 transition-all duration-300 hover:bg-login-800
|
|
3998
|
-
${expanded ? "right-4 top-4" : "left-1/2 top-12 -translate-x-1/2"}
|
|
3999
|
-
`,
|
|
4000
|
-
children: expanded ? /* @__PURE__ */ jsx(ChevronLeft, { size: 20 }) : /* @__PURE__ */ jsx(ChevronRight, { size: 20 })
|
|
4001
|
-
})]
|
|
4002
|
-
}),
|
|
4003
|
-
mobile && /* @__PURE__ */ jsx("div", { className: "h-4" }),
|
|
4004
|
-
/* @__PURE__ */ jsxs("div", {
|
|
4005
|
-
className: "relative flex flex-1 flex-col gap-1 overflow-x-hidden overflow-y-auto px-3 [scrollbar-width:none]",
|
|
4006
|
-
children: [activeIndex >= 0 && /* @__PURE__ */ jsx("span", {
|
|
4007
|
-
"aria-hidden": true,
|
|
4008
|
-
className: "absolute left-3 right-3 top-0 h-12 rounded-lg bg-login-800 transition-transform duration-300 ease-in-out",
|
|
4009
|
-
style: { transform: `translateY(${activeOffset}px)` }
|
|
4010
|
-
}), items.map((item, index) => {
|
|
4011
|
-
const isActive = isItemActive(item);
|
|
4012
|
-
const Icon = item.icon;
|
|
4013
|
-
const activeSubIndex = item.items ? item.items.findIndex(isSubActive) : -1;
|
|
4014
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
4015
|
-
className: "flex flex-col gap-1",
|
|
4016
|
-
children: [/* @__PURE__ */ jsxs(Link, {
|
|
4017
|
-
href: item.path,
|
|
4018
|
-
title: !expanded ? item.name : void 0,
|
|
4019
|
-
className: `
|
|
4020
|
-
group relative z-10 flex items-center
|
|
4021
|
-
overflow-hidden rounded-lg p-3 transition-all duration-200
|
|
4022
|
-
${isActive ? "text-login" : "text-login-200 hover:bg-login-800/50 hover:text-login-100"}
|
|
4023
|
-
`,
|
|
4024
|
-
children: [
|
|
4025
|
-
/* @__PURE__ */ jsx("div", {
|
|
4026
|
-
className: `
|
|
4027
|
-
flex min-w-6 w-6 items-center justify-center transition-all duration-300
|
|
4028
|
-
${expanded ? "" : "translate-x-1"}
|
|
4029
|
-
${isActive ? "[&>svg]:stroke-login" : "group-hover:[&>svg]:stroke-login-100"}
|
|
4030
|
-
`,
|
|
4031
|
-
children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" })
|
|
4032
|
-
}),
|
|
4033
|
-
/* @__PURE__ */ jsx("span", {
|
|
4034
|
-
className: `
|
|
4035
|
-
whitespace-nowrap overflow-hidden transition-all duration-300
|
|
4036
|
-
${expanded ? "ml-3 max-w-48 opacity-100" : "ml-0 max-w-0 opacity-0"}
|
|
4037
|
-
`,
|
|
4038
|
-
children: item.name
|
|
4039
|
-
}),
|
|
4040
|
-
item.status && /* @__PURE__ */ jsx("div", {
|
|
4041
|
-
className: `
|
|
4042
|
-
flex items-center justify-center
|
|
4043
|
-
${expanded ? "ml-auto" : "absolute right-1 top-1 scale-75"}
|
|
4044
|
-
`,
|
|
4045
|
-
children: item.status
|
|
4046
|
-
})
|
|
4047
|
-
]
|
|
4048
|
-
}), item.items && /* @__PURE__ */ jsxs("div", {
|
|
4049
|
-
className: `
|
|
4050
|
-
relative ml-6 flex flex-col gap-1 overflow-hidden
|
|
4051
|
-
border-l border-login-800 pl-2
|
|
4052
|
-
transition-all duration-300 ease-in-out
|
|
4053
|
-
${expanded && isActive ? "max-h-96 opacity-100" : "max-h-0 opacity-0"}
|
|
4054
|
-
`,
|
|
4055
|
-
children: [activeSubIndex >= 0 && /* @__PURE__ */ jsx("span", {
|
|
4056
|
-
"aria-hidden": true,
|
|
4057
|
-
className: "\n absolute left-2 right-0 top-0 h-9 rounded-lg\n bg-login-800/50 transition-transform duration-300 ease-in-out\n ",
|
|
4058
|
-
style: { transform: `translateY(${activeSubIndex * SUB_STRIDE}px)` }
|
|
4059
|
-
}), item.items.map((sub, subIndex) => {
|
|
4060
|
-
const subActive = isSubActive(sub);
|
|
4061
|
-
return /* @__PURE__ */ jsx(Link, {
|
|
4062
|
-
href: sub.path,
|
|
4063
|
-
className: `
|
|
4064
|
-
relative z-10 rounded-lg p-2 text-sm
|
|
4065
|
-
transition-all duration-200
|
|
4066
|
-
${subActive ? "text-login" : "text-login-300 hover:bg-login-800/30 hover:text-login-100"}
|
|
4067
|
-
`,
|
|
4068
|
-
children: sub.name
|
|
4069
|
-
}, `${index}-${subIndex}`);
|
|
4070
|
-
})]
|
|
4071
|
-
})]
|
|
4072
|
-
}, index);
|
|
4073
|
-
})]
|
|
4074
|
-
}),
|
|
4075
|
-
bottomAction && /* @__PURE__ */ jsx("div", {
|
|
4076
|
-
className: "border-t border-login-100/10 p-3",
|
|
4077
|
-
children: bottomAction(expanded)
|
|
4078
|
-
})
|
|
4079
|
-
]
|
|
4080
|
-
});
|
|
4081
|
-
}
|
|
4082
|
-
//#endregion
|
|
4083
|
-
//#region src/components/badge/badge.tsx
|
|
4084
|
-
const variants = {
|
|
4085
|
-
default: "bg-login-600 text-login-100",
|
|
4086
|
-
success: "bg-emerald-500/15 text-emerald-400",
|
|
4087
|
-
warning: "bg-yellow-500/15 text-yellow-400",
|
|
4088
|
-
danger: "bg-red-500/15 text-red-400",
|
|
4089
|
-
info: "bg-sky-500/15 text-sky-400",
|
|
4090
|
-
amber: "bg-amber-500/15 text-amber-400",
|
|
4091
|
-
violet: "bg-violet-500/15 text-violet-400",
|
|
4092
|
-
blue: "bg-blue-500/15 text-blue-400",
|
|
4093
|
-
emerald: "bg-emerald-500/15 text-emerald-400",
|
|
4094
|
-
orange: "bg-login/15 text-login"
|
|
4095
|
-
};
|
|
4096
|
-
const sizes$1 = {
|
|
4097
|
-
sm: "px-2 py-0.5 text-xs",
|
|
4098
|
-
md: "px-2.5 py-1 text-sm"
|
|
4099
|
-
};
|
|
4100
|
-
function Badge({ text, variant = "default", size = "sm", className = "" }) {
|
|
4101
|
-
return /* @__PURE__ */ jsx("span", {
|
|
4102
|
-
className: `inline-flex items-center rounded-full font-medium ${variants[variant]} ${sizes$1[size]} ${className}`,
|
|
4103
|
-
children: text
|
|
4104
|
-
});
|
|
4105
|
-
}
|
|
4106
|
-
//#endregion
|
|
4107
|
-
//#region src/components/empty/emptyState.tsx
|
|
4108
|
-
function EmptyState({ icon: Icon, title, description, action, className = "" }) {
|
|
4109
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
4110
|
-
className: `flex flex-col items-center justify-center gap-3 py-12 text-center ${className}`,
|
|
4111
|
-
children: [
|
|
4112
|
-
Icon && /* @__PURE__ */ jsx("div", {
|
|
4113
|
-
className: "mb-1 rounded-xl bg-login-600/30 p-3 text-login-400",
|
|
4114
|
-
children: /* @__PURE__ */ jsx(Icon, { className: "h-7 w-7" })
|
|
4115
|
-
}),
|
|
4116
|
-
/* @__PURE__ */ jsx("p", {
|
|
4117
|
-
className: "text-sm font-semibold text-login-100",
|
|
4118
|
-
children: title
|
|
4119
|
-
}),
|
|
4120
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
4121
|
-
className: "max-w-xs text-xs leading-relaxed text-login-400",
|
|
4122
|
-
children: description
|
|
4123
|
-
}),
|
|
4124
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
4125
|
-
className: "mt-2",
|
|
4126
|
-
children: action
|
|
4127
|
-
})
|
|
4128
|
-
]
|
|
4129
|
-
});
|
|
4130
|
-
}
|
|
4131
|
-
//#endregion
|
|
4132
|
-
//#region src/components/spinner/spinner.tsx
|
|
4133
|
-
const sizes = {
|
|
4134
|
-
sm: "w-4 h-4 border-2",
|
|
4135
|
-
md: "w-6 h-6 border-2",
|
|
4136
|
-
lg: "w-9 h-9 border-[3px]"
|
|
4137
|
-
};
|
|
4138
|
-
function Spinner({ size = "md", className = "" }) {
|
|
4139
|
-
return /* @__PURE__ */ jsx("div", {
|
|
4140
|
-
role: "status",
|
|
4141
|
-
"aria-label": "Loading",
|
|
4142
|
-
className: `rounded-full border-login-500 border-t-login animate-spin ${sizes[size]} ${className}`
|
|
4143
|
-
});
|
|
4144
|
-
}
|
|
4145
|
-
//#endregion
|
|
4146
|
-
//#region src/components/code/code.tsx
|
|
4147
|
-
function Code({ children, className = "" }) {
|
|
4148
|
-
return /* @__PURE__ */ jsx("code", {
|
|
4149
|
-
className: `font-mono text-xs bg-login-700 text-login px-1.5 py-0.5 rounded ${className}`,
|
|
4150
|
-
children
|
|
4151
|
-
});
|
|
4152
|
-
}
|
|
4153
|
-
function CodeBlock({ code, language, className = "" }) {
|
|
4154
|
-
const [copied, setCopied] = useState(false);
|
|
4155
|
-
function copy() {
|
|
4156
|
-
navigator.clipboard.writeText(code);
|
|
4157
|
-
setCopied(true);
|
|
4158
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
4159
|
-
}
|
|
4160
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
4161
|
-
className: `relative group rounded-xl border border-login-500/30 bg-login-900 overflow-hidden ${className}`,
|
|
4162
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
4163
|
-
className: "flex items-center justify-between px-4 py-2 border-b border-login-500/20 bg-login-800",
|
|
4164
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
4165
|
-
className: "text-xs font-mono text-login-400",
|
|
4166
|
-
children: language ?? ""
|
|
4167
|
-
}), /* @__PURE__ */ jsxs("button", {
|
|
4168
|
-
type: "button",
|
|
4169
|
-
onClick: copy,
|
|
4170
|
-
className: "flex cursor-pointer items-center gap-1.5 text-xs text-login-400 hover:text-login-100 transition-colors",
|
|
4171
|
-
children: [copied ? /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 stroke-emerald-400" }) : /* @__PURE__ */ jsx(Copy, { className: "w-3.5 h-3.5" }), copied ? "Copied" : "Copy"]
|
|
4172
|
-
})]
|
|
4173
|
-
}), /* @__PURE__ */ jsx("pre", {
|
|
4174
|
-
className: "overflow-x-auto p-4 text-xs font-mono leading-relaxed text-login-100",
|
|
4175
|
-
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
4176
|
-
})]
|
|
4177
|
-
});
|
|
4178
|
-
}
|
|
4179
|
-
//#endregion
|
|
1
|
+
import MarkdownRender from "../../components/markdownrender/markdownRender.js";
|
|
2
|
+
import Input from "../../components/inputs/input.js";
|
|
3
|
+
import SearchInput from "../../components/inputs/searchInput.js";
|
|
4
|
+
import Textarea from "../../components/inputs/textarea.js";
|
|
5
|
+
import Checkbox from "../../components/inputs/checkbox.js";
|
|
6
|
+
import Select from "../../components/inputs/select.js";
|
|
7
|
+
import TagInput from "../../components/inputs/tagInput.js";
|
|
8
|
+
import MultiSelect from "../../components/inputs/multiSelect.js";
|
|
9
|
+
import Switch from "../../components/inputs/switch.js";
|
|
10
|
+
import Radio from "../../components/inputs/radio.js";
|
|
11
|
+
import Range from "../../components/inputs/range.js";
|
|
12
|
+
import Logo from "../../components/logo/logo.js";
|
|
13
|
+
import LogoSmall from "../../components/logo/logoSmall.js";
|
|
14
|
+
import ThemeToggle from "../../components/toggle/theme.js";
|
|
15
|
+
import LanguageToggle from "../../components/toggle/language.js";
|
|
16
|
+
import Navbar from "../../components/navbar/navbar.js";
|
|
17
|
+
import NavItem from "../../components/navbar/navbarItem.js";
|
|
18
|
+
import NavDropdown from "../../components/navbar/navbarDropdown.js";
|
|
19
|
+
import VersionTag from "../../components/version/version.js";
|
|
20
|
+
import Footer from "../../components/footer/footer.js";
|
|
21
|
+
import { loginAddress, loginCopyright, loginEmail, loginSocialLinks, loginSponsor } from "../../components/footer/loginContent.js";
|
|
22
|
+
import PageContainer from "../../components/container/page.js";
|
|
23
|
+
import Highlight from "../../components/container/highlight.js";
|
|
24
|
+
import LeftBarPanel from "../../components/container/leftBarPanel.js";
|
|
25
|
+
import Card from "../../components/container/card.js";
|
|
26
|
+
import IconBubble from "../../components/container/iconBubble.js";
|
|
27
|
+
import StatCard from "../../components/container/statCard.js";
|
|
28
|
+
import { TabPanel, Tabs } from "../../components/container/tabs.js";
|
|
29
|
+
import Accordion, { AccordionGroup } from "../../components/container/accordion.js";
|
|
30
|
+
import PulseDot from "../../components/container/pulseDot.js";
|
|
31
|
+
import LoginPage from "../../components/login/loginPage.js";
|
|
32
|
+
import Toaster, { toast } from "../../components/toast/toaster.js";
|
|
33
|
+
import Button from "../../components/buttons/button.js";
|
|
34
|
+
import Alert from "../../components/alert/alert.js";
|
|
35
|
+
import { MenuButton } from "../../components/table/menu.js";
|
|
36
|
+
import Pagination from "../../components/table/pagination.js";
|
|
37
|
+
import { Table } from "../../components/table/table.js";
|
|
38
|
+
import ConfirmPopup from "../../components/confirm/confirmPopup.js";
|
|
39
|
+
import SeverityPill from "../../components/vulnerability/severityPill.js";
|
|
40
|
+
import Toggle from "../../components/inputs/toggle.js";
|
|
41
|
+
import FileInput from "../../components/inputs/fileInput.js";
|
|
42
|
+
import GlassCard from "../../components/container/glassCard.js";
|
|
43
|
+
import ExpandableCard from "../../components/container/expandableCard.js";
|
|
44
|
+
import Modal from "../../components/modal/modal.js";
|
|
45
|
+
import Sidebar from "../../components/sidebar/sidebar.js";
|
|
46
|
+
import Badge from "../../components/badge/badge.js";
|
|
47
|
+
import EmptyState from "../../components/empty/emptyState.js";
|
|
48
|
+
import Spinner from "../../components/spinner/spinner.js";
|
|
49
|
+
import { Code, CodeBlock } from "../../components/code/code.js";
|
|
4180
50
|
export { Accordion, AccordionGroup, Alert, Badge, Button, Card, Checkbox, Code, CodeBlock, ConfirmPopup, EmptyState, ExpandableCard, FileInput, Footer, GlassCard, Highlight, IconBubble, Input, LanguageToggle, LeftBarPanel, LoginPage, Logo, LogoSmall, MarkdownRender, MenuButton, Modal, MultiSelect, NavDropdown, NavItem, Navbar, PageContainer, Pagination, PulseDot, Radio, Range, SearchInput, Select, SeverityPill, Sidebar, Spinner, StatCard, Switch, TabPanel, Table, Tabs, TagInput, Textarea, ThemeToggle, Toaster, Toggle, VersionTag, loginAddress, loginCopyright, loginEmail, loginSocialLinks, loginSponsor, toast };
|