Implement creator studio and upload updates

This commit is contained in:
2026-04-04 10:12:02 +02:00
parent 1da7d3bf88
commit 0b216b7ecd
15107 changed files with 31206 additions and 626514 deletions

View File

@@ -0,0 +1,63 @@
import React from 'react'
import { router, usePage } from '@inertiajs/react'
import StudioLayout from '../../Layouts/StudioLayout'
export default function StudioSearch() {
const { props } = usePage()
const search = props.search || {}
const filters = search.filters || {}
const sections = search.sections || []
const updateFilters = (patch) => {
router.get(window.location.pathname, { ...filters, ...patch }, {
preserveScroll: true,
preserveState: true,
replace: true,
})
}
return (
<StudioLayout title={props.title} subtitle={props.description}>
<div className="space-y-6">
<section className="rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.14),_transparent_35%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 lg:p-6">
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-5">
<label className="space-y-2 text-sm text-slate-300 xl:col-span-3"><span className="block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Search Studio</span><input value={filters.q || ''} onChange={(event) => updateFilters({ q: event.target.value })} className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white" placeholder="Search content, comments, inbox, or assets" /></label>
<label className="space-y-2 text-sm text-slate-300"><span className="block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Surface</span><select value={filters.type || 'all'} onChange={(event) => updateFilters({ type: event.target.value })} className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white">{(search.type_options || []).map((option) => <option key={option.value} value={option.value} className="bg-slate-900">{option.label}</option>)}</select></label>
<label className="space-y-2 text-sm text-slate-300"><span className="block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Module</span><select value={filters.module || 'all'} onChange={(event) => updateFilters({ module: event.target.value })} className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white">{(search.module_options || []).map((option) => <option key={option.value} value={option.value} className="bg-slate-900">{option.label}</option>)}</select></label>
</div>
</section>
{filters.q ? (
<div className="space-y-6">
<div className="text-sm text-slate-400">Found <span className="font-semibold text-white">{Number(search.summary?.total || 0).toLocaleString()}</span> matches for <span className="font-semibold text-white">{search.summary?.query}</span></div>
{sections.length > 0 ? sections.map((section) => (
<section key={section.key} className="rounded-[30px] border border-white/10 bg-white/[0.03] p-6">
<div className="flex items-center justify-between gap-3"><h2 className="text-lg font-semibold text-white">{section.label}</h2><span className="text-xs uppercase tracking-[0.18em] text-slate-500">{section.count} matches</span></div>
<div className="mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3">{section.items.map((item) => <a key={item.id} href={item.href} className="block rounded-[24px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20"><div className="flex items-start gap-3"><div className="flex h-10 w-10 items-center justify-center rounded-2xl bg-white/[0.04] text-sky-100"><i className={item.icon} /></div><div className="min-w-0"><div className="truncate text-base font-semibold text-white">{item.title}</div><div className="mt-1 text-xs uppercase tracking-[0.18em] text-slate-500">{item.subtitle}</div><p className="mt-3 line-clamp-3 text-sm leading-6 text-slate-400">{item.description}</p></div></div></a>)}</div>
</section>
)) : <div className="rounded-[28px] border border-dashed border-white/15 px-6 py-16 text-center text-slate-400">No results matched this search yet.</div>}
</div>
) : (
<div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_320px]">
<section className="rounded-[30px] border border-white/10 bg-white/[0.03] p-6">
<h2 className="text-lg font-semibold text-white">Continue working</h2>
<div className="mt-4 grid gap-3 md:grid-cols-2">{(search.empty_state?.continue_working || []).map((item) => <a key={item.id} href={item.edit_url || item.manage_url} className="block rounded-[24px] border border-white/10 bg-black/20 p-4"><div className="text-sm font-semibold text-white">{item.title}</div><div className="mt-1 text-xs text-slate-500">{item.module_label} · {item.workflow?.readiness?.label}</div></a>)}</div>
</section>
<aside className="space-y-6">
<section className="rounded-[30px] border border-white/10 bg-white/[0.03] p-5">
<h2 className="text-lg font-semibold text-white">Stale drafts</h2>
<div className="mt-4 space-y-3">{(search.empty_state?.stale_drafts || []).map((item) => <a key={item.id} href={item.edit_url || item.manage_url} className="block rounded-2xl border border-white/10 bg-black/20 p-4"><div className="text-sm font-semibold text-white">{item.title}</div><div className="mt-1 text-xs text-slate-500">{item.module_label}</div></a>)}</div>
</section>
<section className="rounded-[30px] border border-white/10 bg-white/[0.03] p-5">
<h2 className="text-lg font-semibold text-white">Quick create</h2>
<div className="mt-4 grid gap-3">{(props.quickCreate || []).map((item) => <a key={item.key} href={item.url} className="inline-flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-100"><i className={item.icon} /><span>New {item.label}</span></a>)}</div>
</section>
</aside>
</div>
)}
</div>
</StudioLayout>
)
}