| 'use client'; |
|
|
| import { DashboardLayout } from '@/components/layout/dashboard-layout'; |
| import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; |
| import { Button } from '@/components/ui/button'; |
| import { Badge } from '@/components/ui/badge'; |
| import { Check, Sparkles, CreditCard, Download, ArrowRight, Zap, Crown, Building2 } from 'lucide-react'; |
| import { cn } from '@/lib/utils'; |
| import { useState } from 'react'; |
|
|
| const plans = [ |
| { |
| name: 'Starter', |
| price: 29, |
| yearlyPrice: 24, |
| description: 'Perfect for small restaurants just getting started.', |
| icon: Zap, |
| features: ['1 restaurant', 'Up to 50 menu items', '5 QR codes', 'Basic analytics', 'Email support', '100 orders/month'], |
| popular: false, |
| current: false, |
| }, |
| { |
| name: 'Pro', |
| price: 79, |
| yearlyPrice: 66, |
| description: 'For growing restaurants with advanced needs.', |
| icon: Crown, |
| features: ['Unlimited restaurants', 'Unlimited menu items', 'Unlimited QR codes', 'Advanced analytics', 'Priority support', 'Unlimited orders', 'Custom branding', 'API access', 'Team members'], |
| popular: true, |
| current: true, |
| }, |
| { |
| name: 'Enterprise', |
| price: 199, |
| yearlyPrice: 166, |
| description: 'For multi-location chains and franchises.', |
| icon: Building2, |
| features: ['Everything in Pro', 'Multi-location support', 'Dedicated account manager', 'Custom integrations', 'SLA guarantee', 'White-label solution', 'Advanced security', 'Onboarding training'], |
| popular: false, |
| current: false, |
| }, |
| ]; |
|
|
| const invoices = [ |
| { id: 'INV-2024-003', date: 'Mar 1, 2025', amount: 79, status: 'paid' }, |
| { id: 'INV-2024-002', date: 'Feb 1, 2025', amount: 79, status: 'paid' }, |
| { id: 'INV-2024-001', date: 'Jan 1, 2025', amount: 79, status: 'paid' }, |
| ]; |
|
|
| export default function BillingPage() { |
| const [annual, setAnnual] = useState(false); |
|
|
| return ( |
| <DashboardLayout> |
| <div className="space-y-8"> |
| {/* Header */} |
| <div> |
| <h1 className="text-2xl font-bold tracking-tight text-zinc-900 dark:text-white sm:text-3xl">Billing & Subscription</h1> |
| <p className="mt-1 text-sm text-zinc-500">Manage your plan, payment methods, and invoices.</p> |
| </div> |
| |
| {/* Current Plan Banner */} |
| <div className="relative overflow-hidden rounded-2xl bg-gradient-to-r from-emerald-600 via-emerald-500 to-cyan-500 p-6 text-white shadow-lg sm:p-8"> |
| <div className="relative z-10"> |
| <Badge className="bg-white/20 text-white border-white/30 mb-3">Current Plan</Badge> |
| <h2 className="text-2xl font-bold">Pro Plan</h2> |
| <p className="mt-1 text-emerald-100">Your next billing date is April 1, 2025</p> |
| <div className="mt-4 flex items-baseline gap-1"> |
| <span className="text-4xl font-bold">$79</span> |
| <span className="text-emerald-200">/month</span> |
| </div> |
| </div> |
| <div className="absolute -right-8 -top-8 h-40 w-40 rounded-full bg-white/10" /> |
| <div className="absolute -bottom-12 -right-12 h-48 w-48 rounded-full bg-white/5" /> |
| </div> |
| |
| {/* Billing Toggle */} |
| <div className="flex items-center justify-center gap-3"> |
| <span className={cn('text-sm font-medium', !annual ? 'text-zinc-900' : 'text-zinc-500')}>Monthly</span> |
| <button |
| onClick={() => setAnnual(!annual)} |
| className={cn( |
| 'relative h-6 w-11 rounded-full transition-colors', |
| annual ? 'bg-emerald-500' : 'bg-zinc-300 dark:bg-zinc-600' |
| )} |
| > |
| <span className={cn( |
| 'absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform', |
| annual && 'translate-x-5' |
| )} /> |
| </button> |
| <span className={cn('text-sm font-medium', annual ? 'text-zinc-900' : 'text-zinc-500')}> |
| Annual <Badge variant="success" className="ml-1 text-[10px]">Save 17%</Badge> |
| </span> |
| </div> |
| |
| {/* Plans */} |
| <div className="grid gap-6 lg:grid-cols-3"> |
| {plans.map((plan) => ( |
| <Card key={plan.name} className={cn( |
| 'relative overflow-hidden transition-all hover:shadow-lg', |
| plan.popular && 'border-emerald-500 shadow-md ring-1 ring-emerald-500/20', |
| plan.current && 'border-emerald-500' |
| )}> |
| {plan.popular && ( |
| <div className="absolute -right-8 top-6 rotate-45 bg-emerald-500 px-10 py-1 text-[10px] font-bold uppercase tracking-wider text-white shadow-sm"> |
| Popular |
| </div> |
| )} |
| <CardContent className="pt-6 space-y-6"> |
| <div> |
| <div className="flex items-center gap-2"> |
| <div className={cn( |
| 'flex h-10 w-10 items-center justify-center rounded-xl', |
| plan.popular ? 'bg-emerald-100 text-emerald-600' : 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800' |
| )}> |
| <plan.icon className="h-5 w-5" /> |
| </div> |
| <div> |
| <h3 className="text-lg font-bold text-zinc-900 dark:text-zinc-100">{plan.name}</h3> |
| </div> |
| </div> |
| <p className="mt-2 text-sm text-zinc-500">{plan.description}</p> |
| </div> |
| |
| <div className="flex items-baseline gap-1"> |
| <span className="text-4xl font-bold text-zinc-900 dark:text-zinc-100"> |
| ${annual ? plan.yearlyPrice : plan.price} |
| </span> |
| <span className="text-zinc-500">/month</span> |
| </div> |
| |
| <Button |
| variant={plan.current ? 'outline' : plan.popular ? 'primary' : 'default'} |
| className="w-full" |
| disabled={plan.current} |
| > |
| {plan.current ? 'Current Plan' : 'Upgrade'} |
| {!plan.current && <ArrowRight className="h-4 w-4" />} |
| </Button> |
| |
| <div className="space-y-3"> |
| {plan.features.map((feature) => ( |
| <div key={feature} className="flex items-center gap-2 text-sm"> |
| <Check className={cn( |
| 'h-4 w-4 shrink-0', |
| plan.popular ? 'text-emerald-500' : 'text-zinc-400' |
| )} /> |
| <span className="text-zinc-600 dark:text-zinc-400">{feature}</span> |
| </div> |
| ))} |
| </div> |
| </CardContent> |
| </Card> |
| ))} |
| </div> |
| |
| {/* Payment Method & Invoices */} |
| <div className="grid gap-6 lg:grid-cols-2"> |
| {/* Payment Method */} |
| <Card> |
| <CardHeader className="flex flex-row items-center justify-between"> |
| <CardTitle>Payment Method</CardTitle> |
| <Button variant="outline" size="sm">Update</Button> |
| </CardHeader> |
| <CardContent> |
| <div className="flex items-center gap-4 rounded-xl border border-zinc-200 p-4 dark:border-zinc-700"> |
| <div className="flex h-12 w-16 items-center justify-center rounded-lg bg-gradient-to-br from-blue-600 to-blue-800"> |
| <CreditCard className="h-6 w-6 text-white" /> |
| </div> |
| <div> |
| <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">Visa ending in 4242</p> |
| <p className="text-xs text-zinc-500">Expires 12/2026</p> |
| </div> |
| <Badge variant="success" className="ml-auto text-[10px]">Default</Badge> |
| </div> |
| </CardContent> |
| </Card> |
| |
| {/* Recent Invoices */} |
| <Card> |
| <CardHeader className="flex flex-row items-center justify-between"> |
| <CardTitle>Recent Invoices</CardTitle> |
| <Button variant="ghost" size="sm" className="text-xs">View All</Button> |
| </CardHeader> |
| <CardContent> |
| <div className="space-y-3"> |
| {invoices.map((invoice) => ( |
| <div key={invoice.id} className="flex items-center justify-between rounded-xl border border-zinc-100 p-3 dark:border-zinc-800"> |
| <div> |
| <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{invoice.id}</p> |
| <p className="text-xs text-zinc-500">{invoice.date}</p> |
| </div> |
| <div className="flex items-center gap-3"> |
| <span className="text-sm font-semibold">${invoice.amount}</span> |
| <Badge variant="success" className="text-[10px]">{invoice.status}</Badge> |
| <Button variant="ghost" size="icon-sm"> |
| <Download className="h-3.5 w-3.5" /> |
| </Button> |
| </div> |
| </div> |
| ))} |
| </div> |
| </CardContent> |
| </Card> |
| </div> |
| </div> |
| </DashboardLayout> |
| ); |
| } |
|
|