Skip to content

Challenge is to build out this quiz app and get it looking as close to the design as possible

License

Notifications You must be signed in to change notification settings

srijanss/frontend-quiz-app

Repository files navigation

Frontend Mentor - Frontend quiz app solution

This is a solution to the Frontend quiz app challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Users should be able to:

  • Select a quiz subject
  • Select a single answer from each question from a choice of four
  • See an error message when trying to submit an answer without making a selection
  • See if they have made a correct or incorrect choice when they submit an answer
  • Move on to the next question after seeing the question result
  • See a completed state with the score after the final question
  • Play again to choose another subject
  • View the optimal layout for the interface depending on their device's screen size
  • See hover and focus states for all interactive elements on the page
  • Navigate the entire app only using their keyboard
  • Change the app's theme between light and dark

Screenshot

Links

My process

Built with

  • Semantic HTML5 markup
  • CSS custom properties
  • Flexbox
  • CSS Grid
  • Mobile-first workflow
  • Vite - Lightweight frontend tooling
  • PostCSS - Tool to transform CSS using plugins

What I learned

Built this app using basic routing based on Regex filtering and history API based state management. Try to make routing work with SPA without using any libraries.

const routes = {
  "/": { component: CategoryPage, name: "home-page" },
  ":category/question/:id/": { component: QuestionPage, name: "question-page" },
  ":category/score/": { component: ScorePage, name: "score-page" },
};

function matchRoute(path) {
  const matchedRoute = routes["/"].component;
  for (const route in routes) {
    const re = new RegExp(`^${route.replace(/:\w+/g, "([^/]+)")}$`);
    path = path.length > 1 ? path.replace(/^\//, "") : path;
    if (!path.endsWith("/")) {
      path += "/";
    }
    const match = path.match(re);
    if (match) {
      matchedRoute.component = routes[route].component;
      const params = match.slice(1);
      if (params.length > 0) {
        matchedRoute.params = params;
      }
      return matchedRoute;
    }
  }
  return matchedRoute;
}
export function navigateTo(path, state) {
  const newPath = path.includes(store.baseURL) ? path : store.baseURL + path;
  window.history.pushState(state || {}, "", newPath);
  render();
}

export function navigateByReplace(path, state) {
  const newPath = path.includes(store.baseURL) ? path : store.baseURL + path;
  window.history.replaceState(state || {}, "", newPath);
  render();
}

export function replaceState(path, state) {
  const newPath = path.includes(store.baseURL) ? path : store.baseURL + path;
  window.history.replaceState(state || {}, "", newPath);
}

export function handleHistoryPopState() {
  window.onpopstate = render;
}

There were many challenges to build this multipage app using SPA, and without any routing libraries or fullstack framework. Like when you refresh a page on any URL except the root URL, then it will redirect back to root page.

Continued development

As a challenge I tried to develop this app without any framework. But in future I will try to build this again with Remix and SvelteKit. It will be fun task.

Useful resources

  • Web components - Custom State Set - Very helpful resource about CustomStateSet in web components.
  • History API - Very helpful to understand how history stack works. And how to maintain persistent data using history state.

Author

About

Challenge is to build out this quiz app and get it looking as close to the design as possible

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published