import React, { useEffect, useState } from 'react' import { Head, Link, router, usePage } from '@inertiajs/react' import AdminLayout from '../../../Layouts/AdminLayout' const PROMPT_VIEW_STORAGE_KEY = 'skinbase.admin.academy.prompts.view' const PROMPT_VIEW_OPTIONS = [ { value: 'gallery', label: 'Gallery', icon: 'fa-images' }, { value: 'grid', label: 'Grid', icon: 'fa-grid-2' }, { value: 'table', label: 'Table', icon: 'fa-table-list' }, ] function formatDateLabel(value) { if (!value) return 'Recently updated' const date = new Date(value) if (Number.isNaN(date.getTime())) return 'Recently updated' return new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'short', year: 'numeric' }).format(date) } function paginationLabel(label) { return String(label || '') .replace(/«/g, 'Previous') .replace(/»/g, 'Next') .replace(/<[^>]+>/g, '') .trim() } function promptSummary(items = []) { return items.reduce((summary, item) => ({ total: summary.total + 1, active: summary.active + (item.active ? 1 : 0), featured: summary.featured + (item.featured ? 1 : 0), promptOfWeek: summary.promptOfWeek + (item.prompt_of_week ? 1 : 0), comparisons: summary.comparisons + Number(item.comparisons_count || 0), }), { total: 0, active: 0, featured: 0, promptOfWeek: 0, comparisons: 0 }) } function PromptFlag({ children, tone = 'default' }) { const toneClass = tone === 'warm' ? 'border-[#ffcfbf]/20 bg-[#ffcfbf]/10 text-[#fff0ea]' : tone === 'sky' ? 'border-sky-300/20 bg-sky-300/10 text-sky-100' : tone === 'emerald' ? 'border-emerald-300/20 bg-emerald-300/10 text-emerald-100' : 'border-white/10 bg-white/[0.05] text-slate-200' return {children} } function PromptActions({ item }) { return (
{item.preview_url ? Preview : null} Edit
) } function PromptPreview({ item, compact = false }) { if (item.preview_image_url) { return {item.title} } return (

Prompt preview

No image attached yet

) } function PromptMeta({ item }) { return (
{item.category_name ? {item.category_name} : null} {item.difficulty ? {item.difficulty} : null} {item.access_level ? {item.access_level} : null} {item.aspect_ratio ? {item.aspect_ratio} : null} {item.featured ? Featured : null} {item.prompt_of_week ? Prompt of week : null} {item.active ? 'Active' : 'Draft'}
) } function PromptGalleryCard({ item }) { return (
{item.comparisons_count || 0} comparisons {item.slug ? {item.slug} : null}

{item.title}

{item.excerpt || 'Add an excerpt to make this prompt easier to scan in moderation.'}

{item.tags?.length ? (
{item.tags.slice(0, 5).map((tag) => ( {tag} ))}
) : null}

Updated

{formatDateLabel(item.updated_at)}

Access

{item.access_level || 'free'}

Status

{item.active ? 'Visible' : 'Hidden'}

) } function PromptGridCard({ item }) { return (

{item.title}

{item.excerpt || 'No excerpt added yet.'}

{formatDateLabel(item.updated_at)} {item.comparisons_count || 0} comparisons
) } function PromptTable({ items }) { return (
{items.map((item) => ( ))}
Prompt Category Access Signals Updated Actions

{item.title}

{item.excerpt || 'No excerpt added yet.'}

{item.category_name || 'Uncategorized'} {item.access_level || 'free'}

{item.comparisons_count || 0} comparisons

{item.difficulty || 'No difficulty'}

{item.active ? 'Active' : 'Draft'}

{formatDateLabel(item.updated_at)}
{item.preview_url ? Preview : null} Edit
) } function PromptHeroCollage({ items = [] }) { const images = items .map((item) => item?.preview_image_url) .filter(Boolean) .slice(0, 4) if (!images.length) { return (

Prompt preview wall

Preview images will appear here as prompts get covers.

) } return (
{images.map((image, index) => (
))}
) } function PaginationLinks({ links = [] }) { if (!Array.isArray(links) || links.length <= 3) return null return (
{links.map((link, index) => { const label = paginationLabel(link.label) const className = link.active ? 'border-sky-300/25 bg-sky-300/12 text-sky-100' : 'border-white/10 bg-white/[0.04] text-slate-200 hover:border-white/20 hover:bg-white/[0.07]' return link.url ? ( {label} ) : ( {label} ) })}
) } function PromptIndexContent({ title, subtitle, items, createUrl }) { const promptItems = items?.data || [] const summary = promptSummary(promptItems) const [viewMode, setViewMode] = useState('gallery') useEffect(() => { if (typeof window === 'undefined') return const storedView = window.localStorage.getItem(PROMPT_VIEW_STORAGE_KEY) if (PROMPT_VIEW_OPTIONS.some((option) => option.value === storedView)) { setViewMode(storedView) } }, []) useEffect(() => { if (typeof window === 'undefined') return window.localStorage.setItem(PROMPT_VIEW_STORAGE_KEY, viewMode) }, [viewMode]) return (
Academy moderation Prompt library

{title}

{subtitle} Review prompts in a visual-first moderation surface, jump into edits quickly, and switch between gallery, grid, or table depending on the task in front of you.

Visual-first

Curate covers and prompt outputs before opening the form.

Workflow-ready

Switch between gallery, compact cards, and scan-heavy tables.

Comparison-aware

Spot prompts with provider notes and attached result references.

{PROMPT_VIEW_OPTIONS.map((option) => { const active = option.value === viewMode return ( ) })}
Create prompt Open public library {summary.total} prompts in view

Active

{summary.active}

Featured

{summary.featured}

Prompt of week

{summary.promptOfWeek}

Comparisons

{summary.comparisons}

Manage Academy content below. Changes clear Academy cache automatically.

View public library Create prompt
{promptItems.length === 0 ? (
No prompt templates exist yet.
) : viewMode === 'table' ? ( ) : viewMode === 'grid' ? (
{promptItems.map((item) => )}
) : (
{promptItems.map((item) => )}
)}
) } export default function AcademyCrudIndex({ title, subtitle, items, columns, createUrl }) { const flash = usePage().props.flash || {} return ( {flash.success ?
{flash.success}
: null} {usePage().props.resource === 'prompts' ? ( ) : ( <>

Manage Academy content below. Changes clear Academy cache automatically.

Create record
{(items?.data || []).length === 0 ? (
No records exist yet.
) : (
{items.data.map((item) => (
{columns.map((column) => (

{column.replaceAll('_', ' ')}

{String(item[column] ?? '')}

))}
{item.builder_url ? Builder : null} Edit
))}
)} )}
) }