update public site

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-02-06 09:53:43 +01:00
parent b2e8398943
commit d1f12ca5e8
7 changed files with 273 additions and 4 deletions

View File

@@ -32,7 +32,7 @@
"embla-carousel-autoplay": "8.0.0-rc22",
"embla-carousel-react": "8.0.0-rc22",
"hamburger-react": "^2.5.0",
"lucide-react": "^0.286.0",
"lucide-react": "^0.323.0",
"next": "~14.0.4",
"nuqs": "^1.15.2",
"react": "18.2.0",

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>React icon</title><path d="M12 9.861A2.139 2.139 0 1 0 12 14.139 2.139 2.139 0 1 0 12 9.861zM6.008 16.255l-.472-.12C2.018 15.246 0 13.737 0 11.996s2.018-3.25 5.536-4.139l.472-.119.133.468a23.53 23.53 0 0 0 1.363 3.578l.101.213-.101.213a23.307 23.307 0 0 0-1.363 3.578l-.133.467zM5.317 8.95c-2.674.751-4.315 1.9-4.315 3.046 0 1.145 1.641 2.294 4.315 3.046a24.95 24.95 0 0 1 1.182-3.046A24.752 24.752 0 0 1 5.317 8.95zM17.992 16.255l-.133-.469a23.357 23.357 0 0 0-1.364-3.577l-.101-.213.101-.213a23.42 23.42 0 0 0 1.364-3.578l.133-.468.473.119c3.517.889 5.535 2.398 5.535 4.14s-2.018 3.25-5.535 4.139l-.473.12zm-.491-4.259c.48 1.039.877 2.06 1.182 3.046 2.675-.752 4.315-1.901 4.315-3.046 0-1.146-1.641-2.294-4.315-3.046a24.788 24.788 0 0 1-1.182 3.046zM5.31 8.945l-.133-.467C4.188 4.992 4.488 2.494 6 1.622c1.483-.856 3.864.155 6.359 2.716l.34.349-.34.349a23.552 23.552 0 0 0-2.422 2.967l-.135.193-.235.02a23.657 23.657 0 0 0-3.785.61l-.472.119zm1.896-6.63c-.268 0-.505.058-.705.173-.994.573-1.17 2.565-.485 5.253a25.122 25.122 0 0 1 3.233-.501 24.847 24.847 0 0 1 2.052-2.544c-1.56-1.519-3.037-2.381-4.095-2.381zM16.795 22.677c-.001 0-.001 0 0 0-1.425 0-3.255-1.073-5.154-3.023l-.34-.349.34-.349a23.53 23.53 0 0 0 2.421-2.968l.135-.193.234-.02a23.63 23.63 0 0 0 3.787-.609l.472-.119.134.468c.987 3.484.688 5.983-.824 6.854a2.38 2.38 0 0 1-1.205.308zm-4.096-3.381c1.56 1.519 3.037 2.381 4.095 2.381h.001c.267 0 .505-.058.704-.173.994-.573 1.171-2.566.485-5.254a25.02 25.02 0 0 1-3.234.501 24.674 24.674 0 0 1-2.051 2.545zM18.69 8.945l-.472-.119a23.479 23.479 0 0 0-3.787-.61l-.234-.02-.135-.193a23.414 23.414 0 0 0-2.421-2.967l-.34-.349.34-.349C14.135 1.778 16.515.767 18 1.622c1.512.872 1.812 3.37.824 6.855l-.134.468zM14.75 7.24c1.142.104 2.227.273 3.234.501.686-2.688.509-4.68-.485-5.253-.988-.571-2.845.304-4.8 2.208A24.849 24.849 0 0 1 14.75 7.24zM7.206 22.677A2.38 2.38 0 0 1 6 22.369c-1.512-.871-1.812-3.369-.823-6.854l.132-.468.472.119c1.155.291 2.429.496 3.785.609l.235.02.134.193a23.596 23.596 0 0 0 2.422 2.968l.34.349-.34.349c-1.898 1.95-3.728 3.023-5.151 3.023zm-1.19-6.427c-.686 2.688-.509 4.681.485 5.254.987.563 2.843-.305 4.8-2.208a24.998 24.998 0 0 1-2.052-2.545 24.976 24.976 0 0 1-3.233-.501zM12 16.878c-.823 0-1.669-.036-2.516-.106l-.235-.02-.135-.193a30.388 30.388 0 0 1-1.35-2.122 30.354 30.354 0 0 1-1.166-2.228l-.1-.213.1-.213a30.3 30.3 0 0 1 1.166-2.228c.414-.716.869-1.43 1.35-2.122l.135-.193.235-.02a29.785 29.785 0 0 1 5.033 0l.234.02.134.193a30.006 30.006 0 0 1 2.517 4.35l.101.213-.101.213a29.6 29.6 0 0 1-2.517 4.35l-.134.193-.234.02c-.847.07-1.694.106-2.517.106zm-2.197-1.084c1.48.111 2.914.111 4.395 0a29.006 29.006 0 0 0 2.196-3.798 28.585 28.585 0 0 0-2.197-3.798 29.031 29.031 0 0 0-4.394 0 28.477 28.477 0 0 0-2.197 3.798 29.114 29.114 0 0 0 2.197 3.798z"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,74 @@
import * as React from 'react';
import type { SVGProps } from 'react';
export const Blob1 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M162.9 81.7c6.8 18.6-7.8 46.3-29.5 61.3-21.6 15-50.3 17.4-70.1 3.8-19.8-13.5-30.8-42.9-23.2-62.7 7.6-19.7 33.7-29.9 60.9-30.2 27.1-.3 55.2 9.2 61.9 27.8Z" />
</svg>
);
export const Blob2 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M142.7 86.2c9.4 28.8 11.5 60-2.1 70-13.6 9.9-42.8-1.5-63.9-18.2-21.2-16.7-34.2-38.8-28.9-62C53 52.9 76.5 28.7 96.6 29.8c20.1 1.1 36.8 27.5 46.1 56.4Z" />
</svg>
);
export const Blob3 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M135.5 88.9c4.3 12.9-2.5 29.9-18.7 44-16.2 14-41.6 25.1-54.7 16.3-13.1-8.8-14-37.6-5.6-56.1C64.9 74.7 82.4 66.4 99 66.8c16.6.3 32.2 9.2 36.5 22.1Z" />
</svg>
);
export const Blob4 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M161.5 88.5c9.2 20.1 1.7 54.1-18.1 67.6-19.8 13.5-51.9 6.6-76.8-11.2-25-17.9-42.8-46.7-36-63.3 6.7-16.6 38.1-21 66.8-20.2 28.7.9 54.8 7 64.1 27.1Z" />
</svg>
);
export const Blob5 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M144.6 81.1c3.8 15.9-9.2 32.9-27.5 47.4-18.4 14.6-42.2 26.7-58 17.6-15.7-9-23.5-39.3-15.3-61.3 8.1-21.9 32.2-35.6 54.4-35 22.2.5 42.7 15.4 46.4 31.3Z" />
</svg>
);
export const Blob6 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M158 83.8c9.5 26.6 4.2 60.6-14.8 74.1-19.1 13.5-52 6.5-68.5-8.9-16.5-15.3-16.6-39-9.7-62 7-23.1 21-45.5 40.1-47.2 19.1-1.7 43.4 17.5 52.9 44Z" />
</svg>
);
export const Blob7 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M163.8 81.2c6.3 17.6-9.8 44.3-28.5 55.1-18.8 10.7-40.3 5.4-58.3-7.1C58.9 116.6 44.2 96.9 48.6 82c4.4-14.9 27.9-24.9 54-25.7 26.1-.9 54.9 7.4 61.2 24.9Z" />
</svg>
);
export const Blob8 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M140.2 93.2c8.6 20.4 10.1 49.3-2.1 57.8-12.2 8.6-38.2-3.3-54.2-17.6s-22.1-31-17.8-45.5c4.4-14.5 19.1-26.6 34.4-26.8 15.3-.2 31 11.7 39.7 32.1Z" />
</svg>
);
export const Blob9 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M150.6 84.9c6.7 19.2-2 44.7-22.1 60.8-20.1 16.2-51.8 23-73.6 8.9C33 140.5 21 105.4 30.1 82.8 39.2 60.2 69.6 50 95.8 51.4c26.2 1.3 48.1 14.3 54.8 33.5Z" />
</svg>
);
export const Blob10 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M162 75.8c6.7 24.7-7.5 52.1-30.7 69.5s-55.4 24.8-77.8 10.4C31 141.4 18.3 105.4 27.7 77 37 48.6 68.5 27.9 98.1 28.5c29.5.6 57.2 22.6 63.9 47.3Z" />
</svg>
);
export const Blob11 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M164.3 77.3c7.7 25.5-5.2 55.9-26.2 69.9-21 14.1-50.2 11.8-66.2-1.5-16.1-13.3-19-37.7-12.2-62 6.9-24.3 23.6-48.7 46.1-50.6 22.5-1.9 50.8 18.7 58.5 44.2Z" />
</svg>
);
export const Blob12 = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" {...props}>
<path d="M140 81.8c5.8 23.1.4 44.7-14.1 55.7-14.6 11-38.2 11.4-59-1.5C46 123.1 27.8 96.9 33.8 73.6c6-23.4 36.1-43.8 59.7-41.7 23.6 2.1 40.7 26.8 46.5 49.9Z" />
</svg>
);

View File

@@ -13,6 +13,12 @@ export function Lead({ children, className }: Props) {
);
}
export function Lead2({ children, className }: Props) {
return (
<p className={cn('text-lg md:text-xl font-light', className)}>{children}</p>
);
}
export function Paragraph({ children, className }: Props) {
return <p className={cn('text-lg', className)}>{children}</p>;
}

View File

@@ -1,17 +1,27 @@
import { Logo } from '@/components/Logo';
import { Button } from '@/components/ui/button';
import type { LucideIcon } from 'lucide-react';
import {
BarChart2,
BellIcon,
ClockIcon,
CloudIcon,
CompassIcon,
ConeIcon,
CookieIcon,
DollarSignIcon,
Globe2Icon,
KeyIcon,
LayoutPanelTopIcon,
LockIcon,
UserRoundSearchIcon,
UsersIcon,
} from 'lucide-react';
import { HomeCarousel } from './carousel';
import { Heading1, Heading2, Lead, Paragraph } from './copy';
import { Heading1, Heading2, Lead, Lead2, Paragraph } from './copy';
import { JoinWaitlist } from './join-waitlist';
import { Section, Sections } from './section';
const features = [
{
@@ -71,6 +81,7 @@ export default function Page() {
</div>
</div>
</div>
<Sections />
<div className="bg-blue-800 p-4 py-8 md:py-16 text-center">
<Heading2 className="text-slate-100 mb-4">
Get a feel how it looks

View File

@@ -0,0 +1,168 @@
'use client';
import { cn } from '@/utils/cn';
import type { LucideIcon, LucideProps } from 'lucide-react';
import {
BellIcon,
ClockIcon,
CloudIcon,
CompassIcon,
ConeIcon,
DollarSignIcon,
KeyIcon,
UserRoundSearchIcon,
} from 'lucide-react';
import {
Blob1,
Blob2,
Blob3,
Blob4,
Blob5,
Blob6,
Blob7,
Blob8,
Blob9,
} from './blob';
import { Heading2, Lead2 } from './copy';
interface SectionItem {
title: string;
description: string;
icon: LucideIcon;
color: string;
soon?: string;
blob: React.ComponentType<LucideProps>;
}
const sections: SectionItem[] = [
{
title: 'Own Your Own Data',
description:
'Take control of your data privacy and ownership with our platform, ensuring full transparency and security.',
icon: KeyIcon,
color: '#2563EB',
blob: Blob1,
},
{
title: 'Cloud or Self-Hosting',
description:
'Choose between the flexibility of cloud-based hosting or the autonomy of self-hosting to tailor your analytics infrastructure to your needs.',
icon: CloudIcon,
color: '#ff7557',
blob: Blob2,
},
{
title: 'Real-Time Events',
description:
'Stay up-to-date with real-time event tracking, enabling instant insights into user actions as they happen.',
icon: ClockIcon,
color: '#7fe1d8',
blob: Blob3,
},
{
title: 'Deep Dive into User Behavior',
description:
"Gain profound insights into user behavior with comprehensive analytics tools, allowing you to understand your audience's actions and preferences.",
icon: UserRoundSearchIcon,
color: '#f8bc3c',
blob: Blob4,
},
{
title: 'Powerful Report Explorer',
description:
'Explore and analyze your data effortlessly with our powerful report explorer, simplifying the process of deriving meaningful insights.',
icon: CompassIcon,
color: '#b3596e',
blob: Blob5,
},
{
soon: 'Coming soon',
title: 'Funnels',
description:
'Track user conversion funnels seamlessly, providing valuable insights into user journey optimization.',
icon: ConeIcon,
color: '#72bef4',
blob: Blob6,
},
{
soon: 'Coming with our native app',
title: 'Push Notifications',
description:
'Stay informed about conversions, events, and peaks with our upcoming push notification tool, empowering you to monitor and respond to critical activities in real-time.',
icon: BellIcon,
color: '#ffb27a',
blob: Blob7,
},
{
title: 'Cost-Effective Alternative to Mixpanel',
description:
'Enjoy the same powerful analytics capabilities as Mixpanel at a fraction of the cost, ensuring affordability without compromising on quality.',
icon: DollarSignIcon,
color: '#0f7ea0',
blob: Blob8,
},
{
soon: 'Something Plausible lacks',
title: 'Great Support for React Native',
description:
'Benefit from robust support for React Native, ensuring seamless integration and compatibility for your projects, a feature notably lacking in other platforms like Plausible.',
icon: (({ className }: LucideProps) => {
return (
<img src="/react-native.svg" alt="React Native" className={className} />
);
}) as unknown as LucideIcon,
color: '#3ba974',
blob: Blob9,
},
];
interface SectionProps extends SectionItem {
reverse?: boolean;
}
export function Section({
title,
description,
icon: Icon,
blob: Blob,
color,
soon,
reverse,
}: SectionProps) {
return (
<div key={title} className={'border-b border-border'}>
<div className="w-full max-w-6xl mx-auto px-4">
<div className={cn('flex py-16', reverse && 'flex-row-reverse')}>
<div className="w-1/2 flex-shrink-0 justify-center items-center flex">
<div className="bg-slate-50 rounded-3xl">
<Blob
style={{ fill: color }}
className="w-[600px] opacity-20 transition-transform animate-[spin_60s_ease-in-out_infinite] -m-[100px]"
/>
</div>
<Icon className="w-40 h-40 absolute" strokeWidth={2} />
</div>
<div className="justify-center flex-col flex">
{!!soon && (
<div className="rounded-full border border-border p-2 px-4 leading-none mb-4 self-start">
{soon}
</div>
)}
<Heading2 className="mb-4">{title}</Heading2>
<Lead2>{description}</Lead2>
</div>
</div>
</div>
</div>
);
}
export function Sections() {
return (
<>
{sections.map((section, index) => (
<Section key={index} {...section} reverse={index % 2 === 1} />
))}
</>
);
}

12
pnpm-lock.yaml generated
View File

@@ -87,8 +87,8 @@ importers:
specifier: ^2.5.0
version: 2.5.0(react@18.2.0)
lucide-react:
specifier: ^0.286.0
version: 0.286.0(react@18.2.0)
specifier: ^0.323.0
version: 0.323.0(react@18.2.0)
next:
specifier: ~14.0.4
version: 14.0.4(react-dom@18.2.0)(react@18.2.0)
@@ -5978,6 +5978,14 @@ packages:
react: 18.2.0
dev: false
/lucide-react@0.323.0(react@18.2.0):
resolution: {integrity: sha512-rTXZFILl2Y4d1SG9p1Mdcf17AcPvPvpc/egFIzUrp7IUy60MUQo3Oi1mu8LGYXUVwuRZYsSMt3csHRW5mAovJg==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/luxon@3.4.4:
resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==}
engines: {node: '>=12'}