import React from 'react' import { router, usePage } from '@inertiajs/react' import StudioLayout from '../../Layouts/StudioLayout' import NovaSelect from '../../components/ui/NovaSelect' function formatDate(value) { if (!value) return 'Draft' const date = new Date(value) if (Number.isNaN(date.getTime())) return 'Draft' return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', }) } function statusTone(status) { switch (status) { case 'published': return 'border-emerald-300/20 bg-emerald-400/10 text-emerald-100' case 'scheduled': return 'border-sky-300/20 bg-sky-400/10 text-sky-100' case 'in_review': return 'border-amber-300/20 bg-amber-400/10 text-amber-100' case 'archived': return 'border-white/10 bg-white/[0.05] text-slate-300' default: return 'border-white/10 bg-white/[0.05] text-slate-300' } } export default function StudioNewsIndex() { const { props } = usePage() const items = Array.isArray(props.listing?.items) ? props.listing.items : [] const filters = props.listing?.filters || {} const meta = props.listing?.meta || {} const deleteItem = (item) => { if (!item?.delete_url) return if (!window.confirm(`Move "${item.title}" to trash?`)) return router.delete(item.delete_url, { preserveScroll: true, }) } const updateFilter = (next) => { router.get('/studio/news', { ...filters, ...next, page: 1, }, { preserveState: true, preserveScroll: true, }) } return (

Editorial surface

Run a first-party newsroom for launches, tutorials, and community stories.

Pinned stories drive the hero, featured pieces strengthen discovery, and related entity links keep News wired into Groups, releases, collections, and profiles.

New article Taxonomies
Status updateFilter({ status: value, q: filters.q || '', type: filters.type || '', category_id: filters.category_id || '' })} placeholder="All statuses" options={(Array.isArray(props.statusOptions) ? props.statusOptions : []).map((option) => ({ value: option.value, label: option.label }))} searchable={false} />
Type updateFilter({ type: value, q: filters.q || '', status: filters.status || '', category_id: filters.category_id || '' })} placeholder="All types" options={(Array.isArray(props.typeOptions) ? props.typeOptions : []).map((option) => ({ value: option.value, label: option.label }))} searchable={false} />
Category updateFilter({ category_id: value, q: filters.q || '', status: filters.status || '', type: filters.type || '' })} placeholder="All categories" options={(Array.isArray(props.categoryOptions) ? props.categoryOptions : []).map((option) => ({ value: String(option.id), label: option.name }))} searchable={false} />
{Number(meta.total || 0).toLocaleString()} articles
{items.length > 0 ? items.map((item) => (
{item.cover_url ? {item.title} :
}
{item.type_label} {item.editorial_status.replaceAll('_', ' ')} {item.is_pinned ? Pinned : null} {item.is_featured ? Featured : null}

{item.title}

{item.category_name ? {item.category_name} : null} {item.author_name} {formatDate(item.published_at)}
Edit {item.editorial_status === 'published' ? 'View' : 'Preview'}
)) :
No News articles match the current filters.
}
) }