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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user