Commit workspace changes
This commit is contained in:
@@ -30,6 +30,13 @@ export default function Step2Details({
|
||||
onContentTypeChange,
|
||||
onRootCategoryChange,
|
||||
onSubCategoryChange,
|
||||
groupOptions,
|
||||
currentContributorOptions,
|
||||
onGroupChange,
|
||||
onPrimaryAuthorChange,
|
||||
onContributorToggle,
|
||||
onContributorRoleChange,
|
||||
onContributorPrimaryChange,
|
||||
// Sidebar (title / tags / description / rights)
|
||||
suggestedTags,
|
||||
publishMode,
|
||||
@@ -93,6 +100,7 @@ export default function Step2Details({
|
||||
const q = subCategorySearch.trim().toLowerCase()
|
||||
return q ? sorted.filter((s) => s.name.toLowerCase().includes(q)) : sorted
|
||||
}, [subCategories, subCategorySearch])
|
||||
const contributorCredits = metadata.contributorCredits || {}
|
||||
|
||||
useEffect(() => {
|
||||
if (!metadata.contentType) {
|
||||
@@ -469,6 +477,128 @@ export default function Step2Details({
|
||||
)}
|
||||
</section>
|
||||
|
||||
{Array.isArray(groupOptions) && groupOptions.length > 0 && (
|
||||
<section className="rounded-2xl border border-white/10 bg-[radial-gradient(ellipse_at_top_left,_rgba(56,189,248,0.08),_transparent_42%),linear-gradient(180deg,rgba(255,255,255,0.04),rgba(255,255,255,0.02))] p-5 sm:p-6">
|
||||
<div className="mb-5 flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-white">Publisher attribution</h3>
|
||||
<p className="mt-1 text-xs text-white/55">Publish personally or switch into a group identity while preserving author and contributor credits.</p>
|
||||
</div>
|
||||
{metadata.group ? <span className="rounded-full border border-sky-300/20 bg-sky-300/10 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100">Group publish</span> : <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300">Personal publish</span>}
|
||||
</div>
|
||||
|
||||
<label className="block">
|
||||
<span className="text-sm font-medium text-white/90">Publishing identity</span>
|
||||
<select
|
||||
value={metadata.group || ''}
|
||||
onChange={(event) => onGroupChange?.(event.target.value)}
|
||||
className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
|
||||
>
|
||||
<option value="">Personal profile</option>
|
||||
{groupOptions.map((group) => (
|
||||
<option key={group.slug} value={group.slug}>{group.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{metadata.group && (
|
||||
<div className="mt-5 grid gap-5 lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
|
||||
<div>
|
||||
<label className="block">
|
||||
<span className="text-sm font-medium text-white/90">Primary author</span>
|
||||
<select
|
||||
value={metadata.primaryAuthorUserId || ''}
|
||||
onChange={(event) => onPrimaryAuthorChange?.(event.target.value)}
|
||||
className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
|
||||
>
|
||||
{currentContributorOptions.map((user) => (
|
||||
<option key={user.id} value={user.id}>{user.name || user.username}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<p className="mt-2 text-xs text-slate-400">The primary author is shown as the lead creator for this group-published artwork.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<span className="text-sm font-medium text-white/90">Contributors</span>
|
||||
<span className="text-xs text-slate-500">Optional</span>
|
||||
</div>
|
||||
<div className="mt-2 grid gap-2">
|
||||
{currentContributorOptions.filter((user) => Number(user.id) !== Number(metadata.primaryAuthorUserId)).map((user) => {
|
||||
const active = Array.isArray(metadata.contributorUserIds) && metadata.contributorUserIds.some((id) => Number(id) === Number(user.id))
|
||||
const creditMeta = contributorCredits?.[user.id] || contributorCredits?.[String(user.id)] || { creditRole: '', isPrimary: false }
|
||||
|
||||
return (
|
||||
<div
|
||||
key={user.id}
|
||||
className={[
|
||||
'rounded-2xl border px-3 py-3 transition',
|
||||
active
|
||||
? 'border-sky-300/30 bg-sky-300/10 text-white'
|
||||
: 'border-white/10 bg-white/[0.03] text-slate-200 hover:border-white/20 hover:bg-white/[0.06]',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
{user.avatar_url ? <img src={user.avatar_url} alt={user.name || user.username} className="h-10 w-10 rounded-2xl object-cover" /> : <div className="flex h-10 w-10 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400"><i className="fa-solid fa-user" /></div>}
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="truncate text-sm font-semibold">{user.name || user.username}</div>
|
||||
<div className="truncate text-xs text-slate-400">@{user.username}</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onContributorToggle?.(user.id)}
|
||||
className={[
|
||||
'inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs font-semibold transition',
|
||||
active
|
||||
? 'border-sky-300/40 bg-sky-300/20 text-sky-50'
|
||||
: 'border-white/10 bg-white/[0.03] text-white/70 hover:border-white/20 hover:text-white',
|
||||
].join(' ')}
|
||||
>
|
||||
<span className={['inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px]', active ? 'border-sky-300/40 bg-sky-300/20 text-sky-50' : 'border-white/10 bg-white/[0.03] text-white/35'].join(' ')}>{active ? '✓' : ''}</span>
|
||||
{active ? 'Added' : 'Add credit'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{active ? (
|
||||
<div className="mt-4 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto] md:items-end">
|
||||
<label className="block">
|
||||
<span className="text-xs font-medium uppercase tracking-[0.16em] text-slate-300">Credit role</span>
|
||||
<input
|
||||
type="text"
|
||||
value={creditMeta.creditRole || ''}
|
||||
onChange={(event) => onContributorRoleChange?.(user.id, event.target.value)}
|
||||
placeholder="Colorist, concept support, layout..."
|
||||
aria-label={`Credit role for ${user.name || user.username}`}
|
||||
className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onContributorPrimaryChange?.(user.id)}
|
||||
aria-pressed={creditMeta.isPrimary ? 'true' : 'false'}
|
||||
aria-label={`Mark ${user.name || user.username} as lead supporting credit`}
|
||||
className={[
|
||||
'inline-flex items-center justify-center rounded-xl border px-3 py-3 text-sm font-medium transition',
|
||||
creditMeta.isPrimary
|
||||
? 'border-emerald-300/35 bg-emerald-400/12 text-emerald-100'
|
||||
: 'border-white/10 bg-white/[0.03] text-slate-200 hover:border-white/20 hover:bg-white/[0.06] hover:text-white',
|
||||
].join(' ')}
|
||||
>
|
||||
{creditMeta.isPrimary ? 'Lead support' : 'Set lead support'}
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Title, tags, description, rights */}
|
||||
<UploadSidebar
|
||||
showHeader={false}
|
||||
|
||||
Reference in New Issue
Block a user