Skip to content

Repository files navigation

🚀 LearnQuest

A gamified, adaptive learning web app for school kids (grades 5–11) covering Mathematics and Science. Built with React 19 + TypeScript + Vite. All progress is stored in the browser — no backend required — with an optional, free, dependency‑free cloud sync.

  • Subject → Category → Chapter series flow with lessons + practice
  • Adaptive difficulty (parent‑controlled speed) and non‑repeating questions
  • Single & multi‑answer questions with clear, kid‑friendly selection UI
  • Parent mode (unlock code 062026): progress charts, learner settings, AI coach, and Backup & Sync
  • Light bundle (~150 KB gzip) — deploys on the Vercel free tier

Develop

npm install
npm run dev        # http://localhost:5173
npm run build      # type-check + production build to dist/
npm run preview    # serve the production build locally

Saving & moving progress

Progress lives in each browser's localStorage, so it is per‑device. Deploying a new version does not erase it. To move or protect progress there are two tools, both in Parent mode → 💾 Backup.

Option 1 — Backup file (offline, no setup)

  • Download backup writes a single learnquest-backup-YYYY-MM-DD.json containing every learner's progress. Keep it in Drive, email, or a USB stick.
  • Restore loads that file on another laptop. Choose:
    • Merge — keep learners already on this laptop, add/update from the file (newest copy of each learner wins, so nothing newer is lost).
    • Replace — discard local learners and use only the file.

Option 2 — Sync code (auto‑sync across laptops, no logins)

Each laptop is linked with one short code (e.g. MANGO-7421). Progress then syncs automatically: it pulls on load and pushes ~1.5 s after each change and when the tab is hidden. Merges are newest‑wins per learner, so moving between laptops never loses newer progress.

The sync code is the only thing guarding a learner's data blob — fine for school progress, but don't post codes publicly.

One‑time Supabase setup

  1. Create a free project at https://supabase.comNew project.

  2. In SQL Editor → New query, run:

    create table if not exists public.sync_blobs (
      code text primary key,
      data text not null,
      updated_at timestamptz not null default now()
    );
    
    alter table public.sync_blobs enable row level security;
    
    create policy "anon read"   on public.sync_blobs for select using (true);
    create policy "anon insert" on public.sync_blobs for insert with check (true);
    create policy "anon update" on public.sync_blobs for update using (true) with check (true);
  3. In Project Settings → API, copy the Project URL and the anon public key (the eyJ... one — not service_role).

Connect the app to Supabase (pick one)

  • Per browser: Parent mode → 💾 Backup → section 3, paste the Project URL + anon key, then Save cloud settings.

  • For everyone (recommended for a shared deploy): set environment variables and redeploy (see below). The UI then skips the paste step automatically.

    Variable Value
    VITE_SUPABASE_URL https://xxxx.supabase.co
    VITE_SUPABASE_ANON_KEY the eyJ... anon public key

Daily use

  • Laptop A: Backup → ✨ Create a new sync code → write down the code.
  • Laptop B: Backup → enter the code under Connect with a code.
  • From then on both laptops auto‑sync. Use Stop auto‑sync to unlink a laptop (local progress is kept).

The Supabase anon public key is designed to be shipped in client apps, so exposing it in the bundle or env vars is expected and safe.


Deploy to Vercel

This is a static Vite app, so deployment is simple.

  1. Push the repo to GitHub and Import it in Vercel (framework preset: Vite).
    • Build command: npm run build
    • Output directory: dist
  2. (Optional, for shared cloud sync) add the two VITE_SUPABASE_* env vars under Project → Settings → Environment Variables, then Redeploy so they are baked into the build.
  3. Every push redeploys. This does not clear users' saved progress — that lives in each visitor's browser.

vercel.json is included for SPA routing.


Project layout

src/
  components/    UI screens (Dashboard, GameScreen, ParentArea, BackupPanel, …)
  curriculum/    Question/lesson content by grade & subject + registry (index.ts)
  data/          store.ts (localStorage + backup), cloudSync.ts (sync code)
  engine/        adaptive.ts (difficulty, XP, progress)
  ai/            optional AI coach hooks
  types.ts       shared data model

