The student site
What the student site offers visitors and signed-in learners, how buying and finishing a course work, and where to change it.
For the Full Stack package
Public pages
Every page lives under a locale prefix, /en or /ar, and the Arabic pages run right to left. Opening / sends the visitor to /en.
| Page | Address | What it shows |
|---|---|---|
| Home | /en | Hero, featured courses, how it works, instructors, testimonials and a call to action. |
| Courses | /en/courses | The catalogue, filtered by category and by type (live or recorded), with pagination. |
| Course | /en/courses/<slug> | Overview, syllabus, preview video, pricing card, instructor, the course's published student reviews with their average rating, FAQ and related courses. Buying starts here. |
| Instructors | /en/instructors | The instructor directory, filtered by specialty. |
| Instructor | /en/instructors/<username> | One instructor's profile and courses. |
| Blog | /en/blog and /en/blog/<slug> | Articles by category, and each article. |
| Verify a certificate | /en/verify-certificate | Anyone can check a certificate number here, without an account. |
| About, Privacy, Terms | /en/about, /en/privacy, /en/terms | Static pages. |
| Checkout results | /en/checkout/success, /en/checkout/cancelled | Where a buyer lands after paying on Stripe's or PayPal's page, and after enrolling on a free course. |
| Sign-in and account pages | /en/auth/... | login, register, forgot-password, reset-password, verify-email, welcome and auth-code-error. |
Any other address shows the site's 404 page. Without an API, the catalogue, instructors and blog come from the bundled sample data: see Sample data in the frontends.
The learner dashboard
A signed-in student gets a dashboard under /en/dashboard. Signed out, any dashboard address sends them to sign in and back to the page they asked for.
| Page | Address | What it does |
|---|---|---|
| Overview | /dashboard | Progress, learning activity, recent lessons and the course to continue. |
| My courses | /dashboard/courses, /dashboard/courses/live, /dashboard/courses/recorded | Every course the student is enrolled in, with progress and a resume button. |
| Course player | /dashboard/courses/<courseId> | Lessons, notes and resources, described below. |
| Quizzes | /dashboard/courses/<courseId>/quizzes | The course's quizzes, their attempts and results. The link shows only when the course has quizzes. |
| Calendar | /dashboard/calendar | Live classes, assignments and deadlines for the week. A student submits an assignment from here. |
| Live class | /dashboard/calendar/live/<sessionId> | The class's video room, open shortly before the class starts. |
| Saved | /dashboard/wishlist | Courses kept for later, ready to move to the cart. |
| Certificates | /dashboard/certificates | Earned certificates, to print or share, and courses close to finishing. |
| Messages | /dashboard/messages | Conversations with the instructors of the student's own courses. |
| Settings | /dashboard/settings | Profile details and password. |
- Notifications open from the bell in the dashboard header: a new certificate, for example.
- Search in the dashboard header finds the student's own courses, the catalogue, instructors, categories and blog posts. It needs at least two characters.
- A student can message an instructor only about a course they are enrolled in.
The course player and lesson progress
- The player opens on the lesson the student last watched. Arriving from a new enrolment, it starts at lesson one.
- A lesson counts as done when its video ends or when the student presses Mark as Complete. Progress is saved on the API, so it survives a reload and another device.
- Each lesson has an overview, the instructor, downloadable resources and a private Notes tab. Notes save on their own while the student types.
- The video player remembers volume, captions and playback speed in the browser, and has keyboard shortcuts.
- Once every lesson is done, the page header offers the course's certificate. A Quizzes button appears there when the course has quizzes.
- Rate this course in the page header opens the student's review: a rating from 1 to 5 stars and an optional comment of up to 2,000 characters. Once sent, the button reads Your review, and the student can edit or delete it from there.
Course reviews
Students review the courses they take, and the course page shows those reviews to every visitor.
- Only a student enrolled on the course can review it, once per course. A cancelled enrolment cannot.
- A review shows on the course page with the student's name and photo, most recent first, with Show more reviews to load the rest. The course's average rating and review count, and its instructor's, are recomputed after every review and every moderation change.
- With the
reviews_require_approvalsetting on, a review waits as Awaiting approval until a moderator publishes it in the admin's Reviews screen, and only its author sees it meanwhile. Off, which is how it ships, it appears at once. - A moderator can hide a review; editing a hidden review sends it back for approval. A review a moderator deleted can no longer be edited or replaced.
- Staff who can see reviews are notified of each new one.
Enrolment and checkout
A student is enrolled on a course by paying for it. The course page's buy button opens a checkout panel, and the cart pays for several courses in one payment, with one order per course. Paying needs a student account: a signed-out visitor who presses pay is sent to sign in.
The student chooses card or PayPal
The panel asks the API which methods this build takes (
GET /api/shop/payment-methods), so it never offers one the server cannot handle.The API takes the payment
On the built-in simulator the card or PayPal form is filled in on the site and settles at once. With Stripe or PayPal configured, the student is sent to the processor's own page and the order stays pending.
The student comes back
The processor returns them to
/<locale>/checkout/success?order=<reference>, or to/checkout/cancelled. The success page confirms the payment and waits until the order is settled.The seat is granted
The enrolment is created only once the payment is confirmed: at once on the simulator, by the processor's webhook otherwise. A receipt email follows.
Expected result: The course appears under My courses.
- Free courses (price 0) show Free and No payment needed on the course page's pricing card, and its button reads Enroll for free. The same panel opens, with no payment method or card fields, and its button reads Enroll for free too. The API completes the order without a payment processor, so a free course works even with no payment keys set. The student goes straight to the success page, the course is theirs at once, and the email confirms the enrolment without a receipt.
- Buying a course the student already owns is refused, so nobody pays twice.
- A double click or a retry sends the same idempotency key, and the API answers with the first order rather than charging again.
- The cart and the saved list are kept in the browser, not on the API.
Finishing a course
A course is finished when both are true:
- Every lesson is done, which takes the student's progress to 100%.
- Every required quiz is passed. Only published quizzes marked as required count. A course without required quizzes is finished when its lessons are.
The API checks this each time the student completes a lesson or passes a quiz. When the course is finished, it marks the enrolment completed and issues the certificate by itself, and the student is notified. The course player also offers the certificate once the lessons are done, which covers a course finished before the certificate could be issued. If a required quiz is still open, the student is told the certificate is not ready yet.
Certificates are listed under Certificates in the dashboard, where the student prints one or shares its link. Anyone shown a certificate can check its number at /verify-certificate.
Search engines and sharing
- Site address: set
NEXT_PUBLIC_SITE_URLbefore building. Canonical links, sharing cards, the sitemap and structured data all use it. Unset, it falls back tohttp://localhost:3030, which makes a wrong address obvious on the first share. - Sitemap:
/sitemap.xmllists the home, courses, instructors, blog, about, privacy and terms pages, plus every published course, every instructor profile and every published article, in every locale, each with its translations. It is built on each request from the same API reads as the pages, so a course published in the admin appears in it at once. Without an API, the courses and instructors come from the sample data and no articles are listed. - robots.txt:
/robots.txtallows everything except/api/, the dashboard and the sign-in pages, and points at the sitemap. - Titles and sharing cards: the home, courses, course, instructors, instructor, blog, article, about, privacy and terms pages each set their own title and description, a canonical address and
hreflanglinks to their other languages, throughbuildPageMetadatainsrc/lib/seo/. Course, instructor and article pages add their own image. The site name, description, Twitter handle (SITE.twitterHandle) and browser colours (SITE.browserChrome) come fromsrc/config/site.ts, and the default sharing images aresrc/app/opengraph-image.pngandtwitter-image.png. - Structured data: the root layout writes the organisation as JSON-LD into every page.
Where to change things
Everything is in frontend/src/. Run the site with yarn dev and open port 3030; every change reloads.
frontendyarn dev| To change | Look in |
|---|---|
| A page or its address | src/app/[locale]/, one folder per route |
| What a page shows | src/features/<feature>/: home, courses, instructors, blog, checkout, certificates, auth, and dashboard/<page> for the dashboard |
| The dashboard sidebar | src/layouts/dashboard/sidebar/config/navigationData.ts |
| The public header and footer | src/layout/NavBar/ and src/layout/Footer/ |
| Name, description, colours, social accounts | src/config/site.ts |
| Languages | src/config/locales.ts, plus messages/<namespace>/<locale>.json for each language |
| Wording | messages/<namespace>/en.json and ar.json |
| Theme colours | src/styles/theme-variables.css |
| Calls to the API | src/lib/api/<domain>/ |
yarn typecheck and yarn lint check your changes; yarn build makes the production build.
How certificates are issued and verified
Included with your purchase. Sign in to read, or open it in your download.
How the API decides a course is finished, numbers and stores each certificate, and answers a verification.
Live classes inside the site
Included with your purchase. Sign in to read, or open it in your download.
How a student enters a live class: the room's opening window, the join request and the Jitsi Meet embed.
How the site's code fits together
Included with your purchase. Sign in to read, or open it in your download.
How data reaches a page, how sign-in and the browser-kept lists work, and the steps to add a page of your own.