SkateSpots/src/pages/TrustPage.tsx

135 lines
4.1 KiB
TypeScript

import { useSeoMeta } from '@unhead/react';
import { Link } from 'react-router-dom';
import { Shield, CheckCircle2, HelpCircle, Flag, Users, Scale, AlertTriangle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useTranslation } from '@/contexts/language';
function Section({
icon: Icon,
color,
title,
children,
}: {
icon: React.ComponentType<{ className?: string; style?: React.CSSProperties }>;
color: string;
title: string;
children: React.ReactNode;
}) {
return (
<section className="rounded-2xl border border-white/8 bg-white/3 p-5">
<div className="mb-3 flex items-center gap-3">
<div
className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-xl"
style={{ background: `${color}1a`, border: `1px solid ${color}40` }}
>
<Icon className="h-5 w-5" style={{ color }} />
</div>
<h2 className="text-lg font-black uppercase tracking-wide text-white">{title}</h2>
</div>
<div className="space-y-3 text-sm leading-relaxed text-gray-400">{children}</div>
</section>
);
}
function Point({
icon: Icon,
color,
title,
desc,
}: {
icon: React.ComponentType<{ className?: string; style?: React.CSSProperties }>;
color: string;
title: string;
desc: string;
}) {
return (
<div className="flex items-start gap-3">
<Icon className="mt-0.5 h-4 w-4 flex-shrink-0" style={{ color }} />
<div>
<p className="font-bold text-white">{title}</p>
<p>{desc}</p>
</div>
</div>
);
}
/**
* Public explainer for the trust buckets. The badge has to be legible and
* attributable, and absence has to be explained (it is the common case), or the
* whole feature reads as an opaque verdict.
*/
export default function TrustPage() {
const { t } = useTranslation();
useSeoMeta({
title: t('trustUi.seoTitle'),
description: t('trustUi.seoDescription'),
});
return (
<div className="container max-w-3xl space-y-5 py-10">
<header className="space-y-3">
<div className="flex items-center gap-3">
<Shield className="h-8 w-8 text-[#ccff00]" />
<h1 className="text-3xl font-black uppercase tracking-wide text-white">
{t('trustUi.title')}
</h1>
</div>
<p className="text-gray-400">{t('trustUi.intro')}</p>
</header>
<Section icon={Scale} color="#13d2e5" title={t('trustUi.statesTitle')}>
<Point
icon={CheckCircle2}
color="#22c55e"
title={t('trustUi.verifiedTitle')}
desc={t('trustUi.verifiedDesc')}
/>
<Point
icon={HelpCircle}
color="#8c929e"
title={t('trustUi.unknownTitle')}
desc={t('trustUi.unknownDesc')}
/>
<Point
icon={Flag}
color="#ef4444"
title={t('trustUi.flaggedTitle')}
desc={t('trustUi.flaggedDesc')}
/>
</Section>
<Section icon={AlertTriangle} color="#f59e0b" title={t('trustUi.absenceTitle')}>
<p>{t('trustUi.absenceDesc')}</p>
</Section>
<Section icon={Users} color="#6366f1" title={t('trustUi.sourceTitle')}>
<p>{t('trustUi.sourceDesc')}</p>
</Section>
<Section icon={Flag} color="#ef4444" title={t('trustUi.endorsementTitle')}>
<p>{t('trustUi.endorsementDesc')}</p>
</Section>
<Section icon={Scale} color="#13d2e5" title={t('trustUi.povTitle')}>
<p>{t('trustUi.povDesc')}</p>
</Section>
<div className="flex flex-col items-center gap-3 pt-2">
<Link to="/settings">
<Button className="gap-2 bg-[#ccff00] text-black hover:bg-[#ccff00]/90">
{t('trustUi.settingsCta')}
</Button>
</Link>
<a
href="https://git.skate-spots.org/skatespots/SkateSpots/blob/main/docs/THREAT_MODEL.md"
target="_blank"
rel="noopener noreferrer"
className="text-xs text-gray-500 underline decoration-dotted underline-offset-2 hover:text-gray-300"
>
{t('common.learnMore')}
</a>
</div>
</div>
);
}