This commit is contained in:
2026-06-06 14:16:30 +02:00
parent f91f9ff3b8
commit 17f7a00bd7
19 changed files with 1278 additions and 91 deletions
+31 -2
View File
@@ -1,5 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
import { Plus, Trash2, RotateCcw, Save, Download, Loader2, Search } from 'lucide-react';
import { Plus, Trash2, RotateCcw, Save, Download, Upload, Loader2, Search } from 'lucide-react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@@ -17,6 +17,7 @@ import {
ImportAwardReferencesText, GetAwardPresets, ApplyAwardPreset,
ListCountries, DXCCForCountry, DXCCName,
PopulateBuiltinReferences, HasBuiltinReferences,
ExportAwards, ImportAwards,
} from '../../wailsjs/go/main/App';
// Above this many references the editor stops loading the whole list and
@@ -182,6 +183,28 @@ export function AwardEditor({ open, onClose, onSaved }: Props) {
async function reset() {
try { setDefs((await ResetAwardDefs()) as any); setSel(0); } catch (e: any) { setErr(String(e?.message ?? e)); }
}
// Export every award definition + reference list to a JSON bundle (backup
// that survives a reinstall / PC change, independent of the database).
async function exportAwards() {
setErr('');
try {
const p = await ExportAwards();
if (p) setErr(`Awards exported to:\n${p}`);
} catch (e: any) { setErr(String(e?.message ?? e)); }
}
// Import an award bundle: definitions are upserted by code, reference lists
// replaced. Reloads the editor afterwards.
async function importAwards() {
setErr('');
try {
const r: any = await ImportAwards();
if (!r || (!r.awards && !r.references)) return; // cancelled
const [d] = await Promise.all([GetAwardDefs(), loadMeta()]);
setDefs((d ?? []) as any); setSel(0);
onSaved();
setErr(`Imported ${r.awards} award(s) and ${r.references} reference(s).`);
} catch (e: any) { setErr(String(e?.message ?? e)); }
}
async function updateList(code: string) {
setUpdating(code); setErr('');
try { await UpdateAwardReferenceList(code); await loadMeta(); }
@@ -228,7 +251,7 @@ export function AwardEditor({ open, onClose, onSaved }: Props) {
{/* Right: tabbed editor for selected award */}
<div className="flex flex-col min-h-0 overflow-hidden">
{err && <div className="mx-4 mt-3 text-xs text-destructive bg-destructive/10 border border-destructive/30 rounded px-3 py-1.5">{err}</div>}
{err && <div className="mx-4 mt-3 text-xs text-destructive bg-destructive/10 border border-destructive/30 rounded px-3 py-1.5 whitespace-pre-line break-all">{err}</div>}
{!cur ? (
<div className="flex-1 grid place-items-center text-sm text-muted-foreground">Select or create an award.</div>
) : (
@@ -338,6 +361,12 @@ export function AwardEditor({ open, onClose, onSaved }: Props) {
<DialogFooter className="px-5 py-3 border-t !flex-row">
<Button variant="ghost" onClick={reset}><RotateCcw className="size-3.5 mr-1" /> Reset to defaults</Button>
<Button variant="outline" onClick={exportAwards} title="Export all award definitions + reference lists to a JSON backup">
<Download className="size-3.5 mr-1" /> Export
</Button>
<Button variant="outline" onClick={importAwards} title="Import an award bundle (definitions + reference lists)">
<Upload className="size-3.5 mr-1" /> Import
</Button>
<div className="flex-1" />
<Button variant="outline" onClick={onClose}>Cancel</Button>
<Button onClick={save}><Save className="size-3.5 mr-1" /> Save</Button>