From a0db42fbfe74ef7c1a605773597401d1a41029d1 Mon Sep 17 00:00:00 2001 From: Wojciech Chrzan <94118824+Worshox@users.noreply.github.com> Date: Fri, 3 Apr 2026 12:28:48 +0200 Subject: [PATCH] feat(i18n): add Polish language support (#252) --- client/src/i18n/TranslationContext.tsx | 8 +- client/src/i18n/translations/pl.ts | 1393 ++++++++++++++++++++++++ 2 files changed, 1398 insertions(+), 3 deletions(-) create mode 100644 client/src/i18n/translations/pl.ts diff --git a/client/src/i18n/TranslationContext.tsx b/client/src/i18n/TranslationContext.tsx index f9ef45e..ee03102 100644 --- a/client/src/i18n/TranslationContext.tsx +++ b/client/src/i18n/TranslationContext.tsx @@ -12,6 +12,7 @@ import nl from './translations/nl' import ar from './translations/ar' import br from './translations/br' import cs from './translations/cs' +import pl from './translations/pl' type TranslationStrings = Record @@ -24,14 +25,15 @@ export const SUPPORTED_LANGUAGES = [ { value: 'nl', label: 'Nederlands' }, { value: 'br', label: 'Português (Brasil)' }, { value: 'cs', label: 'Česky' }, + { value: 'pl', label: 'Polski' }, { value: 'ru', label: 'Русский' }, { value: 'zh', label: '中文' }, { value: 'it', label: 'Italiano' }, { value: 'ar', label: 'العربية' }, ] as const -const translations: Record = { de, en, es, fr, hu, it, ru, zh, nl, ar, br, cs } -const LOCALES: Record = { de: 'de-DE', en: 'en-US', es: 'es-ES', fr: 'fr-FR', hu: 'hu-HU', it: 'it-IT', ru: 'ru-RU', zh: 'zh-CN', nl: 'nl-NL', ar: 'ar-SA', br: 'pt-BR', cs: 'cs-CZ' } +const translations: Record = { de, en, es, fr, hu, it, ru, zh, nl, ar, br, cs, pl } +const LOCALES: Record = { de: 'de-DE', en: 'en-US', es: 'es-ES', fr: 'fr-FR', hu: 'hu-HU', it: 'it-IT', ru: 'ru-RU', zh: 'zh-CN', nl: 'nl-NL', ar: 'ar-SA', br: 'pt-BR', cs: 'cs-CZ', pl: 'pl-PL' } const RTL_LANGUAGES = new Set(['ar']) export function getLocaleForLanguage(language: string): string { @@ -40,7 +42,7 @@ export function getLocaleForLanguage(language: string): string { export function getIntlLanguage(language: string): string { if (language === 'br') return 'pt-BR' - return ['de', 'es', 'fr', 'hu', 'it', 'ru', 'zh', 'nl', 'ar', 'cs'].includes(language) ? language : 'en' + return ['de', 'es', 'fr', 'hu', 'it', 'ru', 'zh', 'nl', 'ar', 'cs', 'pl'].includes(language) ? language : 'en' } export function isRtlLanguage(language: string): boolean { diff --git a/client/src/i18n/translations/pl.ts b/client/src/i18n/translations/pl.ts new file mode 100644 index 0000000..237698c --- /dev/null +++ b/client/src/i18n/translations/pl.ts @@ -0,0 +1,1393 @@ +const pl: Record = { + // Common + 'common.save': 'Zapisz', + 'common.cancel': 'Anuluj', + 'common.delete': 'Usuń', + 'common.edit': 'Edytuj', + 'common.add': 'Dodaj', + 'common.loading': 'Ładowanie...', + 'common.error': 'Błąd', + 'common.back': 'Wstecz', + 'common.all': 'Wszystko', + 'common.close': 'Zamknij', + 'common.open': 'Otwórz', + 'common.upload': 'Prześlij', + 'common.search': 'Szukaj', + 'common.confirm': 'Potwierdź', + 'common.ok': 'OK', + 'common.yes': 'Tak', + 'common.no': 'Nie', + 'common.or': 'lub', + 'common.none': 'Brak', + 'common.date': 'Data', + 'common.rename': 'Zmień nazwę', + 'common.name': 'Nazwa', + 'common.email': 'E-mail', + 'common.password': 'Hasło', + 'common.saving': 'Zapisywanie...', + 'common.update': 'Aktualizuj', + 'common.change': 'Zmień', + 'common.uploading': 'Przesyłanie...', + 'common.backToPlanning': 'Powrót do planowania', + 'common.reset': 'Reset', + + // Navbar + 'nav.trip': 'Podróż', + 'nav.share': 'Udostępnij', + 'nav.settings': 'Ustawienia', + 'nav.admin': 'Admin', + 'nav.logout': 'Wyloguj', + 'nav.lightMode': 'Tryb jasny', + 'nav.darkMode': 'Tryb ciemny', + 'nav.autoMode': 'Tryb automatyczny', + 'nav.administrator': 'Administrator', + + // Dashboard + 'dashboard.title': 'Moje podróże', + 'dashboard.subtitle.loading': 'Ładowanie podróży...', + 'dashboard.subtitle.trips': '{count} podróży ({archived} zarchiwizowanych)', + 'dashboard.subtitle.empty': 'Rozpocznij swoją pierwszą podróż', + 'dashboard.subtitle.activeOne': '{count} aktywna podróż', + 'dashboard.subtitle.activeMany': '{count} aktywnych podróży', + 'dashboard.subtitle.archivedSuffix': ' · {count} zarchiwizowanych', + 'dashboard.newTrip': 'Nowa podróż', + 'dashboard.gridView': 'Widok siatki', + 'dashboard.listView': 'Widok listy', + 'dashboard.currency': 'Waluta', + 'dashboard.timezone': 'Strefy czasowe', + 'dashboard.localTime': 'Czas lokalny', + 'dashboard.timezoneCustomTitle': 'Własna strefa czasowa', + 'dashboard.timezoneCustomLabelPlaceholder': 'Nazwa (opcjonalnie)', + 'dashboard.timezoneCustomTzPlaceholder': 'np. Europe/Warsaw', + 'dashboard.timezoneCustomAdd': 'Dodaj', + 'dashboard.timezoneCustomErrorEmpty': 'Podaj identyfikator strefy czasowej', + 'dashboard.timezoneCustomErrorInvalid': 'Nieprawidłowa strefa czasowa. Użyj formatu takiego jak Europe/Warsaw', + 'dashboard.timezoneCustomErrorDuplicate': 'Już dodana', + 'dashboard.emptyTitle': 'Brak podróży', + 'dashboard.emptyText': 'Utwórz swoją pierwszą podróż i zacznij planować!', + 'dashboard.emptyButton': 'Utwórz pierwszą podróż', + 'dashboard.nextTrip': 'Następna podróż', + 'dashboard.shared': 'Udostępniona', + 'dashboard.sharedBy': 'Udostępniona przez {name}', + 'dashboard.days': 'Dni', + 'dashboard.places': 'Miejsca', + 'dashboard.archive': 'Archiwizuj', + 'dashboard.restore': 'Przywróć', + 'dashboard.archived': 'Zarchiwizowana', + 'dashboard.status.ongoing': 'W trakcie', + 'dashboard.status.today': 'Dzisiaj', + 'dashboard.status.tomorrow': 'Jutro', + 'dashboard.status.past': 'Zakończona', + 'dashboard.status.daysLeft': '{count} dni do końca', + 'dashboard.toast.loadError': 'Nie udało się załadować podróży', + 'dashboard.toast.created': 'Podróż została utworzona pomyślnie!', + 'dashboard.toast.createError': 'Nie udało się utworzyć podróży', + 'dashboard.toast.updated': 'Podróż została zaktualizowana!', + 'dashboard.toast.updateError': 'Nie udało się zaktualizować podróży', + 'dashboard.toast.deleted': 'Podróż została usunięta', + 'dashboard.toast.deleteError': 'Nie udało się usunąć podróży', + 'dashboard.toast.archived': 'Podróż została zarchiwizowana', + 'dashboard.toast.archiveError': 'Nie udało się zarchiwizować podróży', + 'dashboard.toast.restored': 'Podróż została przywrócona', + 'dashboard.toast.restoreError': 'Nie udało się przywrócić podróży', + 'dashboard.confirm.delete': 'Usunąć podróż "{title}"? Wszystkie miejsca i plany zostaną trwale usunięte.', + 'dashboard.editTrip': 'Edytuj podróż', + 'dashboard.createTrip': 'Utwórz nową podróż', + 'dashboard.tripTitle': 'Nazwa podróży', + 'dashboard.tripTitlePlaceholder': 'np. Lato w Japonii', + 'dashboard.tripDescription': 'Opis', + 'dashboard.tripDescriptionPlaceholder': 'Opisz swoją podróż', + 'dashboard.startDate': 'Data rozpoczęcia', + 'dashboard.endDate': 'Data zakończenia', + 'dashboard.noDateHint': 'Nie ustawiono daty — zostanie utworzonych 7 domyślnych dni. Możesz to zmienić w dowolnym momencie.', + 'dashboard.coverImage': 'Okładka', + 'dashboard.addCoverImage': 'Dodaj okładkę (lub przeciągnij i upuść)', + 'dashboard.addMembers': 'Uczestnicy podróży', + 'dashboard.addMember': 'Dodaj uczestnika', + 'dashboard.coverSaved': 'Okładka została zapisana', + 'dashboard.coverUploadError': 'Nie udało się przesłać okładki', + 'dashboard.coverRemoveError': 'Nie udało się usunąć okładki', + 'dashboard.titleRequired': 'Nazwa podróży jest wymagana', + 'dashboard.endDateError': 'Data zakończenia musi być po dacie rozpoczęcia', + + // Settings + 'settings.title': 'Ustawienia', + 'settings.subtitle': 'Skonfiguruj swoje ustawienia', + 'settings.map': 'Mapa', + 'settings.mapTemplate': 'Szablon mapy', + 'settings.mapTemplatePlaceholder.select': 'Wybierz szablon...', + 'settings.mapDefaultHint': 'Pozostaw puste dla OpenStreetMap (domyślnie)', + 'settings.mapTemplatePlaceholder': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + 'settings.mapHint': 'Szablon URL dla kafelków mapy', + 'settings.latitude': 'Szerokość', + 'settings.longitude': 'Długość', + 'settings.saveMap': 'Zapisz mapę', + 'settings.apiKeys': 'Klucze API', + 'settings.mapsKey': 'Klucz Google Maps API', + 'settings.mapsKeyHint': 'Do wyszukiwania miejsc. Wymaga Places API (New). Uzyskaj dostęp na console.cloud.google.com', + 'settings.weatherKey': 'Klucz OpenWeatherMap API', + 'settings.weatherKeyHint': 'Do danych pogodowych. Bezpłatnie na openweathermap.org/api', + 'settings.keyPlaceholder': 'Podaj klucz...', + 'settings.configured': 'Skonfigurowano', + 'settings.saveKeys': 'Zapisz klucze', + 'settings.display': 'Preferencje', + 'settings.colorMode': 'Motyw', + 'settings.light': 'Jasny', + 'settings.dark': 'Ciemny', + 'settings.auto': 'Automatyczny', + 'settings.language': 'Język', + 'settings.temperature': 'Jednostka temperatury', + 'settings.timeFormat': 'Format czasu', + 'settings.routeCalculation': 'Obliczanie trasy', + 'settings.blurBookingCodes': 'Rozmyj kody rezerwacji', + 'settings.notifications': 'Powiadomienia', + 'settings.notifyTripInvite': 'Zaproszenia do podróży', + 'settings.notifyBookingChange': 'Zmiany w rezerwacjach', + 'settings.notifyTripReminder': 'Przypomnienia o podróżach', + 'settings.notifyVacayInvite': 'Zaproszenia do połączenia kalendarzy', + 'settings.notifyPhotosShared': 'Udostępnione zdjęcia (Immich)', + 'settings.notifyCollabMessage': 'Wiadomości czatu (Collab)', + 'settings.notifyPackingTagged': 'Lista pakowania: przypisania', + 'settings.notifyWebhook': 'Powiadomienia Webhook', + 'admin.smtp.title': 'E-maile i powiadomienia', + 'admin.smtp.hint': 'Konfiguracja SMTP dla powiadomień e-mail. Opcjonalnie: URL Webhooka dla Discorda, Slacka, itp.', + 'admin.smtp.testButton': 'Wyślij testowego e-maila', + 'admin.smtp.testSuccess': 'Testowy e-mail został wysłany pomyślnie', + 'admin.smtp.testFailed': 'Nie udało się wysłać testowego e-maila', + 'dayplan.icsTooltip': 'Eksportuj kalendarz (ICS)', + 'share.linkTitle': 'Publiczny link', + 'share.linkHint': 'Utwórz link umożliwiający przeglądanie tej podróży bez logowania. Tylko do odczytu — bez możliwości edycji.', + 'share.createLink': 'Utwórz link', + 'share.deleteLink': 'Usuń link', + 'share.createError': 'Nie udało się utworzyć linku', + 'common.copy': 'Kopiuj', + 'common.copied': 'Skopiowano', + 'share.permMap': 'Mapa i plan', + 'share.permBookings': 'Rezerwacje', + 'share.permPacking': 'Lista pakowania', + 'shared.expired': 'Link wygasł lub jest nieprawidłowy', + 'shared.expiredHint': 'Ten link do podróży jest już nieaktywny.', + 'shared.readOnly': 'Widok udostępniony tylko do odczytu', + 'shared.tabPlan': 'Plan', + 'shared.tabBookings': 'Rezerwacje', + 'shared.tabPacking': 'Lista pakowania', + 'shared.tabBudget': 'Budżet', + 'shared.tabChat': 'Czat', + 'shared.days': 'dni', + 'shared.places': 'miejsca', + 'shared.other': 'Inne', + 'shared.totalBudget': 'Całkowity budżet', + 'shared.messages': 'wiadomości', + 'shared.sharedVia': 'Udostępnione przez', + 'shared.confirmed': 'Potwierdzone', + 'shared.pending': 'Oczekujące', + 'share.permBudget': 'Budżet', + 'share.permCollab': 'Czat', + 'settings.on': 'Włączone', + 'settings.off': 'Wyłączone', + 'settings.mcp.title': 'Konfiguracja MCP', + 'settings.mcp.endpoint': 'Endpoint MCP', + 'settings.mcp.clientConfig': 'Konfiguracja klienta', + 'settings.mcp.clientConfigHint': 'Zastąp tokenem API z listy poniżej. Ścieżka do npx może wymagać dostosowania do Twojego systemu (np. C:\\PROGRA~1\\nodejs\\npx.cmd w systemie Windows).', + 'settings.mcp.copy': 'Kopiuj', + 'settings.mcp.copied': 'Skopiowano!', + 'settings.mcp.apiTokens': 'Tokeny API', + 'settings.mcp.createToken': 'Utwórz nowy token', + 'settings.mcp.noTokens': 'Brak tokenów. Utwórz go, aby połączyć klientów MCP.', + 'settings.mcp.tokenCreatedAt': 'Utworzono', + 'settings.mcp.tokenUsedAt': 'Użyto', + 'settings.mcp.deleteTokenTitle': 'Usuń token', + 'settings.mcp.deleteTokenMessage': 'Ten token przestanie działać natychmiastowo. Każdy klient MCP używający go straci dostęp.', + 'settings.mcp.modal.createTitle': 'Utwórz token API', + 'settings.mcp.modal.tokenName': 'Nazwa tokenu', + 'settings.mcp.modal.tokenNamePlaceholder': 'np. Claude Desktop, Laptop służbowy', + 'settings.mcp.modal.creating': 'Tworzenie...', + 'settings.mcp.modal.create': 'Utwórz token', + 'settings.mcp.modal.createdTitle': 'Token został utworzony', + 'settings.mcp.modal.createdWarning': 'Ten token zostanie wyświetlony tylko raz. Skopiuj i zapisz go — nie będzie można go zobaczyć ponownie.', + 'settings.mcp.modal.done': 'Gotowe', + 'settings.mcp.toast.created': 'Token został utworzony', + 'settings.mcp.toast.createError': 'Nie udało się utworzyć tokenu', + 'settings.mcp.toast.deleted': 'Token został usunięty', + 'settings.mcp.toast.deleteError': 'Nie udało się usunąć tokenu', + 'settings.account': 'Konto', + 'settings.username': 'Nazwa użytkownika', + 'settings.email': 'E-mail', + 'settings.role': 'Rola', + 'settings.roleAdmin': 'Administrator', + 'settings.oidcLinked': 'Połączono z', + 'settings.changePassword': 'Zmień hasło', + 'settings.currentPassword': 'Aktualne hasło', + 'settings.currentPasswordRequired': 'Aktualne hasło jest wymagane', + 'settings.newPassword': 'Nowe hasło', + 'settings.confirmPassword': 'Potwierdź nowe hasło', + 'settings.updatePassword': 'Zaktualizuj hasło', + 'settings.passwordRequired': 'Proszę podać aktualne i nowe hasło', + 'settings.passwordTooShort': 'Hasło musi mieć co najmniej 8 znaków', + 'settings.passwordMismatch': 'Hasła nie są identyczne', + 'settings.passwordWeak': 'Hasło musi zawierać wielką literę, małą literę i cyfrę', + 'settings.passwordChanged': 'Hasło zostało zmienione pomyślnie', + 'settings.deleteAccount': 'Usuń konto', + 'settings.deleteAccountTitle': 'Usunąć twoje konto?', + 'settings.deleteAccountWarning': 'Twoje konto i wszystkie twoje podróże, miejsca i pliki zostaną trwale usunięte. Tej akcji nie można cofnąć.', + 'settings.deleteAccountConfirm': 'Usuń na zawsze', + 'settings.deleteBlockedTitle': 'Nie można usunąć konta', + 'settings.deleteBlockedMessage': 'Jesteś jedynym administratorem. Wyznacz innego użytkownika na administratora przed usunięciem konta.', + 'settings.roleUser': 'Użytkownik', + 'settings.saveProfile': 'Zapisz profil', + 'settings.toast.mapSaved': 'Ustawienia mapy zostały zapisane', + 'settings.toast.keysSaved': 'Klucze API zostały zapisane', + 'settings.toast.displaySaved': 'Preferencje zostały zapisane', + 'settings.toast.profileSaved': 'Profil został zapisany', + 'settings.uploadAvatar': 'Prześlij zdjęcie profilowe', + 'settings.removeAvatar': 'Usuń zdjęcie profilowe', + 'settings.avatarUploaded': 'Zdjęcie profilowe zostało zaktualizowane', + 'settings.avatarRemoved': 'Zdjęcie profilowe zostało usunięte', + 'settings.avatarError': 'Przesyłanie nie powiodło się', + 'settings.mfa.title': 'Uwierzytelnianie dwuskładnikowe (2FA)', + 'settings.mfa.description': 'Dodaje drugi krok, kiedy logujesz się e-mailem i hasłem. Użyj aplikacji uwierzytelniającej (Google Authenticator, Authy, itp.).', + 'settings.mfa.requiredByPolicy': 'Twój administrator wymaga uwierzytelniania dwuskładnikowego. Skonfiguruj aplikację uwierzytelniającą poniżej, zanim przejdziesz dalej.', + 'settings.mfa.backupTitle': 'Kody zapasowe', + 'settings.mfa.backupDescription': 'Użyj tych jednorazowych kodów zapasowych, jeżeli stracisz dostęp do swojej aplikacji uwierzytelniającej.', + 'settings.mfa.backupWarning': 'Zapisz te kody. Każdy z nich może być wykorzystany tylko raz.', + 'settings.mfa.backupCopy': 'Kopiuj kody', + 'settings.mfa.backupDownload': 'Pobierz TXT', + 'settings.mfa.backupPrint': 'Drukuj / PDF', + 'settings.mfa.backupCopied': 'Kody zapasowe zostały skopiowane', + 'settings.mfa.enabled': '2FA jest włączone dla Twojego konta.', + 'settings.mfa.disabled': '2FA jest wyłączone.', + 'settings.mfa.setup': 'Skonfiguruj aplikację uwierzytelniającą', + 'settings.mfa.scanQr': 'Zeskanuj ten kod QR za pomocą aplikacji lub wprowadź klucz ręcznie.', + 'settings.mfa.secretLabel': 'Tajny klucz (wprowadź ręcznie)', + 'settings.mfa.codePlaceholder': '6-cyfrowy kod', + 'settings.mfa.enable': 'Włącz 2FA', + 'settings.mfa.cancelSetup': 'Anuluj', + 'settings.mfa.disableTitle': 'Wyłącz 2FA', + 'settings.mfa.disableHint': 'Podaj hasło do konta i aktualny kod z aplikacji uwierzytelniającej.', + 'settings.mfa.disable': 'Wyłącz 2FA', + 'settings.mfa.toastEnabled': 'Uwierzytelnianie dwuskładnikowe zostało włączone', + 'settings.mfa.toastDisabled': 'Uwierzytelnianie dwuskładnikowe zostało wyłączone', + 'settings.mfa.demoBlocked': 'Niedostępne w trybie demonstracyjnym', + + // Login + 'login.error': 'Logowanie nie powiodło się. Sprawdź dane logowania.', + 'login.tagline': 'Twoje podróże.\nTwój plan.', + 'login.description': 'Planuj wspólnie podróże z interaktywnymi mapami, budżetami i synchronizacją w czasie rzeczywistym.', + 'login.features.maps': 'Interaktywne mapy', + 'login.features.mapsDesc': 'Google Places, trasy i grupowanie', + 'login.features.realtime': 'Synchronizacja w czasie rzeczywistym', + 'login.features.realtimeDesc': 'Planuj wspólnie przez WebSocket', + 'login.features.budget': 'Śledzenie budżetu', + 'login.features.budgetDesc': 'Kategorie, wykresy i koszty w przeliczeniu na osobę', + 'login.features.collab': 'Współpraca', + 'login.features.collabDesc': 'Wielu użytkowników i wspólne podróże', + 'login.features.packing': 'Listy pakowania', + 'login.features.packingDesc': 'Kategorie, postęp i sugestie', + 'login.features.bookings': 'Rezerwacje', + 'login.features.bookingsDesc': 'Loty, hotele, restauracje i więcej', + 'login.features.files': 'Dokumenty', + 'login.features.filesDesc': 'Przesyłaj i zarządzaj dokumentami', + 'login.features.routes': 'Inteligentne trasy', + 'login.features.routesDesc': 'Automatyczna optymalizacja i eksport do Google Maps', + 'login.selfHosted': 'Własny hosting \u00B7 Otwarty kod źródłowy \u00B7 Twoje dane pozostają Twoje', + 'login.title': 'Zaloguj się', + 'login.subtitle': 'Witaj ponownie', + 'login.signingIn': 'Logowanie...', + 'login.signIn': 'Zaloguj się', + 'login.createAdmin': 'Utwórz konto administratora', + 'login.createAdminHint': 'Skonfiguruj pierwsze konto administratora dla TREK.', + 'login.createAccount': 'Utwórz konto', + 'login.createAccountHint': 'Zarejestruj nowe konto.', + 'login.creating': 'Tworzenie...', + 'login.noAccount': "Nie masz konta?", + 'login.hasAccount': 'Masz już konto?', + 'login.register': 'Zarejestruj się', + 'login.emailPlaceholder': 'twoj@email.pl', + 'login.username': 'Nazwa użytkownika', + 'login.oidc.registrationDisabled': 'Rejestracja jest wyłączona. Skontaktuj się z administratorem.', + 'login.oidc.noEmail': 'Nie otrzymano e-maila od dostawcy.', + 'login.oidc.tokenFailed': 'Nie udało się uwierzytelnić.', + 'login.oidc.invalidState': 'Nieprawidłowa sesja. Spróbuj ponownie.', + 'login.demoFailed': 'Nie udało się zalogować do wersji demonstracyjnej', + 'login.oidcSignIn': 'Zaloguj się z {name}', + 'login.oidcOnly': 'Uwierzytelnianie hasłem jest wyłączone. Zaloguj się za pomocą swojego dostawcy SSO.', + 'login.demoHint': 'Wypróbuj demo — nie wymaga rejestracji', + 'login.mfaTitle': 'Uwierzytelnianie dwuskładnikowe', + 'login.mfaSubtitle': 'Wprowadź 6-cyfrowy kod z aplikacji uwierzytelniającej.', + 'login.mfaCodeLabel': 'Kod weryfikacyjny', + 'login.mfaCodeRequired': 'Wprowadź kod z aplikacji uwierzytelniającej.', + 'login.mfaHint': 'Otwórz Google Authenticator, Authy lub inną aplikację TOTP.', + 'login.mfaBack': '← Powrót do logowania', + 'login.mfaVerify': 'Weryfikuj', + + // Register + 'register.passwordMismatch': 'Hasła nie są identyczne', + 'register.passwordTooShort': 'Hasło musi mieć co najmniej 6 znaków', + 'register.failed': 'Rejestracja nie powiodła się', + 'register.getStarted': 'Rozpocznij', + 'register.subtitle': 'Utwórz konto i zacznij planować swoje wymarzone podróże.', + 'register.feature1': 'Nieograniczone plany podróży', + 'register.feature2': 'Interaktywna mapa', + 'register.feature3': 'Zarządzaj miejscami i kategoriami', + 'register.feature4': 'Śledź rezerwacje', + 'register.feature5': 'Twórz listy pakowania', + 'register.feature6': 'Przechowuj zdjęcia i pliki', + 'register.createAccount': 'Utwórz konto', + 'register.startPlanning': 'Zacznij planować podróż', + 'register.minChars': 'Min. 6 znaków', + 'register.confirmPassword': 'Potwierdź hasło', + 'register.repeatPassword': 'Powtórz hasło', + 'register.registering': 'Rejestrowanie...', + 'register.register': 'Zarejestruj się', + 'register.hasAccount': 'Masz już konto?', + 'register.signIn': 'Zaloguj się', + + // Admin + 'admin.title': 'Administracja', + 'admin.subtitle': 'Zarządzanie użytkownikami i ustawienia systemowe', + 'admin.tabs.users': 'Użytkownicy', + 'admin.tabs.categories': 'Kategorie', + 'admin.tabs.backup': 'Backupy', + 'admin.tabs.audit': 'Aktywność', + 'admin.stats.users': 'Użytkownicy', + 'admin.stats.trips': 'Podróże', + 'admin.stats.places': 'Miejsca', + 'admin.stats.photos': 'Zdjęcia', + 'admin.stats.files': 'Pliki', + 'admin.table.user': 'Użytkownik', + 'admin.table.email': 'E-mail', + 'admin.table.role': 'Rola', + 'admin.table.created': 'Utworzono', + 'admin.table.lastLogin': 'Ostatnie logowanie', + 'admin.table.actions': 'Akcje', + 'admin.you': '(Ty)', + 'admin.editUser': 'Edytuj użytkownika', + 'admin.newPassword': 'Nowe hasło', + 'admin.newPasswordHint': 'Pozostaw puste, aby zachować obecne hasło', + 'admin.deleteUser': 'Usunąć użytkownika "{name}"? Wszystkie jego podróże zostaną trwale usunięte.', + 'admin.deleteUserTitle': 'Usuń użytkownika', + 'admin.newPasswordPlaceholder': 'Podaj nowe hasło...', + 'admin.toast.loadError': 'Nie udało się załadować danych administratora', + 'admin.toast.userUpdated': 'Użytkownik został zaktualizowany', + 'admin.toast.updateError': 'Nie udało się zaktualizować użytkownika', + 'admin.toast.userDeleted': 'Użytkownik został usunięty', + 'admin.toast.deleteError': 'Nie udało się usunąć użytkownika', + 'admin.toast.cannotDeleteSelf': 'Nie można usunąć własnego konta', + 'admin.toast.userCreated': 'Użytkownik został utworzony', + 'admin.toast.createError': 'Nie udało się utworzyć użytkownika', + 'admin.toast.fieldsRequired': 'Nazwa użytkownika, e-mail i hasło są wymagane', + 'admin.createUser': 'Utwórz użytkownika', + 'admin.invite.title': 'Linki zaproszeń', + 'admin.invite.subtitle': 'Twórz jednorazowe linki do rejestracji', + 'admin.invite.create': 'Utwórz link', + 'admin.invite.createAndCopy': 'Utwórz i skopiuj', + 'admin.invite.empty': 'Nie utworzono jeszcze żadnych linków zaproszeń', + 'admin.invite.maxUses': 'Maksymalna liczba użyć', + 'admin.invite.expiry': 'Wygasa po', + 'admin.invite.uses': 'użycia', + 'admin.invite.expiresAt': 'wygasa', + 'admin.invite.createdBy': 'utworzone przez', + 'admin.invite.active': 'Aktywny', + 'admin.invite.expired': 'Wygasł', + 'admin.invite.usedUp': 'Wykorzystany', + 'admin.invite.copied': 'Link zaproszenia został skopiowany do schowka', + 'admin.invite.copyLink': 'Skopiuj link', + 'admin.invite.deleted': 'Link zaproszenia został usunięty', + 'admin.invite.createError': 'Nie udało się utworzyć linku zaproszenia', + 'admin.invite.deleteError': 'Nie udało się usunąć linku zaproszenia', + 'admin.tabs.settings': 'Ustawienia', + 'admin.allowRegistration': 'Zezwól na rejestrację', + 'admin.allowRegistrationHint': 'Nowi użytkownicy mogą się rejestrować samodzielnie', + 'admin.requireMfa': 'Wymagaj uwierzytelniania dwuskładnikowego (2FA)', + 'admin.requireMfaHint': 'Użytkownicy bez 2FA muszą ukończyć konfigurację w Ustawieniach zanim zaczną korzystać z aplikacji.', + 'admin.apiKeys': 'Klucze API', + 'admin.apiKeysHint': 'Opcjonalne. Umożliwiają pobieranie większej ilości danych o miejscach, takich jak zdjęcia i pogoda.', + 'admin.mapsKey': 'Klucz Google Maps API', + 'admin.mapsKeyHint': 'Wymagany do wyszukiwania miejsc. Uzyskaj go na console.cloud.google.com', + 'admin.mapsKeyHintLong': 'Bez klucza API, OpenStreetMap jest wykorzystywany do wyszukiwania miejsc. Z kluczem API Google, zdjęcia, oceny i godziny otwarcia również mogą być pobierane. Uzyskaj go na console.cloud.google.com.', + 'admin.recommended': 'Polecane', + 'admin.weatherKey': 'Klucz OpenWeatherMap API', + 'admin.weatherKeyHint': 'Do danych pogodowych. Uzyskaj go bezpłatnie na openweathermap.org', + 'admin.validateKey': 'Test', + 'admin.keyValid': 'Połączono', + 'admin.keyInvalid': 'Niepoprawny', + 'admin.keySaved': 'Klucze API zostały zapisane', + 'admin.oidcTitle': 'Logowanie jednokrotne (OIDC)', + 'admin.oidcSubtitle': 'Zezwól na logowanie za pomocą zewnętrznych dostawców, takich jak Google, Apple, Authentik lub Keycloak.', + 'admin.oidcDisplayName': 'Wyświetlana nazwa', + 'admin.oidcIssuer': 'URL wystawcy', + 'admin.oidcIssuerHint': 'Adres URL wystawcy OpenID Connect dostawcy, np. https://accounts.google.com', + 'admin.oidcSaved': 'Konfiguracja OIDC została zapisana', + 'admin.oidcOnlyMode': 'Wyłącz uwierzytelnianie hasłem', + 'admin.oidcOnlyModeHint': 'Po włączeniu dozwolone jest tylko logowanie jednokrotne. Logowanie i rejestracja za pomocą hasła są zablokowane.', + + // File Types + 'admin.fileTypes': 'Dozwolone typy plików', + 'admin.fileTypesHint': 'Ustaw, które typy plików mogą być przesyłane przez użytkowników.', + 'admin.fileTypesFormat': 'Rozszerzenia oddzielone przecinkami (np. jpg,png,pdf,doc). Użyj * aby zezwolić na wszystkie typy.', + 'admin.fileTypesSaved': 'Ustawienia typów plików zostały zapisane', + + // Packing Templates & Bag Tracking + 'admin.bagTracking.title': 'Kontrola bagażu', + 'admin.bagTracking.subtitle': 'Włącz wagę i przypisywanie do toreb dla przedmiotów do pakowania', + 'admin.tabs.config': 'Konfiguracja', + 'admin.tabs.templates': 'Szablony pakowania', + 'admin.packingTemplates.title': 'Szablony pakowania', + 'admin.packingTemplates.subtitle': 'Twórz szablony list pakowania do wielokrotnego użycia dla swoich podróży', + 'admin.packingTemplates.create': 'Nowy szablon', + 'admin.packingTemplates.namePlaceholder': 'Nazwa szablonu (np. Wakacje na plaży)', + 'admin.packingTemplates.empty': 'Nie utworzono jeszcze żadnych szablonów', + 'admin.packingTemplates.items': 'przedmiotów', + 'admin.packingTemplates.categories': 'kategorie', + 'admin.packingTemplates.itemName': 'Nazwa przedmiotu', + 'admin.packingTemplates.itemCategory': 'Kategoria', + 'admin.packingTemplates.categoryName': 'Nazwa kategorii (np. Ubrania)', + 'admin.packingTemplates.addCategory': 'Dodaj kategorię', + 'admin.packingTemplates.created': 'Szablon został utworzony', + 'admin.packingTemplates.deleted': 'Szablon został usunięty', + 'admin.packingTemplates.loadError': 'Nie udało się załadować szablonów', + 'admin.packingTemplates.createError': 'Nie udało się utworzyć szablonu', + 'admin.packingTemplates.deleteError': 'Nie udało się usunąć szablonu', + 'admin.packingTemplates.saveError': 'Nie udało się zapisać szablonu', + + // Addons + 'admin.tabs.addons': 'Dodatki', + 'admin.addons.title': 'Dodatki', + 'admin.addons.subtitle': 'Włączaj lub wyłączaj funkcje, aby dostosować swoje doświadczenie w TREK.', + 'admin.addons.catalog.packing.name': 'Pakowanie', + 'admin.addons.catalog.packing.description': 'Listy do przygotowania bagażu na każdą podróż', + 'admin.addons.catalog.budget.name': 'Budżet', + 'admin.addons.catalog.budget.description': 'Śledź wydatki i planuj budżet podróży', + 'admin.addons.catalog.documents.name': 'Dokumenty', + 'admin.addons.catalog.documents.description': 'Przechowuj i zarządzaj dokumentami podróżnymi', + 'admin.addons.catalog.vacay.name': 'Urlopy', + 'admin.addons.catalog.vacay.description': 'Osobisty planer urlopu z widokiem kalendarza', + 'admin.addons.catalog.atlas.name': 'Atlas', + 'admin.addons.catalog.atlas.description': 'Mapa świata z odwiedzonymi krajami i statystykami podróży', + 'admin.addons.catalog.collab.name': 'Collab', + 'admin.addons.catalog.collab.description': 'Notatki w czasie rzeczywistym, ankiety i czat do planowania podróży', + 'admin.addons.catalog.memories.name': 'Zdjęcia (Immich)', + 'admin.addons.catalog.memories.description': 'Udostępniaj zdjęcia z podróży za pośrednictwem swojej instancji Immich', + 'admin.addons.catalog.mcp.name': 'MCP', + 'admin.addons.catalog.mcp.description': 'Model Context Protocol dla integracji asystenta AI', + 'admin.addons.subtitleBefore': 'Włączaj lub wyłączaj funkcje, aby dostosować swoje doświadczenie w ', + 'admin.addons.subtitleAfter': '', + 'admin.addons.enabled': 'Włączone', + 'admin.addons.disabled': 'Wyłączone', + 'admin.addons.type.trip': 'Podróż', + 'admin.addons.type.global': 'Globalne', + 'admin.addons.type.integration': 'Integracja', + 'admin.addons.tripHint': 'Dostępne jako zakładka w każdej podróży', + 'admin.addons.globalHint': 'Dostępne jako osobna sekcja w menu głównym', + 'admin.addons.integrationHint': 'Usługi backendowe i integracje API bez dedykowanej strony', + 'admin.addons.toast.updated': 'Dodatek został zaktualizowany', + 'admin.addons.toast.error': 'Nie udało się zaktualizować dodatku', + 'admin.addons.noAddons': 'Brak dostępnych dodatków', + // Weather info + 'admin.weather.title': 'Dane pogodowe', + 'admin.weather.badge': 'Od 24 marca 2026', + 'admin.weather.description': 'TREK korzysta z Open-Meteo jako źródła danych pogodowych. Open-Meteo to darmowy, otwartoźródłowy serwis pogodowy — klucz API nie jest wymagany.', + 'admin.weather.forecast': '16-dniowa prognoza', + 'admin.weather.forecastDesc': 'Wcześniej 5 dni (OpenWeatherMap)', + 'admin.weather.climate': 'Historyczne dane klimatyczne', + 'admin.weather.climateDesc': 'Średnie z ostatnich 85 lat dla dni poza 16-dniową prognozą', + 'admin.weather.requests': '10,000 zapytań / dzień', + 'admin.weather.requestsDesc': 'Bezpłatnie, bez klucza API', + 'admin.weather.locationHint': 'Pogoda jest określana na podstawie pierwszego miejsca z przypisanymi współrzędnymi w danym dniu. Jeśli do dnia nie przypisano żadnego miejsca, jako punkt odniesienia używane jest dowolne miejsce z listy.', + + // GitHub + 'admin.tabs.mcpTokens': 'Tokeny MCP', + 'admin.mcpTokens.title': 'Tokeny MCP', + 'admin.mcpTokens.subtitle': 'Zarządzaj tokenami API dla wszystkich użytkowników', + 'admin.mcpTokens.owner': 'Właściciel', + 'admin.mcpTokens.tokenName': 'Nazwa tokenu', + 'admin.mcpTokens.created': 'Utworzono', + 'admin.mcpTokens.lastUsed': 'Ostatnio użyto', + 'admin.mcpTokens.never': 'Nigdy', + 'admin.mcpTokens.empty': 'Nie utworzono jeszcze żadnych tokenów MCP', + 'admin.mcpTokens.deleteTitle': 'Usuń token', + 'admin.mcpTokens.deleteMessage': 'Spowoduje to natychmiastowe unieważnienie tokenu. Użytkownik straci dostęp MCP przez ten token.', + 'admin.mcpTokens.deleteSuccess': 'Token został usunięty', + 'admin.mcpTokens.deleteError': 'Nie udało się usunąć tokenu', + 'admin.mcpTokens.loadError': 'Nie udało się załadować tokenów', + 'admin.tabs.github': 'GitHub', + + 'admin.audit.subtitle': 'Zdarzenia związane z bezpieczeństwem i administracją (kopie zapasowe, użytkownicy, MFA, ustawienia).', + 'admin.audit.empty': 'Brak zapisów w historii aktywności.', + 'admin.audit.refresh': 'Odśwież', + 'admin.audit.loadMore': 'Załaduj więcej', + 'admin.audit.showing': '{count} załadowanych · {total} łącznie', + 'admin.audit.col.time': 'Czas', + 'admin.audit.col.user': 'Użytkownik', + 'admin.audit.col.action': 'Akcja', + 'admin.audit.col.resource': 'Zasób', + 'admin.audit.col.ip': 'IP', + 'admin.audit.col.details': 'Szczegóły', + 'admin.github.title': 'Historia wydań', + 'admin.github.subtitle': 'Najnowsze aktualizacje z {repo}', + 'admin.github.latest': 'Najnowsze', + 'admin.github.prerelease': 'Wersja testowa', + 'admin.github.showDetails': 'Pokaż szczegóły', + 'admin.github.hideDetails': 'Ukryj szczegóły', + 'admin.github.loadMore': 'Załaduj więcej', + 'admin.github.loading': 'Ładowanie...', + 'admin.github.error': 'Nie udało się załadować wydań', + 'admin.github.by': 'przez', + 'admin.github.support': 'Pomóż mi rozwijać TREK', + + 'admin.update.available': 'Dostępna aktualizacja', + 'admin.update.text': 'Dostępna jest wersja TREK {version}. Używasz {current}.', + 'admin.update.button': 'Zobacz na GitHubie', + 'admin.update.install': 'Zainstaluj aktualizację', + 'admin.update.confirmTitle': 'Zainstalować aktualizację?', + 'admin.update.confirmText': 'TREK zostanie zaktualizowany z {current} do {version}. Serwer zostanie automatycznie zrestartowany po zakończeniu.', + 'admin.update.dataInfo': 'Wszystkie twoje dane (podróże, użytkownicy, klucze API, przesłane pliki, urlopy, Atlas, budżety) zostaną zachowane.', + 'admin.update.warning': 'Aplikacja będzie niedostępna przez krótki czas podczas restartu.', + 'admin.update.confirm': 'Zaktualizuj', + 'admin.update.installing': 'Aktualizowanie...', + 'admin.update.success': 'Aktualizacja zakończona! Serwer restartuje się...', + 'admin.update.failed': 'Aktualizacja nie powiodła się', + 'admin.update.backupHint': 'Zalecamy utworzenie kopii zapasowej przed aktualizacją.', + 'admin.update.backupLink': 'Zrób kopię zapasową', + 'admin.update.howTo': 'Jak zaktualizować', + 'admin.update.dockerText': 'Twoja instancja TREK działa w Dockerze. Aby zaktualizować do {version}, uruchom następujące polecenia na swoim serwerze:', + 'admin.update.reloadHint': 'Proszę odświeżyć stronę za kilka sekund.', + + // Vacay addon + 'vacay.subtitle': 'Planuj i zarządzaj dniami urlopu', + 'vacay.settings': 'Ustawienia', + 'vacay.year': 'Rok', + 'vacay.addYear': 'Dodaj rok', + 'vacay.removeYear': 'Usuń rok', + 'vacay.removeYearConfirm': 'Usunąć {year}?', + 'vacay.removeYearHint': 'Wszystkie wpisy dotyczące urlopów oraz dni wolnych w tym roku zostaną trwale usunięte.', + 'vacay.remove': 'Usuń', + 'vacay.persons': 'Osoby', + 'vacay.noPersons': 'Nie dodano osób', + 'vacay.addPerson': 'Dodaj osobę', + 'vacay.editPerson': 'Edytuj osobę', + 'vacay.removePerson': 'Usuń osobę', + 'vacay.removePersonConfirm': 'Usunąć {name}?', + 'vacay.removePersonHint': 'Wszystkie wpisy dotyczące urlopów dla tej osoby zostaną trwale usunięte.', + 'vacay.personName': 'Imię', + 'vacay.personNamePlaceholder': 'Podaj imię', + 'vacay.color': 'Kolor', + 'vacay.add': 'Dodaj', + 'vacay.legend': 'Legenda', + 'vacay.publicHoliday': 'Święto państwowe', + 'vacay.companyHoliday': 'Urlop firmowy', + 'vacay.weekend': 'Weekend', + 'vacay.modeVacation': 'Urlop', + 'vacay.modeCompany': 'Urlop firmowy', + 'vacay.entitlement': 'Wymiar', + 'vacay.entitlementDays': 'Dni', + 'vacay.used': 'Wykorzystane', + 'vacay.remaining': 'Pozostało', + 'vacay.carriedOver': 'z {year}', + 'vacay.blockWeekends': 'Blokuj weekendy', + 'vacay.blockWeekendsHint': 'Zapobiegaj wpisywaniu urlopów w weekendy', + 'vacay.weekendDays': 'Dni weekendowe', + 'vacay.mon': 'Pon', + 'vacay.tue': 'Wt', + 'vacay.wed': 'Śr', + 'vacay.thu': 'Czw', + 'vacay.fri': 'Pt', + 'vacay.sat': 'Sob', + 'vacay.sun': 'Nd', + 'vacay.publicHolidays': 'Święta państwowe', + 'vacay.publicHolidaysHint': 'Oznacz święta państwowe w kalendarzu', + 'vacay.selectCountry': 'Wybierz kraj', + 'vacay.selectRegion': 'Wybierz region (opcjonalnie)', + 'vacay.addCalendar': 'Dodaj kalendarz', + 'vacay.calendarLabel': 'Etykieta (opcjonalnie)', + 'vacay.calendarColor': 'Kolor', + 'vacay.noCalendars': 'Nie dodano jeszcze kalendarzy świąt', + 'vacay.companyHolidays': 'Urlopy firmowe', + 'vacay.companyHolidaysHint': 'Pozwala oznaczać dni wolne od pracy w kalendarzu', + 'vacay.companyHolidaysNoDeduct': 'Urlopy firmowe nie są odejmowane od puli dni urlopowych.', + 'vacay.carryOver': 'Przeniesienie na kolejny rok', + 'vacay.carryOverHint': 'Automatycznie przenosi pozostałe dni urlopowe na kolejny rok', + 'vacay.sharing': 'Udostępnianie', + 'vacay.sharingHint': 'Udostępnij swój plan urlopów innym użytkownikom TREK', + 'vacay.owner': 'Właściciel', + 'vacay.shareEmailPlaceholder': 'E-mail użytkownika TREK', + 'vacay.shareSuccess': 'Plan został udostępniony pomyślnie', + 'vacay.shareError': 'Nie udało się udostępnić planu', + 'vacay.dissolve': 'Rozłącz kalendarze', + 'vacay.dissolveHint': 'Rozłącz kalendarze ponownie. Twoje wpisy zostaną zachowane.', + 'vacay.dissolveAction': 'Rozłącz', + 'vacay.dissolved': 'Kalendarz został rozłączony', + 'vacay.fusedWith': 'Połączono z', + 'vacay.you': 'ty', + 'vacay.noData': 'Brak danych', + 'vacay.changeColor': 'Zmień kolor', + 'vacay.inviteUser': 'Zaproś użytkownika', + 'vacay.inviteHint': 'Zaproś innego użytkownika TREK do wspólnego kalendarza urlopów.', + 'vacay.selectUser': 'Wybierz użytkownika', + 'vacay.sendInvite': 'Wyślij zaproszenie', + 'vacay.inviteSent': 'Zaproszenie zostało wysłane', + 'vacay.inviteError': 'Nie udało się wysłać zaproszenia', + 'vacay.pending': 'oczekujące', + 'vacay.noUsersAvailable': 'Brak dostępnych użytkowników', + 'vacay.accept': 'Akceptuj', + 'vacay.decline': 'Odrzuć', + 'vacay.acceptFusion': 'Akceptuj i połącz', + 'vacay.inviteTitle': 'Zaproszenie do połączenia', + 'vacay.inviteWantsToFuse': 'chce udostępnić kalendarz urlopów.', + 'vacay.fuseInfo1': 'Obie strony będą widzieć wszystkie wpisy urlopowe w jednym wspólnym kalendarzu.', + 'vacay.fuseInfo2': 'Obie strony mogą tworzyć i edytować wpisy dla drugiej strony.', + 'vacay.fuseInfo3': 'Obie strony mogą usuwać wpisy i zmieniać pulę dni urlopowych.', + 'vacay.fuseInfo4': 'Ustawienia, takie jak święta państwowe i urlopy firmowe, są współdzielone.', + 'vacay.fuseInfo5': 'Połączenie może zostać rozwiązane w dowolnym momencie przez każdą ze stron. Twoje wpisy zostaną zachowane.', + 'nav.myTrips': 'Moje podróże', + + // Atlas addon + 'atlas.subtitle': 'Twój ślad podróżniczy po świecie', + 'atlas.countries': 'Kraje', + 'atlas.trips': 'Podróże', + 'atlas.places': 'Miejsca', + 'atlas.unmark': 'Usuń', + 'atlas.confirmMark': 'Oznaczyć ten kraj jako odwiedzony?', + 'atlas.confirmUnmark': 'Usunąć ten kraj z listy odwiedzonych?', + 'atlas.markVisited': 'Oznacz jako odwiedzony', + 'atlas.markVisitedHint': 'Dodaj ten kraj do listy odwiedzonych', + 'atlas.addToBucket': 'Dodaj do listy marzeń', + 'atlas.addPoi': 'Dodaj miejsce', + 'atlas.bucketNamePlaceholder': 'Nazwa (kraj, miasto, miejsce...)', + 'atlas.month': 'Miesiąc', + 'atlas.year': 'Rok', + 'atlas.addToBucketHint': 'Zapisz jako miejsce, które chcesz odwiedzić', + 'atlas.bucketWhen': 'Kiedy planujesz je odwiedzić?', + 'atlas.statsTab': 'Statystyki', + 'atlas.bucketTab': 'Lista marzeń', + 'atlas.addBucket': 'Dodaj do listy marzeń', + 'atlas.bucketNamePlaceholder': 'Miejsce lub cel podróży...', + 'atlas.bucketNotesPlaceholder': 'Notatki (opcjonalnie)', + 'atlas.bucketEmpty': 'Twoja lista marzeń jest pusta', + 'atlas.bucketEmptyHint': 'Dodaj miejsca, które chcesz odwiedzić', + 'atlas.days': 'Dni', + 'atlas.visitedCountries': 'Odwiedzone kraje', + 'atlas.cities': 'Miasta', + 'atlas.noData': 'Brak danych o podróżach', + 'atlas.noDataHint': 'Utwórz podróż i dodaj miejsca, aby zobaczyć swoją mapę świata', + 'atlas.lastTrip': 'Ostatnia podróż', + 'atlas.nextTrip': 'Następna podróż', + 'atlas.daysLeft': 'dni do wyjazdu', + 'atlas.streak': 'Streak', + 'atlas.year': 'rok', + 'atlas.years': 'lata', + 'atlas.yearInRow': 'rok z rzędu', + 'atlas.yearsInRow': 'lat z rzędu', + 'atlas.tripIn': 'podróż w', + 'atlas.tripsIn': 'podróży w', + 'atlas.since': 'od', + 'atlas.europe': 'Europa', + 'atlas.asia': 'Azja', + 'atlas.northAmerica': 'Ameryka Pn.', + 'atlas.southAmerica': 'Ameryka Pd.', + 'atlas.africa': 'Afryka', + 'atlas.oceania': 'Oceania', + 'atlas.other': 'Inne', + 'atlas.firstVisit': 'Pierwsza podróż', + 'atlas.lastVisitLabel': 'Ostatnia podróż', + 'atlas.tripSingular': 'Podróż', + 'atlas.tripPlural': 'Podróże', + 'atlas.placeVisited': 'Odwiedzone miejsce', + 'atlas.placesVisited': 'Odwiedzone miejsca', + + // Trip Planner + 'trip.tabs.plan': 'Plan', + 'trip.tabs.reservations': 'Rezerwacje', + 'trip.tabs.reservationsShort': 'Rezerwacje', + 'trip.tabs.packing': 'Lista pakowania', + 'trip.tabs.packingShort': 'Pakowanie', + 'trip.tabs.budget': 'Budżet', + 'trip.tabs.files': 'Pliki', + 'trip.loading': 'Ładowanie podróży...', + 'trip.mobilePlan': 'Plan', + 'trip.mobilePlaces': 'Miejsca', + 'trip.toast.placeUpdated': 'Miejsce zostało zaktualizowane', + 'trip.toast.placeAdded': 'Miejsce zostało dodane', + 'trip.toast.placeDeleted': 'Miejsce zostało usunięte', + 'trip.toast.selectDay': 'Proszę najpierw wybrać dzień', + 'trip.toast.assignedToDay': 'Miejsce przypisane do dnia', + 'trip.toast.reorderError': 'Nie udało się zmienić kolejności', + 'trip.toast.reservationUpdated': 'Rezerwacja została zaktualizowana', + 'trip.toast.reservationAdded': 'Rezerwacja została dodana', + 'trip.toast.deleted': 'Usunięto', + 'trip.confirm.deletePlace': 'Czy na pewno chcesz usunąć to miejsce?', + + // Day Plan Sidebar + 'dayplan.emptyDay': 'Brak miejsc zaplanowanych na ten dzień', + 'dayplan.cannotReorderTransport': 'Nie można zmieniać kolejności dla rezerwacji z określoną godziną', + 'dayplan.confirmRemoveTimeTitle': 'Usunąć godzinę?', + 'dayplan.confirmRemoveTimeBody': 'To miejsce ma określoną godzinę ({time}). Przeniesienie go usunie godzinę i umożliwi swobodne sortowanie.', + 'dayplan.confirmRemoveTimeAction': 'Usuń godzinę i przenieś', + 'dayplan.cannotDropOnTimed': 'Nie można umieszczać elementów pomiędzy wpisami z określoną godziną', + 'dayplan.cannotBreakChronology': 'Spowodowałoby to naruszenie chronologicznej kolejności elementów i rezerwacji z określoną godziną', + 'dayplan.addNote': 'Dodaj notatkę', + 'dayplan.editNote': 'Edytuj notatkę', + 'dayplan.noteAdd': 'Dodaj notatkę', + 'dayplan.noteEdit': 'Edytuj notatkę', + 'dayplan.noteTitle': 'Notatka', + 'dayplan.noteSubtitle': 'Notatka dnia', + 'dayplan.totalCost': 'Łączny koszt', + 'dayplan.days': 'Dni', + 'dayplan.dayN': 'Dzień {n}', + 'dayplan.calculating': 'Obliczanie...', + 'dayplan.route': 'Trasa', + 'dayplan.optimize': 'Optymalizuj', + 'dayplan.optimized': 'Trasa została zoptymalizowana', + 'dayplan.routeError': 'Nie udało się obliczyć trasy', + 'dayplan.toast.needTwoPlaces': 'Potrzeba co najmniej dwóch miejsc, aby zoptymalizować trasę', + 'dayplan.toast.routeOptimized': 'Trasa została zoptymalizowana', + 'dayplan.toast.noGeoPlaces': 'Nie znaleziono miejsc ze współrzędnymi do obliczenia trasy', + 'dayplan.confirmed': 'Potwierdzono', + 'dayplan.pendingRes': 'Oczekujące', + 'dayplan.pdf': 'PDF', + 'dayplan.pdfTooltip': 'Eksportuj plan dnia jako PDF', + 'dayplan.pdfError': 'Nie udało się wyeksportować pliku PDF', + + // Places Sidebar + 'places.addPlace': 'Dodaj miejsce/atrakcję', + 'places.importGpx': 'Importuj GPX', + 'places.gpxImported': '{count} miejsc zaimportowanych z GPX', + 'places.urlResolved': 'Miejsce zaimportowane z URL', + 'places.gpxError': 'Nie udało się zaimportować pliku GPX', + 'places.assignToDay': 'Do którego dnia dodać?', + 'places.all': 'Wszystkie', + 'places.unplanned': 'Niezaplanowane', + 'places.search': 'Szukaj miejsc...', + 'places.allCategories': 'Wszystkie kategorie', + 'places.categoriesSelected': 'kategorii', + 'places.clearFilter': 'Wyczyść filtr', + 'places.count': '{count} miejsc', + 'places.countSingular': '1 miejsce', + 'places.allPlanned': 'Wszystkie miejsca są zaplanowane', + 'places.noneFound': 'Nie znaleziono miejsc', + 'places.editPlace': 'Edytuj miejsce', + 'places.formName': 'Nazwa', + 'places.formNamePlaceholder': 'np. Wieża Eiffla', + 'places.formDescription': 'Opis', + 'places.formDescriptionPlaceholder': 'Krótki opis...', + 'places.formAddress': 'Adres', + 'places.formAddressPlaceholder': 'Ulica, miasto, kraj', + 'places.formLat': 'Szerokość (np. 48.8566)', + 'places.formLng': 'Długość (np. 2.3522)', + 'places.formCategory': 'Kategoria', + 'places.noCategory': 'Brak kategorii', + 'places.categoryNamePlaceholder': 'Nazwa kategorii', + 'places.formTime': 'Godzina', + 'places.startTime': 'Początek', + 'places.endTime': 'Koniec', + 'places.endTimeBeforeStart': 'Godzina zakończenia jest przed godziną rozpoczęcia', + 'places.timeCollision': 'Nakładanie się godzin z:', + 'places.formWebsite': 'Strona internetowa', + 'places.formNotesPlaceholder': 'Osobiste notatki...', + 'places.formReservation': 'Rezerwacja', + 'places.reservationNotesPlaceholder': 'Notatki z rezerwacji, numer potwierdzenia...', + 'places.mapsSearchPlaceholder': 'Szukaj miejsc...', + 'places.mapsSearchError': 'Nie udało się wyszukać miejsca.', + 'places.osmHint': 'Korzystając z OpenStreetMap (brak zdjęć, godzin otwarcia czy ocen). Dodaj klucz API Google w ustawieniach aby uzyskać pełne dane.', + 'places.osmActive': 'Szukaj przez OpenStreetMap (brak zdjęć, ocen czy godzin otwarcia). Dodaj klucz API Google w ustawieniach aby uzyskać pełne dane.', + 'places.categoryCreateError': 'Nie udało się utworzyć kategorii', + 'places.nameRequired': 'Proszę podać nazwę', + 'places.saveError': 'Nie udało się zapisać', + // Place Inspector + 'inspector.opened': 'Otwarte', + 'inspector.closed': 'Zamknięte', + 'inspector.openingHours': 'Godziny otwarcia', + 'inspector.showHours': 'Pokaż godziny otwarcia', + 'inspector.files': 'Pliki', + 'inspector.filesCount': '{count} plików', + 'inspector.removeFromDay': 'Usuń z dnia', + 'inspector.addToDay': 'Dodaj do dnia', + 'inspector.confirmedRes': 'Potwierdzona rezerwacja', + 'inspector.pendingRes': 'Oczekująca rezerwacja', + 'inspector.google': 'Otwórz w Mapach Google', + 'inspector.website': 'Otwórz stronę internetową', + 'inspector.addRes': 'Rezerwacja', + 'inspector.editRes': 'Edytuj rezerwację', + 'inspector.participants': 'Uczestnicy', + + // Reservations + 'reservations.title': 'Rezerwacje', + 'reservations.empty': 'Brak rezerwacji', + 'reservations.emptyHint': 'Dodaj rezerwacje lotów, hoteli i innych', + 'reservations.add': 'Dodaj rezerwację', + 'reservations.addManual': 'Rezerwacja ręczna', + 'reservations.placeHint': 'Wskazówka: Rezerwacje najlepiej tworzyć bezpośrednio z miejsca, aby powiązać je z planem dnia.', + 'reservations.confirmed': 'Potwierdzona', + 'reservations.pending': 'Oczekująca', + 'reservations.summary': '{confirmed} potwierdzonych, {pending} oczekujących', + 'reservations.fromPlan': 'Z planu', + 'reservations.showFiles': 'Pokaż pliki', + 'reservations.editTitle': 'Edytuj rezerwację', + 'reservations.status': 'Status', + 'reservations.datetime': 'Data i czas', + 'reservations.startTime': 'Godzina rozpoczęcia', + 'reservations.endTime': 'Godzina zakończenia', + 'reservations.date': 'Data', + 'reservations.time': 'Godzina', + 'reservations.timeAlt': 'Godzina (alternatywna, np. 19:30)', + 'reservations.notes': 'Notatki', + 'reservations.notesPlaceholder': 'Dodatkowe notatki...', + 'reservations.meta.airline': 'Linia lotnicza', + 'reservations.meta.flightNumber': 'Numer lotu', + 'reservations.meta.from': 'Skąd', + 'reservations.meta.to': 'Dokąd', + 'reservations.meta.trainNumber': 'Numer pociągu', + 'reservations.meta.platform': 'Peron', + 'reservations.meta.seat': 'Miejsce', + 'reservations.meta.checkIn': 'Zameldowanie', + 'reservations.meta.checkOut': 'Wymeldowanie', + 'reservations.meta.linkAccommodation': 'Zakwaterowanie', + 'reservations.meta.pickAccommodation': 'Link do zakwaterowania', + 'reservations.meta.noAccommodation': 'Brak', + 'reservations.meta.hotelPlace': 'Zakwaterowanie', + 'reservations.meta.pickHotel': 'Wybierz zakwaterowanie', + 'reservations.meta.fromDay': 'Od', + 'reservations.meta.toDay': 'Do', + 'reservations.meta.selectDay': 'Wybierz dzień', + 'reservations.type.flight': 'Lot', + 'reservations.type.hotel': 'Zakwaterowanie', + 'reservations.type.restaurant': 'Restauracja', + 'reservations.type.train': 'Pociąg', + 'reservations.type.car': 'Samochód', + 'reservations.type.cruise': 'Rejs', + 'reservations.type.event': 'Wydarzenie', + 'reservations.type.tour': 'Wycieczka', + 'reservations.type.other': 'Inne', + 'reservations.confirm.delete': 'Czy na pewno chcesz usunąć rezerwację "{name}"?', + 'reservations.confirm.deleteTitle': 'Usunąć rezerwację?', + 'reservations.confirm.deleteBody': 'Rezerwacja "{name}" zostanie trwale usunięta.', + 'reservations.toast.updated': 'Rezerwacja została zaktualizowana', + 'reservations.toast.removed': 'Rezerwacja została usunięta', + 'reservations.toast.fileUploaded': 'Plik został przesłany', + 'reservations.toast.uploadError': 'Nie udało się przesłać pliku', + 'reservations.newTitle': 'Nowa rezerwacja', + 'reservations.bookingType': 'Rodzaj rezerwacji', + 'reservations.titleLabel': 'Tytuł', + 'reservations.titlePlaceholder': 'np. Ryanair FR123, Hotel Dubaj, ...', + 'reservations.locationAddress': 'Lokalizacja / Adres', + 'reservations.locationPlaceholder': 'Adres, Lotnisko, Hotel...', + 'reservations.confirmationCode': 'Kod rezerwacji', + 'reservations.confirmationPlaceholder': 'np. ABC12345', + 'reservations.day': 'Dzień', + 'reservations.noDay': 'Brak dnia', + 'reservations.place': 'Miejsce', + 'reservations.noPlace': 'Brak miejsca', + 'reservations.pendingSave': 'zostanie zapisane...', + 'reservations.uploading': 'Przesyłanie...', + 'reservations.attachFile': 'Załącz plik', + 'reservations.linkExisting': 'Podlinkuj przesłany plik', + 'reservations.toast.saveError': 'Nie udało się zapisać', + 'reservations.toast.updateError': 'Nie udało się zaktualizować', + 'reservations.toast.deleteError': 'Nie udało się usunąć', + 'reservations.confirm.remove': 'Usunąć rezerwację "{name}"?', + 'reservations.linkAssignment': 'Przypisz do miejsca', + 'reservations.pickAssignment': 'Wybierz miejsce z planu...', + 'reservations.noAssignment': 'Brak przypisania (samodzielna)', + + // Budget + 'budget.title': 'Budżet', + 'budget.emptyTitle': 'Nie utworzono jeszcze budżetu', + 'budget.emptyText': 'Utwórz kategorie i wpisy, aby zaplanować budżet podróży', + 'budget.emptyPlaceholder': 'Podaj nazwę kategorii...', + 'budget.createCategory': 'Utwórz kategorię', + 'budget.category': 'Kategoria', + 'budget.categoryName': 'Nazwa kategorii', + 'budget.table.name': 'Nazwa', + 'budget.table.total': 'Łącznie', + 'budget.table.persons': 'Osoby', + 'budget.table.days': 'Dni', + 'budget.table.perPerson': 'Za osobę', + 'budget.table.perDay': 'Za dzień', + 'budget.table.perPersonDay': 'Za osobę/dzień', + 'budget.table.note': 'Notatka', + 'budget.newEntry': 'Nowy wpis', + 'budget.defaultEntry': 'Nowy wpis', + 'budget.defaultCategory': 'Nowa kategoria', + 'budget.total': 'Łącznie', + 'budget.totalBudget': 'Całkowity budżet', + 'budget.byCategory': 'Według kategorii', + 'budget.editTooltip': 'Kliknij, aby edytować', + 'budget.confirm.deleteCategory': 'Czy na pewno chcesz usunąć kategorię "{name}" z {count} wpisami?', + 'budget.deleteCategory': 'Usuń kategorię', + 'budget.perPerson': 'Za osobę', + 'budget.paid': 'Zapłacone', + 'budget.open': 'Otwarte', + 'budget.noMembers': 'Brak przypisanych członków', + 'budget.settlement': 'Rozliczenie', + 'budget.settlementInfo': 'Kliknij avatar członka przy pozycji w budżecie, aby oznaczyć go na zielono — oznacza to, że zapłacił. Rozliczenie pokaże, kto komu i ile jest winien.', + 'budget.netBalances': 'Bilans', + + // Files + 'files.title': 'Pliki', + 'files.count': '{count} plików', + 'files.countSingular': '1 plik', + 'files.uploaded': '{count} przesłanych', + 'files.uploadError': 'Przesyłanie nie powiodło się', + 'files.dropzone': 'Przeciągnij pliki tutaj', + 'files.dropzoneHint': 'lub kliknij, aby przeglądać', + 'files.allowedTypes': 'Obrazki, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Maks 50 MB', + 'files.uploading': 'Przesyłanie...', + 'files.filterAll': 'Wszystkie', + 'files.filterPdf': 'PDF', + 'files.filterImages': 'Obrazki', + 'files.filterDocs': 'Dokumenty', + 'files.filterCollab': 'Wspólne notatki', + 'files.sourceCollab': 'Z wspólnych notatek', + 'files.empty': 'Brak plików', + 'files.emptyHint': 'Prześlij pliki, aby dodać je do swojej podróży', + 'files.openTab': 'Otwórz w nowej karcie', + 'files.confirm.delete': 'Czy na pewno chcesz usunąć ten plik?', + 'files.toast.deleted': 'Plik został usunięty', + 'files.toast.deleteError': 'Nie udało się usunąć pliku', + 'files.sourcePlan': 'Plan dni', + 'files.sourceBooking': 'Rezerwacje', + 'files.attach': 'Załącz', + 'files.pasteHint': 'Możesz również wkleić obrazki ze schowka (Ctrl+V)', + 'files.trash': 'Kosz', + 'files.trashEmpty': 'Kosz jest pusty', + 'files.emptyTrash': 'Opróżnij kosz', + 'files.restore': 'Przywróć', + 'files.star': 'Oznacz', + 'files.unstar': 'Usuń oznaczenie', + 'files.assign': 'Przypisz', + 'files.assignTitle': 'Przypisz plik', + 'files.assignPlace': 'Miejsce', + 'files.assignBooking': 'Rezerwacja', + 'files.unassigned': 'Nieprzypisane', + 'files.unlink': 'Usuń link', + 'files.toast.trashed': 'Przeniesiono do kosza', + 'files.toast.restored': 'Plik został przywrócony', + 'files.toast.trashEmptied': 'Kosz został opróżniony', + 'files.toast.assigned': 'Plik został przypisany', + 'files.toast.assignError': 'Nie udało się przypisać', + 'files.toast.restoreError': 'Nie udało się przywrócić', + 'files.confirm.permanentDelete': 'Czy na pewno chcesz trwale usunąć ten plik? Tej operacji nie można cofnąć.', + 'files.confirm.emptyTrash': 'Czy na pewno chcesz trwale usunąć wszystkie pliki z kosza? Tej operacji nie można cofnąć.', + 'files.noteLabel': 'Notatka', + 'files.notePlaceholder': 'Dodaj notatkę...', + + // Packing + 'packing.title': 'Lista pakowania', + 'packing.empty': 'Lista pakowania jest pusta', + 'packing.import': 'Importuj', + 'packing.importTitle': 'Importuj listę pakowania', + 'packing.importHint': 'Jedna pozycja w wierszu. Format: kategoria, nazwa, waga w gramach (opcjonalnie), Torba (opcjonalnie), checked/unchecked (opcjonalnie)', + 'packing.importPlaceholder': 'Higiena, Szczoteczka do zębów\nOdzież, Koszulki, 200\nDokumenty, Paszport, , Podręczny\nElektronika, Ładowarka, 50, Walizka, checked', + 'packing.importCsv': 'Załaduj CSV/TXT', + 'packing.importAction': 'Importuj {count}', + 'packing.importSuccess': '{count} pozycji zaimportowanych', + 'packing.importError': 'Import nie powiódł się', + 'packing.importEmpty': 'Brak pozycji do zaimportowania', + 'packing.progress': '{packed} z {total} spakowanych ({percent}%)', + 'packing.clearChecked': 'Usuń {count} spakowanych', + 'packing.clearCheckedShort': 'Usuń {count}', + 'packing.suggestions': 'Sugestie', + 'packing.suggestionsTitle': 'Dodaj sugestie', + 'packing.allSuggested': 'Dodano wszystkie sugestie', + 'packing.allPacked': 'Wszystko spakowane!', + 'packing.addPlaceholder': 'Dodaj nowy przedmiot...', + 'packing.categoryPlaceholder': 'Kategoria...', + 'packing.filterAll': 'Wszystkie', + 'packing.filterOpen': 'Do spakowania', + 'packing.filterDone': 'Spakowane', + 'packing.emptyTitle': 'Lista pakowania jest pusta', + 'packing.emptyHint': 'Dodaj przedmioty lub użyj sugestii', + 'packing.emptyFiltered': 'Brak przedmiotów pasujących do filtra', + 'packing.menuRename': 'Zmień nazwę', + 'packing.menuCheckAll': 'Zaznacz wszystko', + 'packing.menuUncheckAll': 'Odznacz wszystko', + 'packing.menuDeleteCat': 'Usuń kategorię', + 'packing.assignUser': 'Przypisz użytkownika', + 'packing.noMembers': 'Brak członków podróży', + 'packing.addItem': 'Dodaj przedmiot', + 'packing.addItemPlaceholder': 'Nazwa przedmiotu...', + 'packing.addCategory': 'Dodaj kategorię', + 'packing.newCategoryPlaceholder': 'Nazwa kategorii (np. Odzież)', + 'packing.applyTemplate': 'Zastosuj szablon', + 'packing.template': 'Szablon', + 'packing.templateApplied': '{count} przedmiotów dodanych z szablonu', + 'packing.templateError': 'Nie udało się zastosować szablonu', + 'packing.bags': 'Torby', + 'packing.noBag': 'Nieprzypisane', + 'packing.totalWeight': 'Waga całkowita', + 'packing.bagName': 'Nazwa torby...', + 'packing.addBag': 'Dodaj torbę', + 'packing.changeCategory': 'Zmień kategorię', + 'packing.confirm.clearChecked': 'Czy na pewno chcesz usunąć {count} spakowanych przedmiotów?', + 'packing.confirm.deleteCat': 'Czy na pewno chcesz usunąć kategorię "{name}" z {count} przedmiotami?', + 'packing.defaultCategory': 'Inne', + 'packing.toast.saveError': 'Nie udało się zapisać', + 'packing.toast.deleteError': 'Nie udało się usunąć', + 'packing.toast.renameError': 'Nie udało się zmienić nazwy', + 'packing.toast.addError': 'Nie udało się dodać', + + // Packing suggestions + 'packing.suggestions.items': [ + { name: 'Paszport', category: 'Dokumenty' }, + { name: 'Dowód osobisty', category: 'Dokumenty' }, + { name: 'Ubezpieczenie turystyczne', category: 'Dokumenty' }, + { name: 'Bilety lotnicze', category: 'Dokumenty' }, + { name: 'Karta kredytowa', category: 'Finanse' }, + { name: 'Gotówka', category: 'Finanse' }, + { name: 'Wiza', category: 'Dokumenty' }, + { name: 'Koszulki', category: 'Odzież' }, + { name: 'Spodnie', category: 'Odzież' }, + { name: 'Bielizna', category: 'Odzież' }, + { name: 'Skarpetki', category: 'Odzież' }, + { name: 'Kurtka', category: 'Odzież' }, + { name: 'Piżama', category: 'Odzież' }, + { name: 'Strój kąpielowy', category: 'Odzież' }, + { name: 'Kurtka przeciwdeszczowa', category: 'Odzież' }, + { name: 'Wygodne buty', category: 'Obuwie' }, + { name: 'Szczoteczka do zębów', category: 'Higiena' }, + { name: 'Pasta do zębów', category: 'Higiena' }, + { name: 'Szampon', category: 'Higiena' }, + { name: 'Dezodorant', category: 'Higiena' }, + { name: 'Krem z filtrem', category: 'Higiena' }, + { name: 'Maszynka do golenia', category: 'Higiena' }, + { name: 'Ładowarka', category: 'Elektronika' }, + { name: 'Powerbank', category: 'Elektronika' }, + { name: 'Słuchawki', category: 'Elektronika' }, + { name: 'Adapter podróżny', category: 'Elektronika' }, + { name: 'Aparat', category: 'Elektronika' }, + { name: 'Leki', category: 'Zdrowie' }, + { name: 'Plastry', category: 'Zdrowie' }, + { name: 'Środek dezynfekujący', category: 'Zdrowie' }, + ], + + // Members / Sharing + 'members.shareTrip': 'Udostępnij podróż', + 'members.inviteUser': 'Zaproś użytkownika', + 'members.selectUser': 'Wybierz użytkownika...', + 'members.invite': 'Zaproś', + 'members.allHaveAccess': 'Wszyscy użytkownicy mają już dostęp.', + 'members.access': 'Dostęp', + 'members.person': 'osoba', + 'members.persons': 'osoby', + 'members.you': 'ty', + 'members.owner': 'Właściciel', + 'members.leaveTrip': 'Opuść podróż', + 'members.removeAccess': 'Usuń dostęp', + 'members.confirmLeave': 'Opuścić podróż? Stracisz dostęp.', + 'members.confirmRemove': 'Usunąć dostęp dla tego użytkownika?', + 'members.loadError': 'Nie udało się załadować członków', + 'members.added': 'dodano', + 'members.addError': 'Nie udało się dodać członka', + 'members.removed': 'Usunięto członka', + 'members.removeError': 'Nie udało się usunąć członka', + + // Categories (Admin) + 'categories.title': 'Kategorie', + 'categories.subtitle': 'Zarządzaj kategoriami miejsc', + 'categories.new': 'Nowa kategoria', + 'categories.empty': 'Brak kategorii', + 'categories.namePlaceholder': 'Nazwa kategorii', + 'categories.icon': 'Ikona', + 'categories.color': 'Kolor', + 'categories.customColor': 'Wybierz własny kolor', + 'categories.preview': 'Podgląd', + 'categories.defaultName': 'Kategoria', + 'categories.update': 'Aktualizuj', + 'categories.create': 'Utwórz', + 'categories.confirm.delete': 'Usunąć kategorię? Miejsca w tej kategorii nie zostaną usunięte.', + 'categories.toast.loadError': 'Nie udało się załadować kategorii', + 'categories.toast.nameRequired': 'Proszę podać nazwę', + 'categories.toast.updated': 'Kategoria została zaktualizowana', + 'categories.toast.created': 'Kategoria została utworzona', + 'categories.toast.saveError': 'Nie udało się zapisać kategorii', + 'categories.toast.deleted': 'Kategoria została usunięta', + 'categories.toast.deleteError': 'Nie udało się usunąć kategorii', + + // Backup (Admin) + 'backup.title': 'Kopia zapasowa danych', + 'backup.subtitle': 'Baza danych i wszystkie przesłane pliki', + 'backup.refresh': 'Odśwież', + 'backup.upload': 'Prześlij kopię zapasową', + 'backup.uploading': 'Przesyłanie...', + 'backup.create': 'Utwórz kopię zapasową', + 'backup.creating': 'Tworzenie...', + 'backup.empty': 'Brak kopii zapasowych', + 'backup.createFirst': 'Utwórz pierwszą kopię zapasową', + 'backup.download': 'Pobierz', + 'backup.restore': 'Przywróć', + 'backup.confirm.restore': 'Przywrócić kopię zapasową "{name}"?\n\nWszystkie obecne dane zostaną zastąpione danymi z kopii zapasowej.', + 'backup.confirm.uploadRestore': 'Przesłać i przywrócić plik kopii zapasowej "{name}"?\n\nWszystkie obecne dane zostaną nadpisane.', + 'backup.confirm.delete': 'Usunąć kopię zapasową "{name}"?', + 'backup.toast.loadError': 'Nie udało się załadować kopii zapasowych', + 'backup.toast.created': 'Kopia zapasowa została utworzona pomyślnie', + 'backup.toast.createError': 'Nie udało się utworzyć kopii zapasowej', + 'backup.toast.restored': 'Kopia zapasowa została przywrócona. Strona zostanie przeładowana...', + 'backup.toast.restoreError': 'Nie udało się przywrócić kopii zapasowej', + 'backup.toast.uploadError': 'Nie udało się przesłać kopii zapasowej', + 'backup.toast.deleted': 'Kopia zapasowa została usunięta', + 'backup.toast.deleteError': 'Nie udało się usunąć kopii zapasowej', + 'backup.toast.downloadError': 'Nie udało się pobrać kopii zapasowej', + 'backup.toast.settingsSaved': 'Ustawienia automatycznej kopii zapasowej zostały zapisane', + 'backup.toast.settingsError': 'Nie udało się zapisać ustawień', + 'backup.auto.title': 'Automatyczna kopia zapasowa', + 'backup.auto.subtitle': 'Tworzenie automatycznej kopii zapasowej według harmonogramu', + 'backup.auto.enable': 'Włącz automatyczną kopię zapasową', + 'backup.auto.enableHint': 'Kopie zapasowe będą tworzone automatycznie zgodnie z wybranym harmonogramem', + 'backup.auto.interval': 'Częstotliwość', + 'backup.auto.hour': 'Uruchom o godzinie', + 'backup.auto.hourHint': 'Czas lokalny serwera ({format} format)', + 'backup.auto.dayOfWeek': 'Dzień tygodnia', + 'backup.auto.dayOfMonth': 'Dzień miesiąca', + 'backup.auto.dayOfMonthHint': 'Ograniczone do 1–28 dla kompatybilności ze wszystkimi miesiącami', + 'backup.auto.scheduleSummary': 'Harmonogram', + 'backup.auto.summaryDaily': 'Każdego dnia o {hour}:00', + 'backup.auto.summaryWeekly': 'Co {day} o {hour}:00', + 'backup.auto.summaryMonthly': '{day}. dnia każdego miesiąca o {hour}:00', + 'backup.auto.envLocked': 'Docker', + 'backup.auto.envLockedHint': 'Automatyczne kopie zapasowe są konfigurowane za pomocą zmiennych środowiskowych Dockera. Aby zmienić te ustawienia, zaktualizuj plik docker-compose.yml i uruchom ponownie kontener.', + 'backup.auto.copyEnv': 'Kopiuj zmienne środowiskowe Dockera', + 'backup.auto.envCopied': 'Zmienne środowiskowe Dockera zostały skopiowane do schowka', + 'backup.auto.keepLabel': 'Usuń stare kopie zapasowe po', + 'backup.dow.sunday': 'Nd', + 'backup.dow.monday': 'Pon', + 'backup.dow.tuesday': 'Wt', + 'backup.dow.wednesday': 'Śr', + 'backup.dow.thursday': 'Czw', + 'backup.dow.friday': 'Pt', + 'backup.dow.saturday': 'Sob', + 'backup.interval.hourly': 'Co godzinę', + 'backup.interval.daily': 'Co dzień', + 'backup.interval.weekly': 'Co tydzień', + 'backup.interval.monthly': 'Co miesiąc', + 'backup.keep.1day': '1 dzień', + 'backup.keep.3days': '3 dni', + 'backup.keep.7days': '7 dni', + 'backup.keep.14days': '14 dni', + 'backup.keep.30days': '30 dni', + 'backup.keep.forever': 'Przechowuj na zawsze', + + // Photos + 'photos.allDays': 'Wszystkie dni', + 'photos.noPhotos': 'Brak zdjęć', + 'photos.uploadHint': 'Prześlij zdjęcia z podróży', + 'photos.clickToSelect': 'lub kliknij, aby wybrać', + 'photos.linkPlace': 'Połącz z miejscem', + 'photos.noPlace': 'Brak miejsca', + 'photos.uploadN': 'Prześlij {n} zdjęć', + + // Backup restore modal + 'backup.restoreConfirmTitle': 'Przywrócić kopię zapasową?', + 'backup.restoreWarning': 'Wszystkie obecne dane (podróże, miejsca, użytkownicy, przesłane pliki) zostaną trwale zastąpione danymi z kopii zapasowej. Tej operacji nie można cofnąć.', + 'backup.restoreTip': 'Wskazówka: Przed przywróceniem utwórz kopię zapasową bieżącej instancji.', + 'backup.restoreConfirm': 'Tak, przywróć', + + // PDF + 'pdf.travelPlan': 'Plan podróży', + 'pdf.planned': 'Zaplanowane', + 'pdf.costLabel': 'Koszt w EUR', + 'pdf.preview': 'Podgląd PDF', + 'pdf.saveAsPdf': 'Zapisz jako PDF', + + // Planner + 'planner.places': 'Miejsca', + 'planner.bookings': 'Rezerwacje', + 'planner.packingList': 'Lista pakowania', + 'planner.documents': 'Dokumenty', + 'planner.dayPlan': 'Plan', + 'planner.reservations': 'Rezerwacje', + 'planner.minTwoPlaces': 'Wymagane są przynajmniej dwa miejsca ze współrzędnymi', + 'planner.noGeoPlaces': 'Brak miejsc ze współrzędnymi', + 'planner.routeCalculated': 'Trasa została obliczona', + 'planner.routeCalcFailed': 'Nie udało się obliczyć trasy', + 'planner.routeError': 'Błąd obliczania trasy', + 'planner.routeOptimized': 'Trasa została zoptymalizowana', + 'planner.reservationUpdated': 'Rezerwacja została zaktualizowana', + 'planner.reservationAdded': 'Rezerwacja została dodana', + 'planner.confirmDeleteReservation': 'Usunąć rezerwację?', + 'planner.reservationDeleted': 'Rezerwacja została usunięta', + 'planner.days': 'Dni', + 'planner.allPlaces': 'Wszystkie miejsca', + 'planner.totalPlaces': '{n} miejsc ogółem', + 'planner.noDaysPlanned': 'Nie zaplanowano jeszcze dni', + 'planner.editTrip': 'Edytuj podróż \u2192', + 'planner.placeOne': '1 miejsce', + 'planner.placeN': '{n} miejsc', + 'planner.addNote': 'Dodaj notatkę', + 'planner.noEntries': 'Brak wpisów dla tego dnia', + 'planner.addPlace': 'Dodaj miejsce/atrakcję', + 'planner.addPlaceShort': '+ Dodaj miejsce/atrakcję', + 'planner.resPending': 'Rezerwacja oczekująca · ', + 'planner.resConfirmed': 'Rezerwacja potwierdzona · ', + 'planner.notePlaceholder': 'Notatka\u2026', + 'planner.noteTimePlaceholder': 'Godzina (opcjonalnie)', + 'planner.noteExamplePlaceholder': 'np. S3 o 14:30 z dworca centralnego, prom z molo 7, przerwa na lunch\u2026', + 'planner.totalCost': 'Całkowity koszt', + 'planner.searchPlaces': 'Szukaj miejsc\u2026', + 'planner.allCategories': 'Wszystkie kategorie', + 'planner.noPlacesFound': 'Nie znaleziono miejsc', + 'planner.addFirstPlace': 'Dodaj pierwsze miejsce', + 'planner.noReservations': 'Brak rezerwacji', + 'planner.addFirstReservation': 'Dodaj pierwszą rezerwację', + 'planner.new': 'Nowy', + 'planner.addToDay': '+ Dzień', + 'planner.calculating': 'Obliczanie\u2026', + 'planner.route': 'Trasa', + 'planner.optimize': 'Optymalizuj', + 'planner.openGoogleMaps': 'Otwórz w Google Maps', + 'planner.selectDayHint': 'Wybierz dzień z listy po lewej, aby zobaczyć jego plan', + 'planner.noPlacesForDay': 'Brak miejsc dla tego dnia', + 'planner.addPlacesLink': 'Dodaj miejsca \u2192', + 'planner.minTotal': 'min. łącznie', + 'planner.noReservation': 'Brak rezerwacji', + 'planner.removeFromDay': 'Usuń z dnia', + 'planner.addToThisDay': 'Dodaj do dnia', + 'planner.overview': 'Przegląd', + 'planner.noDays': 'Brak dni', + 'planner.editTripToAddDays': 'Edytuj podróż, aby dodać dni', + 'planner.dayCount': '{n} dni', + 'planner.clickToUnlock': 'Kliknij, aby odblokować', + 'planner.keepPosition': 'Zachowaj pozycję podczas optymalizacji trasy', + 'planner.dayDetails': 'Szczegóły dnia', + 'planner.dayN': 'Dzień {n}', + + // Dashboard Stats + 'stats.countries': 'Kraje', + 'stats.cities': 'Miasta', + 'stats.trips': 'Podróże', + 'stats.places': 'Miejsca', + 'stats.worldProgress': 'Postęp', + 'stats.visited': 'odwiedzone', + 'stats.remaining': 'pozostałe', + 'stats.visitedCountries': 'Odwiedzone kraje', + + // Day Detail Panel + 'day.precipProb': 'Prawdopodobieństwo opadów', + 'day.precipitation': 'Opady', + 'day.wind': 'Wiatr', + 'day.sunrise': 'Wschód słońca', + 'day.sunset': 'Zachód słońca', + 'day.hourlyForecast': 'Prognoza godzinowa', + 'day.climateHint': 'Historyczne średnie — rzeczywista prognoza dostępna na następne 16 dni od tej daty.', + 'day.noWeather': 'Brak danych pogodowych. Dodaj miejsce ze współrzędnymi.', + 'day.overview': 'Przegląd dnia', + 'day.accommodation': 'Zakwaterowanie', + 'day.addAccommodation': 'Dodaj zakwaterowanie', + 'day.hotelDayRange': 'Zastosuj do dni', + 'day.noPlacesForHotel': 'Najpierw dodaj miejsca do swojej podróży', + 'day.allDays': 'Wszystkie', + 'day.checkIn': 'Zameldowanie', + 'day.checkOut': 'Wymeldowanie', + 'day.confirmation': 'Potwierdzenie', + 'day.editAccommodation': 'Edytuj zakwaterowanie', + 'day.reservations': 'Rezerwacje', + + // Photos / Immich + 'memories.title': 'Zdjęcia', + 'memories.notConnected': 'Immich nie jest połączony', + 'memories.notConnectedHint': 'Połącz swoją instancję Immich w ustawieniach, aby przeglądać tutaj swoje zdjęcia z podróży.', + 'memories.noDates': 'Dodaj daty do swojej podróży, aby załadować zdjęcia.', + 'memories.noPhotos': 'Nie znaleziono zdjęć', + 'memories.noPhotosHint': 'Nie znaleziono zdjęć w Immich dla tego zakresu dat podróży.', + 'memories.photosFound': 'zdjęć', + 'memories.fromOthers': 'od innych', + 'memories.sharePhotos': 'Udostępnij zdjęcia', + 'memories.sharing': 'Udostępnianie', + 'memories.reviewTitle': 'Przejrzyj swoje zdjęcia', + 'memories.reviewHint': 'Kliknij w zdjęcia, aby wykluczyć je z udostępnienia.', + 'memories.shareCount': 'Udostępnij {count} zdjęć', + 'memories.immichUrl': 'URL serwera Immich', + 'memories.immichApiKey': 'Klucz API', + 'memories.testConnection': 'Test', + 'memories.connected': 'Połączono', + 'memories.disconnected': 'Nie połączono', + 'memories.connectionSuccess': 'Połączono z Immich', + 'memories.connectionError': 'Nie udało się połączyć z Immich', + 'memories.saved': 'Ustawienia Immich zostały zapisane', + 'memories.addPhotos': 'Dodaj zdjęcia', + 'memories.selectPhotos': 'Wybierz zdjęcia z Immich', + 'memories.selectHint': 'Dotknij zdjęć, aby je zaznaczyć.', + 'memories.selected': 'wybranych', + 'memories.addSelected': 'Dodaj {count} zdjęć', + 'memories.alreadyAdded': 'Dodano', + 'memories.private': 'Prywatne', + 'memories.stopSharing': 'Przestań udostępniać', + 'memories.oldest': 'Od najstarszych', + 'memories.newest': 'Od najnowszych', + 'memories.allLocations': 'Wszystkie lokalizacje', + 'memories.tripDates': 'Daty podróży', + 'memories.allPhotos': 'Wszystkie zdjęcia', + 'memories.confirmShareTitle': 'Udostępnić członkom podróży?', + 'memories.confirmShareHint': '{count} zdjęć będzie widocznych dla wszystkich członków tej podróży. Możesz później ustawić poszczególne zdjęcia jako prywatne.', + 'memories.confirmShareButton': 'Udostępnij zdjęcia', + + // Collab Addon + 'collab.tabs.chat': 'Czat', + 'collab.tabs.notes': 'Notatki', + 'collab.tabs.polls': 'Ankiety', + 'collab.whatsNext.title': 'Co dalej', + 'collab.whatsNext.today': 'Dzisiaj', + 'collab.whatsNext.tomorrow': 'Jutro', + 'collab.whatsNext.empty': 'Brak nadchodzących aktywności', + 'collab.whatsNext.until': 'do', + 'collab.whatsNext.emptyHint': 'Aktywności z godzinami pojawią się tutaj', + 'collab.chat.send': 'Wyślij', + 'collab.chat.placeholder': 'Napisz wiadomość...', + 'collab.chat.empty': 'Rozpocznij konwersację', + 'collab.chat.emptyHint': 'Wiadomości są widoczne dla wszystkich uczestników podróży', + 'collab.chat.emptyDesc': 'Dziel się pomysłami, planami i aktualizacjami z uczestnikami podróży', + 'collab.chat.today': 'Dzisiaj', + 'collab.chat.yesterday': 'Wczoraj', + 'collab.chat.deletedMessage': 'usunięto wiadomość', + 'collab.chat.loadMore': 'Załaduj starsze wiadomości', + 'collab.chat.justNow': 'teraz', + 'collab.chat.minutesAgo': '{n}m temu', + 'collab.chat.hoursAgo': '{n}h temu', + 'collab.notes.title': 'Notatki', + 'collab.notes.new': 'Nowa notatka', + 'collab.notes.empty': 'Brak notatek', + 'collab.notes.emptyHint': 'Zapisuj pomysły i plany', + 'collab.notes.all': 'Wszystkie', + 'collab.notes.titlePlaceholder': 'Tytuł notatki', + 'collab.notes.contentPlaceholder': 'Napisz coś...', + 'collab.notes.categoryPlaceholder': 'Kategoria', + 'collab.notes.newCategory': 'Nowa kategoria...', + 'collab.notes.category': 'Kategoria', + 'collab.notes.noCategory': 'Brak kategorii', + 'collab.notes.color': 'Kolor', + 'collab.notes.save': 'Zapisz', + 'collab.notes.cancel': 'Anuluj', + 'collab.notes.edit': 'Edytuj', + 'collab.notes.delete': 'Usuń', + 'collab.notes.pin': 'Przypnij', + 'collab.notes.unpin': 'Odepnij', + 'collab.notes.daysAgo': '{n}d temu', + 'collab.notes.categorySettings': 'Zarządzaj kategoriami', + 'collab.notes.create': 'Utwórz', + 'collab.notes.website': 'Strona internetowa', + 'collab.notes.websitePlaceholder': 'https://...', + 'collab.notes.attachFiles': 'Załącz pliki', + 'collab.notes.noCategoriesYet': 'Brak kategorii', + 'collab.notes.emptyDesc': 'Utwórz notatkę, aby rozpocząć', + 'collab.polls.title': 'Ankiety', + 'collab.polls.new': 'Nowa ankieta', + 'collab.polls.empty': 'Brak ankiet', + 'collab.polls.emptyHint': 'Zapytaj grupę i głosujcie razem', + 'collab.polls.question': 'Pytanie', + 'collab.polls.questionPlaceholder': 'Co powinniśmy zrobić?', + 'collab.polls.addOption': '+ Dodaj opcję', + 'collab.polls.optionPlaceholder': 'Opcja {n}', + 'collab.polls.create': 'Utwórz ankietę', + 'collab.polls.close': 'Zamknij', + 'collab.polls.closed': 'Zamknięta', + 'collab.polls.votes': '{n} głosów', + 'collab.polls.vote': '{n} głos', + 'collab.polls.multipleChoice': 'Wielokrotny wybór', + 'collab.polls.multiChoice': 'Wielokrotny wybór', + 'collab.polls.deadline': 'Koniec', + 'collab.polls.option': 'Opcja', + 'collab.polls.options': 'Opcje', + 'collab.polls.delete': 'Usuń', + 'collab.polls.closedSection': 'Zamknięte', +} + +export default pl