Skip to content

Commit

Permalink
borders between questions, reorder rounds/questions/answers
Browse files Browse the repository at this point in the history
  • Loading branch information
swizzard committed Jul 12, 2020
1 parent d649975 commit c95adcb
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 47 deletions.
3 changes: 0 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

## Host

* Reorder questions
* Dividers between questions
* Reload on DELETE
* Round names

## Player
Expand Down
93 changes: 89 additions & 4 deletions app/src/DraftGame.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React, { useReducer, useState } from 'react';
import { submitDraft, updateDraft } from './db/game';
import { draftGameReducer, types } from './reducers/draft';

const UP_ARROW = <span>&#9650;</span>;
const DOWN_ARROW = <span>&#9660;</span>;

function Answer({ answer, qIx, roundIx, answerIx, points, dispatch }) {
const id = `${roundIx}-${qIx}-${answerIx}`;
return (
Expand Down Expand Up @@ -62,13 +65,49 @@ function Answer({ answer, qIx, roundIx, answerIx, points, dispatch }) {
</button>
</div>
</div>
<div className="form-group">
<div className="btn-group">
<button
className="btn btn-dark btn-sm"
type="button"
title="Move answer up"
onClick={() =>
dispatch({
type: types.REORDER_ANSWER,
roundIx,
qIx,
answerIx,
step: -1
})
}
>
{UP_ARROW}
</button>
<button
className="btn btn-dark btn-sm"
type="button"
title="Move answer down"
onClick={() =>
dispatch({
type: types.REORDER_ANSWER,
roundIx,
qIx,
answerIx,
step: 1
})
}
>
{DOWN_ARROW}
</button>
</div>
</div>
</li>
);
}

function Question({ roundIx, qIx, q, dispatch }) {
return (
<div className="card-body">
<div className="card-body question">
<textarea
rows="5"
cols="40"
Expand Down Expand Up @@ -114,6 +153,28 @@ function Question({ roundIx, qIx, q, dispatch }) {
Remove Question
</button>
</div>
<div className="btn-group">
<button
className="btn btn-dark btn-sm"
type="button"
title="Move question up"
onClick={() =>
dispatch({ type: types.REORDER_QUESTION, roundIx, qIx, step: -1 })
}
>
{UP_ARROW}
</button>
<button
className="btn btn-dark btn-sm"
type="button"
title="Move question down"
onClick={() =>
dispatch({ type: types.REORDER_QUESTION, roundIx, qIx, step: 1 })
}
>
{DOWN_ARROW}
</button>
</div>
</div>
);
}
Expand Down Expand Up @@ -148,13 +209,37 @@ function Round({ ix, questions, dispatch }) {
className="btn btn-dark"
type="button"
onClick={() => {
dispatch({ types: types.DELETE_ROUND, roundIx: ix });
dispatch({ type: types.DELETE_ROUND, roundIx: ix });
}}
>
Remove Round
</button>
</div>
</div>
<div className="col-sm-12">
<div className="btn-group">
<button
className="btn btn-dark btn-sm"
type="button"
title="Move round up"
onClick={() =>
dispatch({ type: types.REORDER_ROUND, roundIx: ix, step: -1 })
}
>
{UP_ARROW}
</button>
<button
className="btn btn-dark btn-sm"
type="button"
title="Move round down"
onClick={() =>
dispatch({ type: types.REORDER_ROUND, roundIx: ix, step: 1 })
}
>
{DOWN_ARROW}
</button>
</div>
</div>
</div>
</div>
);
Expand Down Expand Up @@ -209,10 +294,10 @@ export default function DraftGame({ game, goBack, user }) {
</div>
</div>
<div className="card-columns">
{state.quizRounds.map((_, ix) => (
{state.quizRounds.map((round, ix) => (
<Round
ix={ix}
questions={state.quizRounds[ix].questions}
questions={round.questions}
dispatch={dispatch}
key={`round-${ix}`}
/>
Expand Down
4 changes: 4 additions & 0 deletions app/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ body {
.answers-list li:first-child {
font-weight: bold;
}

.card-body.question {
border-bottom: 1px solid #00000020;
}
203 changes: 164 additions & 39 deletions app/src/reducers/draft.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,184 @@
import { deepSet, removeAt } from "../utils";
import { deepSet, removeAt, reorder } from '../utils';

const ADD_ANSWER = "add_answer";
const CHANGE_ANSWER = "change_answer";
const DELETE_ANSWER = "delete_answer";
const ADD_ANSWER = 'add_answer';
const CHANGE_ANSWER = 'change_answer';
const DELETE_ANSWER = 'delete_answer';
const REORDER_ANSWER = 'reorder_answer';

const ADD_ROUND = "add_round";
const DELETE_ROUND = "delete_round";
const ADD_ROUND = 'add_round';
const DELETE_ROUND = 'delete_round';
const REORDER_ROUND = 'reorder_round';

const ADD_QUESTION = "add_question";
const CHANGE_QUESTION = "change_question";
const DELETE_QUESTION = "delete_question";
const ADD_QUESTION = 'add_question';
const CHANGE_QUESTION = 'change_question';
const DELETE_QUESTION = 'delete_question';
const REORDER_QUESTION = 'reorder_question';

const CHANGE_NAME = "change_name";
const CHANGE_NAME = 'change_name';

export const types = {
ADD_ANSWER,
CHANGE_ANSWER,
DELETE_ANSWER,
REORDER_ANSWER,
ADD_ROUND,
DELETE_ROUND,
REORDER_ROUND,
ADD_QUESTION,
CHANGE_QUESTION,
DELETE_QUESTION,
REORDER_QUESTION,
CHANGE_NAME
};

export function draftGameReducer(state, action) {
let fn;
switch (action.type) {
case ADD_ANSWER:
return deepSet(state, [...state.quizRounds[action.roundIx].questions[action.qIx].answers, { answer: "", points: 0 }], ["quizRounds", action.roundIx, "questions", action.qIx, "answers"]);
fn = add_answer;
break;
case CHANGE_ANSWER:
return deepSet(state, { points: action.points, answer: action.answer }, ["quizRounds", action.roundIx, "questions", action.qIx, "answers", action.answerIx]);
fn = change_answer;
break;
case DELETE_ANSWER:
return deepSet(state, removeAt(state.quizRounds[action.roundIx].questions[action.qIx].answers, action.answerIx), ["quizRounds", action.roundIx, "questions", action.qIx, "answers"]);
fn = delete_answer;
break;
case REORDER_ANSWER:
fn = reorder_answer;
break;
case ADD_ROUND:
return deepSet(state, [...state.quizRounds, { questions: [] }], "quizRounds");
fn = add_round;
break;
case DELETE_ROUND:
return deepSet(state, removeAt(state.quizRounds, action.roundIx), "quizRounds");
fn = delete_round;
break;
case REORDER_ROUND:
fn = reorder_round;
break;
case ADD_QUESTION:
return deepSet(state, [...state.quizRounds[action.roundIx].questions, { question: "", answers: [] }], ["quizRounds", action.roundIx, "questions"]);
fn = add_question;
break;
case CHANGE_QUESTION:
return deepSet(
state,
{
question: action.question,
answers: state.quizRounds[action.roundIx].questions[action.qIx].answers
},
["quizRounds", action.roundIx, "questions", action.qIx]
);
fn = change_question;
break;
case DELETE_QUESTION:
return deepSet(state, removeAt(state.quizRounds[action.roundIx].questions, action.qIx), ["quizRounds", action.roundIx, "questions"]);
fn = delete_question;
break;
case REORDER_QUESTION:
fn = reorder_question;
break;
case CHANGE_NAME:
return deepSet(state, action.name, "quizName");
fn = change_name;
break;
default:
console.log(`INVALID ACTION ${action.type}`);
return state;
fn = invalid_action;
break;
}
return fn(state, action);
}

export const types = {
ADD_ANSWER,
CHANGE_ANSWER,
DELETE_ANSWER,
ADD_ROUND,
DELETE_ROUND,
ADD_QUESTION,
CHANGE_QUESTION,
DELETE_QUESTION,
CHANGE_NAME
};
function add_answer(state, action) {
return deepSet(
state,
[
...state.quizRounds[action.roundIx].questions[action.qIx].answers,
{ answer: '', points: 0 }
],
['quizRounds', action.roundIx, 'questions', action.qIx, 'answers']
);
}

function change_answer(state, action) {
return deepSet(state, { points: action.points, answer: action.answer }, [
'quizRounds',
action.roundIx,
'questions',
action.qIx,
'answers',
action.answerIx
]);
}

function delete_answer(state, action) {
return deepSet(
state,
removeAt(
state.quizRounds[action.roundIx].questions[action.qIx].answers,
action.answerIx
),
['quizRounds', action.roundIx, 'questions', action.qIx, 'answers']
);
}

function reorder_answer(state, action) {
return reorder(state, action.answerIx, action.step, [
'quizRounds',
action.roundIx,
'questions',
action.qIx,
'answers'
]);
}

function add_round(state, _action) {
return deepSet(state, [...state.quizRounds, { questions: [] }], 'quizRounds');
}

function delete_round(state, action) {
return deepSet(
state,
removeAt(state.quizRounds, action.roundIx),
'quizRounds'
);
}

function reorder_round(state, action) {
return reorder(state, action.roundIx, action.step, ['quizRounds']);
}

function add_question(state, action) {
return deepSet(
state,
[
...state.quizRounds[action.roundIx].questions,
{ question: '', answers: [] }
],
['quizRounds', action.roundIx, 'questions']
);
}

function change_question(state, action) {
return deepSet(
state,
{
question: action.question,
answers: state.quizRounds[action.roundIx].questions[action.qIx].answers
},
['quizRounds', action.roundIx, 'questions', action.qIx]
);
}

function delete_question(state, action) {
return deepSet(
state,
removeAt(state.quizRounds[action.roundIx].questions, action.qIx),
['quizRounds', action.roundIx, 'questions']
);
}

function reorder_question(state, action) {
return reorder(state, action.qIx, action.step, [
'quizRounds',
action.roundIx,
'questions'
]);
}

function change_name(state, action) {
return deepSet(state, action.name, 'quizName');
}

function invalid_action(state, action) {
console.log(`INVALID ACTION ${action.type}`);
return state;
}
Loading

0 comments on commit c95adcb

Please sign in to comment.