public: add supporter

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-11-08 22:45:22 +01:00
parent 49d2c7512a
commit 720b56aba6
11 changed files with 450 additions and 182 deletions

View File

@@ -12,7 +12,7 @@ function formatStars(stars: number) {
}
export function GithubButton() {
const [stars, setStars] = useState(3_700);
const [stars, setStars] = useState(4_800);
useEffect(() => {
getGithubRepoInfo().then((res) => {
if (res?.stargazers_count) {

View File

@@ -4,7 +4,6 @@ import { cn } from '@/lib/utils';
import { AnimatePresence, motion } from 'framer-motion';
import { MenuIcon } from 'lucide-react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
import { GithubButton } from './github-button';
import { Logo } from './logo';

View File

@@ -0,0 +1,130 @@
import { cn } from '@/lib/utils';
import {
CheckIcon,
HeartHandshakeIcon,
MessageSquareIcon,
RocketIcon,
SparklesIcon,
StarIcon,
ZapIcon,
PackageIcon,
} from 'lucide-react';
import Link from 'next/link';
const perks = [
{
icon: PackageIcon,
title: 'Latest Docker Images',
description: 'Access to bleeding-edge builds on every commit',
href: '/docs/self-hosting/supporter-access-latest-docker-images',
highlight: true,
},
{
icon: MessageSquareIcon,
title: 'Prioritized Support',
description: 'Get help faster with priority Discord support',
highlight: true,
},
{
icon: RocketIcon,
title: 'Feature Requests',
description: 'Your ideas get prioritized in our roadmap',
highlight: true,
},
{
icon: StarIcon,
title: 'Exclusive Discord Role',
description: 'Special badge and recognition in our community',
},
{
icon: SparklesIcon,
title: 'Early Access',
description: 'Try new features before public release',
},
{
icon: ZapIcon,
title: 'Direct Impact',
description: 'Your support directly funds development',
},
];
export function SupporterPerks({ className }: { className?: string }) {
return (
<div
className={cn(
'col gap-4 p-6 rounded-xl border bg-card',
'sticky top-24',
className,
)}
>
<div className="col gap-2 mb-2">
<div className="row gap-2 items-center">
<HeartHandshakeIcon className="size-5 text-primary" />
<h3 className="font-semibold text-lg">Supporter Perks</h3>
</div>
<p className="text-sm text-muted-foreground">
Everything you get when you support OpenPanel
</p>
</div>
<div className="col gap-3">
{perks.map((perk, index) => {
const Icon = perk.icon;
return (
<div
key={index}
className={cn(
'col gap-1.5 p-3 rounded-lg border transition-colors',
perk.highlight
? 'bg-primary/5 border-primary/20'
: 'bg-background border-border',
)}
>
<div className="row gap-2 items-start">
<Icon
className={cn(
'size-4 mt-0.5 shrink-0',
perk.highlight ? 'text-primary' : 'text-muted-foreground',
)}
/>
<div className="col gap-0.5 flex-1 min-w-0">
<div className="row gap-2 items-center">
<h4
className={cn(
'font-medium text-sm',
perk.highlight && 'text-primary',
)}
>
{perk.title}
</h4>
{perk.highlight && (
<CheckIcon className="size-3.5 text-primary shrink-0" />
)}
</div>
<p className="text-xs text-muted-foreground">
{perk.description}
</p>
{perk.href && (
<Link
href={perk.href}
className="text-xs text-primary hover:underline mt-1"
>
Learn more
</Link>
)}
</div>
</div>
</div>
);
})}
</div>
<div className="mt-4 pt-4 border-t">
<p className="text-xs text-muted-foreground text-center">
Starting at <strong className="text-foreground">$20/month</strong>
</p>
</div>
</div>
);
}

View File

@@ -1,35 +0,0 @@
import { HeartHandshakeIcon } from 'lucide-react';
import Link from 'next/link';
import { SingleSwirl } from '../Swirls';
import { SectionHeader } from '../section';
import { Tag } from '../tag';
import { Button } from '../ui/button';
export function Supporter() {
return (
<section className="overflow-hidden relative bg-foreground dark:bg-background-dark text-background dark:text-foreground rounded-xl p-0 pb-32 pt-16 mx-auto">
<SingleSwirl className="pointer-events-none absolute top-0 bottom-0 left-0" />
<SingleSwirl className="pointer-events-none rotate-180 absolute top-0 bottom-0 -right-0 opacity-50" />
<div className="container center-center col">
<SectionHeader
tag={
<Tag>
<HeartHandshakeIcon className="size-4" />
Support OpenPanel
</Tag>
}
title="Support the future of open analytics"
description="Join our community of supporters and help us build the best open-source alternative to Mixpanel. Every contribution helps keep OpenPanel free and accessible."
/>
<Button size="lg" variant="secondary" asChild>
<Link href="https://buy.polar.sh/polar_cl_Az1CruNFzQB2bYdMOZmGHqTevW317knWqV44W1FqZmV">
Become a supporter
</Link>
</Button>
<div className="text-xs text-muted-foreground max-w-sm mt-4">
Pay what you want and help us keep the lights on.
</div>
</div>
</section>
);
}