Skip to content

Ryasmaston/Quizr

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

295 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Quiz.app logo

📝✨ Quiz.app – Team Creative


👋✨ Hi there, welcome to our project!

📚✨ Project Overview

Quiz.app is a full-stack platform for creating and taking quizzes, built using the MERN stack (MongoDB, Express, React + Vite, Node.js) with Firebase authentication and file storage. We created this application in just 10 days during the Makers Academy remote Software Engineering bootcamp in January 2026, working in a simulated software engineering team using Agile practices.

We worked individually and as a team with morning stand-ups, daily Slack communication, and end-of-day retros. We focused on collaboration, clear communication, and learning good software engineering practices and patterns.

We dealt with real engineering challenges like version control conflicts, debugging, testing, and delivering features under time pressure, while prioritising what mattered most (“keeping the most important things the most important things”).

🧠✨ Our Team of 5 Contributors

🧢✨ Our Coach

☁️✨ Deployment

The project is deployed on Reder under www.quizr.fun

🤝✨ How We Worked as a Team

🛠️✨ Tech Stack

🔹 Frontend

JavaScript HTML5 TailwindCSS Vite React

🔹 Backend

Node.js Express MongoDB Mongoose Firebase

🔹 Tools · Collaboration · Debugging · Data / API

Git GitHub Visual Studio Code Postman Chrome DevTools
Jest Miro Trello draw.io

📌✨ Features

Current core features include:

✅ Implemented Features

  • Authentication: Firebase sign up / log in / log out
  • Authorisation: protected routes + auth-aware navbar redirects
  • Navigation: global navbar across the app
  • Home: landing layout with a Create Quiz entry point
  • Create Quiz: create a quiz title, add questions, add answer options, set the correct answer, save using the latest quiz schema
  • Quiz Discovery: view public quizzes on user profile pages (Quizzes section)
  • Take Quiz: dynamic question pages, back/next navigation, answers saved during the flow, submit attempt as one payload
  • Scoring: server-side scoring + attempt saved per user
  • Profiles: username display, own-profile edit button, quizzes taken, favourites/saved quizzes (where enabled)
  • Leaderboards: per-quiz Top N leaderboard + your best score
  • Friends: friend requests with status (pending/accepted) + friendship metadata (requestedBy, createdAt, acceptedAt)
  • Friends Access: view quizzes within your friend network (where enabled)
  • Seed Data: natural seed users/quizzes + Firebase user seeding (where required)
  • UI: responsive Tailwind CSS styling across core pages (Home, Auth, Profile, Quizzes)
  • Profile linking: link to user profiles from Friends and Quizzes views
  • Leaderboards: friends-only leaderboard view
  • Deployment: deploy the database
  • Multi-answer questions: allow multiple correct answers + allow users to select more than one answer
  • Difficulty insights: difficulty ratings + average completion rate
  • Profile stats: show common quiz topics + average difficulty for created quizzes

🌱 Still in Development – paused due to project deadline

  • Media: Firebase image upload + user profile picture
  • Quiz generation: LLM-assisted quiz creation (auto-generate quizzes)
  • Mistake follow-up: missed questions show a short explanation and/or a mini-quiz later
  • Adaptive difficulty: questions adjust based on performance
  • Randomisation: randomise question order during quiz creation/delivery
  • Streaks: quiz completion streaks

🧩✨ Architecture

This repo contains two applications:

  • api/Node + Express backend (secured with Firebase Admin)
  • frontend/React + Vite SPA, styled with Tailwind CSS

They communicate via HTTP:

  • The frontend reads the API base URL from VITE_BACKEND_URL
  • All API requests go through a custom apiFetch(path, options) helper
  • apiFetch attaches the current Firebase ID token as Authorization: Bearer <token>
  • The backend verifies this token with Firebase Admin and uses req.user for identity
  • Application data is stored in MongoDB (via Mongoose)

🏆✨ Our Achievements

