Freeze/hide the Deck designer (not ready for regular users)

- Remove the deckDesigner card from the DIY hub, so it is not listed publicly.
- Gate /diy/deck-designer to platform admins: DeckDesignerPage redirects to /diy
  for everyone else and shows an "Internal preview" badge to admins.

Code and i18n keys are kept. To un-freeze, remove the Navigate guard and re-add
the card in diyGuides.ts (both noted in comments and AGENTS.md).
This commit is contained in:
SkateSpots 2026-10-05 12:53:13 +07:00
parent bed0fb8e34
commit e3576fcfec
3 changed files with 28 additions and 12 deletions

View file

@ -914,8 +914,15 @@ session with **no other memory of this project**. So:
parse/escape so commas in names are safe. Next: write our own parse/escape so commas in names are safe. Next: write our own
step-by-step guides (NIP-23 `30023` with `t=diy`) to flip the coming-soon cards step-by-step guides (NIP-23 `30023` with `t=diy`) to flip the coming-soon cards
live. live.
- **Deck designer — parametric 2D outline + 1:1 template (`/diy/deck-designer`, - **Deck designer — FROZEN / HIDDEN (2026-10-05):** ⚠️ **Not ready for regular
2026-10-05):** `src/lib/deckDesign.ts` (pure maths) + `components/DeckDesigner.tsx` users.** It is **not listed in the DIY hub** (`diyGuides.ts` has a note where
the card was) and `/diy/deck-designer` is **admin-gated** — `DeckDesignerPage`
returns `<Navigate to="/diy">` unless `isAdminPubkey(user.pubkey)`, and shows an
"Internal preview" badge. To un-freeze: remove the guard in
`DeckDesignerPage.tsx` **and** re-add the `deckDesigner` card in
`diyGuides.ts`. The i18n keys (`diyUi.cards.deckDesigner.*`, `diyUi.designer.*`)
are kept. The code below is otherwise intact.
Parametric 2D outline + 1:1 template (`src/lib/deckDesign.ts` (pure maths) + `components/DeckDesigner.tsx`
+ page. Inputs: width, wheelbase, nose, tail (length is **derived** as + page. Inputs: width, wheelbase, nose, tail (length is **derived** as
nose+wheelbase+tail), waist, end-roundness, concave, thickness, tail/nose kick, nose+wheelbase+tail), waist, end-roundness, concave, thickness, tail/nose kick,
and the **truck-hole pattern** — **New school 53.975 × 41.275 mm (2.125″×1.625″)** and the **truck-hole pattern** — **New school 53.975 × 41.275 mm (2.125″×1.625″)**

View file

@ -65,14 +65,8 @@ export const DIY_CARDS: DiyCard[] = [
blurbKey: 'diyUi.cards.deckCost.blurb', blurbKey: 'diyUi.cards.deckCost.blurb',
to: '/diy/deck-cost', to: '/diy/deck-cost',
}, },
{ // NOTE: the deck *designer* (`/diy/deck-designer`) is intentionally NOT listed
id: 'deckDesigner', // here — it is frozen/hidden and admin-gated until it is ready. See DeckDesignerPage.
category: 'boards',
emoji: '📐',
titleKey: 'diyUi.cards.deckDesigner.title',
blurbKey: 'diyUi.cards.deckDesigner.blurb',
to: '/diy/deck-designer',
},
// ── Ramps & wooden obstacles ───────────────────────────────────────────── // ── Ramps & wooden obstacles ─────────────────────────────────────────────
{ {

View file

@ -1,18 +1,30 @@
import { useSeoMeta } from '@unhead/react'; import { useSeoMeta } from '@unhead/react';
import { Link } from 'react-router-dom'; import { Link, Navigate } from 'react-router-dom';
import { ArrowLeft, Ruler } from 'lucide-react'; import { ArrowLeft, Ruler } from 'lucide-react';
import { useTranslation } from '@/contexts/language'; import { useTranslation } from '@/contexts/language';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { isAdminPubkey } from '@/lib/admins';
import { DeckDesigner } from '@/components/DeckDesigner'; import { DeckDesigner } from '@/components/DeckDesigner';
/** DIY tool page — the parametric 2D deck designer / 1:1 template. */ /**
* DIY tool page — the parametric 2D deck designer / 1:1 template.
*
* FROZEN / NOT READY FOR REGULAR USERS (2026-10-05): not listed in the DIY hub
* and gated to platform admins, so the owner can keep testing it while the public
* can't reach it. Un-gate by removing the `Navigate` guard AND re-adding the
* `deckDesigner` card in `src/lib/diyGuides.ts`.
*/
export default function DeckDesignerPage() { export default function DeckDesignerPage() {
const { t } = useTranslation(); const { t } = useTranslation();
const { user } = useCurrentUser();
useSeoMeta({ useSeoMeta({
title: 'Deck Designer — SkateSpots DIY', title: 'Deck Designer — SkateSpots DIY',
description: 'Design a skateboard or longboard outline, then export a printable 1:1 template, SVG or DXF — concave, kicks, wheelbase and truck holes included.', description: 'Design a skateboard or longboard outline, then export a printable 1:1 template, SVG or DXF — concave, kicks, wheelbase and truck holes included.',
}); });
if (!isAdminPubkey(user?.pubkey)) return <Navigate to="/diy" replace />;
return ( return (
<div className="container mx-auto max-w-6xl px-4 py-8"> <div className="container mx-auto max-w-6xl px-4 py-8">
<Link to="/diy" className="mb-4 inline-flex items-center text-sm text-muted-foreground transition-colors hover:text-foreground"> <Link to="/diy" className="mb-4 inline-flex items-center text-sm text-muted-foreground transition-colors hover:text-foreground">
@ -26,6 +38,9 @@ export default function DeckDesignerPage() {
{t('diyUi.designer.title')} {t('diyUi.designer.title')}
</h1> </h1>
<p className="mt-2 max-w-2xl text-sm text-gray-400">{t('diyUi.designer.intro')}</p> <p className="mt-2 max-w-2xl text-sm text-gray-400">{t('diyUi.designer.intro')}</p>
<p className="mt-3 inline-flex items-center rounded-md border border-amber-500/30 bg-amber-500/[0.08] px-2.5 py-1 text-[11px] font-semibold text-amber-200/90">
Internal preview · not public yet
</p>
</header> </header>
<DeckDesigner /> <DeckDesigner />