feat: Import Dialog mit 3 Buttons (Ja/Nein/Abbrechen)
Ersetzt zwei aufeinanderfolgende confirm()-Dialoge durch einen Custom Dialog mit drei klaren Optionen: - "Ja, überschreiben" → bestehende Prompts aktualisieren - "Nein, nur neue" → existierende überspringen - "Abbrechen" → Import komplett abbrechen UX-Verbesserung: - Alle Optionen auf einen Blick sichtbar - Kein Raten mehr was "OK" oder "Abbrechen" bedeutet - Klare Beschreibungstexte unter jedem Button - Vollbildschirm-Modal mit Overlay Technisch: - importDialogData State für Dialog-Daten - handleImportChoice verarbeitet yes/no/cancel - Custom Modal-JSX statt Browser confirm() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f3a61091c7
commit
c9357d4c0e
|
|
@ -21,6 +21,7 @@ export default function AdminPromptsPage() {
|
|||
const [showNewPrompt, setShowNewPrompt] = useState(false)
|
||||
const [importing, setImporting] = useState(false)
|
||||
const [importResult, setImportResult] = useState(null)
|
||||
const [importDialogData, setImportDialogData] = useState(null) // {count, fileData, event}
|
||||
|
||||
const categories = [
|
||||
{ id: 'all', label: 'Alle Kategorien' },
|
||||
|
|
@ -194,7 +195,6 @@ export default function AdminPromptsPage() {
|
|||
const file = event.target.files[0]
|
||||
if (!file) return
|
||||
|
||||
setImporting(true)
|
||||
setError(null)
|
||||
setImportResult(null)
|
||||
|
||||
|
|
@ -202,28 +202,34 @@ export default function AdminPromptsPage() {
|
|||
const text = await file.text()
|
||||
const data = JSON.parse(text)
|
||||
|
||||
// Two-step confirmation for clarity
|
||||
// Step 1: Confirm import
|
||||
const shouldImport = confirm(
|
||||
`${data.count || 0} Prompts importieren?\n\n` +
|
||||
'OK = Fortfahren\n' +
|
||||
'Abbrechen = Import abbrechen'
|
||||
)
|
||||
// Show custom 3-button dialog
|
||||
setImportDialogData({
|
||||
count: data.count || 0,
|
||||
fileData: data,
|
||||
event: event
|
||||
})
|
||||
} catch (e) {
|
||||
setError('Import-Fehler: ' + e.message)
|
||||
event.target.value = '' // Reset file input
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldImport) {
|
||||
setImporting(false)
|
||||
event.target.value = ''
|
||||
return
|
||||
}
|
||||
const handleImportChoice = async (choice) => {
|
||||
if (!importDialogData) return
|
||||
|
||||
// Step 2: Ask about overwrite
|
||||
const overwrite = confirm(
|
||||
'Existierende Prompts überschreiben?\n\n' +
|
||||
'OK = Ja, bestehende Prompts aktualisieren\n' +
|
||||
'Abbrechen = Nein, nur neue Prompts erstellen'
|
||||
)
|
||||
const { fileData, event } = importDialogData
|
||||
setImportDialogData(null) // Close dialog
|
||||
|
||||
const result = await api.importPrompts(data, overwrite)
|
||||
if (choice === 'cancel') {
|
||||
event.target.value = '' // Reset file input
|
||||
return
|
||||
}
|
||||
|
||||
setImporting(true)
|
||||
|
||||
try {
|
||||
const overwrite = choice === 'yes' // 'yes' = overwrite, 'no' = skip existing
|
||||
const result = await api.importPrompts(fileData, overwrite)
|
||||
setImportResult(result)
|
||||
await loadPrompts()
|
||||
} catch (e) {
|
||||
|
|
@ -621,6 +627,70 @@ export default function AdminPromptsPage() {
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Import Dialog - 3 Button Choice */}
|
||||
{importDialogData && (
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: 'rgba(0,0,0,0.5)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
zIndex: 9999
|
||||
}}>
|
||||
<div style={{
|
||||
background: 'var(--bg)',
|
||||
borderRadius: 12,
|
||||
padding: 24,
|
||||
maxWidth: 500,
|
||||
width: '90%',
|
||||
boxShadow: '0 4px 20px rgba(0,0,0,0.2)'
|
||||
}}>
|
||||
<h3 style={{ marginTop: 0, marginBottom: 16, fontSize: 18 }}>
|
||||
{importDialogData.count} Prompts importieren?
|
||||
</h3>
|
||||
<p style={{ marginBottom: 24, color: 'var(--text2)', lineHeight: 1.5 }}>
|
||||
Wie sollen existierende Prompts behandelt werden?
|
||||
</p>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => handleImportChoice('yes')}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
Ja, überschreiben
|
||||
<div style={{ fontSize: 12, opacity: 0.8, marginTop: 4 }}>
|
||||
Bestehende Prompts aktualisieren
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="btn"
|
||||
onClick={() => handleImportChoice('no')}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
Nein, nur neue
|
||||
<div style={{ fontSize: 12, opacity: 0.8, marginTop: 4 }}>
|
||||
Nur neue Prompts erstellen, bestehende überspringen
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
onClick={() => handleImportChoice('cancel')}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user