diff --git a/apps/admin/app/dashboard/system/node.tsx b/apps/admin/app/dashboard/system/node.tsx index 9e73f26..0308b83 100644 --- a/apps/admin/app/dashboard/system/node.tsx +++ b/apps/admin/app/dashboard/system/node.tsx @@ -8,15 +8,26 @@ import { } from '@/services/admin/system'; import { useQuery } from '@tanstack/react-query'; import { Button } from '@workspace/ui/components/button'; +import { ChartContainer, ChartTooltip } from '@workspace/ui/components/chart'; import { Label } from '@workspace/ui/components/label'; import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table'; +import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { DicesIcon } from 'lucide-react'; import { nanoid } from 'nanoid'; import { useTranslations } from 'next-intl'; -import { useState } from 'react'; +import { useMemo, useState } from 'react'; +import { Cell, Legend, Pie, PieChart } from 'recharts'; import { toast } from 'sonner'; +const COLORS = [ + 'hsl(var(--chart-1))', + 'hsl(var(--chart-2))', + 'hsl(var(--chart-3))', + 'hsl(var(--chart-4))', + 'hsl(var(--chart-5))', +]; + export default function Node() { const t = useTranslations('system.node'); @@ -56,23 +67,25 @@ export default function Node() { }, }); - const addTimeSlot = () => { - setTimeSlots([...timeSlots, { start_time: '', end_time: '', multiplier: 1 }]); - }; + const chartTimeSlots = useMemo(() => { + return timeSlots.map((slot) => ({ + name: `${slot.start_time} - ${slot.end_time}`, + value: slot.multiplier, + })); + }, [timeSlots]); - const removeTimeSlot = (index: number) => { - setTimeSlots(timeSlots.filter((_, i) => i !== index)); - }; - - const updateTimeSlot = (index: number, field: keyof API.TimePeriod, value: string | number) => { - const updatedSlots = timeSlots.map((slot, i) => { - if (i === index) { - return { ...slot, [field]: value }; - } - return slot; - }); - setTimeSlots(updatedSlots); - }; + const chartConfig = useMemo(() => { + return chartTimeSlots.reduce( + (acc, item, index) => { + acc[item.name] = { + label: item.name, + color: COLORS[index % COLORS.length] || 'hsl(var(--default-chart-color))', + }; + return acc; + }, + {} as Record, + ); + }, [data]); return ( <> @@ -162,55 +175,73 @@ export default function Node() { -
-
- {timeSlots.map((slot, index) => ( -
-
- - updateTimeSlot(index, 'start_time', value as string)} - /> -
- -
- - updateTimeSlot(index, 'end_time', value as string)} - /> -
- -
- - updateTimeSlot(index, 'multiplier', value as number)} - min={1} - step='0.1' - /> -
- -
- ))} + {chartTimeSlots.map((entry, index) => ( + + ))} + + { + if (payload && payload.length) { + const data = payload[0]?.payload; + return ( +
+
+
+ + {t('timeSlot')} + + + {data.name || '其他'} + +
+
+ + {t('multiplier')} + + {data.value.toFixed(2)}x +
+
+
+ ); + } + return null; + }} + /> + + + +
+
+ + fields={[ + { + name: 'start_time', + prefix: t('startTime'), + type: 'time', + }, + { name: 'end_time', prefix: t('endTime'), type: 'time' }, + { name: 'multiplier', prefix: t('multiplier'), type: 'number' }, + ]} + value={timeSlots} + onChange={setTimeSlots} + />
-
); diff --git a/apps/admin/locales/cs-CZ/system.json b/apps/admin/locales/cs-CZ/system.json index 0b5e300..95ab548 100644 --- a/apps/admin/locales/cs-CZ/system.json +++ b/apps/admin/locales/cs-CZ/system.json @@ -61,7 +61,8 @@ "reset": "Resetovat", "save": "Uložit", "saveSuccess": "Úspěšně uloženo", - "startTime": "Čas začátku" + "startTime": "Čas začátku", + "timeSlot": "Časový úsek" }, "register": { "emailSuffixWhitelist": "Seznam povolených přípon e-mailů", diff --git a/apps/admin/locales/de-DE/system.json b/apps/admin/locales/de-DE/system.json index 3fc34d1..3a0fe2e 100644 --- a/apps/admin/locales/de-DE/system.json +++ b/apps/admin/locales/de-DE/system.json @@ -61,7 +61,8 @@ "reset": "Zurücksetzen", "save": "Speichern", "saveSuccess": "Erfolgreich gespeichert", - "startTime": "Startzeit" + "startTime": "Startzeit", + "timeSlot": "Zeitfenster" }, "register": { "emailSuffixWhitelist": "E-Mail-Suffix-Whitelist", diff --git a/apps/admin/locales/en-US/system.json b/apps/admin/locales/en-US/system.json index 50799eb..c9072f3 100644 --- a/apps/admin/locales/en-US/system.json +++ b/apps/admin/locales/en-US/system.json @@ -61,7 +61,8 @@ "reset": "Reset", "save": "Save", "saveSuccess": "Save Successful", - "startTime": "Start Time" + "startTime": "Start Time", + "timeSlot": "Time Slot" }, "register": { "emailSuffixWhitelist": "Email Suffix Whitelist", diff --git a/apps/admin/locales/es-ES/system.json b/apps/admin/locales/es-ES/system.json index b50b4aa..40580f8 100644 --- a/apps/admin/locales/es-ES/system.json +++ b/apps/admin/locales/es-ES/system.json @@ -61,7 +61,8 @@ "reset": "Restablecer", "save": "Guardar", "saveSuccess": "Guardado exitosamente", - "startTime": "Hora de Inicio" + "startTime": "Hora de Inicio", + "timeSlot": "Franja Horaria" }, "register": { "emailSuffixWhitelist": "Lista blanca de sufijos de correo electrónico", diff --git a/apps/admin/locales/es-MX/system.json b/apps/admin/locales/es-MX/system.json index e0593f5..b166d90 100644 --- a/apps/admin/locales/es-MX/system.json +++ b/apps/admin/locales/es-MX/system.json @@ -61,7 +61,8 @@ "reset": "Restablecer", "save": "Guardar", "saveSuccess": "Guardado exitosamente", - "startTime": "Hora de Inicio" + "startTime": "Hora de Inicio", + "timeSlot": "Franja Horaria" }, "register": { "emailSuffixWhitelist": "Lista blanca de sufijos de correo electrónico", diff --git a/apps/admin/locales/fa-IR/system.json b/apps/admin/locales/fa-IR/system.json index 5d75a9f..c592640 100644 --- a/apps/admin/locales/fa-IR/system.json +++ b/apps/admin/locales/fa-IR/system.json @@ -61,7 +61,8 @@ "reset": "بازنشانی", "save": "ذخیره", "saveSuccess": "ذخیره با موفقیت انجام شد", - "startTime": "زمان شروع" + "startTime": "زمان شروع", + "timeSlot": "بازه زمانی" }, "register": { "emailSuffixWhitelist": "لیست سفید پسوند ایمیل", diff --git a/apps/admin/locales/fi-FI/system.json b/apps/admin/locales/fi-FI/system.json index e9c65d8..e5b8ede 100644 --- a/apps/admin/locales/fi-FI/system.json +++ b/apps/admin/locales/fi-FI/system.json @@ -61,7 +61,8 @@ "reset": "Nollaa", "save": "Tallenna", "saveSuccess": "Tallennus onnistui", - "startTime": "Aloitusaika" + "startTime": "Aloitusaika", + "timeSlot": "Aikaväli" }, "register": { "emailSuffixWhitelist": "Sähköpostin jälkiliitteen sallittu luettelo", diff --git a/apps/admin/locales/fr-FR/system.json b/apps/admin/locales/fr-FR/system.json index 9db3317..03a2610 100644 --- a/apps/admin/locales/fr-FR/system.json +++ b/apps/admin/locales/fr-FR/system.json @@ -61,7 +61,8 @@ "reset": "Réinitialiser", "save": "Enregistrer", "saveSuccess": "Enregistrement réussi", - "startTime": "Heure de Début" + "startTime": "Heure de Début", + "timeSlot": "Créneau horaire" }, "register": { "emailSuffixWhitelist": "Liste blanche des suffixes d'email", diff --git a/apps/admin/locales/hi-IN/system.json b/apps/admin/locales/hi-IN/system.json index 71ee520..22f2203 100644 --- a/apps/admin/locales/hi-IN/system.json +++ b/apps/admin/locales/hi-IN/system.json @@ -61,7 +61,8 @@ "reset": "रीसेट", "save": "सहेजें", "saveSuccess": "सफलतापूर्वक सहेजा गया", - "startTime": "प्रारंभ समय" + "startTime": "प्रारंभ समय", + "timeSlot": "समय स्लॉट" }, "register": { "emailSuffixWhitelist": "ईमेल प्रत्यय श्वेतसूची", diff --git a/apps/admin/locales/hu-HU/system.json b/apps/admin/locales/hu-HU/system.json index 8b6ed71..3236ee9 100644 --- a/apps/admin/locales/hu-HU/system.json +++ b/apps/admin/locales/hu-HU/system.json @@ -61,7 +61,8 @@ "reset": "Visszaállítás", "save": "Mentés", "saveSuccess": "Sikeres mentés", - "startTime": "Kezdési Idő" + "startTime": "Kezdési Idő", + "timeSlot": "Időpont" }, "register": { "emailSuffixWhitelist": "E-mail végződés fehérlista", diff --git a/apps/admin/locales/ja-JP/system.json b/apps/admin/locales/ja-JP/system.json index 4440167..f648084 100644 --- a/apps/admin/locales/ja-JP/system.json +++ b/apps/admin/locales/ja-JP/system.json @@ -61,7 +61,8 @@ "reset": "リセット", "save": "保存", "saveSuccess": "保存成功", - "startTime": "開始時間" + "startTime": "開始時間", + "timeSlot": "時間枠" }, "register": { "emailSuffixWhitelist": "メールサフィックスホワイトリスト", diff --git a/apps/admin/locales/ko-KR/system.json b/apps/admin/locales/ko-KR/system.json index 0ae5749..2ceca34 100644 --- a/apps/admin/locales/ko-KR/system.json +++ b/apps/admin/locales/ko-KR/system.json @@ -61,7 +61,8 @@ "reset": "재설정", "save": "저장", "saveSuccess": "저장 성공", - "startTime": "시작 시간" + "startTime": "시작 시간", + "timeSlot": "시간대" }, "register": { "emailSuffixWhitelist": "이메일 접미사 화이트리스트", diff --git a/apps/admin/locales/no-NO/system.json b/apps/admin/locales/no-NO/system.json index 75713ff..2686f68 100644 --- a/apps/admin/locales/no-NO/system.json +++ b/apps/admin/locales/no-NO/system.json @@ -61,7 +61,8 @@ "reset": "Tilbakestill", "save": "Lagre", "saveSuccess": "Lagring vellykket", - "startTime": "Starttid" + "startTime": "Starttid", + "timeSlot": "Tidsluke" }, "register": { "emailSuffixWhitelist": "E-post suffiks hviteliste", diff --git a/apps/admin/locales/pl-PL/system.json b/apps/admin/locales/pl-PL/system.json index 7a81a84..c915fda 100644 --- a/apps/admin/locales/pl-PL/system.json +++ b/apps/admin/locales/pl-PL/system.json @@ -61,7 +61,8 @@ "reset": "Resetuj", "save": "Zapisz", "saveSuccess": "Zapisano pomyślnie", - "startTime": "Czas rozpoczęcia" + "startTime": "Czas rozpoczęcia", + "timeSlot": "Przedział czasowy" }, "register": { "emailSuffixWhitelist": "Biała lista sufiksów e-mail", diff --git a/apps/admin/locales/pt-BR/system.json b/apps/admin/locales/pt-BR/system.json index 86778f6..6ac3f5f 100644 --- a/apps/admin/locales/pt-BR/system.json +++ b/apps/admin/locales/pt-BR/system.json @@ -61,7 +61,8 @@ "reset": "Redefinir", "save": "Salvar", "saveSuccess": "Salvo com sucesso", - "startTime": "Hora de Início" + "startTime": "Hora de Início", + "timeSlot": "Horário" }, "register": { "emailSuffixWhitelist": "Lista branca de sufixos de e-mail", diff --git a/apps/admin/locales/ro-RO/system.json b/apps/admin/locales/ro-RO/system.json index f3aefc8..58ff671 100644 --- a/apps/admin/locales/ro-RO/system.json +++ b/apps/admin/locales/ro-RO/system.json @@ -61,7 +61,8 @@ "reset": "Resetare", "save": "Salvare", "saveSuccess": "Salvare reușită", - "startTime": "Ora de Începere" + "startTime": "Ora de Începere", + "timeSlot": "Interval de timp" }, "register": { "emailSuffixWhitelist": "Lista albă a sufixelor de e-mail", diff --git a/apps/admin/locales/ru-RU/system.json b/apps/admin/locales/ru-RU/system.json index d9f1ec7..c1c3f82 100644 --- a/apps/admin/locales/ru-RU/system.json +++ b/apps/admin/locales/ru-RU/system.json @@ -61,7 +61,8 @@ "reset": "Сбросить", "save": "Сохранить", "saveSuccess": "Успешно сохранено", - "startTime": "Время начала" + "startTime": "Время начала", + "timeSlot": "Временной интервал" }, "register": { "emailSuffixWhitelist": "Белый список суффиксов электронной почты", diff --git a/apps/admin/locales/th-TH/system.json b/apps/admin/locales/th-TH/system.json index c85bfcd..7536c73 100644 --- a/apps/admin/locales/th-TH/system.json +++ b/apps/admin/locales/th-TH/system.json @@ -61,7 +61,8 @@ "reset": "รีเซ็ต", "save": "บันทึก", "saveSuccess": "บันทึกสำเร็จ", - "startTime": "เวลาเริ่มต้น" + "startTime": "เวลาเริ่มต้น", + "timeSlot": "ช่วงเวลา" }, "register": { "emailSuffixWhitelist": "รายการอนุญาตโดเมนอีเมล", diff --git a/apps/admin/locales/tr-TR/system.json b/apps/admin/locales/tr-TR/system.json index 5a0ce4a..3089f0e 100644 --- a/apps/admin/locales/tr-TR/system.json +++ b/apps/admin/locales/tr-TR/system.json @@ -61,7 +61,8 @@ "reset": "Sıfırla", "save": "Kaydet", "saveSuccess": "Başarıyla kaydedildi", - "startTime": "Başlangıç Zamanı" + "startTime": "Başlangıç Zamanı", + "timeSlot": "Zaman Dilimi" }, "register": { "emailSuffixWhitelist": "E-posta Soneki Beyaz Listesi", diff --git a/apps/admin/locales/uk-UA/system.json b/apps/admin/locales/uk-UA/system.json index e075a52..cc7cc76 100644 --- a/apps/admin/locales/uk-UA/system.json +++ b/apps/admin/locales/uk-UA/system.json @@ -61,7 +61,8 @@ "reset": "Скинути", "save": "Зберегти", "saveSuccess": "Збережено успішно", - "startTime": "Час Початку" + "startTime": "Час Початку", + "timeSlot": "Часовий проміжок" }, "register": { "emailSuffixWhitelist": "Білий список суфіксів електронної пошти", diff --git a/apps/admin/locales/vi-VN/system.json b/apps/admin/locales/vi-VN/system.json index 35003d4..942076a 100644 --- a/apps/admin/locales/vi-VN/system.json +++ b/apps/admin/locales/vi-VN/system.json @@ -61,7 +61,8 @@ "reset": "Đặt lại", "save": "Lưu", "saveSuccess": "Lưu thành công", - "startTime": "Thời gian bắt đầu" + "startTime": "Thời gian bắt đầu", + "timeSlot": "Khung giờ" }, "register": { "emailSuffixWhitelist": "Danh sách trắng hậu tố email", diff --git a/apps/admin/locales/zh-CN/system.json b/apps/admin/locales/zh-CN/system.json index b871256..9059c7f 100644 --- a/apps/admin/locales/zh-CN/system.json +++ b/apps/admin/locales/zh-CN/system.json @@ -61,7 +61,8 @@ "reset": "重置", "save": "保存", "saveSuccess": "保存成功", - "startTime": "开始时间" + "startTime": "开始时间", + "timeSlot": "时间段" }, "register": { "emailSuffixWhitelist": "电子邮件后缀白名单", diff --git a/apps/admin/locales/zh-HK/system.json b/apps/admin/locales/zh-HK/system.json index c3a210e..ce62bb3 100644 --- a/apps/admin/locales/zh-HK/system.json +++ b/apps/admin/locales/zh-HK/system.json @@ -61,7 +61,8 @@ "reset": "重設", "save": "儲存", "saveSuccess": "保存成功", - "startTime": "開始時間" + "startTime": "開始時間", + "timeSlot": "時間段" }, "register": { "emailSuffixWhitelist": "電子郵件後綴白名單", diff --git a/packages/ui/src/custom-components/dynamic-Inputs.tsx b/packages/ui/src/custom-components/dynamic-Inputs.tsx index 9c5e89a..04a43a6 100644 --- a/packages/ui/src/custom-components/dynamic-Inputs.tsx +++ b/packages/ui/src/custom-components/dynamic-Inputs.tsx @@ -6,7 +6,7 @@ import { useEffect, useState } from 'react'; interface FieldConfig extends Omit { name: string; - type: 'text' | 'number' | 'select'; + type: 'text' | 'number' | 'select' | 'time'; options?: { label: string; value: string }[]; internal?: boolean; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -53,7 +53,7 @@ export function ObjectInput>({ }; return ( -
+
{fields.map(({ name, type, options, ...fieldProps }) => (
{type === 'select' && options ? ( @@ -127,6 +127,12 @@ export function ArrayInput>({ onChange(modifiedItems); }; + useEffect(() => { + if (value.length > 0) { + setDisplayItems(value); + } + }, [value]); + return (
{displayItems.map((item, index) => ( diff --git a/packages/ui/src/custom-components/enhanced-input.tsx b/packages/ui/src/custom-components/enhanced-input.tsx index 4199825..2a6bcdc 100644 --- a/packages/ui/src/custom-components/enhanced-input.tsx +++ b/packages/ui/src/custom-components/enhanced-input.tsx @@ -76,7 +76,9 @@ export function EnhancedInput({ className={cn('border-input flex w-full items-center rounded-md border', className)} suppressHydrationWarning > - {prefix &&
{prefix}
} + {prefix && ( +
{prefix}
+ )} - {suffix &&
{suffix}
} + {suffix && ( +
{suffix}
+ )}
); }