jbwui — JBW360 Web Portal (React)
Module path:
st-integration/jbwui/· packagejbw-clientv0.1.0 · Create React App
Purpose
Section titled “Purpose”The web front-end for the JB Warranties ServiceTitan integration (“JB360”, hosted at jbw360.jbwarranties.com). It is an internal/partner portal — login only, no public signup. Two roles via Cognito groups:
jbw-admin— JB Warranties staff: dashboards, dealer onboarding, user management, admin tools.jbw-dealer— HVAC dealers/contractors: their own dashboard, agreement sync, claims.
Core flows: Cognito auth (incl. forced new-password, forgot/reset, idle timeout), a 4–5 step dealer onboarding wizard (ServiceTitan or Workiz), agreement sync/matching/approval against ServiceTitan data, claims management (with embedded JB&Associates iframes), and admin/dealer KPI dashboards.
Tech Stack
Section titled “Tech Stack”| Concern | Choice |
|---|---|
| Framework | React 18.3 (CRA / react-scripts 5), JavaScript (no TypeScript) |
| UI | MUI v5 + MUI X (DataGrid, Charts, DatePickers), Emotion, styled-components |
| State | React Context (src/AuthContext.jsx) + local state + localStorage; no Redux |
| Forms | Formik + Yup |
| Routing | react-router-dom v6 (createBrowserRouter in src/App.js), guard in src/RouteGuard.jsx |
| Auth | AWS Cognito via amazon-cognito-identity-js (src/services/jbwAuthServices.js) |
| HTTP | axios shared instance with interceptors (src/services/configs/axiosConfig.js) |
| Misc | crypto-js (AES), lodash, date-fns/dayjs/moment, export-from-json |
Routes
Section titled “Routes”Public (under RootLayout):
| Route | Page | Purpose |
|---|---|---|
/, /signin, /signin/:id | pages/SignIn.js | Cognito login; :id carries encrypted email+code for invited users. Post-login: admins → /home/overview, dealers → onboarding check → dashboard or wizard |
/signup | pages/Register.js | Dealer/user registration (verify-then-register) |
/forgotpassword | pages/VerifyUser.js | Initiate forgot-password |
/resetpassword/:id | pages/ResetPassword.js | Reset with code |
/changepassword/:id | pages/ChangePassword.js | Forced new-password challenge |
Authenticated (/home, HomeLayout = TopBar + Sidebar):
| Route | Page | Purpose |
|---|---|---|
/home, /home/overview | pages/Overview.js | Admin dashboard: KPI cards, latest onboardings, Admin Tools console |
/home/dealerdetails[/:id] | pages/DealerDetails.jsx | Dealer dashboard: info, KPIs, tenants, agreements/claims/invoices tabs |
/home/onboardinghome | pages/Onboarding.js | All dealers grid + “Onboard New Dealer” + per-dealer sync |
/home/agreementssynchome | pages/AgreementsSyncHome.jsx | Agreement sync: Map Location / Pending Approval / Approved tabs, Sync Data button |
/home/userslist | pages/UsersList.js | User management |
/home/transactionlog | pages/TransactionLogs.jsx | Transmission/sync logs (from tblTransmissionDetails) |
/home/jbwclaims | pages/JBWarrantiesFrame.jsx | Embedded JB&Associates claim360.aspx iframe |
/home/todohome[/:id] | pages/ToDoHome.jsx | Email-notification inbox (sidebar link currently commented out) |
/home/settings | — | Stub (route renders an MUI icon; pages/settings.js exists but is unused) |
/home/onboarding/* | pages/onboarding/ | Wizard: ClientName → ClientLocation → ClientPlatform → (ST: ClientCustom → ClientId) / (Workiz: ClientAccountId) → CLientConnect |
Auth & Session Behavior
Section titled “Auth & Session Behavior”- Cognito ID token (JWT) stored in
localStorage["token"]; role read fromcognito:groups[0](any group ≠jbw-dealeris treated as admin). - Axios request interceptor attaches
Authorization: Bearer <token>and drives a global loader viaapi-loadingevents. - Response interceptor: on 401, refreshes the Cognito session once (queueing concurrent requests) and retries; on failure fires
session-expired→ re-auth dialog. AuthContextproactively refreshes tokens when <5 min to expiry (60 s check loop) and enforces a 30-minute idle timeout (src/hooks/useIdleTimer.js).
Backend Integration
Section titled “Backend Integration”All API calls go through the shared axios instance with baseURL = REACT_APP_AWS_GATEWAY_BASE_URL (the jbw-sam API Gateway). Service modules live in src/services/ — the complete endpoint-per-module list is in the code reference.
External (non-gateway) integrations:
- ServiceTitan deep links:
REACT_APP_ST_URL; Workiz job links:REACT_APP_WZ_URL. - JB&Associates member portal iframes (hardcoded
jbandassociates.bizURLs): claims console (claim360.aspx), claim dialog (jb360claim.aspx, with postMessage origin check), agreement PDF (customeragpdf.aspx), payment link. - Release-notes PDF from
REACT_APP_RELEASE_NOTE_URL.
Quirk: several callers branch on APP_ENV === "Development" to read res.data.body vs res.data (API Gateway proxy wrapping differs between stages).
Environment Configuration
Section titled “Environment Configuration”CRA REACT_APP_* vars, baked into the bundle at build time. Files: .env (default = Production values), prod.env, stage.env; selected via env-cmd in npm scripts.
| Variable | Purpose |
|---|---|
REACT_APP_MYVARNAME | Env label (“Production”/“Staging”) — drives staging banner + dev response unwrapping |
REACT_APP_USER_POOL_ID / REACT_APP_CLIENT_ID | Cognito user pool / app client |
REACT_APP_AWS_GATEWAY_BASE_URL | Backend API Gateway base URL |
REACT_APP_ST_URL / REACT_APP_WZ_URL | ServiceTitan / Workiz deep-link bases |
REACT_APP_RELEASE_NOTE_URL / REACT_APP_RELEASE_NOTE_MONTH | Release-notes PDF + label |
REACT_APP_ISSTAGING | Staging flag (YES/NO) |
Prod points at go.servicetitan.com and the prod API Gateway stage; stage points at integration.servicetitan.com and the dev stage.
Run / Build / Deploy
Section titled “Run / Build / Deploy”npm installnpm start # dev server :3000, default .env (Production config!)npm run start:stage # staging config, :3006npm run build # production build (default .env)npm run build:prod # production bundle from prod.envnpm run build:stage # staging bundle from stage.envNote: npm scripts use Windows set PORT= syntax. There is no deploy config in the repo — the CRA build/ output is served from the S3 + CloudFront distribution defined in jbw-sam/template.yaml.
Caveats / Known Issues
Section titled “Caveats / Known Issues”.env,stage.env,prod.envare committed to the repo (contain Cognito pool/client IDs and gateway URLs; not strictly secret since CRA bakes them into the public bundle, but worth knowing).- Hardcoded AES key in
src/utils/encryption.js(used for the signin/reset URL payloads) — obfuscation only, not real encryption security. .envandprod.envare near-duplicates that drift (release-notes URL differs).- Default
npm startruns against production config. - No tests (
@testing-library/*present, no test files); README is CRA boilerplate. - Unused deps:
aws-amplify,react-google-recaptcha. Stub/home/settingsroute.
See Also
Section titled “See Also”- Code reference — jbwui (components & services)
- System overview