feat(i18n): Implement multilingual support with Polish and English translations
- Added translation context and provider for managing language state. - Integrated translation functionality into existing components (TaskStatusDropdown, Navigation). - Created LanguageSwitcher component for language selection. - Updated task statuses and navigation labels to use translations. - Added Polish translations for various UI elements, including navigation, tasks, projects, and contracts. - Refactored utility functions to return localized strings for deadlines and date formatting.
This commit is contained in:
@@ -11,8 +11,10 @@ import PageHeader from "@/components/ui/PageHeader";
|
||||
import SearchBar from "@/components/ui/SearchBar";
|
||||
import { LoadingState } from "@/components/ui/States";
|
||||
import { formatDate } from "@/lib/utils";
|
||||
import { useTranslation } from "@/lib/i18n";
|
||||
|
||||
export default function ProjectListPage() {
|
||||
const { t } = useTranslation();
|
||||
const [projects, setProjects] = useState([]);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [filteredProjects, setFilteredProjects] = useState([]);
|
||||
@@ -45,7 +47,7 @@ export default function ProjectListPage() {
|
||||
}, [searchTerm, projects]);
|
||||
|
||||
async function handleDelete(id) {
|
||||
const confirmed = confirm("Are you sure you want to delete this project?");
|
||||
const confirmed = confirm(t('projects.deleteConfirm'));
|
||||
if (!confirmed) return;
|
||||
|
||||
const res = await fetch(`/api/projects/${id}`, {
|
||||
@@ -61,7 +63,7 @@ export default function ProjectListPage() {
|
||||
};
|
||||
return (
|
||||
<PageContainer>
|
||||
<PageHeader title="Projects" description="Manage and track your projects">
|
||||
<PageHeader title={t('projects.title')} description={t('projects.subtitle')}>
|
||||
<div className="flex gap-2">
|
||||
<Link href="/projects/map">
|
||||
<Button variant="outline" size="lg">
|
||||
@@ -78,7 +80,7 @@ export default function ProjectListPage() {
|
||||
d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
|
||||
/>
|
||||
</svg>
|
||||
Map View
|
||||
Widok mapy
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="/projects/new">
|
||||
@@ -96,7 +98,7 @@ export default function ProjectListPage() {
|
||||
d="M12 4v16m8-8H4"
|
||||
/>
|
||||
</svg>
|
||||
Add Project
|
||||
{t('projects.newProject')}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
@@ -105,9 +107,9 @@ export default function ProjectListPage() {
|
||||
<SearchBar
|
||||
searchTerm={searchTerm}
|
||||
onSearchChange={handleSearchChange}
|
||||
placeholder="Search by project name, WP, plot, or investment number..."
|
||||
placeholder={t('projects.searchPlaceholder')}
|
||||
resultsCount={filteredProjects.length}
|
||||
resultsText="projects"
|
||||
resultsText="projektów"
|
||||
/>
|
||||
{filteredProjects.length === 0 && searchTerm ? (
|
||||
<Card>
|
||||
@@ -126,14 +128,13 @@ export default function ProjectListPage() {
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||
No projects found
|
||||
{t('common.noResults')}
|
||||
</h3>
|
||||
<p className="text-gray-500 mb-6">
|
||||
No projects match your search criteria. Try adjusting your search
|
||||
terms.
|
||||
Brak projektów pasujących do kryteriów wyszukiwania. Spróbuj zmienić wyszukiwane frazy.
|
||||
</p>
|
||||
<Button variant="outline" onClick={() => setSearchTerm("")}>
|
||||
Clear Search
|
||||
Wyczyść wyszukiwanie
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -154,13 +155,13 @@ export default function ProjectListPage() {
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||
No projects yet
|
||||
{t('projects.noProjects')}
|
||||
</h3>
|
||||
<p className="text-gray-500 mb-6">
|
||||
Get started by creating your first project
|
||||
{t('projects.noProjectsMessage')}
|
||||
</p>
|
||||
<Link href="/projects/new">
|
||||
<Button variant="primary">Create First Project</Button>
|
||||
<Button variant="primary">Utwórz pierwszy projekt</Button>
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -170,34 +171,34 @@ export default function ProjectListPage() {
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-32">
|
||||
No.
|
||||
Nr.
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700">
|
||||
Project Name
|
||||
{t('projects.projectName')}
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-40">
|
||||
WP
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-20">
|
||||
City
|
||||
{t('projects.city')}
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-40">
|
||||
Address
|
||||
{t('projects.address')}
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-20">
|
||||
Plot
|
||||
{t('projects.plot')}
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-24">
|
||||
Finish
|
||||
{t('projects.finishDate')}
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-12">
|
||||
Type
|
||||
Typ
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-24">
|
||||
Status
|
||||
</th>
|
||||
<th className="text-left px-2 py-3 font-semibold text-xs text-gray-700 w-20">
|
||||
Actions
|
||||
Akcje
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -282,7 +283,7 @@ export default function ProjectListPage() {
|
||||
size="sm"
|
||||
className="text-xs px-2 py-1"
|
||||
>
|
||||
View
|
||||
Wyświetl
|
||||
</Button>
|
||||
</Link>
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user