55 lines
4.1 KiB
JavaScript
55 lines
4.1 KiB
JavaScript
import React from 'react'
|
|
import WorldPreviewButton from './WorldPreviewButton'
|
|
|
|
export default function WorldMiniPreviewPanel({ world, sections, previewUrl }) {
|
|
return (
|
|
<div className="rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
|
|
<div className="flex items-start justify-between gap-4">
|
|
<div>
|
|
<h2 className="text-xl font-semibold text-white">Live mini preview</h2>
|
|
<p className="mt-1 text-sm leading-6 text-slate-400">Hero hierarchy, CTA, badges, section order, and attached content update immediately as you edit.</p>
|
|
</div>
|
|
<WorldPreviewButton previewUrl={previewUrl} />
|
|
</div>
|
|
|
|
<div className="mt-5 overflow-hidden rounded-[28px] border border-white/10 bg-slate-950">
|
|
<div className="relative px-5 py-5" style={{ background: `linear-gradient(135deg, ${world?.accent_color || '#38bdf8'}22, transparent 45%), linear-gradient(180deg, #020617 0%, #0f172a 100%)` }}>
|
|
{world?.cover_url ? <img src={world.cover_url} alt="" className="absolute inset-0 h-full w-full object-cover opacity-25" /> : null}
|
|
<div className="relative">
|
|
<div className="flex flex-wrap gap-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100/80">
|
|
<span className="rounded-full border border-white/15 bg-white/10 px-3 py-1">{world?.type || 'seasonal'}</span>
|
|
{world?.badge_label ? <span className="rounded-full border border-white/15 bg-black/25 px-3 py-1">{world.badge_label}</span> : null}
|
|
{world?.is_featured ? <span className="rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-1 text-emerald-100">Homepage feature</span> : null}
|
|
</div>
|
|
<div className="mt-4 text-3xl font-semibold tracking-[-0.05em] text-white">{world?.title || 'Untitled world'}</div>
|
|
{world?.tagline ? <div className="mt-3 text-xs uppercase tracking-[0.22em] text-white/60">{world.tagline}</div> : null}
|
|
{world?.summary ? <div className="mt-4 max-w-2xl text-sm leading-7 text-slate-200/85">{world.summary}</div> : null}
|
|
|
|
<div className="mt-6 flex flex-wrap gap-3">
|
|
{world?.cta_label ? <span className="inline-flex items-center gap-2 rounded-full bg-white px-4 py-2 text-sm font-semibold text-slate-950">{world.cta_label}<i className="fa-solid fa-arrow-right" /></span> : null}
|
|
{world?.badge_description ? <span className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/8 px-4 py-2 text-sm font-semibold text-white">{world.badge_description}</span> : null}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="border-t border-white/10 px-5 py-4">
|
|
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Visible section order</div>
|
|
<div className="mt-3 grid gap-3">
|
|
{Array.isArray(sections) && sections.length > 0 ? sections.map((section) => (
|
|
<div key={section.key} className="rounded-2xl border border-white/10 bg-black/20 p-4">
|
|
<div className="flex items-center justify-between gap-3">
|
|
<div>
|
|
<div className="text-sm font-semibold text-white">{section.label}</div>
|
|
<div className="mt-1 text-xs text-slate-500">{section.count} attached items</div>
|
|
</div>
|
|
{section.count === 0 ? <span className="rounded-full border border-amber-300/20 bg-amber-400/10 px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-amber-100">Empty</span> : null}
|
|
</div>
|
|
{Array.isArray(section.items) && section.items.length > 0 ? <div className="mt-3 flex flex-wrap gap-2 text-xs text-slate-400">{section.items.map((item) => <span key={`${section.key}-${item.id}`} className="rounded-full bg-white/[0.04] px-3 py-1.5">{item.title}</span>)}</div> : null}
|
|
</div>
|
|
)) : <div className="rounded-2xl border border-dashed border-white/10 bg-white/[0.02] p-4 text-sm text-slate-400">No sections are visible yet. Enable sections and attach content to shape the public world.</div>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
} |