WingoUI
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime Picker
Forms
Address InputCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage CropperImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Gravity Letters
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAI Product PageBlog PageBlog Post PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePress PageProduct Tour PageReferral PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageTemplate Gallery PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Templates

Academy Page

Templates

Academy Page

Design
About PageAccessibility Page
Design
Live props
Appearance
design
thumbnails
alternate
tone
ctaTone
Content
heroCourseId
State
defaultTopic
defaultLevel
defaultSort
Behavior
pageSize
animateIn
locale
Layout
testimonialsLayout
ctaVariant
showAnnouncement
showStats
showContinue
showPaths
showCatalog
showCertifications
showVerify
showSessions
showTestimonials
showFaq
showCta
header
footer
Code
import { AcademyPage } from "@/components/templates/academy-page"

<AcademyPage />
  1. Home
  2. Templates
  3. Academy Page
Pro

Academy Page

v1.0.0·Added in 1.8.0

A learning academy page: a drawn course player, progress and streaks, learning paths, a filterable course catalog and certifications.

The hero rises in once on mount beside a drawn course player (a lesson poster with a play button and scrubber, the chapter list with checkmarks) that settles into place over a soft glow, with a streak chip, a passed quiz and a certificate floating around it on wide screens. Start learning jumps to the catalog, Browse learning paths to the paths. Continue learning greets a signed-in learner with the course in progress (a progress ring, the next lesson, Resume and Syllabus), a streak card with this week's days and the weekly XP goal, and a rail of other courses in progress (swipeable on phones); with learner set to null it shows a sign-in prompt instead. Each learning path draws its courses as nodes on a track (done, up next, not started) ending in a certificate badge; View courses filters the catalog to that path and scrolls there, with a removable path chip. The catalog searches titles, summaries, topics and instructors as you type, filters by topic (a chip row that scrolls sideways on phones) and level (a segmented control), sorts by popularity, date, rating or length, shows the first nine courses with Show all, and an empty state with Clear filters. Clicking a course opens its preview as a dialog (a bottom sheet below 768px): a drawn preview, stats, what you'll learn, the syllabus as an accordion of modules and lessons with durations, and the instructor. Enroll for free spins while onEnroll runs (900 ms without one), then shows You're enrolled, swaps the button for Start course and puts the course at the front of Continue learning. Certifications show drawn badges, requirements and exam facts; Verify a certificate checks the ID format, spins, then shows the certificate (valid or expired) or a not found message. Live sessions link to events; learner quotes, the FAQ and the footer newsletter follow. Reduced motion keeps everything still.

Built with

The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.

  • Marketing Sectionmarketing-section
  • Marketing Headermarketing-header
  • Marketing Footermarketing-footer
  • Testimonials Sectiontestimonials-section
  • FAQ Sectionfaq-section
  • CTA Sectioncta-section

Add to a project

npx wingo-ui@latest add academy-page

Pro item: the CLI needs a Pro account. See plans

Usage

// app/(marketing)/academy/page.tsx
"use client"

import Link from "next/link"
import { AcademyPage } from "@/components/templates/academy-page"

export default function AcademyRoute() {
  return (
    <AcademyPage
      linkComponent={Link}
      ctaTone="brand"
      onEnroll={async (course) => {
        const response = await fetch("/api/academy/enroll", { method: "POST", body: JSON.stringify({ courseId: course.id }) })
        if (!response.ok) throw new Error("Could not enroll")
      }}
      onVerify={async (id) => {
        const response = await fetch(`/api/academy/certificates/${id}`)
        return response.ok ? response.json() : null
      }}
    />
  )
}

