Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render
This commit is contained in:
@@ -3,8 +3,10 @@ import { usePage } from '@inertiajs/react'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
import TagInput from '../../components/tags/TagInput'
|
||||
import UploadWizard from '../../components/upload/UploadWizard'
|
||||
import UploadDescriptionEditor from '../../components/upload/UploadDescriptionEditor'
|
||||
import Checkbox from '../../Components/ui/Checkbox'
|
||||
import { mapUploadErrorNotice, mapUploadResultNotice } from '../../lib/uploadNotices'
|
||||
import { validateMarkdownLiteContent } from '../../utils/contentValidation'
|
||||
|
||||
const phases = {
|
||||
idle: 'idle',
|
||||
@@ -177,7 +179,7 @@ function getTypeKey(ct) {
|
||||
return String(ct.name || '').toLowerCase().replace(/\s+/g, '_').replace(/[^a-z0-9_]/g, '')
|
||||
}
|
||||
|
||||
function useUploadMachine({ draftId, filesCdnUrl, chunkSize, chunkRequestTimeoutMs, userId }) {
|
||||
function useUploadMachine({ draftId = null, filesCdnUrl = '', chunkSize, chunkRequestTimeoutMs, userId = null } = {}) {
|
||||
const [state, dispatch] = useReducer(reducer, { ...initialState, draftId })
|
||||
const pollRef = useRef(null)
|
||||
const adaptiveChunkSizeRef = useRef(Math.max(1, Number(chunkSize || 0)))
|
||||
@@ -548,6 +550,14 @@ function useUploadMachine({ draftId, filesCdnUrl, chunkSize, chunkRequestTimeout
|
||||
return
|
||||
}
|
||||
|
||||
const descriptionErrors = validateMarkdownLiteContent(state.metadata.description)
|
||||
if (descriptionErrors.length > 0) {
|
||||
const message = descriptionErrors[0]
|
||||
dispatch({ type: 'UPLOAD_ERROR', error: message })
|
||||
pushNotice('error', message)
|
||||
return
|
||||
}
|
||||
|
||||
if (!state.metadata.licenseAccepted) {
|
||||
const message = 'You must confirm ownership of the artwork.'
|
||||
dispatch({ type: 'UPLOAD_ERROR', error: message })
|
||||
@@ -619,7 +629,7 @@ function useUploadMachine({ draftId, filesCdnUrl, chunkSize, chunkRequestTimeout
|
||||
}
|
||||
}
|
||||
|
||||
export default function UploadPage({ draftId, filesCdnUrl, chunkSize, chunkRequestTimeoutMs }) {
|
||||
export default function UploadPage({ draftId = null, filesCdnUrl = '', chunkSize, chunkRequestTimeoutMs } = {}) {
|
||||
const { props } = usePage()
|
||||
const pageTitle = 'Upload Artwork — Creator Studio'
|
||||
const pageDescription = 'Submit a new artwork, complete the required metadata, and publish it from Skinbase Creator Studio.'
|
||||
@@ -745,6 +755,7 @@ export default function UploadPage({ draftId, filesCdnUrl, chunkSize, chunkReque
|
||||
)
|
||||
const categoryOptions = useMemo(() => selectedType?.categories || [], [selectedType])
|
||||
const hasAtLeastOneTag = useMemo(() => parseUiTags(state.metadata.tags).length > 0, [state.metadata.tags])
|
||||
const descriptionErrors = useMemo(() => validateMarkdownLiteContent(state.metadata.description), [state.metadata.description])
|
||||
|
||||
useEffect(() => {
|
||||
// Prefer server-provided props, else try fetching from API endpoints
|
||||
@@ -1047,13 +1058,17 @@ export default function UploadPage({ draftId, filesCdnUrl, chunkSize, chunkReque
|
||||
|
||||
<label className="mt-4 block text-sm">
|
||||
<span className="text-white/80">Description</span>
|
||||
<textarea
|
||||
value={state.metadata.description}
|
||||
onChange={(e) => dispatch({ type: 'SET_METADATA', payload: { description: e.target.value } })}
|
||||
className="mt-2 w-full rounded-xl border border-white/10 bg-white/10 px-3 py-2 text-white focus:border-sky-400 focus:outline-none"
|
||||
rows={4}
|
||||
placeholder="Tell the story behind this artwork."
|
||||
/>
|
||||
<div className="mt-2">
|
||||
<UploadDescriptionEditor
|
||||
id="legacy-upload-description"
|
||||
value={state.metadata.description}
|
||||
onChange={(value) => dispatch({ type: 'SET_METADATA', payload: { description: value } })}
|
||||
placeholder="Tell the story behind this artwork."
|
||||
error={descriptionErrors[0] || ''}
|
||||
rows={8}
|
||||
/>
|
||||
</div>
|
||||
{descriptionErrors.length > 0 && <p className="mt-2 text-xs text-red-200">{descriptionErrors[0]}</p>}
|
||||
</label>
|
||||
|
||||
<div className="mt-4">
|
||||
@@ -1099,9 +1114,10 @@ export default function UploadPage({ draftId, filesCdnUrl, chunkSize, chunkReque
|
||||
!state.metadata.category ||
|
||||
!hasAtLeastOneTag ||
|
||||
!state.metadata.description.trim() ||
|
||||
descriptionErrors.length > 0 ||
|
||||
!state.metadata.licenseAccepted
|
||||
}
|
||||
className={`inline-flex items-center gap-2 rounded-full px-5 py-2 text-sm font-semibold text-white ${(!state.file || !state.metadata.title.trim() || !state.metadata.type || !state.metadata.category || !hasAtLeastOneTag || !state.metadata.description.trim() || !state.metadata.licenseAccepted) ? 'bg-white/10 cursor-not-allowed' : 'bg-emerald-500 shadow-lg shadow-emerald-500/30'}`}
|
||||
className={`inline-flex items-center gap-2 rounded-full px-5 py-2 text-sm font-semibold text-white ${(!state.file || !state.metadata.title.trim() || !state.metadata.type || !state.metadata.category || !hasAtLeastOneTag || !state.metadata.description.trim() || descriptionErrors.length > 0 || !state.metadata.licenseAccepted) ? 'bg-white/10 cursor-not-allowed' : 'bg-emerald-500 shadow-lg shadow-emerald-500/30'}`}
|
||||
>
|
||||
<i className="fa-solid fa-rocket" aria-hidden="true"></i>
|
||||
Start upload
|
||||
|
||||
Reference in New Issue
Block a user