Enhance ESLint configuration and update component destructuring for improved code quality

- Added a rule to allow unused variables prefixed with an underscore in ESLint configuration.
- Updated destructuring in leveling-form, logging-form, moderation-form, and welcome-form components to prefix unused variables with an underscore, improving clarity and adherence to ESLint rules.
- Expanded German and English localization files with new moderation, auto-moderation, logging, welcome, verification, leveling, economy, and fun module settings for better user experience.
This commit is contained in:
smueller
2026-07-22 14:56:03 +02:00
parent 1de28fa494
commit d079cfde79
7 changed files with 316 additions and 6 deletions

View File

@@ -20,6 +20,16 @@ const eslintConfig = [
"next-env.d.ts", "next-env.d.ts",
], ],
}, },
{
rules: {
// Allow intentionally unused variables (e.g. destructuring to strip fields)
// when prefixed with an underscore.
"@typescript-eslint/no-unused-vars": [
"warn",
{ varsIgnorePattern: "^_", argsIgnorePattern: "^_" },
],
},
},
]; ];
export default eslintConfig; export default eslintConfig;

View File

@@ -77,7 +77,7 @@ async function saveLeveling(guildId: string, value: LocalLevelingValue): Promise
return { ok: false, error: channelMultipliers.error }; return { ok: false, error: channelMultipliers.error };
} }
const { noXpChannelIdsText, noXpRoleIdsText, roleMultipliersText, channelMultipliersText, ...rest } = value; const { noXpChannelIdsText, noXpRoleIdsText, roleMultipliersText: _roleMultipliersText, channelMultipliersText: _channelMultipliersText, ...rest } = value;
const payload: LevelingConfigDashboard = { const payload: LevelingConfigDashboard = {
...rest, ...rest,

View File

@@ -82,7 +82,7 @@ function toRemote(value: LocalLoggingValue): LoggingConfigDashboard {
ignoreBots: value.ignoreBots, ignoreBots: value.ignoreBots,
ignoredChannelIds: fromCsv(value.ignoredChannelIdsText), ignoredChannelIds: fromCsv(value.ignoredChannelIdsText),
ignoredRoleIds: fromCsv(value.ignoredRoleIdsText), ignoredRoleIds: fromCsv(value.ignoredRoleIdsText),
logChannels: value.logChannels.map(({ clientKey, ...rest }) => rest) logChannels: value.logChannels.map(({ clientKey: _clientKey, ...rest }) => rest)
}; };
} }

View File

