Index: frontend/src/pages/appointments/AppointmentForm.js
===================================================================
--- frontend/src/pages/appointments/AppointmentForm.js	(revision 20468d38749c5a3ed89d6df4db22905a1d0c3df1)
+++ frontend/src/pages/appointments/AppointmentForm.js	(revision 20468d38749c5a3ed89d6df4db22905a1d0c3df1)
@@ -0,0 +1,186 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { appointmentService } from '../../services/appointmentService';
+import { patientService } from '../../services/patientService';
+import { doctorService } from '../../services/doctorService';
+import ErrorAlert from '../../components/ErrorAlert';
+import SuccessAlert from '../../components/SuccessAlert';
+
+function AppointmentForm() {
+  const navigate = useNavigate();
+  const user = JSON.parse(localStorage.getItem('user') || '{}');
+  const isPatient = user.role === 'PATIENT';
+  const isDoctor = user.role === 'DOCTOR';
+
+  const [formData, setFormData] = useState({
+    patientId: isPatient ? (user.patientId || '') : '',
+    doctorId: isDoctor ? (user.doctorId || '') : '',
+    appointmentDate: '',
+    appointmentTime: '',
+  });
+  const [patients, setPatients] = useState([]);
+  const [doctors, setDoctors] = useState([]);
+  const [error, setError] = useState(null);
+  const [success, setSuccess] = useState(null);
+  const [loading, setLoading] = useState(false);
+
+  useEffect(() => {
+    fetchData();
+  }, []);
+
+  const fetchData = async () => {
+    try {
+      // For patients, we don't need to fetch all patients
+      if (!isPatient) {
+        const patientsRes = await patientService.getAllPatients();
+        setPatients(patientsRes.data);
+      }
+
+      const doctorsRes = await doctorService.getAllDoctors();
+      setDoctors(doctorsRes.data);
+    } catch (err) {
+      setError('Failed to fetch doctors');
+    }
+  };
+
+  const handleChange = (e) => {
+    const { name, value } = e.target;
+    setFormData(prev => ({
+      ...prev,
+      [name]: value
+    }));
+  };
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+
+    if (!formData.patientId || !formData.doctorId || !formData.appointmentDate || !formData.appointmentTime) {
+      setError('Please fill in all required fields');
+      return;
+    }
+
+    try {
+      setLoading(true);
+      await appointmentService.createAppointment({
+        patientId: parseInt(formData.patientId),
+        doctorId: parseInt(formData.doctorId),
+        appointmentDate: formData.appointmentDate,
+        appointmentTime: formData.appointmentTime,
+      });
+      setSuccess('Appointment created successfully!');
+      setTimeout(() => navigate('/appointments'), 1500);
+    } catch (err) {
+      setError(err.response?.data?.error || 'Failed to create appointment');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  return (
+    <div className="max-w-2xl mx-auto">
+      <h1 className="text-3xl font-bold mb-6">Create Appointment</h1>
+
+      {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
+      {success && <SuccessAlert message={success} onClose={() => setSuccess(null)} />}
+
+      <form onSubmit={handleSubmit} className="bg-white rounded-lg shadow p-6 space-y-4">
+        {isPatient ? (
+          <div className="bg-blue-50 rounded-lg p-4 mb-4">
+            <p className="text-sm text-gray-700">
+              <strong>Patient:</strong> {user.firstName} {user.lastName} ({user.username})
+            </p>
+          </div>
+        ) : (
+          <div>
+            <label className="block text-sm font-semibold mb-2">Patient *</label>
+            <select
+              name="patientId"
+              value={formData.patientId}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            >
+              <option value="">Select Patient</option>
+              {patients.map(patient => (
+                <option key={patient.patientId} value={patient.patientId}>
+                  {patient.firstName} {patient.lastName} ({patient.embg})
+                </option>
+              ))}
+            </select>
+          </div>
+        )}
+
+        {isDoctor ? (
+          <div>
+            <label className="block text-sm font-semibold mb-2">Doctor</label>
+            <p className="px-4 py-2 bg-gray-100 rounded-lg text-gray-700">
+              Dr. {user.firstName} {user.lastName}
+            </p>
+          </div>
+        ) : (
+          <div>
+            <label className="block text-sm font-semibold mb-2">Doctor *</label>
+            <select
+              name="doctorId"
+              value={formData.doctorId}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            >
+              <option value="">Select Doctor</option>
+              {doctors.map(doctor => (
+                <option key={doctor.doctorId} value={doctor.doctorId}>
+                  Dr. {doctor.firstName} {doctor.lastName}
+                </option>
+              ))}
+            </select>
+          </div>
+        )}
+
+        <div className="grid grid-cols-2 gap-4">
+          <div>
+            <label className="block text-sm font-semibold mb-2">Appointment Date *</label>
+            <input
+              type="date"
+              name="appointmentDate"
+              value={formData.appointmentDate}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            />
+          </div>
+          <div>
+            <label className="block text-sm font-semibold mb-2">Appointment Time *</label>
+            <input
+              type="time"
+              name="appointmentTime"
+              value={formData.appointmentTime}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            />
+          </div>
+        </div>
+
+        <div className="flex gap-4 pt-4">
+          <button
+            type="submit"
+            disabled={loading}
+            className="bg-purple-600 text-white px-6 py-2 rounded hover:bg-purple-700 disabled:opacity-50"
+          >
+            {loading ? 'Creating...' : 'Create Appointment'}
+          </button>
+          <button
+            type="button"
+            onClick={() => navigate('/appointments')}
+            className="bg-gray-300 text-gray-700 px-6 py-2 rounded hover:bg-gray-400"
+          >
+            Cancel
+          </button>
+        </div>
+      </form>
+    </div>
+  );
+}
+
+export default AppointmentForm;
Index: frontend/src/pages/appointments/AppointmentList.js
===================================================================
--- frontend/src/pages/appointments/AppointmentList.js	(revision 20468d38749c5a3ed89d6df4db22905a1d0c3df1)
+++ frontend/src/pages/appointments/AppointmentList.js	(revision 20468d38749c5a3ed89d6df4db22905a1d0c3df1)
@@ -0,0 +1,128 @@
+import React, { useState, useEffect } from 'react';
+import { Link, useSearchParams } from 'react-router-dom';
+import { appointmentService } from '../../services/appointmentService';
+import Loading from '../../components/Loading';
+import ErrorAlert from '../../components/ErrorAlert';
+
+function AppointmentList() {
+  const [appointments, setAppointments] = useState([]);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+  const [searchParams] = useSearchParams();
+  const doctorId = searchParams.get('doctorId');
+  const patientId = searchParams.get('patientId');
+  const user = JSON.parse(localStorage.getItem('user') || '{}');
+
+  useEffect(() => {
+    fetchAppointments();
+  }, [doctorId, patientId]);
+
+  const fetchAppointments = async () => {
+    try {
+      setLoading(true);
+      let response;
+      if (patientId) {
+        response = await appointmentService.getAppointmentsForPatient(patientId);
+      } else if (doctorId) {
+        response = await appointmentService.getAppointmentsForDoctor(doctorId);
+      } else if (user.role === 'PATIENT') {
+        response = await appointmentService.getAppointmentsForPatient(user.patientId);
+      } else if (user.role === 'DOCTOR') {
+        response = await appointmentService.getAppointmentsForDoctor(user.doctorId);
+      } else {
+        response = await appointmentService.getAllAppointments();
+      }
+      setAppointments(response.data);
+    } catch (err) {
+      setError('Failed to fetch appointments');
+      console.error(err);
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const handleCancelAppointment = async (id) => {
+    if (window.confirm('Are you sure you want to cancel this appointment?')) {
+      try {
+        await appointmentService.cancelAppointment(id);
+        setAppointments(appointments.map(apt =>
+          apt.appointmentId === id ? { ...apt, status: 'CANCELLED' } : apt
+        ));
+      } catch (err) {
+        setError('Failed to cancel appointment');
+      }
+    }
+  };
+
+  if (loading) return <Loading />;
+
+  return (
+    <div>
+      <div className="flex justify-between items-center mb-6">
+        <h1 className="text-3xl font-bold" style={{ color: '#7c3aed' }}>
+          {patientId ? 'Patient Appointments' : doctorId ? 'My Appointments' : 'All Appointments'}
+        </h1>
+        <Link to="/appointments/new" style={{
+          display: 'inline-block',
+          background: '#bfdbfe',
+          color: '#1e1035',
+          padding: '8px 16px',
+          borderRadius: '6px',
+          textDecoration: 'none',
+          fontSize: '14px',
+          fontWeight: '400'
+        }} onMouseEnter={(e) => e.currentTarget.style.background = '#93c5fd'} onMouseLeave={(e) => e.currentTarget.style.background = '#bfdbfe'}>
+          New Appointment
+        </Link>
+      </div>
+
+      {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
+
+      <div className="bg-white rounded-lg shadow overflow-hidden">
+        <table className="w-full">
+          <thead className="bg-gray-100">
+            <tr>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Patient</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Doctor</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Date</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Time</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Status</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Actions</th>
+            </tr>
+          </thead>
+          <tbody>
+            {appointments.map(appointment => (
+              <tr key={appointment.appointmentId} className="border-t hover:bg-gray-50">
+                <td className="px-6 py-3">{appointment.patient?.firstName} {appointment.patient?.lastName}</td>
+                <td className="px-6 py-3">Dr. {appointment.doctor?.firstName} {appointment.doctor?.lastName}</td>
+                <td className="px-6 py-3">{appointment.appointmentDate}</td>
+                <td className="px-6 py-3">{appointment.appointmentTime}</td>
+                <td className="px-6 py-3">
+                  <span className={`px-3 py-1 rounded text-sm font-semibold ${
+                    appointment.status === 'SCHEDULED' ? 'bg-purple-100 text-purple-800' :
+                    appointment.status === 'COMPLETED' ? 'bg-green-100 text-green-800' :
+                    'bg-red-100 text-red-800'
+                  }`}>
+                    {appointment.status}
+                  </span>
+                </td>
+                <td className="px-6 py-3">
+                  {appointment.status === 'SCHEDULED' && (
+                    <button
+                      onClick={() => handleCancelAppointment(appointment.appointmentId)}
+                      className="text-red-600 hover:underline px-3 py-2 text-sm font-medium"
+                    >
+                      Cancel
+                    </button>
+                  )}
+                </td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
+      </div>
+    </div>
+  );
+}
+
+export default AppointmentList;
