public: hero improvements
This commit is contained in:
BIN
apps/public/public/clickable-demo.png
Normal file
BIN
apps/public/public/clickable-demo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
apps/public/public/clickhouse.png
Normal file
BIN
apps/public/public/clickhouse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
apps/public/public/getdreams.png
Normal file
BIN
apps/public/public/getdreams.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
BIN
apps/public/public/kiddokitchen.png
Normal file
BIN
apps/public/public/kiddokitchen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
20
apps/public/src/app/(static)/layout.tsx
Normal file
20
apps/public/src/app/(static)/layout.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { Navbar } from '../navbar';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Layout({ children }: Props) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar darkText />
|
||||||
|
<div
|
||||||
|
className="opacity-50 w-full h-screen text-blue-950 bg-[radial-gradient(circle_at_2px_2px,#D9DEF6_2px,transparent_0)] absolute top-0 left-0 right-0 z-0"
|
||||||
|
style={{
|
||||||
|
backgroundSize: '70px 70px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="relative">{children}</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Heading1 } from '../copy';
|
import { Heading1 } from '../../copy';
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
export const revalidate = 3600;
|
export const revalidate = 3600;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Heading1 } from '../copy';
|
import { Heading1 } from '../../copy';
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
export const revalidate = 3600;
|
export const revalidate = 3600;
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
import { Tooltip, TooltipContent } from '@/components/ui/tooltip';
|
||||||
|
import { TooltipTrigger } from '@radix-ui/react-tooltip';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
import { PreviewCarousel } from './carousel';
|
import { PreviewCarousel } from './carousel';
|
||||||
import { Heading1, Lead2 } from './copy';
|
import { Heading1, Lead2 } from './copy';
|
||||||
import { JoinWaitlistHero } from './join-waitlist-hero';
|
import { JoinWaitlistHero } from './join-waitlist-hero';
|
||||||
|
import { SocialProofServer } from './social-proof';
|
||||||
|
import { SocialProof } from './social-proof/social-proof';
|
||||||
|
|
||||||
const avatars = [
|
const avatars = [
|
||||||
'https://api.dicebear.com/7.x/adventurer/svg?seed=Chester&backgroundColor=b6e3f4',
|
'https://api.dicebear.com/7.x/adventurer/svg?seed=Chester&backgroundColor=b6e3f4',
|
||||||
@@ -10,7 +14,7 @@ const avatars = [
|
|||||||
'https://api.dicebear.com/7.x/adventurer/svg?seed=Boo&backgroundColor=ffdfbf',
|
'https://api.dicebear.com/7.x/adventurer/svg?seed=Boo&backgroundColor=ffdfbf',
|
||||||
];
|
];
|
||||||
|
|
||||||
export function Hero({ waitlistCount }: { waitlistCount: number }) {
|
export function Hero() {
|
||||||
return (
|
return (
|
||||||
<div className="flex py-32 flex-col items-center w-full text-center bg-[#1F54FF] relative overflow-hidden">
|
<div className="flex py-32 flex-col items-center w-full text-center bg-[#1F54FF] relative overflow-hidden">
|
||||||
{/* <div className="inset-0 absolute h-full w-full bg-[radial-gradient(circle,rgba(255,255,255,0.1)_0%,rgba(255,255,255,0)_100%)]"></div> */}
|
{/* <div className="inset-0 absolute h-full w-full bg-[radial-gradient(circle,rgba(255,255,255,0.1)_0%,rgba(255,255,255,0)_100%)]"></div> */}
|
||||||
@@ -37,16 +41,12 @@ export function Hero({ waitlistCount }: { waitlistCount: number }) {
|
|||||||
alternative to Mixpanel
|
alternative to Mixpanel
|
||||||
</Heading1>
|
</Heading1>
|
||||||
<Lead2 className="text-white/70 font-light">
|
<Lead2 className="text-white/70 font-light">
|
||||||
Mixpanel + Plausible = <span className="text-white">Openpanel!</span>{' '}
|
The power of Mixpanel, the ease of Plausible <br />
|
||||||
<br />A simple analytics tool that your wallet can afford.
|
and nothing from Google Analytics 😉
|
||||||
</Lead2>
|
</Lead2>
|
||||||
<div className="my-12 w-full flex flex-col items-center">
|
<div className="my-12 w-full flex flex-col items-center">
|
||||||
<JoinWaitlistHero />
|
<JoinWaitlistHero />
|
||||||
<div className="mt-6 flex justify-center items-center">
|
<SocialProofServer className="mt-6" />
|
||||||
<p className="text-white">
|
|
||||||
{waitlistCount} people have already signed up! 🚀
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ export function JoinWaitlistHero({ className }: JoinWaitlistProps) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.op('event', 'waitlist_open');
|
window.op?.('event', 'waitlist_open');
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (success) {
|
if (success) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.op('event', 'waitlist_success', {
|
window.op?.('event', 'waitlist_success', {
|
||||||
email: value,
|
email: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -113,15 +113,23 @@ export function JoinWaitlistHero({ className }: JoinWaitlistProps) {
|
|||||||
>
|
>
|
||||||
Join waitlist now
|
Join waitlist now
|
||||||
</Button>
|
</Button>
|
||||||
<Link
|
|
||||||
href="https://dashboard.openpanel.dev/share/overview/ZQsEhG"
|
<div className="relative">
|
||||||
target="_blank"
|
<Link
|
||||||
rel="nofollow"
|
href="https://dashboard.openpanel.dev/share/overview/ZQsEhG"
|
||||||
>
|
target="_blank"
|
||||||
<Button size="lg" variant="outline" className="text-lg h-12">
|
rel="nofollow"
|
||||||
Demo
|
>
|
||||||
</Button>
|
<Button size="lg" variant="outline" className="text-lg h-12">
|
||||||
</Link>
|
Demo
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<img
|
||||||
|
src="/clickable-demo.png"
|
||||||
|
className="w-44 shrink-0 absolute left-full -top-8 translate-x-10 max-w-none"
|
||||||
|
alt="Clickable demo button"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -35,39 +35,10 @@ export default function RootLayout({
|
|||||||
font.className
|
font.className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
{children}
|
||||||
className="w-full h-screen text-blue-950 bg-[radial-gradient(circle_at_2px_2px,#D9DEF6_2px,transparent_0)] absolute top-0 left-0 right-0 z-0"
|
|
||||||
style={{
|
|
||||||
backgroundSize: '70px 70px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="relative">{children}</div>
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</body>
|
</body>
|
||||||
<Script
|
{/* 301c6dc1-424c-4bc3-9886-a8beab09b615 */}
|
||||||
src="https://openpanel.dev/op.js"
|
|
||||||
async
|
|
||||||
defer
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
id="openpanel"
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: `
|
|
||||||
window.op =
|
|
||||||
window.op ||
|
|
||||||
function (...args) {
|
|
||||||
(window.op.q = window.op.q || []).push(args);
|
|
||||||
};
|
|
||||||
window.op('ctor', {
|
|
||||||
clientId: '301c6dc1-424c-4bc3-9886-a8beab09b615',
|
|
||||||
trackScreenViews: true,
|
|
||||||
trackOutgoingLinks: true,
|
|
||||||
trackAttributes: true,
|
|
||||||
});
|
|
||||||
`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
34
apps/public/src/app/navbar.tsx
Normal file
34
apps/public/src/app/navbar.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Logo } from '@/components/Logo';
|
||||||
|
import { cn } from '@/utils/cn';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
darkText?: boolean;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Navbar({ darkText = false, className }: Props) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const textColor = darkText ? 'text-blue-dark' : 'text-white';
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn('absolute top-0 left-0 right-0 z-10', textColor, className)}
|
||||||
|
>
|
||||||
|
<div className="container flex justify-between items-center py-4">
|
||||||
|
<Logo />
|
||||||
|
<nav className="flex gap-4">
|
||||||
|
{pathname !== '/' && <Link href="/">Home</Link>}
|
||||||
|
<a href="https://docs.openpanel.dev" target="_blank">
|
||||||
|
Docs
|
||||||
|
</a>
|
||||||
|
<a href="https://dashboard.openpanel.dev" target="_blank">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
import { db } from '@openpanel/db';
|
import { db } from '@openpanel/db';
|
||||||
|
|
||||||
import { PreviewCarousel } from './carousel';
|
|
||||||
import { Heading2, Lead2, Paragraph } from './copy';
|
import { Heading2, Lead2, Paragraph } from './copy';
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
|
import { Navbar } from './navbar';
|
||||||
import { Sections } from './section';
|
import { Sections } from './section';
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
export const revalidate = 3600;
|
export const revalidate = 3600;
|
||||||
|
|
||||||
export default async function Page() {
|
export default function Page() {
|
||||||
const waitlistCount = await db.waitlist.count();
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Hero waitlistCount={waitlistCount} />
|
<Navbar darkText={false} className="[&_img]:hidden" />
|
||||||
|
<Hero />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="my-24">
|
<div className="my-24">
|
||||||
<Heading2 className="md:text-5xl mb-2 leading-none">
|
<Heading2 className="md:text-5xl mb-2 leading-none">
|
||||||
|
|||||||
17
apps/public/src/app/social-proof/index.tsx
Normal file
17
apps/public/src/app/social-proof/index.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
|
import { db } from '@openpanel/db';
|
||||||
|
|
||||||
|
import { SocialProof } from './social-proof';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
export async function SocialProofServer(props: Props) {
|
||||||
|
const waitlistCount = await db.waitlist.count();
|
||||||
|
return (
|
||||||
|
<TooltipProvider>
|
||||||
|
<SocialProof count={waitlistCount} {...props} />;
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
72
apps/public/src/app/social-proof/social-proof.tsx
Normal file
72
apps/public/src/app/social-proof/social-proof.tsx
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
'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 {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from '@/components/ui/tooltip';
|
||||||
|
import { cn } from '@/utils/cn';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
interface JoinWaitlistProps {
|
||||||
|
className?: string;
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SocialProof({ className, count }: JoinWaitlistProps) {
|
||||||
|
return (
|
||||||
|
<div className={cn('flex gap-2 justify-center items-center', className)}>
|
||||||
|
<div className="flex">
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger>
|
||||||
|
<Image
|
||||||
|
className="rounded-full"
|
||||||
|
src="/clickhouse.png"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
alt="Clickhouse"
|
||||||
|
/>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Clickhouse is here</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger className="-mx-3">
|
||||||
|
<Image
|
||||||
|
className="rounded-full"
|
||||||
|
src="/getdreams.png"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
alt="GetDreams"
|
||||||
|
/>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>GetDreams is here</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger>
|
||||||
|
<Image
|
||||||
|
className="rounded-full"
|
||||||
|
src="/kiddokitchen.png"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
alt="KiddoKitchen"
|
||||||
|
/>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>KiddoKitchen is here</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<p className="text-white">
|
||||||
|
{count} early birds have already signed up! 🚀
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ const DialogContent = React.forwardRef<
|
|||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',
|
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-100%] md:translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
Reference in New Issue
Block a user