diff --git a/apps/public/package.json b/apps/public/package.json
index 3aa9d365..8024ffe6 100644
--- a/apps/public/package.json
+++ b/apps/public/package.json
@@ -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",
diff --git a/apps/public/public/react-native.svg b/apps/public/public/react-native.svg
new file mode 100644
index 00000000..d4a571d1
--- /dev/null
+++ b/apps/public/public/react-native.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/apps/public/src/app/blob.tsx b/apps/public/src/app/blob.tsx
new file mode 100644
index 00000000..3b115ea2
--- /dev/null
+++ b/apps/public/src/app/blob.tsx
@@ -0,0 +1,74 @@
+import * as React from 'react';
+import type { SVGProps } from 'react';
+
+export const Blob1 = (props: SVGProps) => (
+
+);
+
+export const Blob2 = (props: SVGProps) => (
+
+);
+
+export const Blob3 = (props: SVGProps) => (
+
+);
+
+export const Blob4 = (props: SVGProps) => (
+
+);
+
+export const Blob5 = (props: SVGProps) => (
+
+);
+
+export const Blob6 = (props: SVGProps) => (
+
+);
+
+export const Blob7 = (props: SVGProps) => (
+
+);
+
+export const Blob8 = (props: SVGProps) => (
+
+);
+
+export const Blob9 = (props: SVGProps) => (
+
+);
+
+export const Blob10 = (props: SVGProps) => (
+
+);
+
+export const Blob11 = (props: SVGProps) => (
+
+);
+
+export const Blob12 = (props: SVGProps) => (
+
+);
diff --git a/apps/public/src/app/copy.tsx b/apps/public/src/app/copy.tsx
index 5f2b808b..59f8c287 100644
--- a/apps/public/src/app/copy.tsx
+++ b/apps/public/src/app/copy.tsx
@@ -13,6 +13,12 @@ export function Lead({ children, className }: Props) {
);
}
+export function Lead2({ children, className }: Props) {
+ return (
+ {children}
+ );
+}
+
export function Paragraph({ children, className }: Props) {
return {children}
;
}
diff --git a/apps/public/src/app/page.tsx b/apps/public/src/app/page.tsx
index 6d4ec140..672f8b9c 100644
--- a/apps/public/src/app/page.tsx
+++ b/apps/public/src/app/page.tsx
@@ -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() {
+
Get a feel how it looks
diff --git a/apps/public/src/app/section.tsx b/apps/public/src/app/section.tsx
new file mode 100644
index 00000000..f02b25e2
--- /dev/null
+++ b/apps/public/src/app/section.tsx
@@ -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;
+}
+
+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 (
+
+ );
+ }) 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 (
+
+
+
+
+
+ {!!soon && (
+
+ {soon}
+
+ )}
+
{title}
+
{description}
+
+
+
+
+ );
+}
+
+export function Sections() {
+ return (
+ <>
+ {sections.map((section, index) => (
+
+ ))}
+ >
+ );
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 961b8a72..27c58b60 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -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'}