Zmiana nazwy na Polska Lokalnie, przyklejony naglowek i uklad stron konta
Nazwa i adres: - marka "Mieszko" -> "Polska Lokalnie" w calym interfejsie (27 miejsc), w tekstach zaleznych dodane slowo "serwis", zeby brzmialy poprawnie po polsku - domena mieszko.pl -> polskalokalnie.pl (adresy kontaktowe, profil, udostepnianie) - haslo pod logo: "mieszkania za darmo" -> "ogloszenia za darmo" - backend: teksty powiadomien, dane demo i domyslna nazwa admina - nazwa wyswietlana istniejacego admina zaktualizowana w bazie; login admin@mieszko.pl celowo bez zmian Naglowek: - logo, nawigacja i panel zostaja widoczne przy przewijaniu (position: sticky, warstwa 65 - nad listami rozwijanymi, pod lightboxem zdjec) - sticky sidebary z top: 18-20px wyrownane do 96px, zeby nie wjezdzaly pod naglowek Uklad stron konta: - /ulubione, /wiadomosci i /powiadomienia otwieraja sie jak /konto/wyszukiwania - wspolny layout AccountShell zamiast powielania ukladu w kazdej stronie - /konto/porownanie mialo wlasny uklad (sidebar 300px, inny gap i padding), przez co menu przeskakiwalo - wyrownane do .account-layout wraz z punktem zwijania (1200px zamiast 1500px) - narzedzia publiczne (/wycena, /historia-cen, /ranking-dzielnic, /negocjacje) bez menu konta - dzialaja jak /kupno czy /wynajem Naprawy regresji po zamianie przyciskow na linki: - ikona ulubionych na kartach /kupno wracala do przeplywu (nadpisany position: absolute) - teraz podnoszona jest tylko warstwa - menu uzytkownika i "Zobacz wszystkie" w powiadomieniach: reguly CSS celowaly tylko w <button>, przez co pozycje rozjezdzaly sie na dwie linie Testy: 47 (bylo 41), w tym zabezpieczenie przed powrotem przeskoku menu i przed rozjechaniem pozycji menu uzytkownika. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -175,7 +175,7 @@ public class AuthService {
|
||||
return switch (provider) {
|
||||
case GOOGLE -> "demo.google@gmail.com";
|
||||
case FACEBOOK -> "demo.facebook@facebook.com";
|
||||
case LOCAL -> "demo.local@mieszko.pl";
|
||||
case LOCAL -> "demo.local@polskalokalnie.pl";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DataSeeder implements CommandLineRunner {
|
||||
PasswordEncoder passwordEncoder,
|
||||
@Value("${app.admin.email:admin@mieszko.pl}") String adminEmail,
|
||||
@Value("${app.admin.password:Admin123!}") String adminPassword,
|
||||
@Value("${app.admin.name:Administrator Mieszko}") String adminName
|
||||
@Value("${app.admin.name:Administrator Polska Lokalnie}") String adminName
|
||||
) {
|
||||
this.userRepository = userRepository;
|
||||
this.listingRepository = listingRepository;
|
||||
@@ -93,7 +93,7 @@ public class DataSeeder implements CommandLineRunner {
|
||||
listing.setPrice(price);
|
||||
listing.setArea(area);
|
||||
listing.setRooms(rooms);
|
||||
listing.setOwnerEmail("demo.user@mieszko.pl");
|
||||
listing.setOwnerEmail("demo.user@polskalokalnie.pl");
|
||||
listing.setStatus(status);
|
||||
return listing;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class MessageService {
|
||||
"messages", null);
|
||||
} else {
|
||||
notificationService.create(recipient.getEmail(), "messages", "mail",
|
||||
"Wiadomość od obsługi Mieszko",
|
||||
"Wiadomość od obsługi serwisu Polska Lokalnie",
|
||||
preview,
|
||||
"messages:admin", null);
|
||||
}
|
||||
|
||||
@@ -28,4 +28,4 @@ app:
|
||||
admin:
|
||||
email: ${APP_ADMIN_EMAIL:admin@mieszko.pl}
|
||||
password: ${APP_ADMIN_PASSWORD:Admin123!}
|
||||
name: ${APP_ADMIN_NAME:Administrator Mieszko}
|
||||
name: ${APP_ADMIN_NAME:Administrator Polska Lokalnie}
|
||||
|
||||
@@ -15,4 +15,4 @@ app:
|
||||
admin:
|
||||
email: admin@mieszko.pl
|
||||
password: Admin123!
|
||||
name: Administrator Mieszko
|
||||
name: Administrator Polska Lokalnie
|
||||
|
||||
+66
-31
@@ -1,6 +1,6 @@
|
||||
import { Fragment, type ChangeEvent as ReactChangeEvent, type ClipboardEvent as ReactClipboardEvent, type Dispatch, type DragEvent as ReactDragEvent, type FormEvent as ReactFormEvent, type KeyboardEvent as ReactKeyboardEvent, type MouseEvent as ReactMouseEvent, type PointerEvent as ReactPointerEvent, type ReactNode, type SetStateAction, type WheelEvent as ReactWheelEvent, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||
import './styles.css';
|
||||
import { Link, NavLink, Route, Routes, useLocation, useNavigate, useNavigationType, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { Link, NavLink, Outlet, Route, Routes, useLocation, useNavigate, useNavigationType, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { ROUTES, listingPath, mapPath, negotiationPath, companiesPath, adminTabPath, ADMIN_PATH_TO_TAB, type AdminTabKey } from './routes';
|
||||
import { ProtectedRoute } from './ProtectedRoute';
|
||||
import { apiFetch, useAuth } from './auth';
|
||||
@@ -184,7 +184,7 @@ const userNotifications: UserNotification[] = [
|
||||
},
|
||||
{
|
||||
id: 'support-reply',
|
||||
title: 'Wiadomość od obsługi Mieszko',
|
||||
title: 'Wiadomość od obsługi serwisu Polska Lokalnie',
|
||||
description: 'Dziękujemy za kontakt. Odpowiemy najszybciej jak to możliwe.',
|
||||
timeLabel: 'Wczoraj, 18:20',
|
||||
dayLabel: 'Wczoraj',
|
||||
@@ -630,9 +630,9 @@ function toFavoriteListing(listing: ApiListingDetail): FavoriteListing {
|
||||
}
|
||||
|
||||
function buildMessageThreadTargetFromListing(listing: ApiListingDetail, user: AuthUser | null): MessageThreadTarget {
|
||||
const sellerName = listing.contactName?.trim() || 'Administracja Mieszko';
|
||||
const sellerName = listing.contactName?.trim() || 'Administracja Polska Lokalnie';
|
||||
const isOwner = Boolean(user && listing.ownerEmail && user.email.toLowerCase() === listing.ownerEmail.toLowerCase());
|
||||
const sellerRole = isOwner ? 'To Twoje ogłoszenie' : 'Oficjalny kontakt zespołem Mieszko';
|
||||
const sellerRole = isOwner ? 'To Twoje ogłoszenie' : 'Oficjalny kontakt zespołem serwisu Polska Lokalnie';
|
||||
const threadIdBase = listing.ownerEmail?.trim() || sellerName;
|
||||
const threadId = `listing-${listing.id}-${threadIdBase.toLowerCase().replace(/[^a-z0-9]+/g, '-')}`;
|
||||
|
||||
@@ -1734,7 +1734,7 @@ const sellReasons = [
|
||||
const sellChannels = [
|
||||
{
|
||||
icon: 'logo',
|
||||
title: 'mieszko.pl',
|
||||
title: 'polskalokalnie.pl',
|
||||
text: 'Nasza strona',
|
||||
},
|
||||
{
|
||||
@@ -3466,11 +3466,15 @@ function App() {
|
||||
/>
|
||||
<Route path={ROUTES.map} element={<MapSearchRoute />} />
|
||||
<Route path={ROUTES.sell} element={<SellPage />} />
|
||||
<Route path={ROUTES.valuation} element={<ValuationPage />} />
|
||||
<Route path={ROUTES.creditCalculator} element={<CreditCalculatorPage onSearchWithBudget={handleSearchWithBudget} />} />
|
||||
|
||||
{/* Narzedzia publiczne - dostepne tak samo dla goscia i zalogowanego,
|
||||
bez lewego menu konta (jak /kupno czy /wynajem) */}
|
||||
<Route path={ROUTES.valuation} element={<ValuationPage />} />
|
||||
<Route path={ROUTES.priceHistory} element={<PriceHistoryPage user={user} />} />
|
||||
<Route path={ROUTES.districtRanking} element={<DistrictRankingPage />} />
|
||||
<Route path={ROUTES.negotiation} element={<NegotiationRoute />} />
|
||||
|
||||
<Route path={ROUTES.services} element={<ServicesPage />} />
|
||||
<Route path={ROUTES.companies} element={<CompaniesPage />} />
|
||||
<Route path={ROUTES.guides} element={<GuidesPage />} />
|
||||
@@ -3498,9 +3502,12 @@ function App() {
|
||||
<Route path={ROUTES.accountProfileEdit} element={<AccountProfileEditPage />} />
|
||||
<Route path={ROUTES.accountPublicProfile} element={<AccountPublicProfilePage />} />
|
||||
<Route path={ROUTES.accountHelpContact} element={<AccountHelpContactPage user={user} />} />
|
||||
<Route path={ROUTES.add} element={<AddListingPage />} />
|
||||
|
||||
{/* Pozostale pozycje lewego menu konta - ten sam uklad co /konto/wyszukiwania */}
|
||||
<Route element={<AccountShell />}>
|
||||
<Route path={ROUTES.notifications} element={<NotificationsPage onOpenNotification={handleOpenNotification} />} />
|
||||
<Route path={ROUTES.messages} element={<MessagesPage onOpenListing={openListing} />} />
|
||||
<Route path={ROUTES.add} element={<AddListingPage />} />
|
||||
<Route
|
||||
path={ROUTES.favorites}
|
||||
element={(
|
||||
@@ -3514,6 +3521,7 @@ function App() {
|
||||
)}
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
{/* Panel administratora - zakladki jako podsciezki /admin/* */}
|
||||
<Route element={<ProtectedRoute requireAdmin />}>
|
||||
@@ -3727,7 +3735,7 @@ const ADMIN_TAB_META: Record<AdminTab, { title: string; subtitle: string }> = {
|
||||
reports: { title: 'Zgłoszenia', subtitle: 'Zgłoszenia dotyczące ogłoszeń i użytkowników wymagające uwagi.' },
|
||||
payments: { title: 'Płatności', subtitle: 'Historia płatności i promocji ogłoszeń.' },
|
||||
stats: { title: 'Statystyki', subtitle: 'Statystyki aktywności i ruchu w serwisie.' },
|
||||
settings: { title: 'Ustawienia serwisu', subtitle: 'Globalna konfiguracja serwisu Mieszko.' },
|
||||
settings: { title: 'Ustawienia serwisu', subtitle: 'Globalna konfiguracja serwisu Polska Lokalnie.' },
|
||||
moderation: { title: 'Weryfikacja ogłoszeń', subtitle: 'Kolejka ogłoszeń oczekujących na moderację.' },
|
||||
categories: { title: 'Kategorie', subtitle: 'Zarządzaj kategoriami i typami nieruchomości.' },
|
||||
locations: { title: 'Lokalizacje', subtitle: 'Zarządzaj obsługiwanymi miastami i dzielnicami.' },
|
||||
@@ -5629,6 +5637,33 @@ function AccountSidebar() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wspolny layout stron konta, ktore maja wlasny adres poza /konto/*:
|
||||
* /ulubione, /wiadomosci i /powiadomienia. Dzieki niemu otwieraja sie tak samo
|
||||
* jak /konto/wyszukiwania, bez powtarzania ukladu w kazdej stronie.
|
||||
*
|
||||
* Narzedzia publiczne (wycena, historia cen, ranking, negocjacje) celowo tu nie
|
||||
* trafiaja - dzialaja jak /kupno czy /wynajem, bez menu konta.
|
||||
*/
|
||||
function AccountShell() {
|
||||
const { user } = useAuth();
|
||||
|
||||
if (!user) {
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="account-page account-shell" aria-label="Panel użytkownika">
|
||||
<div className="account-layout">
|
||||
<AccountSidebar />
|
||||
<div className="account-main">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function AccountDashboardPage({
|
||||
savedSearches,
|
||||
onOpenSavedSearch,
|
||||
@@ -5711,14 +5746,14 @@ function AccountDashboardPage({
|
||||
{ id: 'recent', label: 'Ostatnio oglądane', visible: false, layout: 'normal', order: 0 },
|
||||
{ id: 'alerts', label: 'Alerty cenowe', visible: false, layout: 'normal', order: 1 },
|
||||
{ id: 'searches', label: 'Moje wyszukiwania', visible: false, layout: 'normal', order: 2 },
|
||||
{ id: 'tools', label: 'Narzędzia Mieszko', visible: false, layout: 'normal', order: 3 },
|
||||
{ id: 'tools', label: 'Narzędzia Polska Lokalnie', visible: false, layout: 'normal', order: 3 },
|
||||
];
|
||||
|
||||
const widgetCardMeta: Record<DashboardWidgetId, { icon: string; description: string; tone: 'green' | 'blue' | 'pink' | 'amber' }> = {
|
||||
recent: { icon: 'house', description: 'Podgląd ostatnio oglądanych ofert i mieszkań.', tone: 'green' },
|
||||
searches: { icon: 'search', description: 'Twoje zapisane wyszukiwania i nowe dopasowania.', tone: 'blue' },
|
||||
alerts: { icon: 'bell', description: 'Alerty cenowe i ważne powiadomienia z rynku.', tone: 'amber' },
|
||||
tools: { icon: 'gear', description: 'Szybki dostęp do narzędzi Mieszko i analiz.', tone: 'pink' },
|
||||
tools: { icon: 'gear', description: 'Szybki dostęp do narzędzi serwisu Polska Lokalnie i analiz.', tone: 'pink' },
|
||||
};
|
||||
|
||||
const [showWidgetEditLauncher, setShowWidgetEditLauncher] = useState(false);
|
||||
@@ -5897,7 +5932,7 @@ function AccountDashboardPage({
|
||||
tools: (
|
||||
<section className="account-panel" key="tools">
|
||||
<div className="account-panel-head">
|
||||
<h2>Narzędzia Mieszko</h2>
|
||||
<h2>Narzędzia Polska Lokalnie</h2>
|
||||
</div>
|
||||
<div className="account-tools">
|
||||
{tools.map((tool) => (
|
||||
@@ -6290,7 +6325,7 @@ function AccountHelpContactPage({
|
||||
iconTone: 'blue',
|
||||
title: 'E-mail',
|
||||
description: 'Napisz do nas, odpowiemy najszybciej jak to możliwe.',
|
||||
action: 'bok@mieszko.pl',
|
||||
action: 'bok@polskalokalnie.pl',
|
||||
},
|
||||
{
|
||||
id: 'phone',
|
||||
@@ -7604,7 +7639,7 @@ function AccountMeetingsPage() {
|
||||
id: 'meeting-test-now-1',
|
||||
title: 'Test: szybka konsultacja',
|
||||
subtitle: 'Spotkanie testowe na dziś',
|
||||
location: 'Biuro Mieszko, Warszawa',
|
||||
location: 'Biuro Polska Lokalnie, Warszawa',
|
||||
dateKey: addDays(0),
|
||||
start: '18:30',
|
||||
end: '19:00',
|
||||
@@ -9011,7 +9046,7 @@ function AccountSettingsPage() {
|
||||
<section className="settings-card settings-export">
|
||||
<div className="settings-card-head">
|
||||
<h2>Export danych</h2>
|
||||
<p>Pobierz kopię swoich danych z konta Mieszko.</p>
|
||||
<p>Pobierz kopię swoich danych z konta w serwisie Polska Lokalnie.</p>
|
||||
</div>
|
||||
<div className="settings-export-box">
|
||||
<span><Icon name="upload" /></span>
|
||||
@@ -9691,7 +9726,7 @@ function AccountProfileEditPage() {
|
||||
<div className="settings-breadcrumb">Dane i ustawienia <Icon name="chevron" /> <strong>Edytuj profil</strong></div>
|
||||
<header className="settings-head profile-edit-head">
|
||||
<h1>Edytuj profil</h1>
|
||||
<p>Zarządzaj swoimi danymi osobowymi i wizerunkiem w Mieszko.</p>
|
||||
<p>Zarządzaj swoimi danymi osobowymi i wizerunkiem w serwisie Polska Lokalnie.</p>
|
||||
</header>
|
||||
|
||||
<div className="profile-edit-layout">
|
||||
@@ -9745,7 +9780,7 @@ function AccountProfileEditPage() {
|
||||
<input value={profile.nick} onChange={(event) => setField('nick', event.target.value)} />
|
||||
<button type="button" onClick={() => setField('nick', '')}>Zmień nick</button>
|
||||
</div>
|
||||
<small>mieszko.pl/u/{profile.nick}</small>
|
||||
<small>polskalokalnie.pl/u/{profile.nick}</small>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
@@ -10087,7 +10122,7 @@ function AccountProfileEditPage() {
|
||||
<span><Icon name="shield" /></span>
|
||||
<div>
|
||||
<strong>Nie udostępniaj kodu nikomu.</strong>
|
||||
<small>Mieszko nigdy nie poprosi Cię o kod SMS.</small>
|
||||
<small>Polska Lokalnie nigdy nie poprosi Cię o kod SMS.</small>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -10217,7 +10252,7 @@ function AccountPublicProfilePage() {
|
||||
<header className="settings-head public-profile-head">
|
||||
<div>
|
||||
<h1>Jak inni widzą Twój profil</h1>
|
||||
<p>Zobacz, jak Twój profil prezentuje się publicznie dla innych użytkowników Mieszko.</p>
|
||||
<p>Zobacz, jak Twój profil prezentuje się publicznie dla innych użytkowników serwisu Polska Lokalnie.</p>
|
||||
</div>
|
||||
<Link to={ROUTES.accountProfileEdit}><Icon name="gear" /> Edytuj profil</Link>
|
||||
</header>
|
||||
@@ -10452,7 +10487,7 @@ function LoginPage({ onLogin }: { onLogin: (user: AuthUser) => void }) {
|
||||
<div className="login-left">
|
||||
<div className="login-intro">
|
||||
<h1>Witaj ponownie!</h1>
|
||||
<p>Zaloguj się, aby zarządzać ogłoszeniami, zapisywać ulubione oferty i korzystać ze wszystkich funkcji Mieszko.</p>
|
||||
<p>Zaloguj się, aby zarządzać ogłoszeniami, zapisywać ulubione oferty i korzystać ze wszystkich funkcji serwisu Polska Lokalnie.</p>
|
||||
</div>
|
||||
|
||||
<div className="login-benefits">
|
||||
@@ -12555,7 +12590,7 @@ function AddListingPage() {
|
||||
<div>
|
||||
<span><Icon name="mail" /></span>
|
||||
<p>
|
||||
<strong>pomoc@mieszko.pl</strong>
|
||||
<strong>pomoc@polskalokalnie.pl</strong>
|
||||
<small>Odpowiadamy w ciągu 24h</small>
|
||||
</p>
|
||||
</div>
|
||||
@@ -12567,7 +12602,7 @@ function AddListingPage() {
|
||||
</div>
|
||||
|
||||
{!isFinalPreviewStep && <section className="add-footer-benefits">
|
||||
<h2>Dlaczego warto dodać ogłoszenie na mieszko.pl?</h2>
|
||||
<h2>Dlaczego warto dodać ogłoszenie na polskalokalnie.pl?</h2>
|
||||
<div>
|
||||
{addFooterBenefits.map((benefit) => (
|
||||
<article key={benefit.title}>
|
||||
@@ -18698,13 +18733,13 @@ function Header({
|
||||
return (
|
||||
<header className={isAdmin ? 'header header-admin' : 'header'}>
|
||||
<div className="brand-group">
|
||||
<Link className="brand" to={ROUTES.home} aria-label="Mieszko">
|
||||
<Link className="brand" to={ROUTES.home} aria-label="Polska Lokalnie">
|
||||
<span className="brand-mark">
|
||||
<Icon name="logo" />
|
||||
</span>
|
||||
<span>
|
||||
<strong>mieszko</strong>
|
||||
<small>mieszkania za darmo</small>
|
||||
<strong>Polska Lokalnie</strong>
|
||||
<small>ogłoszenia za darmo</small>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -19145,9 +19180,9 @@ function MessagesPage({
|
||||
const existingAdminThread = current.find((thread) => thread.id === ADMIN_THREAD_ID);
|
||||
const adminThread: ChatThread = {
|
||||
id: ADMIN_THREAD_ID,
|
||||
name: 'Administracja Mieszko',
|
||||
name: 'Administracja Polska Lokalnie',
|
||||
avatarImage: heroImage,
|
||||
status: 'Oficjalny kontakt z zespołem Mieszko',
|
||||
status: 'Oficjalny kontakt z zespołem serwisu Polska Lokalnie',
|
||||
listing: existingAdminThread?.listing ?? null,
|
||||
messages,
|
||||
};
|
||||
@@ -20300,7 +20335,7 @@ function FavoritesPage({
|
||||
|
||||
setContactPreview({
|
||||
listingTitle: fullListing.title,
|
||||
sellerName: fullListing.contactName?.trim() || 'Administracja Mieszko',
|
||||
sellerName: fullListing.contactName?.trim() || 'Administracja Polska Lokalnie',
|
||||
phone,
|
||||
});
|
||||
} catch {
|
||||
@@ -21023,13 +21058,13 @@ function ListingDetailPage({
|
||||
const locationLine = [listing.city, listing.district, listing.street && listing.building ? `${listing.street} ${listing.building}` : listing.street]
|
||||
.filter(Boolean)
|
||||
.join(', ');
|
||||
const sellerName = listing.contactName?.trim() || 'Administracja Mieszko';
|
||||
const sellerName = listing.contactName?.trim() || 'Administracja Polska Lokalnie';
|
||||
const isOwner = Boolean(user && listing.ownerEmail && user.email.toLowerCase() === listing.ownerEmail.toLowerCase());
|
||||
const sellerRole = isOwner ? 'To Twoje ogłoszenie' : 'Oficjalny kontakt zespołem Mieszko';
|
||||
const sellerRole = isOwner ? 'To Twoje ogłoszenie' : 'Oficjalny kontakt zespołem serwisu Polska Lokalnie';
|
||||
const favorite = isFavorite(listing.id);
|
||||
const listingAlertEnabled = isListingAlertEnabled(listing.id);
|
||||
const virtualTourEmbed = listing.virtualTourUrl ? getVirtualTourEmbed(listing.virtualTourUrl) : null;
|
||||
const shareUrl = typeof window !== 'undefined' ? window.location.href : `https://mieszko.pl/oferta/${listing.id}`;
|
||||
const shareUrl = typeof window !== 'undefined' ? window.location.href : `https://polskalokalnie.pl/oferta/${listing.id}`;
|
||||
|
||||
const copyShareLink = async () => {
|
||||
try {
|
||||
@@ -21468,7 +21503,7 @@ function ListingDetailPage({
|
||||
<div>
|
||||
<strong>{sellerName}</strong>
|
||||
<small>{sellerRole}</small>
|
||||
<small>Na Mieszko.pl od 2023</small>
|
||||
<small>Na PolskaLokalnie.pl od 2023</small>
|
||||
{isPhoneRevealed && listing.contactPhone && (
|
||||
<a href={`tel:${listing.contactPhone.replace(/\s+/g, '')}`}><Icon name="phone" /> {listing.contactPhone}</a>
|
||||
)}
|
||||
|
||||
+64
-17
@@ -56,8 +56,11 @@ svg {
|
||||
height: 82px;
|
||||
margin: 0 auto;
|
||||
padding: 0 48px;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
/* Naglowek (logo, nawigacja, panel) zostaje widoczny przy przewijaniu na kazdej stronie.
|
||||
Warstwa 65: nad rozwijanymi listami strony (60), pod lightboxem zdjec (70). */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 65;
|
||||
}
|
||||
|
||||
.header-admin {
|
||||
@@ -3238,7 +3241,7 @@ svg {
|
||||
gap: 18px;
|
||||
min-width: 0;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
top: 96px;
|
||||
}
|
||||
|
||||
.map-card {
|
||||
@@ -3844,7 +3847,7 @@ svg {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
top: 96px;
|
||||
}
|
||||
|
||||
.guide-ai-card {
|
||||
@@ -5367,7 +5370,7 @@ svg {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
top: 96px;
|
||||
}
|
||||
|
||||
.listing-preview-card,
|
||||
@@ -12797,7 +12800,7 @@ svg {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.notification-popover-head button {
|
||||
.notification-popover-head button, .notification-popover-head a {
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
border: 1px solid rgba(255, 255, 255, 0.34);
|
||||
border-radius: 7px;
|
||||
@@ -12897,7 +12900,7 @@ svg {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.account-popover button {
|
||||
.account-popover button, .account-popover a {
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
@@ -12913,11 +12916,11 @@ svg {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.account-popover button:hover {
|
||||
.account-popover button:hover, .account-popover a:hover {
|
||||
background: #f2f6fa;
|
||||
}
|
||||
|
||||
.account-popover button svg {
|
||||
.account-popover button svg, .account-popover a svg {
|
||||
color: #6b7b90;
|
||||
font-size: 16px;
|
||||
}
|
||||
@@ -24363,16 +24366,15 @@ svg {
|
||||
.comparison-page {
|
||||
background: #f6f8fb;
|
||||
min-height: calc(100vh - 82px);
|
||||
padding: 22px 0;
|
||||
padding: 16px 18px;
|
||||
}
|
||||
|
||||
.comparison-layout {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
grid-template-columns: 300px minmax(0, 1fr);
|
||||
gap: 14px;
|
||||
grid-template-columns: 256px minmax(0, 1fr);
|
||||
margin: 0 auto;
|
||||
max-width: 1900px;
|
||||
padding: 0 18px;
|
||||
max-width: 1820px;
|
||||
}
|
||||
|
||||
.comparison-main {
|
||||
@@ -24988,7 +24990,7 @@ svg {
|
||||
/* Spis treści */
|
||||
.guide-toc {
|
||||
position: sticky;
|
||||
top: 20px;
|
||||
top: 96px;
|
||||
}
|
||||
|
||||
.guide-toc-inner {
|
||||
@@ -25666,7 +25668,7 @@ svg {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
position: sticky;
|
||||
top: 20px;
|
||||
top: 96px;
|
||||
}
|
||||
|
||||
.guide-aside-card {
|
||||
@@ -26925,7 +26927,12 @@ a.listing-detail-back {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.real-result-card .real-favorite-button,
|
||||
/* Serce jest juz pozycjonowane absolutnie w rogu zdjecia - nie zmieniamy mu
|
||||
position, wystarczy podniesc je nad nakladke rozciagnietego linku. */
|
||||
.real-result-card .real-favorite-button {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.real-result-card .real-card-cta {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
@@ -26937,3 +26944,43 @@ a.listing-detail-back {
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Widoki otwierane z lewego menu konta maja wlasna pelnoekranowa rame (tlo,
|
||||
min-height, padding). Wewnatrz AccountShell ta rama jest zbedna - zapewnia
|
||||
ja .account-page, wiec tutaj ja zdejmujemy. */
|
||||
.account-main > .favorites-page,
|
||||
.account-main > .messages-page,
|
||||
.account-main > .notifications-page,
|
||||
.account-main > .history-page,
|
||||
.account-main > .negotiation-page,
|
||||
.account-main > .valuation-page,
|
||||
.account-main > .district-ranking-page {
|
||||
background: none;
|
||||
border-top: 0;
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Czat wypelnia wysokosc okna - w layoucie konta odliczamy naglowek i marginesy. */
|
||||
.account-main > .messages-page {
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 520px;
|
||||
}
|
||||
|
||||
/* "Zobacz wszystkie" w popoverze powiadomien jest teraz <Link> - <button> centrowal tresc sam. */
|
||||
.notification-popover-head a { align-items: center; display: inline-flex; justify-content: center; }
|
||||
|
||||
/* Lewe menu na porownywarce ma chowac sie przy tej samej szerokosci co na
|
||||
pozostalych stronach konta (1200px), a nie przy 1500px - inaczej menu
|
||||
nadal przeskakiwaloby w tym zakresie szerokosci. */
|
||||
@media (min-width: 1201px) {
|
||||
.comparison-layout { grid-template-columns: 256px minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.comparison-layout { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.comparison-layout { padding: 0; }
|
||||
}
|
||||
|
||||
@@ -247,3 +247,98 @@ test.describe('Trasy chronione', () => {
|
||||
await expect(page.locator('.not-found-page')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Layout konta', () => {
|
||||
// Kazda pozycja lewego menu ma otwierac sie tak samo jak /konto/wyszukiwania,
|
||||
// czyli razem z widocznym menu konta.
|
||||
const ACCOUNT_PAGES = [
|
||||
ROUTES.account,
|
||||
ROUTES.accountSearches,
|
||||
ROUTES.favorites,
|
||||
ROUTES.accountPriceAlerts,
|
||||
ROUTES.comparison,
|
||||
ROUTES.messages,
|
||||
ROUTES.accountMeetings,
|
||||
ROUTES.accountListings,
|
||||
ROUTES.accountSettings,
|
||||
ROUTES.notifications,
|
||||
ROUTES.accountSecurity,
|
||||
ROUTES.accountHelpContact,
|
||||
];
|
||||
|
||||
// Narzedzia publiczne dzialaja jak /kupno czy /wynajem - bez menu konta.
|
||||
const PUBLIC_TOOLS = [ROUTES.valuation, ROUTES.priceHistory, ROUTES.districtRanking, ROUTES.negotiation];
|
||||
|
||||
test('lewe menu konta jest widoczne na wszystkich stronach konta', async ({ page }) => {
|
||||
await login(page);
|
||||
for (const path of ACCOUNT_PAGES) {
|
||||
await goto(page, path);
|
||||
await expect(page.locator('.account-sidebar'), `brak lewego menu na ${path}`).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('lewe menu nie przeskakuje miedzy stronami konta', async ({ page }) => {
|
||||
await login(page);
|
||||
const positions: Array<{ path: string; x: number; width: number }> = [];
|
||||
|
||||
for (const path of ACCOUNT_PAGES) {
|
||||
await goto(page, path);
|
||||
const box = await page.locator('.account-sidebar').first().boundingBox();
|
||||
positions.push({ path, x: Math.round(box!.x), width: Math.round(box!.width) });
|
||||
}
|
||||
|
||||
const first = positions[0];
|
||||
for (const pos of positions) {
|
||||
expect(pos.x, `menu przesuniete na ${pos.path}`).toBe(first.x);
|
||||
expect(pos.width, `inna szerokosc menu na ${pos.path}`).toBe(first.width);
|
||||
}
|
||||
});
|
||||
|
||||
test('narzedzia publiczne nie pokazuja menu konta - takze po zalogowaniu', async ({ page }) => {
|
||||
for (const path of PUBLIC_TOOLS) {
|
||||
await goto(page, path);
|
||||
await expect(page.locator('.account-sidebar'), `menu konta na publicznej ${path}`).toHaveCount(0);
|
||||
}
|
||||
|
||||
await login(page);
|
||||
for (const path of PUBLIC_TOOLS) {
|
||||
await goto(page, path);
|
||||
await expect(page.locator('.account-sidebar'), `menu konta na publicznej ${path}`).toHaveCount(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('menu uzytkownika w naglowku ma pozycje ulozone w jednej linii', async ({ page }) => {
|
||||
await login(page);
|
||||
await goto(page, ROUTES.home);
|
||||
await page.locator('.account-menu-trigger').click();
|
||||
|
||||
const items = page.locator('.account-popover a');
|
||||
await expect(items.first()).toBeVisible();
|
||||
|
||||
for (let i = 0; i < await items.count(); i += 1) {
|
||||
const box = await items.nth(i).boundingBox();
|
||||
// ikona obok tekstu daje ~42px; zawiniecie do dwoch linii daje wyraznie wiecej
|
||||
expect(Math.round(box!.height), 'pozycja menu zawinela sie do dwoch linii').toBeLessThan(56);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Naglowek', () => {
|
||||
test('zostaje przyklejony do gory przy przewijaniu', async ({ page }) => {
|
||||
for (const path of [ROUTES.home, ROUTES.buy, ROUTES.guides]) {
|
||||
await goto(page, path);
|
||||
await page.evaluate(() => window.scrollTo(0, 1400));
|
||||
await page.waitForTimeout(300);
|
||||
const box = await page.locator('.header').boundingBox();
|
||||
expect(Math.round(box!.y), `naglowek odjechal na ${path}`).toBe(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('logo prowadzi na strone glowna i pokazuje nowa nazwe', async ({ page }) => {
|
||||
await goto(page, ROUTES.buy);
|
||||
const brand = page.locator('a.brand');
|
||||
await expect(brand).toHaveAttribute('href', ROUTES.home);
|
||||
await expect(brand).toContainText('Polska Lokalnie');
|
||||
await expect(brand).toContainText('ogłoszenia za darmo');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user