From 55a4f7bf09b694cb6658736782475825477b3d45 Mon Sep 17 00:00:00 2001 From: TheOnlyMace <0815cracky@gmail.com> Date: Wed, 22 Jul 2026 21:49:38 +0200 Subject: [PATCH] Enhance embed functionality across scheduler and welcome components - Updated SchedulerManager and WelcomeForm to integrate DiscordEmbedBuilder for managing embeds, replacing JSON text areas with a more user-friendly interface. - Modified data handling in the scheduler and welcome configurations to support embed structures, ensuring proper parsing and validation. - Updated localization files to reflect changes in embed handling, improving user guidance and clarity in both English and German. - Enhanced validation schemas to require embed titles or descriptions where necessary, ensuring robust data integrity. --- .../components/modules/scheduler-manager.tsx | 30 ++- .../src/components/modules/welcome-form.tsx | 83 +++----- .../components/ui/discord-embed-builder.tsx | 191 ++++++++++++++++++ .../webui/src/lib/module-configs/scheduler.ts | 23 ++- apps/webui/src/lib/module-configs/tags.ts | 26 ++- apps/webui/src/lib/module-configs/welcome.ts | 20 +- apps/webui/src/messages/de.json | 27 ++- apps/webui/src/messages/en.json | 27 ++- docs/PHASE-TRACKING.md | 15 ++ packages/shared/src/dashboard.ts | 32 ++- 10 files changed, 392 insertions(+), 82 deletions(-) create mode 100644 apps/webui/src/components/ui/discord-embed-builder.tsx diff --git a/apps/webui/src/components/modules/scheduler-manager.tsx b/apps/webui/src/components/modules/scheduler-manager.tsx index c84507e..db83aa2 100644 --- a/apps/webui/src/components/modules/scheduler-manager.tsx +++ b/apps/webui/src/components/modules/scheduler-manager.tsx @@ -1,6 +1,6 @@ 'use client'; -import type { ScheduledMessageDashboard } from '@nexumi/shared'; +import type { ScheduledMessageDashboard, WelcomeEmbed } from '@nexumi/shared'; import { Plus, Trash2 } from 'lucide-react'; import { useState } from 'react'; import { toast } from 'sonner'; @@ -9,6 +9,7 @@ import { useTranslations } from '@/components/locale-provider'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { DiscordChannelSelect } from '@/components/ui/discord-channel-select'; +import { DiscordEmbedBuilder, normalizeEmbed } from '@/components/ui/discord-embed-builder'; import { DiscordRoleSelect } from '@/components/ui/discord-role-select'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; @@ -17,6 +18,7 @@ import { Textarea } from '@/components/ui/textarea'; const EMPTY_DRAFT = { channelId: '', content: '', + embed: null as WelcomeEmbed | null, rolePingId: '', cron: '', runAt: '' @@ -35,6 +37,19 @@ function formatTiming(schedule: ScheduledMessageDashboard, t: (key: string) => s return '—'; } +function schedulePreview(schedule: ScheduledMessageDashboard, t: (key: string) => string): string { + if (schedule.content?.trim()) { + return schedule.content; + } + if (schedule.embed?.title?.trim()) { + return schedule.embed.title; + } + if (schedule.embed?.description?.trim()) { + return schedule.embed.description; + } + return t('modulePages.scheduler.noContent'); +} + interface SchedulerManagerProps { guildId: string; initialSchedules: ScheduledMessageDashboard[]; @@ -47,7 +62,9 @@ export function SchedulerManager({ guildId, initialSchedules }: SchedulerManager const [creating, setCreating] = useState(false); async function handleCreate() { - if (!draft.channelId.trim() || !draft.content.trim() || (!draft.cron.trim() && !draft.runAt)) { + const embed = normalizeEmbed(draft.embed); + const hasContent = Boolean(draft.content.trim()) || Boolean(embed?.title) || Boolean(embed?.description); + if (!draft.channelId.trim() || !hasContent || (!draft.cron.trim() && !draft.runAt)) { toast.error(t('modulePages.scheduler.formIncomplete')); return; } @@ -58,7 +75,8 @@ export function SchedulerManager({ guildId, initialSchedules }: SchedulerManager headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ channelId: draft.channelId.trim(), - content: draft.content.trim(), + content: draft.content.trim() || null, + embed, rolePingId: draft.rolePingId.trim() || undefined, cron: draft.cron.trim() || null, runAt: draft.cron.trim() ? null : draft.runAt ? new Date(draft.runAt).toISOString() : null @@ -151,6 +169,10 @@ export function SchedulerManager({ guildId, initialSchedules }: SchedulerManager rows={3} /> +
+ + setDraft((prev) => ({ ...prev, embed }))} /> +

{t('modulePages.scheduler.cronHint')}