SkateSpots/src/pages/AboutPage.tsx

340 lines
16 KiB
TypeScript

import { useSeoMeta } from '@unhead/react';
import { Link } from 'react-router-dom';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { ShareAppCard } from '@/components/ShareAppCard';
import { APP_INSTALL_URL } from '@/lib/platform';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useToast } from '@/hooks/useToast';
import {
MapPin,
Heart,
Globe,
Zap,
Shield,
Users,
Code,
ExternalLink,
BarChart3,
AlertCircle,
Download,
Smartphone,
MessageCircle,
} from 'lucide-react';
import { useTranslation } from '@/contexts/language';
export default function AboutPage() {
const { t } = useTranslation();
useSeoMeta({
title: t('settingsUi.about.seoTitle'),
description: t('settingsUi.about.seoDescription'),
});
const { user } = useCurrentUser();
const { toast } = useToast();
const copyNpub = () => {
navigator.clipboard.writeText('npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx');
toast({
title: t('common.copied'),
description: t('settingsUi.about.npubCopied'),
});
};
// Bug report template for DM
const bugReportTemplate = `${t('settingsUi.about.bugReport')}
${t('settingsUi.about.bugWhatHappened')}
${t('settingsUi.about.bugExpected')}
${t('settingsUi.about.bugSteps')}
Device/Browser: ${navigator.userAgent.includes('Mobile') ? 'Mobile' : 'Desktop'} - ${navigator.userAgent.split(' ').slice(-2).join(' ')}
Version: v0.1.0`;
const bugReportUrl = `/messages/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx?message=${encodeURIComponent(bugReportTemplate)}`;
return (
<>
<div className="container px-4 py-12 max-w-4xl">
{/* Hero */}
<div className="text-center mb-12">
<div className="mb-6">
<div className="inline-flex items-center justify-center w-20 h-20 rounded-2xl bg-gradient-to-br from-[#ff0040] to-[#ff6600] mb-4">
<MapPin className="h-10 w-10 text-white" />
</div>
</div>
<h1 className="text-4xl md:text-6xl font-black uppercase mb-4" style={{
fontFamily: 'Impact, "Arial Black", sans-serif',
letterSpacing: '0.05em'
}}>
<span className="neon-red">{t('settingsUi.about.aboutWord')}</span>{' '}
<span className="gradient-text">SKATESPOTS</span>
</h1>
<p className="text-xl text-gray-300 max-w-2xl mx-auto mb-6">
{t('settingsUi.about.heroBefore')} <strong className="text-[#ff0040]">{t('settingsUi.about.skaterOwned')}</strong>{t('settingsUi.about.heroAfter')}
</p>
<Link to="/stats">
<Button
variant="outline"
className="gap-2 border-2 border-[#ccff00] text-[#ccff00] hover:bg-[#ccff00]/10"
>
<BarChart3 className="h-4 w-4" />
{t('settingsUi.about.viewStats')}
</Button>
</Link>
</div>
{/* Mission */}
<Card className="bg-black/90 border-2 border-[#ff0040]/50 mb-8">
<CardContent className="p-8">
<div className="flex items-start gap-4 mb-4">
<Heart className="h-8 w-8 text-[#ff0040] flex-shrink-0" />
<div>
<h2 className="text-2xl font-black uppercase text-white mb-3">{t('settingsUi.about.missionTitle')}</h2>
<p className="text-gray-300 leading-relaxed">
{t('settingsUi.about.mission1')}
</p>
</div>
</div>
<p className="text-gray-300 leading-relaxed">
{t('settingsUi.about.mission2')}
</p>
</CardContent>
</Card>
{/* Why Nostr */}
<Card className="bg-black/90 border-2 border-[#ccff00]/50 mb-8">
<CardContent className="p-8">
<div className="flex items-start gap-4 mb-6">
<Globe className="h-8 w-8 text-[#ccff00] flex-shrink-0" />
<div>
<h2 className="text-2xl font-black uppercase text-white mb-3">{t('settingsUi.about.whyNostr')}</h2>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 rounded-lg bg-black/50 border border-[#ff0040]/20">
<Shield className="h-6 w-6 text-[#ff0040] mb-2" />
<h3 className="font-bold text-white uppercase text-sm mb-2">{t('settingsUi.about.why1Title')}</h3>
<p className="text-sm text-gray-400">
{t('settingsUi.about.why1Desc')}
</p>
</div>
<div className="p-4 rounded-lg bg-black/50 border border-[#ccff00]/20">
<Users className="h-6 w-6 text-[#ccff00] mb-2" />
<h3 className="font-bold text-white uppercase text-sm mb-2">{t('settingsUi.about.why2Title')}</h3>
<p className="text-sm text-gray-400">
{t('settingsUi.about.why2Desc')}
</p>
</div>
<div className="p-4 rounded-lg bg-black/50 border border-[#ff6600]/20">
<Zap className="h-6 w-6 text-[#ff6600] mb-2" />
<h3 className="font-bold text-white uppercase text-sm mb-2">{t('settingsUi.about.why3Title')}</h3>
<p className="text-sm text-gray-400">
{t('settingsUi.about.why3Desc')}
</p>
</div>
<div className="p-4 rounded-lg bg-black/50 border border-[#ccff00]/20">
<Code className="h-6 w-6 text-[#ccff00] mb-2" />
<h3 className="font-bold text-white uppercase text-sm mb-2">{t('settingsUi.about.why4Title')}</h3>
<p className="text-sm text-gray-400">
{t('settingsUi.about.why4Desc')}
</p>
</div>
</div>
</CardContent>
</Card>
{/* Links */}
<div className="grid grid-cols-1 md:grid-cols-1 gap-6 max-w-md mx-auto">
<Card className="bg-black/90 border-2 border-[#ccff00]/50">
<CardContent className="p-6 text-center">
<h3 className="font-black uppercase text-[#ccff00] mb-4">{t('settingsUi.about.getInvolved')}</h3>
<p className="text-gray-300 mb-4 text-sm">
{t('settingsUi.about.getInvolvedDesc')}
</p>
<Link to="/onboarding">
<Button className="gap-2 bg-[#ccff00] text-black hover:bg-[#ccff00]/90 font-bold uppercase w-full">
{t('common.getStarted')}
</Button>
</Link>
</CardContent>
</Card>
</div>
{/* Beta Testing Notice */}
<Card className="bg-yellow-950/20 border-yellow-500/30 mt-8">
<CardContent className="p-6">
<div className="flex items-start gap-4">
<AlertCircle className="h-6 w-6 text-yellow-500 flex-shrink-0 mt-0.5" />
<div className="flex-1">
<h3 className="font-bold text-yellow-500 uppercase mb-2">{t('settingsUi.about.betaTitle')}</h3>
<p className="text-sm text-gray-300 mb-4">
{t('settingsUi.about.betaDesc')}
</p>
<div className="flex flex-col sm:flex-row gap-3 items-start sm:items-center">
<div className="flex-1 bg-black/30 rounded-lg p-3 border border-yellow-500/20 min-w-0">
<p className="text-xs text-gray-400 mb-1">{t('settingsUi.about.giveFeedback')}</p>
<code className="text-xs text-yellow-400 break-all">
npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx
</code>
</div>
<div className="flex flex-wrap gap-2">
<Link to="/community">
<Button
size="sm"
variant="outline"
className="gap-1.5 border-[#ccff00]/50 text-[#ccff00] hover:bg-[#ccff00]/10"
>
<MessageCircle className="h-3.5 w-3.5" />
{t('communityUi.link')}
</Button>
</Link>
<Button
variant="outline"
size="sm"
className="border-yellow-500/50 text-yellow-500 hover:bg-yellow-500/10"
onClick={copyNpub}
>
{t('settingsUi.about.copyNpub')}
</Button>
{user ? (
<Link to={bugReportUrl}>
<Button
size="sm"
className="bg-yellow-500 text-black hover:bg-yellow-400"
>
{t('settingsUi.about.reportBug')}
</Button>
</Link>
) : (
<a
href="https://njump.me/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx"
target="_blank"
rel="noopener noreferrer"
>
<Button
size="sm"
className="bg-yellow-500 text-black hover:bg-yellow-400"
>
{t('settingsUi.about.viewProfile')}
</Button>
</a>
)}
</div>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Download on Zapstore */}
<Card className="bg-black/90 border-2 border-[#ccff00]/50 mt-8">
<CardContent className="p-6">
<div className="flex flex-col sm:flex-row items-center gap-4">
<div className="flex-1 text-center sm:text-left">
<div className="flex items-center gap-2 justify-center sm:justify-start mb-2">
<Smartphone className="h-5 w-5 text-[#ccff00]" />
<h3 className="font-black uppercase text-[#ccff00]">{t('settingsUi.about.downloadApp')}</h3>
</div>
<p className="text-sm text-gray-300">
{t('settingsUi.about.downloadAppDesc')}
</p>
</div>
<a
href={APP_INSTALL_URL}
target="_blank"
rel="noopener noreferrer"
className="flex-shrink-0"
>
<Button className="gap-2 bg-[#ccff00] text-black hover:bg-[#ccff00]/90 font-bold uppercase px-6">
<Download className="h-4 w-4" />
{t('settingsUi.about.getOnZapstore')}
</Button>
</a>
</div>
</CardContent>
</Card>
{/* Pass the app on (Android only) — QR / share sheet / NFC tag. */}
<ShareAppCard />
{/* Credits */}
<Card className="bg-black/90 border-2 border-gray-700 mt-8">
<CardContent className="p-6">
<h3 className="font-black uppercase text-white mb-4 flex items-center gap-2">
<Heart className="h-5 w-5 text-[#ff0040]" />
{t('settingsUi.about.credits')}
</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm">
{[
{ label: t('settingsUi.about.creditPoweredBy'), name: 'Nostr', url: 'https://github.com/nostr-protocol/nostr', desc: t('settingsUi.about.creditNostr') },
{ label: t('settingsUi.about.creditCrewChat'), name: 'Cordn', url: 'https://cordn.net/', desc: t('settingsUi.about.creditCordn') },
{ label: t('settingsUi.about.creditEcash'), name: 'Cashu', url: 'https://cashu.space/', desc: t('settingsUi.about.creditCashu') },
{ label: t('settingsUi.about.creditWalletConnect'), name: 'NWC', url: 'https://docs.nwc.dev/', desc: t('settingsUi.about.creditNwc') },
{ label: t('settingsUi.about.creditSigning'), name: 'Amber', url: 'https://github.com/greenart7c3/Amber', desc: t('settingsUi.about.creditAmber') },
{ label: t('settingsUi.about.creditMapData'), name: 'BTCMap', url: 'https://btcmap.org/', desc: t('settingsUi.about.creditBtcmap') },
{ label: t('settingsUi.about.creditCrowdfunding'), name: 'Angor', url: 'https://angor.io/project/angor1qtunna00uqyx52rr0nvqa059z2gknhrmn7urd6z', desc: t('settingsUi.about.creditAngor') },
{ label: t('settingsUi.about.creditDistributed'), name: 'Zapstore', url: 'https://zapstore.dev/apps/org.skatespots.app', desc: t('settingsUi.about.creditZapstore') },
{ label: t('settingsUi.about.creditTrust'), name: 'ContextVM', url: 'https://contextvm.org/s/e3564bb877adb0c99a7e4973ccb22e516d7d9eca0027d0bd62a04174ed670530', desc: t('settingsUi.about.creditContextvm') },
].map((item) => (
<a
key={item.name}
href={item.url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-3 p-3 rounded-lg bg-black/50 border border-gray-800 hover:border-[#ccff00]/40 hover:bg-[#ccff00]/5 transition-all group"
>
<ExternalLink className="h-4 w-4 text-gray-600 group-hover:text-[#ccff00] flex-shrink-0" />
<div className="min-w-0">
<span className="text-gray-500 text-xs">{item.label}: </span>
<span className="font-bold text-white group-hover:text-[#ccff00] transition-colors">{item.name}</span>
<p className="text-xs text-gray-500 truncate">{item.desc}</p>
</div>
</a>
))}
</div>
</CardContent>
</Card>
{/* Sasquatch — Ask me anything */}
<Card className="bg-gradient-to-br from-amber-950/30 to-[#ff6600]/10 border-2 border-amber-500/40 mb-8">
<CardContent className="p-6 flex flex-col sm:flex-row items-center gap-5">
<div className="text-5xl flex-shrink-0">🦧</div>
<div className="flex-1 text-center sm:text-left">
<h3 className="text-xl font-black text-white uppercase mb-1">{t('settingsUi.about.stillQuestions')}</h3>
<p className="text-gray-400 text-sm">
{t('settingsUi.about.stillQuestionsDesc')}
</p>
</div>
<Button
onClick={() => window.dispatchEvent(new CustomEvent('sasquatch:ask', { detail: { question: 'Tell me about SkateSpots' } }))}
className="bg-amber-500 hover:bg-amber-400 text-black font-bold gap-2 flex-shrink-0 rounded-full px-6"
>
<MessageCircle className="h-4 w-4" />
{t('settingsUi.about.askSasquatch')}
</Button>
</CardContent>
</Card>
{/* Powered By */}
<div className="text-center mt-8 pb-6 px-4">
<p className="text-gray-400 mb-3 uppercase tracking-wide text-sm">{t('settingsUi.about.poweredBy')}</p>
<div className="flex flex-wrap items-center justify-center gap-2 md:gap-3">
<a href="https://github.com/nostr-protocol/nostr" target="_blank" rel="noopener noreferrer"
className="text-[#ccff00] hover:text-[#ccff00]/80 font-black text-lg md:text-xl uppercase">
Nostr
</a>
<span className="text-gray-600">•</span>
<span className="text-[#ff0040] font-black text-lg md:text-xl uppercase">{t('settingsUi.about.decentralized')}</span>
<span className="text-gray-600">•</span>
<span className="text-orange-400 font-black text-lg md:text-xl uppercase">{t('settingsUi.about.communityOwned')}</span>
</div>
</div>
</div>
</>
);
}