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:
99
packages/frontend/src/pages/Dictionary.tsx
Normal file
99
packages/frontend/src/pages/Dictionary.tsx
Normal 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;
|
||||
|
||||
Reference in New Issue
Block a user