Add dictionary feature with term management and UI components

- Implement backend API for term CRUD operations
- Add frontend dictionary page with search and filtering
- Integrate shadcn/ui components (Dialog)
- Create term management UI with add/edit/delete functionality
- Update database seed with initial terms
- Add API client for term operations
- Complete Phase 2 of development plan
This commit is contained in:
2026-01-17 18:15:01 +01:00
parent bbf143a3b4
commit c6d6c18466
21 changed files with 1757 additions and 176 deletions

View File

@@ -0,0 +1,99 @@
import { useState, useEffect } from 'react';
import { Layout } from '../components/layout/Layout';
import { FilterBar } from '../components/dictionary/FilterBar';
import { WordGrid } from '../components/dictionary/WordGrid';
import { WordDetailModal } from '../components/dictionary/WordDetailModal';
import { Term, TermFilters } from '../types/term';
import { fetchTerms } from '../lib/termApi';
function Dictionary() {
const [terms, setTerms] = useState<Term[]>([]);
const [loading, setLoading] = useState(true);
const [selectedTerm, setSelectedTerm] = useState<Term | null>(null);
const [filters, setFilters] = useState<TermFilters>({
query: '',
wordType: '',
cefrLevel: '',
page: 1,
limit: 20,
});
const [pagination, setPagination] = useState({
page: 1,
limit: 20,
total: 0,
totalPages: 0,
});
useEffect(() => {
loadTerms();
}, [filters]);
const loadTerms = async () => {
try {
setLoading(true);
const response = await fetchTerms(filters);
setTerms(response.terms);
setPagination(response.pagination);
} catch (error) {
console.error('Failed to load terms:', error);
} finally {
setLoading(false);
}
};
const handleFilterChange = (newFilters: TermFilters) => {
setFilters(newFilters);
};
const handlePageChange = (page: number) => {
setFilters({ ...filters, page });
};
const handleTermInfo = (term: Term) => {
setSelectedTerm(term);
};
const handleAddToSentence = (term: Term) => {
// TODO: Implement in Phase 3 (Znakopis)
console.log('Add to sentence:', term);
alert(`Dodavanje riječi "${term.wordText}" u rečenicu će biti implementirano u fazi 3.`);
};
return (
<Layout>
<div className="space-y-6">
{/* Header */}
<div>
<h1 className="text-3xl font-bold text-gray-900 mb-2">Rječnik</h1>
<p className="text-gray-600">
Pretražite i pregledajte hrvatski znakovni jezik
</p>
</div>
{/* Filters */}
<FilterBar filters={filters} onFilterChange={handleFilterChange} />
{/* Word Grid */}
<WordGrid
terms={terms}
loading={loading}
onInfo={handleTermInfo}
onAddToSentence={handleAddToSentence}
pagination={pagination}
onPageChange={handlePageChange}
/>
{/* Word Detail Modal */}
<WordDetailModal
term={selectedTerm}
open={!!selectedTerm}
onClose={() => setSelectedTerm(null)}
onAddToSentence={handleAddToSentence}
/>
</div>
</Layout>
);
}
export default Dictionary;