Next.js + React 19
App Router build with server components for data loading and client components for interactivity, keeping chat, dashboards, and onboarding fast and predictable.
Campus Communities — Full Stack
💠Ever struggled to find the group chat for your class or people to study with on campus?
Between scattered Discord links, Instagram chats, and last minute invites, it always felt harder than it should be to connect with classmates or organize study sessions. I ran into the same problem, so I built GryphChat, a campus-wide messaging platform where students can discover their class group chats, message peers, run polls, and plan study sessions all in one place.
🔗 gryphchat.com
Currently, this project is built specifically for students in the University of Guelph though if you would like to see an app like this for your university, feel free to connect with me!
From a technical standpoint, GryphChat is a full-stack web application built with production reliability in mind:
This project pushed me to think beyond features and focus on scalability, user experience, and real world deployment constraints while building something students would actually use.
We are currently testing GryphChat with 50+ active users, and I would love any feedback as we continue to iterate and improve the platform.
#FullStack #NextJS #React #OAuth #SoftwareEngineering #WebDevelopment #StudentBuilders
App Router build with server components for data loading and client components for interactivity, keeping chat, dashboards, and onboarding fast and predictable.
NextAuth with Prisma adapter + Postgres enables Google OAuth alongside bcrypt-backed credentials. Sessions use the database strategy to keep auth state durable across deployments.
Prisma runs on a pg pool via @prisma/adapter-pg with guards to avoid PgBouncer/poolers; connections must hit port
5432 directly for stability.
Tailwind CSS v4 lives in app/globals.css with custom CSS variables and a light/dark theme persisted in localStorage
(theme init in app/layout.tsx and app/providers.tsx).
Public landing page (app/page.tsx) introduces the product and embeds an AnonymousGlobalChat component for drop-in
conversation backed by a dedicated anonymous user and the global course helper.
app/auth/page.tsx offers Google or credentials tabs; credentials signup hashes passwords, and login accepts email or
username. app/onboarding/page.tsx lets newcomers claim a username via server action.
app/dashboard/page.tsx fetches memberships server-side to show recent classes. app/classes/page.tsx lists
all courses with member counts and search/filter/sort controls so students can join then redirect to chat.
app/chat/page.tsx gates access on session, auto-enrolls users into the global course, honors ?courseId=
for deep links, and renders a ChatExperience client with course filtering, membership pills, infinite scroll, and profile modals.
When Supabase keys exist, clients subscribe to messages-course-{id} channels for INSERT fan-out; otherwise they poll
every 3 seconds. Client-side sortMessages/mergeMessages normalize ordering so pagination and live events
co-exist cleanly.
The UI announces delivery mode (“Realtime connected” vs. “Live via polling”), exposes “Load older messages” when a cursor exists, and keeps compose + sender profile modals responsive during mode changes.
A seeded global-chat Course and helper auto-enroll new users so everyone can chat immediately, while the anonymous user
powers the public lobby.
/api/messages handles cursor pagination and auto-join on read/send, /api/courses/join supports join by id
or code, /api/profile validates majors/years + normalizes interests, and /api/public-global-chat runs the
anonymous lobby.
Prisma schema defines User (username, majorId, year, interests, optional passwordHash), Account/Session/VerificationToken, Course + ClassMembership join table, and Message indexed by course and creation timestamp.
scripts/maybe-run-migrations.js runs migrations pre-build if the DB is reachable. scripts/seed-courses.js
ingests full_course_offerings.json (~6.5MB) to populate thousands of Course rows with derived major/level data.
Env keys: DATABASE_URL (direct Postgres 5432), GOOGLE_CLIENT_ID/SECRET, NEXTAUTH_SECRET,
NEXTAUTH_URL, optional NEXT_PUBLIC_SUPABASE_URL/NEXT_PUBLIC_SUPABASE_ANON_KEY,
SKIP_PRISMA_MIGRATE, DB_CONNECT_TIMEOUT_MS, and PRISMA_INSECURE_TLS.
app/profile/page.tsx + ProfileForm let users edit name/major/year/interests with validation
(lib/profile.ts), calling /api/profile. Snapshot cards mirror current selections for quick verification.
AppLayout + TopNav provide active link highlighting, theme toggles, and sign-out flows while maintaining consistent rounded cards, gradients, and accessibility-focused focus states.
Built a dual-auth, course-aware chat product with realtime + graceful polling fallback, infinite scroll, membership auto-enrollment, seeded course catalog, and deployment-friendly migration guards.