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

@@ -6,8 +6,10 @@ import { Card, CardHeader, CardContent } from "@/components/ui/Card";
import Button from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { formatDateForInput } from "@/lib/utils";
import { useTranslation } from "@/lib/i18n";
export default function ProjectForm({ initialData = null }) {
const { t } = useTranslation();
const [form, setForm] = useState({
contract_id: "",
project_name: "",
@@ -146,7 +148,7 @@ export default function ProjectForm({ initialData = null }) {
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Project Type <span className="text-red-500">*</span>
Typ projektu <span className="text-red-500">*</span>
</label>
<select
name="project_type"
@@ -155,17 +157,17 @@ export default function ProjectForm({ initialData = null }) {
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required
>
<option value="design">Design (Projektowanie)</option>
<option value="construction">Construction (Realizacja)</option>
<option value="design">{t('projectType.design')}</option>
<option value="construction">{t('projectType.construction')}</option>
<option value="design+construction">
Design + Construction (Projektowanie + Realizacja)
{t('projectType.design+construction')}
</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Assigned To
{t('projects.assignedTo')}
</label>
<select
name="assigned_to"
@@ -173,7 +175,7 @@ export default function ProjectForm({ initialData = null }) {
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
>
<option value="">Unassigned</option>
<option value="">{t('projects.unassigned')}</option>
{users.map((user) => (
<option key={user.id} value={user.id}>
{user.name} ({user.email})
@@ -186,92 +188,92 @@ export default function ProjectForm({ initialData = null }) {
{/* Basic Information Section */}
<div className="border-t pt-6">
<h3 className="text-lg font-medium text-gray-900 mb-4">
Basic Information
{t('projects.basicInformation')}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-2">
Project Name <span className="text-red-500">*</span>
{t('projects.projectName')} <span className="text-red-500">*</span>
</label>
<Input
type="text"
name="project_name"
value={form.project_name || ""}
onChange={handleChange}
placeholder="Enter project name"
placeholder={t('projects.enterProjectName')}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
City
{t('projects.city')}
</label>
<Input
type="text"
name="city"
value={form.city || ""}
onChange={handleChange}
placeholder="Enter city"
placeholder={t('projects.enterCity')}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Address
{t('projects.address')}
</label>
<Input
type="text"
name="address"
value={form.address || ""}
onChange={handleChange}
placeholder="Enter address"
placeholder={t('projects.enterAddress')}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Plot
{t('projects.plot')}
</label>
<Input
type="text"
name="plot"
value={form.plot || ""}
onChange={handleChange}
placeholder="Enter plot number"
placeholder={t('projects.enterPlotNumber')}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
District
{t('projects.district')}
</label>
<Input
type="text"
name="district"
value={form.district || ""}
onChange={handleChange}
placeholder="Enter district"
placeholder={t('projects.enterDistrict')}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Unit
{t('projects.unit')}
</label>
<Input
type="text"
name="unit"
value={form.unit || ""}
onChange={handleChange}
placeholder="Enter unit"
placeholder={t('projects.enterUnit')}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Finish Date
</label>{" "}
{t('projects.finishDate')}
</label>
<Input
type="date"
name="finish_date"
@@ -316,33 +318,33 @@ export default function ProjectForm({ initialData = null }) {
<div className="md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-2">
Contact Information
{t('projects.contact')}
</label>
<Input
type="text"
name="contact"
value={form.contact || ""}
onChange={handleChange}
placeholder="Enter contact details"
placeholder={t('projects.placeholders.contact')}
/>
</div>
<div className="md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-2">
Coordinates
{t('projects.coordinates')}
</label>
<Input
type="text"
name="coordinates"
value={form.coordinates || ""}
onChange={handleChange}
placeholder="e.g., 49.622958,20.629562"
placeholder={t('projects.placeholders.coordinates')}
/>
</div>
<div className="md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-2">
Notes
{t('projects.notes')}
</label>
<textarea
name="notes"
@@ -350,7 +352,7 @@ export default function ProjectForm({ initialData = null }) {
onChange={handleChange}
rows={4}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
placeholder="Enter any additional notes"
placeholder={t('projects.placeholders.notes')}
/>
</div>
</div>
@@ -364,7 +366,7 @@ export default function ProjectForm({ initialData = null }) {
onClick={() => router.back()}
disabled={loading}
>
Cancel
{t('common.cancel')}
</Button>
<Button type="submit" variant="primary" disabled={loading}>
{loading ? (
@@ -389,7 +391,7 @@ export default function ProjectForm({ initialData = null }) {
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
{isEdit ? "Updating..." : "Creating..."}
{isEdit ? t('projects.updating') : t('projects.creating')}
</>
) : (
<>
@@ -408,7 +410,7 @@ export default function ProjectForm({ initialData = null }) {
d="M5 13l4 4L19 7"
/>
</svg>
Update Project
{t('projects.updateProject')}
</>
) : (
<>
@@ -425,7 +427,7 @@ export default function ProjectForm({ initialData = null }) {
d="M12 4v16m8-8H4"
/>
</svg>
Create Project
{t('projects.createProject')}
</>
)}
</>