SkateSpots/src/pages/BecomeRolePage.tsx
shakespeare.diy 16e943d4ef refactor: consolidate become-* routes + migrate empty states to shared component
Empty states (P4 follow-up):
- CrewsPage and EventsPage now render the shared <EmptyState> instead of
  their own local copies, keeping spacing/actions/footer consistent.

Become-role routes (P1):
- Add src/lib/becomeRoles.tsx: single registry mapping each role slug to
  either a CraftProfileForm config (artist/graffiti/musician/judge/tattoo/
  trainer) or a lazy bespoke page (coach/filmer/editor/photographer/
  builder/skater). The 6 craft roles were already thin config wrappers, so
  their configs move into the registry and the wrapper files are deleted.
- Replace 12 hardcoded /become-* routes + 12 imports with one
  /become/:role route (BecomeRolePage) that renders from the registry.
- Legacy /become-<slug> URLs now redirect to /become/<slug> so shared/
  bookmarked links keep working.
- Update all internal links (LabPage, Index, SkatersPage, SpotDetailPage,
  NIP19Page, SkaterDirectoryCard) to the canonical /become/<slug> paths.

Note: the 5 large bespoke forms were intentionally NOT merged into one
config — they carry distinct machinery (SpotPicker, wallet/Pro, geohashing)
and forcing them together would increase complexity, not reduce it.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-24 18:44:53 +07:00

57 lines
1.5 KiB
TypeScript

import { Suspense } from 'react';
import { useParams } from 'react-router-dom';
import { useSeoMeta } from '@unhead/react';
import { CraftProfileForm } from '@/components/CraftProfileForm';
import { getBecomeRole } from '@/lib/becomeRoles';
import NotFound from '@/pages/NotFound';
/**
* Single entry point for every "become a <role>" flow (/become/:role).
*
* - Craft roles render the shared <CraftProfileForm> from their data config.
* - Bespoke roles render their own lazy page component.
* - Unknown roles fall through to the 404 page.
*
* This replaces 12 hardcoded routes + 12 component imports in the router.
*/
function PageLoader() {
return (
<div className="min-h-screen bg-black flex items-center justify-center">
<div className="w-8 h-8 border-2 border-[#ff0040] border-t-transparent rounded-full animate-spin" />
</div>
);
}
export default function BecomeRolePage() {
const { role: slug } = useParams<{ role: string }>();
const role = getBecomeRole(slug);
if (!role) {
return <NotFound />;
}
if (role.kind === 'craft') {
return <CraftRole role={role} />;
}
const Component = role.component;
return (
<Suspense fallback={<PageLoader />}>
<Component />
</Suspense>
);
}
function CraftRole({
role,
}: {
role: Extract<ReturnType<typeof getBecomeRole>, { kind: 'craft' }>;
}) {
useSeoMeta({
title: role.seoTitle,
description: role.seoDescription,
});
return <CraftProfileForm config={role.config} />;
}