fix: KPI card counts match feed — exclusive buckets + filter reset on click

- reminderService: dueThisWeek/dueThisMonth use exclusive day ranges (1-7,
  8-30) matching getHorizon() buckets; schattenmarktReadyCount counts by
  type=SCHATTENMARKT_RELEASE (same criteria as the feed filter)
- ReminderKpiBar: clicking a horizon card resets filterType to ALL;
  clicking Pre-Market card resets filterHorizon to ALL — ensures the number
  shown on the card always equals the number of rows displayed below

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-24 23:12:08 +02:00
parent cd220ed282
commit d2af8664f4
2 changed files with 18 additions and 14 deletions
+12 -2
View File
@@ -75,11 +75,21 @@ export function ReminderKpiBar() {
) )
function toggleHorizon(h: FilterHorizon) { function toggleHorizon(h: FilterHorizon) {
setFilterHorizon(filterHorizon === h ? 'ALL' : h) if (filterHorizon === h) {
setFilterHorizon('ALL')
} else {
setFilterHorizon(h)
setFilterType('ALL') // clear type filter so count matches
}
} }
function togglePreMarket() { function togglePreMarket() {
setFilterType(filterType === ReminderType.SCHATTENMARKT_RELEASE ? 'ALL' : ReminderType.SCHATTENMARKT_RELEASE) if (filterType === ReminderType.SCHATTENMARKT_RELEASE) {
setFilterType('ALL')
} else {
setFilterType(ReminderType.SCHATTENMARKT_RELEASE)
setFilterHorizon('ALL') // clear horizon filter so count matches
}
} }
if (isLoading) { if (isLoading) {
+6 -12
View File
@@ -1,6 +1,6 @@
import { MockupReminderProvider } from '../provider/MockupReminderProvider' import { MockupReminderProvider } from '../provider/MockupReminderProvider'
import type { Reminder } from '../domain/reminder' import type { Reminder } from '../domain/reminder'
import { ReminderPriority, ReminderStatus, ShadowMarketRisk } from '../domain/reminder' import { ReminderPriority, ReminderStatus, ReminderType } from '../domain/reminder'
const provider = MockupReminderProvider const provider = MockupReminderProvider
@@ -27,25 +27,19 @@ export const reminderService = {
const urgentCount = active.filter(r => r.priority === ReminderPriority.URGENT).length const urgentCount = active.filter(r => r.priority === ReminderPriority.URGENT).length
const endOfWeek = new Date(MOCK_TODAY) // Counts match getHorizon() in ReminderFeed — exclusive, non-overlapping buckets
endOfWeek.setDate(endOfWeek.getDate() + 7)
const dueThisWeek = active.filter(r => { const dueThisWeek = active.filter(r => {
const d = daysDiff(r.dueDate) const d = daysDiff(r.dueDate)
return d >= 0 && d <= 7 return d >= 1 && d <= 7
}).length }).length
const endOfMonth = new Date(MOCK_TODAY)
endOfMonth.setDate(endOfMonth.getDate() + 30)
const dueThisMonth = active.filter(r => { const dueThisMonth = active.filter(r => {
const d = daysDiff(r.dueDate) const d = daysDiff(r.dueDate)
return d >= 0 && d <= 30 return d >= 8 && d <= 30
}).length }).length
const schattenmarktReadyCount = reminders.filter( const schattenmarktReadyCount = active.filter(
r => r => r.type === ReminderType.SCHATTENMARKT_RELEASE,
r.status === ReminderStatus.ACTIVE &&
!r.schattenmarktEnabled &&
(r.shadowMarketRisk === ShadowMarketRisk.HIGH),
).length ).length
const overdueCount = active.filter(r => daysDiff(r.dueDate) <= 0).length const overdueCount = active.filter(r => daysDiff(r.dueDate) <= 0).length