node 22.21+
The project follows a modern and modular architecture to facilitate maintainability and scalability.
src/
├── app/ # Global app configuration
│ ├── providers/ # All React providers
│ │ ├── ThemeProvider.tsx # Theme context
│ │ └── AuthProvider.tsx
│ ├── styles/
│ │ ├── globals.css # Global styles + Tailwind
│ │ └── themes.css # CSS variables for themes
│ └── App.tsx # Main entry point
│
├── features/ # Features by business domain
# Each feature has its own folder with components, hooks, types, and utils
│ ├── auth/
│ │ ├── components/ # Auth-specific components
│ │ ├── hooks/ # Auth business hooks
│ │ ├── types/ # TypeScript types
│ │ └── utils/ # Auth utilities
│ ├── dashboard/
│ └── users/
│
├── shared/ # Shared code between features
│ ├── components/ # Reusable components
│ │ ├── ui/ # Shadcn components
│ │ ├── layout/ # Header, Sidebar, Footer
│ │ └── common/ # Other shared components
│ ├── hooks/ # Reusable hooks
│ │ ├── useMediaQuery.ts
│ │ ├── useDebounce.ts
│ │ └── useLocalStorage.ts
│ ├── lib/ # External libs configuration
│ │ ├── api.ts # Configured Axios/Fetch
│ │ └── utils.ts # cn() and utilities
│ ├── queries/ # TanStack Query configurations
│ │ └── auth/ # Authentication queries
│ │ ├── auth.api.ts # Auth API functions
│ │ ├── auth.queries.ts # TanStack Query hooks
│ │ └── auth.types.ts # Auth query types
│ ├── types/ # Global types
│ │ └── common.types.ts
│ └── constants/ # Global constants
│ ├── routes.ts
│ └── api-endpoints.ts
│
├── routes/ # TanStack Router routes
│ ├── __root.tsx # Root layout
│ ├── index.tsx # Home page
│ ├── auth/
│ │ ├── login.tsx
│ │ └── register.tsx
│ └── dashboard/
│ └── index.tsx
│
├── assets/ # Static assets
│ ├── images/
│ └── icons/
│
├── main.tsx # Vite entry point
└── vite-env.d.ts
public/
├── locales/ # Translation files
│ ├── en.json # English translations
│ └── fr.json # French translations
└── vite.svg # Vite logo
- Separation by business domain: Each feature is isolated in its own folder with its components, hooks, and API logic
- Centralized shared code: Reusable elements are in
shared/to avoid duplication - Centralized configuration: All providers and global configuration are in
app/ - File-based routing: TanStack Router with an intuitive file structure
- Internationalization: Multi-language support with translation files organized by language
- Query layer: TanStack Query configurations organized by domain in
shared/queries/
Note: Some files and folders shown in the architecture tree do not exist yet. This structure is provided as a guide for the intended project organization.
This project uses Prettier to maintain consistent code formatting across the codebase.
The Prettier configuration is located in the .prettierrc file at the root of the project.
To automatically format your code on save:
- Install the Prettier - Code formatter extension in VS Code
- Set Prettier as your default formatter:
- Open VS Code Settings (Ctrl+, or Cmd+,)
- Search for "Default Formatter"
- Select Prettier - Code formatter from the dropdown
- Enable "Format On Save" in VS Code settings
You can manually format the entire codebase by running:
pnpm run formatThis command will format all TypeScript, JavaScript, JSON, and CSS files in the src/ directory according to the rules defined in .prettierrc.
Copy the .env.example file to .env and configure the following variables:
| Variable | Description | Example |
|---|---|---|
VITE_KEYCLOAK_CLIENT_ID |
Keycloak client ID | frontend |
VITE_KEYCLOAK_AUTHORITY |
Keycloak realm URL | http://localhost:8080/realms/myrealm |
VITE_USER_SERVICE_URL |
User service API URL | http://localhost:3000 |
VITE_COMMUNITY_SERVICE_URL |
Community service API URL | http://localhost:3003 |
VITE_REAL_TIME_URL |
Real-time service URL for WebRTC signaling | http://localhost:4000 |
VITE_WEBRTC_BASE=http://localhost:8080 |
Base URL for WebRTC media server | http://localhost:8080 |
-
Copy the environment file:
cp .env.example .env
-
Install dependencies:
pnpm install
-
Start the development server:
pnpm dev
The client will be available at http://localhost:5173.
To build and run the Beep client application using Docker, follow these steps:
-
Build the Docker Image Open a terminal in the root directory of the project (where the
Dockerfileis located) and run the following command to build the Docker image:docker build -t beep-client . -
Run the Docker Container After the image is built, you can run a container using the following command:
docker run -d --rm -p 8080:8080 beep-client
Use the following command to add components in order to import it with the right file naming convention:
pnpm add-component <component-name>- A minimal WebRTC provider and UI component were added to mirror the provided HTML example.
- Navigate to /webrtc to try it.
- Signaling uses a Phoenix channel for the initial offer/answer and leave events, while in-call negotiation still uses the WebRTC DataChannel (offer/answer messages over the RTC data channel), just like the original HTML snippet.
Signaling details:
- Topic:
voice-channel:<session_id> - Events:
offerrequest payload:{ session_id, endpoint_id, offer_sdp }→ ok reply:{ answer_sdp }leaverequest payload:{ session_id, endpoint_id }
Configuration:
- Set
VITE_REAL_TIME_URLto your backend HTTP base (e.g.,http://localhost:4000). The client derives the Phoenix socket URL asws(s)://.../socket.
Files:
- src/app/providers/WebRTCProvider.tsx: Context/provider encapsulating the WebRTC logic (join, leave, startCam, startMic) with Phoenix channel signaling for initial connection and RTC DataChannel for subsequent negotiation.
- src/app/providers/RealTimeSocketProvider.tsx: Provides a Phoenix socket and helpers to join/leave topics.
- src/features/webrtc/components/WebRTCDemo.tsx: Simple UI using the provider.
- src/routes/webrtc.tsx: Route exposing the demo page and wiring RealTimeSocketProvider + WebRTCProvider.
This README will be completed with additional sections as development progresses.