Replace native selects with NovaSelect
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Link, usePage } from '@inertiajs/react'
|
||||
import NovaSelect from '../components/ui/NovaSelect'
|
||||
import { studioModule, studioSurface, trackStudioEvent } from '../utils/studioEvents'
|
||||
|
||||
const baseNavGroups = [
|
||||
@@ -15,8 +16,9 @@ const baseNavGroups = [
|
||||
label: 'Create',
|
||||
items: [
|
||||
{ label: 'New Artwork', href: '/upload', icon: 'fa-solid fa-cloud-arrow-up' },
|
||||
{ label: 'Upload Queue', href: '/studio/upload-queue', icon: 'fa-solid fa-layer-group' },
|
||||
{ label: 'New Card', href: '/studio/cards/create', icon: 'fa-solid fa-id-card' },
|
||||
{ label: 'New Story', href: '/creator/stories/create', icon: 'fa-solid fa-feather-pointed' },
|
||||
{ label: 'New Story', href: '/studio/stories/create', icon: 'fa-solid fa-feather-pointed', fullLoad: true },
|
||||
{ label: 'New Collection', href: '/settings/collections/create', icon: 'fa-solid fa-layer-group' },
|
||||
],
|
||||
},
|
||||
@@ -34,8 +36,9 @@ const baseNavGroups = [
|
||||
label: 'Library',
|
||||
items: [
|
||||
{ label: 'Drafts', href: '/studio/drafts', icon: 'fa-solid fa-file-pen' },
|
||||
{ label: 'Upload Queue', href: '/studio/upload-queue', icon: 'fa-solid fa-list-check' },
|
||||
{ label: 'Scheduled', href: '/studio/scheduled', icon: 'fa-solid fa-calendar-days' },
|
||||
{ label: 'Calendar', href: '/studio/calendar', icon: 'fa-solid fa-calendar-range' },
|
||||
{ label: 'Calendar', href: '/studio/calendar', icon: 'fa-solid fa-calendar-days' },
|
||||
{ label: 'Archived', href: '/studio/archived', icon: 'fa-solid fa-box-archive' },
|
||||
{ label: 'Assets', href: '/studio/assets', icon: 'fa-solid fa-photo-film' },
|
||||
],
|
||||
@@ -71,7 +74,7 @@ const baseNavGroups = [
|
||||
const baseQuickCreateItems = [
|
||||
{ label: 'Artwork', href: '/upload', icon: 'fa-solid fa-cloud-arrow-up' },
|
||||
{ label: 'Card', href: '/studio/cards/create', icon: 'fa-solid fa-id-card' },
|
||||
{ label: 'Story', href: '/creator/stories/create', icon: 'fa-solid fa-feather-pointed' },
|
||||
{ label: 'Story', href: '/studio/stories/create', icon: 'fa-solid fa-feather-pointed', fullLoad: true },
|
||||
{ label: 'Collection', href: '/settings/collections/create', icon: 'fa-solid fa-layer-group' },
|
||||
]
|
||||
|
||||
@@ -145,14 +148,25 @@ function navigateToStudioUrl(targetUrl) {
|
||||
}
|
||||
|
||||
function NavLink({ item, active }) {
|
||||
const className = `flex items-center gap-3 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 ${
|
||||
active
|
||||
? 'bg-accent/20 text-accent shadow-sm shadow-accent/10'
|
||||
: 'text-slate-400 hover:text-white hover:bg-white/5'
|
||||
}`
|
||||
|
||||
if (item.fullLoad) {
|
||||
return (
|
||||
<a href={item.href} className={className}>
|
||||
<i className={`${item.icon} w-5 text-center text-base`} />
|
||||
<span>{item.label}</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={item.href}
|
||||
className={`flex items-center gap-3 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 ${
|
||||
active
|
||||
? 'bg-accent/20 text-accent shadow-sm shadow-accent/10'
|
||||
: 'text-slate-400 hover:text-white hover:bg-white/5'
|
||||
}`}
|
||||
className={className}
|
||||
>
|
||||
<i className={`${item.icon} w-5 text-center text-base`} />
|
||||
<span>{item.label}</span>
|
||||
@@ -169,6 +183,7 @@ export default function StudioLayout({ children, title, subtitle, actions }) {
|
||||
const currentGroup = props.studioGroup || null
|
||||
const canManageNews = Boolean(props.auth?.user?.is_admin || props.auth?.user?.is_moderator)
|
||||
const canManageWorlds = canManageNews
|
||||
const isStaff = Boolean(props.auth?.user?.is_staff)
|
||||
|
||||
const navGroups = baseNavGroups.map((group) => {
|
||||
if ((!canManageNews && !canManageWorlds) || group.label !== 'Content') {
|
||||
@@ -312,6 +327,7 @@ export default function StudioLayout({ children, title, subtitle, actions }) {
|
||||
navGroups={navGroups}
|
||||
quickCreateItems={quickCreateItems}
|
||||
isActive={isActive}
|
||||
isStaff={isStaff}
|
||||
onNavigate={() => setMobileOpen(false)}
|
||||
onQuickCreate={handleQuickCreateClick}
|
||||
onContextChange={handleContextChange}
|
||||
@@ -328,6 +344,7 @@ export default function StudioLayout({ children, title, subtitle, actions }) {
|
||||
navGroups={navGroups}
|
||||
quickCreateItems={quickCreateItems}
|
||||
isActive={isActive}
|
||||
isStaff={isStaff}
|
||||
onQuickCreate={handleQuickCreateClick}
|
||||
onContextChange={handleContextChange}
|
||||
/>
|
||||
@@ -384,25 +401,22 @@ export default function StudioLayout({ children, title, subtitle, actions }) {
|
||||
|
||||
function ContextSwitcher({ currentGroup, studioGroups, onContextChange }) {
|
||||
return (
|
||||
<label className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-black/20 px-3 py-2 text-sm text-slate-200">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-black/20 px-3 py-2 text-sm text-slate-200">
|
||||
<i className="fa-solid fa-people-group text-sky-200" />
|
||||
<select
|
||||
<NovaSelect
|
||||
value={currentGroup?.slug || ''}
|
||||
onChange={(event) => onContextChange?.(event.target.value)}
|
||||
className="bg-transparent text-sm text-white outline-none"
|
||||
>
|
||||
<option value="" className="bg-slate-950 text-white">Personal studio</option>
|
||||
{studioGroups.map((group) => (
|
||||
<option key={group.slug} value={group.slug} className="bg-slate-950 text-white">
|
||||
{group.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
onChange={(value) => onContextChange?.(value)}
|
||||
options={[
|
||||
{ value: '', label: 'Personal studio' },
|
||||
...studioGroups.map((group) => ({ value: group.slug, label: group.name })),
|
||||
]}
|
||||
searchable={false}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function StudioSidebarContent({ currentGroup, studioGroups, navGroups, quickCreateItems, isActive, onNavigate, onQuickCreate, onContextChange }) {
|
||||
function StudioSidebarContent({ currentGroup, studioGroups, navGroups, quickCreateItems, isActive, isStaff, onNavigate, onQuickCreate, onContextChange }) {
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6 rounded-[26px] border border-white/10 bg-white/[0.04] p-4">
|
||||
@@ -412,16 +426,16 @@ function StudioSidebarContent({ currentGroup, studioGroups, navGroups, quickCrea
|
||||
{studioGroups.length > 0 ? (
|
||||
<div className="mt-4 rounded-2xl border border-white/10 bg-black/20 p-3">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Context</p>
|
||||
<select
|
||||
<NovaSelect
|
||||
value={currentGroup?.slug || ''}
|
||||
onChange={(event) => onContextChange?.(event.target.value)}
|
||||
className="mt-2 w-full rounded-xl border border-white/10 bg-slate-950/80 px-3 py-2 text-sm text-white outline-none"
|
||||
>
|
||||
<option value="">Personal studio</option>
|
||||
{studioGroups.map((group) => (
|
||||
<option key={group.slug} value={group.slug}>{group.name}</option>
|
||||
))}
|
||||
</select>
|
||||
onChange={(value) => onContextChange?.(value)}
|
||||
className="mt-2"
|
||||
options={[
|
||||
{ value: '', label: 'Personal studio' },
|
||||
...studioGroups.map((group) => ({ value: group.slug, label: group.name })),
|
||||
]}
|
||||
searchable={false}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -437,6 +451,20 @@ function StudioSidebarContent({ currentGroup, studioGroups, navGroups, quickCrea
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{isStaff && (
|
||||
<div>
|
||||
<h3 className="mb-2 px-3 text-[11px] font-semibold uppercase tracking-[0.22em] text-rose-500/70">Administration</h3>
|
||||
<div className="space-y-1">
|
||||
<a
|
||||
href="/moderation"
|
||||
className="flex items-center gap-3 rounded-xl px-4 py-2.5 text-sm font-medium text-rose-300/70 transition hover:bg-rose-500/10 hover:text-rose-300"
|
||||
>
|
||||
<i className="fa-solid fa-shield-halved w-5 text-center text-base" />
|
||||
<span>Admin Panel</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
|
||||
<div className="mt-6 rounded-[24px] border border-white/10 bg-[linear-gradient(135deg,_rgba(15,23,42,0.95),_rgba(12,74,110,0.4))] p-4">
|
||||
|
||||
Reference in New Issue
Block a user