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:
Chop
2025-07-27 22:01:15 +02:00
parent 9b6307eabe
commit e828aa660b
16 changed files with 1166 additions and 234 deletions

View File

@@ -25,9 +25,9 @@ export default async function ProjectViewPage({ params }) {
<PageContainer>
<Card>
<CardContent className="text-center py-8">
<p className="text-red-600 text-lg">Project not found.</p>
<p className="text-red-600 text-lg">Projekt nie został znaleziony.</p>
<Link href="/projects" className="mt-4 inline-block">
<Button variant="primary">Back to Projects</Button>
<Button variant="primary">Powrót do projektów</Button>
</Link>
</CardContent>
</Card>
@@ -55,10 +55,10 @@ export default async function ProjectViewPage({ params }) {
{daysRemaining !== null && (
<Badge variant={getDeadlineVariant(daysRemaining)} size="md">
{daysRemaining === 0
? "Due Today"
? "Termin dzisiaj"
: daysRemaining > 0
? `${daysRemaining} days left`
: `${Math.abs(daysRemaining)} days overdue`}
? `${daysRemaining} dni pozostało`
: `${Math.abs(daysRemaining)} dni po terminie`}
</Badge>
)}
<Link href="/projects">
@@ -76,7 +76,7 @@ export default async function ProjectViewPage({ params }) {
d="M15 19l-7-7 7-7"
/>
</svg>
Back to Projects
Powrót do projektów
</Button>
</Link>
<Link href={`/projects/${id}/edit`}>
@@ -94,7 +94,7 @@ export default async function ProjectViewPage({ params }) {
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
Edit Project
Edytuj projekt
</Button>
</Link>
</div>
@@ -108,7 +108,7 @@ export default async function ProjectViewPage({ params }) {
{" "}
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">
Project Information
Informacje o projekcie
</h2>
<Badge
variant={
@@ -123,12 +123,12 @@ export default async function ProjectViewPage({ params }) {
size="sm"
>
{project.project_type === "design"
? "Design (P)"
? "Projektowanie (P)"
: project.project_type === "construction"
? "Construction (R)"
? "Realizacja (R)"
: project.project_type === "design+construction"
? "Design + Construction (P+R)"
: "Unknown"}
? "Projektowanie + Realizacja (P+R)"
: "Nieznany"}
</Badge>
</div>
</CardHeader>
@@ -136,7 +136,7 @@ export default async function ProjectViewPage({ params }) {
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Location
Lokalizacja
</span>
<p className="text-gray-900 font-medium">
{project.city || "N/A"}
@@ -144,7 +144,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Address
Adres
</span>
<p className="text-gray-900 font-medium">
{project.address || "N/A"}
@@ -152,7 +152,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Plot
Działka
</span>
<p className="text-gray-900 font-medium">
{project.plot || "N/A"}
@@ -160,7 +160,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
District
Dzielnica
</span>
<p className="text-gray-900 font-medium">
{project.district || "N/A"}
@@ -168,7 +168,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Unit
Jednostka
</span>
<p className="text-gray-900 font-medium">
{project.unit || "N/A"}
@@ -176,7 +176,7 @@ export default async function ProjectViewPage({ params }) {
</div>{" "}
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Deadline
Termin zakończenia
</span>
<p className="text-gray-900 font-medium">
{project.finish_date
@@ -194,7 +194,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Investment Number
Numer inwestycji
</span>
<p className="text-gray-900 font-medium">
{project.investment_number || "N/A"}
@@ -205,7 +205,7 @@ export default async function ProjectViewPage({ params }) {
{project.contact && (
<div className="border-t pt-4">
<span className="text-sm font-medium text-gray-500 block mb-1">
Contact
Kontakt
</span>
<p className="text-gray-900 font-medium">{project.contact}</p>
</div>
@@ -214,7 +214,7 @@ export default async function ProjectViewPage({ params }) {
{project.coordinates && (
<div className="border-t pt-4">
<span className="text-sm font-medium text-gray-500 block mb-1">
Coordinates
Współrzędne
</span>
<p className="text-gray-900 font-medium font-mono text-sm">
{formatCoordinates(project.coordinates)}
@@ -237,14 +237,14 @@ export default async function ProjectViewPage({ params }) {
<Card>
<CardHeader>
<h2 className="text-xl font-semibold text-gray-900">
Contract Details
Szczegóły umowy
</h2>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Contract Number
Numer umowy
</span>
<p className="text-gray-900 font-medium">
{project.contract_number || "N/A"}
@@ -252,7 +252,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Contract Name
Nazwa umowy
</span>
<p className="text-gray-900 font-medium">
{project.contract_name || "N/A"}
@@ -260,7 +260,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Customer
Klient
</span>
<p className="text-gray-900 font-medium">
{project.customer || "N/A"}
@@ -268,7 +268,7 @@ export default async function ProjectViewPage({ params }) {
</div>
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Investor
Inwestor
</span>
<p className="text-gray-900 font-medium">
{project.investor || "N/A"}
@@ -284,21 +284,21 @@ export default async function ProjectViewPage({ params }) {
<Card>
<CardHeader>
<h2 className="text-lg font-semibold text-gray-900">
Project Status
Status projektu
</h2>
</CardHeader>
<CardContent className="space-y-4">
{" "}
<div>
<span className="text-sm font-medium text-gray-500 block mb-2">
Current Status
Aktualny status
</span>
<ProjectStatusDropdown project={project} size="md" />
</div>
{daysRemaining !== null && (
<div className="border-t pt-4">
<span className="text-sm font-medium text-gray-500 block mb-2">
Timeline
Harmonogram
</span>
<div className="text-center">
<Badge
@@ -306,10 +306,10 @@ export default async function ProjectViewPage({ params }) {
size="lg"
>
{daysRemaining === 0
? "Due Today"
? "Termin dzisiaj"
: daysRemaining > 0
? `${daysRemaining} days remaining`
: `${Math.abs(daysRemaining)} days overdue`}
? `${daysRemaining} dni pozostało`
: `${Math.abs(daysRemaining)} dni po terminie`}
</Badge>
</div>
</div>
@@ -321,7 +321,7 @@ export default async function ProjectViewPage({ params }) {
<Card>
<CardHeader>
<h2 className="text-lg font-semibold text-gray-900">
Quick Actions
Szybkie akcje
</h2>
</CardHeader>
<CardContent className="space-y-3">
@@ -344,7 +344,7 @@ export default async function ProjectViewPage({ params }) {
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
Edit Project
Edytuj projekt
</Button>
</Link>{" "}
<Link href="/projects" className="block">
@@ -366,7 +366,7 @@ export default async function ProjectViewPage({ params }) {
d="M15 19l-7-7 7-7"
/>
</svg>
Back to Projects
Powrót do projektów
</Button>
</Link>
<Link href="/projects/map" className="block">
@@ -388,7 +388,7 @@ export default async function ProjectViewPage({ params }) {
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-1.447-.894L15 4m0 13V4m0 0L9 7"
/>
</svg>
View All on Map
Zobacz wszystkie na mapie
</Button>
</Link>
</CardContent>
@@ -404,7 +404,7 @@ export default async function ProjectViewPage({ params }) {
{" "}
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">
Project Location
Lokalizacja projektu
</h2>
{project.coordinates && (
<Link
@@ -428,7 +428,7 @@ export default async function ProjectViewPage({ params }) {
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-1.447-.894L15 4m0 13V4m0 0L9 7"
/>
</svg>
View on Full Map
Zobacz na pełnej mapie
</Button>
</Link>
)}
@@ -454,7 +454,7 @@ export default async function ProjectViewPage({ params }) {
{/* Notes Section */}
<Card>
<CardHeader>
<h2 className="text-xl font-semibold text-gray-900">Notes</h2>
<h2 className="text-xl font-semibold text-gray-900">Notatki</h2>
</CardHeader>
<CardContent>
<div className="mb-6">
@@ -475,10 +475,10 @@ export default async function ProjectViewPage({ params }) {
</svg>
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">
No notes yet
Brak notatek
</h3>
<p className="text-gray-500">
Add your first note using the form above.
Dodaj swoją pierwszą notatkę używając formularza powyżej.
</p>
</div>
) : (