Add Today action lists and clickable KPI links (Phase 3).

Show upcoming appointments for the rest of today and link each KPI card to its relevant dashboard tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-11 00:48:35 +03:30
parent 394aa98314
commit 3f2b332bd3
10 changed files with 203 additions and 5 deletions

View File

@@ -27,6 +27,16 @@ type TodayCharts = {
tasksByWorkflowStep?: ChartBucket[];
};
type TodayActions = {
upcomingAppointmentsToday?: Array<{
id: string;
patientName: string;
startAt: string;
endAt: string;
purpose: string;
}>;
};
type TodayWidgets = {
appointmentsToday?: { count: number };
patientsToday?: { count: number };
@@ -71,6 +81,7 @@ export class TodayService {
const widgets: TodayWidgets = {};
const charts: TodayCharts = {};
const actions: TodayActions = {};
const tasks: Promise<void>[] = [];
if (orgType === 'CLINIC') {
@@ -78,6 +89,9 @@ export class TodayService {
tasks.push(
this.loadAppointmentsToday(organizationId, from, to, widgets),
);
tasks.push(
this.loadUpcomingAppointmentsToday(organizationId, from, to, actions),
);
}
if (
@@ -136,6 +150,7 @@ export class TodayService {
range: { from: from.toISOString(), to: to.toISOString() },
widgets,
charts,
actions,
},
};
}
@@ -247,6 +262,35 @@ export class TodayService {
widgets.appointmentsToday = { count };
}
private async loadUpcomingAppointmentsToday(
organizationId: string,
from: Date,
to: Date,
actions: TodayActions,
) {
const now = new Date();
const items = await this.prisma.appointment.findMany({
where: {
organizationId,
startAt: { lt: to },
endAt: { gt: now > from ? now : from },
},
include: {
patient: { select: { firstName: true, lastName: true } },
},
orderBy: { startAt: 'asc' },
take: 5,
});
actions.upcomingAppointmentsToday = items.map((appointment) => ({
id: appointment.id,
patientName: `${appointment.patient.firstName} ${appointment.patient.lastName}`.trim(),
startAt: appointment.startAt.toISOString(),
endAt: appointment.endAt.toISOString(),
purpose: appointment.purpose,
}));
}
private async loadPatientsToday(
organizationId: string,
from: Date,