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.

AMS communicates with a remote backend through a thin, three-layer API stack: a shared Axios instance provides the base URL and default configuration; service modules wrap individual REST calls into named async functions; and Redux Thunks call those service functions and translate results (or errors) into store updates. This separation means switching from the current MockAPI backend to a production server requires changes in exactly one file.

Axios Instance

A single Axios instance is created in src/services/api.js and imported by every service module. Centralising the instance means the base URL and any future default configuration are managed in one place.
// src/services/api.js
import axios from "axios";

export default axios.create({
  baseURL: "https://6a61e9edda10c59c180a02b0.mockapi.io",
});
No authentication headers are attached to any request. The MockAPI endpoint is publicly accessible, so no Authorization header is required. See the production migration tip below for how to add auth headers.

Doctor Service

// src/services/doctorServices.js
import api from './api';

// GET /Doctors — returns the full list of doctor objects
export const fetchDoctorsAPI = async () => {
  const response = await api.get('/Doctors');
  return response.data;
};

// GET /Doctors/:id — returns a single doctor object
export const fetchDoctorByIdAPI = async (id) => {
  const response = await api.get(`/Doctors/${id}`);
  return response.data;
};

fetchDoctorsAPI()

Fetches the complete list of doctors. Called by the fetchDoctors thunk on the HomeScreen mount.

fetchDoctorByIdAPI(id)

Fetches a single doctor by ID. Available for detail lookups when only an ID is known.

Appointment Service

// src/services/appointmentApi.js
import API from './api';

// GET /Appointments — returns all appointment records
export const fetchAppointmentsFromApi = async () => {
  const response = await API.get('/Appointments');
  return response.data;
};

// POST /Appointments — creates a new appointment record
export const createAppointmentOnApi = async (appointmentData) => {
  const response = await API.post('/Appointments', appointmentData);
  return response.data;
};

// PUT /Appointments/:id — updates an existing appointment (e.g. set status to Cancelled)
export const updateAppointmentOnApi = async (appointment) => {
  const response = await API.put(`/Appointments/${appointment.id}`, appointment);
  return response.data;
};
FunctionMethodEndpointUsed by thunk
fetchAppointmentsFromApi()GET/AppointmentsfetchAppointments
createAppointmentOnApi(data)POST/AppointmentsaddAppointment
updateAppointmentOnApi(appt)PUT/Appointments/:idcancelAppointment

How Thunks Call Services

Redux thunks are the only callers of service functions. They handle the try/catch boundary and forward errors to Redux via rejectWithValue.
// src/redux/thunk/doctorThunk.js
import { createAsyncThunk } from '@reduxjs/toolkit';
import { fetchDoctorsAPI } from '../../services/doctorServices';

export const fetchDoctors = createAsyncThunk(
  'doctors/fetchDoctors',
  async (_, { rejectWithValue }) => {
    try {
      const data = await fetchDoctorsAPI();
      return data;
    } catch (error) {
      const errorMessage =
        error.response?.data || error.message || 'Failed to fetch doctors';
      return rejectWithValue(errorMessage);
    }
  }
);

Error Handling Pattern

Every thunk follows the same error handling convention:
} catch (error) {
  return rejectWithValue(error.response?.data || error.message);
}
1

Try the service call

The thunk awaits the service function. If it resolves, the data is returned and becomes action.payload in the fulfilled reducer.
2

Catch any exception

If the Axios call throws (network error, non-2xx status), the catch block runs.
3

Prefer structured API error

error.response?.data is checked first — this is the body of a non-2xx HTTP response, which may contain a structured error message from the backend.
4

Fall back to error.message

If there is no response body (e.g. a network timeout), the JavaScript Error.message string is used instead.
5

Store via rejectWithValue

The string is passed to rejectWithValue(), which causes the thunk to dispatch the rejected action with action.payload set to the error string. Slices read this from action.payload and store it in their error field.

Migrating to a Real Backend

To point AMS at a production API, change baseURL in src/services/api.js and add a request interceptor that attaches a JWT token from secure storage:
// src/services/api.js (production version)
import axios from 'axios';
import { getToken } from './secureStorage'; // your token store

const api = axios.create({
  baseURL: 'https://api.your-production-domain.com/v1',
});

api.interceptors.request.use(async (config) => {
  const token = await getToken();
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

export default api;
No changes are needed in the service modules or thunks — they all import the shared instance.

Build docs developers (and LLMs) love