fixed browse and tailwindcss style

This commit is contained in:
2026-02-15 11:01:19 +01:00
parent d114472823
commit 7734e53d87
16 changed files with 341 additions and 200 deletions

View File

@@ -406,9 +406,26 @@ export default function UploadWizard({
if (!selected) return []
return categoryTreeByType[selected] || []
}, [categoryTreeByType, metadata.contentType])
const allRootCategoryOptions = useMemo(() => {
const items = []
Object.entries(categoryTreeByType).forEach(([contentTypeValue, roots]) => {
roots.forEach((root) => {
items.push({
...root,
contentTypeValue,
})
})
})
return items
}, [categoryTreeByType])
const selectedRootFromAnyType = useMemo(() => {
const selectedId = String(metadata.rootCategoryId || '')
if (!selectedId) return null
return allRootCategoryOptions.find((root) => String(root.id) === selectedId) || null
}, [allRootCategoryOptions, metadata.rootCategoryId])
const selectedRootCategory = useMemo(() => {
return filteredCategoryTree.find((root) => String(root.id) === String(metadata.rootCategoryId || '')) || null
}, [filteredCategoryTree, metadata.rootCategoryId])
return filteredCategoryTree.find((root) => String(root.id) === String(metadata.rootCategoryId || '')) || selectedRootFromAnyType || null
}, [filteredCategoryTree, metadata.rootCategoryId, selectedRootFromAnyType])
const requiresSubCategory = Boolean(selectedRootCategory && Array.isArray(selectedRootCategory.children) && selectedRootCategory.children.length > 0)
const stepProgressPercent = useMemo(() => {
if (activeStep === 1) return 33
@@ -851,6 +868,12 @@ export default function UploadWizard({
description: String(metadata.description || '').trim() || null,
}
if (resolvedArtworkId && resolvedArtworkId > 0) {
dispatchMachine({ type: 'PUBLISH_SUCCESS' })
emitUploadEvent('upload_publish', { id: publishTargetId })
return
}
if (!machine.sessionId) {
if (!publishTargetId) throw new Error('Missing publish id.')
const publishController = registerController()
@@ -1023,17 +1046,27 @@ export default function UploadWizard({
<div className="max-w-4xl mx-auto px-4 py-6">
<div className="bg-panel/80 backdrop-blur rounded-2xl shadow-xl shadow-black/40 ring-1 ring-white/10 p-6 space-y-5">
<div className="rounded-xl bg-white/5 px-4 py-3 ring-1 ring-white/10">
<h2 ref={stepHeadingRef} tabIndex={-1} className="text-lg font-semibold text-white focus:outline-none">Add details</h2>
<h2 ref={stepHeadingRef} tabIndex={-1} className="text-lg font-semibold text-white focus:outline-none">Artwork details</h2>
<p className="mt-1 text-sm text-white/65">Complete required metadata and rights confirmation before publishing.</p>
</div>
<div className="mb-6 rounded-xl border border-white/8 bg-white/4 p-4">
<p className="text-xs uppercase tracking-wide text-white/55">Uploaded asset</p>
<div className="mt-2 flex items-center gap-3">
<div className="mt-2 flex flex-col gap-3 md:flex-row md:items-center">
{primaryPreviewUrl && !isArchive ? (
<img src={primaryPreviewUrl} alt="Uploaded artwork thumbnail" className="h-20 w-20 rounded-lg border border-white/50 object-cover" />
<div className="flex h-40 w-40 items-center justify-center overflow-hidden rounded-lg border border-white/50 bg-black/25">
<img
src={primaryPreviewUrl}
alt="Uploaded artwork thumbnail"
className="max-h-full max-w-full object-contain"
loading="lazy"
decoding="async"
width="160"
height="160"
/>
</div>
) : (
<div className="grid h-20 w-20 place-items-center rounded-lg border border-white/15 bg-white/5 text-white/60">📦</div>
<div className="grid h-40 w-40 place-items-center rounded-lg border border-white/15 bg-white/5 text-white/60">📦</div>
)}
<div className="min-w-0">
<p className="truncate text-sm font-medium text-white">{primaryFile?.name || 'Primary file selected'}</p>
@@ -1081,6 +1114,10 @@ export default function UploadWizard({
src={iconPath}
alt={`${ct.name || 'Content type'} mascot`}
className={`h-full w-full object-contain transition-all duration-150 ${active ? 'grayscale-0 opacity-100' : 'grayscale opacity-40 group-hover:grayscale-0 group-hover:opacity-90'}`}
loading="lazy"
decoding="async"
width="80"
height="80"
onError={(event) => {
if (event.currentTarget.src.includes('mascot_other.webp')) return
event.currentTarget.src = '/gfx/mascot_other.webp'
@@ -1132,6 +1169,29 @@ export default function UploadWizard({
})}
</div>
)}
<div className="sr-only">
<label htmlFor="upload-root-category">Root category</label>
<select
id="upload-root-category"
value={String(metadata.rootCategoryId || '')}
onChange={(event) => {
const nextRootId = String(event.target.value || '')
const matchedRoot = allRootCategoryOptions.find((root) => String(root.id) === nextRootId)
setMetadata((current) => ({
...current,
contentType: matchedRoot ? String(matchedRoot.contentTypeValue) : current.contentType,
rootCategoryId: nextRootId,
subCategoryId: '',
}))
}}
>
<option value="">Select root category</option>
{allRootCategoryOptions.map((root) => (
<option key={root.id} value={String(root.id)}>{root.name}</option>
))}
</select>
</div>
</div>
{requiresSubCategory && (
@@ -1160,6 +1220,26 @@ export default function UploadWizard({
)
})}
</div>
<div className="sr-only">
<label htmlFor="upload-subcategory">Subcategory</label>
<select
id="upload-subcategory"
value={String(metadata.subCategoryId || '')}
onChange={(event) => {
const nextSubId = String(event.target.value || '')
setMetadata((current) => ({
...current,
subCategoryId: nextSubId,
}))
}}
>
<option value="">Select subcategory</option>
{selectedRootCategory.children.map((sub) => (
<option key={sub.id} value={String(sub.id)}>{sub.name}</option>
))}
</select>
</div>
</div>
)}
@@ -1195,21 +1275,32 @@ export default function UploadWizard({
}
return (
<div className="rounded-2xl border border-white/8 bg-slate-900/70 p-6 sm:p-7">
<div className="mb-6 rounded-xl border border-white/50 bg-white/5 px-4 py-3">
<h2 ref={stepHeadingRef} tabIndex={-1} className="text-lg font-semibold text-white focus:outline-none">Review & publish</h2>
<p className="mt-1 text-sm text-white/65">Review your submission and publish when all checks are ready.</p>
</div>
<div className="max-w-4xl mx-auto px-4 py-6">
<div className="bg-panel/80 backdrop-blur rounded-2xl shadow-xl shadow-black/40 ring-1 ring-white/10 p-6 space-y-5">
<div className="rounded-xl bg-white/5 px-4 py-3 ring-1 ring-white/10">
<h2 ref={stepHeadingRef} tabIndex={-1} className="text-lg font-semibold text-white focus:outline-none">Review & publish</h2>
<p className="mt-1 text-sm text-white/65">Review your submission and publish when all checks are ready.</p>
</div>
<div className="rounded-xl border border-white/8 bg-white/4 p-5">
<div className="flex flex-col gap-4 sm:flex-row">
<div className="w-full sm:w-40">
<div className="rounded-xl border border-white/8 bg-white/4 p-5">
<div className="flex flex-col gap-4 md:flex-row">
<div className="w-40">
{primaryPreviewUrl && !isArchive ? (
<img src={primaryPreviewUrl} alt="Review preview" className="h-32 w-full rounded-lg border border-white/50 object-cover" />
) : (
<div className="grid h-32 w-full place-items-center rounded-lg border border-white/50 bg-black/25 text-white/60">Archive</div>
)}
</div>
<div className="flex h-40 w-40 items-center justify-center overflow-hidden rounded-lg border border-white/50 bg-black/25">
<img
src={primaryPreviewUrl}
alt="Review preview"
className="max-h-full max-w-full object-contain"
loading="lazy"
decoding="async"
width="160"
height="160"
/>
</div>
) : (
<div className="grid h-40 w-40 place-items-center rounded-lg border border-white/50 bg-black/25 text-white/60">Archive</div>
)}
</div>
<div className="min-w-0 flex-1 space-y-2">
<p className="text-base font-semibold text-white">{metadata.title || 'Untitled artwork'}</p>
<p className="text-sm text-white/75">
@@ -1237,11 +1328,12 @@ export default function UploadWizard({
</div>
</div>
</div>
</div>
)
}
return (
<section ref={stepContentRef} className="space-y-8 text-white" data-is-archive={isArchive ? 'true' : 'false'}>
<section ref={stepContentRef} className="space-y-8 pb-24 text-white lg:pb-0" data-is-archive={isArchive ? 'true' : 'false'}>
{showRestoredBanner && (
<div className="rounded-xl border border-sky-300/30 bg-sky-500/10 px-4 py-2 text-sm text-sky-100">
<div className="flex items-center justify-between gap-3">