Files
reui-blocks/blocks/stats13.tsx
T

160 lines
5.3 KiB
TypeScript

"use client";
import NumberFlow from "@number-flow/react";
import { motion } from "framer-motion";
import { CirclePercent } from "lucide-react";
import React from "react";
import { cn } from "@/lib/utils";
const numberFlowLocales = "fa-IR-u-nu-latn";
const css = `
.candy-bg {
background-color: hsl(0 0% 96%, 2%);
background-image: linear-gradient(
135deg,
hsl(0 0% 96%) 25%,
transparent 25.5%,
transparent 50%,
hsl(0 0% 96%) 50.5%,
hsl(0 0% 96%) 75%,
transparent 75.5%,
transparent
);
background-size: 10px 10px;
}`;
interface Stats13Props {
className?: string;
}
const Stats13 = ({ className }: Stats13Props) => {
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<style>{css}</style>
<div className="gradient container">
<div className="mx-auto max-w-2xl text-center">
<h1 className="font-calSans w-full text-2xll font-medium lg:text-2xll">
نرخ تبدیل پایپ‌لاین، شفاف و قابل مقایسه
</h1>
<p className="my-4 tracking-tight text-muted-foreground lg:px-15 lg:text-lg">
عملکرد فروش خود را کنار رقبا ببینید و گلوگاه‌های تبدیل را سریع
شناسایی کنید.
</p>
</div>
<div className="relative mx-auto mt-20 flex h-112 max-w-4xl items-center justify-center gap-2">
{[
{ value: 35, label: "رقیب الف", delay: 0.2 },
{ value: 25, label: "رقیب ب", delay: 0.4 },
{
value: 99,
label: "ShadcnBlocks",
className: "bg-sky-400",
showToolTip: true,
delay: 0.6,
},
{ value: 37, label: "رقیب ج", delay: 0.8 },
].map((props, index) => (
<motion.div
key={index}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.5,
delay: index * 0.2,
type: "spring",
damping: 10,
}}
className="h-full w-full"
>
<BarChart {...props} />
</motion.div>
))}
</div>
</div>
</section>
);
};
export { Stats13 };
const BarChart = ({
value,
label,
className = "",
showToolTip = false,
delay = 0,
}: {
value: number;
label: string;
className?: string;
showToolTip?: boolean;
delay?: number;
}) => {
return (
<div className="group relative h-full w-full">
<div className="candy-bg relative h-full w-full overflow-hidden rounded-[40px]">
<motion.div
initial={{ opacity: 0, y: 100, height: 0 }}
animate={{ opacity: 1, y: 0, height: `${value}%` }}
transition={{ duration: 0.5, type: "spring", damping: 20, delay }}
className={cn(
"absolute bottom-0 mt-auto w-full rounded-[40px] bg-primary/80 p-3 text-white",
className,
)}
>
<div className="relative flex h-15 w-full items-center justify-center gap-2 rounded-full bg-muted/20 tracking-tighter">
<div className="absolute top-1 start-1 hidden h-13 w-13 items-center justify-center rounded-full bg-muted/20 md:flex">
<CirclePercent className="size-8" />
</div>
<NumberFlow
value={value}
locales={numberFlowLocales}
suffix="٪"
/>
</div>
</motion.div>
</div>
<motion.div
initial={{ opacity: 0, y: 100, height: 0 }}
animate={{ opacity: 1, y: 0, height: `${value}%` }}
transition={{ duration: 0.5, type: "spring", damping: 15, delay }}
className="absolute bottom-0 w-full"
>
<motion.div
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: showToolTip ? 1 : 0, y: showToolTip ? 0 : 100 }}
transition={{ duration: 0.5, type: "spring", damping: 15, delay }}
className="absolute -top-9 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-xl bg-muted-foreground px-2 py-1 text-white"
>
<div className="absolute -bottom-9 left-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white bg-muted-foreground transition-all duration-300 ease-in-out" />
<svg
className={cn(
"absolute -bottom-2 left-1/2 -translate-x-1/2",
className?.includes("bg-sky-400")
? "text-sky-400"
: "text-muted-foreground",
)}
width="10"
height="10"
viewBox="0 0 10 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.83855 8.41381C4.43827 9.45255 5.93756 9.45255 6.53728 8.41381L9.65582 3.01233C10.2555 1.97359 9.50589 0.675159 8.30646 0.675159H2.06937C0.869935 0.675159 0.120287 1.97359 0.720006 3.01233L3.83855 8.41381Z"
fill="currentColor"
/>
</svg>
نرخ تبدیل
</motion.div>
</motion.div>
<p className="mx-auto mt-2 w-fit tracking-tight text-muted-foreground/80">
{label}
</p>
</div>
);
};