Jeopardy

by David Kyle

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.1/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"></script>
<nav class="navbar is-transparent semi-transparent">
  <div class="navbar-brand">
    <a class="navbar-item" href="/">
      <img src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Jeopardy%21_logo.png" width="112" height="28">
    </a>
    <div class="navbar-burger burger" data-target="navbarExampleTransparentExample">
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>

  <div id="navbarExampleTransparentExample" class="navbar-menu">
    <div class="navbar-start">
      <a class="navbar-item" href="https://bulma.io/">
        Home
      </a>
      <div class="navbar-item has-dropdown is-hoverable">
        <a class="navbar-link" href="https://bulma.io/documentation/overview/start/">
          Admin
        </a>
        <div class="navbar-dropdown is-boxed">
          <a class="navbar-item" href="https://bulma.io/documentation/overview/start/">
            Overview
          </a>
          <a class="navbar-item" href="https://bulma.io/documentation/overview/modifiers/">
            Modifiers
          </a>
          <a class="navbar-item" href="https://bulma.io/documentation/columns/basics/">
            Columns
          </a>
          <a class="navbar-item" href="https://bulma.io/documentation/layout/container/">
            Layout
          </a>
          <a class="navbar-item" href="https://bulma.io/documentation/form/general/">
            Form
          </a>
          <hr class="navbar-divider">
          <a class="navbar-item" href="https://bulma.io/documentation/elements/box/">
            Elements
          </a>
  ...

SCSS

$background-image-url: 'https://desktopography.net/wp-content/uploads/bfi_thumb/desktopography-34k1rgj544nq6ngmk7e3gg.jpg';

body {
  background: url($background-image-url) no-repeat fixed;
  font-family: Verdana, Arials, sans-serif;
  font-size: small;
  padding: 0px;
  margin: 0px;
  height: 100vh;
}

.semi-transparent {
  background-color: #efefef77;
  color: black;
}

footer.footer {
  padding-top: 1rem;
  padding-bottom: 1rem;
  font-weight: bold;
}

.body-text {
    color: #efefef55;
}

.board > .columns,
.board > .columns > .column-header {
  background-color: #efefef99;
}

.answer {
  cursor: pointer;
}

JavaScript

function strict() {
  'use strict';
  let container = (function() {
    let self = {};
    let $ = {};
    let events = {};
    let instance = {
      tempName: '',
      model: {},
      speech: {},
      voices: []
    };

    let toggleModal = function($target) {
      const hasClass = $target.hasClass('is-active');
      if (hasClass) {
        $target.fadeOut(300).removeClass('is-active');
      } else {
        $target.fadeIn(300).addClass('is-active');
      }
    };

    events.changeName = function(data) {
      instance.tempName = instance.model.playerName();
      toggleModal($('#name-change-modal'));
    };

    events.nameModalClose = function(data) {
      instance.model.playerName(instance.tempName);
      toggleModal($('#name-change-modal'));
    };

    events.nameChangeSave = function(data) {
      toggleModal($('#name-change-modal'));
    };

    const pointTiers = [
      100,
      200,
      400,
      800,
      1200
    ];

    let boardData = {
      categories: [{
          name: 'In the Kitchen',
          values: [{
            points: 100,
            options: [
              {
                type: 'text',
                answer: 'Booger boards',
                question: 'What is a rolling pin?'
              }
            ]
          }, {
            points: 200,
            options: [{
              type: 'text',
              answer: 'test',
              question: 'test'
            }]
          },
          {
          points: 400,
          options: [{
          	type: 'text',
            answer: 'Let\'s play minecraft now',
            question: 'test'
          }]
          }]
        },
        {
          name: 'Film'
        },
        {
          name: 'Food'
        }
      ]
    };

    self.speak = function(text) {
      instance.speech.text = text;
      window.speechSynthesis.speak(instance.speech);
    }

    self.loadCategories = function() {
      return boardData.categories.map(item => {
        return {
       ...