fixed browse and tailwindcss style
This commit is contained in:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user