# e1n7/stage-timer architecture

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

- Interactive diagram: https://gitdiagram.com/e1n7/stage-timer
- Repository: https://github.com/e1n7/stage-timer

## Overview

Stage Timer is a browser-based live-event timer. The main workflow is configuring timer sequences and messages in the dashboard, operating timers, then showing synchronized timer and message output on a second screen. Rooms organize and transfer configurations; browser storage preserves state, and browser messaging synchronizes tabs. The README documents scheduling, follow-active navigation, overtime, and PWA support; some of those implementations are in unsampled portions of the dashboard, so their internal wiring is not inferred.

Main entry points: [`src/components/TimerOutput.tsx`](https://github.com/e1n7/stage-timer/blob/main/src/components/TimerOutput.tsx) (Timer Display), [`src/App.tsx`](https://github.com/e1n7/stage-timer/blob/main/src/App.tsx) (Dashboard UI), [`src/hooks/useTimer.ts`](https://github.com/e1n7/stage-timer/blob/main/src/hooks/useTimer.ts) (Timer State), [`src/lib/storage.ts`](https://github.com/e1n7/stage-timer/blob/main/src/lib/storage.ts) (JSON Storage)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_dashboard["Dashboard Controls"]
  node_dashboard_route["Dashboard Route<br/>[page.tsx]"]
  node_app["Dashboard UI<br/>[App.tsx]"]
end

subgraph group_timing["Timer Runtime"]
  node_timer_hook["Timer State<br/>[useTimer.ts]"]
  node_time_lib["Time Utilities<br/>[time.ts]"]
end

subgraph group_output["Stage Output"]
  node_output_route["Output Route<br/>[page.tsx]"]
  node_timer_output["Timer Display<br/>[TimerOutput.tsx]"]
  node_progress["Progress Bar<br/>[ProgressBar.tsx]"]
  node_message_stage["Message Stage<br/>[MessageStage.tsx]"]
  node_pwa_manifest["PWA Metadata<br/>[manifest.json]"]
end

subgraph group_persistence["Browser Data"]
  node_room_storage["Room Merge<br/>[roomStorage.ts]"]
  node_storage_lib["JSON Storage<br/>[storage.ts]"]
  node_local_storage_hook["Local Settings<br/>[useLocalStorage.ts]"]
  node_browser_store[("Local Storage")]
  node_channel["Tab Messaging<br/>[sharedChannel.ts]"]
end

node_operator(("Operator"))

node_operator -->|"opens dashboard"| node_dashboard_route
node_dashboard_route -->|"renders"| node_app
node_app -->|"controls timers"| node_timer_hook
node_timer_hook -->|"gets time"| node_time_lib
node_app -->|"merges rooms"| node_room_storage
node_app -->|"reads settings"| node_storage_lib
node_timer_hook -->|"persists state"| node_storage_lib
node_local_storage_hook -->|"reads and writes"| node_browser_store
node_storage_lib -->|"reads and writes"| node_browser_store
node_timer_hook -->|"broadcasts state"| node_channel
node_timer_output -->|"subscribes and replies"| node_channel
node_operator -->|"opens output"| node_output_route
node_output_route -->|"renders"| node_timer_output
node_timer_output -->|"reads saved state"| node_storage_lib
node_timer_output -->|"renders progress"| node_progress
node_timer_output -->|"renders messages"| node_message_stage

click node_dashboard_route "https://github.com/e1n7/stage-timer/blob/main/app/page.tsx"
click node_app "https://github.com/e1n7/stage-timer/blob/main/src/App.tsx"
click node_timer_hook "https://github.com/e1n7/stage-timer/blob/main/src/hooks/useTimer.ts"
click node_time_lib "https://github.com/e1n7/stage-timer/blob/main/src/lib/time.ts"
click node_room_storage "https://github.com/e1n7/stage-timer/blob/main/src/lib/roomStorage.ts"
click node_storage_lib "https://github.com/e1n7/stage-timer/blob/main/src/lib/storage.ts"
click node_local_storage_hook "https://github.com/e1n7/stage-timer/blob/main/src/hooks/useLocalStorage.ts"
click node_channel "https://github.com/e1n7/stage-timer/blob/main/src/lib/sharedChannel.ts"
click node_output_route "https://github.com/e1n7/stage-timer/blob/main/app/output/page.tsx"
click node_timer_output "https://github.com/e1n7/stage-timer/blob/main/src/components/TimerOutput.tsx"
click node_progress "https://github.com/e1n7/stage-timer/blob/main/src/components/ProgressBar.tsx"
click node_message_stage "https://github.com/e1n7/stage-timer/blob/main/src/components/MessageStage.tsx"
click node_pwa_manifest "https://github.com/e1n7/stage-timer/blob/main/public/manifest.json"

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_dashboard_route,node_app toneBlue
class node_timer_hook,node_time_lib toneAmber
class node_output_route,node_timer_output,node_progress,node_message_stage,node_pwa_manifest toneMint
class node_room_storage,node_storage_lib,node_local_storage_hook,node_browser_store,node_channel toneRose
class node_operator toneIndigo
```

## Components

### Dashboard Controls

- [Dashboard Route](https://github.com/e1n7/stage-timer/blob/main/app/page.tsx): `app/page.tsx`
- [Dashboard UI](https://github.com/e1n7/stage-timer/blob/main/src/App.tsx): `src/App.tsx`

### Timer Runtime

- [Timer State](https://github.com/e1n7/stage-timer/blob/main/src/hooks/useTimer.ts): `src/hooks/useTimer.ts`
- [Time Utilities](https://github.com/e1n7/stage-timer/blob/main/src/lib/time.ts): `src/lib/time.ts`

### Stage Output

- [Output Route](https://github.com/e1n7/stage-timer/blob/main/app/output/page.tsx): `app/output/page.tsx`
- [Timer Display](https://github.com/e1n7/stage-timer/blob/main/src/components/TimerOutput.tsx): `src/components/TimerOutput.tsx`
- [Progress Bar](https://github.com/e1n7/stage-timer/blob/main/src/components/ProgressBar.tsx): `src/components/ProgressBar.tsx`
- [Message Stage](https://github.com/e1n7/stage-timer/blob/main/src/components/MessageStage.tsx): `src/components/MessageStage.tsx`
- [PWA Metadata](https://github.com/e1n7/stage-timer/blob/main/public/manifest.json): `public/manifest.json`

### Browser Data

- [Room Merge](https://github.com/e1n7/stage-timer/blob/main/src/lib/roomStorage.ts): `src/lib/roomStorage.ts`
- [JSON Storage](https://github.com/e1n7/stage-timer/blob/main/src/lib/storage.ts): `src/lib/storage.ts`
- [Local Settings](https://github.com/e1n7/stage-timer/blob/main/src/hooks/useLocalStorage.ts): `src/hooks/useLocalStorage.ts`
- **Local Storage**
- [Tab Messaging](https://github.com/e1n7/stage-timer/blob/main/src/lib/sharedChannel.ts): `src/lib/sharedChannel.ts`

### Other components

- **Operator**

## Connections

- Operator → Dashboard Route: opens dashboard
- Dashboard Route → Dashboard UI: renders
- Dashboard UI → Timer State: controls timers
- Timer State → Time Utilities: gets time
- Dashboard UI → Room Merge: merges rooms
- Dashboard UI → JSON Storage: reads settings
- Timer State → JSON Storage: persists state
- Local Settings → Local Storage: reads and writes
- JSON Storage → Local Storage: reads and writes
- Timer State → Tab Messaging: broadcasts state
- Timer Display → Tab Messaging: subscribes and replies
- Operator → Output Route: opens output
- Output Route → Timer Display: renders
- Timer Display → JSON Storage: reads saved state
- Timer Display → Progress Bar: renders progress
- Timer Display → Message Stage: renders messages
