87 | >(({ className, ...props }, ref) => (
88 | [role=checkbox]]:translate-y-[2px]",
92 | className
93 | )}
94 | {...props}
95 | />
96 | ))
97 | TableCell.displayName = "TableCell"
98 |
99 | const TableCaption = React.forwardRef<
100 | HTMLTableCaptionElement,
101 | React.HTMLAttributes
102 | >(({ className, ...props }, ref) => (
103 |
108 | ))
109 | TableCaption.displayName = "TableCaption"
110 |
111 | export {
112 | Table,
113 | TableHeader,
114 | TableBody,
115 | TableFooter,
116 | TableHead,
117 | TableRow,
118 | TableCell,
119 | TableCaption,
120 | }
121 |
--------------------------------------------------------------------------------
/data/csQuestions.js:
--------------------------------------------------------------------------------
1 | const csQuestions = [
2 | {
3 | text: "What does CPU stand for?",
4 | options: [
5 | { text: "Central Processing Unit", isCorrect: true },
6 | { text: "Central Programming Unit", isCorrect: false },
7 | { text: "Central Process Unit", isCorrect: false },
8 | { text: "Computer Processing Unit", isCorrect: false },
9 | ],
10 | },
11 | {
12 | text: "What is the main purpose of an operating system?",
13 | options: [
14 | { text: "To manage computer hardware and software", isCorrect: true },
15 | { text: "To run antivirus software", isCorrect: false },
16 | { text: "To process user data", isCorrect: false },
17 | { text: "To perform arithmetic calculations", isCorrect: false },
18 | ],
19 | },
20 | {
21 | text: "What does HTML stand for?",
22 | options: [
23 | { text: "HyperText Markup Language", isCorrect: true },
24 | { text: "HyperText Machine Language", isCorrect: false },
25 | { text: "HyperText Modern Language", isCorrect: false },
26 | { text: "HyperTool Markup Language", isCorrect: false },
27 | ],
28 | },
29 | {
30 | text: "Which data structure uses LIFO (Last In, First Out)?",
31 | options: [
32 | { text: "Stack", isCorrect: true },
33 | { text: "Queue", isCorrect: false },
34 | { text: "Array", isCorrect: false },
35 | { text: "Tree", isCorrect: false },
36 | ],
37 | },
38 | {
39 | text: "What is a primary key in a database?",
40 | options: [
41 | { text: "A unique identifier for a record", isCorrect: true },
42 | { text: "A foreign key for table relationships", isCorrect: false },
43 | { text: "A column to store large data", isCorrect: false },
44 | { text: "A tool to perform queries", isCorrect: false },
45 | ],
46 | },
47 | {
48 | text: "Which programming language is primarily used for Android app development?",
49 | options: [
50 | { text: "Java", isCorrect: true },
51 | { text: "Python", isCorrect: false },
52 | { text: "C#", isCorrect: false },
53 | { text: "Ruby", isCorrect: false },
54 | ],
55 | },
56 | {
57 | text: "What is the binary representation of the decimal number 5?",
58 | options: [
59 | { text: "101", isCorrect: true },
60 | { text: "110", isCorrect: false },
61 | { text: "111", isCorrect: false },
62 | { text: "100", isCorrect: false },
63 | ],
64 | },
65 | {
66 | text: "Which sorting algorithm is the fastest in the average case?",
67 | options: [
68 | { text: "Merge Sort", isCorrect: false },
69 | { text: "Quick Sort", isCorrect: true },
70 | { text: "Bubble Sort", isCorrect: false },
71 | { text: "Selection Sort", isCorrect: false },
72 | ],
73 | },
74 | {
75 | text: "What is the purpose of an IP address?",
76 | options: [
77 | { text: "To uniquely identify a device on a network", isCorrect: true },
78 | { text: "To store user passwords", isCorrect: false },
79 | { text: "To encrypt network traffic", isCorrect: false },
80 | { text: "To assign memory to a program", isCorrect: false },
81 | ],
82 | },
83 | {
84 | text: "Which of the following is a NoSQL database?",
85 | options: [
86 | { text: "MongoDB", isCorrect: true },
87 | { text: "MySQL", isCorrect: false },
88 | { text: "PostgreSQL", isCorrect: false },
89 | { text: "SQLite", isCorrect: false },
90 | ],
91 | },
92 | ];
93 |
94 | module.exports = csQuestions;
95 |
--------------------------------------------------------------------------------
/data/chemistryQuestions.js:
--------------------------------------------------------------------------------
1 | const chemistryQuestions = [
2 | {
3 | text: "What is the most abundant gas in Earth's atmosphere?",
4 | options: [
5 | { text: "Nitrogen", isCorrect: true },
6 | { text: "Oxygen", isCorrect: false },
7 | { text: "Carbon Dioxide", isCorrect: false },
8 | { text: "Argon", isCorrect: false },
9 | ],
10 | },
11 | {
12 | text: "What is the chemical formula for water?",
13 | options: [
14 | { text: "H2O", isCorrect: true },
15 | { text: "O2", isCorrect: false },
16 | { text: "CO2", isCorrect: false },
17 | { text: "H2O2", isCorrect: false },
18 | ],
19 | },
20 | {
21 | text: "What is the pH of a neutral solution?",
22 | options: [
23 | { text: "7", isCorrect: true },
24 | { text: "0", isCorrect: false },
25 | { text: "14", isCorrect: false },
26 | { text: "1", isCorrect: false },
27 | ],
28 | },
29 | {
30 | text: "What is the molar mass of carbon dioxide (CO2)?",
31 | options: [
32 | { text: "44 g/mol", isCorrect: true },
33 | { text: "28 g/mol", isCorrect: false },
34 | { text: "18 g/mol", isCorrect: false },
35 | { text: "32 g/mol", isCorrect: false },
36 | ],
37 | },
38 | {
39 | text: "Which element is represented by the symbol 'Na'?",
40 | options: [
41 | { text: "Sodium", isCorrect: true },
42 | { text: "Nitrogen", isCorrect: false },
43 | { text: "Neon", isCorrect: false },
44 | { text: "Nickel", isCorrect: false },
45 | ],
46 | },
47 | {
48 | text: "What type of bond is formed between two water molecules?",
49 | options: [
50 | { text: "Hydrogen bond", isCorrect: true },
51 | { text: "Ionic bond", isCorrect: false },
52 | { text: "Covalent bond", isCorrect: false },
53 | { text: "Metallic bond", isCorrect: false },
54 | ],
55 | },
56 | {
57 | text: "What is the atomic number of oxygen?",
58 | options: [
59 | { text: "8", isCorrect: true },
60 | { text: "6", isCorrect: false },
61 | { text: "7", isCorrect: false },
62 | { text: "9", isCorrect: false },
63 | ],
64 | },
65 | {
66 | text: "Which gas is commonly used in balloons because it is lighter than air?",
67 | options: [
68 | { text: "Helium", isCorrect: true },
69 | { text: "Hydrogen", isCorrect: false },
70 | { text: "Nitrogen", isCorrect: false },
71 | { text: "Oxygen", isCorrect: false },
72 | ],
73 | },
74 | {
75 | text: "What is the main component of natural gas?",
76 | options: [
77 | { text: "Methane", isCorrect: true },
78 | { text: "Propane", isCorrect: false },
79 | { text: "Butane", isCorrect: false },
80 | { text: "Ethane", isCorrect: false },
81 | ],
82 | },
83 | {
84 | text: "Which acid is found in vinegar?",
85 | options: [
86 | { text: "Acetic acid", isCorrect: true },
87 | { text: "Citric acid", isCorrect: false },
88 | { text: "Lactic acid", isCorrect: false },
89 | { text: "Sulfuric acid", isCorrect: false },
90 | ],
91 | },
92 | {
93 | text: "What is the process of converting a liquid to a gas called?",
94 | options: [
95 | { text: "Evaporation", isCorrect: true },
96 | { text: "Condensation", isCorrect: false },
97 | { text: "Sublimation", isCorrect: false },
98 | { text: "Freezing", isCorrect: false },
99 | ],
100 | },
101 | {
102 | text: "Which of the following is an alkali metal?",
103 | options: [
104 | { text: "Potassium", isCorrect: true },
105 | { text: "Calcium", isCorrect: false },
106 | { text: "Iron", isCorrect: false },
107 | { text: "Aluminum", isCorrect: false },
108 | ],
109 | },
110 | {
111 | text: "What is the name of the process in which plants produce glucose?",
112 | options: [
113 | { text: "Photosynthesis", isCorrect: true },
114 | { text: "Respiration", isCorrect: false },
115 | { text: "Fermentation", isCorrect: false },
116 | { text: "Oxidation", isCorrect: false },
117 | ],
118 | },
119 | {
120 | text: "Which compound is known as the universal solvent?",
121 | options: [
122 | { text: "Water", isCorrect: true },
123 | { text: "Ethanol", isCorrect: false },
124 | { text: "Acetone", isCorrect: false },
125 | { text: "Methanol", isCorrect: false },
126 | ],
127 | },
128 | {
129 | text: "What is the chemical formula for table salt?",
130 | options: [
131 | { text: "NaCl", isCorrect: true },
132 | { text: "KCl", isCorrect: false },
133 | { text: "CaCl2", isCorrect: false },
134 | { text: "MgCl2", isCorrect: false },
135 | ],
136 | },
137 | ];
138 |
139 | module.exports = chemistryQuestions;
140 |
--------------------------------------------------------------------------------
/data/physicsQuestions.js:
--------------------------------------------------------------------------------
1 | const physicsQuestions = [
2 | {
3 | text: "What is Newton's second law of motion?",
4 | options: [
5 | { text: "Force equals mass times acceleration", isCorrect: true },
6 | { text: "An object in motion stays in motion", isCorrect: false },
7 | {
8 | text: "For every action, there is an equal and opposite reaction",
9 | isCorrect: false,
10 | },
11 | { text: "Energy cannot be created or destroyed", isCorrect: false },
12 | ],
13 | },
14 | {
15 | text: "What is the SI unit of force?",
16 | options: [
17 | { text: "Newton", isCorrect: true },
18 | { text: "Joule", isCorrect: false },
19 | { text: "Pascal", isCorrect: false },
20 | { text: "Watt", isCorrect: false },
21 | ],
22 | },
23 | {
24 | text: "What does E=mc^2 represent?",
25 | options: [
26 | { text: "Energy-mass equivalence", isCorrect: true },
27 | { text: "Kinetic energy formula", isCorrect: false },
28 | { text: "Force-mass relationship", isCorrect: false },
29 | { text: "Work-energy theorem", isCorrect: false },
30 | ],
31 | },
32 | {
33 | text: "What is the universal gravitational constant (G)?",
34 | options: [
35 | { text: "6.674 × 10^-11 N·m²/kg²", isCorrect: true },
36 | { text: "9.8 m/s²", isCorrect: false },
37 | { text: "1.6 × 10^-19 C", isCorrect: false },
38 | { text: "3.0 × 10^8 m/s", isCorrect: false },
39 | ],
40 | },
41 | {
42 | text: "What is the formula for kinetic energy?",
43 | options: [
44 | { text: "1/2 mv²", isCorrect: true },
45 | { text: "mgh", isCorrect: false },
46 | { text: "mv", isCorrect: false },
47 | { text: "qV", isCorrect: false },
48 | ],
49 | },
50 | {
51 | text: "What is the acceleration due to gravity on Earth?",
52 | options: [
53 | { text: "9.8 m/s²", isCorrect: true },
54 | { text: "6.674 × 10^-11 m/s²", isCorrect: false },
55 | { text: "3.0 × 10^8 m/s²", isCorrect: false },
56 | { text: "1.6 × 10^-19 m/s²", isCorrect: false },
57 | ],
58 | },
59 | {
60 | text: "Which law states that the pressure of a gas is inversely proportional to its volume?",
61 | options: [
62 | { text: "Boyle's Law", isCorrect: true },
63 | { text: "Charles's Law", isCorrect: false },
64 | { text: "Avogadro's Law", isCorrect: false },
65 | { text: "Pascal's Law", isCorrect: false },
66 | ],
67 | },
68 | {
69 | text: "What is the SI unit of power?",
70 | options: [
71 | { text: "Watt", isCorrect: true },
72 | { text: "Joule", isCorrect: false },
73 | { text: "Newton", isCorrect: false },
74 | { text: "Ampere", isCorrect: false },
75 | ],
76 | },
77 | {
78 | text: "What is the work done when a 10 N force moves an object 5 m in the direction of the force?",
79 | options: [
80 | { text: "50 J", isCorrect: true },
81 | { text: "5 J", isCorrect: false },
82 | { text: "10 J", isCorrect: false },
83 | { text: "500 J", isCorrect: false },
84 | ],
85 | },
86 | {
87 | text: "What is the speed of light in a vacuum?",
88 | options: [
89 | { text: "3.0 × 10^8 m/s", isCorrect: true },
90 | { text: "9.8 m/s", isCorrect: false },
91 | { text: "1.6 × 10^-19 m/s", isCorrect: false },
92 | { text: "6.674 × 10^-11 m/s", isCorrect: false },
93 | ],
94 | },
95 | {
96 | text: "What type of wave is sound?",
97 | options: [
98 | { text: "Longitudinal", isCorrect: true },
99 | { text: "Transverse", isCorrect: false },
100 | { text: "Electromagnetic", isCorrect: false },
101 | { text: "Stationary", isCorrect: false },
102 | ],
103 | },
104 | {
105 | text: "What is the formula for Ohm's Law?",
106 | options: [
107 | { text: "V = IR", isCorrect: true },
108 | { text: "P = VI", isCorrect: false },
109 | { text: "I = V/R", isCorrect: false },
110 | { text: "R = V/I", isCorrect: false },
111 | ],
112 | },
113 | {
114 | text: "What is the SI unit of electric charge?",
115 | options: [
116 | { text: "Coulomb", isCorrect: true },
117 | { text: "Ampere", isCorrect: false },
118 | { text: "Volt", isCorrect: false },
119 | { text: "Ohm", isCorrect: false },
120 | ],
121 | },
122 | {
123 | text: "What is the energy of a photon with a frequency of 5 × 10^14 Hz? (h = 6.63 × 10^-34 J·s)",
124 | options: [
125 | { text: "3.315 × 10^-19 J", isCorrect: true },
126 | { text: "6.63 × 10^-19 J", isCorrect: false },
127 | { text: "1.327 × 10^-18 J", isCorrect: false },
128 | { text: "5.0 × 10^-14 J", isCorrect: false },
129 | ],
130 | },
131 | {
132 | text: "What is the period of a wave with a frequency of 10 Hz?",
133 | options: [
134 | { text: "0.1 s", isCorrect: true },
135 | { text: "10 s", isCorrect: false },
136 | { text: "0.01 s", isCorrect: false },
137 | { text: "1 s", isCorrect: false },
138 | ],
139 | },
140 | ];
141 |
142 | module.exports = physicsQuestions;
143 |
--------------------------------------------------------------------------------
/data/biologyQuestions.js:
--------------------------------------------------------------------------------
1 | const biologyQuestions = [
2 | {
3 | text: "What is the primary function of mitochondria in cells?",
4 | options: [
5 | { text: "Energy production", isCorrect: true },
6 | { text: "Protein synthesis", isCorrect: false },
7 | { text: "Photosynthesis", isCorrect: false },
8 | { text: "Cell division", isCorrect: false },
9 | ],
10 | },
11 | {
12 | text: "What is the monomer unit of proteins?",
13 | options: [
14 | { text: "Amino acids", isCorrect: true },
15 | { text: "Nucleotides", isCorrect: false },
16 | { text: "Monosaccharides", isCorrect: false },
17 | { text: "Fatty acids", isCorrect: false },
18 | ],
19 | },
20 | {
21 | text: "Which organ is responsible for filtering blood in humans?",
22 | options: [
23 | { text: "Kidney", isCorrect: true },
24 | { text: "Liver", isCorrect: false },
25 | { text: "Heart", isCorrect: false },
26 | { text: "Lungs", isCorrect: false },
27 | ],
28 | },
29 | {
30 | text: "What is the primary pigment involved in photosynthesis?",
31 | options: [
32 | { text: "Chlorophyll", isCorrect: true },
33 | { text: "Carotene", isCorrect: false },
34 | { text: "Xanthophyll", isCorrect: false },
35 | { text: "Anthocyanin", isCorrect: false },
36 | ],
37 | },
38 | {
39 | text: "What is the process by which cells divide to form two identical daughter cells?",
40 | options: [
41 | { text: "Mitosis", isCorrect: true },
42 | { text: "Meiosis", isCorrect: false },
43 | { text: "Binary fission", isCorrect: false },
44 | { text: "Cytokinesis", isCorrect: false },
45 | ],
46 | },
47 | {
48 | text: "What is the molecule that carries genetic information in most living organisms?",
49 | options: [
50 | { text: "DNA", isCorrect: true },
51 | { text: "RNA", isCorrect: false },
52 | { text: "Proteins", isCorrect: false },
53 | { text: "Lipids", isCorrect: false },
54 | ],
55 | },
56 | {
57 | text: "What is the name of the process by which plants lose water through their leaves?",
58 | options: [
59 | { text: "Transpiration", isCorrect: true },
60 | { text: "Respiration", isCorrect: false },
61 | { text: "Photosynthesis", isCorrect: false },
62 | { text: "Excretion", isCorrect: false },
63 | ],
64 | },
65 | {
66 | text: "Which part of the brain controls coordination and balance?",
67 | options: [
68 | { text: "Cerebellum", isCorrect: true },
69 | { text: "Cerebrum", isCorrect: false },
70 | { text: "Medulla oblongata", isCorrect: false },
71 | { text: "Hypothalamus", isCorrect: false },
72 | ],
73 | },
74 | {
75 | text: "What is the structural and functional unit of the kidney?",
76 | options: [
77 | { text: "Nephron", isCorrect: true },
78 | { text: "Neuron", isCorrect: false },
79 | { text: "Alveolus", isCorrect: false },
80 | { text: "Capillary", isCorrect: false },
81 | ],
82 | },
83 | {
84 | text: "Which organ in the human body produces insulin?",
85 | options: [
86 | { text: "Pancreas", isCorrect: true },
87 | { text: "Liver", isCorrect: false },
88 | { text: "Kidney", isCorrect: false },
89 | { text: "Stomach", isCorrect: false },
90 | ],
91 | },
92 | {
93 | text: "What is the name of the bond that joins amino acids together?",
94 | options: [
95 | { text: "Peptide bond", isCorrect: true },
96 | { text: "Ionic bond", isCorrect: false },
97 | { text: "Hydrogen bond", isCorrect: false },
98 | { text: "Glycosidic bond", isCorrect: false },
99 | ],
100 | },
101 | {
102 | text: "What is the term for organisms that produce their own food?",
103 | options: [
104 | { text: "Autotrophs", isCorrect: true },
105 | { text: "Heterotrophs", isCorrect: false },
106 | { text: "Parasites", isCorrect: false },
107 | { text: "Decomposers", isCorrect: false },
108 | ],
109 | },
110 | {
111 | text: "Which type of blood cell is primarily responsible for immunity?",
112 | options: [
113 | { text: "White blood cells", isCorrect: true },
114 | { text: "Red blood cells", isCorrect: false },
115 | { text: "Platelets", isCorrect: false },
116 | { text: "Plasma", isCorrect: false },
117 | ],
118 | },
119 | {
120 | text: "What is the function of ribosomes in a cell?",
121 | options: [
122 | { text: "Protein synthesis", isCorrect: true },
123 | { text: "Lipid storage", isCorrect: false },
124 | { text: "Energy production", isCorrect: false },
125 | { text: "DNA replication", isCorrect: false },
126 | ],
127 | },
128 | {
129 | text: "What is the basic structural unit of all living organisms?",
130 | options: [
131 | { text: "Cell", isCorrect: true },
132 | { text: "Tissue", isCorrect: false },
133 | { text: "Organ", isCorrect: false },
134 | { text: "Molecule", isCorrect: false },
135 | ],
136 | },
137 | ];
138 |
139 | module.exports = biologyQuestions;
140 |
--------------------------------------------------------------------------------
/components/UserStats.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useUser } from "@clerk/nextjs";
3 | import React from "react";
4 | import Loader from "./Loader";
5 | import Image from "next/image";
6 | import { formatTime } from "@/utils/formatTime";
7 | import { checkAbc, crosshairs } from "@/utils/Icons";
8 | import CategoryBarChart from "./CategoryBarChart";
9 | import {
10 | Table,
11 | TableBody,
12 | TableCell,
13 | TableHead,
14 | TableHeader,
15 | TableRow,
16 | } from "./ui/table";
17 | import { ICategoryStats } from "@/types/types";
18 |
19 | function UserStats({ userStats }: any) {
20 | const { user, isLoaded } = useUser();
21 |
22 | if (!isLoaded) {
23 | return ;
24 | }
25 |
26 | // get the most recent attempt date
27 | const recentAttemptDate = userStats?.categoryStats.reduce(
28 | (acc: any, curr: any) => {
29 | const currentDate = new Date(curr.lastAttempt);
30 | return currentDate > acc ? currentDate : acc;
31 | },
32 | new Date(0)
33 | );
34 |
35 | const totalAttempts = userStats?.categoryStats.reduce(
36 | (acc: number, curr: any) => acc + curr.attempts,
37 | 0
38 | );
39 |
40 | const totalCompleted = userStats?.categoryStats.reduce(
41 | (acc: number, curr: any) => acc + curr.completed,
42 | 0
43 | );
44 | // show the 2 most recent attempts
45 | const latestStats = userStats?.categoryStats
46 | .slice(-2)
47 | .sort((a: any, b: any) => {
48 | return (
49 | new Date(b.lastAttempt).getTime() - new Date(a.lastAttempt).getTime()
50 | );
51 | });
52 |
53 | console.log("User stats:", userStats.categoryStats);
54 |
55 | return (
56 |
57 |
58 |
65 |
66 |
67 |
68 | Overview
69 |
70 | A summary of your recent activity and performance
71 |
72 |
73 |
74 |
75 |
76 | {user?.firstName}
77 | Recent Attempt
78 |
79 | {formatTime(recentAttemptDate)}
80 |
81 |
82 |
83 |
84 | {crosshairs}
85 |
86 | Total Attempts
87 | {totalAttempts}
88 |
89 |
90 |
91 |
92 | {checkAbc}
93 |
94 | Total Completed
95 | {totalCompleted}
96 |
97 |
98 |
99 |
100 |
101 | {latestStats?.map((category: any) => (
102 |
103 | ))}
104 |
105 |
106 |
107 | Detailed Category Stats
108 |
109 | Breakdown of performance by category
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Category
118 | Attempts
119 | Completed
120 | Average Score
121 | Last Attempt
122 |
123 |
124 |
125 | {userStats?.categoryStats.map((category: ICategoryStats) => (
126 |
127 |
128 | {category.category.name}
129 |
130 | {category.attempts}
131 | {category.completed}
132 |
133 | {category.averageScore !== null
134 | ? category.averageScore.toFixed(2)
135 | : "N/A"}
136 |
137 | {formatTime(category.lastAttempt)}
138 |
139 | ))}
140 |
141 |
142 |
143 |
144 | );
145 | }
146 |
147 | export default UserStats;
148 |
--------------------------------------------------------------------------------
/app/quiz/setup/[quizId]/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Button } from "@/components/ui/button";
3 | import { Input } from "@/components/ui/input";
4 | import { Label } from "@/components/ui/label";
5 | import {
6 | Select,
7 | SelectContent,
8 | SelectItem,
9 | SelectTrigger,
10 | SelectValue,
11 | } from "@/components/ui/select";
12 | import { useGlobalContext } from "@/context/globalContext";
13 | import { play } from "@/utils/Icons";
14 | import axios from "axios";
15 | import { useRouter } from "next/navigation";
16 | import React, { useEffect } from "react";
17 | import toast from "react-hot-toast";
18 |
19 | function page() {
20 | const router = useRouter();
21 | const { quizSetup, setQuizSetup, selectedQuiz, setFilteredQuestions } =
22 | useGlobalContext();
23 |
24 | useEffect(() => {
25 | if (!selectedQuiz) {
26 | router.push("/");
27 | }
28 | }, [selectedQuiz, router]);
29 |
30 | useEffect(() => {
31 | const filteredQuestions = selectedQuiz?.questions.filter(
32 | (q: { difficulty: string }) => {
33 | return (
34 | !quizSetup?.difficulty ||
35 | quizSetup?.difficulty === "unspecified" ||
36 | q?.difficulty.toLowerCase() === quizSetup?.difficulty.toLowerCase()
37 | );
38 | }
39 | );
40 |
41 | setFilteredQuestions(filteredQuestions);
42 | }, [quizSetup]);
43 |
44 | const handleQuestionChange = (e: React.ChangeEvent) => {
45 | const value = parseInt(e.target.value, 10);
46 | const maxQuestions = selectedQuiz?.questions.length || 1;
47 |
48 | const newCount =
49 | isNaN(value) || value < 1 ? 1 : Math.min(value, maxQuestions);
50 |
51 | setQuizSetup((prev: {}) => ({ ...prev, questionCount: newCount }));
52 | };
53 |
54 | const handleDifficultyChange = (difficulty: string) => {
55 | setQuizSetup((prev: {}) => ({ ...prev, difficulty }));
56 |
57 | console.log("Difficulty: ", difficulty);
58 | };
59 |
60 | const startQuiz = async () => {
61 | const selectedQuestions = selectedQuiz?.questions
62 | .slice(0, quizSetup?.questionCount)
63 | .filter((q: { difficulty: string }) => {
64 | return (
65 | quizSetup?.difficulty ||
66 | q.difficulty?.toLowerCase() ===
67 | selectedQuiz?.difficulty?.toLowerCase()
68 | );
69 | });
70 |
71 | if (selectedQuestions.length > 0) {
72 | //update the db for quiz attempt start
73 |
74 | try {
75 | await axios.post("/api/user/quiz/start", {
76 | categoryId: selectedQuiz?.categoryId,
77 | quizId: selectedQuiz?.id,
78 | });
79 | } catch (error) {
80 | console.log("Error starting quiz: ", error);
81 | }
82 |
83 | // pushh to the quiz page
84 | router.push("/quiz");
85 | } else {
86 | toast.error("No questions found for the selected criteria");
87 | }
88 | };
89 |
90 | return (
91 |
92 |
93 | Quiz Setup
94 |
95 |
96 |
97 |
100 |
108 |
109 |
110 |
111 |
114 |
115 |
126 |
127 |
128 |
129 |
132 |
133 |
147 |
148 |
149 |
150 |
151 |
152 |
159 |
160 |
161 | );
162 | }
163 |
164 | export default page;
165 |
--------------------------------------------------------------------------------
/components/ui/select.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SelectPrimitive from "@radix-ui/react-select"
5 | import { Check, ChevronDown, ChevronUp } from "lucide-react"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const Select = SelectPrimitive.Root
10 |
11 | const SelectGroup = SelectPrimitive.Group
12 |
13 | const SelectValue = SelectPrimitive.Value
14 |
15 | const SelectTrigger = React.forwardRef<
16 | React.ElementRef,
17 | React.ComponentPropsWithoutRef
18 | >(({ className, children, ...props }, ref) => (
19 | span]:line-clamp-1",
23 | className
24 | )}
25 | {...props}
26 | >
27 | {children}
28 |
29 |
30 |
31 |
32 | ))
33 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
34 |
35 | const SelectScrollUpButton = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 |
48 |
49 | ))
50 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
51 |
52 | const SelectScrollDownButton = React.forwardRef<
53 | React.ElementRef,
54 | React.ComponentPropsWithoutRef
55 | >(({ className, ...props }, ref) => (
56 |
64 |
65 |
66 | ))
67 | SelectScrollDownButton.displayName =
68 | SelectPrimitive.ScrollDownButton.displayName
69 |
70 | const SelectContent = React.forwardRef<
71 | React.ElementRef,
72 | React.ComponentPropsWithoutRef
73 | >(({ className, children, position = "popper", ...props }, ref) => (
74 |
75 |
86 |
87 |
94 | {children}
95 |
96 |
97 |
98 |
99 | ))
100 | SelectContent.displayName = SelectPrimitive.Content.displayName
101 |
102 | const SelectLabel = React.forwardRef<
103 | React.ElementRef,
104 | React.ComponentPropsWithoutRef
105 | >(({ className, ...props }, ref) => (
106 |
111 | ))
112 | SelectLabel.displayName = SelectPrimitive.Label.displayName
113 |
114 | const SelectItem = React.forwardRef<
115 | React.ElementRef,
116 | React.ComponentPropsWithoutRef
117 | >(({ className, children, ...props }, ref) => (
118 |
126 |
127 |
128 |
129 |
130 |
131 | {children}
132 |
133 | ))
134 | SelectItem.displayName = SelectPrimitive.Item.displayName
135 |
136 | const SelectSeparator = React.forwardRef<
137 | React.ElementRef,
138 | React.ComponentPropsWithoutRef
139 | >(({ className, ...props }, ref) => (
140 |
145 | ))
146 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName
147 |
148 | export {
149 | Select,
150 | SelectGroup,
151 | SelectValue,
152 | SelectTrigger,
153 | SelectContent,
154 | SelectLabel,
155 | SelectItem,
156 | SelectSeparator,
157 | SelectScrollUpButton,
158 | SelectScrollDownButton,
159 | }
160 |
--------------------------------------------------------------------------------
/app/quiz/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Button } from "@/components/ui/button";
3 | import { useGlobalContext } from "@/context/globalContext";
4 | import { IOption, IQuestion, IResponse } from "@/types/types";
5 | import { flag, next } from "@/utils/Icons";
6 | import axios from "axios";
7 | import { useRouter } from "next/navigation";
8 | import React, { useEffect } from "react";
9 | import toast from "react-hot-toast";
10 |
11 | function page() {
12 | const {
13 | selectedQuiz,
14 | quizSetup,
15 | setQuizSetup,
16 | setQuizResponses,
17 | filteredQuestions,
18 | } = useGlobalContext();
19 | const router = useRouter();
20 |
21 | const [currentIndex, setCurrentIndex] = React.useState(0);
22 | const [activeQuestion, setActiveQuestion] = React.useState(null) as any;
23 | const [responses, setResponses] = React.useState([]);
24 | const [shuffledOptions, setShuffledOptions] = React.useState([]);
25 | const [shuffledQuestions, setShuffledQuestions] = React.useState(
26 | []
27 | );
28 |
29 | if (!selectedQuiz) {
30 | router.push("/");
31 | return null;
32 | }
33 |
34 | // shuffle questions when the quiz is started
35 | useEffect(() => {
36 | const allQuestions = filteredQuestions.slice(0, quizSetup?.questionCount);
37 |
38 | setShuffledQuestions(shuffleArray([...allQuestions]));
39 | }, [selectedQuiz, quizSetup]);
40 |
41 | // suffle options when the active question changes
42 | useEffect(() => {
43 | if (shuffledQuestions[currentIndex]) {
44 | // shuffle options for the current question
45 | setShuffledOptions(
46 | shuffleArray([...shuffledQuestions[currentIndex].options])
47 | );
48 | }
49 | }, [shuffledQuestions, currentIndex]);
50 |
51 | // Fisher-Yates Shuffle Algorithm
52 | const shuffleArray = (array: any[]) => {
53 | for (let i = array.length - 1; i > 0; --i) {
54 | // generate a random index between 0 and i
55 | const j = Math.floor(Math.random() * (i + 1));
56 |
57 | // swap elements --> destructuring assignment
58 | [array[i], array[j]] = [array[j], array[i]];
59 | }
60 |
61 | return array;
62 | };
63 |
64 | const handleActiveQuestion = (option: any) => {
65 | if (!shuffledQuestions[currentIndex]) return;
66 |
67 | const response = {
68 | questionId: shuffledQuestions[currentIndex].id,
69 | optionId: option.id,
70 | isCorrect: option.isCorrect,
71 | };
72 |
73 | setResponses((prev) => {
74 | // check if the response already exists
75 | const existingIndex = prev.findIndex((res) => {
76 | return res.questionId === response.questionId;
77 | });
78 |
79 | // update the response if it exists
80 |
81 | if (existingIndex !== -1) {
82 | // update the response
83 | const updatedResponses = [...prev];
84 | updatedResponses[existingIndex] = response;
85 |
86 | return updatedResponses;
87 | } else {
88 | return [...prev, response];
89 | }
90 | });
91 |
92 | // set the active question
93 | setActiveQuestion(option);
94 | };
95 |
96 | const handleNextQuestion = () => {
97 | if (currentIndex < shuffledQuestions.length - 1) {
98 | setCurrentIndex((prev) => prev + 1);
99 |
100 | // reset the active question
101 | setActiveQuestion(null);
102 | } else {
103 | router.push("/quiz/results");
104 | }
105 | };
106 |
107 | const handleFinishQuiz = async () => {
108 | setQuizResponses(responses);
109 |
110 | const score = responses.filter((res) => res.isCorrect).length;
111 |
112 | try {
113 | const res = await axios.post("/api/user/quiz/finish", {
114 | categoryId: selectedQuiz.categoryId,
115 | quizId: selectedQuiz.id,
116 | score,
117 | responses,
118 | });
119 |
120 | console.log("Quiz finished:", res.data);
121 | } catch (error) {
122 | console.log("Error finishing quiz:", error);
123 | }
124 |
125 | setQuizSetup({
126 | questionCount: 1,
127 | category: null,
128 | difficulty: null,
129 | });
130 |
131 | router.push("/results");
132 | };
133 |
134 | return (
135 |
136 | {shuffledQuestions[currentIndex] ? (
137 |
138 |
139 |
140 | Question: {currentIndex + 1} /{" "}
141 | {shuffledQuestions.length}
142 |
143 |
144 | {shuffledQuestions[currentIndex].text}
145 |
146 |
147 |
148 |
149 | {shuffledOptions.map((option, index) => (
150 |
164 | ))}
165 |
166 |
167 | ) : (
168 | No questions found for this quiz
169 | )}
170 |
171 |
172 |
201 |
202 |
203 | );
204 | }
205 |
206 | export default page;
207 |
--------------------------------------------------------------------------------
/data/programmingQuestions.js:
--------------------------------------------------------------------------------
1 | const programmingQuestions = [
2 | {
3 | text: "What does the acronym OOP stand for?",
4 | options: [
5 | { text: "Object-Oriented Programming", isCorrect: true },
6 | { text: "Objective-Oriented Programming", isCorrect: false },
7 | { text: "Operation-Oriented Programming", isCorrect: false },
8 | { text: "Object-Oriented Process", isCorrect: false },
9 | ],
10 | difficulty: "Easy",
11 | },
12 | {
13 | text: "Which language is primarily used for web development?",
14 | options: [
15 | { text: "JavaScript", isCorrect: true },
16 | { text: "Python", isCorrect: false },
17 | { text: "C++", isCorrect: false },
18 | { text: "Java", isCorrect: false },
19 | ],
20 | difficulty: "Easy",
21 | },
22 | {
23 | text: "What is the output of `console.log(typeof null)` in JavaScript?",
24 | options: [
25 | { text: "object", isCorrect: true },
26 | { text: "null", isCorrect: false },
27 | { text: "undefined", isCorrect: false },
28 | { text: "string", isCorrect: false },
29 | ],
30 | difficulty: "Medium",
31 | },
32 | {
33 | text: "Which method is used to add an element to the end of an array in JavaScript?",
34 | options: [
35 | { text: "push()", isCorrect: true },
36 | { text: "pop()", isCorrect: false },
37 | { text: "shift()", isCorrect: false },
38 | { text: "unshift()", isCorrect: false },
39 | ],
40 | difficulty: "Easy",
41 | },
42 | {
43 | text: "What is the primary purpose of the `virtual` keyword in C++?",
44 | options: [
45 | { text: "To enable polymorphism", isCorrect: true },
46 | { text: "To declare a global variable", isCorrect: false },
47 | { text: "To optimize memory", isCorrect: false },
48 | { text: "To create an abstract class", isCorrect: false },
49 | ],
50 | difficulty: "Medium",
51 | },
52 | {
53 | text: "What is the time complexity of binary search?",
54 | options: [
55 | { text: "O(log n)", isCorrect: true },
56 | { text: "O(n)", isCorrect: false },
57 | { text: "O(1)", isCorrect: false },
58 | { text: "O(n log n)", isCorrect: false },
59 | ],
60 | difficulty: "Medium",
61 | },
62 | {
63 | text: "Which programming paradigm focuses on functions and immutability?",
64 | options: [
65 | { text: "Functional Programming", isCorrect: true },
66 | { text: "Object-Oriented Programming", isCorrect: false },
67 | { text: "Procedural Programming", isCorrect: false },
68 | { text: "Logic Programming", isCorrect: false },
69 | ],
70 | difficulty: "Medium",
71 | },
72 | {
73 | text: "Which of the following is a valid way to declare a variable in Python?",
74 | options: [
75 | { text: "variable_name = 10", isCorrect: true },
76 | { text: "int variable_name = 10;", isCorrect: false },
77 | { text: "let variable_name = 10;", isCorrect: false },
78 | { text: "var variable_name = 10;", isCorrect: false },
79 | ],
80 | difficulty: "Easy",
81 | },
82 | {
83 | text: "What does the `finally` block do in a try-catch-finally structure?",
84 | options: [
85 | { text: "Executes code regardless of an exception", isCorrect: true },
86 | { text: "Handles the exception", isCorrect: false },
87 | { text: "Rethrows the exception", isCorrect: false },
88 | { text: "Prevents exceptions from propagating", isCorrect: false },
89 | ],
90 | difficulty: "Medium",
91 | },
92 | {
93 | text: "Which of the following is NOT a primitive data type in Java?",
94 | options: [
95 | { text: "String", isCorrect: true },
96 | { text: "int", isCorrect: false },
97 | { text: "boolean", isCorrect: false },
98 | { text: "float", isCorrect: false },
99 | ],
100 | difficulty: "Medium",
101 | },
102 | {
103 | text: "Which keyword in JavaScript is used to declare a constant variable?",
104 | options: [
105 | { text: "const", isCorrect: true },
106 | { text: "var", isCorrect: false },
107 | { text: "let", isCorrect: false },
108 | { text: "constant", isCorrect: false },
109 | ],
110 | difficulty: "Easy",
111 | },
112 | {
113 | text: "What is the default value of a reference type in Java?",
114 | options: [
115 | { text: "null", isCorrect: true },
116 | { text: "undefined", isCorrect: false },
117 | { text: "0", isCorrect: false },
118 | { text: "empty string", isCorrect: false },
119 | ],
120 | difficulty: "Medium",
121 | },
122 | {
123 | text: "Which programming language is known for its simplicity and readability?",
124 | options: [
125 | { text: "Python", isCorrect: true },
126 | { text: "C++", isCorrect: false },
127 | { text: "Assembly", isCorrect: false },
128 | { text: "Perl", isCorrect: false },
129 | ],
130 | difficulty: "Easy",
131 | },
132 | {
133 | text: "What does the `super` keyword do in Java?",
134 | options: [
135 | { text: "Accesses the parent class constructor", isCorrect: true },
136 | { text: "Creates a new instance", isCorrect: false },
137 | { text: "References a subclass", isCorrect: false },
138 | { text: "Accesses a static method", isCorrect: false },
139 | ],
140 | difficulty: "Hard",
141 | },
142 | {
143 | text: "What does the term 'closure' refer to in JavaScript?",
144 | options: [
145 | {
146 | text: "A function retaining access to its lexical scope",
147 | isCorrect: true,
148 | },
149 | { text: "A function that is immediately invoked", isCorrect: false },
150 | { text: "A function without a return statement", isCorrect: false },
151 | { text: "A function with no parameters", isCorrect: false },
152 | ],
153 | difficulty: "Hard",
154 | },
155 | {
156 | text: "Which of these is a valid way to create a new thread in Java?",
157 | options: [
158 | { text: "Extend Thread class", isCorrect: true },
159 | { text: "Implement Runnable", isCorrect: true },
160 | { text: "Call thread()", isCorrect: false },
161 | { text: "Use the ThreadFactory", isCorrect: true },
162 | ],
163 | difficulty: "Hard",
164 | },
165 | {
166 | text: "What is the difference between `==` and `===` in JavaScript?",
167 | options: [
168 | { text: "`===` checks both value and type", isCorrect: true },
169 | { text: "`==` checks only value", isCorrect: true },
170 | { text: "`==` and `===` are identical", isCorrect: false },
171 | { text: "`===` checks only type", isCorrect: false },
172 | ],
173 | difficulty: "Medium",
174 | },
175 | {
176 | text: "Which of the following is an immutable object in Java?",
177 | options: [
178 | { text: "String", isCorrect: true },
179 | { text: "ArrayList", isCorrect: false },
180 | { text: "HashMap", isCorrect: false },
181 | { text: "StringBuilder", isCorrect: false },
182 | ],
183 | difficulty: "Medium",
184 | },
185 | {
186 | text: "What is the output of `5 + '5'` in JavaScript?",
187 | options: [
188 | { text: "55", isCorrect: true },
189 | { text: "10", isCorrect: false },
190 | { text: "NaN", isCorrect: false },
191 | { text: "Error", isCorrect: false },
192 | ],
193 | difficulty: "Medium",
194 | },
195 | {
196 | text: "Which of these is a strongly typed programming language?",
197 | options: [
198 | { text: "Java", isCorrect: true },
199 | { text: "JavaScript", isCorrect: false },
200 | { text: "Python", isCorrect: false },
201 | { text: "Ruby", isCorrect: false },
202 | ],
203 | difficulty: "Easy",
204 | },
205 | ];
206 |
207 | module.exports = programmingQuestions;
208 |
--------------------------------------------------------------------------------
/public/categories/image--timeline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/ui/chart.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as RechartsPrimitive from "recharts"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | // Format: { THEME_NAME: CSS_SELECTOR }
9 | const THEMES = { light: "", dark: ".dark" } as const
10 |
11 | export type ChartConfig = {
12 | [k in string]: {
13 | label?: React.ReactNode
14 | icon?: React.ComponentType
15 | } & (
16 | | { color?: string; theme?: never }
17 | | { color?: never; theme: Record }
18 | )
19 | }
20 |
21 | type ChartContextProps = {
22 | config: ChartConfig
23 | }
24 |
25 | const ChartContext = React.createContext(null)
26 |
27 | function useChart() {
28 | const context = React.useContext(ChartContext)
29 |
30 | if (!context) {
31 | throw new Error("useChart must be used within a ")
32 | }
33 |
34 | return context
35 | }
36 |
37 | const ChartContainer = React.forwardRef<
38 | HTMLDivElement,
39 | React.ComponentProps<"div"> & {
40 | config: ChartConfig
41 | children: React.ComponentProps<
42 | typeof RechartsPrimitive.ResponsiveContainer
43 | >["children"]
44 | }
45 | >(({ id, className, children, config, ...props }, ref) => {
46 | const uniqueId = React.useId()
47 | const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
48 |
49 | return (
50 |
51 |
60 |
61 |
62 | {children}
63 |
64 |
65 |
66 | )
67 | })
68 | ChartContainer.displayName = "Chart"
69 |
70 | const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
71 | const colorConfig = Object.entries(config).filter(
72 | ([, config]) => config.theme || config.color
73 | )
74 |
75 | if (!colorConfig.length) {
76 | return null
77 | }
78 |
79 | return (
80 | |