Gopher Queue
Gopher Queue is a smart office-hours website for students and TAs. Students can find upcoming office-hour sessions, run a quick AI intake check on their question, join a live queue, and track their place in line. TAs can create office-hour sessions, manage the queue in real time, group related questions, and build a common-issues board for repeated problems.
The app is designed for University of Minnesota-style course office hours, but the core flow works for any class where students need help and TAs need a calm, organized queue.
What the Website Does
The website has four main experiences:
- Home page: introduces Gopher Queue, shows a calendar of scheduled office hours, and links students into the right queue.
- Office Hours page: lists available sessions by class, location, format, TA, and estimated wait time.
- Student queue page: lets students preview the live queue, run an AI intake check, join with a question, optionally share a queue spot with classmates who have the same question, and leave the queue when needed.
- TA dashboard: lets TAs choose one of their sessions, see waiting/in-progress/completed students, start and finish help sessions, skip students, request AI hints, group similar questions, and manage a common-issues board.
Authentication is handled through Firebase Auth. During profile setup, users choose whether they are a Student or a Student and TA, then save the classes they take and, if applicable, the classes they TA. TA-only actions, like creating office hours, are gated by that role.
App Flow
Students
- Sign in or create an account.
- Add classes during profile setup.
- Find an office-hour session from the home calendar or the Office Hours page.
- Enter a question on the Student page.
- Run the AI intake check to get a short explanation, a next thing to inspect, and a recommendation about whether joining still makes sense.
- Join the queue and watch the live position update.
- Leave the queue once the question is resolved or no longer needed.
TAs
- Sign in with a profile that includes the TA role.
- Add the classes they TA during profile setup.
- Create a new office-hour session with class, date/time, and location.
- Open the TA dashboard and select one of their sessions.
- Move students through waiting, in-progress, skipped, and completed states.
- Use AI tools to get quick hints, group similar questions, and summarize common issues.
Core Features
- Firebase sign-in with email/password and Google authentication.
- Role-based profile setup for students and TAs.
- Class-aware office-hour creation and discovery.
- Live queue updates backed by Firestore subscriptions.
- One-active-queue protection so a student cannot accidentally join multiple sessions at once.
- Shared queue spots for students who have the same question.
- AI intake guidance before joining the queue.
- AI wait-time estimates on office-hour cards and queue pages.
- AI quick hints for TAs while helping students.
- Common-issues board for repeated questions during a session.
Tech Stack
- Framework: Next.js 16 App Router
- UI: React 19 and Tailwind CSS
- Auth: Firebase Authentication
- Database: Firebase Firestore
- AI: OpenAI API with built-in fallback responses for demo resilience
- State: React state plus Firebase realtime subscriptions
Project Structure
src/
app/
page.tsx Home page and office-hours calendar
office-hours/page.tsx Session discovery and class filtering
student/page.tsx Student queue experience
ta/page.tsx TA dashboard shell
ta/office-hours/new/page.tsx Create office-hour sessions
profile/page.tsx Account, role, and class settings
api/ AI and queue API routes
components/
AuthGate.tsx App-wide auth and profile setup gate
AuthButton.tsx Sign-in, account creation, and sign-out UI
StudentQueue.tsx Queue preview, join form, and student status
TADashboard.tsx TA queue controls and AI tools
UserMenu.tsx Account menu
hooks/
useAuth.ts Firebase auth and profile state
lib/
firebase.ts Firebase client setup
profileService.ts Profile persistence and validation
officeHourService.ts Office-hour CRUD and subscriptions
queueService.ts Queue CRUD, membership rules, and subscriptions
commonIssueService.ts Common-issues board persistence
aiService.ts Wait-time and AI helper logic
aiServer.ts Server-side OpenAI client helpers
store/
queueStore.ts Queue data types
Setup
1. Install Dependencies
npm install
2. Configure Firebase
Create a Firebase project, then enable:
- Firebase Authentication
- Email/password sign-in
- Google sign-in, if you want Google login
- Firestore Database
Create .env.local in the project root:
NEXT_PUBLIC_FIREBASE_API_KEY=your_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_domain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_bucket
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
Firestore rules need to allow signed-in users to read and write their own profile documents, and allow the app to read and update office-hour, queue, and common-issue records according to your deployment needs.
3. Configure OpenAI
AI features are optional but recommended for the full experience.
OPENAI_API_KEY=your_key
Keep this key server-only. Do not use a NEXT_PUBLIC_ prefix.
4. Run the Development Server
npm run dev
Open http://localhost:3000.
Data Model
The app stores these main Firestore record types:
Profiles
Profiles connect a Firebase Auth user to app-specific role and class data.
{
"uid": "firebase_user_id",
"displayName": "Student Name",
"email": "[email protected]",
"photoURL": "https://...",
"roles": ["student", "ta"],
"classes": ["CSCI 1133"],
"studentClasses": ["CSCI 1133"],
"taClasses": ["CSCI 1933"],
"createdAt": "server timestamp",
"updatedAt": "server timestamp"
}
Office Hours
Office-hour records describe sessions that students can browse and join.
{
"classCode": "CSCI 1133",
"courseTitle": "CSCI 1133",
"host": "TA Name",
"schedule": "Tuesday, Apr 14, 2026, 2:00 PM",
"location": "Keller Hall 1-250",
"format": "In person",
"startsAt": "2026-04-14T19:00:00.000Z",
"taUserId": "firebase_user_id",
"taEmail": "[email protected]"
}
Queue Students
Queue records represent the active help line for an office-hour session.
{
"name": "Student Name",
"question": "Why does my recursive function never stop?",
"timestamp": 1776193200000,
"status": "waiting",
"officeHourId": "office_hour_id",
"classCode": "CSCI 1133",
"courseTitle": "CSCI 1133",
"allowQuestionJoiners": true,
"joinedStudents": []
}
Common Issues
Common issues collect repeated questions so TAs can answer them once for a group.
{
"officeHourId": "office_hour_id",
"classCode": "CSCI 1133",
"question": "Why does my recursive function never stop?",
"normalizedQuestion": "why does my recursive function never stop?",
"answer": "Check the base case and make sure each call moves toward it.",
"provider": "openai",
"askCount": 5,
"addedBy": "ta"
}
Available Scripts
npm run dev # Start the local Next.js dev server
npm run build # Build the production app
npm run start # Run the production build
npm run lint # Run ESLint
Deployment
The app is ready for Vercel or any hosting provider that supports Next.js.
For Vercel:
npm install -g vercel
vercel
Add the Firebase and OpenAI environment variables in the Vercel project settings before deploying.
Troubleshooting
Firebase sign-in is unavailable
- Confirm every
NEXT_PUBLIC_FIREBASE_*value is set. - Make sure Firebase Authentication is enabled.
- Enable email/password or Google sign-in in the Firebase console.
Profiles or queues do not save
- Check Firestore is enabled.
- Review Firestore security rules.
- Check the browser console for permission errors.
AI responses are missing
- Confirm
OPENAI_API_KEYis set. - Make sure the key is server-only.
- Check API quota and rate limits.
- The app can still return fallback guidance when live AI is unavailable.
License
MIT