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>
61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Button } from '@/components/ui/button'
|
|
import type { Subscription } from '@/lib/types'
|
|
|
|
interface SubscriptionCardProps {
|
|
subscription: Subscription
|
|
}
|
|
|
|
export function SubscriptionCard({ subscription }: SubscriptionCardProps) {
|
|
return (
|
|
<Card className="bg-card border-border">
|
|
<CardHeader>
|
|
<CardTitle>Current Subscription</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="flex flex-col gap-6">
|
|
{/* Plan Details */}
|
|
<div className="flex items-start justify-between">
|
|
<div>
|
|
<h3 className="text-2xl font-bold text-foreground">Growth Plan</h3>
|
|
<p className="text-muted-foreground">AI Automation & Web Design</p>
|
|
</div>
|
|
<div className="text-right">
|
|
<p className="text-2xl font-bold text-foreground">€150</p>
|
|
<p className="text-muted-foreground text-sm">/month</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Status Badge */}
|
|
<div className="flex items-center gap-2">
|
|
<span
|
|
className={`px-3 py-1 rounded-full text-sm font-semibold ${
|
|
subscription.status === 'active'
|
|
? 'bg-emerald-500/10 text-emerald-400'
|
|
: 'bg-red-500/10 text-red-400'
|
|
}`}
|
|
>
|
|
{subscription.status === 'active' ? 'Active' : subscription.status}
|
|
</span>
|
|
{subscription.status === 'active' && (
|
|
<span className="text-muted-foreground text-sm">
|
|
Renews on {new Date(subscription.currentPeriodEnd).toLocaleDateString()}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Actions */}
|
|
<div className="flex gap-3">
|
|
<Button variant="outline" className="flex-1 border-border">
|
|
Manage Subscription
|
|
</Button>
|
|
{subscription.status === 'active' && !subscription.cancelAtPeriodEnd && (
|
|
<Button variant="ghost" className="text-muted-foreground hover:text-foreground">
|
|
Cancel
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|