Skip to content

Commit

Permalink
refactor(files): modularized stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
CorentinTh committed Mar 5, 2024
1 parent 70c7d69 commit 3f7966c
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 88 deletions.
48 changes: 0 additions & 48 deletions http-codes/http-codes.service.ts

This file was deleted.

2 changes: 2 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
extends: ['src/modules/quiz', 'src/modules/http-status'],

devtools: { enabled: true },

modules: ['@nuxt/ui', '@nuxtjs/seo', '@nuxtjs/fontaine', '@vueuse/nuxt', '@nuxtjs/google-fonts', '@pinia/nuxt', '@nuxtjs/plausible'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import _ from 'lodash';

export const codesByCategories: {
category: string;
codes: {
Expand Down Expand Up @@ -413,5 +411,3 @@ export const codesByCategories: {
],
},
];

export const codesQuestionPool = _.chain(codesByCategories).map('codes').flatten().filter({ type: 'HTTP' }).value();
13 changes: 13 additions & 0 deletions src/modules/http-status/http-status.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import _ from 'lodash';
import { codesByCategories } from './http-status.constants';

export { getHttpStatus };

function getHttpStatus() {
return _.chain(codesByCategories)
.map('codes')
.flatten()
.filter({ type: 'HTTP' })
.map(({ type, ...rest }) => rest)
.value();
}
34 changes: 34 additions & 0 deletions src/modules/http-status/http-status.usecases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import _ from 'lodash';
import type { Question } from '../quiz/quiz.types';
import { takeUniqueRandoms } from '../shared/random.models';
import { getHttpStatus } from './http-status.services';

export { getHttpCodeQuestions };

function getHttpCodeQuestions({ questionCount }: { questionCount: number }): Question[] {
const httpStatuses = getHttpStatus();

const httpStatusForQuestions = _.sampleSize(httpStatuses, questionCount);

return httpStatusForQuestions.map((httpStatus) => {
const correctAnswer = {
label: httpStatus.name,
isCorrect: true,
};

const wrongAnswers = takeUniqueRandoms(httpStatuses, { count: 3, excludeBy: (status) => status.code === httpStatus.code }).map((status) => ({
label: status.name,
isCorrect: false,
}));

return {
question: 'Which of the following is the correct HTTP status for this code?',
heading: httpStatus.code.toString(),
answers: _.shuffle([correctAnswer, ...wrongAnswers]),
explanation: {
title: `${httpStatus.code} - ${httpStatus.name}`,
description: httpStatus.description,
},
};
});
}
Empty file.
42 changes: 6 additions & 36 deletions pages/index.vue → src/modules/http-status/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,39 +1,9 @@
<script setup lang="ts">
import { getHttpCodeQuestions } from '../http-codes/http-codes.service';
import { getHttpCodeQuestions } from '../http-status.usecases';
const questions = ref(getHttpCodeQuestions());
const currentQuestionIndex = ref(0);
const currentQuestion = computed(() => questions.value[currentQuestionIndex.value]);
const isAnswered = ref(false);
const selectedAnswer = ref<{
label: string;
isCorrect: boolean;
}>();
function handleAnswer({
answer,
}: {
answer: {
label: string;
isCorrect: boolean;
};
}) {
isAnswered.value = true;
selectedAnswer.value = answer;
}
function handleNext() {
isAnswered.value = false;
selectedAnswer.value = undefined;
if (currentQuestionIndex.value < questions.value.length - 1) {
currentQuestionIndex.value++;
} else {
currentQuestionIndex.value = 0;
questions.value = getHttpCodeQuestions();
}
}
const { currentQuestion, selectAnswer, isAnswered, selectedAnswer, goToNextQuestion } = useQuiz({
questionsBuilder: getHttpCodeQuestions,
});
</script>

<template>
Expand All @@ -47,7 +17,7 @@ function handleNext() {
<UButton
v-for="(answer, index) in currentQuestion.answers"
:key="index"
:onClick="() => handleAnswer({ answer })"
:onClick="() => selectAnswer({ answer })"
:disabled="isAnswered"
size="lg"
class="transition"
Expand All @@ -69,7 +39,7 @@ function handleNext() {
</UCard>

<div class="flex justify-end">
<UButton @click="handleNext" size="lg" color="orange" trailingIcon="i-tabler-arrow-right"> Next </UButton>
<UButton @click="goToNextQuestion" size="lg" color="orange" trailingIcon="i-tabler-arrow-right"> Next </UButton>
</div>
</div>

Expand Down
45 changes: 45 additions & 0 deletions src/modules/quiz/composables/useQuiz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { get } from '@vueuse/core';
import type { Question, QuestionAnswer } from '../quiz.types';

export { useQuiz };

function useQuiz({ questionsBuilder: createQuestions, questionCount = 10 }: { questionsBuilder: (args: { questionCount: number }) => Question[]; questionCount?: MaybeRef<number> }) {
const questions = ref<Question[]>(createQuestions({ questionCount: get(questionCount) }));
const currentQuestionIndex = ref(0);
const currentQuestion = computed<Question>(() => questions.value[currentQuestionIndex.value]);
const selectedAnswer = ref<QuestionAnswer | undefined>(undefined);
const state = ref<'answering' | 'answered' | 'finished'>('answering');
const score = ref(0);

const selectAnswer = ({ answer }: { answer: QuestionAnswer }) => {
if (answer.isCorrect) {
score.value++;
}

selectedAnswer.value = answer;
state.value = 'answered';
};

const goToNextQuestion = () => {
if (currentQuestionIndex.value < questions.value.length - 1) {
currentQuestionIndex.value++;
selectedAnswer.value = undefined;
state.value = 'answering';
} else {
state.value = 'finished';
}
};

return {
questions,
currentQuestion,
selectedAnswer,
state,
score,
selectAnswer,
goToNextQuestion,
isAnswered: computed(() => state.value === 'answered'),
isFinished: computed(() => state.value === 'finished'),
isAnswering: computed(() => state.value === 'answering'),
};
}
Empty file added src/modules/quiz/nuxt.config.ts
Empty file.
14 changes: 14 additions & 0 deletions src/modules/quiz/quiz.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type QuestionAnswer = {
label: string;
isCorrect: boolean;
};

export type Question = {
question: string;
heading: string;
answers: QuestionAnswer[];
explanation?: {
title: string;
description: string;
};
};
7 changes: 7 additions & 0 deletions src/modules/shared/random.models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import _ from 'lodash';

export { takeUniqueRandoms };

function takeUniqueRandoms<T>(data: T[], { count = 1, excludeBy = () => false }: { count?: number; excludeBy?: (item: T) => boolean } = {}): T[] {
return _.chain(data).shuffle().reject(excludeBy).take(count).value();
}

0 comments on commit 3f7966c

Please sign in to comment.