Files

235 lines
8.1 KiB
TypeScript

"use client";
import NumberFlow from "@number-flow/react";
import { motion, useInView } from "framer-motion";
import { ArrowLeft, RefreshCcw } from "lucide-react";
import { useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
const numberFlowLocales = "fa-IR-u-nu-latn";
const STATS = {
monthly: {
TotalRevenue: 12.3,
TotalUsers: 0.3,
CompanyGrowth: 300,
NewCustomers: 100,
BigCorpClients: 10,
},
yearly: {
TotalRevenue: 105,
TotalUsers: 50,
CompanyGrowth: 30,
NewCustomers: 1.5,
BigCorpClients: 75,
},
} as const;
const ZERO_STATS = {
monthly: {
TotalRevenue: 0,
TotalUsers: 0,
CompanyGrowth: 0,
NewCustomers: 0,
BigCorpClients: 0,
},
yearly: {
TotalRevenue: 0,
TotalUsers: 0,
CompanyGrowth: 0,
NewCustomers: 0,
BigCorpClients: 0,
},
};
interface Stats12Props {
className?: string;
}
const Stats12 = ({ className }: Stats12Props) => {
const [showMonthlyStats, setShowMonthlyStats] = useState(false);
const ref = useRef(null);
const isInView = useInView(ref);
const stats = isInView ? STATS : ZERO_STATS;
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container flex justify-center">
<div className="flex w-full flex-col justify-between gap-4 lg:flex-row">
<div className="w-full lg:w-1/3">
<h1 className="font-calSans w-full text-2xll font-medium">
درآمد قابل اندازه‌گیری، نه وعده
</h1>
<p className="my-4 text-lg tracking-tight text-muted-foreground">
با رصد پایپ‌لاین، نرخ تبدیل و MRR، نتایج واقعی فروش را برای تیم
خود شفاف کنید.
</p>
<Button
variant="secondary"
className="text-md group mt-10 flex w-fit items-center justify-center gap-2 rounded-full px-6 py-1 tracking-tight shadow-none"
>
<span>شروع دوره آزمایشی</span>
<ArrowLeft className="size-4 -rotate-45 transition-all ease-out group-hover:ms-3 group-hover:rotate-0" />
</Button>
<div className="mt-10 lg:w-[115%]">
<Graph />
</div>
</div>
<div ref={ref} className="flex w-full flex-col items-start lg:w-1/2">
<h1 className="font-calSans text-8xl leading-0 lg:text-[10rem]">
<NumberFlow
value={
showMonthlyStats
? stats.monthly.TotalRevenue
: stats.yearly.TotalRevenue
}
locales={numberFlowLocales}
format={{
minimumFractionDigits: 1,
maximumFractionDigits: 1,
}}
suffix=" میلیون ریال"
className="font-calSans"
/>
</h1>
<div className="mb-6 flex flex-col items-center justify-center gap-6 lg:flex-row lg:gap-17">
<p>و این فقط درآمد یک سال است</p>
<Button
variant="secondary"
className="text-md group flex w-fit items-center justify-center gap-2 rounded-full px-6 py-1 tracking-tight shadow-none transition-all duration-300 ease-out active:scale-95"
onClick={() => setShowMonthlyStats(!showMonthlyStats)}
>
<span>
{showMonthlyStats
? "نمایش آمار سالانه"
: "نمایش آمار ماهانه"}
</span>
<RefreshCcw className="size-4 -rotate-45 transition-all ease-out group-hover:ms-3 group-hover:rotate-0" />
</Button>
</div>
<div className="mt-auto mb-10 grid w-full grid-cols-2 gap-14">
<div className="text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
showMonthlyStats
? stats.monthly.TotalUsers
: stats.yearly.TotalUsers
}
locales={numberFlowLocales}
format={{
minimumFractionDigits: 1,
maximumFractionDigits: 1,
}}
suffix=" هزار+"
/>
</h2>
<p className="text-muted-foreground/70">کاربر فعال</p>
</div>
<div className="text-end">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
showMonthlyStats
? stats.monthly.CompanyGrowth
: stats.yearly.CompanyGrowth
}
locales={numberFlowLocales}
suffix="٪"
/>
</h2>
<p className="text-muted-foreground/70">رشد MRR</p>
</div>
<div className="text-start">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
showMonthlyStats
? stats.monthly.NewCustomers
: stats.yearly.NewCustomers
}
locales={numberFlowLocales}
format={{
minimumFractionDigits: 1,
maximumFractionDigits: 1,
}}
suffix=" میلیون"
/>
</h2>
<p className="text-muted-foreground/70">حساب جدید</p>
</div>
<div className="text-end">
<h2 className="text-xl font-medium lg:text-2xll">
<NumberFlow
value={
showMonthlyStats
? stats.monthly.BigCorpClients
: stats.yearly.BigCorpClients
}
locales={numberFlowLocales}
prefix="~"
suffix="+"
/>
</h2>
<p className="text-muted-foreground/70">قرارداد سازمانی</p>
</div>
</div>
</div>
</div>
</div>
</section>
);
};
export { Stats12 };
function Graph() {
return (
<div className="wrapper">
<motion.svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 644 388"
initial={{
clipPath: "inset(0px 100% 0px 0px)",
}}
animate={{
clipPath: "inset(0px 0% 0px 0px)",
}}
transition={{
duration: 1,
type: "spring",
damping: 18,
}}
>
<g clipPath="url(#grad)">
<path
d="M1 118.5C1 118.5 83.308 102.999 114.735 89.4998C146.162 76.0008 189.504 87.7868 235.952 77.4998C273.548 69.1718 294.469 62.4938 329.733 46.9998C409.879 11.7848 452.946 30.9998 483.874 22.4998C514.802 13.9998 635.97 0.84884 644 1.49984"
stroke="#0090FF"
strokeWidth="2"
/>
<path
d="M113.912 89.4888C82.437 102.988 1 118.487 1 118.487V438.477H644V1.49977C635.957 0.849773 514.601 13.9988 483.625 22.4978C452.649 30.9958 409.515 11.7838 329.245 46.9938C293.926 62.4868 272.973 69.1638 235.318 77.4908C188.798 87.7768 145.388 75.9908 113.912 89.4888Z"
fill="url(#grad)"
/>
</g>
<defs>
<linearGradient
id="grad"
x1="321.5"
y1="0.476773"
x2="321.5"
y2="387.477"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#138EED" stopOpacity="0.4" />
<stop offset="1" stopColor="#058FFB" stopOpacity="0" />
</linearGradient>
</defs>
</motion.svg>
</div>
);
}