# grenxnja/meetopia architecture

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

- Interactive diagram: https://gitdiagram.com/grenxnja/meetopia
- Repository: https://github.com/grenxnja/meetopia

## Overview

Meetopia is a browser-based video meeting app using Stream for calls and a locally persisted guest identity. A guest gets an identity, the app initializes Stream, and users can create or join meetings; meeting pages look up the call, enforce invited-call membership, then move through setup into the meeting room. Separate views expose upcoming, previous, and recorded calls. The README also describes Clerk security, but the sampled implementation shows guest identity instead; unsampled internals and that discrepancy limit confidence about authentication wiring.

Main entry points: [`components/CallList.tsx`](https://github.com/grenxnja/meetopia/blob/main/components/CallList.tsx) (Call and recording lists), [`providers/GuestProvider.tsx`](https://github.com/grenxnja/meetopia/blob/main/providers/GuestProvider.tsx) (Guest identity), [`app/(root)/meeting/[id]/page.tsx`](https://github.com/grenxnja/meetopia/blob/main/app/(root)/meeting/%5Bid%5D/page.tsx) (Meeting route), [`hooks/useGetCalls.ts`](https://github.com/grenxnja/meetopia/blob/main/hooks/useGetCalls.ts) (Call query and sorting)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_identity["Identity and clients"]
  node_guest["Guest identity<br/>[GuestProvider.tsx]"]
  node_guest_store["Guest persistence<br/>[guest.ts]"]
  node_guest_prompt["Name prompt<br/>[GuestNameModal.tsx]"]
  node_stream_client["Stream client"]
  node_token_action["Token action<br/>[stream.actions.ts]"]
end

subgraph group_meetings["Meeting lifecycle"]
  node_home_actions["Meeting actions"]
  node_meeting_route["Meeting route<br/>[page.tsx]"]
  node_call_lookup["Call lookup<br/>[useGetCallById.ts]"]
  node_meeting_setup["Pre-call setup<br/>[MeetingSetup.tsx]"]
  node_meeting_room["Live meeting room<br/>[MeetingRoom.tsx]"]
  node_end_call["End call control<br/>[EndCallButton.tsx]"]
  node_personal_page["Personal room page<br/>[page.tsx]"]
end

subgraph group_history["Meeting discovery"]
  node_call_query["Call query and sorting<br/>[useGetCalls.ts]"]
  node_call_list["Call and recording lists<br/>[CallList.tsx]"]
  node_meeting_card["Meeting card<br/>[MeetingCard.tsx]"]
  node_upcoming_page["Upcoming page<br/>[page.tsx]"]
  node_previous_page["Previous page<br/>[page.tsx]"]
  node_recordings_page["Recordings page<br/>[page.tsx]"]
end

subgraph group_shell["Navigation and interface"]
  node_home_page["Home page<br/>[page.tsx]"]
  node_home_hero["Home overview<br/>[HomeHero.tsx]"]
  node_sidebar["Sidebar navigation<br/>[Sidebar.tsx]"]
  node_home_layout["Home layout<br/>[layout.tsx]"]
end

node_stream["Stream Video"]
node_guest_user(("Guest user"))

node_guest_user -->|"provides identity"| node_guest
node_guest -->|"reads and persists"| node_guest_store
node_guest -->|"prompts for name"| node_guest_prompt
node_stream_client -->|"uses identity"| node_guest
node_stream_client -->|"requests token"| node_token_action
node_stream_client -->|"initializes client"| node_stream
node_home_page -->|"renders"| node_home_hero
node_home_page -->|"renders"| node_home_actions
node_home_actions -->|"creates calls"| node_stream
node_home_actions -->|"navigates to"| node_meeting_route
node_meeting_route -->|"loads call"| node_call_lookup
node_call_lookup -->|"queries calls"| node_stream
node_meeting_route -->|"renders setup"| node_meeting_setup
node_meeting_route -->|"renders room"| node_meeting_room
node_meeting_room -->|"renders control"| node_end_call
node_call_query -->|"filters by identity"| node_guest
node_call_query -->|"queries calls"| node_stream
node_call_list -->|"loads call data"| node_call_query
node_call_list -->|"queries recordings"| node_stream
node_call_list -->|"renders entries"| node_meeting_card
node_upcoming_page -->|"renders upcoming"| node_call_list
node_previous_page -->|"renders previous"| node_call_list
node_recordings_page -->|"renders recordings"| node_call_list
node_home_layout -->|"renders navigation"| node_sidebar
node_sidebar -->|"loads call counts"| node_call_query
node_personal_page -->|"loads personal call"| node_call_lookup

click node_guest "https://github.com/grenxnja/meetopia/blob/main/providers/GuestProvider.tsx"
click node_guest_store "https://github.com/grenxnja/meetopia/blob/main/lib/guest.ts"
click node_guest_prompt "https://github.com/grenxnja/meetopia/blob/main/components/GuestNameModal.tsx"
click node_stream_client "https://github.com/grenxnja/meetopia/blob/main/providers/StreamClientProvider.tsx"
click node_token_action "https://github.com/grenxnja/meetopia/blob/main/actions/stream.actions.ts"
click node_home_actions "https://github.com/grenxnja/meetopia/blob/main/components/MeetingTypeList.tsx"
click node_meeting_route "https://github.com/grenxnja/meetopia/blob/main/app/(root)/meeting/%5Bid%5D/page.tsx"
click node_call_lookup "https://github.com/grenxnja/meetopia/blob/main/hooks/useGetCallById.ts"
click node_meeting_setup "https://github.com/grenxnja/meetopia/blob/main/components/MeetingSetup.tsx"
click node_meeting_room "https://github.com/grenxnja/meetopia/blob/main/components/MeetingRoom.tsx"
click node_end_call "https://github.com/grenxnja/meetopia/blob/main/components/EndCallButton.tsx"
click node_call_query "https://github.com/grenxnja/meetopia/blob/main/hooks/useGetCalls.ts"
click node_call_list "https://github.com/grenxnja/meetopia/blob/main/components/CallList.tsx"
click node_meeting_card "https://github.com/grenxnja/meetopia/blob/main/components/MeetingCard.tsx"
click node_home_page "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/page.tsx"
click node_home_hero "https://github.com/grenxnja/meetopia/blob/main/components/HomeHero.tsx"
click node_sidebar "https://github.com/grenxnja/meetopia/blob/main/components/Sidebar.tsx"
click node_home_layout "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/layout.tsx"
click node_upcoming_page "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/upcoming/page.tsx"
click node_previous_page "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/previous/page.tsx"
click node_recordings_page "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/recordings/page.tsx"
click node_personal_page "https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/personal-room/page.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_guest,node_guest_store,node_guest_prompt,node_stream_client,node_token_action,node_guest_user toneBlue
class node_home_actions,node_meeting_route,node_call_lookup,node_meeting_setup,node_meeting_room,node_end_call,node_personal_page toneAmber
class node_call_query,node_call_list,node_meeting_card,node_upcoming_page,node_previous_page,node_recordings_page toneMint
class node_home_page,node_home_hero,node_sidebar,node_home_layout toneRose
class node_stream toneIndigo
```

## Components

### Identity and clients

- [Guest identity](https://github.com/grenxnja/meetopia/blob/main/providers/GuestProvider.tsx): `providers/GuestProvider.tsx`
- [Guest persistence](https://github.com/grenxnja/meetopia/blob/main/lib/guest.ts): `lib/guest.ts`
- [Name prompt](https://github.com/grenxnja/meetopia/blob/main/components/GuestNameModal.tsx): `components/GuestNameModal.tsx`
- [Stream client](https://github.com/grenxnja/meetopia/blob/main/providers/StreamClientProvider.tsx): `providers/StreamClientProvider.tsx`
- [Token action](https://github.com/grenxnja/meetopia/blob/main/actions/stream.actions.ts): `actions/stream.actions.ts`

### Meeting lifecycle

- [Meeting actions](https://github.com/grenxnja/meetopia/blob/main/components/MeetingTypeList.tsx): `components/MeetingTypeList.tsx`
- [Meeting route](https://github.com/grenxnja/meetopia/blob/main/app/(root)/meeting/%5Bid%5D/page.tsx): `app/(root)/meeting/[id]/page.tsx`
- [Call lookup](https://github.com/grenxnja/meetopia/blob/main/hooks/useGetCallById.ts): `hooks/useGetCallById.ts`
- [Pre-call setup](https://github.com/grenxnja/meetopia/blob/main/components/MeetingSetup.tsx): `components/MeetingSetup.tsx`
- [Live meeting room](https://github.com/grenxnja/meetopia/blob/main/components/MeetingRoom.tsx): `components/MeetingRoom.tsx`
- [End call control](https://github.com/grenxnja/meetopia/blob/main/components/EndCallButton.tsx): `components/EndCallButton.tsx`
- [Personal room page](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/personal-room/page.tsx): `app/(root)/(home)/personal-room/page.tsx`

### Meeting discovery

- [Call query and sorting](https://github.com/grenxnja/meetopia/blob/main/hooks/useGetCalls.ts): `hooks/useGetCalls.ts`
- [Call and recording lists](https://github.com/grenxnja/meetopia/blob/main/components/CallList.tsx): `components/CallList.tsx`
- [Meeting card](https://github.com/grenxnja/meetopia/blob/main/components/MeetingCard.tsx): `components/MeetingCard.tsx`
- [Upcoming page](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/upcoming/page.tsx): `app/(root)/(home)/upcoming/page.tsx`
- [Previous page](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/previous/page.tsx): `app/(root)/(home)/previous/page.tsx`
- [Recordings page](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/recordings/page.tsx): `app/(root)/(home)/recordings/page.tsx`

### Navigation and interface

- [Home page](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/page.tsx): `app/(root)/(home)/page.tsx`
- [Home overview](https://github.com/grenxnja/meetopia/blob/main/components/HomeHero.tsx): `components/HomeHero.tsx`
- [Sidebar navigation](https://github.com/grenxnja/meetopia/blob/main/components/Sidebar.tsx): `components/Sidebar.tsx`
- [Home layout](https://github.com/grenxnja/meetopia/blob/main/app/(root)/(home)/layout.tsx): `app/(root)/(home)/layout.tsx`

### Other components

- **Stream Video**
- **Guest user**

## Connections

- Guest user → Guest identity: provides identity (evidence: `providers/GuestProvider.tsx`)
- Guest identity → Guest persistence: reads and persists (evidence: `providers/GuestProvider.tsx`)
- Guest identity → Name prompt: prompts for name (evidence: `providers/GuestProvider.tsx`)
- Stream client → Guest identity: uses identity (evidence: `providers/StreamClientProvider.tsx`)
- Stream client → Token action: requests token (evidence: `providers/StreamClientProvider.tsx`)
- Stream client → Stream Video: initializes client (evidence: `providers/StreamClientProvider.tsx`)
- Home page → Home overview: renders (evidence: `app/(root)/(home)/page.tsx`)
- Home page → Meeting actions: renders (evidence: `app/(root)/(home)/page.tsx`)
- Meeting actions → Stream Video: creates calls (evidence: `components/MeetingTypeList.tsx`)
- Meeting actions → Meeting route: navigates to (evidence: `components/MeetingTypeList.tsx`)
- Meeting route → Call lookup: loads call (evidence: `app/(root)/meeting/[id]/page.tsx`)
- Call lookup → Stream Video: queries calls (evidence: `hooks/useGetCallById.ts`)
- Meeting route → Pre-call setup: renders setup (evidence: `app/(root)/meeting/[id]/page.tsx`)
- Meeting route → Live meeting room: renders room (evidence: `app/(root)/meeting/[id]/page.tsx`)
- Live meeting room → End call control: renders control (evidence: `components/MeetingRoom.tsx`)
- Call query and sorting → Guest identity: filters by identity (evidence: `hooks/useGetCalls.ts`)
- Call query and sorting → Stream Video: queries calls (evidence: `hooks/useGetCalls.ts`)
- Call and recording lists → Call query and sorting: loads call data (evidence: `components/CallList.tsx`)
- Call and recording lists → Stream Video: queries recordings (evidence: `components/CallList.tsx`)
- Call and recording lists → Meeting card: renders entries (evidence: `components/CallList.tsx`)
- Upcoming page → Call and recording lists: renders upcoming (evidence: `app/(root)/(home)/upcoming/page.tsx`)
- Previous page → Call and recording lists: renders previous (evidence: `app/(root)/(home)/previous/page.tsx`)
- Recordings page → Call and recording lists: renders recordings (evidence: `app/(root)/(home)/recordings/page.tsx`)
- Home layout → Sidebar navigation: renders navigation (evidence: `app/(root)/(home)/layout.tsx`)
- Sidebar navigation → Call query and sorting: loads call counts (evidence: `components/Sidebar.tsx`)
- Personal room page → Call lookup: loads personal call (evidence: `app/(root)/(home)/personal-room/page.tsx`)
