feat: Content Verwaltung — ContentHub + Object Creation
Adds a full Content Management section:
- Nav link "Content" in header (all pages)
- ContentHub at /content with 3 tiles (Object/Statement/Content Creation)
- ObjectCreation at /content/objects:
- Top bar: ← → pagination through all "uploaded" pictures
- Left panel (1/5): existing objects per picture with their words, + button to start draw mode
- Center: image on dark bg with canvas overlay for polygon drawing
- Right words panel (1/5): picture words + new object words (each with search/create)
- Right toolbar (1/5): draw instructions, "Auswahl hinzufügen", numbered selections list, "Objekt speichern" (requires ≥1 selection + ≥1 object word)
- Canvas drawing: click=add point, dblclick=close polygon, live preview line to mouse cursor
- Selections stored as [{points:[{x,y},...]}] (relative 0-1 coords) in objects.selections JSONB
- Object saved with status "draft", linked picture + words
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
64
src/pages/ContentHub.jsx
Normal file
64
src/pages/ContentHub.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Layout from '../components/Layout';
|
||||
|
||||
const TOOLS = [
|
||||
{
|
||||
key: 'objects',
|
||||
title: 'Object Creation',
|
||||
icon: '🖼️',
|
||||
description: 'Bilder durchblättern, Bereiche einzeichnen und Objekte mit Wörtern verknüpfen.',
|
||||
path: '/content/objects',
|
||||
ready: true,
|
||||
},
|
||||
{
|
||||
key: 'statements',
|
||||
title: 'Statement Creation',
|
||||
icon: '💬',
|
||||
description: 'Aussagen erstellen und mit Wörtern verknüpfen.',
|
||||
path: '/content/statements',
|
||||
ready: false,
|
||||
},
|
||||
{
|
||||
key: 'content',
|
||||
title: 'Content Creation',
|
||||
icon: '✨',
|
||||
description: 'Inhalte zusammenstellen und veröffentlichen.',
|
||||
path: '/content/creation',
|
||||
ready: false,
|
||||
},
|
||||
];
|
||||
|
||||
export default function ContentHub() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Layout back="/">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<h1 className="text-2xl font-bold text-slate-800 mb-2">Content Verwaltung</h1>
|
||||
<p className="text-slate-500 mb-8">Wähle ein Tool um loszulegen.</p>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-5">
|
||||
{TOOLS.map(tool => (
|
||||
<button
|
||||
key={tool.key}
|
||||
onClick={() => tool.ready && navigate(tool.path)}
|
||||
className={`text-left rounded-2xl p-6 shadow-sm border transition-all
|
||||
${tool.ready
|
||||
? 'bg-white border-slate-200 hover:shadow-md hover:border-indigo-300 cursor-pointer'
|
||||
: 'bg-slate-50 border-slate-100 opacity-50 cursor-not-allowed'
|
||||
}`}
|
||||
>
|
||||
<div className="text-3xl mb-3">{tool.icon}</div>
|
||||
<h2 className="font-semibold text-slate-800 mb-1">{tool.title}</h2>
|
||||
<p className="text-sm text-slate-500">{tool.description}</p>
|
||||
{!tool.ready && (
|
||||
<span className="inline-block mt-3 text-xs bg-slate-200 text-slate-500 rounded-full px-2 py-0.5">
|
||||
Bald verfügbar
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user