340 lines
16 KiB
TypeScript
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>
|
|
</>
|
|
);
|
|
}
|