From 2801f80b9a13e386757538d2562fabab9abe9409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 20:37:15 +0100 Subject: [PATCH 01/27] feat: add GitHub-dark design tokens via Tailwind v4 @theme --- src/app/globals.css | 28 +++++++++++++++++++++++++--- src/app/layout.tsx | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index de36292..3feb52b 100755 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,11 +1,33 @@ @import "tailwindcss"; +@theme { + --color-gh-base: #0d1117; + --color-gh-canvas: #161b22; + --color-gh-overlay: #21262d; + --color-gh-sidebar: #010409; + --color-gh-border: #30363d; + --color-gh-border-muted: #21262d; + --color-gh-hover: #1c2128; + --color-gh-primary: #e6edf3; + --color-gh-secondary: #c9d1d9; + --color-gh-muted: #8b949e; + --color-gh-subtle: #6e7681; + --color-gh-blue: #58a6ff; + --color-gh-blue-bg: #1f6feb33; + --color-gh-green: #3fb950; + --color-gh-green-bg: #3fb95022; + --color-gh-yellow: #d29922; + --color-gh-yellow-bg: #d2992220; + --color-gh-red: #f85149; + --color-gh-red-bg: #f8514920; + --color-gh-orange: #f78166; +} + @layer components { .form-input { - @apply mt-1 block w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-white placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500; + @apply block w-full rounded-md border border-gh-border bg-gh-overlay px-3 py-2 text-sm text-gh-primary placeholder-gh-subtle focus:border-gh-blue focus:outline-none focus:ring-1 focus:ring-gh-blue; } - .form-select { - @apply mt-1 block w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-white focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500; + @apply block w-full rounded-md border border-gh-border bg-gh-overlay px-3 py-2 text-sm text-gh-primary focus:border-gh-blue focus:outline-none focus:ring-1 focus:ring-gh-blue; } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2f59ab4..201da29 100755 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,7 +13,7 @@ export default function RootLayout({ }>) { return ( - {children} + {children} ); } From 1d13def6da3dc22e76053a3acae38a760692d166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 20:41:06 +0100 Subject: [PATCH 02/27] feat: add Badge, StatusDot, GhButton shared UI primitives --- src/components/ui/Badge.tsx | 31 ++++++++++++++++++++++ src/components/ui/GhButton.tsx | 47 +++++++++++++++++++++++++++++++++ src/components/ui/StatusDot.tsx | 28 ++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 src/components/ui/Badge.tsx create mode 100644 src/components/ui/GhButton.tsx create mode 100644 src/components/ui/StatusDot.tsx diff --git a/src/components/ui/Badge.tsx b/src/components/ui/Badge.tsx new file mode 100644 index 0000000..9f1f107 --- /dev/null +++ b/src/components/ui/Badge.tsx @@ -0,0 +1,31 @@ +import { cn } from '@/lib/utils'; + +type BadgeVariant = 'green' | 'yellow' | 'red' | 'blue' | 'gray'; + +interface BadgeProps { + variant: BadgeVariant; + children: React.ReactNode; + className?: string; +} + +const variantClasses: Record = { + green: 'bg-gh-green-bg text-gh-green border border-gh-green/20', + yellow: 'bg-gh-yellow-bg text-gh-yellow border border-gh-yellow/20', + red: 'bg-gh-red-bg text-gh-red border border-gh-red/20', + blue: 'bg-gh-blue-bg text-gh-blue border border-gh-blue/20', + gray: 'bg-gh-overlay text-gh-muted border border-gh-border', +}; + +export function Badge({ variant, children, className }: BadgeProps) { + return ( + + {children} + + ); +} diff --git a/src/components/ui/GhButton.tsx b/src/components/ui/GhButton.tsx new file mode 100644 index 0000000..0721ef3 --- /dev/null +++ b/src/components/ui/GhButton.tsx @@ -0,0 +1,47 @@ +import { cn } from '@/lib/utils'; +import { ButtonHTMLAttributes } from 'react'; + +type ButtonVariant = 'primary' | 'ghost' | 'danger-outline' | 'danger-solid'; +type ButtonSize = 'sm' | 'md'; + +interface GhButtonProps extends ButtonHTMLAttributes { + variant?: ButtonVariant; + size?: ButtonSize; +} + +const variantClasses: Record = { + primary: 'bg-[#238636] border border-[#2ea043] text-white hover:bg-[#2ea043]', + ghost: 'bg-transparent border border-gh-border text-gh-secondary hover:bg-gh-overlay hover:text-gh-primary', + 'danger-outline': 'bg-transparent border border-gh-border text-gh-red hover:border-gh-red/40 hover:bg-gh-red-bg', + 'danger-solid': 'bg-gh-overlay border border-gh-red/20 text-gh-red hover:bg-gh-red-bg', +}; + +const sizeClasses: Record = { + sm: 'px-3 py-1.5 text-xs', + md: 'px-4 py-2 text-sm', +}; + +export function GhButton({ + variant = 'ghost', + size = 'md', + className, + children, + disabled, + ...props +}: GhButtonProps) { + return ( + + ); +} diff --git a/src/components/ui/StatusDot.tsx b/src/components/ui/StatusDot.tsx new file mode 100644 index 0000000..98b2008 --- /dev/null +++ b/src/components/ui/StatusDot.tsx @@ -0,0 +1,28 @@ +import { ServiceStatus } from '@/lib/schemas/server'; +import { cn } from '@/lib/utils'; + +interface StatusDotProps { + status: ServiceStatus; + className?: string; +} + +export function StatusDot({ status, className }: StatusDotProps) { + const dotClass = { + [ServiceStatus.Running]: 'bg-gh-green shadow-[0_0_0_3px_#3fb95022]', + [ServiceStatus.Starting]: 'bg-gh-yellow animate-pulse', + [ServiceStatus.Stopping]: 'bg-gh-yellow animate-pulse', + [ServiceStatus.Restarting]: 'bg-gh-yellow animate-pulse', + [ServiceStatus.Stopped]: 'bg-gh-subtle', + [ServiceStatus.Unknown]: 'bg-gh-subtle', + }[status] ?? 'bg-gh-subtle'; + + return ( + + ); +} From 5c69ef716b2358d68f79291034cb150d90991046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 20:56:43 +0100 Subject: [PATCH 03/27] fix: use design tokens for primary button green, add gap to GhButton --- src/app/globals.css | 2 ++ src/components/ui/GhButton.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 3feb52b..843a1ad 100755 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -21,6 +21,8 @@ --color-gh-red: #f85149; --color-gh-red-bg: #f8514920; --color-gh-orange: #f78166; + --color-gh-btn-green: #238636; + --color-gh-btn-green-hover: #2ea043; } @layer components { diff --git a/src/components/ui/GhButton.tsx b/src/components/ui/GhButton.tsx index 0721ef3..0572657 100644 --- a/src/components/ui/GhButton.tsx +++ b/src/components/ui/GhButton.tsx @@ -10,7 +10,7 @@ interface GhButtonProps extends ButtonHTMLAttributes { } const variantClasses: Record = { - primary: 'bg-[#238636] border border-[#2ea043] text-white hover:bg-[#2ea043]', + primary: 'bg-gh-btn-green border border-gh-btn-green-hover text-white hover:bg-gh-btn-green-hover', ghost: 'bg-transparent border border-gh-border text-gh-secondary hover:bg-gh-overlay hover:text-gh-primary', 'danger-outline': 'bg-transparent border border-gh-border text-gh-red hover:border-gh-red/40 hover:bg-gh-red-bg', 'danger-solid': 'bg-gh-overlay border border-gh-red/20 text-gh-red hover:bg-gh-red-bg', @@ -34,7 +34,7 @@ export function GhButton({ {...props} disabled={disabled} className={cn( - 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-gh-blue focus:ring-offset-1 focus:ring-offset-gh-base', + 'inline-flex items-center gap-1.5 justify-center rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-gh-blue focus:ring-offset-1 focus:ring-offset-gh-base', 'disabled:cursor-not-allowed disabled:opacity-40', variantClasses[variant], sizeClasses[size], From 710ac253e222c044e77ce9866cf2eda9f7b26c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 20:59:09 +0100 Subject: [PATCH 04/27] feat: add AppShell with persistent icon sidebar and mobile bottom tab bar --- src/app/dashboard/layout.tsx | 15 +++--- src/components/ui/AppShell.tsx | 19 +++++++ src/components/ui/Sidebar.tsx | 94 ++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/components/ui/AppShell.tsx create mode 100644 src/components/ui/Sidebar.tsx diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index f75f6a0..f6f9af2 100755 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -3,19 +3,20 @@ import { SteamCMDProvider } from '@/lib/context/SteamCMDContext'; import { ServerCreationPopupProvider } from '@/lib/context/ServerCreationPopupContext'; import { ServerCreationPopupContainer } from '@/components/server/ServerCreationPopupContainer'; import { requireAuth } from '@/lib/auth/server'; +import { AppShell } from '@/components/ui/AppShell'; +import { hasPermission } from '@/lib/schemas'; -export default async function DashboardLayout({ - children -}: Readonly<{ - children: React.ReactNode; -}>) { +export default async function DashboardLayout({ children }: Readonly<{ children: React.ReactNode }>) { const session = await requireAuth(); + const showUsers = hasPermission(session.user!, 'membership.view'); return ( - {children} - + + {children} + + diff --git a/src/components/ui/AppShell.tsx b/src/components/ui/AppShell.tsx new file mode 100644 index 0000000..7c21026 --- /dev/null +++ b/src/components/ui/AppShell.tsx @@ -0,0 +1,19 @@ +// NOTE: intentionally no 'use client' — must remain a Server Component +import { Sidebar } from './Sidebar'; + +interface AppShellProps { + children: React.ReactNode; + showUsers: boolean; +} + +export function AppShell({ children, showUsers }: AppShellProps) { + return ( +
+ + {/* Offset for sidebar (desktop: left margin, mobile: bottom padding) */} +
+ {children} +
+
+ ); +} diff --git a/src/components/ui/Sidebar.tsx b/src/components/ui/Sidebar.tsx new file mode 100644 index 0000000..195b03e --- /dev/null +++ b/src/components/ui/Sidebar.tsx @@ -0,0 +1,94 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { cn } from '@/lib/utils'; + +interface SidebarProps { + showUsers: boolean; // true if user has membership.view permission +} + +function ServerIcon({ active }: { active: boolean }) { + return ( + + + + + + + + + ); +} + +function UsersIcon({ active }: { active: boolean }) { + return ( + + + + + + ); +} + +export function Sidebar({ showUsers }: SidebarProps) { + const pathname = usePathname(); + const isServers = !pathname.startsWith('/dashboard/membership'); + const isUsers = pathname.startsWith('/dashboard/membership'); + + const navItems = [ + { href: '/dashboard', label: 'Servers', active: isServers, icon: }, + ...(showUsers ? [{ href: '/dashboard/membership', label: 'Users', active: isUsers, icon: }] : []), + ]; + + return ( + <> + {/* Desktop icon sidebar */} + + + {/* Mobile bottom tab bar */} + + + ); +} From 5a7485f654e3635eb06519b2670971f39c2b9982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:06:25 +0100 Subject: [PATCH 05/27] fix: explicit sidebar active state, popup clears mobile bottom bar --- src/components/server/ServerCreationPopup.tsx | 4 ++-- src/components/ui/Sidebar.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/server/ServerCreationPopup.tsx b/src/components/server/ServerCreationPopup.tsx index 7f1dbfa..fcb5d0a 100755 --- a/src/components/server/ServerCreationPopup.tsx +++ b/src/components/server/ServerCreationPopup.tsx @@ -310,7 +310,7 @@ export function ServerCreationPopup({ !isCompleted && Object.values(steps).some((step) => step.status === 'in_progress'); return ( -
+
From a4ff0a9339ba4f9d743afd069d8c6e15f62fafdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:09:39 +0100 Subject: [PATCH 07/27] fix: use matching border color for login button resting state --- src/components/login/LoginForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/login/LoginForm.tsx b/src/components/login/LoginForm.tsx index c9b74c6..c72a0a6 100755 --- a/src/components/login/LoginForm.tsx +++ b/src/components/login/LoginForm.tsx @@ -71,7 +71,7 @@ export default function LoginForm({ From 025c021896ce52a0c577ea41918d7b2f65d89283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:12:50 +0100 Subject: [PATCH 08/27] =?UTF-8?q?feat:=20restyle=20dashboard=20=E2=80=94?= =?UTF-8?q?=20card=20grid=20(desktop),=20row=20list=20(mobile),=20status?= =?UTF-8?q?=20badges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/dashboard/page.tsx | 43 +----- src/components/server/ServerCard.tsx | 140 +++++++++--------- .../server/ServerListWithActions.tsx | 60 ++++++-- src/components/server/ServerRow.tsx | 86 +++++++++++ src/components/ui/SteamCMDNotification.tsx | 10 +- 5 files changed, 210 insertions(+), 129 deletions(-) create mode 100644 src/components/server/ServerRow.tsx diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 9ccfd1c..18acf6d 100755 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,53 +1,16 @@ import { requireAuth } from '@/lib/auth/server'; import { getServers } from '@/lib/api/server/servers'; -import { hasPermission } from '@/lib/schemas'; -import Link from 'next/link'; import { ServerListWithActions } from '@/components/server/ServerListWithActions'; import { SteamCMDNotification } from '@/components/ui/SteamCMDNotification'; -import LogoutButton from '@/components/ui/LogoutButton'; export default async function DashboardPage() { const session = await requireAuth(); const servers = await getServers(session.token!); return ( -
-
-
-

ACC Server Manager

-
- {hasPermission(session.user!, 'membership.view') && ( - - - - - Users - - )} - -
-
-
- +
- -
- -
-
+ + ); } diff --git a/src/components/server/ServerCard.tsx b/src/components/server/ServerCard.tsx index 8a68653..a49bcdb 100755 --- a/src/components/server/ServerCard.tsx +++ b/src/components/server/ServerCard.tsx @@ -1,17 +1,31 @@ +'use client'; + import Link from 'next/link'; import { useTransition } from 'react'; -import { Server, ServiceStatus, getStatusColor, serviceStatusToString } from '@/lib/schemas'; +import { Server, ServiceStatus, serviceStatusToString } from '@/lib/schemas'; import { startServerEventAction, restartServerEventAction, stopServerEventAction } from '@/lib/actions/servers'; import { useRouter } from 'next/navigation'; +import { StatusDot } from '@/components/ui/StatusDot'; +import { Badge } from '@/components/ui/Badge'; +import { GhButton } from '@/components/ui/GhButton'; interface ServerCardProps { server: Server; } +function statusBadgeVariant(status: ServiceStatus): 'green' | 'yellow' | 'gray' { + if (status === ServiceStatus.Running) return 'green'; + if ( + [ServiceStatus.Starting, ServiceStatus.Restarting, ServiceStatus.Stopping].includes(status) + ) + return 'yellow'; + return 'gray'; +} + export function ServerCard({ server }: ServerCardProps) { const [isPending, startTransition] = useTransition(); const router = useRouter(); @@ -36,82 +50,68 @@ export function ServerCard({ server }: ServerCardProps) { ServiceStatus.Restarting, ServiceStatus.Starting, ServiceStatus.Stopping, - ServiceStatus.Unknown + ServiceStatus.Unknown, ].includes(server.status); return ( - <> -
- -
-
-
-

{server.name}

-
- - - {serviceStatusToString(server.status)} - -
-
-
-
- - - -
-
-
+
+ +
+ {server.name} + +
+
+ {server.state?.track || 'No track'} · {server.state?.playerCount ?? 0} players +
-
-
- Track: - {server.state?.track || 'N/A'} -
-
- Players: - {server.state?.playerCount || 0} -
+
+
+
Players
+
+ {server.state?.playerCount ?? 0} +
+
+
+
Track
+
+ {server.state?.track || 'N/A'}
- - -
- - - - -
+ +
+ + {serviceStatusToString(server.status)} + +
+ + +
+ + Start + + + Restart + + + Stop +
- +
); } diff --git a/src/components/server/ServerListWithActions.tsx b/src/components/server/ServerListWithActions.tsx index 08a2e75..9afecd6 100755 --- a/src/components/server/ServerListWithActions.tsx +++ b/src/components/server/ServerListWithActions.tsx @@ -1,12 +1,15 @@ 'use client'; import { useCallback, useState } from 'react'; -import { Server } from '@/lib/schemas/server'; +import { Server, ServiceStatus } from '@/lib/schemas/server'; import { User, hasPermission } from '@/lib/schemas/user'; import { ServerCard } from './ServerCard'; +import { ServerRow } from './ServerRow'; import { CreateServerModal } from './CreateServerModal'; import RefreshButton from '@/components/ui/RefreshButton'; import { useSteamCMD } from '@/lib/context/SteamCMDContext'; +import { GhButton } from '@/components/ui/GhButton'; +import { Badge } from '@/components/ui/Badge'; interface ServerListWithActionsProps { servers: Server[]; @@ -20,29 +23,58 @@ export function ServerListWithActions({ servers, user }: ServerListWithActionsPr const handleOnClose = useCallback(() => setIsCreateModalOpen(false), []); const canCreateServer = hasPermission(user, 'server.create'); + const runningCount = servers.filter((s) => s.status === ServiceStatus.Running).length; + const offlineCount = servers.filter((s) => s.status === ServiceStatus.Stopped).length; + return ( <> -
-

Your Servers

-
+ {/* Topbar */} +
+
+ Servers + {servers.length} total +
+
+ {canCreateServer && ( - + + New Server + )} - +
+
+ + {/* Status summary bar */} +
+
+ {runningCount > 0 && ● {runningCount} running} + {offlineCount > 0 && {offlineCount} offline}
-
- {servers.map((server) => ( - - ))} + {/* Responsive server list */} +
+ {/* Card grid — desktop only */} +
+ {servers.map((server) => ( + + ))} +
+ {/* Row list — mobile only */} +
+ {servers.map((server) => ( + + ))} +
diff --git a/src/components/server/ServerRow.tsx b/src/components/server/ServerRow.tsx new file mode 100644 index 0000000..800fe18 --- /dev/null +++ b/src/components/server/ServerRow.tsx @@ -0,0 +1,86 @@ +'use client'; + +import { useTransition } from 'react'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; +import { Server, ServiceStatus } from '@/lib/schemas'; +import { + startServerEventAction, + restartServerEventAction, + stopServerEventAction +} from '@/lib/actions/servers'; +import { StatusDot } from '@/components/ui/StatusDot'; +import { GhButton } from '@/components/ui/GhButton'; + +interface ServerRowProps { + server: Server; +} + +export function ServerRow({ server }: ServerRowProps) { + const [isPending, startTransition] = useTransition(); + const router = useRouter(); + + const startServer = () => + startTransition(async () => { + await startServerEventAction(server.id); + router.refresh(); + }); + const restartServer = () => + startTransition(async () => { + await restartServerEventAction(server.id); + router.refresh(); + }); + const stopServer = () => + startTransition(async () => { + await stopServerEventAction(server.id); + router.refresh(); + }); + + const transitioning = [ + ServiceStatus.Restarting, + ServiceStatus.Starting, + ServiceStatus.Stopping, + ServiceStatus.Unknown, + ].includes(server.status); + const disabled = transitioning || isPending; + + return ( +
+ + +
+
{server.name}
+
+ {server.state?.track ?? 'No track'} · {server.state?.playerCount ?? 0} players +
+
+ +
+ {server.status === ServiceStatus.Stopped ? ( + + Start + + ) : ( + <> + + Restart + + + Stop + + + )} +
+
+ ); +} diff --git a/src/components/ui/SteamCMDNotification.tsx b/src/components/ui/SteamCMDNotification.tsx index 1dfddc4..8739055 100755 --- a/src/components/ui/SteamCMDNotification.tsx +++ b/src/components/ui/SteamCMDNotification.tsx @@ -12,11 +12,11 @@ export function SteamCMDNotification() { const serverCount = runningSteamServers.size; return ( -
+
@@ -28,7 +28,7 @@ export function SteamCMDNotification() {
-

+

SteamCMD is currently running for {serverCount} server{serverCount !== 1 ? 's' : ''}. Server actions are temporarily disabled to prevent conflicts. This will automatically resolve when the download completes. @@ -36,8 +36,8 @@ export function SteamCMDNotification() {

-
- Downloading... +
+ Downloading...
From a5e50fe8b723d03543791734e646c399b41c0f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:16:26 +0100 Subject: [PATCH 09/27] fix: remove duplicate card subtitle, improve disable logic, inclusive offline count --- src/components/server/ServerCard.tsx | 10 ++++------ src/components/server/ServerListWithActions.tsx | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/server/ServerCard.tsx b/src/components/server/ServerCard.tsx index a49bcdb..919619e 100755 --- a/src/components/server/ServerCard.tsx +++ b/src/components/server/ServerCard.tsx @@ -52,6 +52,7 @@ export function ServerCard({ server }: ServerCardProps) { ServiceStatus.Stopping, ServiceStatus.Unknown, ].includes(server.status); + const isRunning = server.status === ServiceStatus.Running; return (
@@ -60,9 +61,6 @@ export function ServerCard({ server }: ServerCardProps) { {server.name}
-
- {server.state?.track || 'No track'} · {server.state?.playerCount ?? 0} players -
@@ -91,7 +89,7 @@ export function ServerCard({ server }: ServerCardProps) { variant="primary" size="sm" onClick={startServer} - disabled={server.status === ServiceStatus.Running || isPending || disabled} + disabled={isRunning || disabled || isPending} > Start @@ -99,7 +97,7 @@ export function ServerCard({ server }: ServerCardProps) { variant="ghost" size="sm" onClick={restartServer} - disabled={server.status === ServiceStatus.Stopped || isPending || disabled} + disabled={!isRunning || disabled || isPending} > Restart @@ -107,7 +105,7 @@ export function ServerCard({ server }: ServerCardProps) { variant="danger-outline" size="sm" onClick={stopServer} - disabled={server.status === ServiceStatus.Stopped || isPending || disabled} + disabled={!isRunning || disabled || isPending} > Stop diff --git a/src/components/server/ServerListWithActions.tsx b/src/components/server/ServerListWithActions.tsx index 9afecd6..44efbd1 100755 --- a/src/components/server/ServerListWithActions.tsx +++ b/src/components/server/ServerListWithActions.tsx @@ -24,7 +24,7 @@ export function ServerListWithActions({ servers, user }: ServerListWithActionsPr const canCreateServer = hasPermission(user, 'server.create'); const runningCount = servers.filter((s) => s.status === ServiceStatus.Running).length; - const offlineCount = servers.filter((s) => s.status === ServiceStatus.Stopped).length; + const offlineCount = servers.filter((s) => s.status !== ServiceStatus.Running).length; return ( <> From da92ec72a7694f4483892128ab2d1be64b9461eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:18:33 +0100 Subject: [PATCH 10/27] =?UTF-8?q?feat:=20restyle=20server=20detail=20?= =?UTF-8?q?=E2=80=94=20breadcrumb=20topbar,=20info=20strip,=20tab=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/dashboard/server/[id]/page.tsx | 21 +-- .../server/ServerConfigurationTabs.tsx | 44 +++--- src/components/server/ServerHeader.tsx | 141 +++++------------- 3 files changed, 67 insertions(+), 139 deletions(-) diff --git a/src/app/dashboard/server/[id]/page.tsx b/src/app/dashboard/server/[id]/page.tsx index f93150d..b6033c5 100755 --- a/src/app/dashboard/server/[id]/page.tsx +++ b/src/app/dashboard/server/[id]/page.tsx @@ -28,19 +28,14 @@ export default async function ServerPage({ params }: ServerPageProps) { ]); return ( -
-
- - -
- -
-
+
+ +
); } diff --git a/src/components/server/ServerConfigurationTabs.tsx b/src/components/server/ServerConfigurationTabs.tsx index 499c825..aed43b1 100755 --- a/src/components/server/ServerConfigurationTabs.tsx +++ b/src/components/server/ServerConfigurationTabs.tsx @@ -71,30 +71,28 @@ export function ServerConfigurationTabs({ }; return ( -
-
- -
+
+ -
{renderTabContent()}
+
{renderTabContent()}
); } diff --git a/src/components/server/ServerHeader.tsx b/src/components/server/ServerHeader.tsx index 78c56df..924adb6 100755 --- a/src/components/server/ServerHeader.tsx +++ b/src/components/server/ServerHeader.tsx @@ -1,6 +1,6 @@ 'use client'; import Link from 'next/link'; -import { Server, getStatusColor, serviceStatusToString, ServiceStatus } from '@/lib/schemas/server'; +import { Server, serviceStatusToString, ServiceStatus } from '@/lib/schemas/server'; import { startServerEventAction, restartServerEventAction, @@ -10,6 +10,8 @@ import { hasPermission, User } from '@/lib/schemas'; import { useState, useTransition } from 'react'; import { useRouter } from 'next/navigation'; import { DeleteServerModal } from './DeleteServerModal'; +import { Badge } from '@/components/ui/Badge'; +import { GhButton } from '@/components/ui/GhButton'; interface ServerHeaderProps { server: Server; @@ -43,112 +45,45 @@ export function ServerHeader({ server, user }: ServerHeaderProps) { ServiceStatus.Stopping, ServiceStatus.Unknown ].includes(server.status); + return ( -
-
-
- - - - - Back to Dashboard - + <> + {/* Topbar */} +
+
+ Servers + / + {server.name}
-
- -
-
-
-

{server.name}

-
- - - {serviceStatusToString(server.status)} - -
-
- -
- {canDeleteServer && ( - - )} - - - - - -
+
+ + ● {serviceStatusToString(server.status)} + + Start + Restart + Stop + {canDeleteServer && ( + setIsDeleteModalOpen(true)} disabled={disabled || isPending}>Remove + )}
+ -
-
-
Current Track
-
{server.state?.track || 'N/A'}
+ {/* Info strip */} +
+ {[ + { label: 'Track', value: server.state?.track ?? 'N/A' }, + { label: 'Players', value: `${server.state?.playerCount ?? 0} / ${server.state?.maxConnections ?? 0}` }, + { label: 'Session', value: server.state?.session ?? 'N/A' }, + { label: 'Max Connections', value: String(server.state?.maxConnections ?? 0) }, + ].map(({ label, value }) => ( +
+
{label}
+
{value}
-
-
Players
-
- {server.state?.playerCount || 0} / {server.state?.maxConnections || 0} -
-
-
-
Session
-
{server.state?.session || 'N/A'}
-
-
-
Max Connections
-
- {server.state?.maxConnections || 0} -
-
-
+ ))}
setIsDeleteModalOpen(false)} server={server} /> -
+ ); } From 374899e839f1266d6df7abee45bced84c680532a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:24:39 +0100 Subject: [PATCH 11/27] fix: remove duplicate maxConnections info, use h-screen utility --- src/app/dashboard/server/[id]/page.tsx | 2 +- src/components/server/ServerHeader.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/dashboard/server/[id]/page.tsx b/src/app/dashboard/server/[id]/page.tsx index b6033c5..ef08731 100755 --- a/src/app/dashboard/server/[id]/page.tsx +++ b/src/app/dashboard/server/[id]/page.tsx @@ -28,7 +28,7 @@ export default async function ServerPage({ params }: ServerPageProps) { ]); return ( -
+
(
{label}
From 9d240c3a805ee9bf44160a3f0f769a037c5fbe5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:27:18 +0100 Subject: [PATCH 12/27] =?UTF-8?q?feat:=20restyle=20statistics=20tab=20?= =?UTF-8?q?=E2=80=94=20stat=20cards,=20charts,=20recent=20sessions=20table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/DailyActivityChart.tsx | 14 +++---- .../statistics/PlayerCountChart.tsx | 14 +++---- src/components/statistics/RecentSessions.tsx | 41 ++++++++++--------- .../statistics/SessionTypesChart.tsx | 12 +++--- src/components/statistics/StatCard.tsx | 14 +++---- .../statistics/StatisticsDashboard.tsx | 36 ++++++++-------- 6 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/components/statistics/DailyActivityChart.tsx b/src/components/statistics/DailyActivityChart.tsx index f6af6af..b3f300e 100755 --- a/src/components/statistics/DailyActivityChart.tsx +++ b/src/components/statistics/DailyActivityChart.tsx @@ -29,8 +29,8 @@ export function DailyActivityChart({ data }: DailyActivityChartProps) { { label: 'Sessions', data: data.map((item) => item.sessionsCount), - backgroundColor: 'rgba(59, 130, 246, 0.8)', - borderColor: 'rgb(59, 130, 246)', + backgroundColor: '#3fb950', + borderColor: '#3fb950', borderWidth: 1 } ] @@ -43,27 +43,27 @@ export function DailyActivityChart({ data }: DailyActivityChartProps) { legend: { position: 'top' as const, labels: { - color: '#e5e7eb' + color: '#e6edf3' } } }, scales: { x: { ticks: { - color: '#9ca3af' + color: '#8b949e' }, grid: { - color: '#374151' + color: '#21262d' } }, y: { beginAtZero: true, ticks: { - color: '#9ca3af', + color: '#8b949e', stepSize: 1 }, grid: { - color: '#374151' + color: '#21262d' } } } diff --git a/src/components/statistics/PlayerCountChart.tsx b/src/components/statistics/PlayerCountChart.tsx index 49a4b85..996fb73 100755 --- a/src/components/statistics/PlayerCountChart.tsx +++ b/src/components/statistics/PlayerCountChart.tsx @@ -43,8 +43,8 @@ export function PlayerCountChart({ data }: PlayerCountChartProps) { x: new Date(point.timestamp), y: point.count })), - borderColor: 'rgb(59, 130, 246)', - backgroundColor: 'rgba(59, 130, 246, 0.1)', + borderColor: '#58a6ff', + backgroundColor: '#58a6ff1a', tension: 0.4 } ] @@ -57,7 +57,7 @@ export function PlayerCountChart({ data }: PlayerCountChartProps) { legend: { position: 'top' as const, labels: { - color: '#e5e7eb' + color: '#e6edf3' } } }, @@ -68,20 +68,20 @@ export function PlayerCountChart({ data }: PlayerCountChartProps) { unit: 'hour' as const }, ticks: { - color: '#9ca3af' + color: '#8b949e' }, grid: { - color: '#374151' + color: '#21262d' } }, y: { beginAtZero: true, ticks: { - color: '#9ca3af', + color: '#8b949e', stepSize: 1 }, grid: { - color: '#374151' + color: '#21262d' } } } diff --git a/src/components/statistics/RecentSessions.tsx b/src/components/statistics/RecentSessions.tsx index a6cd72c..5a5c734 100755 --- a/src/components/statistics/RecentSessions.tsx +++ b/src/components/statistics/RecentSessions.tsx @@ -29,51 +29,52 @@ export function RecentSessions({ sessions }: RecentSessionsProps) { if (sessions.length === 0) { return ( -
-
📊
-

No recent sessions found

-
+
No recent sessions found
); } return (
- +
- - + - - - - - + {sessions.map((session) => ( - - + - - - + - diff --git a/src/components/statistics/SessionTypesChart.tsx b/src/components/statistics/SessionTypesChart.tsx index 3ba5e23..c594313 100755 --- a/src/components/statistics/SessionTypesChart.tsx +++ b/src/components/statistics/SessionTypesChart.tsx @@ -15,12 +15,10 @@ interface SessionTypesChartProps { } const colors = [ - '#3b82f6', // blue - '#10b981', // emerald - '#f59e0b', // amber - '#ef4444', // red - '#8b5cf6', // violet - '#06b6d4' // cyan + '#3fb950', // gh-green + '#58a6ff', // gh-blue + '#f78166', // gh-red + '#d29922' // gh-yellow ]; export function SessionTypesChart({ data }: SessionTypesChartProps) { @@ -43,7 +41,7 @@ export function SessionTypesChart({ data }: SessionTypesChartProps) { legend: { position: 'bottom' as const, labels: { - color: '#e5e7eb', + color: '#e6edf3', padding: 20 } }, diff --git a/src/components/statistics/StatCard.tsx b/src/components/statistics/StatCard.tsx index 6c2b32c..8216b99 100755 --- a/src/components/statistics/StatCard.tsx +++ b/src/components/statistics/StatCard.tsx @@ -6,16 +6,12 @@ interface StatCardProps { export function StatCard({ title, value, icon }: StatCardProps) { return ( -
-
-
- {icon} -
-
-
{value}
-
{title}
-
+
+
+ {icon} + {title}
+
{value}
); } diff --git a/src/components/statistics/StatisticsDashboard.tsx b/src/components/statistics/StatisticsDashboard.tsx index 498f781..ef79bd2 100755 --- a/src/components/statistics/StatisticsDashboard.tsx +++ b/src/components/statistics/StatisticsDashboard.tsx @@ -14,17 +14,18 @@ interface StatisticsDashboardProps { export function StatisticsDashboard({ stats }: StatisticsDashboardProps) { if (!stats) { return ( -
-
📊
-

No Statistics Available

-

No data found for the selected date range.

+
+
📊
+

No Statistics Available

+

No data found for the selected date range.

); } return ( -
-
+
+ {/* 4 stat cards */} +
- {/* Charts */} -
-
-

Player Count Over Time

+ {/* Charts row */} +
+
+

Player Count Over Time

- -
-

Session Types

+
+

Session Types

-
-

Daily Activity

+
+

Daily Activity

- {/* Recent Sessions */} -
-

Recent Sessions

+ {/* Recent sessions */} +
+
Recent Sessions
From 14faaf87b7ddf371583389d954420138404ca7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:30:06 +0100 Subject: [PATCH 13/27] fix: correct operator precedence in totalPlaytime calculation --- src/components/statistics/StatisticsDashboard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/statistics/StatisticsDashboard.tsx b/src/components/statistics/StatisticsDashboard.tsx index ef79bd2..47c12ce 100755 --- a/src/components/statistics/StatisticsDashboard.tsx +++ b/src/components/statistics/StatisticsDashboard.tsx @@ -29,7 +29,7 @@ export function StatisticsDashboard({ stats }: StatisticsDashboardProps) { Date: Sat, 21 Mar 2026 21:42:01 +0100 Subject: [PATCH 14/27] feat: restyle all 5 config form tabs to GitHub-dark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace gray-* tokens with gh-* design tokens across all config editors: labels → text-gh-secondary, headings → border-gh-border-muted/text-gh-primary, checkboxes → gh-overlay/gh-green/gh-blue, buttons → gh-btn-green, selects → form-select. --- .../configuration/AssistRulesEditor.tsx | 16 ++--- .../configuration/ConfigurationEditor.tsx | 26 +++---- .../configuration/EventConfigEditor.tsx | 70 +++++++++---------- .../configuration/EventRulesEditor.tsx | 22 +++--- .../configuration/ServerSettingsEditor.tsx | 34 ++++----- 5 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/components/configuration/AssistRulesEditor.tsx b/src/components/configuration/AssistRulesEditor.tsx index 190bc19..68963c9 100755 --- a/src/components/configuration/AssistRulesEditor.tsx +++ b/src/components/configuration/AssistRulesEditor.tsx @@ -96,7 +96,7 @@ export function AssistRulesEditor({ serverId, config }: AssistRulesEditorProps)
{assistFields.map(({ key, label, type }) => (
- + {type === 'number' ? ( handleInputChange(key, e.target.value)} - className="form-input w-full" + className="form-select w-full" > @@ -122,15 +122,15 @@ export function AssistRulesEditor({ serverId, config }: AssistRulesEditorProps) ))}
-
-
diff --git a/src/components/configuration/ConfigurationEditor.tsx b/src/components/configuration/ConfigurationEditor.tsx index 95766e7..56d5b7c 100755 --- a/src/components/configuration/ConfigurationEditor.tsx +++ b/src/components/configuration/ConfigurationEditor.tsx @@ -47,7 +47,7 @@ export function ConfigurationEditor({ serverId, config }: ConfigurationEditorPro
- +
- +
- +
- + handleInputChange('registerToLobby', e.target.value)} - className="form-input w-full" + className="form-select w-full" > @@ -106,15 +106,15 @@ export function ConfigurationEditor({ serverId, config }: ConfigurationEditorPro
-
-
diff --git a/src/components/configuration/EventConfigEditor.tsx b/src/components/configuration/EventConfigEditor.tsx index 8d2d8ae..8445f73 100755 --- a/src/components/configuration/EventConfigEditor.tsx +++ b/src/components/configuration/EventConfigEditor.tsx @@ -99,17 +99,17 @@ export function EventConfigEditor({ serverId, config }: EventConfigEditorProps) return (
-

+

Basic Event Settings

- +
-
+
Date + Type + Track + Duration + Players
+
{formatDate(session.date)} - - {session.type} + + + {session.type === 'R' ? 'Race' : session.type === 'Q' ? 'Qualify' : 'Practice'} {session.track} + {session.track} {formatDuration(session.duration)} + {session.players}
- - - + + + {initialData.length > 0 ? ( + initialData.map((user) => ( + + + + {hasPermission(currentUser, 'membership.edit') && ( + + )} + + )) + ) : ( + + + + )} + +
- + {/* Users table */} +
+ + + + + + {hasPermission(currentUser, 'membership.edit') && ( + - - {hasPermission(currentUser, 'membership.edit') && ( - - )} - - - - {initialData.length > 0 ? ( - initialData.map((user) => ( - - - - {hasPermission(currentUser, 'membership.edit') && ( - - )} - - )) - ) : ( - - - )} - -
+ + + + + Actions - - - Actions -
- {user.username} - - - {user.role.name} - - -
- - {hasPermission(currentUser, 'membership.delete') && ( - - )} -
-
- No users found -
-
- +
+ {user.username} + + + {user.role.name} + + +
+ + {hasPermission(currentUser, 'membership.delete') && ( + + )} +
+
+ No users found +
+
{/* Modals */} {showCreateModal && } From 3c643d5dcc89559dc99d0bc5305dba38dc7c44d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 21:57:57 +0100 Subject: [PATCH 19/27] feat: restyle server create/delete modals to GitHub-dark Apply GH-dark design tokens to Modal container, CreateServerModal, and DeleteServerModal: overlay/canvas card pattern, form-input class, GhButton variants (primary, ghost, danger-solid), and GH token text/border colors. --- src/components/server/CreateServerModal.tsx | 23 ++++++++++++--------- src/components/server/DeleteServerModal.tsx | 23 ++++++++++++--------- src/components/ui/Modal.tsx | 10 ++++----- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/components/server/CreateServerModal.tsx b/src/components/server/CreateServerModal.tsx index 520c0f2..7dda7fb 100755 --- a/src/components/server/CreateServerModal.tsx +++ b/src/components/server/CreateServerModal.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useActionState, useTransition } from 'react'; import { Modal } from '@/components/ui/Modal'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; +import { GhButton } from '@/components/ui/GhButton'; import { createServerAction, type ServerActionResult } from '@/lib/actions/server-management'; import { useServerCreationPopup } from '@/lib/context/ServerCreationPopupContext'; @@ -58,12 +59,12 @@ export function CreateServerModal({ isOpen, onClose }: CreateServerModalProps) { return ( {!state.success && state.message && ( -
{state.message}
+
{state.message}
)}
-
- - +
diff --git a/src/components/server/DeleteServerModal.tsx b/src/components/server/DeleteServerModal.tsx index 3b6d0b5..6fc9592 100755 --- a/src/components/server/DeleteServerModal.tsx +++ b/src/components/server/DeleteServerModal.tsx @@ -3,6 +3,7 @@ import { useState, useTransition } from 'react'; import { Modal } from '@/components/ui/Modal'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; +import { GhButton } from '@/components/ui/GhButton'; import { deleteServerAction } from '@/lib/actions/server-management'; import { Server } from '@/lib/schemas/server'; @@ -42,37 +43,39 @@ export function DeleteServerModal({ isOpen, onClose, server }: DeleteServerModal return ( - {error &&
{error}
} + {error &&
{error}
}
-

+

Are you sure you want to delete the server "{server.name}"?

-

This action cannot be undone.

+

This action cannot be undone.

- - +
); diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx index 7db1a5d..f20454b 100755 --- a/src/components/ui/Modal.tsx +++ b/src/components/ui/Modal.tsx @@ -33,17 +33,17 @@ export function Modal({ isOpen, onClose, title, children, className }: ModalProp if (!isOpen) return null; return ( -
-
+
+
-

{title}

-
From 71fa2280135f11a5ffbf7725c285cb259681d12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 21 Mar 2026 22:11:13 +0100 Subject: [PATCH 20/27] refactor: remove gh/GitHub references from tokens, classes, and component names Rename all --color-gh-* CSS tokens to --color-*, update Tailwind class names (bg-gh-*, text-gh-*, border-gh-*, etc.) across all TSX/TS files, rename GhButton component and file to Button, and remove trivial descriptive comments. --- src/app/globals.css | 48 ++++++------ src/app/layout.tsx | 2 +- .../configuration/AssistRulesEditor.tsx | 10 +-- .../configuration/ConfigurationEditor.tsx | 18 ++--- .../configuration/EventConfigEditor.tsx | 56 +++++++------- .../configuration/EventRulesEditor.tsx | 16 ++-- .../configuration/ServerSettingsEditor.tsx | 24 +++--- .../leaderboard/LeaderboardManager.tsx | 18 ++--- src/components/login/LoginForm.tsx | 18 ++--- src/components/membership/CreateUserModal.tsx | 22 +++--- src/components/membership/DeleteUserModal.tsx | 18 ++--- .../membership/UserManagementTable.tsx | 55 +++++++------- src/components/server/CreateServerModal.tsx | 14 ++-- src/components/server/DeleteServerModal.tsx | 16 ++-- src/components/server/ServerCard.tsx | 28 +++---- .../server/ServerConfigurationTabs.tsx | 6 +- src/components/server/ServerHeader.tsx | 26 +++---- .../server/ServerListWithActions.tsx | 15 ++-- src/components/server/ServerRow.tsx | 20 ++--- src/components/statistics/RecentSessions.tsx | 30 ++++---- .../statistics/SessionTypesChart.tsx | 8 +- src/components/statistics/StatCard.tsx | 6 +- .../statistics/StatisticsDashboard.tsx | 23 +++--- src/components/ui/AppShell.tsx | 2 +- src/components/ui/Badge.tsx | 10 +-- src/components/ui/Button.tsx | 73 ++++++++++--------- src/components/ui/GhButton.tsx | 47 ------------ src/components/ui/Modal.tsx | 6 +- src/components/ui/Sidebar.tsx | 21 ++---- src/components/ui/StatusDot.tsx | 14 ++-- src/components/ui/SteamCMDNotification.tsx | 10 +-- 31 files changed, 308 insertions(+), 372 deletions(-) mode change 100755 => 100644 src/components/ui/Button.tsx delete mode 100644 src/components/ui/GhButton.tsx diff --git a/src/app/globals.css b/src/app/globals.css index 843a1ad..638aa11 100755 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,35 +1,35 @@ @import "tailwindcss"; @theme { - --color-gh-base: #0d1117; - --color-gh-canvas: #161b22; - --color-gh-overlay: #21262d; - --color-gh-sidebar: #010409; - --color-gh-border: #30363d; - --color-gh-border-muted: #21262d; - --color-gh-hover: #1c2128; - --color-gh-primary: #e6edf3; - --color-gh-secondary: #c9d1d9; - --color-gh-muted: #8b949e; - --color-gh-subtle: #6e7681; - --color-gh-blue: #58a6ff; - --color-gh-blue-bg: #1f6feb33; - --color-gh-green: #3fb950; - --color-gh-green-bg: #3fb95022; - --color-gh-yellow: #d29922; - --color-gh-yellow-bg: #d2992220; - --color-gh-red: #f85149; - --color-gh-red-bg: #f8514920; - --color-gh-orange: #f78166; - --color-gh-btn-green: #238636; - --color-gh-btn-green-hover: #2ea043; + --color-base: #0d1117; + --color-canvas: #161b22; + --color-overlay: #21262d; + --color-sidebar: #010409; + --color-border: #30363d; + --color-border-muted: #21262d; + --color-hover: #1c2128; + --color-primary: #e6edf3; + --color-secondary: #c9d1d9; + --color-muted: #8b949e; + --color-subtle: #6e7681; + --color-blue: #58a6ff; + --color-blue-bg: #1f6feb33; + --color-green: #3fb950; + --color-green-bg: #3fb95022; + --color-yellow: #d29922; + --color-yellow-bg: #d2992220; + --color-red: #f85149; + --color-red-bg: #f8514920; + --color-orange: #f78166; + --color-btn-green: #238636; + --color-btn-green-hover: #2ea043; } @layer components { .form-input { - @apply block w-full rounded-md border border-gh-border bg-gh-overlay px-3 py-2 text-sm text-gh-primary placeholder-gh-subtle focus:border-gh-blue focus:outline-none focus:ring-1 focus:ring-gh-blue; + @apply block w-full rounded-md border border-border bg-overlay px-3 py-2 text-sm text-primary placeholder-subtle focus:border-blue focus:outline-none focus:ring-1 focus:ring-blue; } .form-select { - @apply block w-full rounded-md border border-gh-border bg-gh-overlay px-3 py-2 text-sm text-gh-primary focus:border-gh-blue focus:outline-none focus:ring-1 focus:ring-gh-blue; + @apply block w-full rounded-md border border-border bg-overlay px-3 py-2 text-sm text-primary focus:border-blue focus:outline-none focus:ring-1 focus:ring-blue; } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 201da29..6618931 100755 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,7 +13,7 @@ export default function RootLayout({ }>) { return ( - {children} + {children} ); } diff --git a/src/components/configuration/AssistRulesEditor.tsx b/src/components/configuration/AssistRulesEditor.tsx index a6574a2..f2c2445 100755 --- a/src/components/configuration/AssistRulesEditor.tsx +++ b/src/components/configuration/AssistRulesEditor.tsx @@ -96,7 +96,7 @@ export function AssistRulesEditor({ serverId, config }: AssistRulesEditorProps)
{assistFields.map(({ key, label, type }) => (
- + {type === 'number' ? ( -
-