- Implemented ContactForm component for creating and editing contacts. - Added ProjectContactSelector component to manage project-specific contacts. - Updated ProjectForm to include ProjectContactSelector for associating contacts with projects. - Enhanced Card component with a new CardTitle subcomponent for better structure. - Updated Navigation to include a link to the contacts page. - Added translations for contact-related terms in the i18n module. - Initialized contacts database schema and created necessary tables for contact management. - Developed queries for CRUD operations on contacts, including linking and unlinking contacts to projects. - Created a test script to validate contact queries against the database.
1276 lines
42 KiB
JavaScript
1276 lines
42 KiB
JavaScript
"use client";
|
|
|
|
import { createContext, useContext, useState, useEffect } from 'react';
|
|
|
|
// Translation context
|
|
const TranslationContext = createContext();
|
|
|
|
// Translation data
|
|
const translations = {
|
|
pl: {
|
|
// Navigation
|
|
navigation: {
|
|
dashboard: "Panel główny",
|
|
projects: "Projekty",
|
|
contacts: "Kontakty",
|
|
calendar: "Kalendarz",
|
|
taskTemplates: "Szablony zadań",
|
|
projectTasks: "Zadania projektów",
|
|
tasks: "Zadania",
|
|
contracts: "Umowy",
|
|
userManagement: "Zarządzanie użytkownikami",
|
|
projectPanel: "eProjektant",
|
|
loading: "Ładowanie...",
|
|
signOut: "Wyloguj się",
|
|
signIn: "Zaloguj się"
|
|
},
|
|
|
|
// Notifications
|
|
notifications: {
|
|
title: "Powiadomienia",
|
|
noNotifications: "Brak powiadomień",
|
|
placeholder: "To jest miejsce na przyszłe powiadomienia",
|
|
markAllRead: "Oznacz wszystkie jako przeczytane",
|
|
loading: "Ładowanie...",
|
|
justNow: "Przed chwilą"
|
|
},
|
|
|
|
// Common UI elements
|
|
common: {
|
|
save: "Zapisz",
|
|
cancel: "Anuluj",
|
|
delete: "Usuń",
|
|
edit: "Edytuj",
|
|
add: "Dodaj",
|
|
create: "Utwórz",
|
|
update: "Aktualizuj",
|
|
search: "Szukaj",
|
|
filter: "Filtruj",
|
|
loading: "Ładowanie...",
|
|
saving: "Zapisywanie...",
|
|
creating: "Tworzenie...",
|
|
updating: "Aktualizowanie...",
|
|
yes: "Tak",
|
|
no: "Nie",
|
|
confirm: "Potwierdź",
|
|
close: "Zamknij",
|
|
back: "Wstecz",
|
|
next: "Dalej",
|
|
previous: "Poprzedni",
|
|
page: "Strona",
|
|
of: "z",
|
|
items: "pozycji",
|
|
all: "Wszystkie",
|
|
none: "Brak",
|
|
required: "wymagane",
|
|
optional: "opcjonalne",
|
|
selectOption: "Wybierz opcję",
|
|
selectLanguage: "Wybierz język",
|
|
noResults: "Brak wyników",
|
|
error: "Błąd",
|
|
success: "Sukces",
|
|
warning: "Ostrzeżenie",
|
|
info: "Informacja",
|
|
deleteConfirm: "Czy na pewno chcesz to usunąć?",
|
|
addNote: "Dodaj notatkę",
|
|
addNoteSuccess: "Notatka została dodana",
|
|
addNoteError: "Nie udało się zapisać notatki",
|
|
addNotePlaceholder: "Dodaj nową notatkę...",
|
|
status: "Status",
|
|
type: "Typ",
|
|
actions: "Akcje",
|
|
view: "Wyświetl",
|
|
clearSearch: "Wyczyść wyszukiwanie",
|
|
filters:"Filtry",
|
|
clearAll: "Wyczyść",
|
|
clearAllFilters: "Wyczyść wszystkie filtry",
|
|
sortBy: "Sortuj według",
|
|
days: "dni",
|
|
changeHistory: "Historia zmian",
|
|
changedTo: "Zmieniono na",
|
|
from: "Z",
|
|
by: "przez",
|
|
reason: "Powód",
|
|
na: "N/D"
|
|
},
|
|
|
|
// Dashboard
|
|
dashboard: {
|
|
title: "Panel główny",
|
|
subtitle: "Przegląd twoich projektów i zadań",
|
|
totalProjects: "Wszystkie projekty",
|
|
activeProjects: "Aktywne projekty",
|
|
completedProjects: "Ukończone projekty",
|
|
overdueProjects: "Przeterminowane projekty",
|
|
totalContracts: "Wszystkie umowy",
|
|
activeContracts: "Aktywne umowy",
|
|
pendingTasks: "Oczekujące zadania",
|
|
inProgressTasks: "Zadania w trakcie",
|
|
completedTasks: "Ukończone zadania",
|
|
overdueTasks: "Przeterminowane zadania",
|
|
recentProjects: "Najnowsze projekty",
|
|
recentTasks: "Najnowsze zadania",
|
|
upcomingDeadlines: "Nadchodzące terminy",
|
|
projectsThisWeek: "Projekty w tym tygodniu",
|
|
tasksThisWeek: "Zadania w tym tygodniu",
|
|
completionRate: "Wskaźnik ukończenia",
|
|
viewAll: "Zobacz wszystkie",
|
|
noRecentProjects: "Brak najnowszych projektów",
|
|
noRecentTasks: "Brak najnowszych zadań",
|
|
noUpcomingDeadlines: "Brak nadchodzących terminów"
|
|
},
|
|
|
|
// Team Leads Dashboard
|
|
teamDashboard: {
|
|
title: "Dashboard",
|
|
yearLabel: "Rok:",
|
|
allYears: "Wszystkie lata",
|
|
projectCompletionTitle: "Wartość ukończenia projektów w czasie",
|
|
loadingChart: "Ładowanie danych wykresu...",
|
|
errorPrefix: "Błąd:",
|
|
noData: "Brak dostępnych danych ukończonych projektów",
|
|
totalPortfolio: "Całkowity portfel",
|
|
realised: "Zrealizowane",
|
|
unrealised: "Niezrealizowane",
|
|
noSummaryData: "Brak dostępnych danych podsumowania",
|
|
realisedValue: "Wartość zrealizowana",
|
|
unrealisedValue: "Wartość niezrealizowana",
|
|
byProjectType: "Według typu projektu",
|
|
monthLabel: "Miesiąc:",
|
|
monthlyValue: "Wartość miesięczna:",
|
|
cumulative: "Skumulowana:",
|
|
na: "N/D"
|
|
},
|
|
|
|
// Project statuses
|
|
projectStatus: {
|
|
registered: "Zarejestrowany",
|
|
in_progress_design: "W realizacji (projektowanie)",
|
|
in_progress_construction: "W realizacji (budowa)",
|
|
fulfilled: "Zakończony",
|
|
cancelled: "Wycofany",
|
|
unknown: "Nieznany"
|
|
},
|
|
|
|
// Project types
|
|
projectType: {
|
|
design: "Projektowanie",
|
|
construction: "Budowa",
|
|
"design+construction": "Projektowanie + Budowa"
|
|
},
|
|
|
|
// Task statuses
|
|
taskStatus: {
|
|
not_started: "Nie rozpoczęte",
|
|
pending: "Oczekujące",
|
|
in_progress: "W trakcie",
|
|
completed: "Ukończone",
|
|
cancelled: "Anulowane",
|
|
on_hold: "Wstrzymane"
|
|
},
|
|
|
|
// Projects
|
|
projects: {
|
|
title: "Projekty",
|
|
subtitle: "",
|
|
newProject: "Nowy projekt",
|
|
editProject: "Edytuj projekt",
|
|
deleteProject: "Usuń projekt",
|
|
editing: "Edycja",
|
|
backToProjects: "Powrót do projektów",
|
|
projectName: "Nazwa projektu",
|
|
city: "Miasto",
|
|
address: "Adres",
|
|
plot: "Działka",
|
|
district: "Jednostka ewidencyjna",
|
|
unit: "Obręb",
|
|
finishDate: "Data zakończenia",
|
|
type: "Typ",
|
|
contact: "Kontakt",
|
|
coordinates: "Współrzędne",
|
|
notes: "Notatki",
|
|
assignedTo: "Przypisane do",
|
|
unassigned: "Nieprzypisane",
|
|
createdBy: "Utworzone przez",
|
|
lastModified: "Ostatnia modyfikacja",
|
|
basicInformation: "Informacje podstawowe",
|
|
locationDetails: "Szczegóły lokalizacji",
|
|
projectDetails: "Szczegóły projektu",
|
|
additionalInfo: "Dodatkowe informacje",
|
|
searchPlaceholder: "Szukaj projektów po nazwie, mieście lub adresie...",
|
|
noProjects: "Brak projektów",
|
|
noProjectsMessage: "Rozpocznij od utworzenia swojego pierwszego projektu.",
|
|
notFinished: "Nie zakończone",
|
|
projects: "projektów",
|
|
mapView: "Widok mapy",
|
|
mine: "Moje",
|
|
exportExcel: "Eksport do Excela",
|
|
createFirstProject: "Utwórz pierwszy projekt",
|
|
noMatchingResults: "Brak projektów pasujących do kryteriów wyszukiwania. Spróbuj zmienić wyszukiwane frazy.",
|
|
showingResults: "Wyświetlono {shown} z {total} projektów",
|
|
assigned: "Przypisany",
|
|
deleteConfirm: "Czy na pewno chcesz usunąć ten projekt?",
|
|
deleteSuccess: "Projekt został pomyślnie usunięty",
|
|
createSuccess: "Projekt został pomyślnie utworzony",
|
|
updateSuccess: "Projekt został pomyślnie zaktualizowany",
|
|
saveError: "Nie udało się zapisać projektu",
|
|
enterProjectName: "Wprowadź nazwę projektu",
|
|
enterCity: "Wprowadź miasto",
|
|
enterAddress: "Wprowadź adres",
|
|
enterPlotNumber: "Wprowadź numer działki",
|
|
enterDistrict: "Wprowadź jednostkę ewidencyjną",
|
|
enterUnit: "Wprowadź obręb",
|
|
enterContactDetails: "Wprowadź dane kontaktowe",
|
|
coordinatesPlaceholder: "np. 49.622958,20.629562",
|
|
enterNotes: "Wprowadź notatki...",
|
|
createProject: "Utwórz projekt",
|
|
updateProject: "Aktualizuj projekt",
|
|
creating: "Tworzenie...",
|
|
updating: "Aktualizowanie...",
|
|
projectDetails: "Szczegóły projektu",
|
|
editProjectDetails: "Edytuj szczegóły projektu",
|
|
contract: "Umowa",
|
|
selectContract: "Wybierz umowę",
|
|
investmentNumber: "Numer inwestycji",
|
|
enterInvestmentNumber: "Wprowadź numer inwestycji",
|
|
enterWP: "Wprowadź WP",
|
|
contactNumberMatch: "Znaleziono numer kontaktowy",
|
|
phoneSearchEnabled: "Wyszukiwanie po numerze włączone",
|
|
phoneSearchDisabled: "Wyszukiwanie po numerze wyłączone",
|
|
placeholders: {
|
|
contact: "Wprowadź dane kontaktowe",
|
|
coordinates: "np. 49.622958,20.629562",
|
|
notes: "Wprowadź notatki...",
|
|
investmentNumber: "Wprowadź numer inwestycji",
|
|
wp: "Wprowadź WP"
|
|
}
|
|
},
|
|
|
|
// Contacts
|
|
contacts: {
|
|
title: "Kontakty",
|
|
subtitle: "Zarządzaj kontaktami",
|
|
contact: "Kontakt",
|
|
newContact: "Nowy kontakt",
|
|
editContact: "Edytuj kontakt",
|
|
deleteContact: "Usuń kontakt",
|
|
name: "Imię i nazwisko",
|
|
phone: "Telefon",
|
|
email: "Email",
|
|
company: "Firma",
|
|
position: "Stanowisko",
|
|
contactType: "Typ kontaktu",
|
|
notes: "Notatki",
|
|
active: "Aktywny",
|
|
inactive: "Nieaktywny",
|
|
searchPlaceholder: "Szukaj kontaktów...",
|
|
noContacts: "Brak kontaktów",
|
|
addFirstContact: "Dodaj pierwszy kontakt",
|
|
selectContact: "Wybierz kontakt",
|
|
addContact: "Dodaj kontakt",
|
|
linkedProjects: "Powiązane projekty",
|
|
types: {
|
|
project: "Kontakt projektowy",
|
|
contractor: "Wykonawca",
|
|
office: "Urząd",
|
|
supplier: "Dostawca",
|
|
other: "Inny"
|
|
}
|
|
},
|
|
|
|
// Contracts
|
|
contracts: {
|
|
title: "Umowy",
|
|
subtitle: "---",
|
|
contract: "Umowa",
|
|
newContract: "Nowa umowa",
|
|
editContract: "Edytuj umowę",
|
|
deleteContract: "Usuń umowę",
|
|
contractNumber: "Numer umowy",
|
|
contractName: "Nazwa umowy",
|
|
customerContractNumber: "Numer umowy klienta",
|
|
customer: "Klient",
|
|
investor: "Inwestor",
|
|
dateSigned: "Data zawarcia",
|
|
finishDate: "Data zakończenia",
|
|
searchPlaceholder: "Szukaj umów po numerze, nazwie, kliencie lub inwestorze...",
|
|
noContracts: "Brak umów",
|
|
noContractsMessage: "Rozpocznij od utworzenia swojej pierwszej umowy.",
|
|
noMatchingContracts: "Brak pasujących umów",
|
|
changeSearchCriteria: "Spróbuj zmienić kryteria wyszukiwania lub filtry.",
|
|
all: "Wszystkie",
|
|
active: "Aktywne",
|
|
withoutEndDate: "W trakcie",
|
|
expired: "Przeterminowane",
|
|
createContract: "Utwórz umowę",
|
|
enterContractNumber: "Wprowadź numer umowy",
|
|
enterContractName: "Wprowadź nazwę umowy",
|
|
enterCustomerContractNumber: "Wprowadź numer umowy klienta",
|
|
enterCustomerName: "Wprowadź nazwę klienta",
|
|
enterInvestorName: "Wprowadź nazwę inwestora",
|
|
signedOn: "Zawarcie:",
|
|
finishOn: "Zakończenie:",
|
|
customerLabel: "Zleceniodawca:",
|
|
investorLabel: "Inwestor:",
|
|
loadingContractDetails: "Ładowanie szczegółów umowy...",
|
|
contractNotFound: "Umowa nie została znaleziona.",
|
|
backToContracts: "Powrót do umów",
|
|
addProject: "Dodaj projekt",
|
|
contractInformation: "Informacje o umowie",
|
|
contractNumber: "Numer umowy",
|
|
contractName: "Nazwa umowy",
|
|
customerContractNumber: "Numer umowy klienta",
|
|
customer: "Klient",
|
|
investor: "Inwestor",
|
|
dateSigned: "Data zawarcia",
|
|
finishDate: "Data zakończenia",
|
|
summary: "Podsumowanie",
|
|
projectsCount: "Liczba projektów",
|
|
projects: "projektów",
|
|
contractStatus: "Status umowy",
|
|
active: "Aktywna",
|
|
expired: "Przeterminowana",
|
|
contractDocuments: "Dokumenty umowy",
|
|
uploadDocument: "Prześlij dokument",
|
|
associatedProjects: "Powiązane projekty",
|
|
noProjectsYet: "Brak projektów",
|
|
getStartedMessage: "Rozpocznij od utworzenia pierwszego projektu dla tej umowy",
|
|
createFirstProject: "Utwórz pierwszy projekt",
|
|
viewDetails: "Zobacz szczegóły",
|
|
createNewContract: "Utwórz nową umowę",
|
|
addNewContractDescription: "Dodaj nową umowę do swojego portfolio",
|
|
contractDetails: "Szczegóły umowy",
|
|
failedToCreateContract: "Nie udało się utworzyć umowy. Sprawdź dane i spróbuj ponownie.",
|
|
// File upload translations
|
|
uploadDocumentTitle: "Prześlij dokument",
|
|
descriptionOptional: "Opis (opcjonalny)",
|
|
descriptionPlaceholder: "Krótki opis dokumentu...",
|
|
uploading: "Przesyłanie...",
|
|
dropFilesHere: "Upuść pliki tutaj lub kliknij, aby przeglądać",
|
|
supportedFiles: "PDF, DOC, XLS, Obrazy do 10MB",
|
|
chooseFile: "Wybierz plik",
|
|
failedToUploadFile: "Nie udało się przesłać pliku",
|
|
loadingFiles: "Ładowanie plików...",
|
|
noDocumentsUploaded: "Brak przesłanych dokumentów",
|
|
download: "Pobierz",
|
|
confirmDeleteFile: "Czy na pewno chcesz usunąć ten plik?",
|
|
failedToDeleteFile: "Nie udało się usunąć pliku"
|
|
},
|
|
|
|
// Map
|
|
map: {
|
|
loadingMap: "Ładowanie mapy...",
|
|
preparingMap: "Przygotowywanie pełnoekranowego widoku mapy",
|
|
projectsMap: "Mapa projektów",
|
|
projectsWithCoordinates: "projektów z współrzędnymi",
|
|
loadingProjectsMap: "Ładowanie mapy projektów...",
|
|
moveTool: "Narzędzie przesuwania (przesuń mapę)",
|
|
selectTool: "Narzędzie wyboru",
|
|
measureDistance: "Zmierz odległość",
|
|
drawMarkup: "Rysuj/oznacz",
|
|
addPinMarker: "Dodaj pinezkę/znacznik",
|
|
measureArea: "Zmierz powierzchnię",
|
|
listView: "Widok listy",
|
|
addProject: "Dodaj projekt",
|
|
toggleLayerControls: "Przełącz kontrolki warstw",
|
|
mapLayers: "Warstwy mapy",
|
|
active: "aktywnych",
|
|
baseMaps: "Mapy bazowe",
|
|
overlayLayers: "Warstwy nakładkowe",
|
|
filters: "Filtry:",
|
|
toggleAllFilters: "Przełącz wszystkie filtry",
|
|
hideAll: "Ukryj wszystkie",
|
|
showAll: "Pokaż wszystkie",
|
|
toggleFilter: "Przełącz filtr",
|
|
projects: "projektów",
|
|
noProjectsWithCoordinates: "Brak projektów ze współrzędnymi",
|
|
noProjectsMessage: "Projekty potrzebują współrzędnych, aby pojawić się na mapie. Dodaj współrzędne podczas tworzenia lub edycji projektów.",
|
|
viewAllProjects: "Zobacz wszystkie projekty",
|
|
zoomIn: "Przybliż",
|
|
zoomOut: "Oddal",
|
|
viewProjectDetails: "Zobacz szczegóły projektu",
|
|
routePlanning: {
|
|
title: "Planowanie trasy",
|
|
projects: "projektów",
|
|
searchPlaceholder: "Szukaj projektów...",
|
|
noProjectsFound: "Nie znaleziono projektów pasujących do \"{{query}}\"",
|
|
searchHintText: "Spróbuj szukać po nazwie projektu lub numerze WP",
|
|
searchHint: "Przeciągnij aby zmienić kolejność",
|
|
searchHintIcons: "Ustaw początek • Ustaw koniec • Usuń",
|
|
dragToReorder: "Przeciągnij aby zmienić kolejność",
|
|
setStart: "Ustaw początek",
|
|
setEnd: "Ustaw koniec",
|
|
remove: "Usuń",
|
|
start: "START",
|
|
end: "KONIEC",
|
|
setAsStartPoint: "Ustaw jako punkt początkowy",
|
|
setAsEndPoint: "Ustaw jako punkt końcowy",
|
|
removeFromRoute: "Usuń z trasy",
|
|
calculating: "Obliczanie...",
|
|
findOptimalRoute: "Znajdź optymalną trasę",
|
|
calculateRoute: "Oblicz trasę",
|
|
routeCalculated: "Trasa obliczona",
|
|
optimized: "zoptymalizowana",
|
|
method: "Metoda",
|
|
error: "Błąd",
|
|
planRoutes: "Planuj trasy między projektami",
|
|
clickToAddProjects: "Kliknij na znaczniki projektów, aby dodać je do trasy"
|
|
}
|
|
},
|
|
|
|
// Tasks
|
|
tasks: {
|
|
title: "Zadania",
|
|
task: "zadanie",
|
|
tasks: "zadania",
|
|
subtitle: "Zarządzaj zadaniami projektów",
|
|
newTask: "Nowe zadanie",
|
|
editTask: "Edytuj zadanie",
|
|
deleteTask: "Usuń zadanie",
|
|
taskName: "Nazwa zadania",
|
|
description: "Opis",
|
|
priority: "Priorytet",
|
|
assignedTo: "Przypisane do",
|
|
dueDate: "Termin wykonania",
|
|
status: "Status",
|
|
project: "Projekt",
|
|
template: "Szablon",
|
|
searchPlaceholder: "Szukaj zadań, projektów, miast lub adresów...",
|
|
noTasks: "Brak zadań",
|
|
noTasksMessage: "Brak zadań przypisanych do tego projektu.",
|
|
addTaskMessage: "Dodaj zadanie powyżej, aby rozpocząć.",
|
|
filterBy: "Filtruj według",
|
|
sortBy: "Sortuj według",
|
|
allTasks: "Wszystkie zadania",
|
|
myTasks: "Moje zadania",
|
|
mine: "Moje",
|
|
overdue: "Przeterminowane",
|
|
dueSoon: "Niedługo termin",
|
|
high: "Wysoki",
|
|
normal: "Normalny",
|
|
medium: "Średni",
|
|
low: "Niski",
|
|
dateCreated: "Data utworzenia",
|
|
dateModified: "Data modyfikacji",
|
|
daysLeft: "dni pozostało",
|
|
daysOverdue: "dni przeterminowane",
|
|
dueToday: "Termin dzisiaj",
|
|
startTask: "Rozpocznij zadanie",
|
|
completeTask: "Zakończ zadanie",
|
|
comments: "Komentarze",
|
|
addComment: "Dodaj komentarz",
|
|
noComments: "Brak komentarzy",
|
|
maxWait: "Maksymalne oczekiwanie",
|
|
dateStarted: "Data rozpoczęcia",
|
|
actions: "Działania",
|
|
urgent: "Pilne",
|
|
updateTask: "Aktualizuj zadanie",
|
|
taskType: "Typ zadania",
|
|
fromTemplate: "Z szablonu",
|
|
customTask: "Zadanie niestandardowe",
|
|
selectTemplate: "Wybierz szablon zadania",
|
|
chooseTemplate: "Wybierz szablon zadania...",
|
|
enterTaskName: "Wprowadź nazwę zadania...",
|
|
enterDescription: "Wprowadź opis zadania (opcjonalnie)...",
|
|
addTask: "Dodaj zadanie",
|
|
adding: "Dodawanie...",
|
|
addTaskError: "Nie udało się dodać zadania do projektu",
|
|
notes: "notatki",
|
|
deleteNote: "Usuń notatkę",
|
|
deleteError: "Błąd usuwania zadania",
|
|
notStarted: "Nie rozpoczęte",
|
|
days: "dni"
|
|
},
|
|
|
|
// Task Templates
|
|
taskTemplates: {
|
|
title: "Szablony zadań",
|
|
subtitle: "Zarządzaj szablonami zadań",
|
|
newTemplate: "Nowy szablon",
|
|
editTemplate: "Edytuj szablon",
|
|
deleteTemplate: "Usuń szablon",
|
|
templateName: "Nazwa szablonu",
|
|
templateDescription: "Opis szablonu",
|
|
defaultPriority: "Domyślny priorytet",
|
|
estimatedDuration: "Szacowany czas trwania",
|
|
category: "Kategoria",
|
|
searchPlaceholder: "Szukaj szablonów...",
|
|
noTemplates: "Brak szablonów",
|
|
noTemplatesMessage: "Rozpocznij od utworzenia swojego pierwszego szablonu zadania.",
|
|
useTemplate: "Użyj szablonu",
|
|
duplicateTemplate: "Duplikuj szablon"
|
|
},
|
|
|
|
// Forms
|
|
forms: {
|
|
validation: {
|
|
required: "To pole jest wymagane",
|
|
email: "Wprowadź prawidłowy adres email",
|
|
minLength: "Minimalna długość: {min} znaków",
|
|
maxLength: "Maksymalna długość: {max} znaków",
|
|
invalidDate: "Nieprawidłowa data",
|
|
invalidCoordinates: "Nieprawidłowe współrzędne"
|
|
},
|
|
placeholders: {
|
|
enterText: "Wprowadź tekst...",
|
|
selectDate: "Wybierz datę",
|
|
selectOption: "Wybierz opcję",
|
|
searchResults: "Szukaj wyników..."
|
|
}
|
|
},
|
|
|
|
// Sorting and filtering
|
|
sorting: {
|
|
sortBy: "Sortuj według",
|
|
orderBy: "Kolejność",
|
|
ascending: "Rosnąco",
|
|
descending: "Malejąco",
|
|
name: "Nazwa",
|
|
date: "Data",
|
|
status: "Status",
|
|
priority: "Priorytet",
|
|
dateCreated: "Data utworzenia",
|
|
dateModified: "Data modyfikacji",
|
|
startDate: "Data rozpoczęcia",
|
|
finishDate: "Data zakończenia"
|
|
},
|
|
|
|
// Date formats
|
|
dates: {
|
|
today: "Dzisiaj",
|
|
yesterday: "Wczoraj",
|
|
tomorrow: "Jutro",
|
|
daysAgo: "{count} dni temu",
|
|
inDays: "za {count} dni",
|
|
invalidDate: "Nieprawidłowa data",
|
|
selectDate: "Wybierz datę"
|
|
},
|
|
|
|
// Map layers
|
|
mapLayers: {
|
|
polishOrthophoto: "🛰️ Polska Ortofotomapa",
|
|
polishCadastral: "📋 Polskie Dane Katastralne",
|
|
polishSpatialPlanning: "🏗️ Polskie Planowanie Przestrzenne",
|
|
lpPortalRoads: "🛣️ LP-Portal Drogi",
|
|
lpPortalStreetNames: "🏷️ LP-Portal Nazwy Ulic",
|
|
lpPortalParcels: "📐 LP-Portal Działki",
|
|
lpPortalSurveyMarkers: "📍 LP-Portal Punkty Pomiarowe",
|
|
openStreetMap: "🗺️ OpenStreetMap",
|
|
googleSatellite: "🛰️ Google Satelita",
|
|
googleRoads: "🛣️ Google Drogi",
|
|
layerControl: "Kontrola warstw",
|
|
baseLayers: "Warstwy bazowe",
|
|
overlayLayers: "Warstwy nakładkowe",
|
|
opacity: "Przezroczystość"
|
|
},
|
|
|
|
// Authentication
|
|
auth: {
|
|
signIn: "Zaloguj się",
|
|
signOut: "Wyloguj się",
|
|
email: "Email",
|
|
password: "Hasło",
|
|
rememberMe: "Zapamiętaj mnie",
|
|
forgotPassword: "Zapomniałeś hasła?",
|
|
signInWith: "Zaloguj się przez",
|
|
signUp: "Zarejestruj się",
|
|
createAccount: "Utwórz konto",
|
|
alreadyHaveAccount: "Masz już konto?",
|
|
dontHaveAccount: "Nie masz konta?",
|
|
signInError: "Błąd logowania",
|
|
signOutError: "Błąd wylogowania",
|
|
emailRequired: "Email jest wymagany",
|
|
passwordRequired: "Hasło jest wymagane",
|
|
invalidCredentials: "Nieprawidłowe dane logowania"
|
|
},
|
|
|
|
// User roles
|
|
userRoles: {
|
|
admin: "Administrator",
|
|
user: "Użytkownik",
|
|
manager: "Menedżer",
|
|
viewer: "Czytelnik"
|
|
},
|
|
|
|
// Error messages
|
|
errors: {
|
|
generic: "Wystąpił błąd. Spróbuj ponownie.",
|
|
network: "Błąd połączenia sieciowego",
|
|
unauthorized: "Brak autoryzacji",
|
|
forbidden: "Brak uprawnień",
|
|
notFound: "Nie znaleziono",
|
|
validation: "Błąd walidacji danych",
|
|
server: "Błąd serwera",
|
|
timeout: "Przekroczono limit czasu",
|
|
unknown: "Nieznany błąd"
|
|
},
|
|
|
|
// Success messages
|
|
success: {
|
|
saved: "Zapisano pomyślnie",
|
|
created: "Utworzono pomyślnie",
|
|
updated: "Zaktualizowano pomyślnie",
|
|
deleted: "Usunięto pomyślnie",
|
|
sent: "Wysłano pomyślnie",
|
|
completed: "Ukończono pomyślnie"
|
|
},
|
|
|
|
// Admin section
|
|
admin: {
|
|
title: "Administracja",
|
|
subtitle: "Zarządzaj użytkownikami systemu i uprawnieniami",
|
|
userManagement: "Zarządzanie użytkownikami",
|
|
auditLogs: "Logi audytu",
|
|
systemSettings: "Ustawienia systemu",
|
|
users: "Użytkownicy",
|
|
newUser: "Nowy użytkownik",
|
|
editUser: "Edytuj użytkownika",
|
|
deleteUser: "Usuń użytkownika",
|
|
userName: "Nazwa użytkownika",
|
|
userEmail: "Email użytkownika",
|
|
userRole: "Rola użytkownika",
|
|
active: "Aktywny",
|
|
inactive: "Nieaktywny",
|
|
lastLogin: "Ostatnie logowanie",
|
|
createdAt: "Data utworzenia",
|
|
noUsers: "Brak użytkowników",
|
|
system: "System"
|
|
},
|
|
|
|
// Settings
|
|
settings: {
|
|
title: "Ustawienia",
|
|
appearance: "Wygląd",
|
|
theme: "Motyw",
|
|
themeDescription: "Wybierz preferowany motyw",
|
|
language: "Język",
|
|
languageDescription: "Wybierz preferowany język",
|
|
password: "Hasło",
|
|
passwordDescription: "Zmień hasło do konta",
|
|
currentPassword: "Aktualne hasło",
|
|
newPassword: "Nowe hasło",
|
|
confirmPassword: "Potwierdź nowe hasło",
|
|
changePassword: "Zmień hasło"
|
|
}
|
|
},
|
|
|
|
en: {
|
|
// English translations (fallback)
|
|
navigation: {
|
|
dashboard: "Dashboard",
|
|
projects: "Projects",
|
|
taskTemplates: "Task Templates",
|
|
projectTasks: "Project Tasks",
|
|
tasks: "Tasks",
|
|
contracts: "Contracts",
|
|
userManagement: "User Management",
|
|
projectPanel: "Project Panel",
|
|
loading: "Loading...",
|
|
signOut: "Sign Out",
|
|
signIn: "Sign In"
|
|
},
|
|
|
|
common: {
|
|
save: "Save",
|
|
cancel: "Cancel",
|
|
delete: "Delete",
|
|
edit: "Edit",
|
|
add: "Add",
|
|
create: "Create",
|
|
update: "Update",
|
|
search: "Search",
|
|
filter: "Filter",
|
|
loading: "Loading...",
|
|
saving: "Saving...",
|
|
creating: "Creating...",
|
|
updating: "Updating...",
|
|
yes: "Yes",
|
|
no: "No",
|
|
confirm: "Confirm",
|
|
close: "Close",
|
|
back: "Back",
|
|
next: "Next",
|
|
previous: "Previous",
|
|
page: "Page",
|
|
of: "of",
|
|
items: "items",
|
|
all: "All",
|
|
none: "None",
|
|
required: "required",
|
|
optional: "optional",
|
|
selectOption: "Select option",
|
|
selectLanguage: "Select language",
|
|
noResults: "No results",
|
|
error: "Error",
|
|
success: "Success",
|
|
warning: "Warning",
|
|
info: "Info",
|
|
deleteConfirm: "Are you sure you want to delete this?",
|
|
addNote: "Add Note",
|
|
addNoteSuccess: "Note added",
|
|
addNoteError: "Failed to save note",
|
|
addNotePlaceholder: "Add a new note...",
|
|
status: "Status",
|
|
type: "Type",
|
|
actions: "Actions",
|
|
view: "View",
|
|
clearSearch: "Clear search",
|
|
filters: "Filters",
|
|
clearAll: "Clear",
|
|
clearAllFilters: "Clear all filters",
|
|
sortBy: "Sort by",
|
|
days: "days",
|
|
changeHistory: "Change History",
|
|
changedTo: "Changed to",
|
|
from: "From",
|
|
by: "by",
|
|
reason: "Reason",
|
|
na: "N/A"
|
|
},
|
|
|
|
dashboard: {
|
|
title: "Dashboard",
|
|
subtitle: "Overview of your projects and tasks",
|
|
totalProjects: "Total Projects",
|
|
activeProjects: "Active Projects",
|
|
completedProjects: "Completed Projects",
|
|
overdueProjects: "Overdue Projects",
|
|
totalContracts: "Total Contracts",
|
|
activeContracts: "Active Contracts",
|
|
pendingTasks: "Pending Tasks",
|
|
inProgressTasks: "In Progress Tasks",
|
|
completedTasks: "Completed Tasks",
|
|
overdueTasks: "Overdue Tasks",
|
|
recentProjects: "Recent Projects",
|
|
recentTasks: "Recent Tasks",
|
|
upcomingDeadlines: "Upcoming Deadlines",
|
|
projectsThisWeek: "Projects This Week",
|
|
tasksThisWeek: "Tasks This Week",
|
|
completionRate: "Completion Rate",
|
|
viewAll: "View All",
|
|
noRecentProjects: "No recent projects",
|
|
noRecentTasks: "No recent tasks",
|
|
noUpcomingDeadlines: "No upcoming deadlines"
|
|
},
|
|
|
|
// Team Leads Dashboard
|
|
teamDashboard: {
|
|
title: "Dashboard",
|
|
yearLabel: "Year:",
|
|
allYears: "All Years",
|
|
projectCompletionTitle: "Project Completion Value Over Time",
|
|
loadingChart: "Loading chart data...",
|
|
errorPrefix: "Error:",
|
|
noData: "No completed projects data available",
|
|
totalPortfolio: "Total Portfolio",
|
|
realised: "Realised",
|
|
unrealised: "Unrealised",
|
|
noSummaryData: "No summary data available",
|
|
realisedValue: "Realised Value",
|
|
unrealisedValue: "Unrealised Value",
|
|
byProjectType: "By Project Type",
|
|
monthLabel: "Month:",
|
|
monthlyValue: "Monthly Value:",
|
|
cumulative: "Cumulative:",
|
|
na: "N/A"
|
|
},
|
|
|
|
projectStatus: {
|
|
registered: "Registered",
|
|
in_progress_design: "In Progress (Design)",
|
|
in_progress_construction: "In Progress (Construction)",
|
|
fulfilled: "Completed",
|
|
cancelled: "Cancelled",
|
|
unknown: "Unknown"
|
|
},
|
|
|
|
projectType: {
|
|
design: "Design",
|
|
construction: "Construction",
|
|
"design+construction": "Design + Construction"
|
|
},
|
|
|
|
taskStatus: {
|
|
not_started: "Not Started",
|
|
pending: "Pending",
|
|
in_progress: "In Progress",
|
|
completed: "Completed",
|
|
cancelled: "Cancelled",
|
|
on_hold: "On Hold"
|
|
},
|
|
|
|
projects: {
|
|
title: "Projects",
|
|
subtitle: "Manage your projects",
|
|
newProject: "New Project",
|
|
editProject: "Edit Project",
|
|
deleteProject: "Delete Project",
|
|
editing: "Editing",
|
|
backToProjects: "Back to Projects",
|
|
projectName: "Project Name",
|
|
city: "City",
|
|
address: "Address",
|
|
plot: "Plot",
|
|
district: "District",
|
|
unit: "Unit",
|
|
finishDate: "Finish Date",
|
|
type: "Type",
|
|
contact: "Contact",
|
|
coordinates: "Coordinates",
|
|
notes: "Notes",
|
|
assignedTo: "Assigned To",
|
|
unassigned: "Unassigned",
|
|
createdBy: "Created By",
|
|
lastModified: "Last Modified",
|
|
basicInformation: "Basic Information",
|
|
locationDetails: "Location Details",
|
|
projectDetails: "Project Details",
|
|
additionalInfo: "Additional Information",
|
|
searchPlaceholder: "Search projects by name, city or address...",
|
|
noProjects: "No projects",
|
|
noProjectsMessage: "Get started by creating your first project.",
|
|
notFinished: "Not finished",
|
|
projects: "projects",
|
|
mapView: "Map View",
|
|
mine: "Mine",
|
|
exportExcel: "Export to Excel",
|
|
createFirstProject: "Create first project",
|
|
noMatchingResults: "No projects match the search criteria. Try changing your search terms.",
|
|
showingResults: "Showing {shown} of {total} projects",
|
|
assigned: "Assigned",
|
|
deleteConfirm: "Are you sure you want to delete this project?",
|
|
deleteSuccess: "Project deleted successfully",
|
|
createSuccess: "Project created successfully",
|
|
updateSuccess: "Project updated successfully",
|
|
saveError: "Failed to save project",
|
|
enterProjectName: "Enter project name",
|
|
enterCity: "Enter city",
|
|
enterAddress: "Enter address",
|
|
enterPlotNumber: "Enter plot number",
|
|
enterDistrict: "Enter district",
|
|
enterUnit: "Enter unit",
|
|
enterContactDetails: "Enter contact details",
|
|
coordinatesPlaceholder: "e.g., 49.622958,20.629562",
|
|
enterNotes: "Enter notes...",
|
|
createProject: "Create Project",
|
|
updateProject: "Update Project",
|
|
creating: "Creating...",
|
|
updating: "Updating...",
|
|
projectDetails: "Project Details",
|
|
editProjectDetails: "Edit Project Details",
|
|
contract: "Contract",
|
|
selectContract: "Select Contract",
|
|
investmentNumber: "Investment Number",
|
|
enterInvestmentNumber: "Enter investment number",
|
|
enterWP: "Enter WP",
|
|
placeholders: {
|
|
contact: "Enter contact details",
|
|
coordinates: "e.g., 49.622958,20.629562",
|
|
notes: "Enter notes...",
|
|
investmentNumber: "Enter investment number",
|
|
wp: "Enter WP"
|
|
}
|
|
},
|
|
|
|
// Map
|
|
map: {
|
|
loadingMap: "Loading map...",
|
|
preparingMap: "Preparing your full-screen map experience",
|
|
projectsMap: "Projects Map",
|
|
projectsWithCoordinates: "projects with coordinates",
|
|
loadingProjectsMap: "Loading projects map...",
|
|
moveTool: "Move Tool (Pan Map)",
|
|
selectTool: "Select Tool",
|
|
measureDistance: "Measure Distance",
|
|
drawMarkup: "Draw/Markup",
|
|
addPinMarker: "Add Pin/Marker",
|
|
measureArea: "Measure Area",
|
|
listView: "List View",
|
|
addProject: "Add Project",
|
|
toggleLayerControls: "Toggle Layer Controls",
|
|
mapLayers: "Map Layers",
|
|
active: "active",
|
|
baseMaps: "Base Maps",
|
|
overlayLayers: "Overlay Layers",
|
|
filters: "Filters:",
|
|
toggleAllFilters: "Toggle all filters",
|
|
hideAll: "Hide All",
|
|
showAll: "Show All",
|
|
toggleFilter: "Toggle filter",
|
|
projects: "projects",
|
|
noProjectsWithCoordinates: "No projects with coordinates",
|
|
noProjectsMessage: "Projects need coordinates to appear on the map. Add coordinates when creating or editing projects.",
|
|
viewAllProjects: "View All Projects",
|
|
zoomIn: "Zoom In",
|
|
zoomOut: "Zoom Out",
|
|
viewProjectDetails: "View Project Details",
|
|
routePlanning: {
|
|
title: "Route Planning",
|
|
projects: "projects",
|
|
searchPlaceholder: "Search projects...",
|
|
noProjectsFound: "No projects found matching \"{{query}}\"",
|
|
searchHintText: "Try searching by project name or WP number",
|
|
searchHint: "Drag to reorder",
|
|
searchHintIcons: "Set start • Set end • Remove",
|
|
dragToReorder: "Drag to reorder",
|
|
setStart: "Set start",
|
|
setEnd: "Set end",
|
|
remove: "Remove",
|
|
start: "START",
|
|
end: "END",
|
|
setAsStartPoint: "Set as start point",
|
|
setAsEndPoint: "Set as end point",
|
|
removeFromRoute: "Remove from route",
|
|
calculating: "Calculating...",
|
|
findOptimalRoute: "Find Optimal Route",
|
|
calculateRoute: "Calculate Route",
|
|
routeCalculated: "Route Calculated",
|
|
optimized: "optimized",
|
|
method: "Method",
|
|
error: "Error",
|
|
planRoutes: "Plan routes between projects",
|
|
clickToAddProjects: "Click on project markers to add them to your route"
|
|
}
|
|
},
|
|
|
|
contracts: {
|
|
title: "Contracts",
|
|
subtitle: "Manage your contracts and agreements",
|
|
newContract: "New Contract",
|
|
editContract: "Edit Contract",
|
|
deleteContract: "Delete Contract",
|
|
contractNumber: "Contract Number",
|
|
contractName: "Contract Name",
|
|
customerContractNumber: "Customer Contract Number",
|
|
customer: "Customer",
|
|
investor: "Investor",
|
|
dateSigned: "Date Signed",
|
|
finishDate: "Finish Date",
|
|
searchPlaceholder: "Search contracts by number, name, customer or investor...",
|
|
noContracts: "No contracts",
|
|
noContractsMessage: "Get started by creating your first contract.",
|
|
noMatchingContracts: "No matching contracts",
|
|
changeSearchCriteria: "Try changing your search criteria or filters.",
|
|
all: "All",
|
|
active: "Active",
|
|
withoutEndDate: "In Progress",
|
|
expired: "Expired",
|
|
createContract: "Create Contract",
|
|
enterContractNumber: "Enter contract number",
|
|
enterContractName: "Enter contract name",
|
|
enterCustomerContractNumber: "Enter customer contract number",
|
|
enterCustomerName: "Enter customer name",
|
|
enterInvestorName: "Enter investor name",
|
|
signedOn: "Signed:",
|
|
finishOn: "Finish:",
|
|
customerLabel: "Customer:",
|
|
investorLabel: "Investor:"
|
|
},
|
|
|
|
tasks: {
|
|
title: "Tasks",
|
|
task: "task",
|
|
tasks: "tasks",
|
|
subtitle: "Manage project tasks",
|
|
newTask: "New Task",
|
|
editTask: "Edit Task",
|
|
deleteTask: "Delete Task",
|
|
taskName: "Task Name",
|
|
description: "Description",
|
|
priority: "Priority",
|
|
assignedTo: "Assigned To",
|
|
dueDate: "Due Date",
|
|
status: "Status",
|
|
project: "Project",
|
|
template: "Template",
|
|
searchPlaceholder: "Search tasks, projects, city, or address...",
|
|
noTasks: "No tasks",
|
|
noTasksMessage: "No tasks assigned to this project yet.",
|
|
addTaskMessage: "Add a task above to get started.",
|
|
filterBy: "Filter by",
|
|
sortBy: "Sort by",
|
|
allTasks: "All Tasks",
|
|
myTasks: "My Tasks",
|
|
overdue: "Overdue",
|
|
dueSoon: "Due Soon",
|
|
high: "High",
|
|
normal: "Normal",
|
|
medium: "Medium",
|
|
low: "Low",
|
|
dateCreated: "Date Created",
|
|
dateModified: "Date Modified",
|
|
daysLeft: "days left",
|
|
daysOverdue: "days overdue",
|
|
dueToday: "Due Today",
|
|
startTask: "Start Task",
|
|
completeTask: "Complete Task",
|
|
comments: "Comments",
|
|
addComment: "Add Comment",
|
|
noComments: "No comments",
|
|
maxWait: "Max Wait",
|
|
dateStarted: "Date Started",
|
|
actions: "Actions",
|
|
urgent: "Urgent",
|
|
updateTask: "Update Task",
|
|
taskType: "Task Type",
|
|
fromTemplate: "From Template",
|
|
customTask: "Custom Task",
|
|
selectTemplate: "Select Task Template",
|
|
chooseTemplate: "Choose a task template...",
|
|
enterTaskName: "Enter custom task name...",
|
|
enterDescription: "Enter task description (optional)...",
|
|
addTask: "Add Task",
|
|
adding: "Adding...",
|
|
addTaskError: "Failed to add task to project",
|
|
notes: "notes",
|
|
deleteNote: "Delete note",
|
|
deleteError: "Error deleting task",
|
|
notStarted: "Not started",
|
|
days: "days"
|
|
},
|
|
|
|
taskTemplates: {
|
|
title: "Task Templates",
|
|
subtitle: "Manage task templates",
|
|
newTemplate: "New Template",
|
|
editTemplate: "Edit Template",
|
|
deleteTemplate: "Delete Template",
|
|
templateName: "Template Name",
|
|
templateDescription: "Template Description",
|
|
defaultPriority: "Default Priority",
|
|
estimatedDuration: "Estimated Duration",
|
|
category: "Category",
|
|
searchPlaceholder: "Search templates...",
|
|
noTemplates: "No templates",
|
|
noTemplatesMessage: "Get started by creating your first task template.",
|
|
useTemplate: "Use Template",
|
|
duplicateTemplate: "Duplicate Template"
|
|
},
|
|
|
|
forms: {
|
|
validation: {
|
|
required: "This field is required",
|
|
email: "Please enter a valid email address",
|
|
minLength: "Minimum length: {min} characters",
|
|
maxLength: "Maximum length: {max} characters",
|
|
invalidDate: "Invalid date",
|
|
invalidCoordinates: "Invalid coordinates"
|
|
},
|
|
placeholders: {
|
|
enterText: "Enter text...",
|
|
selectDate: "Select date",
|
|
selectOption: "Select option",
|
|
searchResults: "Search results..."
|
|
}
|
|
},
|
|
|
|
sorting: {
|
|
sortBy: "Sort by",
|
|
orderBy: "Order by",
|
|
ascending: "Ascending",
|
|
descending: "Descending",
|
|
name: "Name",
|
|
date: "Date",
|
|
status: "Status",
|
|
priority: "Priority",
|
|
dateCreated: "Date Created",
|
|
dateModified: "Date Modified",
|
|
startDate: "Start Date",
|
|
finishDate: "Finish Date"
|
|
},
|
|
|
|
dates: {
|
|
today: "Today",
|
|
yesterday: "Yesterday",
|
|
tomorrow: "Tomorrow",
|
|
daysAgo: "{count} days ago",
|
|
inDays: "in {count} days",
|
|
invalidDate: "Invalid date",
|
|
selectDate: "Select date"
|
|
},
|
|
|
|
mapLayers: {
|
|
polishOrthophoto: "🛰️ Polish Orthophoto",
|
|
polishCadastral: "📋 Polish Cadastral Data",
|
|
polishSpatialPlanning: "🏗️ Polish Spatial Planning",
|
|
lpPortalRoads: "🛣️ LP-Portal Roads",
|
|
lpPortalStreetNames: "🏷️ LP-Portal Street Names",
|
|
lpPortalParcels: "📐 LP-Portal Parcels",
|
|
lpPortalSurveyMarkers: "📍 LP-Portal Survey Markers",
|
|
openStreetMap: "🗺️ OpenStreetMap",
|
|
googleSatellite: "🛰️ Google Satellite",
|
|
googleRoads: "🛣️ Google Roads",
|
|
layerControl: "Layer Control",
|
|
baseLayers: "Base Layers",
|
|
overlayLayers: "Overlay Layers",
|
|
opacity: "Opacity"
|
|
},
|
|
|
|
auth: {
|
|
signIn: "Sign In",
|
|
signOut: "Sign Out",
|
|
email: "Email",
|
|
password: "Password",
|
|
rememberMe: "Remember Me",
|
|
forgotPassword: "Forgot Password?",
|
|
signInWith: "Sign in with",
|
|
signUp: "Sign Up",
|
|
createAccount: "Create Account",
|
|
alreadyHaveAccount: "Already have an account?",
|
|
dontHaveAccount: "Don't have an account?",
|
|
signInError: "Sign in error",
|
|
signOutError: "Sign out error",
|
|
emailRequired: "Email is required",
|
|
passwordRequired: "Password is required",
|
|
invalidCredentials: "Invalid credentials"
|
|
},
|
|
|
|
userRoles: {
|
|
admin: "Administrator",
|
|
user: "User",
|
|
manager: "Manager",
|
|
viewer: "Viewer"
|
|
},
|
|
|
|
errors: {
|
|
generic: "An error occurred. Please try again.",
|
|
network: "Network connection error",
|
|
unauthorized: "Unauthorized",
|
|
forbidden: "Forbidden",
|
|
notFound: "Not found",
|
|
validation: "Validation error",
|
|
server: "Server error",
|
|
timeout: "Request timeout",
|
|
unknown: "Unknown error"
|
|
},
|
|
|
|
success: {
|
|
saved: "Saved successfully",
|
|
created: "Created successfully",
|
|
updated: "Updated successfully",
|
|
deleted: "Deleted successfully",
|
|
sent: "Sent successfully",
|
|
completed: "Completed successfully"
|
|
},
|
|
|
|
admin: {
|
|
title: "Administration",
|
|
userManagement: "User Management",
|
|
auditLogs: "Audit Logs",
|
|
systemSettings: "System Settings",
|
|
users: "Users",
|
|
newUser: "New User",
|
|
editUser: "Edit User",
|
|
deleteUser: "Delete User",
|
|
userName: "User Name",
|
|
userEmail: "User Email",
|
|
userRole: "User Role",
|
|
active: "Active",
|
|
inactive: "Inactive",
|
|
lastLogin: "Last Login",
|
|
createdAt: "Created At",
|
|
noUsers: "No users",
|
|
system: "System"
|
|
},
|
|
|
|
// Settings
|
|
settings: {
|
|
title: "Settings",
|
|
appearance: "Appearance",
|
|
theme: "Theme",
|
|
themeDescription: "Choose your preferred theme",
|
|
language: "Language",
|
|
languageDescription: "Select your preferred language",
|
|
password: "Password",
|
|
passwordDescription: "Change your account password",
|
|
currentPassword: "Current Password",
|
|
newPassword: "New Password",
|
|
confirmPassword: "Confirm New Password",
|
|
changePassword: "Change Password"
|
|
}
|
|
}
|
|
};
|
|
|
|
// Translation provider component
|
|
export function TranslationProvider({ children, initialLanguage = 'pl' }) {
|
|
const [language, setLanguage] = useState(initialLanguage);
|
|
|
|
// Load language from localStorage on mount
|
|
useEffect(() => {
|
|
const savedLanguage = localStorage.getItem('app-language');
|
|
if (savedLanguage && translations[savedLanguage]) {
|
|
setLanguage(savedLanguage);
|
|
}
|
|
}, []);
|
|
|
|
// Save language to localStorage when changed
|
|
useEffect(() => {
|
|
localStorage.setItem('app-language', language);
|
|
}, [language]);
|
|
|
|
const changeLanguage = (newLanguage) => {
|
|
if (translations[newLanguage]) {
|
|
setLanguage(newLanguage);
|
|
}
|
|
};
|
|
|
|
const t = (key, replacements = {}) => {
|
|
const keys = key.split('.');
|
|
let value = translations[language];
|
|
|
|
for (const k of keys) {
|
|
if (value && typeof value === 'object' && k in value) {
|
|
value = value[k];
|
|
} else {
|
|
// Fallback to English if key not found in current language
|
|
value = translations.en;
|
|
for (const fallbackKey of keys) {
|
|
if (value && typeof value === 'object' && fallbackKey in value) {
|
|
value = value[fallbackKey];
|
|
} else {
|
|
console.warn(`Translation key not found: ${key} (language: ${language})`);
|
|
return key; // Return the key itself as fallback
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (typeof value !== 'string') {
|
|
console.warn(`Translation value is not a string: ${key} (language: ${language})`);
|
|
return key;
|
|
}
|
|
|
|
// Replace placeholders like {count}, {min}, {max}, etc.
|
|
let result = value;
|
|
Object.keys(replacements).forEach(placeholder => {
|
|
result = result.replace(new RegExp(`{${placeholder}}`, 'g'), replacements[placeholder]);
|
|
});
|
|
|
|
return result;
|
|
};
|
|
|
|
return (
|
|
<TranslationContext.Provider value={{
|
|
t,
|
|
language,
|
|
changeLanguage,
|
|
availableLanguages: Object.keys(translations)
|
|
}}>
|
|
{children}
|
|
</TranslationContext.Provider>
|
|
);
|
|
}
|
|
|
|
// Hook to use translations
|
|
export function useTranslation() {
|
|
const context = useContext(TranslationContext);
|
|
if (!context) {
|
|
throw new Error('useTranslation must be used within a TranslationProvider');
|
|
}
|
|
return context;
|
|
}
|
|
|
|
// Export translations for direct access if needed
|
|
export { translations };
|