feat(ui): add cv application frontend and configuration
This commit is contained in:
104
src/admin/components/ExportButton.jsx
Normal file
104
src/admin/components/ExportButton.jsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Download, Upload, Eye, RotateCcw, FileJson } from 'lucide-react';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
export default function ExportButton({ onExport, onImport, onReset }) {
|
||||
const fileInputRef = useRef(null);
|
||||
const [showInstructions, setShowInstructions] = useState(false);
|
||||
|
||||
const handleImport = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const result = onImport(event.target.result);
|
||||
if (result.success) {
|
||||
alert('Import erfolgreich!');
|
||||
} else {
|
||||
alert(`Import fehlgeschlagen: ${result.error}`);
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
onExport();
|
||||
setShowInstructions(true);
|
||||
}}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
|
||||
>
|
||||
<Download size={18} />
|
||||
JSON Export
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 transition-colors"
|
||||
>
|
||||
<Upload size={18} />
|
||||
JSON Import
|
||||
</button>
|
||||
|
||||
<a
|
||||
href="/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 transition-colors"
|
||||
>
|
||||
<Eye size={18} />
|
||||
Vorschau
|
||||
</a>
|
||||
|
||||
{onReset && (
|
||||
<button
|
||||
onClick={() => {
|
||||
if (confirm('Alle Änderungen zurücksetzen?')) {
|
||||
onReset();
|
||||
}
|
||||
}}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-red-50 text-red-600 rounded-lg hover:bg-red-100 transition-colors"
|
||||
>
|
||||
<RotateCcw size={18} />
|
||||
Zurücksetzen
|
||||
</button>
|
||||
)}
|
||||
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept=".json"
|
||||
onChange={handleImport}
|
||||
className="hidden"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{showInstructions && (
|
||||
<div className="p-4 bg-amber-50 border border-amber-200 rounded-lg">
|
||||
<div className="flex items-start gap-3">
|
||||
<FileJson className="text-amber-600 flex-shrink-0" size={20} />
|
||||
<div>
|
||||
<h3 className="font-medium text-amber-800 mb-2">Deployment Instructions</h3>
|
||||
<ol className="text-sm text-amber-700 space-y-1 list-decimal list-inside">
|
||||
<li>JSON Datei wurde heruntergeladen</li>
|
||||
<li>Inhalt der <code className="bg-amber-100 px-1 rounded">cv.json</code> kopieren</li>
|
||||
<li>In <code className="bg-amber-100 px-1 rounded">src/data/cv.js</code> einfügen</li>
|
||||
<li>Committen und pushen: <code className="bg-amber-100 px-1 rounded">git add . && git commit -m "update cv" && git push</code></li>
|
||||
<li>GitHub Actions deployt automatisch</li>
|
||||
</ol>
|
||||
<button
|
||||
onClick={() => setShowInstructions(false)}
|
||||
className="mt-3 text-sm text-amber-600 hover:text-amber-800"
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user