| 1 | import {
|
|---|
| 2 | type Component,
|
|---|
| 3 | createEffect,
|
|---|
| 4 | createResource,
|
|---|
| 5 | For,
|
|---|
| 6 | Show,
|
|---|
| 7 | } from "solid-js";
|
|---|
| 8 | import { useNavigate } from "@solidjs/router";
|
|---|
| 9 | import { useAuth } from "@/context/AuthContext";
|
|---|
| 10 | import { therapistApi } from "@/api/therapist";
|
|---|
| 11 | import { patientApi } from "@/api/patient";
|
|---|
| 12 | import TherapistCard from "@/components/TherapistCard";
|
|---|
| 13 | import { UserType } from "@/enums/UserType";
|
|---|
| 14 |
|
|---|
| 15 | const Therapists: Component = () => {
|
|---|
| 16 | const { user, isAuthenticated } = useAuth();
|
|---|
| 17 | const navigate = useNavigate();
|
|---|
| 18 |
|
|---|
| 19 | const [therapists] = createResource(
|
|---|
| 20 | isAuthenticated,
|
|---|
| 21 | async (authenticated) => {
|
|---|
| 22 | if (!authenticated) return [];
|
|---|
| 23 | const data = await therapistApi.getAllTherapists();
|
|---|
| 24 |
|
|---|
| 25 | return data.sort((a, b) => {
|
|---|
| 26 | const slotsA = a.freeConsultationSlots?.length || 0;
|
|---|
| 27 | const slotsB = b.freeConsultationSlots?.length || 0;
|
|---|
| 28 | return slotsB - slotsA;
|
|---|
| 29 | });
|
|---|
| 30 | },
|
|---|
| 31 | );
|
|---|
| 32 |
|
|---|
| 33 | const [currentTherapistId, { refetch: refetchCurrentTherapist }] =
|
|---|
| 34 | createResource(isAuthenticated, async (authenticated) => {
|
|---|
| 35 | if (!authenticated) return null;
|
|---|
| 36 | return await patientApi.getCurrentTherapist();
|
|---|
| 37 | });
|
|---|
| 38 |
|
|---|
| 39 | createEffect(() => {
|
|---|
| 40 | if (!isAuthenticated()) {
|
|---|
| 41 | navigate("/login", { replace: true });
|
|---|
| 42 | return;
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | const currentUser = user();
|
|---|
| 46 | if (currentUser?.userType !== UserType.PATIENT) {
|
|---|
| 47 | navigate("/", { replace: true });
|
|---|
| 48 | }
|
|---|
| 49 | });
|
|---|
| 50 |
|
|---|
| 51 | const handleTherapistChange = async () => await refetchCurrentTherapist();
|
|---|
| 52 |
|
|---|
| 53 | return (
|
|---|
| 54 | <div class="container mx-auto px-4 py-8">
|
|---|
| 55 | <div class="mb-8">
|
|---|
| 56 | <h1 class="text-3xl font-bold text-gray-900 mb-2">Find a Therapist</h1>
|
|---|
| 57 | <p class="text-gray-600">
|
|---|
| 58 | Browse our available therapists and their free consultation schedules
|
|---|
| 59 | </p>
|
|---|
| 60 | </div>
|
|---|
| 61 |
|
|---|
| 62 | <Show
|
|---|
| 63 | when={!therapists.loading && !currentTherapistId.loading}
|
|---|
| 64 | fallback={
|
|---|
| 65 | <div class="flex justify-center items-center py-12">
|
|---|
| 66 | <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600" />
|
|---|
| 67 | </div>
|
|---|
| 68 | }
|
|---|
| 69 | >
|
|---|
| 70 | <Show
|
|---|
| 71 | when={therapists() && therapists()!.length > 0}
|
|---|
| 72 | fallback={
|
|---|
| 73 | <div class="text-center py-12">
|
|---|
| 74 | <p class="text-gray-500 text-lg">No therapists available</p>
|
|---|
| 75 | </div>
|
|---|
| 76 | }
|
|---|
| 77 | >
|
|---|
| 78 | <div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|---|
| 79 | <For each={therapists()}>
|
|---|
| 80 | {(therapist) => (
|
|---|
| 81 | <TherapistCard
|
|---|
| 82 | therapist={therapist}
|
|---|
| 83 | isCurrentTherapist={currentTherapistId() === therapist.idUser}
|
|---|
| 84 | onTherapistChange={handleTherapistChange}
|
|---|
| 85 | />
|
|---|
| 86 | )}
|
|---|
| 87 | </For>
|
|---|
| 88 | </div>
|
|---|
| 89 | </Show>
|
|---|
| 90 | </Show>
|
|---|
| 91 | </div>
|
|---|
| 92 | );
|
|---|
| 93 | };
|
|---|
| 94 |
|
|---|
| 95 | export default Therapists;
|
|---|