363 lines
18 KiB
JavaScript
363 lines
18 KiB
JavaScript
import React from 'react'
|
|
import { usePage } from '@inertiajs/react'
|
|
import DocsCallout from '../../components/docs/DocsCallout'
|
|
import DocsComparisonTable from '../../components/docs/DocsComparisonTable'
|
|
import DocsFaqAccordion from '../../components/docs/DocsFaqAccordion'
|
|
import DocsSection from '../../components/docs/DocsSection'
|
|
import DocsSidebarNav from '../../components/docs/DocsSidebarNav'
|
|
import DocsStepList from '../../components/docs/DocsStepList'
|
|
import QuickstartNextSteps from '../../components/docs/QuickstartNextSteps'
|
|
import SeoHead from '../../components/seo/SeoHead'
|
|
import {
|
|
ATTACHMENT_WORKFLOW_ITEMS,
|
|
BEST_PRACTICES,
|
|
BUILD_WORLD_STEPS,
|
|
COMMON_MISTAKES,
|
|
COMPARISON_COLUMNS,
|
|
COMPARISON_ROWS,
|
|
FAQ_ITEMS,
|
|
HERO_METRICS,
|
|
LIFECYCLE_ITEMS,
|
|
MEDIA_AND_SEO_GUIDANCE,
|
|
RECURRENCE_GUIDANCE,
|
|
RELATED_HELP_ITEMS,
|
|
RELATION_TYPE_ITEMS,
|
|
SECTION_ITEMS,
|
|
SECTION_ITEMS_DETAIL,
|
|
TROUBLESHOOTING_ITEMS,
|
|
WHAT_WORLDS_ARE_ITEMS,
|
|
} from './worldsHelpContent'
|
|
|
|
function HeroMetric({ label, value, note }) {
|
|
return (
|
|
<div className="rounded-[24px] border border-white/10 bg-black/20 p-4">
|
|
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">{label}</div>
|
|
<div className="mt-2 text-lg font-semibold text-white">{value}</div>
|
|
<p className="mt-2 text-sm leading-6 text-slate-400">{note}</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function InsightCard({ item }) {
|
|
return (
|
|
<article className="rounded-[28px] border border-white/10 bg-black/20 p-5">
|
|
<h3 className="text-lg font-semibold text-white">{item.title}</h3>
|
|
<p className="mt-3 text-sm leading-7 text-slate-300">{item.body}</p>
|
|
</article>
|
|
)
|
|
}
|
|
|
|
function BulletGrid({ items, tone = 'sky' }) {
|
|
const dotColor = tone === 'amber' ? 'bg-amber-300' : tone === 'emerald' ? 'bg-emerald-300' : 'bg-sky-300'
|
|
|
|
return (
|
|
<div className="grid gap-3 md:grid-cols-2">
|
|
{items.map((item) => (
|
|
<div key={item} className="rounded-[24px] border border-white/10 bg-black/20 p-4">
|
|
<div className="flex gap-3 text-sm leading-6 text-slate-300">
|
|
<span className={`mt-2 h-2 w-2 shrink-0 rounded-full ${dotColor}`} />
|
|
<span>{item}</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function TroubleCard({ item, links }) {
|
|
return (
|
|
<a href={links[item.linkKey]} className="rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]">
|
|
<h3 className="text-lg font-semibold text-white">{item.title}</h3>
|
|
<p className="mt-3 text-sm leading-7 text-slate-300">{item.body}</p>
|
|
<div className="mt-4 flex items-center justify-between gap-3">
|
|
<span className="text-sm font-semibold text-sky-200">{item.linkLabel}</span>
|
|
<span className="text-slate-500">→</span>
|
|
</div>
|
|
</a>
|
|
)
|
|
}
|
|
|
|
export default function WorldsHelpPage() {
|
|
const { props } = usePage()
|
|
const links = props.links || {}
|
|
|
|
const jsonLd = [
|
|
{
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Article',
|
|
headline: 'Worlds Help',
|
|
description: props.description,
|
|
url: props.seo?.canonical,
|
|
author: {
|
|
'@type': 'Organization',
|
|
name: 'Skinbase',
|
|
},
|
|
about: ['Worlds', 'Seasonal campaigns', 'Editorial curation', 'Studio workflows', 'Homepage promotion'],
|
|
},
|
|
{
|
|
'@context': 'https://schema.org',
|
|
'@type': 'FAQPage',
|
|
mainEntity: FAQ_ITEMS.map((item) => ({
|
|
'@type': 'Question',
|
|
name: item.question,
|
|
acceptedAnswer: {
|
|
'@type': 'Answer',
|
|
text: item.answer,
|
|
},
|
|
})),
|
|
},
|
|
]
|
|
|
|
const relatedHelpItems = RELATED_HELP_ITEMS.map((item) => ({
|
|
...item,
|
|
href: links[item.linkKey],
|
|
}))
|
|
|
|
return (
|
|
<main className="min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.18),_transparent_23%),radial-gradient(circle_at_bottom_right,_rgba(249,115,22,0.16),_transparent_22%),linear-gradient(180deg,_#020617_0%,_#030712_100%)] px-4 py-8 sm:px-6 lg:px-8">
|
|
<SeoHead seo={props.seo || {}} title={props.title} description={props.description} jsonLd={jsonLd} />
|
|
|
|
<div className="mx-auto max-w-[1500px]">
|
|
<section id="introduction" className="rounded-[36px] border border-white/10 bg-[linear-gradient(135deg,rgba(15,23,42,0.92),rgba(15,23,42,0.72)),radial-gradient(circle_at_top_right,rgba(125,211,252,0.16),transparent_28%)] p-6 shadow-[0_30px_100px_rgba(2,6,23,0.35)] md:p-8 lg:p-10">
|
|
<div className="grid gap-8 xl:grid-cols-[minmax(0,1fr)_360px]">
|
|
<div>
|
|
<p className="text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/80">Worlds help</p>
|
|
<h1 className="mt-3 max-w-4xl text-4xl font-semibold tracking-[-0.04em] text-white md:text-5xl xl:text-6xl">Worlds are where Skinbase turns curated content into a live campaign surface.</h1>
|
|
<p className="mt-5 max-w-3xl text-base leading-8 text-slate-300 md:text-lg">This guide explains what Worlds are, how attached content works, how section visibility and order shape the result, and how to preview, publish, promote, and reuse Worlds for recurring campaigns.</p>
|
|
<div className="mt-6 flex flex-wrap gap-3">
|
|
<a href={links.create_world} className="rounded-full border border-sky-300/25 bg-sky-300/12 px-5 py-3 text-sm font-semibold text-sky-100 transition hover:border-sky-300/40 hover:bg-sky-300/18">Create a World</a>
|
|
<a href={links.studio_worlds} className="rounded-full border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.07]">Open Worlds workspace</a>
|
|
<a href={links.worlds_index} className="rounded-full border border-white/10 bg-black/20 px-5 py-3 text-sm font-semibold text-slate-200 transition hover:border-white/20 hover:bg-white/[0.05]">Browse public Worlds</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid gap-3 sm:grid-cols-3 xl:grid-cols-1">
|
|
{HERO_METRICS.map((metric) => (
|
|
<HeroMetric key={metric.label} label={metric.label} value={metric.value} note={metric.note} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div className="mt-8 grid gap-6 lg:grid-cols-[240px_minmax(0,1fr)] xl:grid-cols-[240px_minmax(0,1fr)_280px]">
|
|
<DocsSidebarNav sections={SECTION_ITEMS} ariaLabel="Worlds help sections" selectLabel="Jump to Worlds help section" />
|
|
|
|
<div className="space-y-6">
|
|
<DocsSection
|
|
id="what-worlds-are"
|
|
eyebrow="Foundations"
|
|
title="What Worlds are"
|
|
summary="Worlds are premium editorial destinations for campaign moments, not just another listing surface. They combine identity, structure, and curation into one public result."
|
|
>
|
|
<div className="grid gap-4 xl:grid-cols-3">
|
|
{WHAT_WORLDS_ARE_ITEMS.map((item) => (
|
|
<InsightCard key={item.title} item={item} />
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-6 grid gap-4 md:grid-cols-3">
|
|
{LIFECYCLE_ITEMS.map((item) => (
|
|
<InsightCard key={item.title} item={item} />
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-6">
|
|
<DocsCallout tone="note" title="The shortest useful definition">
|
|
A World is one hero, one short intro, one clear CTA, and a controlled set of attached modules arranged like an editorial campaign rather than a generic content pile.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="worlds-vs-other-surfaces"
|
|
eyebrow="Format choice"
|
|
title="Worlds vs other public surfaces"
|
|
summary="Use a World when the real need is a campaign hub. If the job is simpler, another surface may be a better fit."
|
|
>
|
|
<DocsComparisonTable columns={COMPARISON_COLUMNS} rows={COMPARISON_ROWS} caption="Comparison between Worlds, collections, and Group pages" />
|
|
|
|
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
|
<DocsCallout tone="tip" title="Choose a World when curation needs structure">
|
|
If the page needs multiple content modules, campaign identity, timing, and possible homepage promotion, a World is usually the right answer.
|
|
</DocsCallout>
|
|
<DocsCallout tone="warning" title="Do not use Worlds when a simpler surface is enough">
|
|
If the content only needs a list, collection, or shared identity page, using a World can make the workflow heavier than necessary.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="building-a-world"
|
|
eyebrow="Workflow"
|
|
title="Building a World"
|
|
summary="The editorial workflow is deliberate: define the campaign identity, attach the right content, check structure, preview the result, then publish only when the page reads clearly."
|
|
>
|
|
<DocsStepList items={BUILD_WORLD_STEPS} />
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="attached-content-and-sections"
|
|
eyebrow="Composition"
|
|
title="Attached content and sections"
|
|
summary="Attachments are the heart of the World system. They let editors compose a campaign hub out of explicit, curated relations instead of relying on vague automation."
|
|
>
|
|
<div className="grid gap-4 md:grid-cols-3">
|
|
{ATTACHMENT_WORKFLOW_ITEMS.map((item) => (
|
|
<InsightCard key={item.title} item={item} />
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-6">
|
|
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80">Supported attached entity types</p>
|
|
<div className="mt-4">
|
|
<BulletGrid items={RELATION_TYPE_ITEMS} tone="emerald" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-6">
|
|
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80">Built-in World sections</p>
|
|
<div className="mt-4 grid gap-4 xl:grid-cols-3">
|
|
{SECTION_ITEMS_DETAIL.map((item) => (
|
|
<InsightCard key={item.title} item={item} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
|
<DocsCallout tone="practice" title="Section order and section presence are different controls">
|
|
Reordering changes where a module appears. Visibility decides whether that module appears at all. Strong Worlds use both intentionally.
|
|
</DocsCallout>
|
|
<DocsCallout tone="note" title="Attached content can stay private to the editor layout">
|
|
A section can remain disabled on the public page even if attached items exist for it. This is useful when editors are still shaping the campaign or intentionally trimming the public result.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="preview-publishing-and-promotion"
|
|
eyebrow="Confidence"
|
|
title="Preview, publishing, and promotion"
|
|
summary="Worlds are meant for real campaign operations, so lifecycle and promotion state need to be visible and understandable before anything goes public."
|
|
>
|
|
<div className="grid gap-4 md:grid-cols-3">
|
|
{LIFECYCLE_ITEMS.map((item) => (
|
|
<InsightCard key={item.title} item={item} />
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
|
<DocsCallout tone="tip" title="Use preview as a safety check">
|
|
Check the hero, cover, CTA, badge, section order, and attached content hierarchy before moving a World into a public or promoted lifecycle state.
|
|
</DocsCallout>
|
|
<DocsCallout tone="warning" title="Featured promotion is stronger than just publish">
|
|
A World can be publicly visible at its own URL without also being ready for homepage or spotlight promotion. Treat those decisions separately.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="recurrence-and-new-editions"
|
|
eyebrow="Reuse"
|
|
title="Recurrence and new editions"
|
|
summary="Recurring campaigns should be easy to understand operationally. Worlds include recurrence fields and duplication actions so campaign families can evolve cleanly over time."
|
|
>
|
|
<BulletGrid items={RECURRENCE_GUIDANCE} tone="sky" />
|
|
|
|
<div className="mt-6">
|
|
<DocsCallout tone="practice" title="Think in campaign families">
|
|
“Halloween 2026” and “Halloween 2027” should feel like different editions of the same family, not like unrelated Worlds with manually repeated structure.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="media-seo-and-theme-presets"
|
|
eyebrow="Presentation"
|
|
title="Media, SEO, and theme presets"
|
|
summary="Worlds are visual and promotional. Theme presets accelerate setup, while media and SEO fields shape how the page reads inside the platform and when shared outward."
|
|
>
|
|
<BulletGrid items={MEDIA_AND_SEO_GUIDANCE} tone="amber" />
|
|
|
|
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
|
<DocsCallout tone="note" title="Current media workflow">
|
|
Worlds currently use absolute URLs or CDN storage paths for cover and OG assets. The editor includes asset previews and is already prepared for a future shared media picker.
|
|
</DocsCallout>
|
|
<DocsCallout tone="tip" title="Use presets to move faster, not to stop thinking">
|
|
Theme presets should give you a strong start. Editors should still adjust the result when the campaign needs a sharper, more specific identity.
|
|
</DocsCallout>
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="best-practices"
|
|
eyebrow="Quality habits"
|
|
title="Best practices"
|
|
summary="Strong Worlds feel editorially intentional. Every section, asset, and attached item should earn its place."
|
|
>
|
|
<BulletGrid items={BEST_PRACTICES} tone="emerald" />
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="common-mistakes"
|
|
eyebrow="Avoid this"
|
|
title="Common mistakes"
|
|
summary="Most Worlds problems are not technical. They come from weak curation, unclear promotion decisions, or using the wrong format for the job."
|
|
>
|
|
<BulletGrid items={COMMON_MISTAKES} tone="amber" />
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="faq"
|
|
eyebrow="FAQ"
|
|
title="Worlds FAQ"
|
|
summary="These answers cover the most common editorial and workflow questions about creating, attaching, and promoting Worlds."
|
|
>
|
|
<DocsFaqAccordion items={FAQ_ITEMS} />
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="troubleshooting"
|
|
eyebrow="Troubleshooting"
|
|
title="Troubleshooting"
|
|
summary="Use these routes when the problem is access, preview quality, format choice, publishing readiness, or an editor workflow issue."
|
|
>
|
|
<div className="grid gap-4 xl:grid-cols-2">
|
|
{TROUBLESHOOTING_ITEMS.map((item) => (
|
|
<TroubleCard key={item.title} item={item} links={links} />
|
|
))}
|
|
</div>
|
|
</DocsSection>
|
|
|
|
<DocsSection
|
|
id="related-help"
|
|
eyebrow="Next steps"
|
|
title="Related help"
|
|
summary="Use these links when Worlds are understood and the next question is about adjacent workflows such as Studio, uploads, cards, or Group collaboration."
|
|
>
|
|
<QuickstartNextSteps items={relatedHelpItems} />
|
|
</DocsSection>
|
|
</div>
|
|
|
|
<aside className="hidden xl:block xl:sticky xl:top-24 xl:self-start">
|
|
<div className="space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]">
|
|
<div>
|
|
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80">Quick route map</p>
|
|
<div className="mt-4 space-y-2">
|
|
<a href={links.create_world} className="block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]">Create a World</a>
|
|
<a href={links.studio_worlds} className="block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]">Open Worlds workspace</a>
|
|
<a href={links.worlds_index} className="block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]">Browse public Worlds</a>
|
|
<a href={links.studio_help} className="block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]">Read Studio help</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="rounded-[24px] border border-sky-300/20 bg-sky-400/10 p-4 text-sky-50">
|
|
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100/80">Fast reminder</div>
|
|
<p className="mt-2 text-sm leading-6 text-sky-50/85">A World should feel like an editorial decision, not a container. If the page feels cluttered, the usual fix is stronger curation, fewer modules, and clearer promotion intent.</p>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
)
|
|
} |