Add new features and enhancements to the WebUI and dashboard components

- Updated package.json to include new dependencies: `@radix-ui/react-dialog` and `cmdk`.
- Enhanced global styles in globals.css for improved visual depth in dark mode.
- Refactored dashboard page components to improve layout and accessibility, including new icons and responsive design adjustments.
- Implemented suspense handling in commands page for better loading states.
- Improved sidebar navigation with new icons and mobile responsiveness.
- Added FieldAnchor components across various forms for better accessibility and structure.
- Enhanced commands manager with search parameter handling for improved user experience.
- Updated multiple module forms to include FieldAnchor for consistent layout and accessibility.
This commit is contained in:
TheOnlyMace
2026-07-22 19:44:55 +02:00
parent f1d74f922d
commit 75ac91eecc
49 changed files with 2393 additions and 320 deletions

View File

@@ -0,0 +1,53 @@
import { DASHBOARD_MODULES, KNOWN_COMMAND_NAMES } from '@nexumi/shared';
import { describe, expect, it } from 'vitest';
import {
SETTINGS_SEARCH_FIELDS,
buildGuildSearchHref,
buildGuildSearchIndex
} from './dashboard-search-index';
describe('dashboard-search-index', () => {
it('includes core pages, all modules, all commands, and settings fields', () => {
const index = buildGuildSearchIndex();
const pages = index.filter((entry) => entry.kind === 'page');
const commands = index.filter((entry) => entry.kind === 'command');
const settings = index.filter((entry) => entry.kind === 'setting');
expect(pages.length).toBe(5 + DASHBOARD_MODULES.length);
expect(commands.length).toBe(KNOWN_COMMAND_NAMES.length);
expect(settings.length).toBe(SETTINGS_SEARCH_FIELDS.length);
expect(settings.length).toBeGreaterThan(40);
});
it('builds correct hrefs for pages, commands, and settings', () => {
const guildId = '123';
expect(buildGuildSearchHref(guildId, { id: 'p', kind: 'page', href: '' })).toBe('/dashboard/123');
expect(buildGuildSearchHref(guildId, { id: 'p', kind: 'page', href: 'moderation' })).toBe(
'/dashboard/123/moderation'
);
expect(
buildGuildSearchHref(guildId, {
id: 'c',
kind: 'command',
href: 'commands?q=ban'
})
).toBe('/dashboard/123/commands?q=ban');
expect(
buildGuildSearchHref(guildId, {
id: 's',
kind: 'setting',
href: 'logging',
hash: 'field-logging-retention'
})
).toBe('/dashboard/123/logging#field-logging-retention');
});
it('assigns unique ids and hashes for settings entries', () => {
const ids = new Set(SETTINGS_SEARCH_FIELDS.map((entry) => entry.id));
expect(ids.size).toBe(SETTINGS_SEARCH_FIELDS.length);
for (const entry of SETTINGS_SEARCH_FIELDS) {
expect(entry.hash).toMatch(/^field-/);
expect(entry.href.length).toBeGreaterThan(0);
}
});
});

View File

