feat: Reminder Manager + Schattenmarkt-Freigabe + mock data overhaul
- Add Reminder Manager page (/supply/reminder-manager) with KPI bar, filter bar, list/card feed, and detail drawer (7 sections incl. activity log, snooze, complete, dismiss actions) - Add Schattenmarkt-Freigabe toggle on PropertyDetailView: Verwaltung can opt-in properties for early market exposure before contract expiry - Auto-generate FutureSignal cards via useSchattenmarktSignals hook when leaseEndDate - leadTimeMonths <= MOCK_TODAY - Fix useUnifiedResults: use property.resultType as fallback (was defaulting everything to VERIFIED_PORTFOLIO) - Fix demand Results: hide VERIFIED_PORTFOLIO from non-manager users even when showOwnProperties toggle was previously enabled - Fix AppShell: redirect to allowed workspace on user role switch - Fix 3 wrong match scores (match-002: 93→62, match-009: 86→55, match-017: 87→52) - Add 7 new match records (match-050–056) for need-001, need-002, need-011 - Add need-011 (Retail Bern Innenstadt) - Add prop-031–036 (EXTERNAL_MARKET / MAISON_WORK / FUTURE_AVAILABILITY) - Fix duplicate image URLs across all properties - Add signal-011 (Bern Altstadt, Mode Boutique) + propertyId to signal-001 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { reminderService } from '../services/reminderService'
|
||||
|
||||
export function useReminders() {
|
||||
return useQuery({
|
||||
queryKey: ['reminders'],
|
||||
queryFn: reminderService.getAll,
|
||||
})
|
||||
}
|
||||
|
||||
export function useReminder(id: string) {
|
||||
return useQuery({
|
||||
queryKey: ['reminder', id],
|
||||
queryFn: () => reminderService.getById(id),
|
||||
enabled: !!id,
|
||||
})
|
||||
}
|
||||
|
||||
export function useReminderInsights() {
|
||||
return useQuery({
|
||||
queryKey: ['reminder-insights'],
|
||||
queryFn: reminderService.getInsights,
|
||||
})
|
||||
}
|
||||
|
||||
export function useCompleteReminder() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ id, note }: { id: string; note?: string }) =>
|
||||
reminderService.complete(id, note),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reminders'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['reminder-insights'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDismissReminder() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ id, note }: { id: string; note?: string }) =>
|
||||
reminderService.dismiss(id, note),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reminders'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['reminder-insights'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useSnoozeReminder() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ id, until }: { id: string; until: string }) =>
|
||||
reminderService.snooze(id, until),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reminders'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['reminder-insights'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useUpdateReminder() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ id, data }: { id: string; data: Partial<import('../domain/reminder').Reminder> }) =>
|
||||
reminderService.update(id, data),
|
||||
onSuccess: (_result, { id }) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reminders'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['reminder', id] })
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user