rigs completed
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { CheckCircle2, Loader2, XCircle } from 'lucide-react';
|
||||
import { EventsOn } from '../../wailsjs/runtime/runtime';
|
||||
|
||||
type Step = {
|
||||
id: string;
|
||||
label: string;
|
||||
status: 'pending' | 'running' | 'done' | 'error';
|
||||
detail?: string;
|
||||
};
|
||||
|
||||
// ShutdownProgress is a full-screen overlay that appears while HamLog is
|
||||
// running its close-time tasks (backup, future LoTW upload, ...). It
|
||||
// listens for `shutdown:start` / `shutdown:update` / `shutdown:done`
|
||||
// events from the backend and renders a checklist that updates as each
|
||||
// task completes. The backend triggers wruntime.Quit() once everything
|
||||
// is finished, so this component never has to dismiss itself.
|
||||
export function ShutdownProgress() {
|
||||
const [steps, setSteps] = useState<Step[] | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const u1 = EventsOn('shutdown:start', (s: Step[]) => setSteps(s ?? []));
|
||||
const u2 = EventsOn('shutdown:update', (s: Step[]) => setSteps(s ?? []));
|
||||
const u3 = EventsOn('shutdown:done', (s: Step[]) => setSteps(s ?? []));
|
||||
return () => { u1?.(); u2?.(); u3?.(); };
|
||||
}, []);
|
||||
|
||||
if (!steps) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
||||
<div className="bg-card border border-border rounded-lg shadow-xl p-6 min-w-[360px] max-w-[480px]">
|
||||
<div className="text-sm font-semibold mb-3 text-foreground">Closing HamLog…</div>
|
||||
<div className="space-y-2">
|
||||
{steps.length === 0 ? (
|
||||
<div className="text-xs text-muted-foreground italic">Nothing to do, exiting.</div>
|
||||
) : steps.map((s) => (
|
||||
<div key={s.id} className="flex items-start gap-2 text-sm">
|
||||
<div className="mt-0.5 w-4 flex items-center justify-center">
|
||||
{s.status === 'done' && <CheckCircle2 className="size-4 text-emerald-600" />}
|
||||
{s.status === 'running' && <Loader2 className="size-4 animate-spin text-primary" />}
|
||||
{s.status === 'error' && <XCircle className="size-4 text-rose-600" />}
|
||||
{s.status === 'pending' && <span className="size-2 rounded-full bg-muted-foreground/40" />}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className={
|
||||
s.status === 'done' ? 'text-foreground'
|
||||
: s.status === 'error' ? 'text-rose-700 font-medium'
|
||||
: s.status === 'pending' ? 'text-muted-foreground'
|
||||
: 'text-foreground font-medium'
|
||||
}>
|
||||
{s.label}
|
||||
</div>
|
||||
{s.detail && (
|
||||
<div className="text-[11px] text-muted-foreground mt-0.5 font-mono break-all">
|
||||
{s.detail}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user