Wire admin studio SSR and search infrastructure

This commit is contained in:
2026-05-01 11:46:06 +02:00
parent 257b0dbef6
commit 18cea8b0f0
329 changed files with 197465 additions and 2741 deletions

View 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>
)
}