Add create modal for words and pictures tables
- + Button in TableView for tables with a create form (words, pictures) - Words: form with titel_de/en/sv + difficulty_level → POST /words - Pictures: design field + image uploader → POST /pictures then POST /pictures/:id/upload - Image drag-drop area with preview before upload, sends multipart to Hetzner via API - New record prepended to table on success - apiPost + apiUpload helpers added to api.js Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { useEffect, useState, useMemo } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import Layout from '../components/Layout';
|
||||
import RecordModal from '../components/RecordModal';
|
||||
import CreateModal, { hasCreateForm } from '../components/CreateModal';
|
||||
import { fetchAll } from '../lib/api';
|
||||
import { TABLES, STATUS_COLORS } from '../lib/tables';
|
||||
|
||||
@@ -86,6 +87,7 @@ export default function TableView() {
|
||||
const [textFilter, setTextFilter] = useState('');
|
||||
const [highlightId, setHighlightId] = useState(null);
|
||||
const [modalRecord, setModalRecord] = useState(null);
|
||||
const [showCreate, setShowCreate] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
@@ -124,6 +126,10 @@ export default function TableView() {
|
||||
setRows(prev => prev.map(r => (r.id === updated.id ? { ...r, ...updated } : r)));
|
||||
}
|
||||
|
||||
function handleRecordCreated(newRecord) {
|
||||
setRows(prev => [newRecord, ...prev]);
|
||||
}
|
||||
|
||||
if (!meta) return <Layout back="/db"><p className="text-red-500">Unbekannte Tabelle: {tableKey}</p></Layout>;
|
||||
|
||||
return (
|
||||
@@ -135,6 +141,14 @@ export default function TableView() {
|
||||
({filtered.length}{rows.length === 500 ? '+' : ''} von {rows.length}{rows.length === 500 ? '+' : ''})
|
||||
</span>
|
||||
</h2>
|
||||
{hasCreateForm(tableKey) && (
|
||||
<button
|
||||
onClick={() => setShowCreate(true)}
|
||||
className="flex items-center gap-1.5 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-medium px-3 py-1.5 rounded-lg transition-colors"
|
||||
>
|
||||
<span className="text-lg leading-none">+</span> Neu
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Filters */}
|
||||
@@ -226,6 +240,15 @@ export default function TableView() {
|
||||
onSaved={handleRecordSaved}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showCreate && (
|
||||
<CreateModal
|
||||
tableKey={tableKey}
|
||||
meta={meta}
|
||||
onClose={() => setShowCreate(false)}
|
||||
onCreated={handleRecordCreated}
|
||||
/>
|
||||
)}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user