source: frontend/src/pages/Consultations.tsx@ 700e2f9

main
Last change on this file since 700e2f9 was 700e2f9, checked in by 186079 <matej.milevski@…>, 5 days ago

Init

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[700e2f9]1import {
2 type Component,
3 createEffect,
4 createResource,
5 createSignal,
6 Show,
7} from "solid-js";
8import { useNavigate } from "@solidjs/router";
9import { useAuth } from "@/context/AuthContext";
10import {
11 consultationApi,
12 type Consultation,
13 type CreateConsultationRequest,
14 type UpdateConsultationRequest,
15 isConsultationPaid,
16} from "@/api/consultation";
17import ConsultationTable from "../components/ConsultationTable";
18import ConsultationModal from "../components/ConsultationModal";
19import { patientApi } from "@/api/patient";
20import { UserType } from "@/enums/UserType";
21import type { Therapy } from "@/api/therapy";
22
23const Consultations: Component = () => {
24 const { user, isAuthenticated } = useAuth();
25 const navigate = useNavigate();
26
27 const [isModalOpen, setIsModalOpen] = createSignal(false);
28 const [editingConsultation, setEditingConsultation] =
29 createSignal<Consultation | null>(null);
30 const [formData, setFormData] = createSignal({
31 patientId: 0,
32 date: "",
33 price: 0,
34 advice: "",
35 dateOfPayment: null as string | null,
36 });
37 const [newTherapies, setNewTherapies] = createSignal<Therapy[]>([]);
38 const [existingTherapies, setExistingTherapies] = createSignal<Therapy[]>([]);
39
40 const isTherapist = () => user()?.userType === UserType.THERAPIST;
41 const isPatient = () => user()?.userType === UserType.PATIENT;
42
43 const [patients] = createResource(
44 () => ({
45 authenticated: isAuthenticated(),
46 isTherapist: isTherapist(),
47 }),
48 async (params) => {
49 if (!params.authenticated || !params.isTherapist) return [];
50 return await patientApi.getAllPatients();
51 },
52 );
53
54 const [consultations, { refetch }] = createResource(
55 () => ({
56 authenticated: isAuthenticated(),
57 userId: user()?.userId,
58 isTherapist: isTherapist(),
59 isPatient: isPatient(),
60 }),
61 async (params) => {
62 if (!params.authenticated || !params.userId) return [];
63
64 if (params.isTherapist) {
65 return await consultationApi.getTherapistConsultations(params.userId);
66 } else if (params.isPatient) {
67 return await consultationApi.getPatientConsultations(params.userId);
68 }
69
70 return [];
71 },
72 );
73
74 createEffect(() => {
75 if (!isAuthenticated()) {
76 navigate("/login", { replace: true });
77 }
78 });
79
80 const openCreateModal = () => {
81 setEditingConsultation(null);
82 setNewTherapies([]);
83 setExistingTherapies([]);
84 const today = new Date().toISOString().split("T")[0];
85 setFormData({
86 patientId: patients()?.[0]?.userId || 0,
87 date: today,
88 price: 0,
89 advice: "",
90 dateOfPayment: null,
91 });
92 setIsModalOpen(true);
93 };
94
95 const openEditModal = (consultation: Consultation) => {
96 setEditingConsultation(consultation);
97 setExistingTherapies(consultation.therapies || []);
98 setNewTherapies([]);
99 setFormData({
100 patientId: consultation.patientId,
101 date: consultation.date,
102 price: consultation.price,
103 advice: consultation.advice,
104 dateOfPayment: consultation.dateOfPayment,
105 });
106 setIsModalOpen(true);
107 };
108
109 const closeModal = () => {
110 setIsModalOpen(false);
111 setEditingConsultation(null);
112 };
113
114 const handleSubmit = async (e: Event) => {
115 e.preventDefault();
116
117 try {
118 const data = formData();
119 const therapiesToSend = newTherapies().map((t) => ({
120 name: t.name,
121 dose: t.dose,
122 expDate: t.expDate,
123 }));
124
125 if (editingConsultation()) {
126 const updateData: UpdateConsultationRequest = {
127 date: data.date,
128 price: data.price,
129 advice: data.advice,
130 dateOfPayment: data.dateOfPayment,
131 therapies: therapiesToSend,
132 };
133 await consultationApi.updateConsultation(
134 editingConsultation()!.idConsultation,
135 updateData,
136 );
137 } else {
138 const createData: CreateConsultationRequest = {
139 patientId: data.patientId,
140 date: data.date,
141 price: data.price,
142 advice: data.advice,
143 dateOfPayment: data.dateOfPayment,
144 therapies: therapiesToSend,
145 };
146 await consultationApi.createConsultation(createData);
147 }
148
149 refetch();
150 closeModal();
151 } catch (error: any) {
152 alert(error.message || "Failed to save consultation");
153 }
154 };
155
156 const handleDelete = async (consultationId: number) => {
157 if (!confirm("Are you sure you want to delete this consultation?")) return;
158
159 try {
160 await consultationApi.deleteConsultation(consultationId);
161 refetch();
162 } catch (error: any) {
163 alert(error.message || "Failed to delete consultation");
164 }
165 };
166
167 const togglePaymentStatus = async (consultation: Consultation) => {
168 try {
169 const updateData: UpdateConsultationRequest = {
170 dateOfPayment: isConsultationPaid(consultation)
171 ? null
172 : new Date().toISOString().split("T")[0],
173 };
174 await consultationApi.updateConsultation(
175 consultation.idConsultation,
176 updateData,
177 );
178 refetch();
179 } catch (error: any) {
180 alert(error.message || "Failed to update payment status");
181 }
182 };
183
184 return (
185 <div class="container mx-auto px-4 py-8 max-w-7xl">
186 <div class="mb-6 flex justify-between items-center">
187 <h1 class="text-3xl font-bold text-gray-900">
188 {isTherapist() ? "Consultation Records" : "My Consultations"}
189 </h1>
190 <Show when={isTherapist()}>
191 <button
192 onClick={openCreateModal}
193 class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition cursor-pointer"
194 >
195 Log New Consultation
196 </button>
197 </Show>
198 </div>
199
200 <Show
201 when={!consultations.loading}
202 fallback={<div class="text-center py-8">Loading consultations...</div>}
203 >
204 <Show
205 when={(consultations()?.length ?? 0) > 0}
206 fallback={
207 <div class="text-center py-8 text-gray-500">
208 No consultations logged yet. Click "Log New Consultation" to add
209 one.
210 </div>
211 }
212 >
213 <ConsultationTable
214 consultations={consultations()!}
215 onEdit={openEditModal}
216 onDelete={handleDelete}
217 onTogglePayment={togglePaymentStatus}
218 readOnly={isPatient()}
219 />
220 </Show>
221 </Show>
222
223 <Show when={isModalOpen()}>
224 <ConsultationModal
225 editingConsultation={editingConsultation()}
226 formData={formData()}
227 patients={patients() || []}
228 newTherapies={newTherapies()}
229 existingTherapies={existingTherapies()}
230 onClose={closeModal}
231 onSubmit={handleSubmit}
232 onFormChange={setFormData}
233 onNewTherapiesChange={setNewTherapies}
234 onExistingTherapiesChange={(therapies) => {
235 setExistingTherapies(therapies);
236 refetch();
237 }}
238 readOnly={isPatient()}
239 />
240 </Show>
241 </div>
242 );
243};
244
245export default Consultations;
Note: See TracBrowser for help on using the repository browser.