Overview
The Appointment module provides a comprehensive scheduling system with calendar views, real-time status management, and filtering capabilities across doctors and branches.
Appointment Calendar
Timeline View
The main appointment page (/appointments) displays a professional timeline view with:
30-minute time slots from 8:00 AM to 6:30 PM
Mini calendar for quick date navigation
Advanced filters for doctor, branch, and status
Real-time statistics showing total, pending, and completed appointments
Calendar Navigation
The sidebar includes a mini calendar with:
Month/year navigation with arrow buttons
Day selection (Monday-Sunday format)
Today indicator with teal border
Selected date highlighting
Automatic appointment refresh on date change
// Navigate between months
function changeMonth ( delta ) {
const newDate = new Date ( viewDate );
newDate . setMonth ( newDate . getMonth () + delta );
viewDate = newDate ;
}
Database Schema
CREATE TABLE appointments (
id INT AUTO_INCREMENT PRIMARY KEY ,
patient_id INT NOT NULL ,
doctor_id INT NOT NULL ,
branch_id INT NOT NULL ,
appointment_date DATE NOT NULL ,
appointment_time TIME NOT NULL ,
duration_minutes INT DEFAULT 30 ,
status ENUM( 'scheduled' , 'confirmed' , 'waiting' , 'completed' , 'cancelled' ) DEFAULT 'scheduled' ,
notes TEXT ,
uuid CHAR ( 36 ) UNIQUE ,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (patient_id) REFERENCES patients(id) ON DELETE CASCADE ,
FOREIGN KEY (doctor_id) REFERENCES doctors(id) ON DELETE CASCADE ,
FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE
);
Appointment Status Management
Status Workflow
Appointments follow a lifecycle with 5 distinct statuses:
Scheduled
Initial state when appointment is created. Shows in gray/slate color.
Confirmed
Patient confirmed attendance via phone/WhatsApp. Shows in blue.
Waiting
Patient arrived and is in the waiting room. Shows in amber/yellow.
Completed
Appointment finished successfully. Shows in green/teal.
Cancelled
Appointment was cancelled by patient or clinic. Shows in red/rose.
Status Colors
.badge-scheduled { background : #f1f5f9 ; color : #475569 ; }
.badge-confirmed { background : #eff6ff ; color : #1e40af ; }
.badge-waiting { background : #fffbeb ; color : #92400e ; }
.badge-completed { background : #f0fdf4 ; color : #15803d ; }
.badge-cancelled { background : #fef2f2 ; color : #b91c1c ; }
Updating Status
Staff can update appointment status directly from the timeline:
Click the status dropdown on any appointment
Select the new status
Status updates immediately via API
API Endpoint:
PATCH / api / appointments / { id }
Body : {
status : 'scheduled' | 'confirmed' | 'waiting' | 'completed' | 'cancelled'
}
Advanced Filtering
Filter Options
The sidebar provides multiple filters:
Doctor Filter Filter by specific doctor or view all doctors’ appointments.
Branch Filter Filter by clinic branch (Central, Norte, Sur).
Status Filter Filter by appointment status to focus on specific workflows.
Filter Implementation
const filters = {
doctor_id: 'all' ,
branch_id: 'all' ,
status: 'all'
};
// API call with filters
const params = new URLSearchParams ({
date: dateStr ,
doctor_id: filters . doctor_id ,
branch_id: filters . branch_id ,
status: filters . status
});
fetch ( `/api/appointments? ${ params . toString () } ` );
Appointment Details
Each appointment block shows:
Exact time in [HH:MM] format with teal background
Patient name as clickable link to patient profile
Doctor name with emoji icon (👨⚕️)
Branch location with emoji icon (📍)
Status dropdown for quick updates
Notes (if present) in styled box with 📝 icon
Clicking the patient name navigates to /patients/{patient_id} for quick access to full patient details.
Appointment Block Styling
Appointments feature:
Left border color matching status
Hover animation (slide right with shadow)
Rounded corners (18px border-radius)
Subtle shadow for depth
.apt-block-premium {
border-left : 6 px solid var ( --status-color );
transition : all 0.2 s ;
}
.apt-block-premium:hover {
transform : translateX ( 4 px );
box-shadow : 0 10 px 15 px -3 px rgba ( 0 , 0 , 0 , 0.05 );
}
Statistics Dashboard
Real-time Metrics
The header displays three key statistics:
const stats = {
total: appointments . length ,
completed: appointments . filter ( a => a . status === 'completed' ). length ,
pending: appointments . filter ( a =>
[ 'scheduled' , 'confirmed' , 'waiting' ]. includes ( a . status )
). length
};
Total Total appointments for selected date
Pendientes Appointments awaiting completion (shown in amber)
Completadas Successfully completed appointments (shown in teal)
Creating Appointments
From Patient Profile
Appointments are typically created from the patient profile page:
Navigate to patient details
Go to “Appointments” tab
Click “Nueva Cita” button
Fill in appointment details:
Doctor selection
Date and time
Duration (default 30 minutes)
Branch selection
Optional notes
Required Permissions:
CREATE_APPOINTMENTS - Create new appointments
VIEW_APPOINTMENTS - View appointment calendar
API Endpoint
POST / api / appointments
Body : {
patient_id : number ,
doctor_id : number ,
branch_id : number ,
appointment_date : string , // YYYY-MM-DD
appointment_time : string , // HH:MM:SS
duration_minutes : number ,
notes ?: string
}
Appointment Reminders
UUID System
Each appointment has a unique UUID for secure reminder links:
uuid CHAR ( 36 ) UNIQUE -- For reminder URLs and WhatsApp links
This UUID can be used for:
WhatsApp reminder messages
Email confirmation links
Public-facing confirmation pages
Reminder Permissions
Access the reminders dashboard to see upcoming appointments needing confirmation.
Send WhatsApp or email reminders to patients about their appointments.
Time Slot Management
30-Minute Intervals
The timeline is divided into 30-minute slots:
const hours = [
'08:00' , '08:30' , '09:00' , '09:30' , '10:00' , '10:30' ,
'11:00' , '11:30' , '12:00' , '12:30' , '13:00' , '13:30' ,
'14:00' , '14:30' , '15:00' , '15:30' , '16:00' , '16:30' ,
'17:00' , '17:30' , '18:00' , '18:30'
];
Slot Assignment Logic
Appointments are assigned to slots based on their start time:
const slotApts = appointments . filter ( a => {
const [ ah , am ] = a . appointment_time . split ( ':' ). map ( Number );
const [ sh , sm ] = h . split ( ':' ). map ( Number );
// Match hour and minute range (0-29 or 30-59)
return ah === sh && ( sm === 0 ? am < 30 : am >= 30 );
});
Empty slots display a dashed line to indicate availability.
Permissions Reference
Appointment Permissions
VIEW_APPOINTMENTS Module : CitasAccess the appointment calendar and view scheduled appointments.
CREATE_APPOINTMENTS Module : CitasSchedule new appointments in the system.
EDIT_APPOINTMENTS Module : CitasModify existing appointment details (time, doctor, notes).
CANCEL_APPOINTMENTS Module : CitasCancel appointments when patients reschedule or no-show.
API Reference
List Appointments
GET / api / appointments ? date = {YYYY-MM- DD } & doctor_id = { id } & branch_id = { id } & status = { status }
Response : {
success: true ,
appointments: [
{
id: number ,
patient_id: number ,
patient_first_name: string ,
patient_last_name: string ,
doctor_id: number ,
doctor_name: string ,
branch_id: number ,
branch_name: string ,
appointment_date: string ,
appointment_time: string ,
duration_minutes: number ,
status: string ,
notes: string | null ,
uuid: string
}
]
}
Update Appointment Status
PATCH / api / appointments / { id }
Body : { status : string }
Response : {
success : true ,
message : 'Appointment updated'
}
Mobile Responsiveness
On screens below 1024px width, the sidebar stacks above the timeline for better mobile viewing.
@media ( max-width : 1024 px ) {
.agenda-layout {
grid-template-columns : 1 fr ;
}
}
Best Practices
Confirm Appointments
Use the “Confirmed” status after calling patients to verify attendance.
Update Status Promptly
Change to “Waiting” when patients arrive, and “Completed” after consultation.
Add Detailed Notes
Include reason for visit or special instructions in the notes field.
Handle Cancellations
Mark appointments as “Cancelled” rather than deleting them for record-keeping.
Use Filters Efficiently
Filter by doctor or branch to manage busy schedules across multiple locations.