Waitlist
blockmarketingPre-launch signup page. Split layout with product pitch, logo mark, three benefit bullets on the left and an email capture card on the right that flips to a queue-position confirmation with referral hint after submit.
Installation
$pnpm dlx shadcn@latest add https://uipkge.dev/r/react/waitlist.json$npx shadcn@latest add https://uipkge.dev/r/react/waitlist.json$yarn dlx shadcn@latest add https://uipkge.dev/r/react/waitlist.json$bunx shadcn@latest add https://uipkge.dev/r/react/waitlist.jsonNamed registry:
npx shadcn@latest add @uipkge-react/waitlistInstalls to:components/blocks/Variants
Loading interactive previews…
Loading interactive previews…
npm dependencies
Files installed (1)
components/blocks/Waitlist.tsx4.6 kB
'use client' import { useState } from 'react' import { Check, Layers, Link2, ShieldCheck, Zap, type LucideIcon } from 'lucide-react' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' const benefits: { icon: LucideIcon; title: string; copy: string }[] = [ { icon: Zap, title: 'Ships in minutes', copy: 'Drop-in blocks and primitives, not boilerplate to rewrite.' }, { icon: ShieldCheck, title: 'Own the code', copy: 'Every file is copied into your repo. Edit it freely, no lock-in.', }, { icon: Layers, title: 'Dual framework', copy: 'Vue and React mirrors stay in lockstep across every component.' }, ] export function Waitlist() { const [email, setEmail] = useState('') const [submitted, setSubmitted] = useState(false) const [position] = useState(214) function handleSubmit(event: React.FormEvent<HTMLFormElement>) { event.preventDefault() if (!email.includes('@')) return setSubmitted(true) } return ( <section data-slot="waitlist" className="bg-background grid min-h-screen lg:grid-cols-2"> <div className="bg-muted/40 relative flex items-center px-6 py-16 lg:border-r lg:px-16"> <div className="max-w-lg"> <div className="flex items-center gap-3"> <div className="bg-primary text-primary-foreground grid size-10 place-items-center rounded-lg shadow-sm"> <Layers className="size-5" /> </div> <span className="text-sm font-semibold tracking-tight">Northwind</span> </div> <h1 className="mt-8 text-3xl font-semibold tracking-tight sm:text-4xl">Be first in line when we launch</h1> <p className="text-muted-foreground mt-4 text-base sm:text-lg"> We’re onboarding a small cohort of teams each week. Join the waitlist and we’ll save your spot. </p> <ul className="mt-10 space-y-6"> {benefits.map((benefit) => ( <li key={benefit.title} className="flex gap-4"> <div className="bg-primary/10 text-primary grid size-9 shrink-0 place-items-center rounded-lg"> <benefit.icon className="size-4.5" /> </div> <div> <p className="text-sm font-medium">{benefit.title}</p> <p className="text-muted-foreground mt-1 text-sm">{benefit.copy}</p> </div> </li> ))} </ul> </div> </div> <div className="flex items-center justify-center px-6 py-16"> <Card className="w-full max-w-md"> {!submitted ? ( <> <CardHeader> <CardTitle>Join the waitlist</CardTitle> <CardDescription> Early access rolls out weekly. No spam — one email when it’s your turn. </CardDescription> </CardHeader> <CardContent> <form className="space-y-3" onSubmit={handleSubmit}> <Input type="email" placeholder="you@company.com" value={email} onChange={(event) => setEmail(event.target.value)} required /> <Button type="submit" className="w-full"> Request access </Button> </form> <p className="text-muted-foreground mt-4 text-xs">2,300+ teams already in line</p> </CardContent> </> ) : ( <CardContent className="pt-6 text-center"> <div className="bg-primary/10 text-primary mx-auto grid size-12 place-items-center rounded-full"> <Check className="size-6" /> </div> <h2 className="mt-5 text-2xl font-semibold tracking-tight">You’re #{position} in line</h2> <p className="text-muted-foreground mt-2 text-sm"> We’ll email {email} as soon as your spot opens up. </p> <div className="bg-muted/50 mt-6 flex items-start gap-3 rounded-lg border p-4 text-left"> <Link2 className="text-muted-foreground mt-0.5 size-4 shrink-0" /> <p className="text-muted-foreground text-xs"> Want to skip the queue? Share your invite link after launch — every friend who signs up moves you up 5 spots. </p> </div> </CardContent> )} </Card> </div> </section> ) }
Raw manifest:https://uipkge.dev/r/react/waitlist.json