diff --git a/packages/frontend/src/components/dictionary/WordCard.tsx b/packages/frontend/src/components/dictionary/WordCard.tsx index 3404905..1355f5a 100644 --- a/packages/frontend/src/components/dictionary/WordCard.tsx +++ b/packages/frontend/src/components/dictionary/WordCard.tsx @@ -1,6 +1,7 @@ import { Info, Plus } from 'lucide-react'; import { Term, CefrLevel } from '../../types/term'; import { Button } from '../ui/button'; +import { wordTypeColors, wordTypeLabels } from '../../lib/wordTypeColors'; interface WordCardProps { term: Term; @@ -17,32 +18,6 @@ const cefrColors: Record = { [CefrLevel.C2]: 'bg-red-500', }; -const wordTypeColors: Record = { - NOUN: 'bg-green-600', // Imenica - zelena - VERB: 'bg-red-600', // Glagol - crvena - ADJECTIVE: 'bg-blue-600', // Pridjev - plava - ADVERB: 'bg-purple-600', // Prilog - ljubičasta - PRONOUN: 'bg-yellow-600', // Zamjenica - žuta - PREPOSITION: 'bg-orange-600', // Prijedlog - narančasta - CONJUNCTION: 'bg-pink-600', // Veznik - roza - INTERJECTION: 'bg-teal-600', // Uzvik - tirkizna - PHRASE: 'bg-indigo-600', // Fraza - indigo - OTHER: 'bg-gray-600', // Ostalo - siva -}; - -const wordTypeLabels: Record = { - NOUN: 'Imenica', - VERB: 'Glagol', - ADJECTIVE: 'Pridjev', - ADVERB: 'Prilog', - PRONOUN: 'Zamjenica', - PREPOSITION: 'Prijedlog', - CONJUNCTION: 'Veznik', - INTERJECTION: 'Uzvik', - PHRASE: 'Fraza', - OTHER: 'Ostalo', -}; - export function WordCard({ term, onInfo, onAddToSentence }: WordCardProps) { const videoMedia = term.media?.find(m => m.kind === 'VIDEO'); const imageMedia = term.media?.find(m => m.kind === 'IMAGE' || m.kind === 'ILLUSTRATION'); diff --git a/packages/frontend/src/components/layout/Layout.tsx b/packages/frontend/src/components/layout/Layout.tsx index d0b0d89..83cef2d 100644 --- a/packages/frontend/src/components/layout/Layout.tsx +++ b/packages/frontend/src/components/layout/Layout.tsx @@ -1,15 +1,26 @@ import { ReactNode } from 'react'; import { Sidebar } from './Sidebar'; +import { TokenTray } from '../znakopis/TokenTray'; +import { useSentenceStore } from '../../stores/sentenceStore'; interface LayoutProps { children: ReactNode; } export function Layout({ children }: LayoutProps) { + const { currentTokens } = useSentenceStore(); + return (
+ {/* Global TokenTray - sticky at top when tokens exist */} + {currentTokens.length > 0 && ( +
+ +
+ )} +
{children}
diff --git a/packages/frontend/src/components/znakopis/SortableToken.tsx b/packages/frontend/src/components/znakopis/SortableToken.tsx index 017de8e..5e8eb00 100644 --- a/packages/frontend/src/components/znakopis/SortableToken.tsx +++ b/packages/frontend/src/components/znakopis/SortableToken.tsx @@ -2,26 +2,13 @@ import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { X, GripVertical } from 'lucide-react'; import { SentenceToken } from '../../stores/sentenceStore'; -import { Button } from '../ui/button'; +import { wordTypeColors } from '../../lib/wordTypeColors'; interface SortableTokenProps { token: SentenceToken; onRemove: (tokenId: string) => void; } -const wordTypeColors: Record = { - NOUN: 'bg-green-600', - VERB: 'bg-red-600', - ADJECTIVE: 'bg-blue-600', - ADVERB: 'bg-purple-600', - PRONOUN: 'bg-yellow-600', - PREPOSITION: 'bg-orange-600', - CONJUNCTION: 'bg-pink-600', - INTERJECTION: 'bg-teal-600', - PHRASE: 'bg-indigo-600', - OTHER: 'bg-gray-600', -}; - export function SortableToken({ token, onRemove }: SortableTokenProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: token.id, diff --git a/packages/frontend/src/components/znakopis/TokenTray.tsx b/packages/frontend/src/components/znakopis/TokenTray.tsx index 3f12146..32d8c31 100644 --- a/packages/frontend/src/components/znakopis/TokenTray.tsx +++ b/packages/frontend/src/components/znakopis/TokenTray.tsx @@ -5,7 +5,11 @@ import { SortableToken } from './SortableToken'; import { X } from 'lucide-react'; import { Button } from '../ui/button'; -export function TokenTray() { +interface TokenTrayProps { + compact?: boolean; +} + +export function TokenTray({ compact = false }: TokenTrayProps) { const { currentTokens, reorderTokens, removeToken, clearTokens } = useSentenceStore(); const sensors = useSensors( @@ -27,10 +31,21 @@ export function TokenTray() { } }; + // Conditional styling based on compact mode + const containerClass = compact + ? "bg-white rounded-lg shadow-sm p-3" + : "bg-white rounded-lg shadow p-6"; + + const headerClass = compact + ? "text-lg font-semibold text-gray-900" + : "text-xl font-semibold text-gray-900"; + + const gapClass = compact ? "gap-2" : "gap-3"; + return ( -
-
-

Trenutna rečenica

+
+
+

Trenutna rečenica

{currentTokens.length > 0 && (
{currentTokens.length === 0 ? ( -
-

Nema riječi u rečenici

-

Idite na Rječnik i dodajte riječi klikom na "Dodaj"

-
+ !compact && ( +
+

Nema riječi u rečenici

+

Idite na Rječnik i dodajte riječi klikom na "Dodaj"

+
+ ) ) : ( t.id)} strategy={horizontalListSortingStrategy}> -
+
{currentTokens.map((token) => ( ))} @@ -56,7 +73,7 @@ export function TokenTray() { )} - {currentTokens.length > 0 && ( + {currentTokens.length > 0 && !compact && (

Savjet: Povucite i ispustite riječi za promjenu redoslijeda. Kliknite "Spremi" za spremanje rečenice u dokument. diff --git a/packages/frontend/src/lib/wordTypeColors.ts b/packages/frontend/src/lib/wordTypeColors.ts new file mode 100644 index 0000000..19d42f9 --- /dev/null +++ b/packages/frontend/src/lib/wordTypeColors.ts @@ -0,0 +1,31 @@ +/** + * Shared color scheme for word types across the application. + * Used in WordCard, SortableToken, and other components that display word types. + */ + +export const wordTypeColors: Record = { + NOUN: 'bg-green-600', // Imenica - zelena + VERB: 'bg-red-600', // Glagol - crvena + ADJECTIVE: 'bg-blue-600', // Pridjev - plava + ADVERB: 'bg-purple-600', // Prilog - ljubičasta + PRONOUN: 'bg-yellow-600', // Zamjenica - žuta + PREPOSITION: 'bg-orange-600', // Prijedlog - narančasta + CONJUNCTION: 'bg-pink-600', // Veznik - roza + INTERJECTION: 'bg-teal-600', // Uzvik - tirkizna + PHRASE: 'bg-indigo-600', // Fraza - indigo + OTHER: 'bg-gray-600', // Ostalo - siva +}; + +export const wordTypeLabels: Record = { + NOUN: 'Imenica', + VERB: 'Glagol', + ADJECTIVE: 'Pridjev', + ADVERB: 'Prilog', + PRONOUN: 'Zamjenica', + PREPOSITION: 'Prijedlog', + CONJUNCTION: 'Veznik', + INTERJECTION: 'Uzvik', + PHRASE: 'Fraza', + OTHER: 'Ostalo', +}; + diff --git a/packages/frontend/src/pages/Znakopis.tsx b/packages/frontend/src/pages/Znakopis.tsx index c4a476e..a52d9f8 100644 --- a/packages/frontend/src/pages/Znakopis.tsx +++ b/packages/frontend/src/pages/Znakopis.tsx @@ -6,7 +6,7 @@ import { useSentenceStore } from '../stores/sentenceStore'; import { documentApi, Document } from '../lib/documentApi'; import { toast } from 'sonner'; import { Button } from '../components/ui/button'; -import { Save, FileText, Plus } from 'lucide-react'; +import { Save, FileText } from 'lucide-react'; function Znakopis() { const { currentTokens, clearTokens } = useSentenceStore(); @@ -166,9 +166,9 @@ function Znakopis() { {/* Two-column layout */}

- {/* Left: Token Tray (2/3 width) */} + {/* Left: Token Tray (2/3 width) - Full version for editing */}
- +
{/* Right: Document Panel (1/3 width) */}