scalesite/app/checkout/checkout-content.tsx
bast1qn 98552163a8 Initial ScaleSite Next.js implementation
Complete frontend implementation with:
- Next.js 16 with App Router and TypeScript
- Tailwind CSS v4 with custom violet theme
- shadcn/ui components with Lucide React icons
- Landing page with hero, services, pricing, testimonials, FAQ
- Service selection page with toggle
- Login/Register pages with social auth UI
- Multi-step checkout flow
- Client dashboard with stats, projects, support tickets
- Billing page with subscription, payment methods, invoices
- All mock data and TypeScript types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 21:42:48 +01:00

286 lines
12 KiB
TypeScript

'use client'
import { useState } from 'react'
import { useSearchParams } from 'next/navigation'
import { Card } from '@/components/ui/card'
import { CheckoutSteps } from '@/components/checkout/checkout-steps'
import { CheckoutSummary } from '@/components/checkout/checkout-summary'
import { PaymentMethodCard } from '@/components/checkout/payment-method-card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { getPricingPlanById } from '@/lib/mock-data'
import Link from 'next/link'
import { Rocket, ChevronRight } from 'lucide-react'
export function CheckoutContent() {
const searchParams = useSearchParams()
const planId = searchParams.get('plan') || 'growth-web'
const step = (searchParams.get('step') as 'account' | 'billing' | 'payment') || 'account'
const [currentStep, setCurrentStep] = useState<'account' | 'billing' | 'payment'>(step)
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState('card')
const plan = getPricingPlanById(planId)
if (!plan) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h1 className="text-2xl font-bold mb-4">Plan not found</h1>
<Button asChild>
<Link href="/services">Back to Services</Link>
</Button>
</div>
</div>
)
}
const serviceName = plan.serviceType === 'web-design' ? 'Web Design' : 'AI Automation'
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="border-b border-border py-4">
<div className="max-w-[1280px] mx-auto px-4 flex items-center gap-3">
<Link href="/" className="flex items-center gap-3">
<div className="size-8 flex items-center justify-center rounded bg-gradient-to-br from-primary to-primary-glow text-white">
<Rocket className="w-5 h-5" />
</div>
<h2 className="text-foreground text-lg font-bold">ScaleSite</h2>
</Link>
</div>
</header>
<div className="max-w-6xl mx-auto px-4 py-12">
{/* Steps */}
<CheckoutSteps currentStep={currentStep} />
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Left side - Forms */}
<div className="lg:col-span-2">
{/* Account Step */}
{currentStep === 'account' && (
<Card className="bg-card border-border p-6">
<h2 className="text-xl font-bold text-foreground mb-6">Account Information</h2>
<form className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="email">Email Address</Label>
<Input
id="email"
type="email"
placeholder="you@example.com"
className="bg-background border-border"
/>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="confirm-email">Confirm Email</Label>
<Input
id="confirm-email"
type="email"
placeholder="you@example.com"
className="bg-background border-border"
/>
</div>
<div className="flex items-start gap-2">
<input type="checkbox" id="newsletter" className="mt-1" />
<Label htmlFor="newsletter" className="text-sm text-muted-foreground">
I want to receive updates about my order and promotional offers
</Label>
</div>
<Button
type="button"
onClick={() => setCurrentStep('billing')}
className="glow-button bg-primary hover:bg-primary-glow text-white w-full"
>
Continue to Billing
</Button>
</form>
</Card>
)}
{/* Billing Step */}
{currentStep === 'billing' && (
<Card className="bg-card border-border p-6">
<h2 className="text-xl font-bold text-foreground mb-6">Billing Address</h2>
<form className="flex flex-col gap-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="firstName">First Name</Label>
<Input
id="firstName"
type="text"
placeholder="John"
className="bg-background border-border"
/>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="lastName">Last Name</Label>
<Input
id="lastName"
type="text"
placeholder="Doe"
className="bg-background border-border"
/>
</div>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="address">Street Address</Label>
<Input
id="address"
type="text"
placeholder="123 Main St"
className="bg-background border-border"
/>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="city">City</Label>
<Input
id="city"
type="text"
placeholder="Berlin"
className="bg-background border-border"
/>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="postalCode">Postal Code</Label>
<Input
id="postalCode"
type="text"
placeholder="10115"
className="bg-background border-border"
/>
</div>
<div className="flex flex-col gap-2 col-span-2 md:col-span-1">
<Label htmlFor="country">Country</Label>
<Input
id="country"
type="text"
placeholder="Germany"
className="bg-background border-border"
/>
</div>
</div>
<div className="flex gap-3">
<Button
type="button"
variant="outline"
onClick={() => setCurrentStep('account')}
className="bg-card border-border"
>
Back
</Button>
<Button
type="button"
onClick={() => setCurrentStep('payment')}
className="glow-button bg-primary hover:bg-primary-glow text-white flex-1"
>
Continue to Payment
</Button>
</div>
</form>
</Card>
)}
{/* Payment Step */}
{currentStep === 'payment' && (
<Card className="bg-card border-border p-6">
<h2 className="text-xl font-bold text-foreground mb-6">Payment Method</h2>
<div className="flex flex-col gap-3 mb-6">
<PaymentMethodCard
id="card"
icon="card"
label="Credit Card"
description="Pay with Visa, Mastercard, or Amex"
selected={selectedPaymentMethod === 'card'}
onSelect={() => setSelectedPaymentMethod('card')}
/>
<PaymentMethodCard
id="paypal"
icon="paypal"
label="PayPal"
description="Pay with your PayPal account"
selected={selectedPaymentMethod === 'paypal'}
onSelect={() => setSelectedPaymentMethod('paypal')}
/>
<PaymentMethodCard
id="stripe-link"
icon="link"
label="Stripe Link"
description="Quick payment with saved cards"
selected={selectedPaymentMethod === 'stripe-link'}
onSelect={() => setSelectedPaymentMethod('stripe-link')}
/>
</div>
{selectedPaymentMethod === 'card' && (
<form className="flex flex-col gap-4 border-t border-border pt-6">
<div className="flex flex-col gap-2">
<Label htmlFor="cardNumber">Card Number</Label>
<Input
id="cardNumber"
type="text"
placeholder="4242 4242 4242 4242"
className="bg-background border-border"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="expiry">Expiry Date</Label>
<Input
id="expiry"
type="text"
placeholder="MM/YY"
className="bg-background border-border"
/>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="cvc">CVC</Label>
<Input
id="cvc"
type="text"
placeholder="123"
className="bg-background border-border"
/>
</div>
</div>
<div className="flex gap-3">
<Button
type="button"
variant="outline"
onClick={() => setCurrentStep('billing')}
className="bg-card border-border"
>
Back
</Button>
<Button
type="button"
className="glow-button bg-primary hover:bg-primary-glow text-white flex-1"
>
Pay Now
</Button>
</div>
</form>
)}
</Card>
)}
</div>
{/* Right side - Summary */}
<div className="lg:col-span-1">
<div className="sticky top-24">
<CheckoutSummary
serviceName={serviceName}
tier={plan.tier}
price={plan.price}
currency={plan.currency}
/>
</div>
</div>
</div>
</div>
</div>
)
}