@otmc/ui 0.1.2 → 0.1.4
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/index.cjs +470 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -2
- package/dist/index.d.ts +80 -2
- package/dist/index.js +512 -64
- package/dist/index.js.map +1 -1
- package/package.json +65 -60
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,10 @@ __export(index_exports, {
|
|
|
29
29
|
Footer: () => Footer,
|
|
30
30
|
InformationContent: () => InformationContent,
|
|
31
31
|
InformationModal: () => InformationModal,
|
|
32
|
+
NotFound: () => NotFound,
|
|
33
|
+
ThemeMenu: () => ThemeMenu,
|
|
34
|
+
ThemeProvider: () => ThemeProvider,
|
|
35
|
+
ThemeSetting: () => ThemeSetting,
|
|
32
36
|
UNKNOWN: () => UNKNOWN,
|
|
33
37
|
calculateRemainingTime: () => calculateRemainingTime,
|
|
34
38
|
copyToClipboard: () => copyToClipboard,
|
|
@@ -37,12 +41,15 @@ __export(index_exports, {
|
|
|
37
41
|
formatHumanDate: () => formatHumanDate,
|
|
38
42
|
formatRelativeTime: () => formatRelativeTime,
|
|
39
43
|
normalizeDate: () => normalizeDate,
|
|
40
|
-
pad: () => pad
|
|
44
|
+
pad: () => pad,
|
|
45
|
+
resolveColorScheme: () => resolveColorScheme,
|
|
46
|
+
useTheme: () => useTheme
|
|
41
47
|
});
|
|
42
48
|
module.exports = __toCommonJS(index_exports);
|
|
43
49
|
|
|
44
50
|
// src/branding/Footer.tsx
|
|
45
51
|
var import_core = require("@mantine/core");
|
|
52
|
+
var import_lucide_react = require("lucide-react");
|
|
46
53
|
var import_icons_react = require("@tabler/icons-react");
|
|
47
54
|
|
|
48
55
|
// src/utils/constants.ts
|
|
@@ -93,7 +100,7 @@ function Footer({
|
|
|
93
100
|
"Copyright",
|
|
94
101
|
" "
|
|
95
102
|
] }),
|
|
96
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
103
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Copyright, { size: 15, color: "var(--mantine-color-dimmed)" }),
|
|
97
104
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Text, { size: "xs", c: "dimmed", children: [
|
|
98
105
|
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
99
106
|
" ",
|
|
@@ -137,10 +144,330 @@ function Footer({
|
|
|
137
144
|
] });
|
|
138
145
|
}
|
|
139
146
|
|
|
140
|
-
// src/
|
|
147
|
+
// src/components/ThemeMenu.tsx
|
|
148
|
+
var import_core3 = require("@mantine/core");
|
|
149
|
+
var import_lucide_react2 = require("lucide-react");
|
|
150
|
+
|
|
151
|
+
// src/contexts/ThemeProvider.tsx
|
|
141
152
|
var import_react = require("react");
|
|
142
153
|
var import_core2 = require("@mantine/core");
|
|
154
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
155
|
+
var ThemeContext = (0, import_react.createContext)(null);
|
|
156
|
+
var useTheme = () => {
|
|
157
|
+
const ctx = (0, import_react.useContext)(ThemeContext);
|
|
158
|
+
if (!ctx) {
|
|
159
|
+
throw new Error("useTheme must be used inside ThemeProvider");
|
|
160
|
+
}
|
|
161
|
+
return ctx;
|
|
162
|
+
};
|
|
163
|
+
var resolveColorScheme = (colorScheme) => {
|
|
164
|
+
if (colorScheme === "auto") {
|
|
165
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
166
|
+
}
|
|
167
|
+
return colorScheme;
|
|
168
|
+
};
|
|
169
|
+
var resolveTimeBasedTheme = (settings) => {
|
|
170
|
+
const now = /* @__PURE__ */ new Date();
|
|
171
|
+
const minutes = now.getHours() * 60 + now.getMinutes();
|
|
172
|
+
const [lh, lm] = settings.lightStartTime.split(":").map(Number);
|
|
173
|
+
const [dh, dm] = settings.darkStartTime.split(":").map(Number);
|
|
174
|
+
const light = lh * 60 + lm;
|
|
175
|
+
const dark = dh * 60 + dm;
|
|
176
|
+
return light < dark ? minutes >= light && minutes < dark ? "light" : "dark" : minutes >= light || minutes < dark ? "light" : "dark";
|
|
177
|
+
};
|
|
178
|
+
var resolveAutoScheme = () => window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
179
|
+
var ThemeProvider = ({
|
|
180
|
+
children,
|
|
181
|
+
defaultTheme = "auto",
|
|
182
|
+
defaultTimeBasedSettings = {
|
|
183
|
+
lightStartTime: "07:00",
|
|
184
|
+
darkStartTime: "19:00"
|
|
185
|
+
},
|
|
186
|
+
storagePrefix = ""
|
|
187
|
+
}) => {
|
|
188
|
+
const themeStorageKey = `${storagePrefix}theme`;
|
|
189
|
+
const timeStorageKey = `${storagePrefix}time-theme`;
|
|
190
|
+
const { colorScheme, setColorScheme } = (0, import_core2.useMantineColorScheme)();
|
|
191
|
+
const [theme, setThemeState] = (0, import_react.useState)(
|
|
192
|
+
() => localStorage.getItem(themeStorageKey) ?? defaultTheme
|
|
193
|
+
);
|
|
194
|
+
const [timeBasedSettings, setTimeBasedSettings] = (0, import_react.useState)(
|
|
195
|
+
() => JSON.parse(localStorage.getItem(timeStorageKey) || "null") ?? defaultTimeBasedSettings
|
|
196
|
+
);
|
|
197
|
+
const handleSetTimeBasedSettings = (settings) => {
|
|
198
|
+
setTimeBasedSettings(settings);
|
|
199
|
+
localStorage.setItem(timeStorageKey, JSON.stringify(settings));
|
|
200
|
+
if (theme === "time-based") {
|
|
201
|
+
applyTheme("time-based");
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const applyTheme = (mode) => {
|
|
205
|
+
let scheme;
|
|
206
|
+
switch (mode) {
|
|
207
|
+
case "light":
|
|
208
|
+
case "dark":
|
|
209
|
+
case "auto":
|
|
210
|
+
scheme = mode;
|
|
211
|
+
break;
|
|
212
|
+
case "time-based":
|
|
213
|
+
scheme = resolveTimeBasedTheme(timeBasedSettings);
|
|
214
|
+
break;
|
|
215
|
+
default:
|
|
216
|
+
scheme = "auto";
|
|
217
|
+
}
|
|
218
|
+
setColorScheme(scheme);
|
|
219
|
+
};
|
|
220
|
+
(0, import_react.useEffect)(() => {
|
|
221
|
+
applyTheme(theme);
|
|
222
|
+
}, [theme, timeBasedSettings]);
|
|
223
|
+
const setTheme = (mode) => {
|
|
224
|
+
setThemeState(mode);
|
|
225
|
+
localStorage.setItem(themeStorageKey, mode);
|
|
226
|
+
applyTheme(mode);
|
|
227
|
+
};
|
|
228
|
+
const toggleTheme = () => {
|
|
229
|
+
setTheme(colorScheme === "dark" ? "light" : "dark");
|
|
230
|
+
};
|
|
231
|
+
const currentTheme = theme === "time-based" ? resolveTimeBasedTheme(timeBasedSettings) : colorScheme === "auto" ? resolveAutoScheme() : colorScheme;
|
|
232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
233
|
+
ThemeContext.Provider,
|
|
234
|
+
{
|
|
235
|
+
value: {
|
|
236
|
+
theme,
|
|
237
|
+
currentTheme,
|
|
238
|
+
setTheme,
|
|
239
|
+
toggleTheme,
|
|
240
|
+
timeBasedSettings,
|
|
241
|
+
setTimeBasedSettings: handleSetTimeBasedSettings
|
|
242
|
+
},
|
|
243
|
+
children
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// src/components/ThemeMenu.tsx
|
|
249
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
250
|
+
var DEFAULT_LABELS = {
|
|
251
|
+
tooltip: "Ch\u1EBF \u0111\u1ED9 giao di\u1EC7n",
|
|
252
|
+
title: "Ch\u1EBF \u0111\u1ED9 giao di\u1EC7n",
|
|
253
|
+
light: "S\xE1ng",
|
|
254
|
+
dark: "T\u1ED1i",
|
|
255
|
+
auto: "Theo h\u1EC7 th\u1ED1ng",
|
|
256
|
+
timeBased: "Theo th\u1EDDi gian"
|
|
257
|
+
};
|
|
258
|
+
var MODE_ICONS = {
|
|
259
|
+
light: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Sun, { size: 16 }),
|
|
260
|
+
dark: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Moon, { size: 16 }),
|
|
261
|
+
auto: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Monitor, { size: 16 }),
|
|
262
|
+
"time-based": /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Clock, { size: 16 })
|
|
263
|
+
};
|
|
264
|
+
function ThemeMenu({
|
|
265
|
+
modes = ["light", "dark", "auto", "time-based"],
|
|
266
|
+
labels = {},
|
|
267
|
+
iconSize = 20,
|
|
268
|
+
size = "lg",
|
|
269
|
+
menuProps = {}
|
|
270
|
+
}) {
|
|
271
|
+
const { theme, currentTheme, setTheme } = useTheme();
|
|
272
|
+
const text = { ...DEFAULT_LABELS, ...labels };
|
|
273
|
+
const isDark = currentTheme === "dark";
|
|
274
|
+
const activeColor = isDark ? "yellow.8" : "blue.8";
|
|
275
|
+
const triggerIcon = theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Sun, { size: iconSize, strokeWidth: 2 }) : theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Moon, { size: iconSize, strokeWidth: 2 }) : theme === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Monitor, { size: iconSize, strokeWidth: 2 }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Clock, { size: iconSize, strokeWidth: 2 });
|
|
276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Menu, { shadow: "md", width: 200, position: "bottom-end", ...menuProps, children: [
|
|
277
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Menu.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tooltip, { label: text.tooltip, position: "bottom", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
278
|
+
import_core3.ActionIcon,
|
|
279
|
+
{
|
|
280
|
+
variant: "subtle",
|
|
281
|
+
color: activeColor,
|
|
282
|
+
size,
|
|
283
|
+
radius: "lg",
|
|
284
|
+
style: {
|
|
285
|
+
boxShadow: isDark ? "0 0 15px rgba(250, 176, 5, 0.2)" : "0 0 15px rgba(34, 139, 230, 0.2)"
|
|
286
|
+
},
|
|
287
|
+
children: triggerIcon
|
|
288
|
+
}
|
|
289
|
+
) }) }),
|
|
290
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Menu.Dropdown, { style: { borderRadius: "11px" }, children: [
|
|
291
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Menu.Label, { children: text.title }),
|
|
292
|
+
modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
293
|
+
import_core3.Menu.Item,
|
|
294
|
+
{
|
|
295
|
+
leftSection: MODE_ICONS[mode],
|
|
296
|
+
onClick: () => setTheme(mode),
|
|
297
|
+
color: theme === mode ? activeColor : void 0,
|
|
298
|
+
fw: theme === mode ? 700 : 400,
|
|
299
|
+
children: text[mode === "time-based" ? "timeBased" : mode]
|
|
300
|
+
},
|
|
301
|
+
mode
|
|
302
|
+
))
|
|
303
|
+
] })
|
|
304
|
+
] });
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/components/ThemeSetting.tsx
|
|
308
|
+
var import_core4 = require("@mantine/core");
|
|
309
|
+
var import_dates = require("@mantine/dates");
|
|
143
310
|
var import_icons_react2 = require("@tabler/icons-react");
|
|
311
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
312
|
+
var DEFAULT_LABELS2 = {
|
|
313
|
+
title: "Appearance",
|
|
314
|
+
subtitle: "Control how the application looks and feels",
|
|
315
|
+
themeMode: "Theme mode",
|
|
316
|
+
themeModeHint: "Auto will switch between light and dark based on time of day",
|
|
317
|
+
currentlyActive: "Currently active:",
|
|
318
|
+
timeBasedSettings: "Time-based settings",
|
|
319
|
+
lightStartTime: "Light theme start time",
|
|
320
|
+
darkStartTime: "Dark theme start time",
|
|
321
|
+
light: "Light",
|
|
322
|
+
dark: "Dark",
|
|
323
|
+
system: "System",
|
|
324
|
+
timeBased: "Time-based"
|
|
325
|
+
};
|
|
326
|
+
var MODE_ICONS2 = {
|
|
327
|
+
light: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconSun, { size: 16 }),
|
|
328
|
+
dark: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconMoon, { size: 16 }),
|
|
329
|
+
auto: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconDeviceLaptop, { size: 16 }),
|
|
330
|
+
"time-based": /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconClock, { size: 16 })
|
|
331
|
+
};
|
|
332
|
+
var MODE_ORDER = ["light", "dark", "auto", "time-based"];
|
|
333
|
+
function ThemeSetting({
|
|
334
|
+
modes = MODE_ORDER,
|
|
335
|
+
labels = {},
|
|
336
|
+
cardProps = {}
|
|
337
|
+
}) {
|
|
338
|
+
const {
|
|
339
|
+
theme,
|
|
340
|
+
timeBasedSettings,
|
|
341
|
+
setTheme,
|
|
342
|
+
setTimeBasedSettings,
|
|
343
|
+
currentTheme
|
|
344
|
+
} = useTheme();
|
|
345
|
+
const text = { ...DEFAULT_LABELS2, ...labels };
|
|
346
|
+
const isTimeBased = theme === "time-based";
|
|
347
|
+
const isDark = currentTheme === "dark";
|
|
348
|
+
const showTimeBased = modes.includes("time-based");
|
|
349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
350
|
+
import_core4.Card,
|
|
351
|
+
{
|
|
352
|
+
withBorder: true,
|
|
353
|
+
radius: "lg",
|
|
354
|
+
p: "25px",
|
|
355
|
+
bg: isDark ? "dark.8" : "gray.0",
|
|
356
|
+
style: { flex: 1, overflow: "auto", display: "flex", flexDirection: "column" },
|
|
357
|
+
...cardProps,
|
|
358
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Stack, { gap: "lg", style: { flex: 1 }, children: [
|
|
359
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
|
|
360
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: "xs", children: [
|
|
361
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.ThemeIcon, { variant: "subtle", color: "blue.8", size: "md", radius: "md", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconPalette, { size: 25 }) }),
|
|
362
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Title, { order: 4, children: text.title })
|
|
363
|
+
] }),
|
|
364
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", c: "dimmed", children: text.subtitle })
|
|
365
|
+
] }),
|
|
366
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Divider, {}),
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { fw: 500, mb: 6, children: text.themeMode }),
|
|
369
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
370
|
+
import_core4.SegmentedControl,
|
|
371
|
+
{
|
|
372
|
+
fullWidth: true,
|
|
373
|
+
value: theme,
|
|
374
|
+
radius: "lg",
|
|
375
|
+
color: "teal.8",
|
|
376
|
+
bg: isDark ? "dark.6" : "gray.3",
|
|
377
|
+
onChange: (value) => setTheme(value),
|
|
378
|
+
data: MODE_ORDER.filter((mode) => modes.includes(mode)).map(
|
|
379
|
+
(mode) => ({
|
|
380
|
+
value: mode,
|
|
381
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: 6, children: [
|
|
382
|
+
MODE_ICONS2[mode],
|
|
383
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: mode === "light" ? text.light : mode === "dark" ? text.dark : mode === "auto" ? text.system : text.timeBased })
|
|
384
|
+
] })
|
|
385
|
+
})
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
),
|
|
389
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: text.themeModeHint }),
|
|
390
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Text, { size: "xs", mt: 4, children: [
|
|
391
|
+
text.currentlyActive,
|
|
392
|
+
" ",
|
|
393
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("b", { children: isDark ? text.dark : text.light })
|
|
394
|
+
] })
|
|
395
|
+
] }),
|
|
396
|
+
showTimeBased && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Divider, {}),
|
|
398
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
399
|
+
import_core4.Box,
|
|
400
|
+
{
|
|
401
|
+
style: {
|
|
402
|
+
opacity: isTimeBased ? 1 : 0.45,
|
|
403
|
+
pointerEvents: isTimeBased ? "auto" : "none",
|
|
404
|
+
transition: "opacity 150ms ease"
|
|
405
|
+
},
|
|
406
|
+
children: [
|
|
407
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: 6, mb: 6, children: [
|
|
408
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconClock, { size: 16 }),
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { fw: 500, children: text.timeBasedSettings })
|
|
410
|
+
] }),
|
|
411
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { grow: true, children: [
|
|
412
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
|
|
413
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.lightStartTime }),
|
|
414
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
415
|
+
import_dates.TimeInput,
|
|
416
|
+
{
|
|
417
|
+
withSeconds: false,
|
|
418
|
+
radius: "13px",
|
|
419
|
+
value: timeBasedSettings.lightStartTime,
|
|
420
|
+
onChange: (event) => setTimeBasedSettings({
|
|
421
|
+
...timeBasedSettings,
|
|
422
|
+
lightStartTime: event.currentTarget.value
|
|
423
|
+
})
|
|
424
|
+
}
|
|
425
|
+
)
|
|
426
|
+
] }),
|
|
427
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
|
|
428
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.darkStartTime }),
|
|
429
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
430
|
+
import_dates.TimeInput,
|
|
431
|
+
{
|
|
432
|
+
withSeconds: false,
|
|
433
|
+
radius: "13px",
|
|
434
|
+
value: timeBasedSettings.darkStartTime,
|
|
435
|
+
onChange: (event) => setTimeBasedSettings({
|
|
436
|
+
...timeBasedSettings,
|
|
437
|
+
darkStartTime: event.currentTarget.value
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
] })
|
|
442
|
+
] }),
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: [
|
|
444
|
+
text.light,
|
|
445
|
+
": ",
|
|
446
|
+
timeBasedSettings.lightStartTime,
|
|
447
|
+
" \u2192",
|
|
448
|
+
" ",
|
|
449
|
+
timeBasedSettings.darkStartTime,
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("br", {}),
|
|
451
|
+
text.dark,
|
|
452
|
+
": ",
|
|
453
|
+
timeBasedSettings.darkStartTime,
|
|
454
|
+
" \u2192",
|
|
455
|
+
" ",
|
|
456
|
+
timeBasedSettings.lightStartTime
|
|
457
|
+
] })
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
)
|
|
461
|
+
] })
|
|
462
|
+
] })
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/modals/Information.tsx
|
|
468
|
+
var import_react2 = require("react");
|
|
469
|
+
var import_core5 = require("@mantine/core");
|
|
470
|
+
var import_lucide_react3 = require("lucide-react");
|
|
144
471
|
|
|
145
472
|
// src/utils/commonUtils.ts
|
|
146
473
|
var copyToClipboard = async (text) => {
|
|
@@ -280,58 +607,58 @@ function formatHumanDate(date, options) {
|
|
|
280
607
|
}
|
|
281
608
|
|
|
282
609
|
// src/modals/Information.tsx
|
|
283
|
-
var
|
|
284
|
-
var DEFAULT_TITLE = /* @__PURE__ */ (0,
|
|
285
|
-
/* @__PURE__ */ (0,
|
|
286
|
-
/* @__PURE__ */ (0,
|
|
610
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
611
|
+
var DEFAULT_TITLE = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "xs", wrap: "nowrap", children: [
|
|
612
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Cpu, { size: 20 }),
|
|
613
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "System Information" })
|
|
287
614
|
] });
|
|
288
615
|
function InformationContent({ info }) {
|
|
289
|
-
const colorScheme = (0,
|
|
616
|
+
const colorScheme = (0, import_core5.useComputedColorScheme)();
|
|
290
617
|
const author = info.author ?? DEFAULT_AUTHOR;
|
|
291
618
|
const versionType = info.versionType ?? DEFAULT_VERSION_TYPE;
|
|
292
619
|
const cards = [
|
|
293
620
|
{
|
|
294
|
-
icon: /* @__PURE__ */ (0,
|
|
621
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.User, { size: 18 }),
|
|
295
622
|
label: "Author",
|
|
296
623
|
value: author,
|
|
297
624
|
color: "blue"
|
|
298
625
|
},
|
|
299
626
|
{
|
|
300
|
-
icon: /* @__PURE__ */ (0,
|
|
627
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Award, { size: 18 }),
|
|
301
628
|
label: "License",
|
|
302
629
|
value: info.license ?? DEFAULT_LICENSE,
|
|
303
630
|
color: "orange"
|
|
304
631
|
},
|
|
305
632
|
{
|
|
306
|
-
icon: /* @__PURE__ */ (0,
|
|
633
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.MapPin, { size: 18 }),
|
|
307
634
|
label: "Location",
|
|
308
635
|
value: info.location ?? DEFAULT_LOCATION,
|
|
309
636
|
color: "teal"
|
|
310
637
|
},
|
|
311
638
|
{
|
|
312
|
-
icon: /* @__PURE__ */ (0,
|
|
639
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Tag, { size: 18 }),
|
|
313
640
|
label: "Version Type",
|
|
314
641
|
value: versionType,
|
|
315
642
|
color: "red"
|
|
316
643
|
},
|
|
317
644
|
{
|
|
318
|
-
icon: /* @__PURE__ */ (0,
|
|
645
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Calendar, { size: 18 }),
|
|
319
646
|
label: "Build Time",
|
|
320
647
|
value: info.buildTime !== void 0 ? formatAbsoluteAndRelativeTime(info.buildTime) : UNKNOWN,
|
|
321
648
|
color: "green"
|
|
322
649
|
},
|
|
323
650
|
...info.metadata ?? []
|
|
324
651
|
];
|
|
325
|
-
return /* @__PURE__ */ (0,
|
|
326
|
-
/* @__PURE__ */ (0,
|
|
652
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: "lg", children: [
|
|
653
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: "xs", align: "center", children: [
|
|
327
654
|
info.logo,
|
|
328
|
-
/* @__PURE__ */ (0,
|
|
329
|
-
/* @__PURE__ */ (0,
|
|
330
|
-
info.tagline && /* @__PURE__ */ (0,
|
|
655
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, align: "center", children: [
|
|
656
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Title, { order: 2, children: info.name }),
|
|
657
|
+
info.tagline && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", c: "dimmed", w: 600, ta: "center", children: info.tagline })
|
|
331
658
|
] }),
|
|
332
|
-
/* @__PURE__ */ (0,
|
|
333
|
-
info.version && /* @__PURE__ */ (0,
|
|
334
|
-
|
|
659
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "xs", children: [
|
|
660
|
+
info.version && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
661
|
+
import_core5.Badge,
|
|
335
662
|
{
|
|
336
663
|
size: "lg",
|
|
337
664
|
color: "blue",
|
|
@@ -345,8 +672,8 @@ function InformationContent({ info }) {
|
|
|
345
672
|
]
|
|
346
673
|
}
|
|
347
674
|
),
|
|
348
|
-
/* @__PURE__ */ (0,
|
|
349
|
-
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
676
|
+
import_core5.Badge,
|
|
350
677
|
{
|
|
351
678
|
size: "lg",
|
|
352
679
|
color: "teal",
|
|
@@ -362,39 +689,39 @@ function InformationContent({ info }) {
|
|
|
362
689
|
)
|
|
363
690
|
] })
|
|
364
691
|
] }),
|
|
365
|
-
/* @__PURE__ */ (0,
|
|
366
|
-
/* @__PURE__ */ (0,
|
|
367
|
-
cards.map((card) => /* @__PURE__ */ (0,
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Divider, { label: "System Information", labelPosition: "center" }),
|
|
693
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
|
|
694
|
+
cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
368
695
|
InfoCard,
|
|
369
696
|
{
|
|
370
|
-
icon: card.icon ?? /* @__PURE__ */ (0,
|
|
697
|
+
icon: card.icon ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Award, { size: 18 }),
|
|
371
698
|
label: card.label,
|
|
372
699
|
value: card.value,
|
|
373
700
|
color: card.color ?? "gray"
|
|
374
701
|
},
|
|
375
702
|
card.label
|
|
376
703
|
)),
|
|
377
|
-
/* @__PURE__ */ (0,
|
|
378
|
-
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
705
|
+
import_core5.Paper,
|
|
379
706
|
{
|
|
380
707
|
withBorder: true,
|
|
381
708
|
p: "sm",
|
|
382
709
|
radius: "18px",
|
|
383
710
|
bg: colorScheme === "dark" ? "gray.9" : "gray.0",
|
|
384
|
-
children: /* @__PURE__ */ (0,
|
|
385
|
-
/* @__PURE__ */ (0,
|
|
386
|
-
/* @__PURE__ */ (0,
|
|
387
|
-
/* @__PURE__ */ (0,
|
|
388
|
-
/* @__PURE__ */ (0,
|
|
389
|
-
/* @__PURE__ */ (0,
|
|
711
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { justify: "space-between", wrap: "nowrap", children: [
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "sm", flex: 1, children: [
|
|
713
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ThemeIcon, { variant: "light", color: "yellow", size: "lg", radius: "14px", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Hash, { size: 18 }) }),
|
|
714
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, children: [
|
|
715
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Build ID" }),
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", fw: 500, truncate: true, children: info.buildId ?? UNKNOWN })
|
|
390
717
|
] })
|
|
391
718
|
] }),
|
|
392
|
-
info.buildId && /* @__PURE__ */ (0,
|
|
719
|
+
info.buildId && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyBuildIdButton, { buildId: info.buildId })
|
|
393
720
|
] })
|
|
394
721
|
}
|
|
395
722
|
)
|
|
396
723
|
] }),
|
|
397
|
-
/* @__PURE__ */ (0,
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
398
725
|
Footer,
|
|
399
726
|
{
|
|
400
727
|
copyright: info.copyright,
|
|
@@ -411,8 +738,8 @@ function InformationModal({
|
|
|
411
738
|
info,
|
|
412
739
|
title = DEFAULT_TITLE
|
|
413
740
|
}) {
|
|
414
|
-
return /* @__PURE__ */ (0,
|
|
415
|
-
|
|
741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
742
|
+
import_core5.Modal,
|
|
416
743
|
{
|
|
417
744
|
opened,
|
|
418
745
|
onClose,
|
|
@@ -431,12 +758,12 @@ function InformationModal({
|
|
|
431
758
|
}
|
|
432
759
|
},
|
|
433
760
|
title,
|
|
434
|
-
children: /* @__PURE__ */ (0,
|
|
761
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InformationContent, { info })
|
|
435
762
|
}
|
|
436
763
|
);
|
|
437
764
|
}
|
|
438
765
|
function CopyBuildIdButton({ buildId }) {
|
|
439
|
-
const [copied, setCopied] = (0,
|
|
766
|
+
const [copied, setCopied] = (0, import_react2.useState)(false);
|
|
440
767
|
const handleCopy = async () => {
|
|
441
768
|
const success = await copyToClipboard(buildId);
|
|
442
769
|
if (success) {
|
|
@@ -444,13 +771,13 @@ function CopyBuildIdButton({ buildId }) {
|
|
|
444
771
|
setTimeout(() => setCopied(false), 2e3);
|
|
445
772
|
}
|
|
446
773
|
};
|
|
447
|
-
return /* @__PURE__ */ (0,
|
|
448
|
-
|
|
774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Tooltip, { label: copied ? "Copied!" : "Copy ID", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
775
|
+
import_core5.ActionIcon,
|
|
449
776
|
{
|
|
450
777
|
variant: "subtle",
|
|
451
778
|
color: copied ? "teal" : "gray",
|
|
452
779
|
onClick: handleCopy,
|
|
453
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
780
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Check, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Copy, { size: 16 })
|
|
454
781
|
}
|
|
455
782
|
) });
|
|
456
783
|
}
|
|
@@ -460,15 +787,101 @@ function InfoCard({
|
|
|
460
787
|
value,
|
|
461
788
|
color
|
|
462
789
|
}) {
|
|
463
|
-
const colorScheme = (0,
|
|
464
|
-
return /* @__PURE__ */ (0,
|
|
465
|
-
/* @__PURE__ */ (0,
|
|
466
|
-
/* @__PURE__ */ (0,
|
|
467
|
-
/* @__PURE__ */ (0,
|
|
468
|
-
/* @__PURE__ */ (0,
|
|
790
|
+
const colorScheme = (0, import_core5.useComputedColorScheme)();
|
|
791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Paper, { withBorder: true, p: "md", radius: "18px", h: "100%", bg: colorScheme === "dark" ? "gray.9" : "gray.0", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "sm", align: "flex-start", children: [
|
|
792
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ThemeIcon, { color, variant: "light", size: "lg", radius: "14px", children: icon }),
|
|
793
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, flex: 1, children: [
|
|
794
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: label }),
|
|
795
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", fw: 500, lineClamp: 1, children: value })
|
|
469
796
|
] })
|
|
470
797
|
] }) });
|
|
471
798
|
}
|
|
799
|
+
|
|
800
|
+
// src/pages/NotFound.tsx
|
|
801
|
+
var import_core6 = require("@mantine/core");
|
|
802
|
+
var import_icons_react3 = require("@tabler/icons-react");
|
|
803
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
804
|
+
function NotFound({
|
|
805
|
+
path,
|
|
806
|
+
onSearchClick,
|
|
807
|
+
onHomeClick
|
|
808
|
+
}) {
|
|
809
|
+
const currentPath = path || (typeof window !== "undefined" ? window.location.pathname : "/404");
|
|
810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
811
|
+
import_core6.Box,
|
|
812
|
+
{
|
|
813
|
+
style: {
|
|
814
|
+
minHeight: "100vh",
|
|
815
|
+
display: "flex",
|
|
816
|
+
alignItems: "center",
|
|
817
|
+
background: "radial-gradient(circle at top left, rgba(34, 139, 230, 0.15), transparent 45%), radial-gradient(circle at bottom right, rgba(34, 211, 238, 0.12), transparent 45%), var(--mantine-color-body)"
|
|
818
|
+
},
|
|
819
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Container, { size: "xl", py: 80, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core6.Paper, { radius: "xl", p: 48, withBorder: true, style: { borderColor: "var(--mantine-color-default-border)", textAlign: "center" }, children: [
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
821
|
+
import_core6.Box,
|
|
822
|
+
{
|
|
823
|
+
mx: "auto",
|
|
824
|
+
mb: "xl",
|
|
825
|
+
w: 96,
|
|
826
|
+
h: 96,
|
|
827
|
+
style: {
|
|
828
|
+
borderRadius: "50%",
|
|
829
|
+
display: "flex",
|
|
830
|
+
alignItems: "center",
|
|
831
|
+
justifyContent: "center",
|
|
832
|
+
background: "linear-gradient(135deg, var(--mantine-color-blue-6), var(--mantine-color-cyan-6))",
|
|
833
|
+
boxShadow: "0 12px 32px rgba(34, 139, 230, 0.35)"
|
|
834
|
+
},
|
|
835
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconFileOff, { size: 44, stroke: 1.5, color: "white" })
|
|
836
|
+
}
|
|
837
|
+
),
|
|
838
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
839
|
+
import_core6.Text,
|
|
840
|
+
{
|
|
841
|
+
fz: { base: 72, sm: 100 },
|
|
842
|
+
fw: 900,
|
|
843
|
+
lh: 1,
|
|
844
|
+
variant: "gradient",
|
|
845
|
+
gradient: { from: "blue.7", to: "cyan.5", deg: 45 },
|
|
846
|
+
children: "404"
|
|
847
|
+
}
|
|
848
|
+
),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Badge, { variant: "light", color: "blue", size: "lg", mb: "xs", children: "NOT FOUND" }),
|
|
850
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Title, { order: 2, mt: "sm", mb: "xs", children: "Trang kh\xF4ng t\u1ED3n t\u1EA1i" }),
|
|
851
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Text, { c: "dimmed", size: "sm", maw: 440, mx: "auto", children: "Trang ho\u1EB7c \u0111\u01B0\u1EDDng d\u1EABn b\u1EA1n truy c\u1EADp kh\xF4ng t\u1ED3n t\u1EA1i ho\u1EB7c \u0111\xE3 \u0111\u01B0\u1EE3c di chuy\u1EC3n. Vui l\xF2ng ki\u1EC3m tra l\u1EA1i \u0111\u01B0\u1EDDng d\u1EABn ho\u1EB7c quay v\u1EC1 trang ch\u1EE7." }),
|
|
852
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Box, { mt: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Code, { color: "blue", variant: "light", px: "md", py: 6, children: currentPath }) }),
|
|
853
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core6.Group, { gap: "sm", mt: "xl", justify: "center", children: [
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
855
|
+
import_core6.Button,
|
|
856
|
+
{
|
|
857
|
+
variant: "light",
|
|
858
|
+
leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconArrowLeft, { size: 16 }),
|
|
859
|
+
onClick: () => window.history.back(),
|
|
860
|
+
children: "Quay l\u1EA1i"
|
|
861
|
+
}
|
|
862
|
+
),
|
|
863
|
+
onSearchClick && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
864
|
+
import_core6.Button,
|
|
865
|
+
{
|
|
866
|
+
variant: "outline",
|
|
867
|
+
leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconSearch, { size: 16 }),
|
|
868
|
+
onClick: onSearchClick,
|
|
869
|
+
children: "T\xECm Docs"
|
|
870
|
+
}
|
|
871
|
+
),
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
873
|
+
import_core6.Button,
|
|
874
|
+
{
|
|
875
|
+
leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconHome, { size: 16 }),
|
|
876
|
+
onClick: onHomeClick || (() => window.location.href = "/"),
|
|
877
|
+
children: "Trang ch\u1EE7"
|
|
878
|
+
}
|
|
879
|
+
)
|
|
880
|
+
] })
|
|
881
|
+
] }) })
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
}
|
|
472
885
|
// Annotate the CommonJS export names for ESM import in node:
|
|
473
886
|
0 && (module.exports = {
|
|
474
887
|
DEFAULT_AUTHOR,
|
|
@@ -480,6 +893,10 @@ function InfoCard({
|
|
|
480
893
|
Footer,
|
|
481
894
|
InformationContent,
|
|
482
895
|
InformationModal,
|
|
896
|
+
NotFound,
|
|
897
|
+
ThemeMenu,
|
|
898
|
+
ThemeProvider,
|
|
899
|
+
ThemeSetting,
|
|
483
900
|
UNKNOWN,
|
|
484
901
|
calculateRemainingTime,
|
|
485
902
|
copyToClipboard,
|
|
@@ -488,6 +905,8 @@ function InfoCard({
|
|
|
488
905
|
formatHumanDate,
|
|
489
906
|
formatRelativeTime,
|
|
490
907
|
normalizeDate,
|
|
491
|
-
pad
|
|
908
|
+
pad,
|
|
909
|
+
resolveColorScheme,
|
|
910
|
+
useTheme
|
|
492
911
|
});
|
|
493
912
|
//# sourceMappingURL=index.cjs.map
|