Implement Owner Panel features and maintenance mode handling
- Introduced the Owner Panel with new routes and UI components for managing guilds, user blacklists, feature flags, and bot presence. - Added maintenance mode functionality to prevent non-owner users from executing commands during maintenance periods. - Enhanced localization with new keys for Owner Panel features in both English and German. - Updated job processing to include a presence refresh job, ensuring the bot's status is regularly updated. - Improved environment configuration to support owner user IDs for access control.
This commit is contained in:
@@ -9,17 +9,25 @@ interface DashboardShellProps {
|
||||
currentGuild: DashboardGuild;
|
||||
otherGuilds: DashboardGuild[];
|
||||
user: SessionUser;
|
||||
showOwnerLink?: boolean;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function DashboardShell({ guildId, currentGuild, otherGuilds, user, children }: DashboardShellProps) {
|
||||
export function DashboardShell({
|
||||
guildId,
|
||||
currentGuild,
|
||||
otherGuilds,
|
||||
user,
|
||||
showOwnerLink = false,
|
||||
children
|
||||
}: DashboardShellProps) {
|
||||
return (
|
||||
<div className="flex min-h-screen">
|
||||
<Sidebar guildId={guildId} />
|
||||
<div className="flex flex-1 flex-col">
|
||||
<header className="flex h-14 items-center justify-between border-b border-border px-6">
|
||||
<ServerSwitcher currentGuild={currentGuild} otherGuilds={otherGuilds} />
|
||||
<UserMenu user={user} />
|
||||
<UserMenu user={user} showOwnerLink={showOwnerLink} />
|
||||
</header>
|
||||
<main className="flex-1 px-6 py-8">
|
||||
<div className="mx-auto w-full max-w-[1200px]">{children}</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import type { SessionUser } from '@nexumi/shared';
|
||||
import { LogOut, Moon, Sun } from 'lucide-react';
|
||||
import { LogOut, Moon, Shield, Sun } from 'lucide-react';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
@@ -26,7 +26,7 @@ function initials(user: SessionUser): string {
|
||||
return name.slice(0, 2).toUpperCase();
|
||||
}
|
||||
|
||||
export function UserMenu({ user }: { user: SessionUser }) {
|
||||
export function UserMenu({ user, showOwnerLink = false }: { user: SessionUser; showOwnerLink?: boolean }) {
|
||||
const t = useTranslations();
|
||||
const { theme, setTheme } = useTheme();
|
||||
const router = useRouter();
|
||||
@@ -58,6 +58,19 @@ export function UserMenu({ user }: { user: SessionUser }) {
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
<DropdownMenuLabel className="truncate">{user.globalName ?? user.username}</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{showOwnerLink ? (
|
||||
<>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
router.push('/owner');
|
||||
}}
|
||||
>
|
||||
<Shield className="size-4" />
|
||||
{t('userMenu.ownerPanel')}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
) : null}
|
||||
<DropdownMenuItem onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
|
||||
{theme === 'dark' ? <Sun className="size-4" /> : <Moon className="size-4" />}
|
||||
{theme === 'dark' ? t('userMenu.themeLight') : t('userMenu.themeDark')}
|
||||
|
||||
Reference in New Issue
Block a user