Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BhushanBadhe39/SkinFirts/llms.txt

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

SkinFirts loads the full doctor roster from MockAPI when the app starts and stores it in Redux so every screen can access the same live data without additional network calls. From the Doctors screen, users can sort and filter the list in five ways, tap through to a detailed profile, and mark any doctor as a favourite — changes to favourites are persisted back to the server immediately via a PATCH request.

Loading doctors

Doctors are fetched once on startup inside SplashScreen, which dispatches the loadDoctors async thunk:
// src/redux/Slices/DoctorSlice.js
export const loadDoctors = createAsyncThunk(
  'doctors/load',
  async () => {
    const data = await fetchDoctors()
    return data
  }
)
fetchDoctors() sends a GET request to /doctorData and returns the array of doctor objects. On success, the thunk’s fulfilled handler stores the array in state.doctors.data. While the request is in flight, state.doctors.loading is true; on failure, state.doctors.error holds the error message.
// src/api/doctorsApi.js
export async function fetchDoctors() {
  const { data } = await apiClient.get('./doctorData')
  return data
}

Sort and filter options

The DoctorsScreen exposes five sort/filter tabs controlled by a pageIndex integer. The active tab is reflected in both the header title and the rendered list.
IndexTab labelBehaviour
0Doctors (A–Z)Sorts all doctors alphabetically by doctorName
1RatingSorts all doctors by ratings descending
2FavoriteFilters to doctors where isFavorite === true, with sub-tabs for Doctors and Services
3FemaleFilters to doctors where gender === "Female"
4MaleFilters to doctors where gender === "Male"
The pageList array that drives the header title is defined as:
// src/screens/doctors/DoctorsScreen.jsx
const pageList = ['Doctors', 'Rating', 'Favorite', 'Female', 'Male']
The transformation is applied inside a useMemo that re-runs whenever the doctor data or the active pageIndex changes:
// src/screens/doctors/DoctorsScreen.jsx
const sortedDoctors = useMemo(() => {
  let result = [...doctors]

  switch (pageIndex) {
    case 0:
      result = result.sort((a, b) => a.doctorName.localeCompare(b.doctorName))
      break
    case 1:
      result = result.sort((a, b) => b.ratings - a.ratings)
      break
    case 2:
      result = result.filter((a) => a.isFavorite === true)
      break
    case 3:
      result = result.filter((a) => a.gender === 'Female')
      break
    case 4:
      result = result.filter((a) => a.gender === 'Male')
      break
  }
  return result
}, [doctors, pageIndex])

Favorite sub-tabs

When pageIndex is 2, an additional pair of buttons — Doctors and Services — appears. The primaryState boolean switches between the FavoriteDoctors component (renders the filtered doctor list) and the FavouriteServices component.

Doctor card fields

Each card in the list displays a subset of the doctor data object. The full set of fields available on every doctor record is:

Identity

doctorName, department, img, gender

Stats

ratings, experience, reviews, availability

Profile content

focus, profile, careerPath, highlights

Interaction state

isFavorite

DoctorInfo screen

Tapping the Info button on any doctor card navigates to DoctorInfo, passing the doctor object as item and the current pageIndex as route params. The screen opens in Info mode and shows:
  • A profile card with the doctor’s photo, experience (years), focus area, doctorName, and department
  • Rating, review count, and availability displayed as icon-info pairs
  • A Schedule button that switches the screen to calendar mode (see Appointment booking)
  • Scrollable sections for Profile, Career Path, and Highlights
The sort bar is mirrored on this screen. Pressing a sort button calls navigation.replace('Doctors', { selectedSort: index }), taking the user back to the DoctorsScreen with the chosen sort active.

Favouriting a doctor

The heart icon on every doctor card dispatches the toggleFavorite async thunk. The thunk receives the full doctor object, uses doctor.id as the path parameter in the PATCH request, and flips isFavorite to its opposite value. The updated record is then merged into state.doctors.data in place.
// src/redux/Slices/DoctorSlice.js
export const toggleFavorite = createAsyncThunk(
  'doctors/toggleFavorite',
  async (doctor) => {
    const updated = await updateDoctors(doctor.id, { isFavorite: !doctor.isFavorite })
    return updated
  }
)
// src/api/doctorsApi.js
// Note: the parameter is named `email` in the source but is used as the doctor's
// record ID — it is passed as `doctor.id` from the toggleFavorite thunk.
export async function updateDoctors(email, updates) {
  const { data } = await apiClient.patch(`./doctorData/${email}`, updates)
  return data
}
On toggleFavorite.fulfilled, the slice finds the doctor by id and merges the server response into the existing record:
.addCase(toggleFavorite.fulfilled, (state, action) => {
  const updated = action.payload
  const index = state.data.findIndex(d => d.id === updated.id)
  if (index !== -1) {
    state.data[index] = { ...state.data[index], ...updated }
  }
})

useDoctors hook

A standalone useDoctors hook is available at src/hooks/useDoctors.js for components that need direct API access outside of Redux. It fetches the doctor list on mount and exposes an updateDoctorData helper that PATCHes a record by ID and updates local state.
// src/hooks/useDoctors.js
export function useDoctors() {
  const [doctorData, setDoctorData] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  useEffect(() => {
    let isMounted = true
    fetchDoctors()
      .then((data) => isMounted && setDoctorData(data))
      .catch((err) => isMounted && setError(err))
      .finally(() => isMounted && setLoading(false))
    return () => { isMounted = false }
  }, [])

  const updateDoctorData = async (id, updates) => {
    const updated = await updateDoctors(id, updates)
    setDoctorData(prev =>
      prev.map(d => d.id === id ? { ...d, ...updated } : d)
    )
    return updated
  }

  return { doctorData, loading, error, updateDoctorData }
}
The Appointment screen uses this hook to access doctor data for appointment list rendering.
The Home screen can navigate directly to a pre-selected sort tab on the Doctors screen by passing a selectedSort route param. For example, to jump straight to the Favorites view:
navigation.navigate('Doctors', { selectedSort: 2 })
DoctorsScreen initialises pageIndex from route.params?.selectedSort ?? 0 and also watches the param in a useEffect so that back-navigation with a new param updates the active tab correctly.

Build docs developers (and LLMs) love