Added the ability for some exams to be private and not chosen randomly
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Module } from ".";
|
import {Module} from ".";
|
||||||
|
|
||||||
export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam;
|
export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam;
|
||||||
export type Variant = "full" | "partial";
|
export type Variant = "full" | "partial";
|
||||||
@@ -15,6 +15,7 @@ interface ExamBase {
|
|||||||
shuffle?: boolean;
|
shuffle?: boolean;
|
||||||
createdBy?: string; // option as it has been added later
|
createdBy?: string; // option as it has been added later
|
||||||
createdAt?: string; // option as it has been added later
|
createdAt?: string; // option as it has been added later
|
||||||
|
private?: boolean;
|
||||||
}
|
}
|
||||||
export interface ReadingExam extends ExamBase {
|
export interface ReadingExam extends ExamBase {
|
||||||
module: "reading";
|
module: "reading";
|
||||||
@@ -67,7 +68,7 @@ export interface UserSolution {
|
|||||||
};
|
};
|
||||||
exercise: string;
|
exercise: string;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
shuffleMaps?: ShuffleMap[]
|
shuffleMaps?: ShuffleMap[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WritingExam extends ExamBase {
|
export interface WritingExam extends ExamBase {
|
||||||
@@ -99,24 +100,19 @@ export type Exercise =
|
|||||||
export interface Evaluation {
|
export interface Evaluation {
|
||||||
comment: string;
|
comment: string;
|
||||||
overall: number;
|
overall: number;
|
||||||
task_response: { [key: string]: number | { grade: number; comment: string } };
|
task_response: {[key: string]: number | {grade: number; comment: string}};
|
||||||
misspelled_pairs?: { correction: string | null; misspelled: string }[];
|
misspelled_pairs?: {correction: string | null; misspelled: string}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type InteractivePerfectAnswerKey = `perfect_answer_${number}`;
|
type InteractivePerfectAnswerKey = `perfect_answer_${number}`;
|
||||||
type InteractiveTranscriptKey = `transcript_${number}`;
|
type InteractiveTranscriptKey = `transcript_${number}`;
|
||||||
type InteractiveFixedTextKey = `fixed_text_${number}`;
|
type InteractiveFixedTextKey = `fixed_text_${number}`;
|
||||||
|
|
||||||
type InteractivePerfectAnswerType = { [key in InteractivePerfectAnswerKey]: { answer: string } };
|
type InteractivePerfectAnswerType = {[key in InteractivePerfectAnswerKey]: {answer: string}};
|
||||||
type InteractiveTranscriptType = { [key in InteractiveTranscriptKey]?: string };
|
type InteractiveTranscriptType = {[key in InteractiveTranscriptKey]?: string};
|
||||||
type InteractiveFixedTextType = { [key in InteractiveFixedTextKey]?: string };
|
type InteractiveFixedTextType = {[key in InteractiveFixedTextKey]?: string};
|
||||||
|
|
||||||
interface InteractiveSpeakingEvaluation extends Evaluation,
|
|
||||||
InteractivePerfectAnswerType,
|
|
||||||
InteractiveTranscriptType,
|
|
||||||
InteractiveFixedTextType { }
|
|
||||||
|
|
||||||
|
interface InteractiveSpeakingEvaluation extends Evaluation, InteractivePerfectAnswerType, InteractiveTranscriptType, InteractiveFixedTextType {}
|
||||||
|
|
||||||
interface SpeakingEvaluation extends CommonEvaluation {
|
interface SpeakingEvaluation extends CommonEvaluation {
|
||||||
perfect_answer_1?: string;
|
perfect_answer_1?: string;
|
||||||
@@ -189,10 +185,10 @@ export interface InteractiveSpeakingExercise {
|
|||||||
first_title?: string;
|
first_title?: string;
|
||||||
second_title?: string;
|
second_title?: string;
|
||||||
text: string;
|
text: string;
|
||||||
prompts: { text: string; video_url: string }[];
|
prompts: {text: string; video_url: string}[];
|
||||||
userSolutions: {
|
userSolutions: {
|
||||||
id: string;
|
id: string;
|
||||||
solution: { questionIndex: number; question: string; answer: string }[];
|
solution: {questionIndex: number; question: string; answer: string}[];
|
||||||
evaluation?: InteractiveSpeakingEvaluation;
|
evaluation?: InteractiveSpeakingEvaluation;
|
||||||
}[];
|
}[];
|
||||||
topic?: string;
|
topic?: string;
|
||||||
@@ -208,14 +204,14 @@ export interface FillBlanksMCOption {
|
|||||||
B: string;
|
B: string;
|
||||||
C: string;
|
C: string;
|
||||||
D: string;
|
D: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FillBlanksExercise {
|
export interface FillBlanksExercise {
|
||||||
prompt: string; // *EXAMPLE: "Complete the summary below. Click a blank to select the corresponding word for it."
|
prompt: string; // *EXAMPLE: "Complete the summary below. Click a blank to select the corresponding word for it."
|
||||||
type: "fillBlanks";
|
type: "fillBlanks";
|
||||||
id: string;
|
id: string;
|
||||||
words: (string | { letter: string; word: string } | FillBlanksMCOption)[]; // *EXAMPLE: ["preserve", "unaware"]
|
words: (string | {letter: string; word: string} | FillBlanksMCOption)[]; // *EXAMPLE: ["preserve", "unaware"]
|
||||||
text: string; // *EXAMPLE: "They tried to {{1}} burning"
|
text: string; // *EXAMPLE: "They tried to {{1}} burning"
|
||||||
allowRepetition?: boolean;
|
allowRepetition?: boolean;
|
||||||
solutions: {
|
solutions: {
|
||||||
@@ -234,7 +230,7 @@ export interface TrueFalseExercise {
|
|||||||
id: string;
|
id: string;
|
||||||
prompt: string; // *EXAMPLE: "Select the appropriate option."
|
prompt: string; // *EXAMPLE: "Select the appropriate option."
|
||||||
questions: TrueFalseQuestion[];
|
questions: TrueFalseQuestion[];
|
||||||
userSolutions: { id: string; solution: "true" | "false" | "not_given" }[];
|
userSolutions: {id: string; solution: "true" | "false" | "not_given"}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TrueFalseQuestion {
|
export interface TrueFalseQuestion {
|
||||||
@@ -263,7 +259,7 @@ export interface MatchSentencesExercise {
|
|||||||
type: "matchSentences";
|
type: "matchSentences";
|
||||||
id: string;
|
id: string;
|
||||||
prompt: string;
|
prompt: string;
|
||||||
userSolutions: { question: string; option: string }[];
|
userSolutions: {question: string; option: string}[];
|
||||||
sentences: MatchSentenceExerciseSentence[];
|
sentences: MatchSentenceExerciseSentence[];
|
||||||
allowRepetition: boolean;
|
allowRepetition: boolean;
|
||||||
options: MatchSentenceExerciseOption[];
|
options: MatchSentenceExerciseOption[];
|
||||||
@@ -286,7 +282,7 @@ export interface MultipleChoiceExercise {
|
|||||||
id: string;
|
id: string;
|
||||||
prompt: string; // *EXAMPLE: "Select the appropriate option."
|
prompt: string; // *EXAMPLE: "Select the appropriate option."
|
||||||
questions: MultipleChoiceQuestion[];
|
questions: MultipleChoiceQuestion[];
|
||||||
userSolutions: { question: string; option: string }[];
|
userSolutions: {question: string; option: string}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MultipleChoiceQuestion {
|
export interface MultipleChoiceQuestion {
|
||||||
@@ -306,10 +302,10 @@ export interface ShuffleMap {
|
|||||||
questionID: string;
|
questionID: string;
|
||||||
map: {
|
map: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Shuffles {
|
export interface Shuffles {
|
||||||
exerciseID: string;
|
exerciseID: string;
|
||||||
shuffles: ShuffleMap[]
|
shuffles: ShuffleMap[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {collection, getDocs, query, where, setDoc, doc, Firestore, getDoc} from "firebase/firestore";
|
import {collection, getDocs, query, where, setDoc, doc, Firestore, getDoc, and} from "firebase/firestore";
|
||||||
import {shuffle} from "lodash";
|
import {shuffle} from "lodash";
|
||||||
import {Difficulty, Exam, InstructorGender, SpeakingExam, Variant, WritingExam} from "@/interfaces/exam";
|
import {Difficulty, Exam, InstructorGender, SpeakingExam, Variant, WritingExam} from "@/interfaces/exam";
|
||||||
import {DeveloperUser, Stat, StudentUser, User} from "@/interfaces/user";
|
import {DeveloperUser, Stat, StudentUser, User} from "@/interfaces/user";
|
||||||
@@ -17,7 +17,7 @@ export const getExams = async (
|
|||||||
): Promise<Exam[]> => {
|
): Promise<Exam[]> => {
|
||||||
const moduleRef = collection(db, module);
|
const moduleRef = collection(db, module);
|
||||||
|
|
||||||
const q = query(moduleRef, where("isDiagnostic", "==", false));
|
const q = query(moduleRef, and(where("isDiagnostic", "==", false), where("private", "!=", true)));
|
||||||
const snapshot = await getDocs(q);
|
const snapshot = await getDocs(q);
|
||||||
|
|
||||||
const allExams = shuffle(
|
const allExams = shuffle(
|
||||||
|
|||||||
Reference in New Issue
Block a user