website refactor

This commit is contained in:
2026-01-20 00:36:18 +01:00
parent e9dfe15dff
commit f5215f9d73
2 changed files with 94 additions and 44 deletions

View File

@@ -229,7 +229,9 @@ export function DevToolbar() {
if (isMinimized) { if (isMinimized) {
return ( return (
<Stack position="fixed" right={4} bottom={4} zIndex={1000}> <Stack
style={{ position: 'fixed', right: '1rem', bottom: '6rem', zIndex: 1000 }}
>
<IconButton <IconButton
icon={Wrench} icon={Wrench}
onClick={() => setIsMinimized(false)} onClick={() => setIsMinimized(false)}
@@ -243,10 +245,6 @@ export function DevToolbar() {
return ( return (
<Stack <Stack
position="fixed"
right={4}
bottom={24}
zIndex={1000}
width="min(420px, calc(100vw - 2rem))" width="min(420px, calc(100vw - 2rem))"
maxHeight="calc(100vh - 2rem)" maxHeight="calc(100vh - 2rem)"
overflow="auto" overflow="auto"
@@ -256,6 +254,10 @@ export function DevToolbar() {
bg="rgba(20, 22, 25, 0.92)" bg="rgba(20, 22, 25, 0.92)"
padding={3} padding={3}
style={{ style={{
position: 'fixed',
right: '1rem',
bottom: '6rem',
zIndex: 1000,
boxShadow: '0 18px 40px rgba(0,0,0,0.55)', boxShadow: '0 18px 40px rgba(0,0,0,0.55)',
backdropFilter: 'blur(12px)', backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)',
@@ -277,12 +279,14 @@ export function DevToolbar() {
onClick={() => setIsExpanded(!isExpanded)} onClick={() => setIsExpanded(!isExpanded)}
variant="ghost" variant="ghost"
size="sm" size="sm"
title={isExpanded ? "Collapse" : "Expand"}
/> />
<IconButton <IconButton
icon={X} icon={X}
onClick={() => setIsMinimized(true)} onClick={() => setIsMinimized(true)}
variant="ghost" variant="ghost"
size="sm" size="sm"
title="Minimize"
/> />
</Stack> </Stack>
</Stack> </Stack>

View File

@@ -1,10 +1,10 @@
'use client'; 'use client';
import { Modal } from '@/components/shared/Modal';
import { Box } from '@/ui/Box'; import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text'; import { Text } from '@/ui/Text';
import { Search, Command, ArrowRight } from 'lucide-react'; import { Search, Command, ArrowRight, X } from 'lucide-react';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
interface CommandModalProps { interface CommandModalProps {
isOpen: boolean; isOpen: boolean;
@@ -13,6 +13,27 @@ interface CommandModalProps {
export function CommandModal({ isOpen, onClose }: CommandModalProps) { export function CommandModal({ isOpen, onClose }: CommandModalProps) {
const [query, setQuery] = useState(''); const [query, setQuery] = useState('');
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose();
}
};
if (isOpen) {
document.addEventListener('keydown', down);
document.body.style.overflow = 'hidden';
}
return () => {
document.removeEventListener('keydown', down);
document.body.style.overflow = 'unset';
};
}, [isOpen, onClose]);
// Mock results // Mock results
const results = [ const results = [
@@ -21,50 +42,75 @@ export function CommandModal({ isOpen, onClose }: CommandModalProps) {
{ label: 'Create League', shortcut: 'C L' }, { label: 'Create League', shortcut: 'C L' },
].filter(r => r.label.toLowerCase().includes(query.toLowerCase())); ].filter(r => r.label.toLowerCase().includes(query.toLowerCase()));
return ( if (!mounted) return null;
<Modal if (!isOpen) return null;
isOpen={isOpen}
onClose={onClose} return createPortal(
title="Command Palette" <div className="fixed inset-0 z-[9999] flex items-start justify-center pt-[20vh] px-4">
size="md" {/* Backdrop */}
icon={<Command size={20} />} <div
> className="absolute inset-0 bg-black/60 backdrop-blur-sm transition-opacity"
<Box className="flex flex-col gap-4"> onClick={onClose}
<Box className="relative"> />
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-text-low" size={16} />
{/* Modal Content */}
<div className="relative w-full max-w-lg bg-surface-charcoal border border-outline-steel rounded-xl shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200">
<div className="flex items-center border-b border-outline-steel px-4 py-3 gap-3">
<Search className="text-text-low" size={18} />
<input <input
autoFocus autoFocus
type="text" type="text"
placeholder="Type a command or search..." placeholder="Type a command or search..."
className="w-full bg-surface-charcoal border border-outline-steel rounded-md pl-10 pr-4 py-3 text-text-high placeholder:text-text-low focus:border-primary-accent focus:outline-none transition-colors" className="flex-1 bg-transparent border-none outline-none text-text-high placeholder:text-text-low/50 text-base h-6"
value={query} value={query}
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
/> />
</Box> <button onClick={onClose} className="text-text-low hover:text-text-high transition-colors">
<span className="sr-only">Close</span>
<kbd className="hidden sm:inline-block px-1.5 py-0.5 text-[10px] font-mono bg-white/5 rounded border border-white/5">ESC</kbd>
</button>
</div>
<Box className="flex flex-col gap-1"> <div className="p-2">
<Text size="xs" className="text-text-low font-mono uppercase tracking-wider px-2 mb-1"> {results.length > 0 ? (
Suggestions <div className="flex flex-col gap-1">
</Text> <div className="px-2 py-1.5 text-[10px] font-mono uppercase tracking-wider text-text-low/50 font-bold">
{results.map((result, i) => ( Suggestions
<button </div>
key={i} {results.map((result, i) => (
className="flex items-center justify-between px-3 py-2 rounded-md hover:bg-white/5 text-left group transition-colors" <button
onClick={onClose} key={i}
> className="flex items-center justify-between px-3 py-2.5 rounded-lg hover:bg-white/5 text-left group transition-colors"
<Text size="sm" className="text-text-med group-hover:text-text-high"> onClick={onClose}
{result.label} >
</Text> <span className="text-sm text-text-med group-hover:text-text-high font-medium">
<Box className="flex items-center gap-2"> {result.label}
<Text size="xs" className="text-text-low font-mono bg-white/5 px-1.5 py-0.5 rounded"> </span>
{result.shortcut} <div className="flex items-center gap-2">
</Text> <span className="text-[10px] font-mono text-text-low bg-white/5 px-1.5 py-0.5 rounded border border-white/5">
<ArrowRight size={14} className="text-text-low opacity-0 group-hover:opacity-100 transition-opacity" /> {result.shortcut}
</Box> </span>
</button> <ArrowRight size={14} className="text-text-low opacity-0 group-hover:opacity-100 transition-opacity -translate-x-2 group-hover:translate-x-0" />
))} </div>
</Box> </button>
</Box> ))}
</Modal> </div>
) : (
<div className="px-4 py-8 text-center text-text-low text-sm">
No results found.
</div>
)}
</div>
<div className="px-4 py-2 bg-white/2 border-t border-white/5 flex items-center justify-between text-[10px] text-text-low">
<div className="flex gap-3">
<span><strong className="text-text-med"></strong> to navigate</span>
<span><strong className="text-text-med"></strong> to select</span>
</div>
<span>GridPilot Command</span>
</div>
</div>
</div>,
document.body
); );
} }