diff --git a/apps/public/public/demo-2/1.png b/apps/public/public/demo-2/1.png new file mode 100644 index 00000000..fdfec989 Binary files /dev/null and b/apps/public/public/demo-2/1.png differ diff --git a/apps/public/public/demo-2/2.png b/apps/public/public/demo-2/2.png new file mode 100644 index 00000000..ae691d9a Binary files /dev/null and b/apps/public/public/demo-2/2.png differ diff --git a/apps/public/public/demo-2/3.png b/apps/public/public/demo-2/3.png new file mode 100644 index 00000000..210f0332 Binary files /dev/null and b/apps/public/public/demo-2/3.png differ diff --git a/apps/public/public/demo-2/4.png b/apps/public/public/demo-2/4.png new file mode 100644 index 00000000..11a69cb3 Binary files /dev/null and b/apps/public/public/demo-2/4.png differ diff --git a/apps/public/public/demo-2/5.png b/apps/public/public/demo-2/5.png new file mode 100644 index 00000000..17356ab5 Binary files /dev/null and b/apps/public/public/demo-2/5.png differ diff --git a/apps/public/public/demo-2/6.png b/apps/public/public/demo-2/6.png new file mode 100644 index 00000000..e3d3a124 Binary files /dev/null and b/apps/public/public/demo-2/6.png differ diff --git a/apps/public/public/demo-2/7.png b/apps/public/public/demo-2/7.png new file mode 100644 index 00000000..3c08953d Binary files /dev/null and b/apps/public/public/demo-2/7.png differ diff --git a/apps/public/public/logo-white.png b/apps/public/public/logo-white.png new file mode 100644 index 00000000..27f53ef7 Binary files /dev/null and b/apps/public/public/logo-white.png differ diff --git a/apps/public/src/app/carousel.tsx b/apps/public/src/app/carousel.tsx index 061ffcf2..630c8f9d 100644 --- a/apps/public/src/app/carousel.tsx +++ b/apps/public/src/app/carousel.tsx @@ -13,25 +13,23 @@ import Image from 'next/image'; const images = [ { title: 'Beautiful overview, everything is clickable to get more details', - url: '/demo/overview-min.png', + url: '/demo-2/1.png', }, { title: 'Histogram, perfect for showing active users', - url: '/demo/histogram-min.png', + url: '/demo-2/2.png', }, - { title: 'Make your overview public', url: '/demo/overview-share-min.png' }, + { title: 'Make your overview public', url: '/demo-2/3.png' }, { title: 'See real time events from your users', - url: '/demo/events-min.png', + url: '/demo-2/4.png', }, - { title: 'The classic line chart', url: '/demo/line-min.png' }, + { title: 'The classic line chart', url: '/demo-2/5.png' }, { title: 'Bar charts to see your most popular content', - url: '/demo/bar-min.png', + url: '/demo-2/6.png', }, - { title: 'Get nice metric cards with graphs', url: '/demo/metrics-min.png' }, - { title: 'See where your events comes from', url: '/demo/worldmap-min.png' }, - { title: 'The classic pie chart', url: '/demo/pie-min.png' }, + { title: 'Get nice metric cards with graphs', url: '/demo-2/7.png' }, ]; export function PreviewCarousel() { @@ -51,13 +49,18 @@ export function PreviewCarousel() { key={item.url} className="flex-[0_0_80%] max-w-3xl pl-8" > -
-
+
+
{item.title}
diff --git a/apps/public/src/app/copy.tsx b/apps/public/src/app/copy.tsx index 826c8fc3..61274589 100644 --- a/apps/public/src/app/copy.tsx +++ b/apps/public/src/app/copy.tsx @@ -26,7 +26,10 @@ export function Paragraph({ children, className }: Props) { export function Heading1({ children, className }: Props) { return (

{children}

diff --git a/apps/public/src/app/footer.tsx b/apps/public/src/app/footer.tsx index 9dcad137..dd33682d 100644 --- a/apps/public/src/app/footer.tsx +++ b/apps/public/src/app/footer.tsx @@ -20,9 +20,9 @@ export default function Footer() {
-
+
Openpanel overview page
-
+
-
+
-
+
Terms and Conditions diff --git a/apps/public/src/app/hero.tsx b/apps/public/src/app/hero.tsx index 3656cc3a..337cf92e 100644 --- a/apps/public/src/app/hero.tsx +++ b/apps/public/src/app/hero.tsx @@ -1,76 +1,56 @@ -// background-image: radial-gradient(circle at 1px 1px, black 1px, transparent 0); -// background-size: 40px 40px; - -import { Logo } from '@/components/Logo'; -import { - BarChart2Icon, - CookieIcon, - Globe2Icon, - LayoutPanelTopIcon, - LockIcon, - ServerIcon, -} from 'lucide-react'; import Image from 'next/image'; -import { Heading1, Lead, Lead2 } from './copy'; -import { JoinWaitlist } from './join-waitlist'; +import { PreviewCarousel } from './carousel'; +import { Heading1, Lead2 } from './copy'; +import { JoinWaitlistHero } from './join-waitlist-hero'; -const features = [ - { - title: 'Great overview', - icon: LayoutPanelTopIcon, - }, - { - title: 'Beautiful charts', - icon: BarChart2Icon, - }, - { - title: 'Privacy focused', - icon: LockIcon, - }, - { - title: 'Open-source', - icon: Globe2Icon, - }, - { - title: 'No cookies', - icon: CookieIcon, - }, - { - title: 'Self-hosted', - icon: ServerIcon, - }, +const avatars = [ + 'https://api.dicebear.com/7.x/adventurer/svg?seed=Chester&backgroundColor=b6e3f4', + 'https://api.dicebear.com/7.x/adventurer/svg?seed=Casper&backgroundColor=c0aede', + 'https://api.dicebear.com/7.x/adventurer/svg?seed=Boo&backgroundColor=ffdfbf', ]; export function Hero({ waitlistCount }: { waitlistCount: number }) { return ( -
-
- +
+ {/*
*/} +
+
+
+
+
+
+
+
+
+
+ Openpanel Logo + An open-source
alternative to Mixpanel
-

- Mixpanel + Plausible ={' '} - Openpanel! A simple - analytics tool that your wallet can afford. -

+ + Mixpanel + Plausible = Openpanel!{' '} +
A simple analytics tool that your wallet can afford. +
- -
-

{waitlistCount} people have already signed up! 🚀

+ +
+

+ {waitlistCount} people have already signed up! 🚀 +

-
- {features.map(({ icon: Icon, title }) => ( -
- - {title} -
- ))} -
+ +
); } diff --git a/apps/public/src/app/join-waitlist-hero.tsx b/apps/public/src/app/join-waitlist-hero.tsx new file mode 100644 index 00000000..e5c68232 --- /dev/null +++ b/apps/public/src/app/join-waitlist-hero.tsx @@ -0,0 +1,128 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { cn } from '@/utils/cn'; +import Link from 'next/link'; + +interface JoinWaitlistProps { + className?: string; +} + +export function JoinWaitlistHero({ className }: JoinWaitlistProps) { + const [value, setValue] = useState(''); + const [open, setOpen] = useState(false); + const [success, setSuccess] = useState(false); + + useEffect(() => { + if (open) { + // @ts-ignore + window.openpanel.event('waitlist_open'); + } + }, [open]); + + useEffect(() => { + if (success) { + // @ts-ignore + window.openpanel.event('waitlist_success', { + email: value, + }); + } + }, [success]); + + const renderSuccess = () => ( + + + Thanks so much! + + You're now on the waiting list. We'll let you know when we're ready. + Should be within a month or two 🚀 + + + + + + + + ); + + const renderForm = () => ( + + + Almost there! + + Enter your email to join the waiting list. We'll let you know when + we're ready. + + + +
{ + e.preventDefault(); + fetch('/api/waitlist', { + method: 'POST', + body: JSON.stringify({ email: value }), + headers: { + 'Content-Type': 'application/json', + }, + }).then((res) => { + if (res.ok) { + setSuccess(true); + } + }); + }} + > +
+ setValue(e.target.value)} + /> + +
+
+
+ ); + + return ( + <> + + {success ? renderSuccess() : renderForm()} + +
+ + + + +
+ + ); +} diff --git a/apps/public/src/app/layout.tsx b/apps/public/src/app/layout.tsx index 8b36adbe..c802af60 100644 --- a/apps/public/src/app/layout.tsx +++ b/apps/public/src/app/layout.tsx @@ -2,7 +2,6 @@ import { cn } from '@/utils/cn'; import '@/styles/globals.css'; -import { Logo } from '@/components/Logo'; import type { Metadata } from 'next'; import { Bricolage_Grotesque } from 'next/font/google'; import Script from 'next/script'; @@ -36,13 +35,6 @@ export default function RootLayout({ font.className )} > -
-
-
- -
-
-
-
-
- -
-
-
+
Analytics should be easy
diff --git a/apps/public/src/app/section.tsx b/apps/public/src/app/section.tsx index 1b01da08..c2b81848 100644 --- a/apps/public/src/app/section.tsx +++ b/apps/public/src/app/section.tsx @@ -10,29 +10,23 @@ import { CheckCircle, ClockIcon, CloudIcon, - CloudLightning, CloudLightningIcon, CompassIcon, ConeIcon, DatabaseIcon, DollarSignIcon, DownloadIcon, - FileIcon, FilterIcon, FolderIcon, - FolderOpenIcon, HandCoinsIcon, HandshakeIcon, KeyIcon, PieChartIcon, - PointerIcon, RouteIcon, ServerIcon, ShieldPlusIcon, ShoppingCartIcon, - SquareUserRound, StarIcon, - ThumbsUp, ThumbsUpIcon, TrendingUpIcon, UserRoundSearchIcon, @@ -40,23 +34,11 @@ import { WebhookIcon, } from 'lucide-react'; -import { - Blob1, - Blob2, - Blob3, - Blob4, - Blob5, - Blob6, - Blob7, - Blob8, - Blob9, -} from './blob'; -import { Heading2, Lead2 } from './copy'; import { Widget } from './widget'; interface SectionItem { title: string; - description: string; + description: string | React.ReactNode; icon: LucideIcon; color: string; soon?: string; @@ -67,8 +49,18 @@ interface SectionItem { 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.', + description: ( + <> +

+ Take control of your data privacy and ownership with our platform, + ensuring full transparency and security. +

+

+ All our serveres are hosted in EU (Stockholm) and we are fully GDPR + compliant. +

+ + ), icon: KeyIcon, color: '#2563EB', icons: [FolderIcon, DatabaseIcon, ShieldPlusIcon, KeyIcon], @@ -76,8 +68,12 @@ const sections: SectionItem[] = [ }, { 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.', + 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', icons: [CloudIcon, CheckCircle, ServerIcon, DownloadIcon], @@ -85,8 +81,12 @@ const sections: SectionItem[] = [ }, { title: 'Real-Time Events', - description: - 'Stay up-to-date with real-time event tracking, enabling instant insights into user actions as they happen.', + description: ( +

+ Stay up-to-date with real-time event tracking, enabling instant insights + into user actions as they happen. +

+ ), icon: ClockIcon, color: '#7fe1d8', icons: [CloudLightningIcon, ShoppingCartIcon, ArrowUpFromDotIcon], @@ -94,8 +94,13 @@ const sections: SectionItem[] = [ }, { title: 'Deep Dive into User Behaviors', - description: - "Gain profound insights into user behavior with comprehensive analytics tools, allowing you to understand your audience's actions and preferences.", + 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', icons: [UsersIcon, RouteIcon, BookmarkIcon], @@ -103,8 +108,12 @@ const sections: SectionItem[] = [ }, { title: 'Powerful Report Explorer', - description: - 'Explore and analyze your data effortlessly with our powerful report explorer, simplifying the process of deriving meaningful insights.', + description: ( +

+ Explore and analyze your data effortlessly with our powerful report + explorer, simplifying the process of deriving meaningful insights. +

+ ), icon: CompassIcon, color: '#b3596e', icons: [ThumbsUpIcon, TrendingUpIcon, PieChartIcon, BarChart2Icon], @@ -113,8 +122,12 @@ const sections: SectionItem[] = [ { soon: 'Coming soon', title: 'Funnels', - description: - 'Track user conversion funnels seamlessly, providing valuable insights into user journey optimization.', + description: ( +

+ Track user conversion funnels seamlessly, providing valuable insights + into user journey optimization. +

+ ), icon: ConeIcon, color: '#72bef4', icons: [ConeIcon, FilterIcon], @@ -123,8 +136,13 @@ const sections: SectionItem[] = [ { 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.', + 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', icons: [WebhookIcon, BellIcon], @@ -132,8 +150,12 @@ const sections: SectionItem[] = [ }, { 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.', + 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', icons: [DollarSignIcon, HandCoinsIcon, HandshakeIcon, StarIcon], @@ -142,8 +164,13 @@ const sections: SectionItem[] = [ { 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.', + 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 @@ -151,7 +178,7 @@ const sections: SectionItem[] = [ }) as unknown as LucideIcon, color: '#3ba974', icons: [FolderIcon, DatabaseIcon, ShieldPlusIcon, KeyIcon], - className: 'bg-[#f8bc3c]', + className: 'bg-[#e19900]', }, ]; @@ -187,7 +214,7 @@ export function Sections() { : ['-top-10 -left-20 rotate-12', 'top-10 -rotate-12', '-right-5']; const className = even - ? cn('text-white [&_h3]:text-white col-span-2', section.className) + ? cn('[&_*]:text-white/90 col-span-2', section.className) : cn('border border-border', section.className); return ( @@ -198,7 +225,7 @@ export function Sections() { icons={section.icons} offsets={offsets} > -

{section.description}

+ {section.description} ); })} diff --git a/apps/public/src/app/widget.tsx b/apps/public/src/app/widget.tsx index 5986dbfd..795eec57 100644 --- a/apps/public/src/app/widget.tsx +++ b/apps/public/src/app/widget.tsx @@ -22,12 +22,12 @@ export function Widget({ return (
- {title} - {children} + {title} +
{children}
{icons.map((Icon, i) => (
- + {/* */}