Files
website/apps/website/components/stats.tsx

176 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { HandCoins, Users } from "lucide-react";
import React from "react";
import { useId } from "react";
import NumberTicker from "./ui/number-ticker";
const statsValues = {
githubStars: 18100,
dockerDownloads: 1000000,
contributors: 135,
sponsors: 45,
};
export function StatsSection() {
return (
<div className="py-20 lg:py-40 flex flex-col gap-10 px-4 ">
<div className="mx-auto max-w-2xl md:text-center">
<h2 className="font-display text-3xl tracking-tight sm:text-4xl text-center">
Stats You Didnt Ask For (But Secretly Love to See)
</h2>
<p className="mt-4 text-lg tracking-tight text-muted-foreground text-center">
Just a few numbers to show were not *completely* making this up.
Turns out, Dokploy has actually helped a few peoplewho knew?
</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-10 md:gap-2 max-w-7xl mx-auto">
{grid.map((feature, index) => (
<div
key={feature.title}
className="relative bg-gradient-to-b from-neutral-900 to-neutral-950 p-6 rounded-3xl overflow-hidden"
>
<Grid size={20} />
<p className="text-base font-bold text-white relative z-20 flex flex-row gap-4 items-center">
{feature.title}
{feature.icon}
</p>
<p className="text-neutral-400 mt-4 text-base font-normal relative z-20">
{feature.description}
</p>
{feature.component}
</div>
))}
</div>
</div>
);
}
const grid = [
{
title: "GitHub Stars",
description: `With over ${(statsValues.githubStars / 1000).toFixed(1)}k stars on GitHub, Dokploy is trusted by developers worldwide. Explore our repositories and join our community!`,
icon: (
<svg aria-hidden="true" className="h-6 w-6 fill-white">
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2Z" />
</svg>
),
component: (
<p className="whitespace-pre-wrap text-2xl !font-semibold tracking-tighter mt-4">
<NumberTicker value={statsValues.githubStars} />+
</p>
),
},
{
title: "DockerHub Downloads",
description: `Downloaded over ${(statsValues.dockerDownloads / 1000).toFixed(0)}k times, Dokploy has become a go-to solution for seamless deployments. Discover our presence on DockerHub.`,
icon: (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6 fill-white"
>
<path d="M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z" />
</svg>
),
component: (
<p className="whitespace-pre-wrap text-2xl !font-semibold tracking-tighter mt-4">
<NumberTicker value={statsValues.dockerDownloads} />+
</p>
),
},
{
title: "Community Contributors",
description: `Thanks to a growing base of over ${statsValues.contributors} contributors, Dokploy continues to thrive with valuable contributions from developers around the world.`,
icon: <Users className="h-6 w-6 stroke-white" />,
component: (
<p className="whitespace-pre-wrap text-2xl !font-semibold tracking-tighter mt-4">
<NumberTicker value={statsValues.contributors} />+
</p>
),
},
{
title: "Sponsors",
description: `More than ${statsValues.sponsors} companies/individuals have sponsored Dokploy, ensuring a steady flow of support and resources. Join our community!`,
icon: <HandCoins className="h-6 w-6 stroke-white" />,
component: (
<p className="whitespace-pre-wrap text-2xl !font-semibold tracking-tighter mt-4">
<NumberTicker value={statsValues.sponsors} />+
</p>
),
},
];
export const Grid = ({
pattern,
size,
}: {
pattern?: number[][];
size?: number;
}) => {
const p = pattern ?? [
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
];
return (
<div className="pointer-events-none absolute left-1/2 top-0 -ml-20 -mt-2 h-full w-full [mask-image:linear-gradient(white,transparent)]">
<div className="absolute inset-0 bg-gradient-to-r [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] from-zinc-900/30 to-zinc-900/30 opacity-100">
<GridPattern
width={size ?? 20}
height={size ?? 20}
x="-12"
y="4"
squares={p}
className="absolute inset-0 h-full w-full mix-blend-overlay fill-white/10 stroke-white/10 "
/>
</div>
</div>
);
};
export function GridPattern({ width, height, x, y, squares, ...props }: any) {
const patternId = useId();
return (
<svg aria-hidden="true" {...props}>
<defs>
<pattern
id={patternId}
width={width}
height={height}
patternUnits="userSpaceOnUse"
x={x}
y={y}
>
<path d={`M.5 ${height}V.5H${width}`} fill="none" />
</pattern>
</defs>
<rect
width="100%"
height="100%"
strokeWidth={0}
fill={`url(#${patternId})`}
/>
{squares && (
<svg x={x} y={y} className="overflow-visible">
{squares.map(([x, y]: any) => (
<rect
strokeWidth="0"
key={`${x}-${y}`}
width={width + 1}
height={height + 1}
x={x * width}
y={y * height}
/>
))}
</svg>
)}
</svg>
);
}