198 lines
4.8 KiB
TypeScript
198 lines
4.8 KiB
TypeScript
import { For } from "solid-js";
|
|
import type { JSX } from "solid-js";
|
|
import { cn } from "~/lib/utils";
|
|
import PageContainer from "~/components/layout/PageContainer";
|
|
|
|
interface Step {
|
|
number: number;
|
|
title: string;
|
|
description: string;
|
|
icon: () => JSX.Element;
|
|
}
|
|
|
|
function EnrollIcon() {
|
|
return (
|
|
<svg
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="w-8 h-8 text-white"
|
|
>
|
|
<path
|
|
d="M12 4a4 4 0 100 8 4 4 0 000-8zM6 21v-2a4 4 0 014-4h4a4 4 0 014 4v2"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path
|
|
d="M17 8l2 2 4-4"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
function MonitorIcon() {
|
|
return (
|
|
<svg
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="w-8 h-8 text-white"
|
|
>
|
|
<path
|
|
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
/>
|
|
<path
|
|
d="M12 8v4l3 3"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
<path
|
|
d="M3 12h3m15 0h3M12 3v3m0 15v3"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
opacity="0.5"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
function AlertIcon() {
|
|
return (
|
|
<svg
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="w-8 h-8 text-white"
|
|
>
|
|
<path
|
|
d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
<path
|
|
d="M12 22a2 2 0 01-2-2h4a2 2 0 01-2 2z"
|
|
fill="currentColor"
|
|
/>
|
|
<path
|
|
d="M12 11v3m0-6v1"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
const steps: Step[] = [
|
|
{
|
|
number: 1,
|
|
title: "Enroll Your Identity",
|
|
description:
|
|
"Sign up and add your emails, phone numbers, and family members to create your protection profile.",
|
|
icon: EnrollIcon,
|
|
},
|
|
{
|
|
number: 2,
|
|
title: "We Monitor 24/7",
|
|
description:
|
|
"Our system runs continuous dark web scans, voiceprint detection, and spam filtering to catch threats early.",
|
|
icon: MonitorIcon,
|
|
},
|
|
{
|
|
number: 3,
|
|
title: "Get Instant Alerts",
|
|
description:
|
|
"Receive real-time notifications the moment a threat is detected, with clear guidance on what to do next.",
|
|
icon: AlertIcon,
|
|
},
|
|
];
|
|
|
|
interface StepBlockProps {
|
|
step: Step;
|
|
index: number;
|
|
}
|
|
|
|
function StepBlock(props: StepBlockProps) {
|
|
const isEven = props.index % 2 === 0;
|
|
const Icon = props.step.icon;
|
|
|
|
return (
|
|
<div
|
|
class={cn(
|
|
"flex gap-8 md:flex-row flex-col",
|
|
isEven ? "" : "md:flex-row-reverse",
|
|
)}
|
|
>
|
|
<div class="flex-1">
|
|
<div class="flex items-start gap-5">
|
|
<div class="w-14 h-14 rounded-full gradient-primary shadow-glow-primary flex items-center justify-center shrink-0">
|
|
<Icon />
|
|
</div>
|
|
<div>
|
|
<div class="inline-flex items-center gap-2 mb-1.5">
|
|
<span class="text-sm font-semibold text-[var(--color-brand-primary)]">
|
|
Step {props.step.number}
|
|
</span>
|
|
</div>
|
|
<h3 class="text-xl md:text-2xl font-bold text-[var(--color-text-primary)] mb-2">
|
|
{props.step.title}
|
|
</h3>
|
|
<p class="text-base text-[var(--color-text-secondary)] leading-relaxed">
|
|
{props.step.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex-1 hidden md:block" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface HowItWorksSectionProps {
|
|
class?: string;
|
|
}
|
|
|
|
export default function HowItWorksSection(props: HowItWorksSectionProps) {
|
|
return (
|
|
<section
|
|
id="how-it-works"
|
|
class={cn("py-20 md:py-28 scroll-mt-16", props.class)}
|
|
>
|
|
<PageContainer py="py-8">
|
|
<div class="text-center mb-16">
|
|
<h2 class="text-3xl md:text-4xl lg:text-5xl font-bold text-[var(--color-text-primary)] mb-4">
|
|
How It Works
|
|
</h2>
|
|
<p class="text-lg text-[var(--color-text-secondary)] max-w-2xl mx-auto">
|
|
Three simple steps to full identity protection
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex flex-col gap-12 md:gap-16">
|
|
<For each={steps}>
|
|
{(step, index) => <StepBlock step={step} index={index()} />}
|
|
</For>
|
|
</div>
|
|
</PageContainer>
|
|
</section>
|
|
);
|
|
}
|