# This is how I built Mugen Quiz, an April Fool's day project.

On the. day before April Fool's day, I got a silly idea for the April Fool's day project. It's similar to [Akinator](https://en.akinator.com/) except it only determines your favorite language, has only Yes and No, and never ends. I tried to do it simple way. Let's take a look at my project. The code is on [this repo.](https://github.com/pontakornth/mugen-quiz).

## Project structure


![Screen Shot 2565-04-02 at 21.32.09.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1648909946028/zFi_5py_N.png)

The project is so simple to the point that I don't even create a folder for components. The `page` directory is for the home page and quiz page. The `app.tsx` file contains logic for this project. The `data` directory contains questions for the quiz. 

I use CSS file for styling as there is no benefit using complicated system such as CSS Module or CSS-in-JS. Tailwind is a good alternative choice.


## Source of app.tsx

```typescript
import { Logo } from './logo'
import Router, { route, Route } from 'preact-router'
import { h } from 'preact'
import { useState } from 'preact/hooks'
import { Index } from './pages/index'
import { Quiz, QuizProps } from './pages/quiz'
import { questions } from './data/questions'

function getQuestion() {
  return questions[Math.floor(Math.random() * questions.length)]
}

export function App() {
  const [questionNumber, setQuestionNumber] = useState(1)
  const [started, setStarted] = useState(false)
  const [currentQuestion, setCurrentQuestion] = useState<string>(getQuestion())

  const handleNext = () => {
    setStarted(_ => true)
    setQuestionNumber(n => n + 1)
    setCurrentQuestion(oldQuestion => {
      let newQuestion: string
      do {
        newQuestion = getQuestion()
      } while (newQuestion == oldQuestion)
      return newQuestion
    })
    route(`/questions/${questionNumber}`)
  }
  return (
    <>
      <Router>
        <Route component={() => <Index onNext={handleNext} />} path="/" />
        <Route component={({ questionNumber }: Partial<QuizProps>) => <Quiz onNext={handleNext} questionNumber={questionNumber} currentQuestion={currentQuestion} started={started} />} path="/questions/:questionNumber" />
      </Router>
    </>
  )
}
```

Note that I use [preact-router](https://github.com/preactjs/preact-router). It render components inside base on the `path` prop. It's not quite friendly for TypeScript because I would need to define the component to accept `path` props or have global definitions similar to how `css` props work. I don't know how to do it yet.  Preact router provides `Route` component so I can use the router in TypeScript friendly way.


There is nothing interesting in `Index` page component. Let's take a look at `Quiz` page.

## Source code of quiz.tsx

```typescript
import { route } from "preact-router"
import { useEffect } from "preact/hooks"

export interface QuizProps {
	onNext: () => void,
	questionNumber: number | undefined,
	currentQuestion: string,
	started: boolean,
}

export function Quiz({ onNext, questionNumber, currentQuestion, started }: QuizProps) {
	useEffect(() => {
		if (!started) {
			// Go home. You haven't visit home yet.
			route("/", true)
		}
	}, [])
	return (
		<>
			<h1>Question {questionNumber}</h1>
			<p>{currentQuestion}</p>
			<button onClick={onNext}>Yes</button>
			<button onClick={onNext}>No</button>
		</>
	)
}
```

And that's the prank, no matter what you clicked, you only get another random question. Nothing is saved. Nothing is used to determine your favorite language.

This projected fooled my friends to think that the quiz will eventually end. I want this prank to be obvious so I put joke questions such as "What is your favorite TV show?" there.


## Conclusion

This is a simple project created in a simple way. There is no need for CSS-in-JS, state management or advanced build tools configuration although I used Vite to simplify development setup. It can even be simplified more such as don't use any JavaScript framework.  


I hope this post can be a example for anyone who have no idea what to build yet.  I am looking forward to see your projects.
