4import { useAuth } from "../../hooks/useAuth";
5import { useExamService } from "../../hooks/useExamService";
6import { Attempt, Exam, Question, Answer } from "../../../shared/database/schema";
78interface QuestionWithAnswer extends Question {
offlineexamappTakeExam.tsx2 matches
4import { useAuth } from "../../hooks/useAuth";
5import { useExamService } from "../../hooks/useExamService";
6import { Exam, Question, Attempt } from "../../../shared/database/schema";
78const TakeExam: React.FC = () => {
128}));
129
130// Save answer to database
131if (attempt) {
132const currentQuestion = questions[currentQuestionIndex];
offlineexamappDashboard.tsx1 match
4import { useAuth } from "../../hooks/useAuth";
5import { useExamService } from "../../hooks/useExamService";
6import { Exam, Attempt } from "../../../shared/database/schema";
78const StudentDashboard: React.FC = () => {
offlineexamappRegister.tsx1 match
3import { useNavigate, Link } from "https://esm.sh/react-router-dom@6.20.1?deps=react@18.2.0";
4import { useAuth } from "../hooks/useAuth";
5import { UserRole } from "../../shared/database/schema";
67const Register: React.FC = () => {
offlineexamappuseExamService.ts2 matches
1import { useMemo } from "https://esm.sh/react@18.2.0";
2import { useDatabase } from "./useDatabase";
3import { ExamService } from "../services/examService";
45export const useExamService = () => {
6const { db, isInitialized } = useDatabase();
7
8const examService = useMemo(() => {
offlineexamappexamService.ts3 matches
5Attempt,
6Answer
7} from "../../shared/database/schema";
89/**
11*/
12export class ExamService {
13private db: IDBDatabase;
1415constructor(db: IDBDatabase) {
16this.db = db;
17}
offlineexamappuseDatabase.ts3 matches
1import { useContext } from "https://esm.sh/react@18.2.0";
2import { DatabaseContext } from "../contexts/DatabaseContext";
34export const useDatabase = () => {
5return useContext(DatabaseContext);
6};
offlineexamappAuthContext.tsx8 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { createContext, useState, useEffect } from "https://esm.sh/react@18.2.0";
3import { useDatabase } from "../hooks/useDatabase";
4import { User } from "../../shared/database/schema";
56interface AuthContextType {
2728export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
29const { db, isInitialized } = useDatabase();
30const [user, setUser] = useState<User | null>(null);
31const [isLoading, setIsLoading] = useState(true);
43const userData = JSON.parse(storedUser) as User;
44
45// Verify that the user still exists in the database
46if (db) {
47const transaction = db.transaction(["users"], "readonly");
53setUser(userData);
54} else {
55// User no longer exists in the database
56localStorage.removeItem("currentUser");
57}
79// Login function
80const login = async (username: string, password: string): Promise<void> => {
81if (!db) throw new Error("Database not initialized");
82
83setIsLoading(true);
150// Register function
151const register = async (userData: Omit<User, "id" | "createdAt" | "lastLogin">): Promise<void> => {
152if (!db) throw new Error("Database not initialized");
153
154setIsLoading(true);
242// Update user function
243const updateUser = async (userData: Partial<User>): Promise<void> => {
244if (!db || !user) throw new Error("Database not initialized or user not logged in");
245
246setIsLoading(true);
offlineexamappDatabaseContext.tsx26 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { createContext, useState, useEffect } from "https://esm.sh/react@18.2.0";
3import { initDatabase, seedData, DB_CONFIG } from "../../shared/database/schema";
45interface DatabaseContextType {
6db: IDBDatabase | null;
7isInitialized: boolean;
8error: Error | null;
9}
1011export const DatabaseContext = createContext<DatabaseContextType>({
12db: null,
13isInitialized: false,
15});
1617export const DatabaseProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
18const [db, setDb] = useState<IDBDatabase | null>(null);
19const [isInitialized, setIsInitialized] = useState(false);
20const [error, setError] = useState<Error | null>(null);
2122useEffect(() => {
23const initializeDatabase = async () => {
24try {
25// Initialize the database
26const database = await initDatabase();
27setDb(database);
28
29// Check if we need to seed the database
30const needsSeed = await checkIfNeedsSeed(database);
31
32if (needsSeed) {
33await seedDatabase(database);
34}
35
36setIsInitialized(true);
37} catch (err) {
38console.error("Failed to initialize database:", err);
39setError(err instanceof Error ? err : new Error(String(err)));
40}
41};
4243initializeDatabase();
4445return () => {
46// Close the database connection when the component unmounts
47if (db) {
48db.close();
51}, []);
5253// Check if the database needs to be seeded
54const checkIfNeedsSeed = async (database: IDBDatabase): Promise<boolean> => {
55return new Promise((resolve) => {
56const transaction = database.transaction(["users"], "readonly");
57const store = transaction.objectStore("users");
58const countRequest = store.count();
59
60countRequest.onsuccess = () => {
61// If there are no users, we need to seed the database
62resolve(countRequest.result === 0);
63};
70};
7172// Seed the database with initial data
73const seedDatabase = async (database: IDBDatabase): Promise<void> => {
74return new Promise((resolve, reject) => {
75const transaction = database.transaction(
76Object.keys(DB_CONFIG.stores),
77"readwrite"
79
80transaction.onerror = () => {
81reject(new Error("Failed to seed database"));
82};
83
113114return (
115<DatabaseContext.Provider value={{ db, isInitialized, error }}>
116{children}
117</DatabaseContext.Provider>
118);
119};
offlineexamappschema.ts5 matches
1/**
2* Database Schema for the Nigerian Mock Exam Application
3*
4* This file defines the IndexedDB schema and types for the application.
5*/
67// Database configuration
8export const DB_CONFIG = {
9name: "NigerianMockExamDB",
102}
103104// Database initialization function
105export async function initDatabase(): Promise<IDBDatabase> {
106return new Promise((resolve, reject) => {
107const request = indexedDB.open(DB_CONFIG.name, DB_CONFIG.version);
108
109request.onerror = (event) => {
110reject(new Error("Failed to open database"));
111};
112