SkateSpots/src/pages/DiyPage.tsx

111 lines
3.8 KiB
TypeScript

import { useSeoMeta } from '@unhead/react';
import { Link } from 'react-router-dom';
import { Hammer, ChevronRight } from 'lucide-react';
import { useTranslation } from '@/contexts/language';
import { cn } from '@/lib/utils';
import { DIY_CATEGORIES, DIY_CARDS, DIY_ACTIONS, type DiyCard } from '@/lib/diyGuides';
/**
* DIY — resources for making your own boards, ramps and concrete spots, with
* cross-links into the rest of the app (find a builder, map a spot, sell).
* Content lives in `src/lib/diyGuides.ts`. Cards with no destination yet render
* unclickable with a "Coming soon" badge.
*/
function DiyCardView({ card }: { card: DiyCard }) {
const { t } = useTranslation();
const body = (
<>
<span className="text-2xl leading-none" aria-hidden>{card.emoji}</span>
<span className="min-w-0 flex-1">
<span className="flex items-center gap-2">
<span className="font-bold text-white">{t(card.titleKey)}</span>
{card.comingSoon && (
<span className="flex-shrink-0 rounded-full border border-white/15 bg-white/5 px-2 py-0.5 text-[9px] font-black uppercase tracking-wider text-gray-400">
{t('diyUi.comingSoon')}
</span>
)}
</span>
<span className="mt-0.5 block text-xs leading-relaxed text-gray-400">{t(card.blurbKey)}</span>
</span>
{card.to && <ChevronRight className="mt-0.5 h-4 w-4 flex-shrink-0 text-gray-500" />}
</>
);
const base = 'flex items-start gap-3 rounded-2xl border border-white/10 p-4 transition-colors';
if (!card.to) {
// Coming soon — deliberately not a link.
return (
<div
aria-disabled="true"
className={cn(base, 'cursor-default border-dashed bg-white/[0.015]')}
>
{body}
</div>
);
}
return (
<Link
to={card.to}
className={cn(base, 'bg-white/[0.03] hover:border-[#ccff00]/40 hover:bg-white/[0.06]')}
>
{body}
</Link>
);
}
export default function DiyPage() {
const { t } = useTranslation();
useSeoMeta({
title: t('seoUi.diyTitle'),
description: t('seoUi.diyDesc'),
});
return (
<div className="container mx-auto max-w-5xl px-4 py-8">
{/* Header */}
<header className="mb-6">
<h1 className="flex items-center gap-2 text-3xl md:text-4xl font-black uppercase tracking-tight text-white">
<Hammer className="h-7 w-7 text-[#ccff00]" />
{t('diyUi.title')}
</h1>
<p className="mt-2 text-sm text-gray-400 max-w-2xl">{t('diyUi.tagline')}</p>
</header>
{/* Resource sections */}
{DIY_CATEGORIES.map((cat) => {
const cards = DIY_CARDS.filter((c) => c.category === cat.id);
if (cards.length === 0) return null;
return (
<section key={cat.id} id={cat.id} className="mb-10 scroll-mt-28">
<h2 className="mb-3 flex items-center gap-2 text-lg font-black uppercase tracking-wide text-[#ccff00]">
<span aria-hidden>{cat.emoji}</span>
{t(cat.titleKey)}
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{cards.map((card) => <DiyCardView key={card.id} card={card} />)}
</div>
</section>
);
})}
{/* Do it with people — cross-links into the app */}
<section className="mb-10">
<h2 className="mb-3 flex items-center gap-2 text-lg font-black uppercase tracking-wide text-[#ccff00]">
<span aria-hidden>🤝</span>
{t('diyUi.doItWithPeople')}
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
{DIY_ACTIONS.map((card) => <DiyCardView key={card.id} card={card} />)}
</div>
</section>
<p className="mt-6 text-center text-[11px] leading-relaxed text-gray-600">
{t('diyUi.footer')}
</p>
</div>
);
}