Teamwork & delivery flow:

  • We communicated clearly about tasks, progress and blockers ✅
  • Took shared ownership and stayed focused on shipping a complete, working product ✅
  • Supported each other from start to finish ✅

Minimum Viable Product delivered on time:

  • We shipped a working MVP within the project timeline ✅
  • With the core features implemented and stable ✅
  • Stable enough for real users to use end-to-end. ✅

Functionality & UI leveled up:

  • We iterated on both functionality and design ✅
  • Refining layouts, improving usability ✅
  • Making the interface more consistent and user-friendly over time✅

🐞✨ Our Challenges

Bugs & debugging - we improved by:

  • Discussing issues as a team before making changes ✅
  • Logging bugs in Trello board to make sure nothing was missed ✅
  • Screen sharing on Zoom and testing before merging ✅

Git & merge conflicts - we improved by:

  • Creating smaller pull requests ✅
  • Merging to main more often ✅
  • Communicating before touching the same files ✅

Time management - we improved by:

  • Balancing learning new tech vs. actually shipping features ✅
  • Had to drop/scale back some ideas to hit the deadline ✅
  • Taking regular breaks for gym, run, walk in the park etc ✅

🏁✨ Getting Started

  • Set-up instructions were provided as a starting template for us to use
  • We created our own seed project (the base version of the app) and extended it throughout development

🔑✨ Authentication

Our backend is locked by default. Firebase Auth proves who the user is (email, uid), and Express verifies that token once globally. If you’re not authenticated, nothing gets through.

Frontend

Rules
  • Never call fetch() directly for our API
  • Always use: apiFetch(path, options) from src/services/api.js
  • Auth is handled automatically by apiFetch

Import Firebase directly only on auth pages (done) and file storage features For everything else, use this:

import { apiFetch } from "../services/api";

And then:

const res = await apiFetch("/quizzes");

Example src/services/quizzes.js file:

import { apiFetch } from "./api";

export async function getQuizzes() {
  const res = await apiFetch("/quizzes");
  if (!res.ok) throw new Error("Failed to load quizzes");
  return res.json();
}

export async function createQuiz(data) {
  const res = await apiFetch("/quizzes", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
  });
  return res.json();
}

No auth tokens passed, all of that is already handles by the api helper.

Backend

Rules
  • Auth is global by default, because app.use(requireAuth) is in api/app.js
  • In controllers, the user identity is always req.user.uid
  • Never accept userId from the client
In controllers, always use req.user

Example:

function createQuiz(req, res) {
  const ownerUid = req.user.uid;
}

Never do:

req.body.userId
req.params.userId

The user identity always comes from Firebase, never the client.

Mount the router normally

In api/app.js, for example /quizzes route:

app.use("/quizzes", quizzesRouter);

No auth logic here. It’s already enforced globally.

Files that make up the auth layer

Frontend
  • src/services/firebase.js - Firebase client init (auth + storage)
  • src/services/authentication.js - login/signup (Firebase Auth only)
  • src/services/api.js - centralized authenticated fetch
  • pages/Login/* - login UI + redirect logic
  • pages/Signup/* - signup UI + redirect logic
  • pages/Home/* - auth-guarded page (example)
Backend
  • api/middleware/requireAuth.js - verifies Firebase ID token
  • api/lib/firebaseAdmin.js - Firebase Admin init
  • api/app.js - global auth gate
  • api/routes/* - normal routers (no auth logic inside)
  • api/controllers/* - always use req.user.uid

Extra explainer

Internally, apiFetch retrieves the Firebase ID token from the current session and sends it as an Authorization: Bearer <token> header. The backend verifies this token once per request.

About

Full-stack quiz based application built in the MERN stack, integrating firebase authentication and file storage. Users can create, publish, and take interactive quizzes through a clean, user-focused interface. Features secure user authentication, real-time scoring and scalable data handling

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 97.5%
  • CSS 2.3%
  • HTML 0.2%