Skip to content

Commit fd39f7a

Browse files
Merge pull request #4 from radiantlab/FrontEnd
Created base React frontend and connected it to FastAPI backend
2 parents b9714ac + 1b29258 commit fd39f7a

21 files changed

Lines changed: 1769 additions & 9 deletions

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,8 @@ svc/.env
216216

217217
# API Docs
218218
docs/TintSpecifics.txt
219-
docs/TintSpecificAPIPages.pdf
219+
docs/TintSpecificAPIPages.pdf
220+
221+
# web node and build
222+
web/node_modules/
223+
web/dist/

DEV-SETUP.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
## What you need to install
3+
**Git** – Get it from [https://git-scm.com](https://git-scm.com)
4+
Check installation:
5+
git --version
6+
7+
8+
**Python 3.11 or newer** – Get it from [https://python.org](https://python.org)
9+
On Windows, check “Add Python to PATH”.
10+
Check installation:
11+
python --version
12+
13+
14+
**Node.js (LTS) and NPM** – Get it from [https://nodejs.org](https://nodejs.org)
15+
Check installation:
16+
node --version
17+
npm --version
18+
19+
---
20+
21+
## Repository setup
22+
Clone the repository and go inside
23+
cd GlazingControlApp
24+
25+
---
26+
27+
## Run the service
28+
Open a terminal in the `svc` folder:
29+
cd svc
30+
31+
32+
Create and activate a virtual environment:
33+
- **Windows PowerShell**
34+
python -m venv .venv
35+
..venv\Scripts\Activate.ps1
36+
37+
- **Windows CMD**
38+
.venv\Scripts\activate
39+
40+
- **Mac/Linux**
41+
python3 -m venv .venv
42+
source .venv/bin/activate
43+
44+
45+
Install packages:
46+
pip install --upgrade pip
47+
pip install -r requirements.txt
48+
49+
50+
Create your `.env` file from the example:
51+
- **Windows**
52+
copy .env.example .env
53+
54+
- **Mac/Linux**
55+
cp .env.example .env
56+
57+
58+
Start the server:
59+
python main.py
60+
61+
You should see Uvicorn running on port 8000.
62+
63+
Open the API docs in a browser: http://127.0.0.1:8000/docs
64+
65+
---
66+
67+
## Run the web app
68+
Open a new terminal in the `web` folder:
69+
cd web
70+
71+
72+
Install packages:
73+
npm install
74+
75+
76+
Start the dev server:
77+
npm run dev
78+
79+
80+
Open the link shown by Vite (usually http://127.0.0.1:5173).
81+
You should see the control interface.
82+
83+
Use the app:
84+
- The header shows service status
85+
- Pick a group, set a level, press **Set group**
86+
- Move a slider on any panel and press **Apply**
87+
- Press **Refresh** in the header to reload state

OVERVIEW.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# SETUP AND MAP
2+
3+
## Project overview
4+
Simple goal
5+
Control tint levels for 18 facade panels and 2 skylights in the OSU trailer
6+
FastAPI service in Python
7+
React web app in TypeScript
8+
Runs on your laptop today
9+
Swap to the real trailer later
10+
11+
---
12+
13+
## File map and what each file does
14+
15+
### Root
16+
* **README.md** – Top level summary and team list
17+
* **OVERVIEW.md** – General Overview of each file
18+
* **DEV-SETUP.md** – Instructions for development setup
19+
* **LICENSE** – License
20+
* **CONTRIBUTING.md** – Rules for branches, reviews, commits, and CI
21+
* **.gitignore** – Keeps build output, local env, and cache out of git
22+
* **.github/PULL_REQUEST_TEMPLATE.md** – Pull request checklist and sections
23+
* **.github/workflows/ci.yml** - CI that echoes a message on push and pull request
24+
* **docs/meeting_template.md** – Skeleton for meeting notes and action items
25+
* **docs/quick_start_draft.md** – Early draft for a researcher quick start
26+
27+
### Service folder (svc)
28+
* **svc/main.py** – Starts FastAPI, mounts routes, enables CORS for the web app on port 5173
29+
* **svc/requirements.txt** – Python packages used by the service
30+
* **svc/.env.example** – Sample settings to copy to .env
31+
* **svc/app/__init__.py** – Empty marker so Python treats app as a package
32+
* **svc/app/config.py** – Reads env settings, mode (sim or real), file paths for saved data and audit log
33+
* **svc/app/models.py** – Pydantic models for panels, groups, requests, and responses; snapshot and audit entry shapes
34+
* **svc/app/routes.py** – API endpoints for the web app (GET health, GET panels, GET groups, POST commands/set-level)
35+
* **svc/app/service.py** – Core logic layer; picks simulator in sim mode; enforces dwell time and writes audit
36+
* **svc/app/simulator.py** – In-memory simulator with disk persistence; updates panel levels and saves snapshot
37+
* **svc/app/state.py** – Load and save snapshot JSON; bootstrap default panels and groups; append one audit line per change
38+
* **svc/tests/test_basic.py** – Tests health listing, dwell, and group updates
39+
40+
### Web folder (web)
41+
* **web/index.html** – Root HTML for the React app
42+
* **web/package.json** – NPM scripts and dependencies
43+
* **web/tsconfig.json** – TypeScript config with React JSX and Vite types
44+
* **web/vite.config.ts** – Vite dev server config (port 5173)
45+
* **web/.env.development** – Points the web app to the service at http://127.0.0.1:8000
46+
* **web/src/env.d.ts** – Types for Vite env values
47+
* **web/src/main.tsx** – React entry and mount
48+
* **web/src/App.tsx** – Main page with status, group control, and panel grid
49+
* **web/src/api.ts** – Small client for health, panels, groups, and tint commands
50+
* **web/src/styles.css** – Theme layout for cards, sliders, chips, and header styling
51+
* **web/src/components/PanelGrid.tsx** – Cards for each panel with a slider, quick chips, and apply

svc/.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# service settings
2+
SVC_MODE=sim
3+
SVC_MIN_DWELL_SECONDS=20
4+
SVC_DATA_DIR=data
5+
6+
# real vendor adapter placeholders only used when SVC_MODE=real
7+
HALIO_API_URL=https://api.halio.com
8+
HALIO_SITE_ID=
9+
HALIO_API_KEY=

svc/main.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
from __future__ import annotations
22
import uvicorn
33
from fastapi import FastAPI
4+
from fastapi.middleware.cors import CORSMiddleware
45
from app.routes import router
56
from app.state import bootstrap_default_if_empty
67

78
def create_app() -> FastAPI:
8-
# ensure seed data exists for the simulator on first run
99
bootstrap_default_if_empty()
1010
app = FastAPI(title="ECG Control Service", version="0.1.0")
11+
12+
# CORS for local web dev
13+
app.add_middleware(
14+
CORSMiddleware,
15+
allow_origins=["http://localhost:5173", "http://127.0.0.1:5173"],
16+
allow_credentials=True,
17+
allow_methods=["*"],
18+
allow_headers=["*"],
19+
)
20+
1121
app.include_router(router)
1222
return app
1323

1424
app = create_app()
1525

1626
if __name__ == "__main__":
17-
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
27+
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

svc/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ uvicorn==0.32.1
33
pydantic==2.9.2
44
httpx==0.27.2
55
pytest==8.3.3
6-
requests==2.31.0
6+
python-dotenv==1.0.1
7+
requests==2.32.3

svc/svc/data/audit.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
11
{"ts": 1760726759.5898983, "actor": "api", "target_type": "panel", "target_id": "P01", "level": 50, "applied_to": ["P01"], "result": "panel updated"}
2+
{"ts": 1761606135.4254916, "actor": "api", "target_type": "panel", "target_id": "P01", "level": 50, "applied_to": ["P01"], "result": "panel updated"}
3+
{"ts": 1761606147.8508916, "actor": "api", "target_type": "panel", "target_id": "P01", "level": 55, "applied_to": [], "result": "dwell time not met"}
4+
{"ts": 1761606162.6037679, "actor": "api", "target_type": "panel", "target_id": "P02", "level": 55, "applied_to": ["P02"], "result": "panel updated"}
5+
{"ts": 1761606480.7200904, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 56, "applied_to": ["P08"], "result": "panel updated"}
6+
{"ts": 1761606522.6949575, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 31, "applied_to": ["P08"], "result": "panel updated"}
7+
{"ts": 1761606574.0336995, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 25, "applied_to": ["P08"], "result": "panel updated"}
8+
{"ts": 1761606581.7225833, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 50, "applied_to": [], "result": "dwell time not met"}
9+
{"ts": 1761606623.4984012, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 50, "applied_to": ["P08"], "result": "panel updated"}
10+
{"ts": 1761606623.993461, "actor": "api", "target_type": "panel", "target_id": "P08", "level": 50, "applied_to": [], "result": "dwell time not met"}

svc/svc/data/panels.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
"name": "Facade 1",
66
"group_id": "G-facade",
77
"level": 50,
8-
"last_change_ts": 1760726759.5898983
8+
"last_change_ts": 1761606135.4239554
99
},
1010
"P02": {
1111
"id": "P02",
1212
"name": "Facade 2",
1313
"group_id": "G-facade",
14-
"level": 0,
15-
"last_change_ts": 0.0
14+
"level": 55,
15+
"last_change_ts": 1761606162.6023843
1616
},
1717
"P03": {
1818
"id": "P03",
@@ -53,8 +53,8 @@
5353
"id": "P08",
5454
"name": "Facade 8",
5555
"group_id": "G-facade",
56-
"level": 0,
57-
"last_change_ts": 0.0
56+
"level": 50,
57+
"last_change_ts": 1761606623.4969633
5858
},
5959
"P09": {
6060
"id": "P09",

web/.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VITE_API_BASE=http://127.0.0.1:8000

web/README.md

Whitespace-only changes.

0 commit comments

Comments
 (0)