Files
reui-blocks/blocks/stats15.tsx
T

217 lines
7.3 KiB
TypeScript

"use client";
import NumberFlow from "@number-flow/react";
import { motion } from "framer-motion";
import { ArrowLeft } from "lucide-react";
import React, { useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
const numberFlowLocales = "fa-IR-u-nu-latn";
const formatNumber = (value: number) => value.toLocaleString("fa-IR");
interface Stats15Props {
className?: string;
}
const Stats15 = ({ className }: Stats15Props) => {
const ref = useRef(null);
const IllustrationRef = useRef(null);
const [selectedYear, setSelectedYear] = useState(2021);
const Stats = {
2021: {
TotalRevenue: 12.3,
TotalUsers: 0.3,
CompanyGrowth: 300,
NewCustomers: 100,
BigCorpClients: 10,
PathHeight: 0,
},
2022: {
TotalRevenue: 105,
TotalUsers: 50,
CompanyGrowth: 30,
NewCustomers: 1.5,
BigCorpClients: 75,
PathHeight: 55,
},
2023: {
TotalRevenue: 250,
TotalUsers: 120,
CompanyGrowth: 45,
NewCustomers: 2.8,
BigCorpClients: 150,
PathHeight: 105,
},
2024: {
TotalRevenue: 500,
TotalUsers: 300,
CompanyGrowth: 65,
NewCustomers: 4.2,
BigCorpClients: 250,
PathHeight: 160,
},
};
const years = Object.keys(Stats).map(Number);
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container flex flex-col md:flex-row">
<div className="z-10 md:flex-1">
<h1 className="font-cal max-w-xl text-2xll font-medium tracking-tighter md:text-2xll">
مسیر رشد درآمد، سال‌به‌سال
</h1>
<p className="mt-4 max-w-xl text-muted-foreground/80">
کاربران فعال، رشد MRR و حساب‌های جدید را در یک نمای زمانی شفاف
مقایسه کنید.
</p>
<div className="my-10 flex gap-4">
<Button
variant="secondary"
className="text-md group flex w-fit items-center justify-center gap-2 rounded-full px-4 py-1 tracking-tight"
>
<span>مستندات API</span>
<ArrowLeft className="size-4 -rotate-45 transition-all ease-out group-hover:ms-3 group-hover:rotate-0" />
</Button>
<Button
variant="default"
className="text-md group flex w-fit items-center justify-center gap-2 rounded-full px-4 py-1 tracking-tight"
>
<span>شروع رایگان</span>
<ArrowLeft className="size-4 -rotate-45 transition-all ease-out group-hover:ms-3 group-hover:rotate-0" />
</Button>
</div>
<div
ref={ref}
className="mt-12 flex max-w-3xl flex-col items-start bg-background md:mt-32 xl:bg-transparent"
>
<div className="mt-auto mb-10 grid w-full grid-cols-2 gap-4 md:grid-cols-4">
<div className="w-full text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={Stats[selectedYear as keyof typeof Stats].TotalUsers}
locales={numberFlowLocales}
format={{
minimumFractionDigits: 1,
maximumFractionDigits: 1,
}}
suffix=" هزار+"
/>
</h2>
<p className="text-sm whitespace-pre text-muted-foreground/70">
کاربر فعال
</p>
</div>
<div className="w-full text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
Stats[selectedYear as keyof typeof Stats].CompanyGrowth
}
locales={numberFlowLocales}
suffix="٪"
/>
</h2>
<p className="text-sm whitespace-pre text-muted-foreground/70">
رشد MRR
</p>
</div>
<div className="w-full text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
Stats[selectedYear as keyof typeof Stats].NewCustomers
}
locales={numberFlowLocales}
format={{
minimumFractionDigits: 1,
maximumFractionDigits: 1,
}}
suffix=" میلیون"
/>
</h2>
<p className="text-sm whitespace-pre text-muted-foreground/70">
حساب جدید
</p>
</div>
<div ref={IllustrationRef} className="w-full text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
Stats[selectedYear as keyof typeof Stats].BigCorpClients
}
locales={numberFlowLocales}
prefix="~"
suffix="+"
/>
</h2>
<p className="text-sm whitespace-pre text-muted-foreground/70">
قرارداد سازمانی
</p>
</div>
</div>
</div>
</div>
<div className="relative flex w-fit flex-row flex-wrap gap-2 md:mt-42 md:flex-col">
{years.map((year) => (
<div key={year} className="group">
<button
onClick={() => setSelectedYear(year)}
className={`relative rounded-full px-4 py-1 text-sm transition-all ease-out ${
selectedYear === year
? "bg-primary text-primary-foreground md:translate-x-8"
: "bg-muted/70 group-hover:translate-x-4 group-hover:bg-muted"
}`}
>
{formatNumber(year)} - {formatNumber(year + 1)}
</button>
</div>
))}
<LinkIllustration
className="absolute bottom-9 -right-14 hidden translate-x-full -translate-y-full text-orange-500 md:block"
PathHeight={Stats[selectedYear as keyof typeof Stats].PathHeight}
/>
</div>
</div>
</section>
);
};
export { Stats15 };
const LinkIllustration = ({ className = "", PathHeight = 0 }) => {
return (
<svg
width="280"
height="124"
viewBox="0 0 412 178"
overflow="visible"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<motion.path
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1 }}
key={PathHeight}
d={`M408.308 ${PathHeight}H294L114.965 274H1`}
stroke="currentColor"
strokeWidth="1.5"
/>
<motion.path
d={`M408.308 ${PathHeight}H294L114.965 274H1`}
stroke="black"
strokeWidth="1.5"
opacity="0.1"
/>
<circle cx="408.309" cy={PathHeight} r="5" fill="currentColor" />
<circle cx="2" cy="274" r="5" fill="currentColor" />
</svg>
);
};