diff --git a/apps/Frontend/src/components/analytics/appointments-by-day.tsx b/apps/Frontend/src/components/analytics/appointments-by-day.tsx index c00aa5f..8c817ed 100644 --- a/apps/Frontend/src/components/analytics/appointments-by-day.tsx +++ b/apps/Frontend/src/components/analytics/appointments-by-day.tsx @@ -1,30 +1,67 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { BarChart, Bar, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip } from "recharts"; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + ResponsiveContainer, + Tooltip, +} from "recharts"; interface AppointmentsByDayProps { appointments: any[]; } export function AppointmentsByDay({ appointments }: AppointmentsByDayProps) { - // Data processing for appointments by day const daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - - // Initialize counts for each day - const countsByDay = daysOfWeek.map(day => ({ day, count: 0 })); - - // Count appointments by day of week - appointments.forEach(appointment => { + const countsByDay = daysOfWeek.map((day) => ({ day, count: 0 })); + + // Get current date and set time to start of day (midnight) + const now = new Date(); + now.setHours(0, 0, 0, 0); + + // Calculate Monday of the current week + const day = now.getDay(); // 0 = Sunday, 1 = Monday, ... + const diffToMonday = day === 0 ? -6 : 1 - day; // adjust if Sunday + const monday = new Date(now); + monday.setDate(now.getDate() + diffToMonday); + + // Sunday of the current week + const sunday = new Date(monday); + sunday.setDate(monday.getDate() + 6); + + // Filter appointments only from this week (Monday to Sunday) + const appointmentsThisWeek = appointments.filter((appointment) => { + if (!appointment.date) return false; + + const date = new Date(appointment.date); + // Reset time to compare just the date + date.setHours(0, 0, 0, 0); + + return date >= monday && date <= sunday; + }); + + // Count appointments by day for current week + appointmentsThisWeek.forEach((appointment) => { const date = new Date(appointment.date); const dayOfWeek = date.getDay(); // 0 = Sunday, 1 = Monday, ... - const dayIndex = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Adjust to make Monday first - countsByDay[dayIndex].count += 1; + const dayIndex = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Monday=0, Sunday=6 + if (countsByDay[dayIndex]) { + countsByDay[dayIndex].count += 1; + } }); + return ( - Appointments by Day -

Distribution of appointments throughout the week

+ + Appointments by Day + +

+ Distribution of appointments throughout the week +

@@ -34,9 +71,14 @@ export function AppointmentsByDay({ appointments }: AppointmentsByDayProps) { margin={{ top: 5, right: 5, left: 0, bottom: 5 }} > - + - [`${value} appointments`, "Count"]} labelFormatter={(value) => `${value}`} /> @@ -47,4 +89,4 @@ export function AppointmentsByDay({ appointments }: AppointmentsByDayProps) { ); -} \ No newline at end of file +} diff --git a/apps/Frontend/src/components/analytics/new-patients.tsx b/apps/Frontend/src/components/analytics/new-patients.tsx index a2d40e6..0336c34 100644 --- a/apps/Frontend/src/components/analytics/new-patients.tsx +++ b/apps/Frontend/src/components/analytics/new-patients.tsx @@ -16,7 +16,9 @@ export function NewPatients({ patients }: NewPatientsProps) { patients.forEach(patient => { const createdDate = new Date(patient.createdAt); const monthIndex = createdDate.getMonth(); - patientsByMonth[monthIndex].count += 1; + if (patientsByMonth[monthIndex]) { + patientsByMonth[monthIndex].count += 1; +} }); // Add some sample data for visual effect if no patients @@ -24,9 +26,10 @@ export function NewPatients({ patients }: NewPatientsProps) { // Sample data pattern similar to the screenshot const sampleData = [17, 12, 22, 16, 15, 17, 22, 28, 20, 16]; sampleData.forEach((value, index) => { - if (index < patientsByMonth.length) { + if (index < patientsByMonth.length ) { + if (patientsByMonth[index]) { patientsByMonth[index].count = value; - } + }} }); } diff --git a/apps/Frontend/src/pages/claims-page.tsx b/apps/Frontend/src/pages/claims-page.tsx index 710c1de..1c6dd4a 100644 --- a/apps/Frontend/src/pages/claims-page.tsx +++ b/apps/Frontend/src/pages/claims-page.tsx @@ -6,10 +6,60 @@ import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { ClaimForm } from "@/components/claims/claim-form"; import { useToast } from "@/hooks/use-toast"; import { useAuth } from "@/hooks/use-auth"; -// import { Patient, Appointment } from "@shared/schema"; -import { PatientUncheckedCreateInputObjectSchema, AppointmentUncheckedCreateInputObjectSchema } from "@repo/db/shared/schemas"; +import { PatientUncheckedCreateInputObjectSchema, AppointmentUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas"; import { Plus, FileCheck, CheckCircle, Clock, AlertCircle } from "lucide-react"; import { format } from "date-fns"; +import {z} from "zod"; +import { apiRequest } from "@/lib/queryClient"; + +//creating types out of schema auto generated. +type Appointment = z.infer; + +const insertAppointmentSchema = ( + AppointmentUncheckedCreateInputObjectSchema as unknown as z.ZodObject +).omit({ + id: true, + createdAt: true, +}); +type InsertAppointment = z.infer; + +const updateAppointmentSchema = ( + AppointmentUncheckedCreateInputObjectSchema as unknown as z.ZodObject +) + .omit({ + id: true, + createdAt: true, + }) + .partial(); +type UpdateAppointment = z.infer; + +const PatientSchema = ( + PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject +).omit({ + appointments: true, +}); +type Patient = z.infer; + +const insertPatientSchema = ( + PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject +).omit({ + id: true, + createdAt: true, +}); +type InsertPatient = z.infer; + +const updatePatientSchema = ( + PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject +) + .omit({ + id: true, + createdAt: true, + userId: true, + }) + .partial(); + +type UpdatePatient = z.infer; + export default function ClaimsPage() { const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); @@ -21,19 +71,29 @@ export default function ClaimsPage() { const { user } = useAuth(); // Fetch patients - const { data: patients = [], isLoading: isLoadingPatients } = useQuery({ - queryKey: ["/api/patients"], - enabled: !!user, - }); - + const { data: patients = [], isLoading: isLoadingPatients } = useQuery< + Patient[] + >({ + queryKey: ["/api/patients/"], + queryFn: async () => { + const res = await apiRequest("GET", "/api/patients/"); + return res.json(); + }, + enabled: !!user, + }); + // Fetch appointments - const { - data: appointments = [] as Appointment[], - isLoading: isLoadingAppointments - } = useQuery({ - queryKey: ["/api/appointments"], - enabled: !!user, - }); + const { + data: appointments = [] as Appointment[], + isLoading: isLoadingAppointments, + } = useQuery({ + queryKey: ["/api/appointments/all"], + queryFn: async () => { + const res = await apiRequest("GET", "/api/appointments/all"); + return res.json(); + }, + enabled: !!user, + }); const toggleMobileMenu = () => { setIsMobileMenuOpen(!isMobileMenuOpen); @@ -59,10 +119,10 @@ export default function ClaimsPage() { acc.push({ patientId: patient.id, patientName: `${patient.firstName} ${patient.lastName}`, - appointmentId: appointment.id, + appointmentId: Number(appointment.id), insuranceProvider: patient.insuranceProvider || 'N/A', insuranceId: patient.insuranceId || 'N/A', - lastAppointment: appointment.date + lastAppointment: String(appointment.date) }); } } @@ -98,7 +158,7 @@ export default function ClaimsPage() { onClick={() => { if (patientsWithAppointments.length > 0) { const firstPatient = patientsWithAppointments[0]; - handleNewClaim(firstPatient.patientId, firstPatient.appointmentId); + handleNewClaim(Number(firstPatient?.patientId), Number(firstPatient?.appointmentId)); } else { toast({ title: "No patients available",