@@ -0,0 +1,847 @@
import { DASHBOARD_MODULES, KNOWN_COMMAND_NAMES } from '@nexumi/shared';
export type SearchItemKind = 'page' | 'command' | 'setting';
export interface SearchIndexEntry {
id: string;
kind: SearchItemKind;
/** i18n key for display label; for commands use raw name via labelOverride */
labelKey?: string;
labelOverride?: string;
keywords?: string[];
/** Path relative to `/dashboard/{guildId}` (no leading slash), or absolute for owner */
href: string;
hash?: string;
}
const CORE_PAGES: SearchIndexEntry[] = [
{ id: 'page-overview', kind: 'page', labelKey: 'nav.overview', href: '' },
{ id: 'page-settings', kind: 'page', labelKey: 'nav.settings', href: 'settings' },
{ id: 'page-modules', kind: 'page', labelKey: 'nav.modules', href: 'modules' },
{ id: 'page-access', kind: 'page', labelKey: 'nav.access', href: 'access' },
{ id: 'page-commands', kind: 'page', labelKey: 'nav.commands', href: 'commands' }
];
const MODULE_PAGES: SearchIndexEntry[] = DASHBOARD_MODULES.map((module) => ({
id: `page-${module.id}`,
kind: 'page' as const,
labelKey: `modules.${module.id}.label`,
keywords: [module.id, module.href],
href: module.href
}));
const COMMAND_ENTRIES: SearchIndexEntry[] = KNOWN_COMMAND_NAMES.map((name) => ({
id: `cmd-${name}`,
kind: 'command' as const,
labelOverride: `/${name}`,
keywords: [name],
href: `commands?q=${encodeURIComponent(name)}`
}));
/** All searchable settings fields with deep-link hashes. */
export const SETTINGS_SEARCH_FIELDS: SearchIndexEntry[] = [
// General settings
{
id: 'setting-locale',
kind: 'setting',
labelKey: 'settings.general.localeLabel',
href: 'settings',
hash: 'field-locale',
keywords: ['language', 'sprache']
},
{
id: 'setting-timezone',
kind: 'setting',
labelKey: 'settings.general.timezoneLabel',
href: 'settings',
hash: 'field-timezone',
keywords: ['timezone', 'zeitzone']
},
{
id: 'setting-moderation-toggle',
kind: 'setting',
labelKey: 'settings.general.moderationLabel',
href: 'settings',
hash: 'field-moderation-toggle',
keywords: ['moderation']
},
{
id: 'setting-snipe',
kind: 'setting',
labelKey: 'settings.general.snipeLabel',
href: 'settings',
hash: 'field-snipe',
keywords: ['snipe', 'editsnipe']
},
// Access
{
id: 'setting-access-role',
kind: 'setting',
labelKey: 'access.roleIdLabel',
href: 'access',
hash: 'field-access-role',
keywords: ['access', 'role']
},
{
id: 'setting-access-modules',
kind: 'setting',
labelKey: 'access.modulesLabel',
href: 'access',
hash: 'field-access-modules',
keywords: ['access']
},
// Moderation
{
id: 'setting-mod-enabled',
kind: 'setting',
labelKey: 'modulePages.moderation.enabledLabel',
href: 'moderation',
hash: 'field-mod-enabled'
},
{
id: 'setting-mod-escalations',
kind: 'setting',
labelKey: 'modulePages.moderation.escalationsTitle',
href: 'moderation',
hash: 'field-mod-escalations',
keywords: ['escalation', 'warn']
},
{
id: 'setting-mod-cases',
kind: 'setting',
labelKey: 'modulePages.moderation.casesTitle',
href: 'moderation',
hash: 'field-mod-cases',
keywords: ['cases', 'fälle']
},
// Automod
{
id: 'setting-automod-enabled',
kind: 'setting',
labelKey: 'modulePages.automod.enabledLabel',
href: 'automod',
hash: 'field-automod-enabled'
},
{
id: 'setting-anti-raid',
kind: 'setting',
labelKey: 'modulePages.automod.antiRaidTitle',
href: 'automod',
hash: 'field-anti-raid',
keywords: ['raid']
},
{
id: 'setting-anti-nuke',
kind: 'setting',
labelKey: 'modulePages.automod.antiNukeTitle',
href: 'automod',
hash: 'field-anti-nuke',
keywords: ['nuke']
},
{
id: 'setting-lockdown',
kind: 'setting',
labelKey: 'modulePages.automod.lockdownActive',
href: 'automod',
hash: 'field-lockdown',
keywords: ['lockdown']
},
// Logging
{
id: 'setting-logging-enabled',
kind: 'setting',
labelKey: 'modulePages.logging.enabledLabel',
href: 'logging',
hash: 'field-logging-enabled'
},
{
id: 'setting-logging-ignore-bots',
kind: 'setting',
labelKey: 'modulePages.logging.ignoreBotsLabel',
href: 'logging',
hash: 'field-logging-ignore-bots'
},
{
id: 'setting-logging-ignored-channels',
kind: 'setting',
labelKey: 'modulePages.logging.ignoredChannelsLabel',
href: 'logging',
hash: 'field-logging-ignored-channels'
},
{
id: 'setting-logging-ignored-roles',
kind: 'setting',
labelKey: 'modulePages.logging.ignoredRolesLabel',
href: 'logging',
hash: 'field-logging-ignored-roles'
},
{
id: 'setting-logging-retention',
kind: 'setting',
labelKey: 'modulePages.logging.retentionLabel',
href: 'logging',
hash: 'field-logging-retention',
keywords: ['retention', 'aufbewahrung']
},
{
id: 'setting-logging-channels',
kind: 'setting',
labelKey: 'modulePages.logging.channelsTitle',
href: 'logging',
hash: 'field-logging-channels'
},
// Welcome
{
id: 'setting-welcome-enabled',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeEnabledLabel',
href: 'welcome',
hash: 'field-welcome-enabled'
},
{
id: 'setting-welcome-channel',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeChannelId',
href: 'welcome',
hash: 'field-welcome-channel'
},
{
id: 'setting-welcome-type',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeType',
href: 'welcome',
hash: 'field-welcome-type'
},
{
id: 'setting-welcome-content',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeContent',
href: 'welcome',
hash: 'field-welcome-content'
},
{
id: 'setting-welcome-embed',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeEmbed',
href: 'welcome',
hash: 'field-welcome-embed'
},
{
id: 'setting-welcome-dm',
kind: 'setting',
labelKey: 'modulePages.welcome.welcomeDmEnabled',
href: 'welcome',
hash: 'field-welcome-dm'
},
{
id: 'setting-welcome-user-autoroles',
kind: 'setting',
labelKey: 'modulePages.welcome.userAutoroles',
href: 'welcome',
hash: 'field-welcome-user-autoroles',
keywords: ['autorole']
},
{
id: 'setting-welcome-bot-autoroles',
kind: 'setting',
labelKey: 'modulePages.welcome.botAutoroles',
href: 'welcome',
hash: 'field-welcome-bot-autoroles'
},
{
id: 'setting-welcome-image-title',
kind: 'setting',
labelKey: 'modulePages.welcome.imageTitle',
href: 'welcome',
hash: 'field-welcome-image-title'
},
{
id: 'setting-welcome-image-subtitle',
kind: 'setting',
labelKey: 'modulePages.welcome.imageSubtitle',
href: 'welcome',
hash: 'field-welcome-image-subtitle'
},
{
id: 'setting-leave-enabled',
kind: 'setting',
labelKey: 'modulePages.welcome.leaveEnabledLabel',
href: 'welcome',
hash: 'field-leave-enabled'
},
{
id: 'setting-leave-channel',
kind: 'setting',
labelKey: 'modulePages.welcome.leaveChannelId',
href: 'welcome',
hash: 'field-leave-channel'
},
{
id: 'setting-leave-content',
kind: 'setting',
labelKey: 'modulePages.welcome.leaveContent',
href: 'welcome',
hash: 'field-leave-content'
},
{
id: 'setting-leave-embed',
kind: 'setting',
labelKey: 'modulePages.welcome.leaveEmbed',
href: 'welcome',
hash: 'field-leave-embed'
},
// Verification
{
id: 'setting-verify-enabled',
kind: 'setting',
labelKey: 'modulePages.verification.enabledLabel',
href: 'verification',
hash: 'field-verify-enabled'
},
{
id: 'setting-verify-mode',
kind: 'setting',
labelKey: 'modulePages.verification.mode',
href: 'verification',
hash: 'field-verify-mode'
},
{
id: 'setting-verify-fail',
kind: 'setting',
labelKey: 'modulePages.verification.failAction',
href: 'verification',
hash: 'field-verify-fail'
},
{
id: 'setting-verify-channel',
kind: 'setting',
labelKey: 'modulePages.verification.channelId',
href: 'verification',
hash: 'field-verify-channel'
},
{
id: 'setting-verify-role',
kind: 'setting',
labelKey: 'modulePages.verification.verifiedRoleId',
href: 'verification',
hash: 'field-verify-role'
},
{
id: 'setting-verify-unverified',
kind: 'setting',
labelKey: 'modulePages.verification.unverifiedRoleId',
href: 'verification',
hash: 'field-verify-unverified'
},
{
id: 'setting-verify-age',
kind: 'setting',
labelKey: 'modulePages.verification.minAccountAgeDays',
href: 'verification',
hash: 'field-verify-age'
},
// Leveling
{
id: 'setting-leveling-enabled',
kind: 'setting',
labelKey: 'modulePages.leveling.enabledLabel',
href: 'leveling',
hash: 'field-leveling-enabled'
},
{
id: 'setting-leveling-text-min',
kind: 'setting',
labelKey: 'modulePages.leveling.textXpMin',
href: 'leveling',
hash: 'field-leveling-text-min'
},
{
id: 'setting-leveling-text-max',
kind: 'setting',
labelKey: 'modulePages.leveling.textXpMax',
href: 'leveling',
hash: 'field-leveling-text-max'
},
{
id: 'setting-leveling-cooldown',
kind: 'setting',
labelKey: 'modulePages.leveling.textCooldownSeconds',
href: 'leveling',
hash: 'field-leveling-cooldown'
},
{
id: 'setting-leveling-voice',
kind: 'setting',
labelKey: 'modulePages.leveling.voiceXpPerMinute',
href: 'leveling',
hash: 'field-leveling-voice'
},
{
id: 'setting-leveling-no-xp-channels',
kind: 'setting',
labelKey: 'modulePages.leveling.noXpChannels',
href: 'leveling',
hash: 'field-leveling-no-xp-channels'
},
{
id: 'setting-leveling-no-xp-roles',
kind: 'setting',
labelKey: 'modulePages.leveling.noXpRoles',
href: 'leveling',
hash: 'field-leveling-no-xp-roles'
},
{
id: 'setting-leveling-role-multipliers',
kind: 'setting',
labelKey: 'modulePages.leveling.roleMultipliers',
href: 'leveling',
hash: 'field-leveling-role-multipliers'
},
{
id: 'setting-leveling-channel-multipliers',
kind: 'setting',
labelKey: 'modulePages.leveling.channelMultipliers',
href: 'leveling',
hash: 'field-leveling-channel-multipliers'
},
{
id: 'setting-leveling-levelup',
kind: 'setting',
labelKey: 'modulePages.leveling.levelUpTitle',
href: 'leveling',
hash: 'field-leveling-levelup'
},
{
id: 'setting-leveling-stack',
kind: 'setting',
labelKey: 'modulePages.leveling.stackRewards',
href: 'leveling',
hash: 'field-leveling-stack'
},
{
id: 'setting-leveling-rank-card',
kind: 'setting',
labelKey: 'modulePages.leveling.rankCardTitle',
href: 'leveling',
hash: 'field-leveling-rank-card'
},
// Economy
{
id: 'setting-economy-enabled',
kind: 'setting',
labelKey: 'modulePages.economy.enabledLabel',
href: 'economy',
hash: 'field-economy-enabled'
},
{
id: 'setting-economy-currency-name',
kind: 'setting',
labelKey: 'modulePages.economy.currencyName',
href: 'economy',
hash: 'field-economy-currency-name'
},
{
id: 'setting-economy-currency-symbol',
kind: 'setting',
labelKey: 'modulePages.economy.currencySymbol',
href: 'economy',
hash: 'field-economy-currency-symbol'
},
{
id: 'setting-economy-daily',
kind: 'setting',
labelKey: 'modulePages.economy.dailyAmount',
href: 'economy',
hash: 'field-economy-daily'
},
{
id: 'setting-economy-weekly',
kind: 'setting',
labelKey: 'modulePages.economy.weeklyAmount',
href: 'economy',
hash: 'field-economy-weekly'
},
{
id: 'setting-economy-work-min',
kind: 'setting',
labelKey: 'modulePages.economy.workMin',
href: 'economy',
hash: 'field-economy-work-min'
},
{
id: 'setting-economy-work-max',
kind: 'setting',
labelKey: 'modulePages.economy.workMax',
href: 'economy',
hash: 'field-economy-work-max'
},
{
id: 'setting-economy-work-cooldown',
kind: 'setting',
labelKey: 'modulePages.economy.workCooldownSeconds',
href: 'economy',
hash: 'field-economy-work-cooldown'
},
{
id: 'setting-economy-starting',
kind: 'setting',
labelKey: 'modulePages.economy.startingBalance',
href: 'economy',
hash: 'field-economy-starting'
},
// Fun
{
id: 'setting-fun-enabled',
kind: 'setting',
labelKey: 'modulePages.fun.enabledLabel',
href: 'fun',
hash: 'field-fun-enabled'
},
{
id: 'setting-fun-media',
kind: 'setting',
labelKey: 'modulePages.fun.mediaEnabledLabel',
href: 'fun',
hash: 'field-fun-media'
},
// Tickets
{
id: 'setting-tickets-enabled',
kind: 'setting',
labelKey: 'modulePages.tickets.enabledLabel',
href: 'tickets',
hash: 'field-tickets-enabled'
},
{
id: 'setting-tickets-mode',
kind: 'setting',
labelKey: 'modulePages.tickets.mode',
href: 'tickets',
hash: 'field-tickets-mode'
},
{
id: 'setting-tickets-category',
kind: 'setting',
labelKey: 'modulePages.tickets.categoryId',
href: 'tickets',
hash: 'field-tickets-category'
},
{
id: 'setting-tickets-log',
kind: 'setting',
labelKey: 'modulePages.tickets.logChannelId',
href: 'tickets',
hash: 'field-tickets-log'
},
{
id: 'setting-tickets-inactivity',
kind: 'setting',
labelKey: 'modulePages.tickets.inactivityHours',
href: 'tickets',
hash: 'field-tickets-inactivity'
},
{
id: 'setting-tickets-transcript',
kind: 'setting',
labelKey: 'modulePages.tickets.transcriptDm',
href: 'tickets',
hash: 'field-tickets-transcript'
},
{
id: 'setting-tickets-rating',
kind: 'setting',
labelKey: 'modulePages.tickets.ratingEnabled',
href: 'tickets',
hash: 'field-tickets-rating'
},
{
id: 'setting-tickets-categories',
kind: 'setting',
labelKey: 'modulePages.tickets.categoriesTitle',
href: 'tickets',
hash: 'field-tickets-categories'
},
// Giveaways
{
id: 'setting-giveaways-create',
kind: 'setting',
labelKey: 'modulePages.giveaways.createTitle',
href: 'giveaways',
hash: 'field-giveaways-create'
},
{
id: 'setting-giveaways-list',
kind: 'setting',
labelKey: 'modulePages.giveaways.listTitle',
href: 'giveaways',
hash: 'field-giveaways-list'
},
// Selfroles
{
id: 'setting-selfroles-create',
kind: 'setting',
labelKey: 'modulePages.selfroles.createTitle',
href: 'selfroles',
hash: 'field-selfroles-create'
},
{
id: 'setting-selfroles-list',
kind: 'setting',
labelKey: 'modulePages.selfroles.listTitle',
href: 'selfroles',
hash: 'field-selfroles-list'
},
// Tags
{
id: 'setting-tags-create',
kind: 'setting',
labelKey: 'modulePages.tags.createTitle',
href: 'tags',
hash: 'field-tags-create'
},
{
id: 'setting-tags-list',
kind: 'setting',
labelKey: 'modulePages.tags.listTitle',
href: 'tags',
hash: 'field-tags-list'
},
// Starboard
{
id: 'setting-starboard-enabled',
kind: 'setting',
labelKey: 'modulePages.starboard.enabledLabel',
href: 'starboard',
hash: 'field-starboard-enabled'
},
{
id: 'setting-starboard-channel',
kind: 'setting',
labelKey: 'modulePages.starboard.channelId',
href: 'starboard',
hash: 'field-starboard-channel'
},
{
id: 'setting-starboard-emoji',
kind: 'setting',
labelKey: 'modulePages.starboard.emoji',
href: 'starboard',
hash: 'field-starboard-emoji'
},
{
id: 'setting-starboard-threshold',
kind: 'setting',
labelKey: 'modulePages.starboard.threshold',
href: 'starboard',
hash: 'field-starboard-threshold'
},
{
id: 'setting-starboard-self',
kind: 'setting',
labelKey: 'modulePages.starboard.allowSelfStar',
href: 'starboard',
hash: 'field-starboard-self'
},
{
id: 'setting-starboard-ignored',
kind: 'setting',
labelKey: 'modulePages.starboard.ignoredChannelIds',
href: 'starboard',
hash: 'field-starboard-ignored'
},
// Suggestions
{
id: 'setting-suggestions-enabled',
kind: 'setting',
labelKey: 'modulePages.suggestions.enabledLabel',
href: 'suggestions',
hash: 'field-suggestions-enabled'
},
{
id: 'setting-suggestions-open',
kind: 'setting',
labelKey: 'modulePages.suggestions.openChannelId',
href: 'suggestions',
hash: 'field-suggestions-open'
},
{
id: 'setting-suggestions-approved',
kind: 'setting',
labelKey: 'modulePages.suggestions.approvedChannelId',
href: 'suggestions',
hash: 'field-suggestions-approved'
},
{
id: 'setting-suggestions-denied',
kind: 'setting',
labelKey: 'modulePages.suggestions.deniedChannelId',
href: 'suggestions',
hash: 'field-suggestions-denied'
},
{
id: 'setting-suggestions-thread',
kind: 'setting',
labelKey: 'modulePages.suggestions.createThread',
href: 'suggestions',
hash: 'field-suggestions-thread'
},
{
id: 'setting-suggestions-list',
kind: 'setting',
labelKey: 'modulePages.suggestions.listTitle',
href: 'suggestions',
hash: 'field-suggestions-list'
},
// Birthdays
{
id: 'setting-birthdays-enabled',
kind: 'setting',
labelKey: 'modulePages.birthdays.enabledLabel',
href: 'birthdays',
hash: 'field-birthdays-enabled'
},
{
id: 'setting-birthdays-channel',
kind: 'setting',
labelKey: 'modulePages.birthdays.channelId',
href: 'birthdays',
hash: 'field-birthdays-channel'
},
{
id: 'setting-birthdays-role',
kind: 'setting',
labelKey: 'modulePages.birthdays.roleId',
href: 'birthdays',
hash: 'field-birthdays-role'
},
{
id: 'setting-birthdays-timezone',
kind: 'setting',
labelKey: 'modulePages.birthdays.timezone',
href: 'birthdays',
hash: 'field-birthdays-timezone'
},
{
id: 'setting-birthdays-message',
kind: 'setting',
labelKey: 'modulePages.birthdays.message',
href: 'birthdays',
hash: 'field-birthdays-message'
},
// Tempvoice
{
id: 'setting-tempvoice-enabled',
kind: 'setting',
labelKey: 'modulePages.tempvoice.enabledLabel',
href: 'tempvoice',
hash: 'field-tempvoice-enabled'
},
{
id: 'setting-tempvoice-hub',
kind: 'setting',
labelKey: 'modulePages.tempvoice.hubChannelId',
href: 'tempvoice',
hash: 'field-tempvoice-hub'
},
{
id: 'setting-tempvoice-category',
kind: 'setting',
labelKey: 'modulePages.tempvoice.categoryId',
href: 'tempvoice',
hash: 'field-tempvoice-category'
},
{
id: 'setting-tempvoice-name',
kind: 'setting',
labelKey: 'modulePages.tempvoice.defaultName',
href: 'tempvoice',
hash: 'field-tempvoice-name'
},
{
id: 'setting-tempvoice-limit',
kind: 'setting',
labelKey: 'modulePages.tempvoice.defaultLimit',
href: 'tempvoice',
hash: 'field-tempvoice-limit'
},
// Stats
{
id: 'setting-stats-enabled',
kind: 'setting',
labelKey: 'modulePages.stats.enabledLabel',
href: 'stats',
hash: 'field-stats-enabled'
},
{
id: 'setting-stats-members',
kind: 'setting',
labelKey: 'modulePages.stats.membersChannelId',
href: 'stats',
hash: 'field-stats-members'
},
{
id: 'setting-stats-online',
kind: 'setting',
labelKey: 'modulePages.stats.onlineChannelId',
href: 'stats',
hash: 'field-stats-online'
},
{
id: 'setting-stats-boosts',
kind: 'setting',
labelKey: 'modulePages.stats.boostsChannelId',
href: 'stats',
hash: 'field-stats-boosts'
},
// Feeds
{
id: 'setting-feeds-add',
kind: 'setting',
labelKey: 'modulePages.feeds.addFeed',
href: 'feeds',
hash: 'field-feeds-add'
},
// Scheduler
{
id: 'setting-scheduler-create',
kind: 'setting',
labelKey: 'modulePages.scheduler.createTitle',
href: 'scheduler',
hash: 'field-scheduler-create'
},
// Backup
{
id: 'setting-backup',
kind: 'setting',
labelKey: 'modules.guildbackup.label',
href: 'backup',
hash: 'field-backup',
keywords: ['backup', 'restore']
}
];
export const OWNER_NAV_ENTRIES: SearchIndexEntry[] = [
{ id: 'owner-overview', kind: 'page', labelKey: 'owner.nav.overview', href: '/owner' },
{ id: 'owner-guilds', kind: 'page', labelKey: 'owner.nav.guilds', href: '/owner/guilds' },
{ id: 'owner-users', kind: 'page', labelKey: 'owner.nav.users', href: '/owner/users' },
{ id: 'owner-flags', kind: 'page', labelKey: 'owner.nav.flags', href: '/owner/flags' },
{ id: 'owner-premium', kind: 'page', labelKey: 'owner.nav.premium', href: '/owner/premium' },
{ id: 'owner-presence', kind: 'page', labelKey: 'owner.nav.presence', href: '/owner/presence' },
{ id: 'owner-team', kind: 'page', labelKey: 'owner.nav.team', href: '/owner/team' },
{ id: 'owner-jobs', kind: 'page', labelKey: 'owner.nav.jobs', href: '/owner/jobs' },
{ id: 'owner-changelog', kind: 'page', labelKey: 'owner.nav.changelog', href: '/owner/changelog' },
{ id: 'owner-audit', kind: 'page', labelKey: 'owner.nav.audit', href: '/owner/audit' }
];
export function buildGuildSearchIndex(): SearchIndexEntry[] {
return [...CORE_PAGES, ...MODULE_PAGES, ...COMMAND_ENTRIES, ...SETTINGS_SEARCH_FIELDS];
}
/** Commands use query string; settings use hash; pages are plain paths. */
export function buildGuildSearchHref(guildId: string, entry: SearchIndexEntry): string {
if (entry.kind === 'command') {
return `/dashboard/${guildId}/${entry.href}`;
}
const base = entry.href ? `/dashboard/${guildId}/${entry.href}` : `/dashboard/${guildId}`;
return entry.hash ? `${base}#${entry.hash}` : base;
}