diff --git a/client/index.html b/client/index.html
index afbe8ee..864a5c7 100644
--- a/client/index.html
+++ b/client/index.html
@@ -4,7 +4,7 @@
-
-
- {/* Header */}
-
+
+ {/* Header Section */}
+
+
+
My Appointments
+
+ Manage and view your medical appointments
+
+
+
+ {/* Search and Filter */}
+
+
+
+
+
+
+
+
+
+
+
+
{/* Error State */}
- {error &&
}
+ {error && (
+
+ )}
+
+ {/* Tabs */}
+
+
+
+ {[
+ { id: 'upcoming', label: 'Upcoming', count: tabCounts.upcoming },
+ { id: 'today', label: 'Today', count: tabCounts.today },
+ { id: 'past', label: 'Past', count: tabCounts.past },
+ ].map((tab) => (
+
+ ))}
+
+
+
{/* Main Content */}
-
navigate(`/patient/appointment/${appointmentId}`)}
- />
-
- {/* Quick Stats */}
-
+
+ {tabAppointments.length === 0 ? (
+
+
+
+ No {activeTab} appointments
+
+
+ {searchTerm || filterStatus !== 'all'
+ ? 'No appointments match your search criteria.'
+ : `You have no ${activeTab} appointments.`}
+
+
+ ) : (
+
+ {tabAppointments.map((appointment) => (
+
handleAppointmentClick(appointment._id)}
+ />
+ ))}
+
+ )}
+
+
+ {/* Stats Cards */}
+
+ }
+ iconBg="bg-gray-100"
+ iconColor="text-gray-600"
+ />
+ }
+ iconBg="bg-blue-100"
+ iconColor="text-blue-600"
+ />
+ }
+ iconBg="bg-green-100"
+ iconColor="text-green-600"
+ />
+ }
+ iconBg="bg-purple-100"
+ iconColor="text-purple-600"
+ />
+
+
+
+ );
+};
+
+/**
+ * AppointmentCard Component
+ * Displays individual appointment information
+ *
+ * @param {Object} props - Component props
+ * @param {Object} props.appointment - Appointment data
+ * @param {boolean} props.hasPrescription - Whether prescription is available
+ * @param {Function} props.onClick - Click handler
+ */
+const AppointmentCard = ({ appointment, hasPrescription, onClick }) => {
+ const getStatusBadge = (status) => {
+ const statusConfig = {
+ scheduled: {
+ label: 'Pending',
+ bg: 'bg-yellow-50',
+ text: 'text-yellow-700',
+ border: 'border-yellow-200',
+ },
+ completed: {
+ label: 'Completed',
+ bg: 'bg-green-50',
+ text: 'text-green-700',
+ border: 'border-green-200',
+ },
+ cancelled: {
+ label: 'Cancelled',
+ bg: 'bg-red-50',
+ text: 'text-red-700',
+ border: 'border-red-200',
+ },
+ };
+
+ const config = statusConfig[status] || statusConfig.scheduled;
+
+ return (
+
+ ⏱ {config.label}
+
+ );
+ };
+
+ const getInitials = (firstName, lastName) => {
+ const first = firstName?.charAt(0) || '';
+ const last = lastName?.charAt(0) || '';
+ return `${first}${last}`.toUpperCase() || 'NA';
+ };
+
+ return (
+
{
+ if (e.key === 'Enter' || e.key === ' ') {
+ onClick();
+ }
+ }}
+ aria-label={`View appointment with Dr. ${appointment.doctorId?.firstName} ${appointment.doctorId?.lastName}`}
+ >
+ {/* Header with Avatar and Status */}
+
+
+
+ {getInitials(appointment.doctorId?.firstName, appointment.doctorId?.lastName)}
+
+
+
+ Dr. {appointment.doctorId?.firstName || 'N/A'} {appointment.doctorId?.lastName || ''}
+
+
+ {appointment.doctorId?.specialization || 'General'}
+
+
+
+ {getStatusBadge(appointment.status)}
+
+
+ {/* Date and Time */}
+
+
+
+ {appointment.date || 'N/A'}
+
+ {appointment.time || 'N/A'}
+
+
+
+ {appointment.clinicId?.name || 'N/A'}
+
+ {appointment.visitType && (
+
+
+ {appointment.visitType}
+
+ )}
+
+
+ {/* Reason */}
+ {appointment.reason && (
+
+
Reason:
+
{appointment.reason}
+
+ )}
+
+ {/* Prescription Status */}
+
+
+
+
+ Prescription: {hasPrescription ? 'Available' : 'Not available'}
+
+
+ {hasPrescription && (
+
+ )}
+
+
+ );
+};
+
+/**
+ * StatCard Component
+ * Displays appointment statistics
+ *
+ * @param {Object} props - Component props
+ * @param {string} props.label - Stat label
+ * @param {number} props.value - Stat value
+ * @param {JSX.Element} props.icon - Icon component
+ * @param {string} props.iconBg - Icon background color class
+ * @param {string} props.iconColor - Icon color class
+ */
+const StatCard = ({ label, value, icon, iconBg, iconColor }) => {
+ return (
+
);