// Centralna mapa adresów aplikacji. Jedyne źródło prawdy dla nawigacji - // komponenty korzystają z ROUTES zamiast trzymać identyfikatory widoków w stanie. export const ROUTES = { home: '/', buy: '/kupno', rent: '/wynajem', sell: '/jak-sprzedawac', valuation: '/wycena', priceHistory: '/historia-cen', districtRanking: '/ranking-dzielnic', negotiation: '/negocjacje', comparison: '/konto/porownanie', add: '/dodaj-ogloszenie', edit: '/edytuj-ogloszenie/:id', services: '/firmy-i-uslugi', companies: '/firmy', advertising: '/reklama', guides: '/poradniki', guideBuying: '/poradniki/kupno-mieszkania', guideCredit: '/poradniki/kredyty-hipoteczne', guideRent: '/poradniki/wynajem', guideInvesting: '/poradniki/inwestowanie', guideRenovation: '/poradniki/remont-i-wykonczenie', guideLaw: '/poradniki/prawo-i-podatki', guideTopicList: '/poradniki/temat/:topicSlug', guideArticle: '/poradniki/artykul/:id', guideAdd: '/poradniki/dodaj', creditCalculator: '/kalkulator-zdolnosci', map: '/mapa', login: '/logowanie', account: '/konto', accountSearches: '/konto/wyszukiwania', accountPriceAlerts: '/konto/alerty-cenowe', accountMeetings: '/konto/spotkania', accountListings: '/konto/moje-oferty', accountSettings: '/konto/ustawienia', accountSecurity: '/konto/bezpieczenstwo', accountProfileEdit: '/konto/profil/edycja', accountPublicProfile: '/konto/profil', accountHelpContact: '/konto/pomoc', terms: '/regulamin', privacy: '/polityka-prywatnosci', activation: '/aktywacja/:token', passwordReset: '/reset-hasla/:token', notifications: '/powiadomienia', favorites: '/ulubione', messages: '/wiadomosci', // Rozmowa o ogloszeniu (numer z API) albo "administracja" - rozmowa z obsluga serwisu. messagesConversation: '/wiadomosci/:conversationId', // Nowa rozmowa z ogloszenia - watek powstaje na serwerze dopiero z pierwsza wiadomoscia. messagesNew: '/wiadomosci/nowa/:listingId', admin: '/admin', listingDetail: '/oferta/:id', publicProfile: '/profil/:id', // Ten sam profil pod nazwą użytkownika - adres pokazywany w ustawieniach konta. publicProfileByNick: '/u/:nick', } as const; export type RoutePath = (typeof ROUTES)[keyof typeof ROUTES]; // Kanoniczna lista tematów poradników. Slug = ostatni segment adresu i zarazem klucz w API // (/api/articles?topic=slug). `guide` to wbudowany, kompletny poradnik danego tematu. export type GuideTopicMeta = { slug: string; title: string; icon: string; guide: string }; export const GUIDE_TOPICS: GuideTopicMeta[] = [ { slug: 'kupno-mieszkania', title: 'Kupno mieszkania', icon: 'house', guide: ROUTES.guideBuying }, { slug: 'kredyty-hipoteczne', title: 'Kredyty hipoteczne', icon: 'percent', guide: ROUTES.guideCredit }, { slug: 'wynajem', title: 'Wynajem', icon: 'key', guide: ROUTES.guideRent }, { slug: 'inwestowanie', title: 'Inwestowanie', icon: 'chart', guide: ROUTES.guideInvesting }, { slug: 'remont-i-wykonczenie', title: 'Remont i wykończenie', icon: 'paint', guide: ROUTES.guideRenovation }, { slug: 'prawo-i-podatki', title: 'Prawo i podatki', icon: 'scale', guide: ROUTES.guideLaw }, ]; export function guideTopicBySlug(slug: string | undefined): GuideTopicMeta | undefined { return GUIDE_TOPICS.find((topic) => topic.slug === slug); } // Kafelki tematów na /poradniki prowadzą do listy poradników danego tematu. export function guideTopicListPath(slug: string): string { return `/poradniki/temat/${slug}`; } // Pojedynczy artykuł użytkownika. export function articlePath(id: number): string { return `/poradniki/artykul/${id}`; } // Formularz dodawania artykułu z opcjonalnym wstępnie wybranym tematem. export function guideAddPath(topicSlug?: string): string { return topicSlug ? `${ROUTES.guideAdd}?temat=${encodeURIComponent(topicSlug)}` : ROUTES.guideAdd; } // Szczegóły oferty: identyfikator trafia do adresu, nie do stanu Reacta. export function listingPath(id: number): string { return `/oferta/${id}`; } // Profil publiczny innego użytkownika - otwierany m.in. z rozmowy w wiadomościach. export function publicProfilePath(id: number): string { return `/profil/${id}`; } // Identyfikator rozmowy z obsluga serwisu w adresie /wiadomosci/:conversationId. export const ADMIN_CONVERSATION_SLUG = 'administracja'; export function conversationPath(id: number | typeof ADMIN_CONVERSATION_SLUG): string { return `/wiadomosci/${id}`; } export function newConversationPath(listingId: number): string { return `/wiadomosci/nowa/${listingId}`; } // Dedykowana strona edycji wlasnego ogloszenia. export function listingEditPath(id: number): string { return `/edytuj-ogloszenie/${id}`; } // Profil pod nazwą użytkownika. Nick jest unikalny w skali serwisu, więc jednoznacznie // wskazuje osobę - imię i nazwisko może się powtarzać u wielu kont. export function publicProfileNickPath(nick: string): string { return `/u/${encodeURIComponent(nick)}`; } // Negocjacje dotyczą konkretnej oferty - bez identyfikatora pokazujemy pierwszą z listy. export function negotiationPath(offerId?: number | null): string { return offerId ? `${ROUTES.negotiation}/${offerId}` : ROUTES.negotiation; } // Lista ofert kupna zawężona do miasta - miasto w query stringu, żeby link działał po odświeżeniu // i dało się go udostępnić (np. kliknięcie kafelka miasta na stronie głównej). export function buyCityPath(city: string): string { const params = new URLSearchParams(); params.set('miasto', city); return `${ROUTES.buy}?${params.toString()}`; } // Mapa: miasto i typ oferty jako parametry zapytania, dzięki czemu wynik da się udostępnić. export function mapPath(city?: string, offerType?: 'SALE' | 'RENT'): string { const params = new URLSearchParams(); if (city) { params.set('miasto', city); } if (offerType === 'RENT') { params.set('typ', 'wynajem'); } const query = params.toString(); return query ? `${ROUTES.map}?${query}` : ROUTES.map; } // Historia cen z wybraną lokalizacją w adresie - wejście z alertu cenowego otwiera // od razu to miasto, a link da się skopiować, odświeżyć i otworzyć w nowej karcie. export function priceHistoryPath(label?: string, propertyType?: string, marketType?: string): string { const params = new URLSearchParams(); if (label) { params.set('lokalizacja', label); } if (propertyType) { params.set('typ', propertyType); } if (marketType) { params.set('rynek', marketType); } const query = params.toString(); return query ? `${ROUTES.priceHistory}?${query}` : ROUTES.priceHistory; } // Lista firm i usług: kategoria w query stringu, dzięki czemu widok da się // skopiować, odświeżyć i otworzyć w nowej karcie. export function companiesPath(categorySlug?: string): string { return categorySlug ? `${ROUTES.companies}?kategoria=${encodeURIComponent(categorySlug)}` : ROUTES.companies; } // Strona "Jeszcze nie mamy tej usługi" z formularzem reklamowym. Kategoria trafia do query // stringu, żeby po wejściu z kafelka pole "Rodzaj usługi" było już wypełnione. export function advertisingPath(categorySlug?: string): string { return categorySlug ? `${ROUTES.advertising}?kategoria=${encodeURIComponent(categorySlug)}` : ROUTES.advertising; } // Zakładki panelu administratora jako podścieżki /admin/*. export const ADMIN_TAB_PATHS = { dashboard: '', listings: 'ogloszenia', users: 'uzytkownicy', messages: 'wiadomosci', support: 'pomoc-i-kontakt', advertisingEnquiries: 'zapytania-o-reklame', reports: 'zgloszenia', articleRequests: 'poradniki-prosby', payments: 'platnosci', stats: 'statystyki', settings: 'ustawienia', moderation: 'weryfikacja', categories: 'kategorie', locations: 'lokalizacje', promotions: 'promocje', forbiddenWords: 'zakazane-slowa', leads: 'leady', campaigns: 'kampanie', smtpConfig: 'konfiguracja-smtp', smsConfig: 'konfiguracja-sms', } as const; export type AdminTabKey = keyof typeof ADMIN_TAB_PATHS; export function adminTabPath(tab: AdminTabKey): string { const segment = ADMIN_TAB_PATHS[tab]; return segment ? `${ROUTES.admin}/${segment}` : ROUTES.admin; } export const ADMIN_PATH_TO_TAB = Object.entries(ADMIN_TAB_PATHS).reduce>( (acc, [tab, segment]) => { acc[segment] = tab as AdminTabKey; return acc; }, {}, ); // Trasy dostępne wyłącznie po zalogowaniu (bramka w ProtectedRoute). export const PROTECTED_PATHS: string[] = [ ROUTES.add, ROUTES.account, ROUTES.accountSearches, ROUTES.accountPriceAlerts, ROUTES.accountMeetings, ROUTES.accountListings, ROUTES.accountSettings, ROUTES.accountSecurity, ROUTES.accountProfileEdit, ROUTES.accountPublicProfile, ROUTES.accountHelpContact, ROUTES.notifications, ROUTES.favorites, ROUTES.messages, ROUTES.messagesConversation, ROUTES.messagesNew, ROUTES.comparison, ROUTES.guideAdd, ];