@@ -24,7 +24,7 @@ function toLocal(rules: EscalationRuleDashboard[]): LocalEscalation[] {
} }
function toRemote(rules: LocalEscalation[]): EscalationRuleDashboard[] { function toRemote(rules: LocalEscalation[]): EscalationRuleDashboard[] {
return rules.map(({ clientKey, ...rest }) => rest); return rules.map(({ clientKey: _clientKey, ...rest }) => rest);
} }
async function saveModeration(guildId: string, value: ModerationDashboard): Promise<SettingsSaveResult> { async function saveModeration(guildId: string, value: ModerationDashboard): Promise<SettingsSaveResult> {

View File

@@ -70,7 +70,7 @@ async function saveWelcome(guildId: string, value: LocalWelcomeValue): Promise<S
return { ok: false, error: leaveEmbed.error }; return { ok: false, error: leaveEmbed.error };
} }
const { userAutoroleIdsText, botAutoroleIdsText, welcomeEmbedText, leaveEmbedText, ...rest } = value; const { userAutoroleIdsText, botAutoroleIdsText, welcomeEmbedText: _welcomeEmbedText, leaveEmbedText: _leaveEmbedText, ...rest } = value;
const payload: WelcomeConfigDashboard = { const payload: WelcomeConfigDashboard = {
...rest, ...rest,

View File

@@ -119,9 +119,159 @@
}, },
"modulePlaceholder": { "modulePlaceholder": {
"title": "{module}-Einstellungen", "title": "{module}-Einstellungen",
"message": "Modul-Einstellungen kommen in Phase 7.", "message": "Modul-Einstellungen kommen in einer späteren Phase.",
"backToModules": "Zurück zu den Modulen" "backToModules": "Zurück zu den Modulen"
}, },
"modulePages": {
"moderation": {
"title": "Moderation",
"description": "Aktiviere das Moderations-Modul und konfiguriere automatische Eskalationsregeln.",
"enabledLabel": "Moderations-Modul aktiviert",
"enabledHint": "Aktiviert Ban, Kick, Warn, Purge und das Fall-System auf diesem Server.",
"escalationsTitle": "Eskalationsregeln",
"escalationsDescription": "Automatische Strafen ab einer bestimmten Anzahl an Verwarnungen.",
"noEscalations": "Keine Eskalationsregeln konfiguriert.",
"addEscalation": "Regel hinzufügen",
"warnCount": "Anzahl Verwarnungen",
"action": "Aktion",
"actions": { "TIMEOUT": "Timeout", "KICK": "Kick", "BAN": "Ban" },
"durationMs": "Dauer (ms)",
"reason": "Grund",
"reasonPlaceholder": "Optionaler Standardgrund",
"casesTitle": "Fälle",
"casesDescription": "Liste der zuletzt erstellten Moderations-Fälle (nur Lesezugriff).",
"searchPlaceholder": "Suche nach User- oder Moderator-ID / Grund",
"actionPlaceholder": "Aktion filtern, z. B. BAN",
"casesEmpty": "Keine Fälle gefunden.",
"target": "Ziel",
"moderator": "Moderator",
"createdAt": "Erstellt am",
"noReason": "Kein Grund angegeben"
},
"automod": {
"title": "Auto-Moderation",
"description": "Grundeinstellungen sowie Anti-Raid- und Anti-Nuke-Schutz.",
"enabledLabel": "Auto-Moderation aktiviert",
"enabledHint": "Aktiviert alle Auto-Moderations-Regeln (Spam, Wortfilter, Links, …) auf diesem Server.",
"antiRaidTitle": "Anti-Raid",
"antiRaidDescription": "Erkennt ungewöhnlich schnelle Join-Wellen und aktiviert automatisch einen Lockdown.",
"antiRaidEnabled": "Anti-Raid aktiviert",
"antiRaidJoinThreshold": "Schwellenwert (Joins)",
"antiRaidWindowSeconds": "Zeitfenster (Sekunden)",
"antiRaidActionHint": "Aktuell implementierte Reaktion: Server-Lockdown.",
"antiNukeTitle": "Anti-Nuke",
"antiNukeDescription": "Schützt vor Massen-Bans oder Massen-Kanal-Löschungen durch kompromittierte Accounts.",
"antiNukeEnabled": "Anti-Nuke aktiviert",
"antiNukeBanThreshold": "Schwellenwert (Bans)",
"antiNukeChannelThreshold": "Schwellenwert (Kanal-Löschungen)",
"antiNukeWindowSeconds": "Zeitfenster (Sekunden)",
"lockdownActive": "Lockdown aktiv",
"lockdownActiveHint": "Wird automatisch bei einem erkannten Raid gesetzt. Manuell zurücksetzen, um den Lockdown zu beenden."
},
"logging": {
"title": "Logging",
"description": "Log-Kanäle, Ignore-Listen und die Event-zu-Kanal-Zuordnung.",
"enabledLabel": "Logging aktiviert",
"ignoreBotsLabel": "Bot-Nachrichten/-Aktionen ignorieren",
"ignoredChannelsLabel": "Ignorierte Kanäle",
"ignoredRolesLabel": "Ignorierte Rollen",
"idsPlaceholder": "Kommagetrennte IDs, z. B. 123456789012345678, 234567890123456789",
"idsHint": "Discord-IDs kommagetrennt eintragen. Entwicklermodus aktivieren, um IDs zu kopieren.",
"channelsTitle": "Event-Kanal-Zuordnung",
"channelsDescription": "Lege für jeden Event-Typ einen eigenen Log-Kanal fest.",
"channelsEmpty": "Keine Event-Kanal-Zuordnungen konfiguriert.",
"eventType": "Event-Typ",
"channelId": "Kanal-ID",
"addMapping": "Zuordnung hinzufügen"
},
"welcome": {
"welcomeTitle": "Willkommen",
"welcomeDescription": "Nachricht, Kanal und Autoroles für neue Mitglieder.",
"welcomeEnabledLabel": "Willkommensnachricht aktiviert",
"welcomeChannelId": "Willkommens-Kanal-ID",
"welcomeType": "Nachrichtentyp",
"type": { "TEXT": "Text", "EMBED": "Embed", "IMAGE": "Bild-Karte" },
"welcomeContent": "Nachrichtentext",
"contentPlaceholder": "Willkommen {user} auf {server}!",
"placeholdersHint": "Verfügbare Platzhalter: {user}, {user.name}, {user.tag}, {user.id}, {server}, {memberCount}",
"welcomeEmbed": "Embed (JSON, optional)",
"welcomeDmEnabled": "Willkommens-DM aktiviert",
"dmContentPlaceholder": "Optionale private Nachricht an neue Mitglieder",
"userAutoroles": "Autoroles für Nutzer",
"botAutoroles": "Autoroles für Bots",
"imageTitle": "Bild-Karte: Titel",
"imageSubtitle": "Bild-Karte: Untertitel",
"leaveTitle": "Abschied",
"leaveDescription": "Nachricht und Kanal, wenn ein Mitglied den Server verlässt.",
"leaveEnabledLabel": "Abschiedsnachricht aktiviert",
"leaveChannelId": "Abschieds-Kanal-ID",
"leaveContent": "Nachrichtentext",
"leaveEmbed": "Embed (JSON, optional)"
},
"verification": {
"title": "Verifizierung",
"description": "Modus, Rollen und Anforderungen für die Mitglieder-Verifizierung.",
"enabledLabel": "Verifizierung aktiviert",
"mode": "Modus",
"mode.BUTTON": "Button",
"mode.CAPTCHA": "Captcha (WebUI)",
"failAction": "Aktion bei Fehlschlag",
"failAction.KICK": "Kick",
"failAction.BAN": "Ban",
"failAction.NONE": "Keine",
"channelId": "Verifizierungs-Kanal-ID",
"verifiedRoleId": "Rolle nach Verifizierung",
"unverifiedRoleId": "Rolle vor Verifizierung",
"minAccountAgeDays": "Mindest-Accountalter (Tage)"
},
"leveling": {
"title": "Leveling & XP",
"description": "Text- und Voice-XP-Raten, Cooldowns und No-XP-Listen.",
"enabledLabel": "Leveling aktiviert",
"textXpMin": "Text-XP (Minimum)",
"textXpMax": "Text-XP (Maximum)",
"textCooldownSeconds": "Text-XP-Cooldown (Sekunden)",
"voiceXpPerMinute": "Voice-XP pro Minute",
"noXpChannels": "No-XP-Kanäle",
"noXpRoles": "No-XP-Rollen",
"roleMultipliers": "Rollen-Multiplikatoren",
"channelMultipliers": "Kanal-Multiplikatoren",
"multiplierHint": "Ein Eintrag pro Zeile im Format ID:Multiplikator, z. B. 123456789012345678:1.5",
"levelUpTitle": "Level-Up-Nachricht",
"levelUpMode": "Modus",
"mode.CHANNEL": "Kanal",
"mode.DM": "Direktnachricht",
"mode.OFF": "Aus",
"levelUpChannelId": "Level-Up-Kanal-ID",
"levelUpMessage": "Nachrichtentext",
"stackRewards": "Rollen-Belohnungen stapeln",
"rankCardTitle": "Rang-Karte",
"cardAccentColor": "Akzentfarbe",
"cardBackgroundColor": "Hintergrundfarbe"
},
"economy": {
"title": "Economy",
"description": "Währung und Beträge der Einkommens-Commands.",
"enabledLabel": "Economy aktiviert",
"currencyName": "Währungsname",
"currencySymbol": "Währungssymbol",
"amountsTitle": "Beträge",
"dailyAmount": "Tägliche Belohnung",
"weeklyAmount": "Wöchentliche Belohnung",
"workMin": "Work: Minimum",
"workMax": "Work: Maximum",
"workCooldownSeconds": "Work-Cooldown (Sekunden)",
"startingBalance": "Startguthaben"
},
"fun": {
"title": "Fun & Spiele",
"description": "Minispiele und Medien-Commands für diesen Server.",
"enabledLabel": "Fun-Modul aktiviert",
"enabledHint": "Aktiviert Minispiele wie Trivia, Tic-Tac-Toe und 8-Ball.",
"mediaEnabledLabel": "Medien-Commands aktiviert",
"mediaEnabledHint": "Aktiviert API-basierte Commands wie /cat und /dog."
}
},
"userMenu": { "userMenu": {
"theme": "Design", "theme": "Design",
"themeDark": "Dunkel", "themeDark": "Dunkel",

View File

@@ -119,9 +119,159 @@
}, },
"modulePlaceholder": { "modulePlaceholder": {
"title": "{module} settings", "title": "{module} settings",
"message": "Module settings arrive in Phase 7.", "message": "Module settings arrive in a later phase.",
"backToModules": "Back to modules" "backToModules": "Back to modules"
}, },
"modulePages": {
"moderation": {
"title": "Moderation",
"description": "Enable the moderation module and configure automatic escalation rules.",
"enabledLabel": "Moderation module enabled",
"enabledHint": "Enables ban, kick, warn, purge and the case system on this server.",
"escalationsTitle": "Escalation rules",
"escalationsDescription": "Automatic penalties once a member reaches a certain number of warnings.",
"noEscalations": "No escalation rules configured.",
"addEscalation": "Add rule",
"warnCount": "Warning count",
"action": "Action",
"actions": { "TIMEOUT": "Timeout", "KICK": "Kick", "BAN": "Ban" },
"durationMs": "Duration (ms)",
"reason": "Reason",
"reasonPlaceholder": "Optional default reason",
"casesTitle": "Cases",
"casesDescription": "List of the most recent moderation cases (read-only).",
"searchPlaceholder": "Search by user/moderator ID or reason",
"actionPlaceholder": "Filter by action, e.g. BAN",
"casesEmpty": "No cases found.",
"target": "Target",
"moderator": "Moderator",
"createdAt": "Created at",
"noReason": "No reason provided"
},
"automod": {
"title": "Auto-Moderation",
"description": "Base settings plus anti-raid and anti-nuke protection.",
"enabledLabel": "Auto-moderation enabled",
"enabledHint": "Enables all auto-moderation rules (spam, word filter, links, …) on this server.",
"antiRaidTitle": "Anti-Raid",
"antiRaidDescription": "Detects unusually fast join waves and automatically activates a lockdown.",
"antiRaidEnabled": "Anti-raid enabled",
"antiRaidJoinThreshold": "Join threshold",
"antiRaidWindowSeconds": "Time window (seconds)",
"antiRaidActionHint": "Currently implemented response: server lockdown.",
"antiNukeTitle": "Anti-Nuke",
"antiNukeDescription": "Protects against mass bans or mass channel deletions by compromised accounts.",
"antiNukeEnabled": "Anti-nuke enabled",
"antiNukeBanThreshold": "Ban threshold",
"antiNukeChannelThreshold": "Channel deletion threshold",
"antiNukeWindowSeconds": "Time window (seconds)",
"lockdownActive": "Lockdown active",
"lockdownActiveHint": "Automatically set when a raid is detected. Toggle off manually to end the lockdown."
},
"logging": {
"title": "Logging",
"description": "Log channels, ignore lists and the event-to-channel mapping.",
"enabledLabel": "Logging enabled",
"ignoreBotsLabel": "Ignore bot messages/actions",
"ignoredChannelsLabel": "Ignored channels",
"ignoredRolesLabel": "Ignored roles",
"idsPlaceholder": "Comma-separated IDs, e.g. 123456789012345678, 234567890123456789",
"idsHint": "Enter Discord IDs, comma-separated. Enable Developer Mode to copy IDs.",
"channelsTitle": "Event-channel mapping",
"channelsDescription": "Assign a dedicated log channel for each event type.",
"channelsEmpty": "No event-channel mappings configured.",
"eventType": "Event type",
"channelId": "Channel ID",
"addMapping": "Add mapping"
},
"welcome": {
"welcomeTitle": "Welcome",
"welcomeDescription": "Message, channel and autoroles for new members.",
"welcomeEnabledLabel": "Welcome message enabled",
"welcomeChannelId": "Welcome channel ID",
"welcomeType": "Message type",
"type": { "TEXT": "Text", "EMBED": "Embed", "IMAGE": "Image card" },
"welcomeContent": "Message content",
"contentPlaceholder": "Welcome {user} to {server}!",
"placeholdersHint": "Available placeholders: {user}, {user.name}, {user.tag}, {user.id}, {server}, {memberCount}",
"welcomeEmbed": "Embed (JSON, optional)",
"welcomeDmEnabled": "Welcome DM enabled",
"dmContentPlaceholder": "Optional private message to new members",
"userAutoroles": "Autoroles for users",
"botAutoroles": "Autoroles for bots",
"imageTitle": "Image card: title",
"imageSubtitle": "Image card: subtitle",
"leaveTitle": "Leave",
"leaveDescription": "Message and channel when a member leaves the server.",
"leaveEnabledLabel": "Leave message enabled",
"leaveChannelId": "Leave channel ID",
"leaveContent": "Message content",
"leaveEmbed": "Embed (JSON, optional)"
},
"verification": {
"title": "Verification",
"description": "Mode, roles and requirements for member verification.",
"enabledLabel": "Verification enabled",
"mode": "Mode",
"mode.BUTTON": "Button",
"mode.CAPTCHA": "Captcha (WebUI)",
"failAction": "Action on failure",
"failAction.KICK": "Kick",
"failAction.BAN": "Ban",
"failAction.NONE": "None",
"channelId": "Verification channel ID",
"verifiedRoleId": "Role after verification",
"unverifiedRoleId": "Role before verification",
"minAccountAgeDays": "Minimum account age (days)"
},
"leveling": {
"title": "Leveling & XP",
"description": "Text and voice XP rates, cooldowns and no-XP lists.",
"enabledLabel": "Leveling enabled",
"textXpMin": "Text XP (minimum)",
"textXpMax": "Text XP (maximum)",
"textCooldownSeconds": "Text XP cooldown (seconds)",
"voiceXpPerMinute": "Voice XP per minute",
"noXpChannels": "No-XP channels",
"noXpRoles": "No-XP roles",
"roleMultipliers": "Role multipliers",
"channelMultipliers": "Channel multipliers",
"multiplierHint": "One entry per line in the format id:multiplier, e.g. 123456789012345678:1.5",
"levelUpTitle": "Level-up message",
"levelUpMode": "Mode",
"mode.CHANNEL": "Channel",
"mode.DM": "Direct message",
"mode.OFF": "Off",
"levelUpChannelId": "Level-up channel ID",
"levelUpMessage": "Message content",
"stackRewards": "Stack role rewards",
"rankCardTitle": "Rank card",
"cardAccentColor": "Accent color",
"cardBackgroundColor": "Background color"
},
"economy": {
"title": "Economy",
"description": "Currency and amounts for the income commands.",
"enabledLabel": "Economy enabled",
"currencyName": "Currency name",
"currencySymbol": "Currency symbol",
"amountsTitle": "Amounts",
"dailyAmount": "Daily reward",
"weeklyAmount": "Weekly reward",
"workMin": "Work: minimum",
"workMax": "Work: maximum",
"workCooldownSeconds": "Work cooldown (seconds)",
"startingBalance": "Starting balance"
},
"fun": {
"title": "Fun & Games",
"description": "Mini games and media commands for this server.",
"enabledLabel": "Fun module enabled",
"enabledHint": "Enables mini games like trivia, tic-tac-toe and 8-ball.",
"mediaEnabledLabel": "Media commands enabled",
"mediaEnabledHint": "Enables API-based commands like /cat and /dog."
}
},
"userMenu": { "userMenu": {
"theme": "Theme", "theme": "Theme",
"themeDark": "Dark", "themeDark": "Dark",