74 lines
5.1 KiB
JavaScript
74 lines
5.1 KiB
JavaScript
import React from 'react'
|
|
import { router, usePage } from '@inertiajs/react'
|
|
import StudioLayout from '../../Layouts/StudioLayout'
|
|
|
|
function actionUrl(item, key) {
|
|
return item?.urls?.[key] || ''
|
|
}
|
|
|
|
export default function StudioGroupReviewQueue() {
|
|
const { props } = usePage()
|
|
const listing = props.listing || {}
|
|
const items = Array.isArray(listing.items) ? listing.items : []
|
|
|
|
const sendAction = (item, action) => {
|
|
const notes = window.prompt('Optional reviewer note', '') || ''
|
|
router.post(actionUrl(item, action), { action, review_notes: notes })
|
|
}
|
|
|
|
return (
|
|
<StudioLayout title={props.title} subtitle={props.description}>
|
|
<div className="grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]">
|
|
<section className="rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
|
|
<div className="flex items-center justify-between gap-3">
|
|
<div>
|
|
<h2 className="text-xl font-semibold text-white">Submission queue</h2>
|
|
<p className="mt-1 text-sm text-slate-400">Review artwork drafts before they publish under the group identity.</p>
|
|
</div>
|
|
<span className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-300">{listing.filters?.bucket || 'submitted'}</span>
|
|
</div>
|
|
|
|
<div className="mt-4 space-y-4">
|
|
{items.length > 0 ? items.map((item) => (
|
|
<article key={item.id} className="rounded-[24px] border border-white/10 bg-black/20 p-4">
|
|
<div className="flex flex-wrap items-start gap-4">
|
|
{item.thumb ? <img src={item.thumb} alt={item.title} className="h-24 w-24 rounded-2xl object-cover" /> : <div className="flex h-24 w-24 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400"><i className="fa-solid fa-image" /></div>}
|
|
<div className="min-w-0 flex-1">
|
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
|
<h3 className="text-lg font-semibold text-white">{item.title}</h3>
|
|
<span className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-300">{item.group_review_status}</span>
|
|
</div>
|
|
<div className="mt-2 flex flex-wrap gap-3 text-xs text-slate-400">
|
|
{item.primary_author ? <span>Author: {item.primary_author.name || item.primary_author.username}</span> : null}
|
|
{item.uploader ? <span>Uploader: {item.uploader.name || item.uploader.username}</span> : null}
|
|
{item.submitted_at ? <span>Submitted {new Date(item.submitted_at).toLocaleString()}</span> : null}
|
|
</div>
|
|
{item.group_review_notes ? <p className="mt-3 rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2 text-sm text-slate-300">{item.group_review_notes}</p> : null}
|
|
<div className="mt-4 flex flex-wrap gap-2">
|
|
<a href={item.urls?.edit} className="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white">Open draft</a>
|
|
{item.can_review ? <button type="button" onClick={() => sendAction(item, 'approve')} className="rounded-full border border-emerald-300/20 bg-emerald-400/10 px-4 py-2 text-sm font-semibold text-emerald-100">Approve</button> : null}
|
|
{item.can_review ? <button type="button" onClick={() => sendAction(item, 'needs_changes')} className="rounded-full border border-amber-300/20 bg-amber-400/10 px-4 py-2 text-sm font-semibold text-amber-100">Needs changes</button> : null}
|
|
{item.can_review ? <button type="button" onClick={() => sendAction(item, 'reject')} className="rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100">Reject</button> : null}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
)) : <div className="rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-5 text-sm text-slate-400">No submissions in this bucket.</div>}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
|
|
<h2 className="text-xl font-semibold text-white">Recent history</h2>
|
|
<div className="mt-4 space-y-3">
|
|
{(Array.isArray(props.recentHistory) ? props.recentHistory : []).map((item) => (
|
|
<div key={item.id} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3">
|
|
<div className="text-sm font-semibold text-white">{item.summary || item.action_type}</div>
|
|
<div className="mt-1 text-xs text-slate-400">{item.actor?.name || item.actor?.username || 'System'} • {item.created_at ? new Date(item.created_at).toLocaleString() : 'Recently'}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</StudioLayout>
|
|
)
|
|
} |