Wire admin studio SSR and search infrastructure
This commit is contained in:
79
resources/js/Pages/Admin/Artworks.jsx
Normal file
79
resources/js/Pages/Admin/Artworks.jsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import React from 'react'
|
||||
import { Head, router } from '@inertiajs/react'
|
||||
import AdminLayout from '../../Layouts/AdminLayout'
|
||||
|
||||
export default function AdminArtworks({ artworks }) {
|
||||
const items = artworks?.data ?? []
|
||||
|
||||
return (
|
||||
<AdminLayout title="Artworks" subtitle="Browse and manage all artworks on the platform">
|
||||
<Head title="Admin · Artworks" />
|
||||
|
||||
<div className="overflow-hidden rounded-2xl border border-white/[0.07] bg-white/[0.02]">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-white/[0.07] text-left text-xs font-semibold uppercase tracking-wider text-slate-600">
|
||||
<th className="px-5 py-3.5">Artwork</th>
|
||||
<th className="px-5 py-3.5">Author</th>
|
||||
<th className="px-5 py-3.5">Status</th>
|
||||
<th className="px-5 py-3.5">Uploaded</th>
|
||||
<th className="px-5 py-3.5 text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-white/[0.04]">
|
||||
{items.length === 0 && (
|
||||
<tr><td colSpan={5} className="px-5 py-12 text-center text-slate-500">No artworks found.</td></tr>
|
||||
)}
|
||||
{items.map((artwork) => (
|
||||
<tr key={artwork.id} className="transition hover:bg-white/[0.025]">
|
||||
<td className="px-5 py-4">
|
||||
<div className="flex items-center gap-3">
|
||||
{artwork.thumb && (
|
||||
<img src={artwork.thumb} alt={artwork.title} className="h-10 w-10 rounded-lg object-cover" />
|
||||
)}
|
||||
<span className="font-medium text-white">{artwork.title || <span className="italic text-slate-500">Untitled</span>}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-5 py-4 text-slate-400">{artwork.user?.name ?? '—'}</td>
|
||||
<td className="px-5 py-4">
|
||||
<span className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-semibold capitalize ${
|
||||
artwork.status === 'published' ? 'bg-teal-500/20 text-teal-300'
|
||||
: artwork.status === 'pending' ? 'bg-amber-500/20 text-amber-300'
|
||||
: 'bg-slate-500/20 text-slate-400'
|
||||
}`}>{artwork.status ?? 'unknown'}</span>
|
||||
</td>
|
||||
<td className="px-5 py-4 text-slate-500">
|
||||
{artwork.created_at ? new Date(artwork.created_at).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' }) : '—'}
|
||||
</td>
|
||||
<td className="px-5 py-4 text-right">
|
||||
<a href={`/studio/artworks/${artwork.id}/edit`}
|
||||
className="rounded-lg border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-white/70 transition hover:bg-white/[0.09]">
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{artworks?.last_page > 1 && (
|
||||
<div className="flex items-center justify-between border-t border-white/[0.06] px-5 py-4">
|
||||
<p className="text-xs text-slate-500">Showing {artworks.from}–{artworks.to} of {artworks.total} artworks</p>
|
||||
<div className="flex gap-1">
|
||||
{artworks.links.map((link, i) => (
|
||||
link.url ? (
|
||||
<button key={i} type="button" onClick={() => router.get(link.url, {}, { preserveScroll: true })}
|
||||
className={`rounded-lg px-3 py-1.5 text-xs transition ${link.active ? 'bg-rose-500/20 font-semibold text-rose-300' : 'text-slate-500 hover:bg-white/[0.06] hover:text-white'}`}
|
||||
dangerouslySetInnerHTML={{ __html: link.label }} />
|
||||
) : (
|
||||
<span key={i} className="rounded-lg px-3 py-1.5 text-xs text-slate-700" dangerouslySetInnerHTML={{ __html: link.label }} />
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</AdminLayout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user