Index: frontend/src/pages/patients/PatientDetail.js
===================================================================
--- frontend/src/pages/patients/PatientDetail.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/src/pages/patients/PatientDetail.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,105 @@
+import React, { useState, useEffect } from 'react';
+import { useParams, Link, useNavigate } from 'react-router-dom';
+import { patientService } from '../../services/patientService';
+import Loading from '../../components/Loading';
+import ErrorAlert from '../../components/ErrorAlert';
+
+function PatientDetail() {
+  const user = JSON.parse(localStorage.getItem('user') || '{}');
+  const isAdmin = user.role === 'ADMIN';
+  const isLabTechnician = user.role === 'LAB_TECHNICIAN';
+  const { id } = useParams();
+  const navigate = useNavigate();
+  const [patient, setPatient] = useState(null);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+
+  useEffect(() => {
+    const fetchPatient = async () => {
+      try {
+        setLoading(true);
+        const response = await patientService.getPatientById(id);
+        setPatient(response.data);
+      } catch (err) {
+        setError('Failed to fetch patient details');
+        console.error(err);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchPatient();
+  }, [id]);
+
+  if (loading) return <Loading />;
+
+  if (!patient) {
+    return (
+      <div>
+        <ErrorAlert message="Patient not found" onClose={() => navigate('/patients')} />
+      </div>
+    );
+  }
+
+  return (
+    <div>
+      <div className="flex justify-between items-center mb-6">
+        <h1 className="text-3xl font-bold" style={{ color: '#7c3aed' }}>{patient.firstName} {patient.lastName}</h1>
+        <div className="space-x-2">
+          {isAdmin && (
+            <Link to={`/patients/${id}/edit`} className="bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700">
+              Edit
+            </Link>
+          )}
+          <button onClick={() => navigate('/patients')} className="bg-gray-300 text-gray-700 px-4 py-2 rounded hover:bg-gray-400">
+            Back
+          </button>
+        </div>
+      </div>
+
+      {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
+
+      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
+        <div className="bg-white rounded-lg shadow p-6">
+          <h2 className="text-xl font-bold mb-4">Personal Information</h2>
+          <div className="space-y-3">
+            <InfoRow label="EMBG" value={patient.embg} />
+            <InfoRow label="Email" value={patient.emailAddress} />
+            <InfoRow label="Phone" value={patient.phoneNumber} />
+            <InfoRow label="Date of Birth" value={patient.dateOfBirth} />
+            <InfoRow label="Gender" value={patient.gender} />
+            <InfoRow label="Blood Type" value={patient.bloodType} />
+          </div>
+        </div>
+
+        {!isLabTechnician && (
+          <div className="bg-white rounded-lg shadow p-6">
+            <h2 className="text-xl font-bold mb-4">Quick Links</h2>
+            <div className="space-y-2">
+              <Link to={`/appointments?patientId=${id}`} className="block p-3 bg-blue-50 hover:bg-purple-100 rounded text-purple-600">
+                View Appointments
+              </Link>
+              <Link to={`/medical-records?patientId=${id}`} className="block p-3 bg-green-50 hover:bg-green-100 rounded text-green-600">
+                View Medical Records
+              </Link>
+              <Link to={`/billing?patientId=${id}`} className="block p-3 bg-purple-50 hover:bg-purple-100 rounded text-purple-600">
+                View Billing History
+              </Link>
+            </div>
+          </div>
+        )}
+      </div>
+    </div>
+  );
+}
+
+function InfoRow({ label, value }) {
+  return (
+    <div className="flex justify-between">
+      <span className="font-semibold text-gray-600">{label}:</span>
+      <span className="text-gray-800">{value || 'N/A'}</span>
+    </div>
+  );
+}
+
+export default PatientDetail;
Index: frontend/src/pages/patients/PatientForm.js
===================================================================
--- frontend/src/pages/patients/PatientForm.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/src/pages/patients/PatientForm.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,214 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { patientService } from '../../services/patientService';
+import ErrorAlert from '../../components/ErrorAlert';
+import SuccessAlert from '../../components/SuccessAlert';
+
+function PatientForm() {
+  const { id } = useParams();
+  const navigate = useNavigate();
+  const [formData, setFormData] = useState({
+    firstName: '',
+    lastName: '',
+    emailAddress: '',
+    embg: '',
+    phoneNumber: '',
+    dateOfBirth: '',
+    gender: '',
+    bloodType: '',
+  });
+  const [error, setError] = useState(null);
+  const [success, setSuccess] = useState(null);
+  const [loading, setLoading] = useState(false);
+
+  useEffect(() => {
+    if (id) {
+      const fetchPatient = async () => {
+        try {
+          setLoading(true);
+          const response = await patientService.getPatientById(id);
+          setFormData(response.data);
+        } catch (err) {
+          setError('Failed to fetch patient');
+        } finally {
+          setLoading(false);
+        }
+      };
+
+      fetchPatient();
+    }
+  }, [id]);
+
+  const handleChange = (e) => {
+    const { name, value } = e.target;
+    setFormData(prev => ({
+      ...prev,
+      [name]: value
+    }));
+  };
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+
+    if (!formData.firstName || !formData.lastName || !formData.embg) {
+      setError('Please fill in all required fields');
+      return;
+    }
+
+    try {
+      setLoading(true);
+      if (id) {
+        await patientService.updatePatient(id, formData);
+        setSuccess('Patient updated successfully!');
+      } else {
+        await patientService.createPatient(formData);
+        setSuccess('Patient created successfully!');
+      }
+      setTimeout(() => navigate('/patients'), 1500);
+    } catch (err) {
+      setError(err.response?.data?.error || 'Failed to save patient');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  return (
+    <div className="max-w-2xl mx-auto">
+      <h1 className="text-3xl font-bold mb-6">
+        {id ? 'Edit Patient' : 'Add New Patient'}
+      </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">
+        <div className="grid grid-cols-2 gap-4">
+          <div>
+            <label className="block text-sm font-semibold mb-2">First Name *</label>
+            <input
+              type="text"
+              name="firstName"
+              value={formData.firstName}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            />
+          </div>
+          <div>
+            <label className="block text-sm font-semibold mb-2">Last Name *</label>
+            <input
+              type="text"
+              name="lastName"
+              value={formData.lastName}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+              required
+            />
+          </div>
+        </div>
+
+        <div>
+          <label className="block text-sm font-semibold mb-2">EMBG *</label>
+          <input
+            type="text"
+            name="embg"
+            value={formData.embg}
+            onChange={handleChange}
+            className="w-full px-4 py-2 border rounded-lg"
+            required
+            disabled={!!id}
+          />
+        </div>
+
+        <div>
+          <label className="block text-sm font-semibold mb-2">Email</label>
+          <input
+            type="email"
+            name="emailAddress"
+            value={formData.emailAddress}
+            onChange={handleChange}
+            className="w-full px-4 py-2 border rounded-lg"
+          />
+        </div>
+
+        <div className="grid grid-cols-2 gap-4">
+          <div>
+            <label className="block text-sm font-semibold mb-2">Phone</label>
+            <input
+              type="tel"
+              name="phoneNumber"
+              value={formData.phoneNumber}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+            />
+          </div>
+          <div>
+            <label className="block text-sm font-semibold mb-2">Date of Birth</label>
+            <input
+              type="date"
+              name="dateOfBirth"
+              value={formData.dateOfBirth}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+            />
+          </div>
+        </div>
+
+        <div className="grid grid-cols-2 gap-4">
+          <div>
+            <label className="block text-sm font-semibold mb-2">Gender</label>
+            <select
+              name="gender"
+              value={formData.gender}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+            >
+              <option value="">Select Gender</option>
+              <option value="MALE">Male</option>
+              <option value="FEMALE">Female</option>
+              <option value="OTHER">Other</option>
+            </select>
+          </div>
+          <div>
+            <label className="block text-sm font-semibold mb-2">Blood Type</label>
+            <select
+              name="bloodType"
+              value={formData.bloodType}
+              onChange={handleChange}
+              className="w-full px-4 py-2 border rounded-lg"
+            >
+              <option value="">Select Blood Type</option>
+              <option value="O_POSITIVE">O+</option>
+              <option value="O_NEGATIVE">O-</option>
+              <option value="A_POSITIVE">A+</option>
+              <option value="A_NEGATIVE">A-</option>
+              <option value="B_POSITIVE">B+</option>
+              <option value="B_NEGATIVE">B-</option>
+              <option value="AB_POSITIVE">AB+</option>
+              <option value="AB_NEGATIVE">AB-</option>
+            </select>
+          </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 ? 'Saving...' : 'Save Patient'}
+          </button>
+          <button
+            type="button"
+            onClick={() => navigate('/patients')}
+            className="bg-gray-300 text-gray-700 px-6 py-2 rounded hover:bg-gray-400"
+          >
+            Cancel
+          </button>
+        </div>
+      </form>
+    </div>
+  );
+}
+
+export default PatientForm;
Index: frontend/src/pages/patients/PatientList.js
===================================================================
--- frontend/src/pages/patients/PatientList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/src/pages/patients/PatientList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,104 @@
+import React, { useState, useEffect } from 'react';
+import { Link } from 'react-router-dom';
+import { patientService } from '../../services/patientService';
+import Loading from '../../components/Loading';
+import ErrorAlert from '../../components/ErrorAlert';
+
+function PatientList() {
+  const user = JSON.parse(localStorage.getItem('user') || '{}');
+  const isAdmin = user.role === 'ADMIN';
+  const [patients, setPatients] = useState([]);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+  const [searchTerm, setSearchTerm] = useState('');
+
+  useEffect(() => {
+    fetchPatients();
+  }, []);
+
+  const fetchPatients = async () => {
+    try {
+      setLoading(true);
+      const response = await patientService.getAllPatients();
+      setPatients(response.data);
+    } catch (err) {
+      setError('Failed to fetch patients');
+      console.error(err);
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const filteredPatients = patients.filter(patient =>
+    patient.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
+    patient.lastName.toLowerCase().includes(searchTerm.toLowerCase()) ||
+    patient.embg.includes(searchTerm)
+  );
+
+  if (loading) return <Loading />;
+
+  return (
+    <div>
+      <div className="flex justify-between items-center mb-6">
+        <h1 className="text-3xl font-bold" style={{ color: '#7c3aed' }}>Patients</h1>
+        {isAdmin && (
+          <Link to="/patients/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'}>
+            Add Patient
+          </Link>
+        )}
+      </div>
+
+      {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
+
+      <div className="mb-6">
+        <input
+          type="text"
+          placeholder="Search by name or EMBG..."
+          className="w-full px-4 py-2 border rounded-lg"
+          value={searchTerm}
+          onChange={(e) => setSearchTerm(e.target.value)}
+        />
+      </div>
+
+      <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">Name</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">EMBG</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Email</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Phone</th>
+              <th className="px-6 py-3 text-left text-sm font-semibold">Actions</th>
+            </tr>
+          </thead>
+          <tbody>
+            {filteredPatients.map(patient => (
+              <tr key={patient.patientId} className="border-t hover:bg-gray-50">
+                <td className="px-6 py-3">{patient.firstName} {patient.lastName}</td>
+                <td className="px-6 py-3">{patient.embg}</td>
+                <td className="px-6 py-3">{patient.emailAddress}</td>
+                <td className="px-6 py-3">{patient.phoneNumber}</td>
+                <td className="px-6 py-3">
+                  <Link to={`/patients/${patient.patientId}`} className="text-purple-600 hover:underline">
+                    View
+                  </Link>
+                </td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
+      </div>
+    </div>
+  );
+}
+
+export default PatientList;
