Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Jay-byte389/AMS/llms.txt

Use this file to discover all available pages before exploring further.

Appointment data in AMS is managed entirely through three async thunks defined in src/redux/thunk/appointmentThunk.js. Each thunk calls the corresponding function in src/services/appointmentApi.js, which wraps an Axios instance pointed at the REST backend. The appointmentSlice in src/redux/slices/appointmentSlice.js handles all lifecycle cases — pending, fulfilled, and rejected — updating state.list in place so the UI always reflects the latest server data.

Redux State Shape

FieldTypeDescription
listAppointment[]All appointments loaded from the API
loadingbooleantrue during any in-flight async operation
errorstring | nullLast error message from a failed operation

Thunks

fetchAppointments

Fetches all appointments from the backend and replaces the entire local list. This is the primary way to hydrate or refresh appointment data.
Action typeappointments/fetchAppointments
ParametersNone
API callGET /Appointments via fetchAppointmentsFromApi()
Returns (fulfilled)Appointment[] — the full array from response.data
Returns (rejected)rejectWithValue(error.response?.data | error.message)
State effects
Caseloadinglisterror
pendingtruenull
fulfilledfalsereplaced with API payload
rejectedfalseerror string
Because fetchAppointments replaces state.list on every call rather than merging, it is safe to dispatch it repeatedly — the list will always match what the server returns. Use useFocusEffect to trigger a refresh whenever a screen comes back into focus after a booking or cancellation.
import { useFocusEffect } from '@react-navigation/native';

useFocusEffect(
  React.useCallback(() => {
    dispatch(fetchAppointments());
  }, [])
);

addAppointment

Creates a new appointment on the server and appends the server response (with its assigned id) to the local list.
Action typeappointments/addAppointment
API callPOST /Appointments via createAppointmentOnApi(newAppointment)
Returns (fulfilled)The created Appointment object with a server-assigned id
Returns (rejected)rejectWithValue(error.response?.data | error.message)
newAppointment
object
required
The appointment payload to send to the server. The object typically includes the fields below, though the exact schema is determined by the backend.
doctorId
string
ID of the doctor being booked.
doctorName
string
Display name of the doctor (denormalized for quick rendering).
date
string
Appointment date in YYYY-MM-DD format.
time
string
Appointment time slot, e.g. "10:00 AM".
patientName
string
Name of the patient.
status
string
Initial status — typically "Upcoming" when first created.
State effects
Caseloadinglisterror
pendingtrue
fulfilledfalsenew appointment pushed
rejectedfalseerror string
import { useDispatch } from 'react-redux';
import { addAppointment } from '../redux/thunk/appointmentThunk';

const dispatch = useDispatch();

const handleBookAppointment = async () => {
  const appointmentData = {
    doctorId: selectedDoctor.id,
    doctorName: selectedDoctor.name,
    specialty: selectedDoctor.specialty,
    date: selectedDate,         // e.g. '2025-07-20'
    time: selectedTimeSlot,     // e.g. '10:00 AM'
    patientName: user.name,
    patientPhone: user.mobile,
    status: 'Upcoming',
  };

  const result = await dispatch(addAppointment(appointmentData));

  if (addAppointment.fulfilled.match(result)) {
    navigation.navigate('AppointmentConfirmation', {
      appointment: result.payload,
    });
  } else {
    Alert.alert('Booking failed', result.payload);
  }
};

cancelAppointment

Marks an existing appointment as 'Cancelled' by sending a PUT request to the server with the updated status, then replacing the matching entry in state.list in-place.
Action typeappointments/cancelAppointment
API callPUT /Appointments/:id via updateAppointmentOnApi({ ...appointment, status: 'Cancelled' })
Returns (fulfilled)The updated Appointment object returned by the server
Returns (rejected)rejectWithValue(error.response?.data | error.message)
appointment
object
required
The full existing appointment object from state.list. The thunk spreads it and overrides status: 'Cancelled' before sending the PUT request — all original fields (including id) are preserved.
State effects
Caseloadinglisterror
pendingtrue
fulfilledfalsematched item updated in-place
rejectedfalseerror string
The cancelAppointment.fulfilled reducer finds the appointment by id (state.list.findIndex(item => item.id === action.payload.id)) and replaces it with the server response. The appointment stays in the list with status: 'Cancelled' rather than being removed, so the user can see their full booking history.
import { useDispatch } from 'react-redux';
import { cancelAppointment } from '../redux/thunk/appointmentThunk';

const dispatch = useDispatch();

const handleCancel = (appointment) => {
  Alert.alert(
    'Cancel Appointment',
    'Are you sure you want to cancel this appointment?',
    [
      { text: 'No', style: 'cancel' },
      {
        text: 'Yes, Cancel',
        style: 'destructive',
        onPress: async () => {
          const result = await dispatch(cancelAppointment(appointment));

          if (cancelAppointment.rejected.match(result)) {
            Alert.alert('Error', result.payload);
          }
        },
      },
    ]
  );
};

Keeping Data Fresh with useFocusEffect

Because React Navigation does not unmount screens when you navigate away, a plain useEffect will only fire once. Use useFocusEffect to re-fetch appointments every time the screen comes into focus — for example, after the user books a new appointment and navigates back to the appointments list.
import React from 'react';
import { useDispatch } from 'react-redux';
import { useFocusEffect } from '@react-navigation/native';
import { fetchAppointments } from '../redux/thunk/appointmentThunk';

export default function AppointmentsScreen() {
  const dispatch = useDispatch();

  useFocusEffect(
    React.useCallback(() => {
      dispatch(fetchAppointments());
    }, [dispatch])
  );

  // ...
}
Wrap the callback in React.useCallback with [dispatch] as the dependency array to satisfy the react-hooks/exhaustive-deps lint rule and avoid creating a new function on every render.

Build docs developers (and LLMs) love