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.
This commit is contained in:
2026-03-21 21:57:57 +01:00
parent c99eebde05
commit 3c643d5dcc
3 changed files with 31 additions and 25 deletions

View File

@@ -3,6 +3,7 @@
import { useState, useEffect, useActionState, useTransition } from 'react'; import { useState, useEffect, useActionState, useTransition } from 'react';
import { Modal } from '@/components/ui/Modal'; import { Modal } from '@/components/ui/Modal';
import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
import { GhButton } from '@/components/ui/GhButton';
import { createServerAction, type ServerActionResult } from '@/lib/actions/server-management'; import { createServerAction, type ServerActionResult } from '@/lib/actions/server-management';
import { useServerCreationPopup } from '@/lib/context/ServerCreationPopupContext'; import { useServerCreationPopup } from '@/lib/context/ServerCreationPopupContext';
@@ -58,12 +59,12 @@ export function CreateServerModal({ isOpen, onClose }: CreateServerModalProps) {
return ( return (
<Modal isOpen={isOpen} onClose={handleClose} title="Create New Server"> <Modal isOpen={isOpen} onClose={handleClose} title="Create New Server">
{!state.success && state.message && ( {!state.success && state.message && (
<div className="mb-4 rounded-md bg-red-900 p-3 text-sm text-red-300">{state.message}</div> <div className="mb-4 rounded-md border border-gh-red/20 bg-gh-red-bg p-3 text-sm text-gh-red">{state.message}</div>
)} )}
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="mb-6"> <div className="mb-6">
<label htmlFor="server-name" className="block text-sm font-medium text-gray-300"> <label htmlFor="server-name" className="mb-1.5 block text-sm font-medium text-gh-secondary">
Server Name Server Name
</label> </label>
<input <input
@@ -73,34 +74,36 @@ export function CreateServerModal({ isOpen, onClose }: CreateServerModalProps) {
onChange={(e) => setServerName(e.target.value)} onChange={(e) => setServerName(e.target.value)}
required required
disabled={isSubmitting || isPending} disabled={isSubmitting || isPending}
className="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:ring-1 focus:ring-blue-500 focus:outline-none disabled:opacity-50" className="form-input"
placeholder="Enter server name..." placeholder="Enter server name..."
/> />
</div> </div>
<div className="flex justify-end space-x-2"> <div className="flex justify-end space-x-2">
<button <GhButton
type="button" type="button"
variant="ghost"
size="md"
onClick={handleClose} onClick={handleClose}
disabled={isSubmitting || isPending} disabled={isSubmitting || isPending}
className="rounded-md bg-gray-600 px-4 py-2 text-sm font-medium transition-colors hover:bg-gray-700 disabled:opacity-50"
> >
Cancel Cancel
</button> </GhButton>
<button <GhButton
type="submit" type="submit"
variant="primary"
size="md"
disabled={isSubmitting || !serverName.trim() || isPending} disabled={isSubmitting || !serverName.trim() || isPending}
className="flex items-center rounded-md bg-green-600 px-4 py-2 text-sm font-medium transition-colors hover:bg-green-700 disabled:opacity-50"
> >
{isSubmitting ? ( {isSubmitting ? (
<> <>
<LoadingSpinner className="mr-2 h-4 w-4" /> <LoadingSpinner className="h-4 w-4" />
Creating... Creating...
</> </>
) : ( ) : (
'Create Server' 'Create Server'
)} )}
</button> </GhButton>
</div> </div>
</form> </form>
</Modal> </Modal>

View File

@@ -3,6 +3,7 @@
import { useState, useTransition } from 'react'; import { useState, useTransition } from 'react';
import { Modal } from '@/components/ui/Modal'; import { Modal } from '@/components/ui/Modal';
import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
import { GhButton } from '@/components/ui/GhButton';
import { deleteServerAction } from '@/lib/actions/server-management'; import { deleteServerAction } from '@/lib/actions/server-management';
import { Server } from '@/lib/schemas/server'; import { Server } from '@/lib/schemas/server';
@@ -42,37 +43,39 @@ export function DeleteServerModal({ isOpen, onClose, server }: DeleteServerModal
return ( return (
<Modal isOpen={isOpen} onClose={handleClose} title="Delete Server"> <Modal isOpen={isOpen} onClose={handleClose} title="Delete Server">
{error && <div className="mb-4 rounded-md bg-red-900 p-3 text-sm text-red-300">{error}</div>} {error && <div className="mb-4 rounded-md border border-gh-red/20 bg-gh-red-bg p-3 text-sm text-gh-red">{error}</div>}
<div className="mb-6"> <div className="mb-6">
<p className="text-gray-300"> <p className="text-gh-secondary">
Are you sure you want to delete the server <strong>&quot;{server.name}&quot;</strong>? Are you sure you want to delete the server <strong>&quot;{server.name}&quot;</strong>?
</p> </p>
<p className="mt-2 text-sm text-gray-400">This action cannot be undone.</p> <p className="mt-2 text-sm text-gh-muted">This action cannot be undone.</p>
</div> </div>
<div className="flex justify-end space-x-2"> <div className="flex justify-end space-x-2">
<button <GhButton
variant="ghost"
size="md"
onClick={handleClose} onClick={handleClose}
disabled={isPending} disabled={isPending}
className="rounded-md bg-gray-600 px-4 py-2 text-sm font-medium transition-colors hover:bg-gray-700 disabled:opacity-50"
> >
Cancel Cancel
</button> </GhButton>
<button <GhButton
variant="danger-solid"
size="md"
onClick={handleDelete} onClick={handleDelete}
disabled={isPending} disabled={isPending}
className="flex items-center rounded-md bg-red-600 px-4 py-2 text-sm font-medium transition-colors hover:bg-red-700 disabled:opacity-50"
> >
{isPending ? ( {isPending ? (
<> <>
<LoadingSpinner size="sm" className="mr-2" /> <LoadingSpinner size="sm" />
Deleting... Deleting...
</> </>
) : ( ) : (
'Delete Server' 'Delete Server'
)} )}
</button> </GhButton>
</div> </div>
</Modal> </Modal>
); );

View File

@@ -33,17 +33,17 @@ export function Modal({ isOpen, onClose, title, children, className }: ModalProp
if (!isOpen) return null; if (!isOpen) return null;
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center"> <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4">
<div className="bg-opacity-50 absolute inset-0 bg-black" onClick={onClose} /> <div className="absolute inset-0" onClick={onClose} />
<div <div
className={cn( className={cn(
'relative mx-4 w-full max-w-md rounded-lg bg-gray-800 p-6 shadow-lg', 'relative w-full max-w-md rounded-lg border border-gh-border bg-gh-canvas p-6 shadow-xl',
className className
)} )}
> >
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex items-center justify-between">
<h3 className="text-lg font-semibold text-white">{title}</h3> <h3 className="text-lg font-semibold text-gh-primary">{title}</h3>
<button onClick={onClose} className="text-gray-400 hover:text-white"> <button onClick={onClose} className="text-gh-muted hover:text-gh-primary">
× ×
</button> </button>
</div> </div>