Skip to content

Latest commit

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Langora

Learn Chinese the way you learn touch‑typing. Read an English prompt, hear the audio, type the pinyin — get instant, gamified feedback.

Next.jsReactTypeScriptSupabaseDrizzleTailwind CSSLicense: MIT

中文文档 · [Report a bug](GitHub Repository/issues) · [Request a feature](GitHub Repository/issues)

Langora landing page hero

Overview

Langora is an interactive practice app for Chinese learners, inspired by TypingClub's "type‑to‑progress" model. Each question shows an English prompt and auto‑plays its audio; the learner types the matching pinyin, and the app validates the answer, plays sound effects, and records progress in real time.

Lessons are grouped by theme — Greetings, Casual Conversation, Ordering Food, and more — and the content is monetized through a monthly subscription, a lifetime plan, and single‑lesson purchases.

🔗 Live demo: [https://langora.joy-codex.com] · 📦 Repository: [GitHub Repository](https://github.com/KapiYue/Langora)

Screenshots

Course storeLearner dashboard
Course Store — browse lessons by topic and access tierDashboard — streaks, accuracy, and recent lessons
Pricing
Simple, transparent pricing — Free, Monthly Pro, and Lifetime

Features

Learning experience

  • Type‑to‑progress drills — English prompt + auto‑played audio; answer in pinyin with lenient matching (case, tone numbers, and extra spaces are ignored), and multiple accepted answers per question.
  • Immersive feedback — keystroke, correct, and error sound effects, plus a confetti animation on lesson completion.
  • Keyboard shortcutsCtrl + P replays the audio, Enter submits an answer or advances to the next question.
  • Progress visualization — per‑item progress bar, question counter, and live accuracy tracking.

Authentication

  • Email/password sign‑up, login, forgot‑password, and reset flows powered by Supabase Auth.
  • Cookie‑based SSR sessions (@supabase/ssr), refreshed centrally through Next.js Middleware.

Dashboard

  • Learning overview: lessons completed, total words mastered, current streak, weekly practice time, and average accuracy.
  • Recent lessons, a course store with per‑lesson progress, a profile page, and account settings (password change).

Content & access control

  • Lessons, lesson items, and progress are stored in Postgres and can be imported via a seed script.
  • Access rules: the free lesson (greetings_l1) is open to everyone; Pro and Lifetime members unlock every lesson; single‑lesson purchases unlock just that lesson.

Payments & membership (Creem)

  • Three tiers: Free, Monthly Pro ($10/mo), Lifetime ($99 one‑time) — plus standalone single‑lesson purchases.
  • Webhook requests are verified with an HMAC‑SHA256 signature check (crypto.timingSafeEqual) before any data is written.
  • Grace period on cancellation — a canceled subscription stays active until the end of the current billing cycle; a refund revokes access immediately.
  • Upgrade protection — purchasing Lifetime access automatically cancels an active Monthly Pro subscription to prevent double billing.
  • Duplicate‑purchase guard — blocks redundant checkouts when the user already owns an equal or higher tier.

Tech stack

AreaTechnology
FrameworkNext.js 15 (App Router, Turbopack), React 19
LanguageTypeScript 5
UITailwind CSS 3, shadcn/ui (Radix UI), Framer Motion, lucide-react
AuthSupabase Auth (@supabase/ssr, cookie/SSR)
DatabaseSupabase Postgres + Drizzle ORM (postgres-js driver)
Migrationsdrizzle-kit
PaymentsCreem (Checkout + Webhook)
Miscuse-sound, react-confetti, next-themes

Architecture

flowchart LR
U[Browser] -->|SSR / Client| N[Next.js App Router]
N -->|Middleware session refresh| SB[(Supabase Auth)]
N -->|Drizzle ORM| PG[(Supabase Postgres)]
N -->|Create checkout| CR[Creem API]
CR -->|Webhook event + signature| N
N -->|Write subscriptions / purchases / transactions| PG
Loading

Data model

TablePurpose
lessonsLessons (title, description, tag, order, cover image)
lesson_itemsLesson items (English prompt, Chinese, pinyin, accepted answers, audio)
user_profilesProfile and aggregate stats (lessons completed, words mastered, streak)
user_lesson_progressLesson‑level progress (completed items, accuracy, time spent)
user_item_progressItem‑level progress (attempts, correct attempts)
user_daily_statsDaily learning statistics
user_subscriptionsPro / Lifetime subscriptions
user_course_purchasesSingle‑lesson purchases
payment_transactionsPayment transaction ledger

Project structure

app/
page.tsx # Landing page (Hero / Features / Pricing / ...)
auth/ # Login / sign-up / password recovery
dashboard/ # Overview / courses / membership / billing / profile / settings
lesson/[lessonId]/ # Lesson player (with access control)
api/
lesson-progress/ # Save learning progress
payment/ # checkout / webhook / status / cancel
components/ # Landing page, dashboard, lesson, and shared UI components
lib/
supabase/ # client / server / middleware
db/ # schema / queries / seed / connection
creem.ts # Payment config and helpers
membership/plans.ts # Plan definitions
drizzle/ # Migration files
docs/ # API references, lesson seed data, screenshots

Getting started

Prerequisites

  • Node.js ≥ 20 and pnpm
  • A Supabase project (Postgres + Auth)
  • A Creem account (the test environment is fine)

1. Install dependencies

pnpm install

2. Configure environment variables

Copy .env.example to .env.local and fill in the values:

# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_OR_ANON_KEY=
DATABASE_URL=
# Site
NEXT_PUBLIC_SITE_URL=http://localhost:3000
# Creem
CREEM_API_KEY=
CREEM_WEBHOOK_SECRET=
NEXT_PUBLIC_CREEM_URL=https://test-api.creem.io
CREEM_LIFETIME_PRODUCT_ID=
CREEM_SUBSCRIPTION_PRODUCT_ID=
CREEM_SINGLE_COURSE_PRODUCT_ID=

3. Initialize the database

pnpm db:push # sync the schema (or db:migrate to apply migrations)
pnpm db:seed # import lessons from docs/lessons.json

4. Run the dev server

pnpm dev

Open http://localhost:3000.

Available scripts

CommandDescription
pnpm devStart the dev server (Turbopack)
pnpm build / pnpm startBuild / run in production
pnpm lintRun ESLint
pnpm db:generateGenerate a new migration
pnpm db:migrate / pnpm db:pushApply migrations / push schema directly
pnpm db:studioOpen Drizzle Studio
pnpm db:seedSeed lesson data from docs/lessons.json

Payments notes (Creem)

  • Checkout sessions pass userId, paymentType, and lessonId through metadata, which the webhook uses to post ledger entries accurately.
  • The webhook path (/api/payment/webhook) is excluded from the Middleware matcher so the session‑refresh logic never interferes with it, and it verifies its own signature independently.
  • Switch between test and production by changing NEXT_PUBLIC_CREEM_URL and the three *_PRODUCT_ID environment variables.

Deployment

Recommended stack: Vercel + Supabase.

  1. Create a Supabase project, then run migrations and seed the lesson data.
  2. Set the environment variables above in your Vercel project (NEXT_PUBLIC_SITE_URL should point to your live domain).
  3. Point the Creem webhook to https://<your-domain>/api/payment/webhook.

Roadmap

  • More lesson themes and difficulty tiers
  • Mistake review / spaced repetition
  • Leaderboards and achievements
  • Mobile UX polish
  • Full UI internationalization (i18n)

Contributing

Contributions, issues, and feature requests are welcome. Please read CONTRIBUTING.md before opening a pull request, and note that this project follows a Code of Conduct.

Security

If you discover a security vulnerability, please follow the responsible‑disclosure process described in SECURITY.md instead of opening a public issue.

License

Released under the MIT License.

About

Langora is an interactive practice app for Chinese learners, inspired by TypingClub's "type‑to‑progress" model. Each question shows an English prompt and auto‑plays its audio; the learner types the matching **pinyin**, and the app validates the answer, plays sound effects, and records progress in real time.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages