Historia ogladania i uklad panelu osobno dla kazdego konta
Deploy Polska Lokalnie / deploy (push) Successful in 11s
Deploy Polska Lokalnie / deploy (push) Successful in 11s
Oba klucze byly globalne dla przegladarki, wiec na wspolnym komputerze jedno konto widzialo, czego szukalo drugie, i nadpisywalo mu uklad kafelkow. Teraz oba siedza pod accountProfile:<id>:*. Zapis do historii czeka na zakonczenie wczytywania konta - wczesniej oferta otwarta zaraz po wejsciu trafiala do historii "goscia". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+48
-27
@@ -224,16 +224,18 @@ type RecentlyViewedItem = {
|
||||
photo: string | null;
|
||||
};
|
||||
|
||||
const RECENTLY_VIEWED_KEY = 'polskalokalnie-recently-viewed';
|
||||
// Historia ogladania jest osobna dla kazdego konta - na wspolnym komputerze jedna osoba
|
||||
// nie moze zobaczyc, czego szukala druga.
|
||||
const RECENTLY_VIEWED_SUFFIX = 'recently-viewed';
|
||||
// Ile ostatnio otwartych ofert pokazuje panel "Ostatnio przeglądane".
|
||||
const RECENTLY_VIEWED_PANEL_LIMIT = 5;
|
||||
|
||||
function readRecentlyViewed(): RecentlyViewedItem[] {
|
||||
function readRecentlyViewed(user: AuthUser | null): RecentlyViewedItem[] {
|
||||
if (typeof window === 'undefined') {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const raw = window.localStorage.getItem(RECENTLY_VIEWED_KEY);
|
||||
const raw = window.localStorage.getItem(accountStorageKey(RECENTLY_VIEWED_SUFFIX, user));
|
||||
const parsed = raw ? JSON.parse(raw) : [];
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch {
|
||||
@@ -241,14 +243,14 @@ function readRecentlyViewed(): RecentlyViewedItem[] {
|
||||
}
|
||||
}
|
||||
|
||||
function pushRecentlyViewed(item: RecentlyViewedItem): void {
|
||||
function pushRecentlyViewed(item: RecentlyViewedItem, user: AuthUser | null): void {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const list = readRecentlyViewed().filter((entry) => entry.id !== item.id);
|
||||
const list = readRecentlyViewed(user).filter((entry) => entry.id !== item.id);
|
||||
list.unshift(item);
|
||||
window.localStorage.setItem(RECENTLY_VIEWED_KEY, JSON.stringify(list.slice(0, 12)));
|
||||
window.localStorage.setItem(accountStorageKey(RECENTLY_VIEWED_SUFFIX, user), JSON.stringify(list.slice(0, 12)));
|
||||
} catch {
|
||||
/* brak dostepu do localStorage - pomijamy */
|
||||
}
|
||||
@@ -6653,18 +6655,19 @@ function AccountDashboardPage({
|
||||
order: number;
|
||||
};
|
||||
|
||||
const dashboardWidgetsStorageKey = 'polskalokalnie-dashboard-widgets';
|
||||
// Uklad kafelkow to personalizacja konta - na wspolnym komputerze kazde konto ma swoj.
|
||||
const dashboardWidgetsStorageKey = accountStorageKey('dashboard-widgets', user);
|
||||
|
||||
// Realne dane panelu: ostatnio oglądane oferty (localStorage) i alerty cenowe użytkownika
|
||||
// (to samo źródło co strona /konto/alerty-cenowe).
|
||||
const [recentlyViewed, setRecentlyViewed] = useState<RecentlyViewedItem[]>(() => readRecentlyViewed());
|
||||
const [recentlyViewed, setRecentlyViewed] = useState<RecentlyViewedItem[]>(() => readRecentlyViewed(user));
|
||||
const [cityAlerts, setCityAlerts] = useState<CityPriceAlertSubscription[]>(
|
||||
() => readUserJsonStorage<CityPriceAlertSubscription[]>(user, CITY_PRICE_ALERTS_STORAGE_SUFFIX, []),
|
||||
);
|
||||
|
||||
// Po zmianie konta wczytujemy dane właściwego użytkownika.
|
||||
useEffect(() => {
|
||||
setRecentlyViewed(readRecentlyViewed());
|
||||
setRecentlyViewed(readRecentlyViewed(user));
|
||||
setCityAlerts(readUserJsonStorage<CityPriceAlertSubscription[]>(user, CITY_PRICE_ALERTS_STORAGE_SUFFIX, []));
|
||||
}, [user]);
|
||||
|
||||
@@ -6707,9 +6710,9 @@ function AccountDashboardPage({
|
||||
const [isWidgetEditorOpen, setIsWidgetEditorOpen] = useState(false);
|
||||
const [draggedWidgetId, setDraggedWidgetId] = useState<DashboardWidgetId | null>(null);
|
||||
const [dragOverWidgetId, setDragOverWidgetId] = useState<DashboardWidgetId | null>(null);
|
||||
const [dashboardWidgets, setDashboardWidgets] = useState<DashboardWidgetConfig[]>(() => {
|
||||
const readDashboardWidgets = (storageKey: string): DashboardWidgetConfig[] => {
|
||||
try {
|
||||
const raw = window.localStorage.getItem(dashboardWidgetsStorageKey);
|
||||
const raw = window.localStorage.getItem(storageKey);
|
||||
if (!raw) {
|
||||
return defaultDashboardWidgets;
|
||||
}
|
||||
@@ -6732,11 +6735,21 @@ function AccountDashboardPage({
|
||||
} catch {
|
||||
return defaultDashboardWidgets;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const [dashboardWidgets, setDashboardWidgets] = useState<DashboardWidgetConfig[]>(
|
||||
() => readDashboardWidgets(dashboardWidgetsStorageKey),
|
||||
);
|
||||
|
||||
// Po zmianie konta wczytujemy uklad wlasciwego uzytkownika, zeby nie zapisac mu cudzego.
|
||||
useEffect(() => {
|
||||
setDashboardWidgets(readDashboardWidgets(dashboardWidgetsStorageKey));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dashboardWidgetsStorageKey]);
|
||||
|
||||
useEffect(() => {
|
||||
window.localStorage.setItem(dashboardWidgetsStorageKey, JSON.stringify(dashboardWidgets));
|
||||
}, [dashboardWidgets]);
|
||||
}, [dashboardWidgets, dashboardWidgetsStorageKey]);
|
||||
|
||||
const sortedWidgets = [...dashboardWidgets].sort((left, right) => left.order - right.order);
|
||||
|
||||
@@ -13116,8 +13129,9 @@ function CardSlider({ ariaLabel, children, autoScroll = false }: { ariaLabel: st
|
||||
function HomePage({ filters, onOpenMap }: { filters: FilterState; onOpenMap: (city: string, mode?: 'buy' | 'rent') => void }) {
|
||||
const navigate = useNavigate();
|
||||
const { formatPrice, formatPricePerArea, formatArea, showRecentlyViewedOnHome } = useDisplay();
|
||||
const { user } = useAuth();
|
||||
const [searchMode, setSearchMode] = useState<'buy' | 'rent'>('buy');
|
||||
const [recentlyViewed] = useState<RecentlyViewedItem[]>(() => readRecentlyViewed());
|
||||
const [recentlyViewed] = useState<RecentlyViewedItem[]>(() => readRecentlyViewed(user));
|
||||
const { items: liveSaleListings, loading: liveSaleLoading } = useLiveListings('SALE');
|
||||
|
||||
// Liczba ogloszen na zywo per miasto do sekcji "Przegladaj miasta". Bierzemy wszystkie zatwierdzone
|
||||
@@ -21474,7 +21488,7 @@ function PriceHistoryPage({ user }: { user: AuthUser | null }) {
|
||||
() => readUserJsonStorage<PriceHistoryMarket[]>(user, PRICE_HISTORY_MARKETS_SUFFIX, []),
|
||||
);
|
||||
// Ostatnio otwarte oferte (sprzedaz i wynajem) - wspolny rejestr zasilany przy wejsciu na oferte.
|
||||
const recentListings = useMemo(() => readRecentlyViewed().slice(0, RECENTLY_VIEWED_PANEL_LIMIT), []);
|
||||
const recentListings = useMemo(() => readRecentlyViewed(user).slice(0, RECENTLY_VIEWED_PANEL_LIMIT), [user]);
|
||||
const skipNextFetch = useRef(false);
|
||||
const locationQuery = locationInput.trim();
|
||||
const localSuggestions = locationQuery.length >= 2 ? historyLocalSuggestions(locationQuery) : HISTORY_POPULAR_MARKETS.map((label, index) => {
|
||||
@@ -26961,9 +26975,27 @@ function ListingDetailPage({
|
||||
onToggleListingAlert: (listing: ApiListingDetail) => void;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const { user } = useAuth();
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
const { formatPrice, formatPricePerArea, formatArea, areaSuffix } = useDisplay();
|
||||
const [listing, setListing] = useState<ApiListingDetail | null>(null);
|
||||
// Historia ogladania jest per konto, wiec zapisujemy ja dopiero, gdy wiadomo, kto oglada -
|
||||
// inaczej oferta obejrzana zaraz po wejsciu trafilaby do historii "goscia".
|
||||
useEffect(() => {
|
||||
if (!listing || authLoading) {
|
||||
return;
|
||||
}
|
||||
pushRecentlyViewed({
|
||||
id: listing.id,
|
||||
title: listing.title,
|
||||
city: listing.city,
|
||||
district: listing.district,
|
||||
price: listing.price,
|
||||
offerType: listing.offerType,
|
||||
area: listing.area,
|
||||
rooms: listing.rooms,
|
||||
photo: listing.photos[0] ?? null,
|
||||
}, user);
|
||||
}, [listing, authLoading, user]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [activePhoto, setActivePhoto] = useState(0);
|
||||
@@ -27031,17 +27063,6 @@ function ListingDetailPage({
|
||||
if (!cancelled) {
|
||||
setListing(data);
|
||||
setLoading(false);
|
||||
pushRecentlyViewed({
|
||||
id: data.id,
|
||||
title: data.title,
|
||||
city: data.city,
|
||||
district: data.district,
|
||||
price: data.price,
|
||||
offerType: data.offerType,
|
||||
area: data.area,
|
||||
rooms: data.rooms,
|
||||
photo: data.photos[0] ?? null,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
Reference in New Issue
Block a user