import React from 'react'
import { Link } from '@inertiajs/react'
import SeoHead from '../../components/seo/SeoHead'
import { trackUpgradeClick, useAcademyPageAnalytics } from '../../lib/academyAnalytics'
function academyHref(section, slug) {
return `/academy/${section}/${encodeURIComponent(slug)}`
}
function formatStatValue(value, singular, plural = `${singular}s`) {
const numericValue = Number(value || 0)
return `${numericValue.toLocaleString()} ${numericValue === 1 ? singular : plural}`
}
function FeatureCard({ title, description, href, cta, icon, eyebrow, highlights = [], tags = [], meta, theme }) {
return (
{description}
{highlights.map((item) => (
{item.label}
{item.value}
))}
{tags.map((tag) => (
{tag}
))}
{cta}
{meta}
)
}
function FeatureRailCard({ eyebrow, title, description, icon, items = [], emptyText, actionHref = null, actionLabel = null, theme, renderItem }) {
return (
{eyebrow}
{title}
{description}
{actionHref && actionLabel ? (
{actionLabel}
) : null}
{items.length > 0 ? items.map((item, index) => renderItem(item, index)) : (
{emptyText}
)}
)
}
function MetricCard({ label, value, accent }) {
return (
)
}
function FeaturedCourseCard({ course }) {
const cover = course?.cover_image_url || course?.teaser_image_url || course?.cover_image || course?.teaser_image || ''
return (
{cover ?
: null}
{course.difficulty}
{course.access_level}
Guided course
{course.title}
{course.excerpt || course.description || 'Guided Academy course.'}
{course.lessons_count || 0} lessons ยท {course.estimated_minutes ? `${course.estimated_minutes} min` : 'Flexible duration'}
Open path
)
}
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 'Preview the Academy before you upgrade.'
}
}
function academyAccessMeta(access) {
const items = [
{ label: 'Current tier', value: access?.tierLabel || 'Guest' },
{ label: 'Status', value: access?.statusLabel || 'Preview access only' },
]
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?.signedIn && !access?.hasPaidAccess) {
items.push({ label: 'Upgrade', value: 'Creator and Pro unlock premium workflows' })
} else if (!access?.signedIn) {
items.push({ label: 'Upgrade', value: 'Sign in to track access and unlock premium content' })
}
return items
}
export default function AcademyIndex({ seo, pricingUrl, academyAccess = null, links, featureFlags, stats, featuredCourses, featuredLessons, featuredPrompts, featuredChallenges, analytics }) {
useAcademyPageAnalytics(analytics)
const accessHeading = academyAccessHeading(academyAccess)
const accessMeta = academyAccessMeta(academyAccess)
const useBillingAction = academyAccess?.signedIn && academyAccess?.hasPaidAccess && academyAccess?.billingUrl
const accessActionLabel = useBillingAction ? (academyAccess?.status === 'grace_period' ? 'Renew now' : 'Manage billing') : 'See plans'
const accessActionHref = useBillingAction ? academyAccess.billingUrl : pricingUrl
const academySections = [
{
title: 'Courses',
description: 'Follow guided learning paths that stitch reusable Academy lessons into a clean progression with completion tracking.',
href: links.courses,
cta: 'Browse courses',
icon: 'fa-solid fa-route',
eyebrow: 'Academy paths',
highlights: [
{ label: 'Library', value: formatStatValue(stats?.courseCount, 'course') },
{ label: 'Includes', value: formatStatValue(stats?.lessonCount, 'lesson') },
],
tags: ['Progress tracked', 'Learning paths', 'Skill ladders'],
meta: 'Structured progression',
theme: {
shell: 'border-sky-300/18 bg-slate-950/40 hover:border-sky-300/30',
backdrop: 'bg-[linear-gradient(145deg,rgba(14,165,233,0.16),rgba(15,23,42,0.95)_42%,rgba(16,185,129,0.18))]',
pattern: 'bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.16),transparent_30%),linear-gradient(125deg,transparent_0%,transparent_45%,rgba(125,211,252,0.08)_45%,rgba(125,211,252,0.08)_52%,transparent_52%,transparent_100%)]',
glow: 'bg-sky-300/25',
eyebrow: 'text-sky-100/80',
iconWrap: 'border-sky-200/20 bg-sky-300/12 text-sky-100',
highlightCard: 'border-sky-200/12 bg-slate-950/40',
highlightLabel: 'text-sky-100/75',
tag: 'border-sky-200/12 bg-sky-300/10 text-sky-100',
cta: 'border-sky-300/25 bg-sky-300/12 text-sky-100',
meta: 'text-sky-100/75',
},
},
{
title: 'Lessons',
description: 'Structured tutorials for prompt writing, cleanup workflows, AI ethics, and Skinbase-native publishing habits.',
href: links.lessons,
cta: 'Open lessons',
icon: 'fa-solid fa-book-open-reader',
eyebrow: 'Focused tutorials',
highlights: [
{ label: 'Depth', value: formatStatValue(stats?.lessonCount, 'lesson') },
{ label: 'Coverage', value: 'Prompt craft + workflow cleanup' },
],
tags: ['Short wins', 'Creative habits', 'Practical steps'],
meta: 'Skill-by-skill learning',
theme: {
shell: 'border-amber-300/18 bg-slate-950/40 hover:border-amber-300/30',
backdrop: 'bg-[linear-gradient(160deg,rgba(251,191,36,0.18),rgba(15,23,42,0.95)_40%,rgba(249,115,22,0.14))]',
pattern: 'bg-[radial-gradient(circle_at_top_right,rgba(253,230,138,0.14),transparent_28%),linear-gradient(180deg,transparent_0%,transparent_54%,rgba(251,191,36,0.08)_54%,rgba(251,191,36,0.08)_58%,transparent_58%,transparent_100%)]',
glow: 'bg-amber-300/20',
eyebrow: 'text-amber-100/85',
iconWrap: 'border-amber-200/20 bg-amber-300/12 text-amber-100',
highlightCard: 'border-amber-200/12 bg-slate-950/42',
highlightLabel: 'text-amber-100/75',
tag: 'border-amber-200/12 bg-amber-300/10 text-amber-100',
cta: 'border-amber-300/25 bg-amber-300/12 text-amber-100',
meta: 'text-amber-100/75',
},
},
{
title: 'Prompt Library',
description: 'Discover reusable prompt templates, locked premium previews, and creator-focused visual workflows.',
href: links.prompts,
cta: 'Explore prompts',
icon: 'fa-solid fa-wand-magic-sparkles',
eyebrow: 'Reusable prompt kits',
highlights: [
{ label: 'Templates', value: formatStatValue(stats?.promptCount, 'prompt') },
{ label: 'Use case', value: 'Reusable systems + premium previews' },
],
tags: ['Fast starts', 'Visual workflows', 'Copy + adapt'],
meta: 'High-speed ideation',
theme: {
shell: 'border-rose-300/18 bg-slate-950/40 hover:border-rose-300/30',
backdrop: 'bg-[linear-gradient(150deg,rgba(244,63,94,0.16),rgba(15,23,42,0.95)_38%,rgba(45,212,191,0.16))]',
pattern: 'bg-[radial-gradient(circle_at_20%_15%,rgba(251,113,133,0.16),transparent_24%),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px),linear-gradient(180deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[length:auto,22px_22px,22px_22px]',
glow: 'bg-rose-300/20',
eyebrow: 'text-rose-100/85',
iconWrap: 'border-rose-200/20 bg-rose-300/12 text-rose-100',
highlightCard: 'border-rose-200/12 bg-slate-950/42',
highlightLabel: 'text-rose-100/75',
tag: 'border-rose-200/12 bg-rose-300/10 text-rose-100',
cta: 'border-rose-300/25 bg-rose-300/12 text-rose-100',
meta: 'text-rose-100/75',
},
},
]
const academyFeatureRails = [
{
key: 'lessons',
eyebrow: 'Featured lessons',
title: 'Jump-in tutorials',
description: 'Shorter Academy pieces for specific prompt problems, cleanup workflows, and publishing habits.',
icon: 'fa-solid fa-book-open-reader',
actionHref: links.lessons,
actionLabel: 'All lessons',
items: (featuredLessons || []).slice(0, 3),
emptyText: 'Featured lessons will appear here when the Academy team highlights a new tutorial.',
theme: {
shell: 'border-amber-300/16 bg-slate-950/45',
backdrop: 'bg-[linear-gradient(160deg,rgba(251,191,36,0.15),rgba(15,23,42,0.96)_42%,rgba(249,115,22,0.14))]',
pattern: 'bg-[radial-gradient(circle_at_top_right,rgba(253,230,138,0.12),transparent_24%),linear-gradient(180deg,transparent_0%,transparent_52%,rgba(251,191,36,0.08)_52%,rgba(251,191,36,0.08)_56%,transparent_56%,transparent_100%)]',
glow: 'bg-amber-300/18',
eyebrow: 'text-amber-100/82',
iconWrap: 'border-amber-200/20 bg-amber-300/12 text-amber-100',
action: 'border-amber-300/22 bg-amber-300/10 text-amber-100 hover:border-amber-300/34 hover:bg-amber-300/16',
item: 'border-amber-200/10 bg-slate-950/38 hover:border-amber-200/18 hover:bg-slate-950/52',
itemEyebrow: 'text-amber-100/75',
itemMeta: 'text-amber-100/70',
empty: 'border-amber-200/10 bg-slate-950/30 text-amber-50/80',
},
renderItem: (item, index, theme) => (
{index + 1}
{item.lesson_label || 'Featured lesson'}
{item.title}
Practical tutorial
),
},
{
key: 'prompts',
eyebrow: 'Featured prompts',
title: 'Reusable prompt packs',
description: 'Template-driven prompt entries designed for fast reuse, remixing, and premium workflow previews.',
icon: 'fa-solid fa-wand-magic-sparkles',
actionHref: links.promptPopular,
actionLabel: 'Top prompts',
items: (featuredPrompts || []).slice(0, 3),
emptyText: 'Featured prompts will appear here when reusable prompt templates are promoted on the homepage.',
theme: {
shell: 'border-rose-300/16 bg-slate-950/45',
backdrop: 'bg-[linear-gradient(155deg,rgba(244,63,94,0.14),rgba(15,23,42,0.96)_40%,rgba(45,212,191,0.14))]',
pattern: 'bg-[radial-gradient(circle_at_20%_18%,rgba(251,113,133,0.14),transparent_24%),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px),linear-gradient(180deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[length:auto,22px_22px,22px_22px]',
glow: 'bg-rose-300/18',
eyebrow: 'text-rose-100/82',
iconWrap: 'border-rose-200/20 bg-rose-300/12 text-rose-100',
action: 'border-rose-300/22 bg-rose-300/10 text-rose-100 hover:border-rose-300/34 hover:bg-rose-300/16',
item: 'border-rose-200/10 bg-slate-950/38 hover:border-rose-200/18 hover:bg-slate-950/52',
itemEyebrow: 'text-rose-100/75',
itemMeta: 'text-rose-100/70',
empty: 'border-rose-200/10 bg-slate-950/30 text-rose-50/80',
},
renderItem: (item, index, theme) => (
Prompt template #{index + 1}
{item.title}
Template
Reusable workflow
),
},
{
key: 'challenges',
eyebrow: 'Current challenges',
title: 'Build around a brief',
description: 'Academy challenges turn lessons and prompt systems into practical output with a clear creative objective.',
icon: 'fa-solid fa-trophy',
items: (featuredChallenges || []).slice(0, 3),
emptyText: 'Current challenges will appear here when the Academy team launches a new guided brief.',
theme: {
shell: 'border-emerald-300/16 bg-slate-950/45',
backdrop: 'bg-[linear-gradient(155deg,rgba(16,185,129,0.14),rgba(15,23,42,0.96)_42%,rgba(56,189,248,0.12))]',
pattern: 'bg-[radial-gradient(circle_at_top_left,rgba(110,231,183,0.14),transparent_24%),linear-gradient(135deg,transparent_0%,transparent_48%,rgba(16,185,129,0.08)_48%,rgba(16,185,129,0.08)_56%,transparent_56%,transparent_100%)]',
glow: 'bg-emerald-300/18',
eyebrow: 'text-emerald-100/82',
iconWrap: 'border-emerald-200/20 bg-emerald-300/12 text-emerald-100',
action: 'border-emerald-300/22 bg-emerald-300/10 text-emerald-100 hover:border-emerald-300/34 hover:bg-emerald-300/16',
item: 'border-emerald-200/10 bg-slate-950/38 hover:border-emerald-200/18 hover:bg-slate-950/52',
itemEyebrow: 'text-emerald-100/75',
itemMeta: 'text-emerald-100/70',
empty: 'border-emerald-200/10 bg-slate-950/30 text-emerald-50/80',
},
renderItem: (item, index, theme) => (
#{index + 1}
Active brief
{item.title}
Apply what you learned
),
},
]
const handleAccessAction = () => {
if (!useBillingAction) {
trackUpgradeClick(analytics, { source: 'academy_home_hero' })
}
}
const academyMetrics = [
{
key: 'courses',
label: 'Courses',
value: stats?.courseCount || 0,
accent: {
shell: 'border-sky-300/14 bg-sky-300/[0.08]',
label: 'text-sky-100/78',
},
},
{
key: 'lessons',
label: 'Lessons',
value: stats?.lessonCount || 0,
accent: {
shell: 'border-amber-300/14 bg-amber-300/[0.08]',
label: 'text-amber-100/78',
},
},
{
key: 'prompts',
label: 'Prompts',
value: stats?.promptCount || 0,
accent: {
shell: 'border-rose-300/14 bg-rose-300/[0.08]',
label: 'text-rose-100/78',
},
},
{
key: 'challenges',
label: 'Challenges',
value: stats?.challengeCount || 0,
accent: {
shell: 'border-emerald-300/14 bg-emerald-300/[0.08]',
label: 'text-emerald-100/78',
},
},
]
const jsonLd = [{
'@context': 'https://schema.org',
'@type': 'WebPage',
name: 'Skinbase AI Academy',
description: seo?.description,
url: seo?.canonical,
}]
return (
Skinbase AI Academy
Learn how to turn prompts into wallpapers, digital art, skins, covers, and visual worlds.
Skinbase AI Academy is the creative learning hub for AI-assisted art on Skinbase. Start with free lessons, explore prompt templates, and unlock premium workflows later.
Browse courses
Browse lessons
Open prompt library
Top prompts
trackUpgradeClick(analytics, { source: 'academy_home_hero' })} className="rounded-full border border-sky-300/25 bg-sky-300/12 px-5 py-3 text-sm font-semibold text-sky-100 transition hover:border-sky-300/40 hover:bg-sky-300/18">See plans
Your Academy access
{accessHeading}
{accessMeta.map((item) => (
{item.label}
{item.value}
))}
{accessActionLabel}
{academyAccess?.status === 'grace_period' ?
Opens billing account to restore renewal before access ends.
: null}
Choose your Academy lane
Start with the format that matches how you learn.
Courses, lessons, prompts
{academySections.map((section) => (
))}
{academyMetrics.map((metric) => (
))}
{featuredCourses?.length ? (
Featured courses
Guided Academy paths
Longer learning paths for people who want a clearer start-to-finish route instead of individual tutorials or standalone prompt templates.
{formatStatValue(featuredCourses.length, 'featured path')}
All courses
{featuredCourses.slice(0, 3).map((course) => )}
) : null}
{academyFeatureRails.map((rail) => (
rail.renderItem(item, index, rail.theme)}
/>
))}
)
}