import React from 'react' import { Link, router, usePage } from '@inertiajs/react' import SeoHead from '../../components/seo/SeoHead' import NovaSelect from '../../components/ui/NovaSelect' import { trackAcademySearchResultClick, trackUpgradeClick, useAcademyPageAnalytics } from '../../lib/academyAnalytics' function Breadcrumbs({ items = [] }) { if (!items.length) { return null } return ( ) } function formatAccessDate(value) { if (!value) { return null } const parsed = new Date(value) if (Number.isNaN(parsed.getTime())) { return null } return new Intl.DateTimeFormat(undefined, { year: 'numeric', month: 'short', day: 'numeric', }).format(parsed) } function academyAccessHeading(access) { switch (access?.status) { case 'staff_access': return 'You currently have full staff access to the Academy.' case 'grace_period': return `${access.tierLabel} access is still active.` case 'trialing': return `${access.tierLabel} trial is active right now.` case 'active': return access?.hasPaidAccess ? `${access.tierLabel} access is active.` : 'Your Academy access is active.' case 'free': return 'You currently have Free access to the Academy.' default: return null } } function academyAccessMeta(access) { if (!access?.signedIn) { return [] } const items = [ { label: 'Current tier', value: access?.tierLabel || 'Free' }, { label: 'Status', value: access?.statusLabel || 'Free access' }, ] const formattedDate = formatAccessDate(access?.expiresAt) if (formattedDate && access?.dateLabel) { items.push({ label: access.dateLabel, value: formattedDate }) } else if (access?.renewsAutomatically) { items.push({ label: 'Billing', value: 'Renews automatically' }) } else if (!access?.hasPaidAccess) { items.push({ label: 'Upgrade', value: 'Creator and Pro unlock premium lessons and courses' }) } return items } function CourseCard({ course, analytics = null, searchContext = null, position = null }) { const progress = course?.progress || null const cover = course?.cover_image_url || course?.teaser_image_url || course?.cover_image || course?.teaser_image || '' const trackSearchClick = () => { if (!searchContext?.query) { return } trackAcademySearchResultClick(analytics, searchContext, { contentType: 'academy_course', contentId: course?.id, position, }) } return (
{cover ? : null}
{course?.difficulty ? {course.difficulty} : null} {course?.access_level ? {course.access_level} : null} {course.is_featured ? Featured : null}
{course?.lessons_count || 0} lessons {course?.estimated_minutes ? `${course.estimated_minutes} min` : 'Flexible pace'}

Academy course

{course?.subtitle ? {course.subtitle} : null}

{course.title}

{course.excerpt || course.description || 'Structured Academy course.'}

{progress ? `${progress.percent}% complete` : 'Start fresh'}{course?.access_level ? ` ยท ${course.access_level}` : ''}

) } export default function AcademyCoursesIndex({ seo, title, description, items, featuredCourses = [], filters = {}, pricingUrl, lessonsUrl, promptLibraryUrl, academyAccess = null, analytics }) { const flash = usePage().props.flash || {} useAcademyPageAnalytics(analytics) const breadcrumbs = [ { label: 'Academy', href: '/academy' }, { label: 'Courses', href: '/academy/courses' }, ] const visibleItems = Array.isArray(items?.data) ? items.data : [] const totalCourses = Number(items?.total || items?.data?.length || 0) const featuredCount = featuredCourses.length const featuredCourse = featuredCourses.find((course) => course?.cover_image_url || course?.teaser_image_url || course?.cover_image || course?.teaser_image) || featuredCourses[0] || visibleItems[0] || null const featuredCover = featuredCourse?.cover_image_url || featuredCourse?.teaser_image_url || featuredCourse?.cover_image || featuredCourse?.teaser_image || '' const showSignedInAccess = Boolean(academyAccess?.signedIn) const accessHeading = academyAccessHeading(academyAccess) const accessMeta = academyAccessMeta(academyAccess) const useBillingAction = showSignedInAccess && academyAccess?.hasPaidAccess && academyAccess?.billingUrl const primaryActionLabel = useBillingAction ? (academyAccess?.status === 'grace_period' ? 'Renew now' : 'Manage billing') : 'See plans' const primaryActionIcon = useBillingAction ? (academyAccess?.status === 'grace_period' ? 'fa-solid fa-rotate-right' : 'fa-solid fa-sliders') : 'fa-solid fa-arrow-up-right-from-square' const primaryActionHref = useBillingAction ? academyAccess.billingUrl : pricingUrl const searchContext = analytics?.search ? { query: analytics.search.query, normalizedQuery: analytics.search.normalizedQuery, resultsCount: analytics.search.resultsCount, filters, } : null const difficultyOptions = [ { value: '', label: 'All levels' }, { value: 'beginner', label: 'Beginner' }, { value: 'intermediate', label: 'Intermediate' }, { value: 'advanced', label: 'Advanced' }, ] const accessOptions = [ { value: '', label: 'All access' }, { value: 'free', label: 'Free' }, { value: 'premium', label: 'Premium' }, { value: 'mixed', label: 'Mixed' }, ] const handlePrimaryAction = () => { if (!useBillingAction) { trackUpgradeClick(analytics, { source: 'academy_courses_index_hero_primary' }) } } return (
Skinbase AI Academy Courses {totalCourses} guided paths

{title}

{description}

Library

{totalCourses} guided courses

Focus

Sequenced learning + tracked completion

Structured progression Tracked completion Reusable lesson paths
Browse lessons Prompt library {primaryActionLabel}

Featured course

{featuredCourse?.difficulty ? {featuredCourse.difficulty} : null}
{featuredCover ? : null}
{featuredCourse?.access_level ? {featuredCourse.access_level} : null} {featuredCourse?.is_featured ? Spotlight : null}

{featuredCourse?.subtitle || 'Guided learning path'}

{featuredCourse?.title || 'Explore courses'}

{featuredCourse?.excerpt || featuredCourse?.description || 'Open a structured Academy course built from reusable lessons.'}

{showSignedInAccess ? 'Your Academy access' : 'Upgrade for full access'}

{showSignedInAccess ? accessHeading : 'Unlock the full course library, premium lesson paths, and the broader Academy learning track.'}

{showSignedInAccess ? (
{accessMeta.map((item) => (

{item.label}

{item.value}

))}
) : null}
{primaryActionLabel} Browse lessons
{academyAccess?.status === 'grace_period' ?

Opens billing account to restore renewal before access ends.

: null}
{flash.success ?
{flash.success}
: null} {flash.error ?
{flash.error}
: null}
router.get(window.location.pathname, { ...filters, difficulty: nextValue || undefined }, { preserveScroll: true, preserveState: true })} options={difficultyOptions} searchable={false} className="rounded-2xl bg-white/[0.04]" /> router.get(window.location.pathname, { ...filters, access: nextValue || undefined }, { preserveScroll: true, preserveState: true })} options={accessOptions} searchable={false} className="rounded-2xl bg-white/[0.04]" />
{visibleItems.length === 0 ? (
No published Academy courses matched these filters.
) : (
{visibleItems.map((course, index) => )}
)}
) }