Props

  • designdefault "classic"
    "classic" | "bold" | "minimal"

    The whole page's look. classic follows the layout props: a split hero with the player on the right over a dotted glow; bold: a pill header, a giant stage title on a color mesh, rounder panels, an inverted Verify panel, a quote wall, FAQ cards, an image band and a wordmark footer; minimal: a transparent header, a centered stacked hero, no glow or floating chips, outlined flat panels, gray thumbnails, no bands and a simple footer. The *Props overrides still win.

  • topicsdefault "ACADEMY_TOPICS"
    AcademyTopic[]

    The topic chips, { value, label, icon? }; only topics that hold courses show.

  • coursesdefault "ACADEMY_COURSES"
    AcademyCourse[]

    The catalog: { id, title, summary, topic, level, scene (the drawn thumbnail), accent?, rating, ratings, learners, instructor, badge?, publishedAt, outcomes, modules: { id, title, lessons: { title, minutes, kind? }[] }[] }.

  • pathsdefault "ACADEMY_PATHS"
    AcademyPath[]

    Learning paths: { id, title, description, level, courseIds, certificationId?, icon?, accent? }; each course is a node on the drawn track.

  • certificationsdefault "ACADEMY_CERTIFICATIONS"
    AcademyCertification[]

    { id, name, level, description, requirements, exam: { questions, minutes, passScore, price }, holders, validMonths, shape, accent?, code }.

  • issuedCertificatesdefault "ACADEMY_ISSUED_CERTIFICATES"
    AcademyIssuedCertificate[]

    What the pretend Verify looks IDs up in when there is no onVerify.

  • learnerdefault "ACADEMY_LEARNER"
    AcademyLearner | null

    The signed-in learner: { name, avatar?, courses: { courseId, completed }[], paths?, streak, week, today?, xp, weeklyXp, weeklyGoal }. null shows the signed-out page with a sign-in prompt.

  • sessionsdefault "ACADEMY_SESSIONS"
    AcademySession[]

    Live sessions: { id, kind, title, startsAt (ISO, UTC), minutes, host }.

  • statsdefault "ACADEMY_STATS"
    AcademyStat[]

    The hero numbers: { value, label, decimals?, suffix? }.

  • testimonialsdefault "ACADEMY_TESTIMONIALS"
    Testimonial[]

    Learner quotes: { quote, name, role?, company?, companyIcon?, metric? }.

  • faqdefault "ACADEMY_FAQ"
    FaqItem[]

    { question, answer } pairs about the Academy.

  • labelsdefault "DEFAULT_ACADEMY_PAGE_LABELS"
    Partial<AcademyPageLabels>

    Every visible string; the ones with numbers in them are functions.

  • hrefsdefault "DEFAULT_ACADEMY_PAGE_HREFS"
    Partial<AcademyPageHrefs>

    { catalog, paths, course, signIn, signUp, events, examGuide }; a course's page is `${course}/${id}`.

  • heroCourseIddefault "automations-101"
    string

    The course drawn in the hero's player.

  • defaultTopicdefault "all"
    string

    The topic filter on load: all or a topic value.

  • defaultLeveldefault "all"
    "all" | "beginner" | "intermediate" | "advanced"

    The level filter on load.

  • defaultSortdefault "popular"
    "popular" | "newest" | "rating" | "shortest"

    The catalog's order on load.

  • pageSizedefault 9
    number

    Courses shown before Show all; 0 shows every course.

  • thumbnailsdefault "color"
    "color" | "mono"

    Course thumbnails tinted with each course's accent, or all gray. Applies to the classic and bold designs.

  • testimonialsLayoutdefault "featured"
    "featured" | "grid" | "carousel" | "marquee"

    Learner quotes as one big quote and two small, a masonry grid, a swipeable rail or drifting rows. Applies to the classic design.

  • ctaVariantdefault "inverted"
    "inverted" | "soft" | "split"

    The closing band: a solid band, a gray band, or copy beside the buttons on a raised panel. Applies to the classic design.

  • showAnnouncementdefault true
    boolean

    The strip above the header bar.

  • showStatsdefault true
    boolean

    The hero's numbers.

  • showContinuedefault true
    boolean

    Continue learning, or the sign-in prompt when signed out.

  • showPathsdefault true
    boolean

    The learning paths.

  • showCatalogdefault true
    boolean

    The course catalog.

  • showCertificationsdefault true
    boolean

    The certification cards.

  • showVerifydefault true
    boolean

    The Verify a certificate panel.

  • showSessionsdefault true
    boolean

    The live sessions.

  • showTestimonialsdefault true
    boolean

    The learner quotes.

  • showFaqdefault true
    boolean

    The FAQ.

  • showCtadefault true
    boolean

    The closing call to action.

  • alternatedefault true
    boolean

    Gray bands on every other section. Applies to the classic and bold designs.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Accents across the page: the hero glow, progress rings and bars, streak days, path nodes, topic chips, the level control and checks.

  • ctaTonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Start learning, Resume, Enroll for free, Verify, Sign in, the header's Get started and the closing band; brand is the marketing orange.

  • headerdefault true
    boolean

    The marketing header; off inside a site layout.

  • footerdefault true
    boolean

    The marketing footer with its newsletter form.

  • headerProps
    Partial<MarketingHeaderProps>

    Passed to MarketingHeader.

  • footerProps
    Partial<MarketingFooterProps>

    Passed to MarketingFooter.

  • testimonialsProps
    Partial<TestimonialsSectionProps>

    Overrides for the TestimonialsSection.

  • faqProps
    Partial<FaqSectionProps>

    Overrides for the FaqSection.

  • ctaProps
    Partial<CtaSectionProps>

    Overrides for the CtaSection.

  • onEnroll
    (course: AcademyCourse) => (void | Promise<unknown>)

    Enroll for free. A promise keeps the button loading and a rejection shows an error in the dialog. Without it the button waits 900 ms; then the course counts as enrolled and joins Continue learning.

  • onVerify
    (id: string) => (AcademyVerifyResult | Promise<AcademyVerifyResult>)

    Looks a certificate ID up (already upper-cased and checked against ACME-XXX-00000). Resolve with the certificate or null; a rejection shows an error. Without it: 900 ms, then issuedCertificates.

  • onCourseOpen
    (course: AcademyCourse) => void

    A course's preview opened.

  • onSubscribe
    (email: string) => (void | Promise<unknown>)

    The footer newsletter; a rejected promise shows an error.

  • animateIndefault true
    boolean

    The hero rises in once, the player settles into place and the quotes drift; false keeps the page still (thumbnails). Reduced motion always does.

  • localedefault "en-US"
    string

    Intl locale for counts, ratings, prices and dates (dates in UTC).

  • linkComponentdefault "<a>"
    (props: LinkComponentProps) => ReactNode

    The router link for every link on the page (next/link in an app).

  • className
    string

    Classes for the root.

  • classNames
    Partial<Record<AcademyPageSlot, string>>

    Classes for header, hero, title, player, stats, continue, paths, path, catalog, toolbar, course, detail, certifications, certification, verify, sessions, testimonials, faq, cta and footer.

