# patriciasegantine/redirect-lab-client architecture

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

- Interactive diagram: https://gitdiagram.com/patriciasegantine/redirect-lab-client
- Repository: https://github.com/patriciasegantine/redirect-lab-client

## Overview

Redirect Lab is a React client for managing short links. Users create or edit a link, manage the collection, copy/open short URLs, and export links; visitors can resolve a short URL and redirect to its destination. The README also documents access-count updates across tabs and theme switching. The sampled source confirms routing and API-service behavior; UI-to-hook wiring is represented at the feature level, while backend persistence and export delivery remain external.

Main entry points: [`src/services/api-client.ts`](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/api-client.ts) (HTTP client), [`src/App.tsx`](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/App.tsx) (Route table), [`src/services/links-service.ts`](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/links-service.ts) (Service facade), [`src/hooks/use-links.ts`](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/hooks/use-links.ts) (Link state hook)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application shell"]
  node_app_entry["App entry<br/>[main.tsx]"]
  node_app_routes["Route table<br/>[App.tsx]"]
end

subgraph group_features["Link workflows"]
  node_home["Home page<br/>[home.tsx]"]
  node_redirect_page["Redirect page<br/>[redirecting.tsx]"]
  node_not_found["Not found<br/>[not-found.tsx]"]
  node_create_ui["Create link<br/>[create-link.tsx]"]
  node_my_links["My links<br/>[my-links.tsx]"]
  node_links_list["Links list<br/>[links-list.tsx]"]
  node_edit_dialog["Edit dialog"]
  node_delete_dialog["Delete dialog"]
end

subgraph group_client["Client data layer"]
  node_link_schema["Link validation<br/>[create-link.ts]"]
  node_links_hook["Link state hook<br/>[use-links.ts]"]
  node_links_service["Service facade<br/>[links-service.ts]"]
  node_get_links["List links"]
  node_create_link["Create link API"]
  node_update_link["Update link API"]
  node_delete_link["Delete link API"]
  node_resolve_link["Resolve short URL"]
  node_export_csv["CSV export API"]
  node_api_client["HTTP client<br/>[api-client.ts]"]
  node_channel["Tab sync channel<br/>[links-channel.ts]"]
end

subgraph group_presentation["Shared presentation"]
  node_header["Header<br/>[header.tsx]"]
  node_layout["Page layout<br/>[layout.tsx]"]
  node_theme["Theme provider<br/>[theme-provider.tsx]"]
end

node_visitor(("Visitor"))
node_dashboard_user(("Dashboard user"))
node_api_server["Redirect Lab API"]

node_dashboard_user -->|"uses"| node_app_entry
node_app_entry -->|"renders"| node_app_routes
node_app_routes -->|"routes"| node_home
node_app_routes -->|"routes"| node_redirect_page
node_app_routes -->|"routes"| node_not_found
node_app_routes -->|"renders"| node_header
node_app_routes -->|"wraps"| node_layout
node_home -->|"presents"| node_create_ui
node_home -->|"presents"| node_my_links
node_my_links -->|"displays"| node_links_list
node_create_ui -->|"validates"| node_link_schema
node_create_ui -->|"submits"| node_links_hook
node_links_list -->|"manages"| node_links_hook
node_links_list -->|"opens"| node_edit_dialog
node_links_list -->|"opens"| node_delete_dialog
node_links_hook -->|"dispatches"| node_links_service
node_links_service -->|"delegates"| node_get_links
node_links_service -->|"delegates"| node_create_link
node_links_service -->|"delegates"| node_update_link
node_links_service -->|"delegates"| node_delete_link
node_links_service -->|"delegates"| node_export_csv
node_get_links -->|"requests"| node_api_client
node_create_link -->|"requests"| node_api_client
node_update_link -->|"requests"| node_api_client
node_delete_link -->|"requests"| node_api_client
node_resolve_link -->|"requests"| node_api_client
node_export_csv -->|"requests"| node_api_client
node_api_client -->|"calls"| node_api_server
node_visitor -->|"opens short URL"| node_redirect_page
node_redirect_page -->|"resolves"| node_resolve_link
node_redirect_page -->|"redirects"| node_visitor
node_channel -->|"notifies updates"| node_links_hook
node_links_hook -->|"broadcasts access"| node_channel
node_links_hook -.->|"refreshes counts"| node_api_server
node_app_entry -->|"provides theme"| node_theme

click node_app_entry "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/main.tsx"
click node_app_routes "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/App.tsx"
click node_home "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/home.tsx"
click node_redirect_page "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/redirecting.tsx"
click node_not_found "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/not-found.tsx"
click node_create_ui "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/create-link/create-link.tsx"
click node_my_links "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/my-links/my-links.tsx"
click node_links_list "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/links-list/links-list.tsx"
click node_edit_dialog "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/edit-link-dialog/edit-link-dialog.tsx"
click node_delete_dialog "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/delete-link-dialog/delete-link-dialog.tsx"
click node_link_schema "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/schema/create-link.ts"
click node_links_hook "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/hooks/use-links.ts"
click node_links_service "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/links-service.ts"
click node_get_links "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/get-links/get-links.service.ts"
click node_create_link "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/create-link/create-link.service.ts"
click node_update_link "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/update-link/update-link.service.ts"
click node_delete_link "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/delete-link/delete-link.service.ts"
click node_resolve_link "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/get-link-by-short-url/get-link-by-short-url.service.ts"
click node_export_csv "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/export-links-csv/export-links-csv.service.ts"
click node_api_client "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/api-client.ts"
click node_channel "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/lib/links-channel.ts"
click node_header "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/header/header.tsx"
click node_layout "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/layout.tsx"
click node_theme "https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/theme-provider.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_app_entry,node_app_routes,node_dashboard_user toneBlue
class node_home,node_redirect_page,node_not_found,node_create_ui,node_my_links,node_links_list,node_edit_dialog,node_delete_dialog toneAmber
class node_link_schema,node_links_hook,node_links_service,node_get_links,node_create_link,node_update_link,node_delete_link,node_resolve_link,node_export_csv,node_api_client,node_channel,node_api_server toneMint
class node_header,node_layout,node_theme toneRose
class node_visitor toneIndigo
```

## Components

### Application shell

- [App entry](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/main.tsx): `src/main.tsx`
- [Route table](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/App.tsx): `src/App.tsx`

### Link workflows

- [Home page](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/home.tsx): `src/components/pages/home.tsx`
- [Redirect page](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/redirecting.tsx): `src/components/pages/redirecting.tsx`
- [Not found](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/pages/not-found.tsx): `src/components/pages/not-found.tsx`
- [Create link](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/create-link/create-link.tsx): `src/components/layout/create-link/create-link.tsx`
- [My links](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/my-links/my-links.tsx): `src/components/layout/my-links/my-links.tsx`
- [Links list](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/links-list/links-list.tsx): `src/components/layout/links-list/links-list.tsx`
- [Edit dialog](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/edit-link-dialog/edit-link-dialog.tsx): `src/components/edit-link-dialog/edit-link-dialog.tsx`
- [Delete dialog](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/delete-link-dialog/delete-link-dialog.tsx): `src/components/delete-link-dialog/delete-link-dialog.tsx`

### Client data layer

- [Link validation](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/schema/create-link.ts): `src/schema/create-link.ts`
- [Link state hook](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/hooks/use-links.ts): `src/hooks/use-links.ts`
- [Service facade](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/links-service.ts): `src/services/links-service.ts`
- [List links](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/get-links/get-links.service.ts): `src/services/get-links/get-links.service.ts`
- [Create link API](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/create-link/create-link.service.ts): `src/services/create-link/create-link.service.ts`
- [Update link API](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/update-link/update-link.service.ts): `src/services/update-link/update-link.service.ts`
- [Delete link API](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/delete-link/delete-link.service.ts): `src/services/delete-link/delete-link.service.ts`
- [Resolve short URL](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/get-link-by-short-url/get-link-by-short-url.service.ts): `src/services/get-link-by-short-url/get-link-by-short-url.service.ts`
- [CSV export API](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/export-links-csv/export-links-csv.service.ts): `src/services/export-links-csv/export-links-csv.service.ts`
- [HTTP client](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/services/api-client.ts): `src/services/api-client.ts`
- [Tab sync channel](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/lib/links-channel.ts): `src/lib/links-channel.ts`

### Shared presentation

- [Header](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/header/header.tsx): `src/components/layout/header/header.tsx`
- [Page layout](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/layout/layout.tsx): `src/components/layout/layout.tsx`
- [Theme provider](https://github.com/patriciasegantine/redirect-lab-client/blob/main/src/components/theme-provider.tsx): `src/components/theme-provider.tsx`

### Other components

- **Visitor**
- **Dashboard user**
- **Redirect Lab API**

## Connections

- Dashboard user → App entry: uses
- App entry → Route table: renders
- Route table → Home page: routes
- Route table → Redirect page: routes
- Route table → Not found: routes
- Route table → Header: renders
- Route table → Page layout: wraps
- Home page → Create link: presents
- Home page → My links: presents
- My links → Links list: displays
- Create link → Link validation: validates
- Create link → Link state hook: submits
- Links list → Link state hook: manages
- Links list → Edit dialog: opens
- Links list → Delete dialog: opens
- Link state hook → Service facade: dispatches
- Service facade → List links: delegates
- Service facade → Create link API: delegates
- Service facade → Update link API: delegates
- Service facade → Delete link API: delegates
- Service facade → CSV export API: delegates
- List links → HTTP client: requests
- Create link API → HTTP client: requests
- Update link API → HTTP client: requests
- Delete link API → HTTP client: requests
- Resolve short URL → HTTP client: requests
- CSV export API → HTTP client: requests
- HTTP client → Redirect Lab API: calls
- Visitor → Redirect page: opens short URL
- Redirect page → Resolve short URL: resolves
- Redirect page → Visitor: redirects
- Tab sync channel → Link state hook: notifies updates
- Link state hook → Tab sync channel: broadcasts access
- Link state hook → Redirect Lab API: refreshes counts
- App entry → Theme provider: provides theme
