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 @@ + +React icon \ 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 ( + React Native + ); + }) 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'}