Feature reference

  • Grades: 5, 6, 7, 8, 9, 10, 11. Grade union + GRADES array live in src/types.ts; the dashboard grade picker reads GRADES, so adding a grade is a one-line change plus curriculum content.
  • Subjects: Mathematics (math, 🔢) and Science (science, 🔬), defined in SUBJECTS (src/curriculum/index.ts).
  • Content flow: Subject → Category (e.g. "Algebra · Grade 9") → Chapter (a lesson + a practice round). Lessons render in LessonScreen, practice in GameScreen.
  • Question types: single-answer and multi-answer (multi: true, answers: string[]). Multi questions require the selected set to exactly match answers. Generators are parameterized so questions don't repeat within a session (anti-repeat tracking in GameScreen).
  • Answer UX: selection is amber before submit; only after submitting do correct answers turn green and wrong picks red. On-screen instructions, per-choice tooltips, ☐/☑/○/◉ marks, and a "Select all that apply" badge for multi questions.
  • Adaptive difficulty: engine/adaptive.ts raises/lowers difficulty on streaks; parent-set speed (gentle/normal/fast) changes the streak threshold (4/3/2).
  • Gamification: XP, levels, day-streak, badges, totals (GameState).
  • Parent mode: unlocked with code 062026 (ParentGate.tsx). Tabs: 📊 Progress (per-topic charts), ⚙️ Learners (add/edit learners, grade & speed), 🤖 AI Coach, 💾 Backup (file backup + sync code).
  • Optional AI Coach: plug in any OpenAI-compatible API key (stored only in the browser) for richer hints/feedback; falls back to built-in hints otherwise.

Data model (localStorage)

Key Holds
learnquest.children.v1 all learner states (Record<id, ChildState>)
learnquest.activeChild.v1 id of the currently selected learner
learnquest.sb.url / learnquest.sb.anon Supabase config (if pasted in UI)
learnquest.syncCode this laptop's sync code (if connected)
  • ChildState = { profile, settings, game, subjects, lastSavedAt }. lastSavedAt powers newest-wins merging for backup/cloud restore.
  • store.ts migrate() upgrades older saved profiles (e.g. backfills grade and settings.adaptiveSpeed) so existing users never lose progress on update.
  • save() emits a learnquest:changed event; cloud sync listens to it to push.

Extending the curriculum

Content is split into registry files in src/curriculum/, all spread into CATEGORIES in index.ts:

File Exports Chapter id prefix
math.ts MATH_CATEGORIES m5- m8- m10-
math_more.ts MATH_MORE mx-
math_grades.ts MATH_GRADES (grades 6/7/9/11) mg-
science.ts SCIENCE_CATEGORIES s5- s8- s10-
science_more.ts SCIENCE_MORE sx-
science_grades.ts SCIENCE_GRADES (grades 6/7/9/11) sg-

To add content:

  1. Add Category objects (with chapters) to the relevant file, using generator helpers from curriculum/util.ts:
    • build(...) — single-answer multiple choice
    • numericMC(...) — numeric single-answer
    • buildMulti(...)multi-answer (correct answers must never appear in distractors)
  2. Keep chapter ids globally unique with the prefix above — getChapter() resolves chapters by scanning all categories.
  3. If a new file is created, import it and spread it into CATEGORIES in index.ts.
  4. Verify: npx tsc --noEmit then npm run build. (Type-check validates every file; a quick smoke loop over CATEGORIES can assert each answer ∈ choices and that multi answers ⊆ choices and are disjoint from distractors.)

Build history

  • R1–R2: grade-based restructure; curriculum split; adaptive engine; parent Learners tab; Vercel config.
  • R3–R4: expanded curriculum (*_more.ts); fixed select-then-submit & question repetition; dynamic round size; mistake correction; grade dropdown; parent gate changed to unlock code 062026.
  • R5: grades 6/7/9/11; multi-answer questions + amber/green-red answer UX + on-screen selection instructions.
  • R6: progress saving — Backup file (export/import, newest-wins merge) and sync code cloud sync (dependency-free Supabase REST); README + GitHub.

Ideas for future enhancements

  • More subjects (the original vision: English, languages, Computer Science, Robotics, Health Sciences) — each is a new Subject + curriculum files.
  • Account-based sync (Option 3) on top of the same Supabase backend.
  • Spaced-repetition revision scheduling; printable progress reports.
  • Per-chapter target dates surfaced as reminders.

About

Learn Quest application

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages