improve(public): re-design landing page a bit

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-06-18 14:38:14 +02:00
parent 9b16bbaccd
commit 5c6d71f176
23 changed files with 859 additions and 154 deletions

View File

@@ -1,46 +1,125 @@
import { cn } from '@/lib/utils';
import { DollarSignIcon } from 'lucide-react';
import {
ArrowRightIcon,
CalendarIcon,
CheckIcon,
ChevronRightIcon,
CookieIcon,
CreditCardIcon,
DatabaseIcon,
DollarSignIcon,
FlaskRoundIcon,
GithubIcon,
ServerIcon,
StarIcon,
} from 'lucide-react';
import Link from 'next/link';
import { useState } from 'react';
import { Competition } from './competition';
import { HeroCarousel } from './hero-carousel';
import { HeroMap } from './hero-map';
import { Tag } from './tag';
import { Button } from './ui/button';
const perks = [
{ text: 'Free trial 30 days', icon: CalendarIcon },
{ text: 'No credit card required', icon: CreditCardIcon },
{ text: 'Cookie-less tracking', icon: CookieIcon },
{ text: 'Open-source', icon: GithubIcon },
{ text: 'Your data, your rules', icon: DatabaseIcon },
{ text: 'Self-hostable', icon: ServerIcon },
];
export function Hero() {
return (
<HeroContainer>
{/* Shadow bottom */}
<div className="w-full absolute bottom-0 h-32 bg-gradient-to-t from-background to-transparent z-20" />
{/* Content */}
<div className="container relative z-10">
<div className="max-w-2xl col gap-4 pt-44 text-center mx-auto ">
<Tag className="self-center">
<DollarSignIcon className="size-4" />
Release 1.0 is live!
</Tag>
<h1 className="text-4xl md:text-6xl font-bold leading-[1.1]">
An open-source alternative to <span>Mixpanel</span>
</h1>
<p className="text-xl text-muted-foreground">
The power of Mixpanel, the ease of Plausible and nothing from Google
Analytics 😉
</p>
</div>
{/* CTA */}
<div className="col md:row gap-4 center-center my-12">
<Button size="lg" asChild>
<div className="container relative z-10 col sm:row sm:py-44 max-sm:pt-32">
<div className="col gap-8 w-full sm:w-1/2 sm:pr-12">
<div className="col gap-4">
<Tag className="self-start">
<StarIcon className="size-4 fill-yellow-500 text-yellow-500" />
Trusted by +2000 projects
</Tag>
<h1
className="text-4xl md:text-5xl font-extrabold leading-[1.1]"
title="An open-source alternative to Mixpanel"
>
An open-source alternative to <Competition />
</h1>
<p className="text-xl text-muted-foreground">
A web and product analytics platform that combines the power of
Mixpanel with the ease of Plausible and one of the best Google
Analytics replacements.
</p>
</div>
<Button size="lg" asChild className="group w-72">
<Link href="https://dashboard.openpanel.dev/onboarding">
Try it for free
Get started now
<ChevronRightIcon className="size-4 group-hover:translate-x-1 transition-transform group-hover:scale-125" />
</Link>
</Button>
<p className="text-sm text-muted-foreground">
Free trial for 30 days, no credit card required
</p>
<ul className="grid grid-cols-2 gap-2">
{perks.map((perk) => (
<li key={perk.text} className="text-sm text-muted-foreground">
<perk.icon className="size-4 inline-block mr-1" />
{perk.text}
</li>
))}
</ul>
</div>
<HeroCarousel />
<div className="col sm:w-1/2 relative group">
<div
className={cn([
'overflow-hidden rounded-lg border border-border bg-background shadow-lg',
'sm:absolute sm:left-0 sm:-top-12 sm:w-[800px] sm:-bottom-32',
'max-sm:h-[800px] max-sm:-mx-4 max-sm:mt-12 relative',
])}
>
{/* Window controls */}
<div className="flex items-center gap-2 px-4 py-2 border-b border-border bg-muted/50 h-12">
<div className="flex gap-1.5">
<div className="w-3 h-3 rounded-full bg-red-500" />
<div className="w-3 h-3 rounded-full bg-yellow-500" />
<div className="w-3 h-3 rounded-full bg-green-500" />
</div>
{/* URL bar */}
<a
target="_blank"
rel="noreferrer noopener nofollow"
href="https://demo.openpanel.dev/demo/shoey"
className="group flex-1 mx-4 px-3 py-1 text-sm bg-background rounded-md border border-border flex items-center gap-2"
>
<span className="text-muted-foreground flex-1">
https://demo.openpanel.dev
</span>
<ArrowRightIcon className="size-4 opacity-0 group-hover:opacity-100 transition-opacity" />
</a>
</div>
<iframe
src={'https://demo.openpanel.dev/demo/shoey?range=lastHour'}
className="w-full h-full"
title="Live preview"
scrolling="no"
/>
<div className="pointer-events-none absolute inset-0 top-12 center-center group-hover:bg-foreground/20 transition-colors">
<Button
asChild
className="group-hover:opacity-100 opacity-0 transition-opacity pointer-events-auto"
>
<Link
href="https://demo.openpanel.dev/demo/shoey"
rel="noreferrer noopener nofollow"
target="_blank"
>
Test live demo
<FlaskRoundIcon className="size-4" />
</Link>
</Button>
</div>
</div>
</div>
</div>
</HeroContainer>
);
@@ -55,13 +134,6 @@ export function HeroContainer({
}): React.ReactElement {
return (
<section className={cn('radial-gradient overflow-hidden relative')}>
{/* Map */}
<HeroMap />
{/* Gradient over map */}
<div className="absolute inset-0 radial-gradient-dot-1 select-none" />
<div className="absolute inset-0 radial-gradient-dot-1 select-none" />
<div className={cn('relative z-10', className)}>{children}</div>
{/* Shadow bottom */}