CLASSROOMIO-T-49

merge

CLASSROOMIO-T-49: Quiz CRUD

CLASSROOMIO-T-49: Validate quiz question

CLASSROOMIO-T-49: Begin work on quiz preview

CLASSROOMIO-T-49: Complete quiz page

CLASSROOMIO-T-49: Init quiz work

CLASSROOMIO-T-49: Quiz CRUD

CLASSROOMIO-T-49: Validate quiz question

CLASSROOMIO-T-49: Begin work on quiz preview

CLASSROOMIO-T-49: Complete quiz page

CLASSROOMIO-T-49: Init quiz work


Co-authored-by: Rotimi Best <rotimiibitoyeemma@gmail.com>

Merge-request: CLASSROOMIO-MR-14
Merged-by: Best Admin <digdippa@gmail.com>
This commit is contained in:
Rotimi Best
2023-06-17 19:11:29 +00:00
committed by Space Cloud
co-authored by Rotimi Best
parent b532ea6d29
commit 1e71a91a54
70 changed files with 10601 additions and 497 deletions
+110
View File
@@ -0,0 +1,110 @@
import cloneDeep from 'lodash/cloneDeep';
export const themeImages = {
standard: {
card: 'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/standard-quiz-card.svg',
editor:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/standard-quiz-editor.svg',
play: 'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/standard-quiz-play.svg',
},
mainland: {
card: 'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/mainstream-quiz-card.svg',
editor:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/mainstream-quiz-editor.svg',
play: 'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/mainstream-quiz-play.svg',
},
};
export const defOption = {
id: 1,
label: '',
options: [],
};
export const optionImage = {
circle:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/circle.svg',
spade:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/spade.svg',
square:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/square.svg',
pentagon:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/pentagon.svg',
hexagon:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/hexagon.svg',
triangle:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/triangle.svg',
};
export const allOptions = [
{
id: 'circle',
label: '',
isCorrect: false,
},
{
id: 'triangle',
label: '',
isCorrect: false,
},
{
id: 'spade',
label: '',
isCorrect: false,
},
{
id: 'square',
label: '',
isCorrect: false,
},
{
id: 'pentagon',
label: '',
isCorrect: false,
},
{
id: 'hexagon',
label: '',
isCorrect: false,
},
];
export const booleanOptions = [
{
id: 'triangle',
label: 'True',
image:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/triangle.svg',
},
{
id: 'square',
label: 'False',
image:
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/quizes/square.svg',
},
];
export const allThemes = [
{
id: 'standard',
label: 'Standard',
},
{
id: 'mainland',
label: 'Mainland Bridge',
},
];
export const defQuestion = {
id: new Date().getTime(),
title: '',
type: 'multichoice',
options: [],
timelimit: '10s',
};
export const STEPS = {
CONNECT_TO_PLAY: 'CONNECT_TO_PLAY',
WAIT_FOR_PLAYERS: 'WAIT_FOR_PLAYERS',
SHOW_NEXT_QUESTION: 'SHOW_NEXT_QUESTION',
SCOREBOARD: 'SCOREBOARD',
PODIUM: 'PODIUM',
};
+4
View File
@@ -18,6 +18,10 @@ export function isOrgPage(path) {
return /org\/[a-z 0-9 -]/.test(path);
}
export function isQuizPage(path) {
return /org\/[a-z 0-9 -]+\/quiz\/[a-z 0-9 -]/.test(path);
}
export function isLMSPage(path) {
return /lms[\/a-z 0-9 -]*/.test(path);
}
+5
View File
@@ -0,0 +1,5 @@
export function genQuizPin() {
var minm = 100000;
var maxm = 999999;
return Math.floor(Math.random() * (maxm - minm + 1)) + minm;
}
+32 -3
View File
@@ -1,6 +1,15 @@
import get from 'lodash/get';
import isNumber from 'lodash/isNumber';
import z from 'zod';
import { validateEmail } from './validateEmail';
const createQuizValidationSchema = z.object({
title: z.string().min(6, {
message: 'Must be 6 or more characters long',
invalid_type_error: 'Must not be empty',
}),
});
const askCommunityValidationSchema = z.object({
title: z.string().min(6, {
message: 'Must be 6 or more characters long',
@@ -71,14 +80,28 @@ export const getConfirmPasswordError = ({ password, confirmPassword }) => {
: null;
};
const processErrors = (error) => {
const processErrors = (error, mapToId) => {
const errors = {};
if (Array.isArray(error?.issues)) {
for (const issue of error.issues) {
const { message, path } = issue;
console.log(issue);
if (path.length) {
if (!path.length) {
continue;
}
if (mapToId) {
let value = '';
path.forEach((p, i) => {
const isLast = !path[i + 1];
const formatP = isNumber(p) ? `[${p}]` : p;
value += !value ? formatP : `.${formatP}`;
});
const key = value.replace('label', 'id');
errors[key] = value;
} else {
errors[path[0]] = message;
}
}
@@ -115,6 +138,12 @@ export const onboardingValidation = (fields = {}, step) => {
return processErrors(error);
};
export const createQuizValidation = (fields = {}) => {
const { error } = createQuizValidationSchema.safeParse(fields);
return processErrors(error);
};
export const askCommunityValidation = (fields = {}) => {
const { error } = askCommunityValidationSchema.safeParse(fields);
+26
View File
@@ -0,0 +1,26 @@
import { createQuizModal, deleteModal } from '../../store/org';
export function onEdit(quiz) {}
export function onShare(quiz) {}
export function onReport(quiz) {}
export function onRename(quiz) {
createQuizModal.update((m) => ({
...m,
id: quiz.id,
title: quiz.title,
openEdit: true,
}));
}
export function onMakeCopy(quiz) {}
export function onDelete(quiz) {
deleteModal.update((m) => ({
...m,
open: true,
id: quiz.id,
}));
}
+31
View File
@@ -1,4 +1,6 @@
import cloneDeep from 'lodash/cloneDeep';
import { writable, derived } from 'svelte/store';
import { allOptions, STEPS, booleanOptions } from '../constants/quiz';
export const orgs = writable([]);
export const currentOrg = writable({
@@ -14,3 +16,32 @@ export const currentOrgPath = derived(
currentOrg,
($currentOrg) => `/org/${$currentOrg.siteName}`
);
// Quiz
export const createQuizModal = writable({
open: false,
openEdit: false,
title: '',
id: null,
});
export const deleteModal = writable({
id: null,
open: false,
isQuestion: false,
});
export const quizesStore = writable([]);
export const quizStore = writable({
uuid: '',
title: '',
questions: [],
timelimit: '10s',
theme: 'standard',
pin: '',
});
export const playQuizStore = writable({
step: STEPS.CONNECT_TO_PLAY,
});