Files
SkinbaseNova/resources/js/components/worlds/WorldRecapHero.jsx

55 lines
4.2 KiB
JavaScript

import React from 'react'
import WorldEndedBadge from './WorldEndedBadge'
import WorldStatusBadge from './WorldStatusBadge'
function recapStyle(world) {
return {
'--world-accent': world?.theme?.accent_color || '#38bdf8',
'--world-accent-secondary': world?.theme?.accent_color_secondary || '#0f172a',
}
}
export default function WorldRecapHero({ world, recap, previewMode = false }) {
if (!world || !recap) {
return null
}
return (
<section id="world-recap" className="relative overflow-hidden rounded-[36px] border border-white/10" style={recapStyle(world)}>
<div className="absolute inset-0 bg-[radial-gradient(circle_at_15%_20%,_color-mix(in_srgb,var(--world-accent)_28%,transparent),_transparent_32%),radial-gradient(circle_at_85%_18%,_color-mix(in_srgb,var(--world-accent-secondary)_70%,transparent),_transparent_40%),linear-gradient(140deg,_rgba(2,6,23,0.95),_rgba(15,23,42,0.84)_48%,_rgba(2,6,23,0.98))]" />
{recap.cover_url ? <img src={recap.cover_url} alt={recap.title || world.title} className="absolute inset-0 h-full w-full object-cover opacity-20" /> : null}
<div className="absolute inset-0 bg-gradient-to-r from-slate-950 via-slate-950/75 to-slate-950/10" />
<div className="relative grid gap-8 px-6 py-8 sm:px-8 lg:grid-cols-[minmax(0,1.18fr)_21rem] lg:px-10 lg:py-10">
<div>
<div className="flex flex-wrap items-center gap-3">
<WorldEndedBadge label={previewMode && recap.status === 'draft_preview' ? 'Recap draft preview' : 'Published recap'} />
{(Array.isArray(world.status_badges) ? world.status_badges : []).slice(0, 3).map((badge) => <WorldStatusBadge key={badge.label} badge={badge} />)}
</div>
<h1 className="mt-5 max-w-4xl text-4xl font-semibold tracking-[-0.05em] text-white sm:text-5xl lg:text-6xl">{recap.title}</h1>
{world.title ? <p className="mt-3 text-xs uppercase tracking-[0.24em] text-white/55">{world.title}</p> : null}
{recap.summary ? <p className="mt-6 max-w-3xl text-base leading-7 text-slate-200/90 sm:text-lg">{recap.summary}</p> : null}
<div className="mt-8 flex flex-wrap gap-3">
{world.cta_url ? <a href={world.cta_url} data-world-event="world_cta_clicked" data-world-section-key="recap_hero" data-world-cta-key="recap_primary" className="inline-flex items-center gap-2 rounded-full bg-white px-5 py-3 text-sm font-semibold text-slate-950 transition hover:bg-sky-100">{world.cta_label || 'Browse recap highlights'}<i className="fa-solid fa-arrow-right" /></a> : null}
{world.public_url ? <a href={`${world.public_url}#world-recap-highlights`} data-world-event="world_cta_clicked" data-world-section-key="recap_hero" data-world-cta-key="recap_jump_highlights" className="inline-flex items-center gap-2 rounded-full border border-white/12 bg-white/[0.05] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]">Edition highlights</a> : null}
</div>
</div>
<aside className="rounded-[28px] border border-white/12 bg-black/25 p-5 text-sm text-slate-200 shadow-2xl shadow-slate-950/30 backdrop-blur-sm">
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">Recap status</div>
<div className="mt-3 space-y-3">
<div>
<div className="text-xs uppercase tracking-[0.16em] text-slate-500">Edition state</div>
<div className="mt-1 text-base font-semibold text-white">Archive-facing recap</div>
</div>
{recap.published_at ? <div><div className="text-xs uppercase tracking-[0.16em] text-slate-500">Published</div><div className="mt-1 text-base font-semibold text-white">{new Date(recap.published_at).toLocaleDateString()}</div></div> : null}
{world.edition_label ? <div><div className="text-xs uppercase tracking-[0.16em] text-slate-500">Edition</div><div className="mt-1 text-base font-semibold text-white">{world.edition_label}</div></div> : null}
{world.family_title ? <div><div className="text-xs uppercase tracking-[0.16em] text-slate-500">Family</div><div className="mt-1 text-base font-semibold text-white">{world.family_title}</div></div> : null}
</div>
</aside>
</div>
</section>
)
}