zminay w alertach cenowych

This commit is contained in:
2026-08-10 18:34:26 +02:00
parent c464c5f708
commit b30a0b9b95
9 changed files with 2577 additions and 516 deletions
+853 -241
View File
File diff suppressed because it is too large Load Diff
+23 -1
View File
@@ -12,6 +12,7 @@ export type ServerNotification = {
title: string;
body: string | null;
link: string | null;
dedupeKey: string | null;
read: boolean;
createdAt: string;
};
@@ -41,6 +42,9 @@ type NotificationsContextValue = {
markRead: (id: number) => void;
markAllRead: () => void;
notify: (input: NotifyInput) => void;
// Kasuje powiadomienia o kluczu zaczynajacym sie od prefiksu - uzywane przy usuwaniu
// alertu cenowego, zeby nie zostal po nim slad.
dismissByDedupePrefix: (prefix: string) => void;
refresh: () => void;
};
@@ -162,8 +166,26 @@ export function NotificationsProvider({ children }: { children: ReactNode }) {
.catch(() => {});
}, []);
const dismissByDedupePrefix = useCallback((prefix: string) => {
if (!getToken() || !prefix) {
return;
}
// Znikaja od razu z listy, reszte sprzata backend.
setNotifications((current) => current.filter((item) => !(item.dedupeKey ?? '').startsWith(prefix)));
// Zdejmujemy tez blokade deduplikacji, inaczej po ponownym dodaniu alertu ta sama
// zmiana ceny nie wygenerowalaby juz powiadomienia w tej sesji.
sentDedupeKeys.current.forEach((key) => {
if (key.startsWith(prefix)) {
sentDedupeKeys.current.delete(key);
}
});
apiFetch(`/notifications?dedupePrefix=${encodeURIComponent(prefix)}`, { method: 'DELETE' }).catch(() => {});
}, []);
return (
<NotificationsContext.Provider value={{ notifications, unreadCount, markRead, markAllRead, notify, refresh }}>
<NotificationsContext.Provider
value={{ notifications, unreadCount, markRead, markAllRead, notify, dismissByDedupePrefix, refresh }}
>
{children}
</NotificationsContext.Provider>
);
+17
View File
@@ -70,6 +70,23 @@ export function mapPath(city?: string, offerType?: 'SALE' | 'RENT'): string {
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 {
+786 -274
View File
File diff suppressed because it is too large Load Diff