# innocentemutabazi/user-directory architecture

> Architecture diagram of the GitHub repository innocentemutabazi/user-directory, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/innocentemutabazi/user-directory
- Repository: https://github.com/innocentemutabazi/user-directory

## Overview

Staff Directory is a React app for browsing, searching, sorting, and opening shareable user profiles. The main flow routes a visitor to the directory or a deep-linked profile; page hooks load and validate JSONPlaceholder data through a shared HTTP layer, while caches retain results across mounts. Search and sort are reflected in the URL, and the interface provides loading, error, empty, and theme states. The README documents these capabilities; some page, API, and layout implementations were not sampled, so their internal wiring is shown only where documented.

Main entry points: [`src/features/users/pages/UserListPage.tsx`](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserListPage.tsx) (Directory page), [`src/app/router.tsx`](https://github.com/innocentemutabazi/user-directory/blob/main/src/app/router.tsx) (Route table), [`src/features/users/pages/UserDetailPage.tsx`](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserDetailPage.tsx) (Profile page), [`src/features/users/api/usersApi.ts`](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/usersApi.ts) (User API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application shell"]
  node_mount["React entry<br/>[main.tsx]"]
  node_app_root["App root<br/>[App.tsx]"]
  node_router["Route table<br/>[router.tsx]"]
  node_layout["Root layout<br/>[RootLayout.tsx]"]
end

subgraph group_directory["Directory discovery"]
  node_list_page["Directory page<br/>[UserListPage.tsx]"]
  node_search["Search control<br/>[SearchBar.tsx]"]
  node_sort["Sort control<br/>[SortToggle.tsx]"]
  node_user_card["User card<br/>[UserCard.tsx]"]
  node_list_hook["List state<br/>[useUsers.ts]"]
  node_list_cache[("List cache<br/>[usersCache.ts]")]
end

subgraph group_profile["User profiles"]
  node_detail_page["Profile page<br/>[UserDetailPage.tsx]"]
  node_detail_hook["Profile state<br/>[useUser.ts]"]
  node_user_cache[("Profile cache<br/>[userCache.ts]")]
end

subgraph group_shared["Shared services"]
  node_api["User API<br/>[usersApi.ts]"]
  node_http["HTTP client<br/>[http.ts]"]
  node_theme["Theme toggle<br/>[ThemeToggle.tsx]"]
  node_empty_error["Request states<br/>[ErrorState.tsx]"]
end

node_visitor(("Visitor"))
node_api_service["JSONPlaceholder"]
node_url["Browser URL"]

node_visitor -->|"navigates"| node_router
node_mount -->|"mounts"| node_app_root
node_app_root -->|"provides routes"| node_router
node_router -->|"renders shell"| node_layout
node_router -->|"routes directory"| node_list_page
node_router -->|"routes profile"| node_detail_page
node_layout -->|"renders toggle"| node_theme
node_list_page -->|"loads list"| node_list_hook
node_list_page -->|"renders control"| node_search
node_list_page -->|"renders control"| node_sort
node_list_page -->|"renders results"| node_user_card
node_list_page -->|"mirrors search and sort"| node_url
node_url -->|"restores view state"| node_list_page
node_list_hook -->|"loads and revalidates"| node_list_cache
node_list_cache -->|"fetches users"| node_api
node_detail_page -->|"loads profile"| node_detail_hook
node_detail_page -->|"preserves return query"| node_url
node_detail_hook -->|"loads and revalidates"| node_user_cache
node_user_cache -->|"fetches user"| node_api
node_api -->|"requests JSON"| node_http
node_http -->|"fetches endpoint"| node_api_service
node_list_page -->|"renders request states"| node_empty_error
node_detail_page -->|"renders request errors"| node_empty_error

click node_mount "https://github.com/innocentemutabazi/user-directory/blob/main/src/main.tsx"
click node_app_root "https://github.com/innocentemutabazi/user-directory/blob/main/src/App.tsx"
click node_router "https://github.com/innocentemutabazi/user-directory/blob/main/src/app/router.tsx"
click node_layout "https://github.com/innocentemutabazi/user-directory/blob/main/src/app/RootLayout.tsx"
click node_list_page "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserListPage.tsx"
click node_search "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/SearchBar.tsx"
click node_sort "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/SortToggle.tsx"
click node_user_card "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/UserCard.tsx"
click node_list_hook "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/hooks/useUsers.ts"
click node_list_cache "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/usersCache.ts"
click node_detail_page "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserDetailPage.tsx"
click node_detail_hook "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/hooks/useUser.ts"
click node_user_cache "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/userCache.ts"
click node_api "https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/usersApi.ts"
click node_http "https://github.com/innocentemutabazi/user-directory/blob/main/src/lib/http.ts"
click node_theme "https://github.com/innocentemutabazi/user-directory/blob/main/src/components/ThemeToggle.tsx"
click node_empty_error "https://github.com/innocentemutabazi/user-directory/blob/main/src/components/ErrorState.tsx"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_mount,node_app_root,node_router,node_layout,node_url toneBlue
class node_list_page,node_search,node_sort,node_user_card,node_list_hook,node_list_cache toneAmber
class node_detail_page,node_detail_hook,node_user_cache toneMint
class node_api,node_http,node_theme,node_empty_error toneRose
class node_visitor,node_api_service toneIndigo
```

## Components

### Application shell

- [React entry](https://github.com/innocentemutabazi/user-directory/blob/main/src/main.tsx): `src/main.tsx`
- [App root](https://github.com/innocentemutabazi/user-directory/blob/main/src/App.tsx): `src/App.tsx`
- [Route table](https://github.com/innocentemutabazi/user-directory/blob/main/src/app/router.tsx): `src/app/router.tsx`
- [Root layout](https://github.com/innocentemutabazi/user-directory/blob/main/src/app/RootLayout.tsx): `src/app/RootLayout.tsx`

### Directory discovery

- [Directory page](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserListPage.tsx): `src/features/users/pages/UserListPage.tsx`
- [Search control](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/SearchBar.tsx): `src/features/users/components/SearchBar.tsx`
- [Sort control](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/SortToggle.tsx): `src/features/users/components/SortToggle.tsx`
- [User card](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/components/UserCard.tsx): `src/features/users/components/UserCard.tsx`
- [List state](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/hooks/useUsers.ts): `src/features/users/hooks/useUsers.ts`
- [List cache](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/usersCache.ts): `src/features/users/api/usersCache.ts`

### User profiles

- [Profile page](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/pages/UserDetailPage.tsx): `src/features/users/pages/UserDetailPage.tsx`
- [Profile state](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/hooks/useUser.ts): `src/features/users/hooks/useUser.ts`
- [Profile cache](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/userCache.ts): `src/features/users/api/userCache.ts`

### Shared services

- [User API](https://github.com/innocentemutabazi/user-directory/blob/main/src/features/users/api/usersApi.ts): `src/features/users/api/usersApi.ts`
- [HTTP client](https://github.com/innocentemutabazi/user-directory/blob/main/src/lib/http.ts): `src/lib/http.ts`
- [Theme toggle](https://github.com/innocentemutabazi/user-directory/blob/main/src/components/ThemeToggle.tsx): `src/components/ThemeToggle.tsx`
- [Request states](https://github.com/innocentemutabazi/user-directory/blob/main/src/components/ErrorState.tsx): `src/components/ErrorState.tsx`

### Other components

- **Visitor**
- **JSONPlaceholder**
- **Browser URL**

## Connections

- Visitor → Route table: navigates
- React entry → App root: mounts
- App root → Route table: provides routes
- Route table → Root layout: renders shell
- Route table → Directory page: routes directory
- Route table → Profile page: routes profile
- Root layout → Theme toggle: renders toggle
- Directory page → List state: loads list
- Directory page → Search control: renders control
- Directory page → Sort control: renders control
- Directory page → User card: renders results
- Directory page → Browser URL: mirrors search and sort
- Browser URL → Directory page: restores view state
- List state → List cache: loads and revalidates
- List cache → User API: fetches users
- Profile page → Profile state: loads profile
- Profile page → Browser URL: preserves return query
- Profile state → Profile cache: loads and revalidates
- Profile cache → User API: fetches user
- User API → HTTP client: requests JSON
- HTTP client → JSONPlaceholder: fetches endpoint
- Directory page → Request states: renders request states
- Profile page → Request states: renders request errors
