Replace native selects with NovaSelect

This commit is contained in:
2026-05-01 07:45:37 +02:00
parent 67be537c86
commit 35011001ba
55 changed files with 3136 additions and 1662 deletions

View File

@@ -1,6 +1,7 @@
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'
@@ -36,6 +37,15 @@ export default function StudioNewsIndex() {
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,
@@ -89,45 +99,36 @@ export default function StudioNewsIndex() {
}}
/>
</label>
<label className="grid gap-2 text-sm text-slate-300">
<div className="grid gap-2 text-sm text-slate-300">
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Status</span>
<select
<NovaSelect
value={filters.status || ''}
onChange={(event) => updateFilter({ status: event.target.value, q: filters.q || '', type: filters.type || '', category_id: filters.category_id || '' })}
className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none"
>
<option value="">All statuses</option>
{(Array.isArray(props.statusOptions) ? props.statusOptions : []).map((option) => (
<option key={option.value} value={option.value}>{option.label}</option>
))}
</select>
</label>
<label className="grid gap-2 text-sm text-slate-300">
onChange={(value) => 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}
/>
</div>
<div className="grid gap-2 text-sm text-slate-300">
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Type</span>
<select
<NovaSelect
value={filters.type || ''}
onChange={(event) => updateFilter({ type: event.target.value, q: filters.q || '', status: filters.status || '', category_id: filters.category_id || '' })}
className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none"
>
<option value="">All types</option>
{(Array.isArray(props.typeOptions) ? props.typeOptions : []).map((option) => (
<option key={option.value} value={option.value}>{option.label}</option>
))}
</select>
</label>
<label className="grid gap-2 text-sm text-slate-300">
onChange={(value) => 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}
/>
</div>
<div className="grid gap-2 text-sm text-slate-300">
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Category</span>
<select
<NovaSelect
value={filters.category_id || ''}
onChange={(event) => updateFilter({ category_id: event.target.value, q: filters.q || '', status: filters.status || '', type: filters.type || '' })}
className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none"
>
<option value="">All categories</option>
{(Array.isArray(props.categoryOptions) ? props.categoryOptions : []).map((option) => (
<option key={option.id} value={option.id}>{option.name}</option>
))}
</select>
</label>
onChange={(value) => 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}
/>
</div>
<div className="text-sm text-slate-400 lg:text-right">{Number(meta.total || 0).toLocaleString()} articles</div>
</div>
</section>
@@ -154,6 +155,7 @@ export default function StudioNewsIndex() {
<div className="mt-5 flex flex-wrap gap-2">
<a href={item.edit_url} className="rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 text-sm font-semibold text-sky-100">Edit</a>
<a href={item.editorial_status === 'published' ? item.public_url : item.preview_url} className="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white">{item.editorial_status === 'published' ? 'View' : 'Preview'}</a>
<button type="button" onClick={() => deleteItem(item)} className="rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100">Trash</button>
</div>
</div>
</article>