Skip to the article
Aniq-UI

LearnioThe student site

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.

PageAddressWhat it shows
Home/enHero, featured courses, how it works, instructors, testimonials and a call to action.
Courses/en/coursesThe 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/instructorsThe 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-certificateAnyone can check a certificate number here, without an account.
About, Privacy, Terms/en/about, /en/privacy, /en/termsStatic pages.
Checkout results/en/checkout/success, /en/checkout/cancelledWhere 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.

PageAddressWhat it does
Overview/dashboardProgress, learning activity, recent lessons and the course to continue.
My courses/dashboard/courses, /dashboard/courses/live, /dashboard/courses/recordedEvery 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>/quizzesThe course's quizzes, their attempts and results. The link shows only when the course has quizzes.
Calendar/dashboard/calendarLive 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/wishlistCourses kept for later, ready to move to the cart.
Certificates/dashboard/certificatesEarned certificates, to print or share, and courses close to finishing.
Messages/dashboard/messagesConversations with the instructors of the student's own courses.
Settings/dashboard/settingsProfile 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_approval setting 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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_URL before building. Canonical links, sharing cards, the sitemap and structured data all use it. Unset, it falls back to http://localhost:3030, which makes a wrong address obvious on the first share.
  • Sitemap: /sitemap.xml lists 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.txt allows 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 hreflang links to their other languages, through buildPageMetadata in src/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 from src/config/site.ts, and the default sharing images are src/app/opengraph-image.png and twitter-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.

Terminalin frontend
yarn dev
To changeLook in
A page or its addresssrc/app/[locale]/, one folder per route
What a page showssrc/features/<feature>/: home, courses, instructors, blog, checkout, certificates, auth, and dashboard/<page> for the dashboard
The dashboard sidebarsrc/layouts/dashboard/sidebar/config/navigationData.ts
The public header and footersrc/layout/NavBar/ and src/layout/Footer/
Name, description, colours, social accountssrc/config/site.ts
Languagessrc/config/locales.ts, plus messages/<namespace>/<locale>.json for each language
Wordingmessages/<namespace>/en.json and ar.json
Theme colourssrc/styles/theme-variables.css
Calls to the APIsrc/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.

Stuck on a step?

Find a fix before you start over.

Troubleshooting

Cookie Preferences

We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising.