Team 401's operations hub for managing projects, assignments, certifications, attendance, manufacturing, inventory, and reporting. It is built as a static Next.js application and uses Firebase Authentication, Cloud Firestore, and Firebase Storage for its backend.
- Kanban boards for the full team and individual subteams
- Searchable drivetrain inventory for gears, pulleys, sprockets, and belts
- Certification-aware task assignment and self-assignment
- Task priorities, due dates, points of contact, comments, and file attachments
- Stuck-task reasons and prerequisite task relationships
- Calendar and embedded Gantt views for due dates and dependencies
- Student and coach certification management
- Metrics for task throughput, workload, and subteam activity
- Individual reports containing task history, certifications, and attendance hours
- CSV exports for team summaries, task history, and attendance
- Coach-managed timeclock with shop and outreach sessions
- Full-screen kiosk mode using automatically assigned 1–3 digit PINs
- Coach tools for signing out one person or everyone who forgot to clock out
- Coach roster administration, individual account creation, CSV batch imports, and prepared credential emails
- Live manufacturing queue for Onshape DXF, STEP, and lathe requests, including file downloads and completion tracking
| Role | Access |
|---|---|
| Coach | Manages all tasks, accounts, PINs, certifications, reports, metrics, and timeclock sessions. Coaches can also launch kiosk mode. |
| Student leader | Manages tasks and student certifications for their own subteam. Their reports are limited to their own information. |
| Student | Can view boards, join eligible tasks, update assigned tasks, add comments or attachments, and view their own certifications and report. |
The interface hides unavailable actions, but the actual authorization boundary is enforced by firestore.rules and storage.rules.
The authenticated /inventory page tracks quantities, bin locations, sourcing
details, and category-specific specifications. It includes the team's standard
20 DP gears, 3mm GT2 and 5mm HTD belts/pulleys, #25 and #35 sprockets, 9mm and
15mm widths, single/double-sided belts, and common robot bore standards.
Suggested specifications remain free-text entries, so newly acquired bore,
profile, width, and chain options automatically become searchable filter
choices without a schema change. Any signed-in team member can add hardware,
edit records, and adjust stock; only coaches can permanently delete records.
The authenticated /parts page reads the exports collection produced by
PChild/onshape-parts-export.
It displays the complete manufacturing packet, links back to the source Onshape
element, downloads DXF and STEP files from Cloud Storage, and records shop
completion separately from the exporter's file-generation status.
The exporter and this app use one Firebase project and Storage bucket. The
firestore.rules and storage.rules files in both repositories must therefore
stay identical: the merged rules protect exporter OAuth/session records while
allowing the dashboard's authenticated manufacturing workflow. Deploy both rule
files before using the page:
firebase deploy --only firestore:rules,storageCopy these merged rule files to the exporter repository too. Deploying an older copy from either repository will replace the project-wide rules for both apps.
- Next.js 16 with the App Router and static export
- React 19 and TypeScript
- Tailwind CSS 4
- Firebase Authentication, Cloud Firestore, and Firebase Storage
- dnd-kit for board interactions
- Recharts for metrics
- date-fns for scheduling and reports
npm installCreate a Firebase project and web app, then enable:
- Authentication with the Email/Password provider
- Cloud Firestore
- Firebase Storage
Create .env.local in the project root using the Firebase web configuration:
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.firebasestorage.app
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
NEXT_PUBLIC_FIREBASE_APP_ID=your-app-idThese values identify the Firebase web app and are safe to include in a client build. Firebase security rules, not secrecy of these values, protect application data.
Install and authenticate the Firebase CLI if needed, then select the correct Firebase project and deploy both rule files:
npx firebase-tools login
npx firebase-tools use --add
npx firebase-tools deploy --only firestore:rules,storageTask attachments are limited to 20 MB per file by the Storage rules.
There is deliberately no public account-registration page. The first coach must be bootstrapped from the Firebase console:
- In Authentication → Users, create an email/password user.
- Copy the new user's UID.
- In Firestore, create
users/{uid}with the following fields:
{
"uid": "the-authentication-uid",
"displayName": "Coach Name",
"email": "coach@example.com",
"role": "coach",
"subteam": null,
"certificationIds": [],
"createdAt": "2026-01-01T00:00:00.000Z",
"mustResetPassword": false
}After signing in, that coach can create the remaining accounts from Admin → Roster. New accounts receive a temporary password and an available timeclock PIN automatically.
npm run devOpen http://localhost:3000.
| Command | Purpose |
|---|---|
npm run dev |
Start the local development server |
npm run lint |
Run ESLint |
npm run build |
Type-check and generate the static site in out/ |
npm run start |
Start Next.js in server mode; the deployed app normally uses the static export instead |
The app currently uses these top-level collections:
users— profiles, roles, subteams, and certificationstasks— task details, assignment history, comments, attachments, and dependenciescertifications— coach-managed certification definitionsinventory— mechanical hardware specifications, locations, and live stock countssubteams— optional coach-managed subteam reference datatimeclockPins— coach-only kiosk PIN records kept separate from public profilestimeEntries— shop and outreach attendance sessions
Uploaded task files are stored under task-attachments/{taskId}/... in Firebase Storage.
Only a coach can launch the kiosk. Kiosk PINs identify which team member is clocking in or out; they are not Firebase passwords and cannot be used to sign into the main application.
The kiosk runs inside the authenticated coach session, so exiting kiosk mode requires the current coach's password. While kiosk mode is active, a root-level guard blocks other app routes and replaces Back/Forward navigation with the locked timeclock. A safe-sign-out option is also available and returns the device to the login screen. Firestore rules restrict all time-entry writes and PIN reads to coaches.
The project is configured for static export and includes .github/workflows/deploy.yml. Pushes to main build and deploy the out/ directory.
Add each NEXT_PUBLIC_FIREBASE_* value listed above as a GitHub Actions repository secret, then configure Settings → Pages to use GitHub Actions as the deployment source.
The GitHub Pages base path is derived from the repository name in next.config.ts:
const repoName = "ops";With the repository named ops, the project site is published at
https://team401.github.io/ops/ or at /ops/ beneath the team's configured
custom domain. Update this value if the repository is renamed again.
- Removing someone from the Admin roster deletes their Firestore profile but not their Firebase Authentication record. Delete the Authentication user from the Firebase console when access must be fully revoked.
- Changes to
firestore.rulesorstorage.rulesare not applied by the GitHub Pages deployment. Deploy Firebase rules separately. - Firebase Storage may require the Firebase project to use the Blaze plan, even when usage remains within no-cost quotas.
- Unknown routes redirect to the app home page, which then sends authenticated users to the board and signed-out users to login.