Parts

  • ACADEMY_PAGE_SAMPLE

    constant

    All the sample content in one object: topics, courses, paths, certifications, issued certificates, learner, sessions, stats, testimonials and faq.

  • ACADEMY_TOPICS

    constant

    Eight topics, from Getting started to Integrations and API.

  • ACADEMY_COURSES

    constant

    Sixteen courses with drawn thumbnails, instructors, outcomes and full syllabi.

  • ACADEMY_PATHS

    constant

    Acme Foundations, Workflow Automation, Team Admin and Acme for Product Managers.

  • ACADEMY_CERTIFICATIONS

    constant

    Acme Certified Admin, Builder and Expert.

  • ACADEMY_ISSUED_CERTIFICATES

    constant

    Three issued certificates for the pretend lookup: ACME-ADM-24817, ACME-BLD-50392 and ACME-EXP-00731.

  • ACADEMY_LEARNER

    constant

    Chloe Martin: three courses in progress, a 12-day streak and 320 of 500 XP this week.

  • ACADEMY_SESSIONS

    constant

    Three live sessions in October 2026: office hours, an AMA and a workshop.

  • ACADEMY_STATS

    constant

    16 free courses, 180,000+ learners, 3 certifications, 4.8 average rating.

  • ACADEMY_TESTIMONIALS

    constant

    Six learner quotes.

  • ACADEMY_FAQ

    constant

    Six questions about price, accounts, renewals, retakes, teams and captions.

  • findAcademyCertificate

    function

    (id, issued = ACADEMY_ISSUED_CERTIFICATES) => the issued certificate with that ID (trimmed, any case) or null.

  • DEFAULT_ACADEMY_PAGE_LABELS

    constant

    The English strings.

  • DEFAULT_ACADEMY_PAGE_HREFS

    constant

    The default link targets.

  • ACADEMY_PAGE_DESIGNS

    constant

    The design names, classic first: ["classic", "bold", "minimal"].

  • AcademyPageProps

    type

    Props of AcademyPage.

  • AcademyPageDesign

    type

    "classic" | "bold" | "minimal".

  • AcademyCourse

    type

    One course with its syllabus.

  • AcademyModule

    type

    A module of a course: { id, title, lessons }.

  • AcademyLesson

    type

    A lesson: { title, minutes, kind? }.

  • AcademyPath

    type

    One learning path.

  • AcademyCertification

    type

    One certification with its exam.

  • AcademyIssuedCertificate

    type

    A certificate someone earned: { id, holder, certificationId, issuedAt, expiresAt }.

  • AcademyVerifyResult

    type

    What onVerify resolves with: AcademyIssuedCertificate | null.

  • AcademyLearner

    type

    The signed-in learner's progress, streak and XP.

  • AcademySession

    type

    One live session.

  • AcademyPageLabels

    type

    The strings labels can override.

  • AcademyPageHrefs

    type

    The link targets hrefs can override.

Examples

Open

Bold design

design="bold": a giant stage title on a color mesh, rounder panels, an inverted Verify panel, a quote wall and a wordmark footer.

Open

Minimal design

design="minimal": a transparent header, a centered hero, gray thumbnails, outlined panels, no gray bands and a simple footer.

Open

Signed out, in brand orange

learner={null} with tone and ctaTone brand: Continue learning becomes a sign-in prompt; enroll in a course to see it appear there.

Open

Advanced automation courses

defaultTopic automations, defaultLevel advanced and the newest first, with the API course in the hero and a grid of quotes.

Open

Enrollment down

An onEnroll that rejects: open a course and enroll to see the error while the button stays ready to try again.

Dependencies

lucide-reactmotionmarketing-sectionmarketing-headermarketing-footertestimonials-sectionfaq-sectioncta-sectionaccordionavatarbuttondialogempty-stateinputprogresssearch-inputsegmented-controlselectmotionnavigationtext-matchtonesui-config

Files

  • components/templates/academy-page.tsx
  • components/templates/academy-page-data.ts

See also

Help Center PageDocs Home PageEvents PageProgressAccordion
PreviousAbout PageNext Accessibility Page