source: frontend/src/pages/appointments/AppointmentForm.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.0 KB
Line 
1import React, { useState, useEffect } from 'react';
2import { useNavigate } from 'react-router-dom';
3import { appointmentService } from '../../services/appointmentService';
4import { patientService } from '../../services/patientService';
5import { doctorService } from '../../services/doctorService';
6import ErrorAlert from '../../components/ErrorAlert';
7import SuccessAlert from '../../components/SuccessAlert';
8
9function AppointmentForm() {
10 const navigate = useNavigate();
11 const user = JSON.parse(localStorage.getItem('user') || '{}');
12 const isPatient = user.role === 'PATIENT';
13 const isDoctor = user.role === 'DOCTOR';
14
15 const [formData, setFormData] = useState({
16 patientId: isPatient ? (user.patientId || '') : '',
17 doctorId: isDoctor ? (user.doctorId || '') : '',
18 appointmentDate: '',
19 appointmentTime: '',
20 });
21 const [patients, setPatients] = useState([]);
22 const [doctors, setDoctors] = useState([]);
23 const [error, setError] = useState(null);
24 const [success, setSuccess] = useState(null);
25 const [loading, setLoading] = useState(false);
26
27 useEffect(() => {
28 const fetchData = async () => {
29 try {
30 if (!isPatient) {
31 const patientsRes = await patientService.getAllPatients();
32 setPatients(patientsRes.data);
33 }
34
35 const doctorsRes = await doctorService.getAllDoctors();
36 setDoctors(doctorsRes.data);
37 } catch (err) {
38 setError('Failed to fetch doctors');
39 }
40 };
41
42 fetchData();
43 }, [isPatient]);
44
45 const handleChange = (e) => {
46 const { name, value } = e.target;
47 setFormData(prev => ({
48 ...prev,
49 [name]: value
50 }));
51 };
52
53 const handleSubmit = async (e) => {
54 e.preventDefault();
55
56 if (!formData.patientId || !formData.doctorId || !formData.appointmentDate || !formData.appointmentTime) {
57 setError('Please fill in all required fields');
58 return;
59 }
60
61 try {
62 setLoading(true);
63 await appointmentService.createAppointment({
64 patientId: parseInt(formData.patientId),
65 doctorId: parseInt(formData.doctorId),
66 appointmentDate: formData.appointmentDate,
67 appointmentTime: formData.appointmentTime,
68 });
69 setSuccess('Appointment created successfully!');
70 setTimeout(() => navigate('/appointments'), 1500);
71 } catch (err) {
72 setError(err.response?.data?.error || 'Failed to create appointment');
73 } finally {
74 setLoading(false);
75 }
76 };
77
78 return (
79 <div className="max-w-2xl mx-auto">
80 <h1 className="text-3xl font-bold mb-6">Create Appointment</h1>
81
82 {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
83 {success && <SuccessAlert message={success} onClose={() => setSuccess(null)} />}
84
85 <form onSubmit={handleSubmit} className="bg-white rounded-lg shadow p-6 space-y-4">
86 {isPatient ? (
87 <div className="bg-blue-50 rounded-lg p-4 mb-4">
88 <p className="text-sm text-gray-700">
89 <strong>Patient:</strong> {user.firstName} {user.lastName} ({user.username})
90 </p>
91 </div>
92 ) : (
93 <div>
94 <label className="block text-sm font-semibold mb-2">Patient *</label>
95 <select
96 name="patientId"
97 value={formData.patientId}
98 onChange={handleChange}
99 className="w-full px-4 py-2 border rounded-lg"
100 required
101 >
102 <option value="">Select Patient</option>
103 {patients.map(patient => (
104 <option key={patient.patientId} value={patient.patientId}>
105 {patient.firstName} {patient.lastName} ({patient.embg})
106 </option>
107 ))}
108 </select>
109 </div>
110 )}
111
112 {isDoctor ? (
113 <div>
114 <label className="block text-sm font-semibold mb-2">Doctor</label>
115 <p className="px-4 py-2 bg-gray-100 rounded-lg text-gray-700">
116 Dr. {user.firstName} {user.lastName}
117 </p>
118 </div>
119 ) : (
120 <div>
121 <label className="block text-sm font-semibold mb-2">Doctor *</label>
122 <select
123 name="doctorId"
124 value={formData.doctorId}
125 onChange={handleChange}
126 className="w-full px-4 py-2 border rounded-lg"
127 required
128 >
129 <option value="">Select Doctor</option>
130 {doctors.map(doctor => (
131 <option key={doctor.doctorId} value={doctor.doctorId}>
132 Dr. {doctor.firstName} {doctor.lastName}
133 </option>
134 ))}
135 </select>
136 </div>
137 )}
138
139 <div className="grid grid-cols-2 gap-4">
140 <div>
141 <label className="block text-sm font-semibold mb-2">Appointment Date *</label>
142 <input
143 type="date"
144 name="appointmentDate"
145 value={formData.appointmentDate}
146 onChange={handleChange}
147 className="w-full px-4 py-2 border rounded-lg"
148 required
149 />
150 </div>
151 <div>
152 <label className="block text-sm font-semibold mb-2">Appointment Time *</label>
153 <input
154 type="time"
155 name="appointmentTime"
156 value={formData.appointmentTime}
157 onChange={handleChange}
158 className="w-full px-4 py-2 border rounded-lg"
159 required
160 />
161 </div>
162 </div>
163
164 <div className="flex gap-4 pt-4">
165 <button
166 type="submit"
167 disabled={loading}
168 className="bg-purple-600 text-white px-6 py-2 rounded hover:bg-purple-700 disabled:opacity-50"
169 >
170 {loading ? 'Creating...' : 'Create Appointment'}
171 </button>
172 <button
173 type="button"
174 onClick={() => navigate('/appointments')}
175 className="bg-gray-300 text-gray-700 px-6 py-2 rounded hover:bg-gray-400"
176 >
177 Cancel
178 </button>
179 </div>
180 </form>
181 </div>
182 );
183}
184
185export default AppointmentForm;
Note: See TracBrowser for help on using the repository browser.