Files
SkinbaseNova/resources/js/Pages/Group/GroupQuickstartPage.jsx

322 lines
15 KiB
JavaScript

import React from 'react'
import { usePage } from '@inertiajs/react'
import DocsCallout from '../../components/docs/DocsCallout'
import DocsSection from '../../components/docs/DocsSection'
import DocsSidebarNav from '../../components/docs/DocsSidebarNav'
import DocsStepList from '../../components/docs/DocsStepList'
import QuickstartChecklist from '../../components/docs/QuickstartChecklist'
import QuickstartNextSteps from '../../components/docs/QuickstartNextSteps'
import SeoHead from '../../components/seo/SeoHead'
import {
COMPARISON_CARDS,
COMMON_MISTAKES,
CREATE_STEPS,
CREDIT_TERMS,
FIRST_WEEK_BEST_PRACTICES,
GOOD_FIT,
NEXT_STEPS,
NOT_NEEDED_YET,
PUBLISH_STEPS,
QUICK_CHECKLIST,
ROLE_CARDS,
SECTION_ITEMS,
SETUP_TASKS,
} from './groupQuickstartContent'
function HeroStat({ label, value, note }) {
return (
<div className="rounded-[22px] 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 ComparisonCard({ card }) {
return (
<article className="rounded-[28px] border border-white/10 bg-black/20 p-5">
<div className="flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.04] text-sky-200">
<i className={card.icon} />
</div>
<h3 className="mt-4 text-xl font-semibold text-white">{card.title}</h3>
<ul className="mt-4 space-y-2">
{card.bullets.map((item) => (
<li key={item} className="flex gap-3 text-sm leading-6 text-slate-300">
<span className="mt-1.5 h-2 w-2 shrink-0 rounded-full bg-sky-300" />
<span>{item}</span>
</li>
))}
</ul>
</article>
)
}
function SimpleListCard({ title, eyebrow, items, tone = 'sky' }) {
const toneClass = tone === 'emerald'
? 'border-emerald-300/15 bg-emerald-400/10 text-emerald-50'
: 'border-white/10 bg-black/20 text-white'
return (
<div className={`rounded-[28px] border p-5 ${toneClass}`}>
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] opacity-80">{eyebrow}</p>
<h3 className="mt-2 text-xl font-semibold">{title}</h3>
<ul className="mt-4 space-y-3">
{items.map((item) => (
<li key={item} className="flex gap-3 text-sm leading-6 opacity-95">
<span className="mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-white/10 bg-white/[0.06] text-[10px]">
<i className="fa-solid fa-check" />
</span>
<span>{item}</span>
</li>
))}
</ul>
</div>
)
}
function RoleCard({ role }) {
return (
<article className="rounded-[26px] border border-white/10 bg-black/20 p-5">
<div className="inline-flex rounded-full border border-sky-300/20 bg-sky-300/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100">
{role.role}
</div>
<p className="mt-4 text-sm leading-7 text-slate-300">{role.summary}</p>
<p className="mt-3 text-sm font-medium text-slate-200">{role.note}</p>
</article>
)
}
function CompactGrid({ items }) {
return (
<div className="grid gap-3 md:grid-cols-2">
{items.map((item) => (
<div key={item} className="rounded-[22px] border border-white/10 bg-black/20 p-4 text-sm leading-6 text-slate-300">
{item}
</div>
))}
</div>
)
}
function CreditCard({ item }) {
return (
<div className="rounded-[24px] border border-white/10 bg-black/20 p-4">
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">{item.label}</div>
<div className="mt-2 text-base font-semibold text-white">{item.value}</div>
<p className="mt-2 text-sm leading-6 text-slate-300">{item.note}</p>
</div>
)
}
export default function GroupQuickstartPage() {
const { props } = usePage()
const links = props.links || {}
const nextSteps = NEXT_STEPS.map((item) => ({
...item,
href: links[item.linkKey] || '#',
}))
const jsonLd = [
{
'@context': 'https://schema.org',
'@type': 'Article',
headline: props.title,
description: props.description,
url: props.seo?.canonical,
author: {
'@type': 'Organization',
name: 'Skinbase',
},
about: ['Groups', 'Quickstart', 'Collaborative publishing', 'Contributor credit'],
},
]
return (
<main className="min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(14,165,233,0.18),_transparent_24%),radial-gradient(circle_at_bottom_right,_rgba(250,204,21,0.14),_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-[1380px]">
<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.74)),radial-gradient(circle_at_top_right,rgba(125,211,252,0.18),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)_340px]">
<div>
<p className="text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/80">Groups quickstart</p>
<h1 className="mt-3 max-w-4xl text-4xl font-semibold tracking-[-0.04em] text-white md:text-5xl xl:text-6xl">Get started with Groups fast and publish together without losing individual credit.</h1>
<p className="mt-5 max-w-3xl text-base leading-8 text-slate-300 md:text-lg">This quickstart is the fast path from curiosity to first success. It shows what a Group is, when to use one, how to invite the right people, and how to publish your first Group artwork with contributor credit handled properly.</p>
<div className="mt-6 flex flex-wrap gap-3">
<a href={links.create_group} 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 Group</a>
<a href={links.group_studio} 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 Group Studio</a>
<a href={links.full_documentation} 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]">Read full Groups documentation</a>
</div>
{links.faq ? (
<div className="mt-4">
<a href={links.faq} className="text-sm font-semibold text-sky-200 underline underline-offset-4">
Need quick answers instead of the full guide? Open the Groups FAQ.
</a>
</div>
) : null}
</div>
<div className="grid gap-3 sm:grid-cols-3 xl:grid-cols-1">
<HeroStat label="What a Group is" value="A shared team identity" note="Use it when a studio, crew, or project needs one public home instead of scattered personal uploads." />
<HeroStat label="What stays visible" value="Real contributor credit" note="Published by, uploaded by, primary author, and contributor roles can still reflect the real people behind the work." />
<HeroStat label="First win" value="Create, invite, publish" note="The goal of this page is simple: get you to a clean first Group publish without confusion." />
</div>
</div>
</section>
<div className="mt-8 grid gap-6 lg:grid-cols-[220px_minmax(0,1fr)]">
<DocsSidebarNav sections={SECTION_ITEMS} />
<div className="space-y-6">
<DocsSection
id="what-is-a-group"
eyebrow="Start here"
title="What is a Group?"
summary="A Group is a shared creative identity for multiple people. It lets a team publish together under one name while still showing who uploaded, authored, and contributed to the work."
>
<div className="grid gap-4 md:grid-cols-2">
{COMPARISON_CARDS.map((card) => <ComparisonCard key={card.title} card={card} />)}
</div>
<div className="mt-6">
<DocsCallout tone="note" title="The key idea to keep in your head">
Group and personal publishing can coexist. A Group gives the team a shared identity, but it should not erase the people behind the work.
</DocsCallout>
</div>
</DocsSection>
<DocsSection
id="when-to-use"
eyebrow="Decision"
title="When should you use a Group?"
summary="Use a Group when collaboration is real enough to need shared identity, shared workflow, or shared publishing. Skip it for now if it only adds overhead."
>
<div className="grid gap-4 lg:grid-cols-2">
<SimpleListCard title="Use a Group when..." eyebrow="Good fit" items={GOOD_FIT} tone="emerald" />
<SimpleListCard title="You can wait when..." eyebrow="Not necessary yet" items={NOT_NEEDED_YET} />
</div>
</DocsSection>
<DocsSection
id="create-first-group"
eyebrow="Build the foundation"
title="Create your first Group"
summary="The fastest clean start is a simple start. Get the identity created first, then improve it as the Group becomes active."
>
<DocsStepList items={CREATE_STEPS} />
<div className="mt-6">
<DocsCallout tone="tip" title="Start simple">
You do not need perfect branding or a complex team structure on day one. You need a clear name, a usable page, and the right first members.
</DocsCallout>
</div>
</DocsSection>
<DocsSection
id="setup-properly"
eyebrow="Right after creation"
title="Set up your Group properly"
summary="The first few setup moves decide whether the Group feels trustworthy and active or unfinished and confusing."
>
<CompactGrid items={SETUP_TASKS} />
</DocsSection>
<DocsSection
id="invite-and-roles"
eyebrow="Team setup"
title="Invite members and choose roles"
summary="Keep the role model clear. Most teams should stay simple at first: very few Owners, very few Admins, Editors for trusted content operators, and Contributors for most collaborators."
>
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
{ROLE_CARDS.map((role) => <RoleCard key={role.role} role={role} />)}
</div>
<div className="mt-6 grid gap-4 md:grid-cols-2">
<DocsCallout tone="practice" title="Recommended first move">
Invite your first members, assign only the roles they need right now, and avoid advanced permission tuning until the team has real workflow pressure.
</DocsCallout>
<DocsCallout tone="note" title="Advanced overrides can wait">
If you need permission overrides later, you can add them later. The quickstart path is deliberately simpler than the full feature set.
</DocsCallout>
</div>
</DocsSection>
<DocsSection
id="publish-first-artwork"
eyebrow="First success"
title="Publish your first artwork as a Group"
summary="This is where new teams get tripped up most often. The artwork should appear under the Group publicly, but the people behind it should still be represented correctly."
>
<DocsStepList items={PUBLISH_STEPS} />
<div className="mt-6">
<DocsCallout tone="warning" title="Always check publishing context before the final click">
Confirm whether you are publishing as your personal profile or as the Group. That one check prevents a lot of cleanup later.
</DocsCallout>
</div>
</DocsSection>
<DocsSection
id="contributor-credit"
eyebrow="Credit"
title="Understand contributor credit"
summary="Groups are for shared identity, not for hiding who did the actual work. Before the first public publish, make sure the credit record reflects reality."
>
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
{CREDIT_TERMS.map((item) => <CreditCard key={item.label} item={item} />)}
</div>
<div className="mt-6">
<DocsCallout tone="practice" title="Best practice">
Review contributor credit before every first release, first Group artwork, or first major collaborative drop. Do not leave attribution as an afterthought.
</DocsCallout>
</div>
</DocsSection>
<DocsSection
id="first-week-best-practices"
eyebrow="First week"
title="First-week best practices"
summary="The first week should make the Group feel intentional, active, and easy to understand."
>
<CompactGrid items={FIRST_WEEK_BEST_PRACTICES} />
</DocsSection>
<DocsSection
id="common-mistakes"
eyebrow="Avoid these"
title="Common mistakes to avoid"
summary="These are the fastest ways to make a new Group feel confusing or unreliable."
>
<div className="grid gap-3 md:grid-cols-2">
{COMMON_MISTAKES.map((item) => (
<div key={item} className="rounded-[24px] border border-amber-300/15 bg-amber-400/10 p-4 text-sm leading-6 text-amber-50/95">
{item}
</div>
))}
</div>
</DocsSection>
<section id="quick-checklist" className="scroll-mt-24">
<QuickstartChecklist
title="Use this before your first Group publish"
summary="This is the lightweight completion list you want to be able to say yes to before the Group starts publishing publicly."
items={QUICK_CHECKLIST}
/>
</section>
<DocsSection
id="next-steps"
eyebrow="Keep going"
title="Next steps"
summary="Once the first Group exists and the first publish is clear, move into the next surface that helps your team actually operate."
>
<QuickstartNextSteps items={nextSteps} />
</DocsSection>
</div>
</div>
</div>
</main>
)
}