Migrated from ideal-git.ddns.net
  • JavaScript 95.7%
  • Python 2.2%
  • Shell 1.4%
  • Dockerfile 0.3%
  • CSS 0.2%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
helmi ff3a6fff13 Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug
- useSpeechRecognition: fall back to local Whisper STT on browser SpeechRecognition 'network' errors (common on Android Chrome when Google's cloud speech service is unreachable) instead of silently failing
- New badges + activity_log tables; /progress/complete now awards a 1-3 star badge based on real accuracy, idempotent
- New GET /badges, GET /analytics/summary, GET /analytics/activity endpoints
- CertificateReveal component replaces the static trophy screen on unit completion with a printable certificate (name, unit, stars, date); wired into all 7 Unit*Page.jsx
- New /certificates (badge gallery) and /analytics (progress report: per-unit accuracy, 14-day activity trend) pages, linked from Dashboard header
- Fix real deploy bug: frontend-build mounted the static_files volume directly at /app/dist, so Docker only auto-seeded it once (on first-ever build) - every later rebuild silently kept serving stale files. Now builds into the image normally and explicitly copies into the volume on every container start.
- README roadmap updated to match actual state (units 2-7 were already built, roadmap was stale) + proposed Phase 4 module ideas
2026-09-14 11:38:13 +00:00
.github/skills/dyscalculia-courseware-designer Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
backend Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug 2026-09-14 11:38:13 +00:00
database Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug 2026-09-14 11:38:13 +00:00
docs Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
frontend Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug 2026-09-14 11:38:13 +00:00
nginx Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
releases Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
scripts Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
.env.example Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
.gitignore Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
docker-compose.prod.yml Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug 2026-09-14 11:38:13 +00:00
docker-compose.yml Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00
README.md Add certificate/badge system + analytics dashboard, fix Android Chrome talk + frontend deploy bug 2026-09-14 11:38:13 +00:00
STRUCTURE.md Initial commit -- D-NuRI (courseware for dyscalculia, space theme, Kapten Nuri) 2026-08-26 07:57:48 +00:00

D-NuRI — Aplikasi Pembelajaran Nombor Interaktif

Courseware berasaskan web untuk murid bermasalah dyscalculia (diskalkulia), bertemakan angkasa lepas dengan watak Kapten Nuri (parrot angkasawan).


Kandungan


Gambaran Keseluruhan

Perkara Details
Target Murid umur ~7 tahun dengan dyscalculia
Watak Kapten Nuri (SVG animated parrot astronaut)
Tema Angkasa lepas, meteor, roket
Audio Browser Web Speech API (TTS Bahasa Malaysia)
Auth Email + kata laluan (JWT 7 hari)
Platform Web + PWA (boleh install kat phone/tablet)

Tech Stack

Frontend

Package Versi Fungsi
React 18 UI framework
Vite 5 Build tool + dev server
Tailwind CSS 3 Styling
Framer Motion 11 Animasi (Kapten Nuri, meteor, transitions)
Zustand 4 State management (auth + progress)
React Router 6 Navigation
vite-plugin-pwa 0.20 Service worker + PWA manifest
Axios 1.7 HTTP client

Backend

Package Versi Fungsi
Node.js 20 LTS Runtime
Express 4 HTTP server
pg 8 PostgreSQL client
bcryptjs 2.4 Password hashing
jsonwebtoken 9 JWT auth
redis 4 Session cache (ready untuk future)

Infrastructure

Container Image Port
nginx nginx:alpine 80, 443
frontend node:20-alpine 5173 (dev)
backend node:20-alpine 4000
postgres postgres:16-alpine 5432
redis redis:7-alpine 6379

Struktur Projek

prestijProject/
├── docker-compose.yml          # Dev environment (6 containers)
├── docker-compose.prod.yml     # Production VPS deployment
├── .env.example                # Template env vars
├── .env                        # Actual env vars (jangan commit!)
│
├── frontend/
│   ├── Dockerfile
│   ├── package.json
│   ├── vite.config.js          # Vite + PWA + proxy config
│   ├── tailwind.config.js      # Custom space theme colors + animations
│   ├── index.html
│   └── src/
│       ├── App.jsx             # Router + PrivateRoute
│       ├── main.jsx
│       ├── index.css           # Tailwind base
│       │
│       ├── api/
│       │   └── client.js       # Axios instance + JWT interceptor
│       │
│       ├── store/
│       │   ├── authStore.js    # Zustand: token, user, logout
│       │   └── progressStore.js # Zustand: unit progress (persisted)
│       │
│       ├── hooks/
│       │   ├── useTTS.js       # Web Speech API wrapper (ms-MY)
│       │   └── useTimer.js     # Flash timer helper
│       │
│       ├── components/
│       │   ├── common/
│       │   │   ├── SpaceBackground.jsx  # 80 animated stars SVG
│       │   │   └── KaptenNuri.jsx       # Parrot SVG + speech bubble
│       │   │
│       │   └── units/unit1/
│       │       ├── Introduction.jsx     # Intro screen + TTS
│       │       ├── Interactive.jsx      # Touch meteors → colour change → number
│       │       ├── FlashTraining.jsx    # Flash timer + answer grid + score
│       │       └── exercises/
│       │           ├── Exercise1.jsx    # Corak rawak (random dots)
│       │           ├── Exercise2.jsx    # Garis nombor (number line)
│       │           ├── Exercise3.jsx    # Petak 10 (10-frame grid)
│       │           └── Exercise4.jsx    # Jari robot (robot fingers)
│       │
│       └── pages/
│           ├── Landing.jsx     # Home page
│           ├── Login.jsx       # Email login form
│           ├── Register.jsx    # Registration (Murid/Guru)
│           ├── Dashboard.jsx   # Unit cards + progress + unlock logic
│           └── Unit1Page.jsx   # Unit 1 orchestrator (intro→interactive→training→complete)
│
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
│       ├── index.js            # Express app entry
│       ├── config/
│       │   ├── db.js           # PostgreSQL pool
│       │   └── redis.js        # Redis client
│       ├── middleware/
│       │   └── authMiddleware.js # JWT verify
│       └── routes/
│           ├── auth.js         # POST /register, POST /login
│           └── progress.js     # GET /, POST /attempt, POST /complete
│
├── database/
│   └── init.sql                # PostgreSQL schema (auto-run on first start)
│
└── nginx/
    ├── Dockerfile
    ├── nginx.conf              # Dev: proxy ke Vite + backend
    └── nginx.prod.conf         # Prod: SSL, gzip, SPA fallback, cache headers

Setup & Jalankan (Dev)

Prerequisites

  • Node.js 20 LTS
  • Docker Desktop (WSL2 backend)
  • Git

Langkah-langkah

# 1. Clone & masuk folder
cd prestijProject

# 2. Copy env file
cp .env.example .env
# Edit .env — tukar password ikut suka

# 3. Build & run semua containers
docker compose up --build

# App akan available di:
# http://localhost       ← main app (via nginx)
# http://localhost:5173  ← frontend direct (Vite HMR)
# http://localhost:4000  ← backend API direct

Frontend Dev Tanpa Docker (preview sahaja)

cd frontend
npm install
npm run dev
# App kat http://localhost:5173
# Note: backend features (login/register) perlu Docker running

Docker Compose

Development (docker-compose.yml)

# 6 containers:
# nginx    → reverse proxy port 80
# frontend → Vite dev server port 5173 (hot reload)
# backend  → Node.js API port 4000
# postgres → Database port 5432
# redis    → Cache port 6379
# Start semua
docker compose up --build

# Start background
docker compose up -d

# Stop
docker compose down

# Tengok logs
docker compose logs -f backend
docker compose logs -f postgres

# Reset database (CAREFUL — delete all data)
docker compose down -v
docker compose up --build

Production (docker-compose.prod.yml)

# Build frontend as static files, serve via nginx
docker compose -f docker-compose.prod.yml up -d --build

Deploy ke VPS (Prod)

Requirements VPS

  • Ubuntu 22.04 / 24.04
  • Min 1GB RAM (2GB recommended)
  • Docker + Docker Compose installed
  • Domain name (optional, boleh guna IP terus)

Step-by-step

# 1. SSH masuk VPS
ssh root@<VPS_IP>

# 2. Install Docker
curl -fsSL https://get.docker.com | sh
apt install docker-compose-plugin -y

# 3. Clone projek ke VPS
git clone <repo-url> /opt/dnuri
cd /opt/dnuri

# 4. Setup environment
cp .env.example .env
nano .env   # Tukar semua password!

# 5. SSL certificate (Let's Encrypt)
# Letak cert.pem dan key.pem dalam folder ssl/

# 6. Deploy
docker compose -f docker-compose.prod.yml up -d --build

# 7. Verify running
docker compose -f docker-compose.prod.yml ps
curl http://localhost/api/health

Environment Variables (Production)

POSTGRES_USER=dnuri_user
POSTGRES_PASSWORD=<strong-password-min-16-chars>
POSTGRES_DB=dnuri_db
JWT_SECRET=<random-32-char-string>
JWT_REFRESH_SECRET=<random-32-char-string>

Generate random secrets:

openssl rand -base64 32

5 Unit Pembelajaran

Unit Tajuk Status Kemahiran
1 Pengamatan Kuantiti ✅ Siap Subitizing 1–6 tanpa mengira
2 Kepekaan Nombor 🔒 Belum build Perbandingan "lebih banyak"
3 Item Padanan 🔒 Belum build 1-to-1 matching, sama banyak
4 Penghitungan Titik 🔒 Belum build Kira titik, simbol 1–10
5 Perbandingan Nombor 🔒 Belum build Mana lebih besar (2 angka)

Unit 1 — Pengamatan Kuantiti (Subitizing)

Murid dilatih mengecam kuantiti 1–6 secara spontan dalam masa kurang 3 saat tanpa mengira satu-per-satu.

3 Fasa:

  1. Pengenalan — Kapten Nuri perkenalkan diri, TTS auto-play, butang roket
  2. Interaktif — Sentuh meteor satu-satu → tukar warna → nombor muncul
  3. Latihan Kilat — 4 jenis latihan dengan flash timer 2 saat:
    • Exercise 1: Corak rawak (random meteor pattern)
    • Exercise 2: Garis nombor (number line dots)
    • Exercise 3: Petak 10 (10-frame grid)
    • Exercise 4: Jari robot (robot finger hands, 1–6)

Unlock Logic: Unit N akan unlock apabila Unit N-1 completed.


API Reference

Base URL: http://localhost/api (dev) atau https://domain.com/api (prod)

Auth

POST /auth/register
Body: { name, email, password, role: "student"|"teacher" }
Response: { token, user: { id, name, email, role } }

POST /auth/login
Body: { email, password }
Response: { token, user: { id, name, email, role } }

Progress (requires Bearer token)

GET /progress
Response: [ { id, unit_id, exercise, correct_count, attempt_count, completed } ]

POST /progress/attempt
Body: { unit_id, exercise, correct: true|false }
Response: { ok: true }

POST /progress/complete
Body: { unit_id }
Response: { ok: true }

GET /health
Response: { status: "ok", service: "D-NuRI API" }

Database Schema

-- Users table
CREATE TABLE users (
  id            SERIAL PRIMARY KEY,
  name          VARCHAR(120) NOT NULL,
  email         VARCHAR(255) NOT NULL UNIQUE,
  password_hash VARCHAR(255) NOT NULL,
  role          VARCHAR(20)  DEFAULT 'student',  -- student | teacher | admin
  created_at    TIMESTAMPTZ  DEFAULT NOW()
);

-- Progress table
CREATE TABLE progress (
  id             SERIAL PRIMARY KEY,
  user_id        INTEGER REFERENCES users(id) ON DELETE CASCADE,
  unit_id        INTEGER NOT NULL,
  exercise       INTEGER DEFAULT 0,
  correct_count  INTEGER DEFAULT 0,
  attempt_count  INTEGER DEFAULT 0,
  completed      BOOLEAN DEFAULT false,
  updated_at     TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE (user_id, unit_id, exercise)
);

PWA Features

App boleh diinstall kat phone/tablet macam native app.

Feature Details
Manifest name, icons, theme_color, display: standalone
Service Worker vite-plugin-pwa + Workbox (auto-update)
Offline Static assets cached, API NetworkFirst (10s timeout)
Icons 192×192 dan 512×512 PNG
Orientation Portrait (portrait-primary)

Install PWA

  • Android Chrome: Menu → "Add to Home Screen"
  • iOS Safari: Share → "Add to Home Screen"
  • Desktop Chrome: Address bar → install icon

Roadmap

Phase 1 ✅

  • Unit 1 lengkap (Introduction + Interactive + 4 Exercises)
  • Auth system (register/login JWT)
  • Progress tracking (Zustand + API sync)
  • PWA setup
  • Docker Compose (dev + prod)

Phase 2 ✅

  • Unit 2: Kepekaan Nombor (biskut coklat comparison)
  • Unit 3: Item Padanan (1-to-1 matching)
  • Scaffolding / hint system untuk setiap unit (corrective TTS hint lepas jawapan salah)
  • Teacher dashboard — skipped (2026-09-14): app ni untuk satu murid je buat masa ni, tak perlu multi-student view. teacher role masih wujud dalam DB/register kalau nak sambung balik nanti.

Phase 3 ✅ (2026-09-14)

  • Unit 4: Penghitungan Titik
  • Unit 5: Perbandingan Nombor
  • Unit 6: Banding Nombor (Besar vs Kecil)
  • Unit 7: Operasi Tambah — bonus, luar skop asal
  • Certificate / badge system — badges table (1–3 bintang ikut ketepatan), sijil boleh cetak (CertificateReveal.jsx, gallery kat /certificates)
  • Analytics dashboard — /analytics: ketepatan ikut unit, masa belajar, trend aktiviti 14 hari (activity_log table)
  • Pre-recorded audio (ganti TTS) — belum buat; ini kerja rakam audio/content, bukan kerja code. TTS Web Speech API sedia ada masih jalan elok.

Phase 4 (dicadangkan — belum dibina)

Modul tambahan berasaskan kaedah intervensi dyscalculia yang terbukti (concrete→pictorial→abstract, subitizing, number sense):

  • Unit 8 — Rakan 10 (Number Bonds to 10): penguraian/gabungan nombor (contoh: "7 + berapa = 10?") — asas penting sebelum tambah/tolak sebenar
  • Unit 9 — Tambah & Tolak Ringkas (dalam 10): guna pendekatan konkrit→gambar→simbol (CPA), sambung terus dari Unit 7
  • Unit 10 — Garis Nombor & Nilai Tempat: anggaran kedudukan pada garis nombor + konsep puluh/sa (bundling visual)
  • Working-memory mini-games (ingat & ulang urutan) — kerap jadi cabaran khusus untuk murid dyscalculia, berasingan dari number sense

Built with ❤️ untuk murid-murid diskalkulia Malaysia