Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render
This commit is contained in:
53
resources/js/components/enhance/BeforeAfterSlider.jsx
Normal file
53
resources/js/components/enhance/BeforeAfterSlider.jsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function BeforeAfterSlider({ beforeUrl, afterUrl, beforeAlt = 'Original image', afterAlt = 'Enhanced image' }) {
|
||||
const [position, setPosition] = React.useState(50)
|
||||
|
||||
if (!beforeUrl || !afterUrl) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-[28px] border border-white/10 bg-[#08111d] p-5 shadow-[0_18px_48px_rgba(2,6,23,0.2)]">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400">Before / after</p>
|
||||
<h3 className="mt-2 text-xl font-semibold tracking-[-0.03em] text-white">Compare the original with the enhanced result</h3>
|
||||
</div>
|
||||
<span className="rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-200">{position}%</span>
|
||||
</div>
|
||||
|
||||
<div className="relative mt-5 overflow-hidden rounded-[24px] border border-white/10 bg-black/40">
|
||||
<img src={beforeUrl} alt={beforeAlt} className="block w-full object-cover" />
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 overflow-hidden border-r border-white/80" style={{ width: `${position}%` }}>
|
||||
<img src={afterUrl} alt={afterAlt} className="block h-full w-full object-cover" />
|
||||
</div>
|
||||
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0" style={{ left: `calc(${position}% - 1px)` }}>
|
||||
<div className="flex h-full items-center">
|
||||
<div className="flex h-10 w-10 -translate-x-1/2 items-center justify-center rounded-full border border-white/80 bg-black/60 text-white shadow-[0_0_30px_rgba(15,23,42,0.5)]">
|
||||
<i className="fa-solid fa-left-right text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pointer-events-none absolute left-3 top-3 rounded-full border border-white/10 bg-[#08111dd8] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-100">Original</div>
|
||||
<div className="pointer-events-none absolute right-3 top-3 rounded-full border border-emerald-300/20 bg-emerald-400/12 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-emerald-100">Enhanced</div>
|
||||
</div>
|
||||
|
||||
<label className="mt-5 block">
|
||||
<span className="sr-only">Adjust before and after comparison slider</span>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
value={position}
|
||||
onChange={(event) => setPosition(Number(event.target.value || 50))}
|
||||
className="h-2 w-full cursor-pointer appearance-none rounded-full bg-white/10 accent-sky-300"
|
||||
aria-label="Adjust before and after comparison slider"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
34
resources/js/components/enhance/EnhanceStatusBadge.jsx
Normal file
34
resources/js/components/enhance/EnhanceStatusBadge.jsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
|
||||
const TONES = {
|
||||
pending: 'border-white/10 bg-white/[0.05] text-slate-200',
|
||||
queued: 'border-sky-300/20 bg-sky-400/12 text-sky-100',
|
||||
processing: 'border-violet-300/20 bg-violet-400/12 text-violet-100',
|
||||
completed: 'border-emerald-300/20 bg-emerald-400/12 text-emerald-100',
|
||||
failed: 'border-rose-300/20 bg-rose-400/12 text-rose-100',
|
||||
cancelled: 'border-amber-300/20 bg-amber-400/12 text-amber-100',
|
||||
expired: 'border-white/10 bg-white/[0.05] text-slate-300',
|
||||
unknown: 'border-white/10 bg-white/[0.04] text-slate-300',
|
||||
}
|
||||
|
||||
const LABELS = {
|
||||
pending: 'Pending',
|
||||
queued: 'Queued',
|
||||
processing: 'Processing',
|
||||
completed: 'Completed',
|
||||
failed: 'Failed',
|
||||
cancelled: 'Cancelled',
|
||||
expired: 'Expired',
|
||||
}
|
||||
|
||||
export default function EnhanceStatusBadge({ status, className = '' }) {
|
||||
const key = String(status || '').toLowerCase()
|
||||
const tone = TONES[key] || TONES.unknown
|
||||
const label = LABELS[key] || 'Unknown'
|
||||
|
||||
return (
|
||||
<span className={`inline-flex items-center rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] ${tone} ${className}`.trim()}>
|
||||
{label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
14
resources/js/components/enhance/EnhanceStubWarning.jsx
Normal file
14
resources/js/components/enhance/EnhanceStubWarning.jsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function EnhanceStubWarning({ config, moderation = false, className = '' }) {
|
||||
if (!config?.showStubWarning) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`rounded-2xl border border-amber-300/20 bg-amber-400/10 px-4 py-3 text-sm text-amber-50 ${className}`.trim()}>
|
||||
<div>Skinbase Enhance is currently running in preview mode. The generated result is a workflow placeholder until the real upscaling worker is enabled.</div>
|
||||
{moderation ? <div className="mt-2 text-xs uppercase tracking-[0.14em] text-amber-100/80">Engine: {config.engine}. This is not a real AI upscale result.</div> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user