Add Znakopis feature with document and sentence management

- Implemented Znakopis page with document and sentence CRUD operations
- Added backend routes for documents and sentences
- Created UI components for sentence editing and display
- Added sentence store for state management
- Integrated select component for document selection
- Updated README with Phase 3 completion status
- Removed obsolete fix-colors.md file
This commit is contained in:
2026-01-17 18:50:53 +01:00
parent 2b768d4c13
commit 8bdd4f6368
17 changed files with 1654 additions and 190 deletions

View File

@@ -0,0 +1,69 @@
import { useSentenceStore } from '../../stores/sentenceStore';
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent } from '@dnd-kit/core';
import { arrayMove, SortableContext, sortableKeyboardCoordinates, horizontalListSortingStrategy } from '@dnd-kit/sortable';
import { SortableToken } from './SortableToken';
import { X } from 'lucide-react';
import { Button } from '../ui/button';
export function TokenTray() {
const { currentTokens, reorderTokens, removeToken, clearTokens } = useSentenceStore();
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
if (over && active.id !== over.id) {
const oldIndex = currentTokens.findIndex((token) => token.id === active.id);
const newIndex = currentTokens.findIndex((token) => token.id === over.id);
const newTokens = arrayMove(currentTokens, oldIndex, newIndex);
reorderTokens(newTokens);
}
};
return (
<div className="bg-white rounded-lg shadow p-6">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-semibold text-gray-900">Trenutna rečenica</h2>
{currentTokens.length > 0 && (
<Button variant="outline" size="sm" onClick={clearTokens}>
<X className="h-4 w-4 mr-1" />
Očisti sve
</Button>
)}
</div>
{currentTokens.length === 0 ? (
<div className="text-center py-12 text-gray-500">
<p className="text-lg mb-2">Nema riječi u rečenici</p>
<p className="text-sm">Idite na Rječnik i dodajte riječi klikom na "Dodaj"</p>
</div>
) : (
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<SortableContext items={currentTokens.map((t) => t.id)} strategy={horizontalListSortingStrategy}>
<div className="flex flex-wrap gap-3">
{currentTokens.map((token) => (
<SortableToken key={token.id} token={token} onRemove={removeToken} />
))}
</div>
</SortableContext>
</DndContext>
)}
{currentTokens.length > 0 && (
<div className="mt-6 p-4 bg-blue-50 rounded-lg">
<p className="text-sm text-blue-900">
<strong>Savjet:</strong> Povucite i ispustite riječi za promjenu redoslijeda. Kliknite "Spremi" za spremanje rečenice u dokument.
</p>
</div>
)}
</div>
);
}