SkateSpots/src/lib/diyGuides.ts
SkateSpots 84fde55ddd Add the DIY section (resources for boards, ramps & concrete)
New /diy hub: curated resources for making your own gear, with cross-links into
the rest of the app.

- src/lib/diyGuides.ts: seed data — categories (Boards, Ramps & wooden
  obstacles, Concrete & DIY spots, Repairs & tuning, Tools & plans), resource
  cards (Open Source Skateboards / SK8CAD / Instructables / YouTube), and an
  actions block (find a Builder, find a DIY crew, map a DIY spot, sell builds,
  find a coach).
- src/pages/DiyPage.tsx renders it (category chips + card grid + actions);
  external links go through sanitizeUrl and credit the source.
- Route /diy (lazyWithRetry) + a nav-catalog entry (id diy) so it appears in the
  desktop "More" menu and the mobile burger; also linked from the site footer
  and the map links strip. Smoke test walks /diy.
2026-10-05 09:55:26 +07:00

210 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Curated DIY resources — how to make your own boards, ramps and concrete spots.
*
* This is a **seed** list (vetted links + in-app actions), not user content, so
* it needs no moderation. Titles/blurbs are i18n keys (`diyUi.*`). To extend,
* just add entries here.
*
* ⚠️ Link out, never rehost: credit the source. External URLs are rendered
* through `sanitizeUrl` on the page.
*/
export type DiyCategoryId = 'boards' | 'ramps' | 'concrete' | 'repairs' | 'tools';
export interface DiyCategory {
id: DiyCategoryId;
titleKey: string;
emoji: string;
}
/** A resource card — either an external guide (`url`) or an in-app action (`to`). */
export interface DiyCard {
id: string;
/** Omit for the cross-link actions block. */
category?: DiyCategoryId;
titleKey: string;
blurbKey: string;
emoji: string;
/** Shown as a credit for external links. */
source?: string;
url?: string;
to?: string;
}
export const DIY_CATEGORIES: DiyCategory[] = [
{ id: 'boards', titleKey: 'diyUi.categories.boards', emoji: '🛹' },
{ id: 'ramps', titleKey: 'diyUi.categories.ramps', emoji: '🪚' },
{ id: 'concrete', titleKey: 'diyUi.categories.concrete', emoji: '🧱' },
{ id: 'repairs', titleKey: 'diyUi.categories.repairs', emoji: '🔧' },
{ id: 'tools', titleKey: 'diyUi.categories.tools', emoji: '📐' },
];
export const DIY_CARDS: DiyCard[] = [
// ── Boards ────────────────────────────────────────────────────────────────
{
id: 'oss-build',
category: 'boards',
emoji: '🛹',
titleKey: 'diyUi.cards.ossBuild.title',
blurbKey: 'diyUi.cards.ossBuild.blurb',
source: 'Open Source Skateboards',
url: 'https://opensourceskateboards.com',
},
{
id: 'sk8cad',
category: 'boards',
emoji: '🧊',
titleKey: 'diyUi.cards.sk8cad.title',
blurbKey: 'diyUi.cards.sk8cad.blurb',
source: 'Open Source Skateboards',
url: 'https://sk8cad.com',
},
{
id: 'deck-cost',
category: 'boards',
emoji: '💰',
titleKey: 'diyUi.cards.deckCost.title',
blurbKey: 'diyUi.cards.deckCost.blurb',
source: 'Open Source Skateboards',
url: 'https://opensourceskateboards.com',
},
// ── Ramps & wooden obstacles ─────────────────────────────────────────────
{
id: 'ledge-box',
category: 'ramps',
emoji: '📦',
titleKey: 'diyUi.cards.ledgeBox.title',
blurbKey: 'diyUi.cards.ledgeBox.blurb',
source: 'Instructables',
url: 'https://www.instructables.com/howto/skate+ledge/',
},
{
id: 'quarterpipe',
category: 'ramps',
emoji: '🌊',
titleKey: 'diyUi.cards.quarterpipe.title',
blurbKey: 'diyUi.cards.quarterpipe.blurb',
source: 'Instructables',
url: 'https://www.instructables.com/howto/skate+ramp/',
},
{
id: 'flatbar',
category: 'ramps',
emoji: '➖',
titleKey: 'diyUi.cards.flatbar.title',
blurbKey: 'diyUi.cards.flatbar.blurb',
source: 'YouTube',
url: 'https://www.youtube.com/results?search_query=how+to+build+a+skate+flatbar',
},
// ── Concrete & DIY spots ─────────────────────────────────────────────────
{
id: 'concrete-basics',
category: 'concrete',
emoji: '🧱',
titleKey: 'diyUi.cards.concreteBasics.title',
blurbKey: 'diyUi.cards.concreteBasics.blurb',
source: 'Instructables',
url: 'https://www.instructables.com/howto/concrete+skatepark/',
},
{
id: 'coping',
category: 'concrete',
emoji: '🛞',
titleKey: 'diyUi.cards.coping.title',
blurbKey: 'diyUi.cards.coping.blurb',
source: 'YouTube',
url: 'https://www.youtube.com/results?search_query=diy+skatepark+coping',
},
{
id: 'map-spot',
category: 'concrete',
emoji: '📍',
titleKey: 'diyUi.cards.mapSpot.title',
blurbKey: 'diyUi.cards.mapSpot.blurb',
to: '/create-spot',
},
// ── Repairs & tuning ─────────────────────────────────────────────────────
{
id: 'regrip',
category: 'repairs',
emoji: '🩹',
titleKey: 'diyUi.cards.regrip.title',
blurbKey: 'diyUi.cards.regrip.blurb',
source: 'YouTube',
url: 'https://www.youtube.com/results?search_query=how+to+regrip+a+skateboard',
},
{
id: 'tune',
category: 'repairs',
emoji: '🔩',
titleKey: 'diyUi.cards.tune.title',
blurbKey: 'diyUi.cards.tune.blurb',
source: 'YouTube',
url: 'https://www.youtube.com/results?search_query=clean+skateboard+bearings+bushings',
},
// ── Tools & plans ────────────────────────────────────────────────────────
{
id: 'print-molds',
category: 'tools',
emoji: '🖨️',
titleKey: 'diyUi.cards.printMolds.title',
blurbKey: 'diyUi.cards.printMolds.blurb',
source: 'Printables',
url: 'https://www.printables.com/search/models?q=skateboard+mold',
},
{
id: 'sk8cad-tools',
category: 'tools',
emoji: '📐',
titleKey: 'diyUi.cards.sk8cadTools.title',
blurbKey: 'diyUi.cards.sk8cadTools.blurb',
source: 'Open Source Skateboards',
url: 'https://sk8cad.com',
},
];
/**
* Cross-links into the rest of the app — the point of the section: turn a guide
* into a person, a place, or a sale.
*/
export const DIY_ACTIONS: DiyCard[] = [
{
id: 'find-builder',
emoji: '🧱',
titleKey: 'diyUi.actions.findBuilder.title',
blurbKey: 'diyUi.actions.findBuilder.blurb',
to: '/lab?craft=building',
},
{
id: 'find-crew',
emoji: '👥',
titleKey: 'diyUi.actions.findCrew.title',
blurbKey: 'diyUi.actions.findCrew.blurb',
to: '/crews',
},
{
id: 'map-spot-action',
emoji: '📍',
titleKey: 'diyUi.actions.mapSpot.title',
blurbKey: 'diyUi.actions.mapSpot.blurb',
to: '/create-spot',
},
{
id: 'sell-builds',
emoji: '🛒',
titleKey: 'diyUi.actions.sellBuilds.title',
blurbKey: 'diyUi.actions.sellBuilds.blurb',
to: '/create-listing',
},
{
id: 'find-coach',
emoji: '🎓',
titleKey: 'diyUi.actions.findCoach.title',
blurbKey: 'diyUi.actions.findCoach.blurb',
to: '/lab?craft=coaching',
},
];