How niamhramadhaan/jemima works
1. JEMIMA is a single-repo, locally hosted digital-signage app with three runtime pieces: a React/Vite TypeScript front end, a small Node/Express server for serving media files, and an optional Electron shell for kiosk/desktop deployment.
2. The main architecture boundary is between UI state and media assets. Business data such as screens, schedules, preferences, and theme selection live in browser localStorage via shared hooks/utilities, while actual media files live on disk in a project-root media folder and are streamed by the server.
3. The front end is route-based. App.tsx wires navigation and access flow, while main.tsx boots the app. Pages under src/pages represent the major product surfaces: dashboard, films/library, ingest, schedules, show builder, locations/screens, player views, settings, login, and onboarding/quick start.
4. The admin/control plane is centered on the Dashboard, Schedule, Films, Locations, and Settings pages. These screens let a user import files, assemble playback sequences, assign schedules to screens, inspect status, and change app-wide options without any backend API or database.
5. Playback is split into dedicated player surfaces: Player, ScreenPlayer, PlayerConfig, and related screen detail pages. This separation reflects the product model where the same app can act as both operator console and display player, with fullscreen/kiosk behavior emphasized for installed screens.
6. Scheduling is the core domain model. The ShowBuilder and Schedule pages create ordered sequences of media items, support time-based start behavior, loop vs one-shot modes, background audio, and conflict detection. The dashboard then consumes that schedule state to show now-playing, next-up, and completion status.
7. Media ingestion is filesystem-first rather than upload-based. FilmIngest reads local files from the content directory, supported media types are indexed into the library, and player views load those assets from the Node server rather than from a cloud store.
8. Shared UI is organized as a reusable shell plus feature components. Layout, Sidebar, Topbar, Pagination, LocationTimeline, LocationsMap, SetlistModal, and ErrorBoundary provide the app frame and operational widgets, while src/components/ui contains decorative theme-driven primitives like the highlighter and light rays.
9. Theme and configuration are treated as first-class app state. themes.ts, src/lib/theme.ts, and src/config/app.ts define the accent system and app constants, and the useLocalStorage hook plus storage.ts/data.ts helpers centralize persistence and retrieval of user preferences and domain records.
10. The Electron layer is a packaging boundary, not a separate product tier. electron/main.cjs and electron/preload.cjs wrap the same app for standalone kiosk use, embedding the Express server so a dedicated display machine can launch JEMIMA without running a separate browser and server setup.
11. Architecturally, there are no external cloud services, no database, and no real auth system. That keeps the system simple and local-first, but also means the repository’s state is intentionally per-device and best understood as a single-node signage controller with browser-based multi-screen views.
Main entry points: App.tsx App · storage.ts storage · server.cjs server.cjs · main.cjs electron main
Components 21
React app
Browser UI, route surfaces, shared state, and presentation components.
- main.tsx · React entrypoint that mounts the app.
src/main.tsx - App · Top-level navigation and access flow.
src/App.tsx - Layout · App frame and global layout wrapper.
src/components/Layout.tsx - Sidebar · Primary navigation for operator screens.
src/components/Sidebar.tsx - Topbar · Top-level status and actions bar.
src/components/Topbar.tsx - Dashboard · Now-playing, next-up, and status overview.
src/pages/Dashboard.tsx - Films · Media library and asset browsing.
src/pages/Films.tsx - Ingest · Imports local files into the library.
src/pages/FilmIngest.tsx - Schedule · Builds and manages timed playback sequences.
src/pages/Schedule.tsx - ShowBuilder · Constructs ordered shows and playback modes.
src/pages/ShowBuilder.tsx - Locations · Manages screens and deployment locations.
src/pages/Locations.tsx - Player · Dedicated playback surface for kiosk or display mode.
src/pages/Player.tsx - ScreenPlayer · Fullscreen screen-oriented playback surface.
src/pages/ScreenPlayer.tsx - ScreenDetail · Screen-specific detail and playback status.
src/pages/ScreenDetail.tsx - Settings · App-wide options and theme selection.
src/pages/Settings.tsx
Media server
Local Node server that serves on-disk media assets.
- server.cjs · Node/Express server that streams on-disk media.
server.cjs
Electron shell
Optional kiosk/desktop packaging around the same app.
- electron main · Electron main process for standalone kiosk packaging.
electron/main.cjs - preload · Electron preload bridge for the renderer.
electron/preload.cjs
Shared core
Persistence, theme, config, and domain helpers used across the app.
- storage · LocalStorage-backed persistence and retrieval helpers.
src/lib/storage.ts - theme · Theme and accent configuration helpers.
src/lib/theme.ts - app config · App-wide constants and configuration values.
src/config/app.ts
Connections 27
- main.tsx → App: mounts · Bootstraps the routed app.
- App → Layout: wraps · Uses the shared application shell.
- Layout → Sidebar: contains · Primary navigation lives in the shell.
- Layout → Topbar: contains · Shell header and actions.
- App → Dashboard: routes to · Main operator overview.
- App → Films: routes to · Media library surface.
- App → Ingest: routes to · Filesystem-based import flow.
- App → Schedule: routes to · Scheduling and playback planning.
- App → ShowBuilder: routes to · Show composition editor.
- App → Locations: routes to · Screen and location management.
- App → Player: routes to · Operator/player surface.
- App → ScreenPlayer: routes to · Fullscreen playback surface.
- App → ScreenDetail: routes to · Screen detail view.
- App → Settings: routes to · Preferences and theme settings.
- Dashboard → storage: reads state · Consumes local schedule and screen state.
- Schedule → storage: persists · Stores show and schedule records locally.
- ShowBuilder → storage: persists · Stores ordered show definitions locally.
- Films → storage: reads library · Loads indexed media records.
- Ingest → server.cjs: indexes assets · Relies on the local media server and disk content.
- Player → server.cjs: streams media · Loads playable files from the Node server.
- ScreenPlayer → server.cjs: streams media · Fullscreen playback reads served assets.
- Settings → theme: updates · Changes app accent and presentation state.
- Settings → app config: uses · Reads app constants and configuration.
- electron main → server.cjs: embeds · Packages the local server inside the desktop shell.
- electron main → preload: loads · Initializes renderer bridge.
- electron main → main.tsx: launches · Starts the same React app in kiosk/desktop mode.
- ScreenDetail → storage: reads state · Uses local screen and playback records.