Files
mission-control-v2/frontend/src/components/CustomDialog.tsx
T
Hitonabi 74f64731ab Refactor: Frontend-Fundament — Format-Utils, Dialog-Ref, Typen (Phase 3a)
- Neuer lib/format.ts: gb/fmtBytes/fmtSize/fmtEta/fmtCtx zentral; aus
  DashboardView/SystemView/ModelsView entdoppelt und importiert.
- CustomDialog: document.getElementById -> useRef (kein DOM-Query, robuster).
- api.ts: GitInfo/ComponentVersion/Versions typisiert, SystemStatus.versions
  ergänzt; App.tsx nutzt SystemStatus statt any.

tsc grün, Build grün, Dashboard verifiziert (keine Konsolenfehler, Formatierer
rendern identisch).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 14:36:28 +02:00

67 lines
2.7 KiB
TypeScript

import { useRef } from "react"
import { X } from "lucide-react"
export interface CustomDialogProps {
type: "alert" | "confirm" | "prompt"
title: string
message: string
defaultValue?: string
onConfirm: (val?: string) => void
onCancel?: () => void
}
export function CustomDialog({ type, title, message, defaultValue, onConfirm, onCancel }: CustomDialogProps) {
const inputRef = useRef<HTMLInputElement>(null)
return (
<div className="fixed inset-0 z-[99] bg-black/60 backdrop-blur-sm flex items-center justify-center p-4">
<div className="w-full max-w-sm rounded-2xl border border-border/80 bg-card p-6 shadow-2xl space-y-4 animate-in fade-in zoom-in-95 duration-200">
<div className="flex items-center justify-between border-b border-border/20 pb-2">
<h3 className="text-xs font-bold uppercase tracking-wider text-primary">{title}</h3>
<button
onClick={onCancel || (() => onConfirm())}
className="p-1 rounded hover:bg-accent text-muted-foreground hover:text-foreground cursor-pointer"
>
<X className="h-4 w-4" />
</button>
</div>
<p className="text-xs text-muted-foreground leading-relaxed">{message}</p>
{type === "prompt" && (
<input
ref={inputRef}
type="text"
defaultValue={defaultValue}
className="w-full h-9 px-3 text-xs bg-background/40 border border-border/60 rounded-lg outline-none focus:border-primary transition-colors text-foreground"
autoFocus
onKeyDown={(e) => {
if (e.key === "Enter") {
onConfirm(inputRef.current?.value)
}
}}
/>
)}
<div className="flex justify-end gap-3 pt-2">
{(type === "confirm" || type === "prompt") && (
<button
onClick={onCancel}
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-muted-foreground border border-border/60 bg-background/20 hover:bg-accent rounded-lg transition-colors cursor-pointer"
>
Abbrechen
</button>
)}
<button
onClick={() => {
const val = type === "prompt" ? inputRef.current?.value : undefined
onConfirm(val)
}}
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-primary-foreground bg-primary hover:bg-primary/95 rounded-lg transition-colors cursor-pointer"
>
{type === "confirm" ? "Ja, fortfahren" : type === "prompt" ? "Übernehmen" : "OK"}
</button>
</div>
</div>
</div>
)
}