Colors (GSD palette) untouched. New visual vocabulary across the whole GUI: - warm-tinted layered shadow tokens (--shadow-xs/sm/md) replacing flat rings; cards/dialogs framed with hairline border + real elevation - strict radii scale: xl cards / lg inputs / md controls / 2xl dialogs; buttons move from pills to rounded-md - third type register: --font-mono + tabular-nums on SQL, timers, dates, ids; standardized .thot-label micro-label tier - prose: framed tables with uppercase headers, elevated code blocks - SqlViewer badges moved from hardcoded Tailwind greens/reds to success/ destructive token tints; ResultsPanel inline styles replaced with classes - artifact gate: first option rendered as filled primary action Verified offline via Playwright against a mock backend replaying a real psd session (no VPN needed). tsc clean, 115/115 vitest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "../components/ui/dialog";
|
|
import { Button } from "../components/ui/button";
|
|
|
|
interface Props {
|
|
open: boolean;
|
|
initial: string;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSubmit: (name: string) => void;
|
|
title?: string;
|
|
}
|
|
|
|
export function RenameDialog({ open, initial, onOpenChange, onSubmit, title = "Rename session" }: Props) {
|
|
const [name, setName] = useState(initial);
|
|
useEffect(() => { if (open) setName(initial); }, [open, initial]);
|
|
|
|
function submit(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
if (!name.trim()) return;
|
|
onSubmit(name.trim());
|
|
onOpenChange(false);
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent>
|
|
<DialogHeader><DialogTitle>{title}</DialogTitle></DialogHeader>
|
|
<form onSubmit={submit} className="flex flex-col gap-3">
|
|
<div>
|
|
<label className="mb-1.5 block text-xs font-medium text-muted-foreground" htmlFor="rename-name">Name</label>
|
|
<input
|
|
id="rename-name"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
className="w-full rounded-lg border border-input bg-card px-3 py-2 text-sm shadow-xs outline-none transition-[border-color,box-shadow] focus:border-primary/50 focus:ring-3 focus:ring-ring/15"
|
|
placeholder="Session name…"
|
|
/>
|
|
</div>
|
|
<DialogFooter>
|
|
<Button type="button" variant="outline" size="sm" onClick={() => onOpenChange(false)}>Cancel</Button>
|
|
<Button type="submit" size="sm">Save</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|