Files
dashcaddy.net/src/app/pricing/page.tsx
T

170 lines
6.9 KiB
TypeScript

'use client';
import { useState } from 'react';
import PricingCards from '@/components/PricingCards';
import Link from 'next/link';
import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer';
export default function PricingPage() {
const [isAnnual, setIsAnnual] = useState(false);
const faqs = [
{
question: 'Can I try Premium for free?',
answer: 'There is no free trial. Premium features unlock when you start a paid subscription.',
},
{
question: 'What happens when my subscription ends?',
answer: 'If your subscription ends, DashCaddy falls back to the free tier. Your data remains intact.',
},
{
question: 'Can I self-host the license server?',
answer: 'Coming soon! We\'re working on a self-hosted license server option for enterprise deployments.',
},
{
question: 'Do you offer refunds?',
answer: 'Yes, we offer a 30-day money-back guarantee. If you\'re not satisfied with Premium, contact support for a full refund.',
},
{
question: 'Is my data safe?',
answer: 'DashCaddy remains self-hosted for your infrastructure. Only billing and license validation touch the hosted licensing service.',
},
];
const [expandedFaq, setExpandedFaq] = useState<number | null>(0);
return (
<div className="flex flex-col min-h-screen bg-surface-950 text-surface-50">
<Navbar />
{/* Hero Section */}
<section className="relative py-16 sm:py-20 lg:py-24">
<div className="absolute inset-0 -z-10">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-brand-500/20 rounded-full blur-3xl opacity-30 animate-pulse" />
</div>
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6">
Simple, Transparent <span className="text-brand-400">Pricing</span>
</h1>
<p className="text-xl text-surface-300 mb-8 max-w-2xl mx-auto">
Start free. Upgrade when you need advanced features. No surprises, no lock-in.
</p>
{/* Toggle for Monthly/Yearly */}
<div className="flex items-center justify-center gap-4 mb-12">
<span className={`text-sm font-medium ${!isAnnual ? 'text-surface-50' : 'text-surface-400'}`}>
Monthly
</span>
<button
onClick={() => setIsAnnual(!isAnnual)}
className={`relative inline-flex h-8 w-14 items-center rounded-full transition-colors ${
isAnnual ? 'bg-brand-500' : 'bg-surface-700'
}`}
aria-label="Toggle annual pricing"
>
<span
className={`inline-block h-6 w-6 transform rounded-full bg-white transition-transform ${
isAnnual ? 'translate-x-7' : 'translate-x-1'
}`}
/>
</button>
<span className={`text-sm font-medium ${isAnnual ? 'text-surface-50' : 'text-surface-400'}`}>
Annual
</span>
{isAnnual && (
<span className="ml-2 inline-block rounded-full bg-brand-500/20 px-3 py-1 text-sm font-semibold text-brand-300">
Best Value
</span>
)}
</div>
</div>
</section>
{/* Pricing Cards */}
<section className="relative py-12 sm:py-16 lg:py-20">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<PricingCards />
</div>
</section>
{/* FAQ Section */}
<section className="relative py-16 sm:py-20 lg:py-24 bg-gradient-to-b from-surface-950 to-surface-900">
<div className="mx-auto max-w-3xl px-4 sm:px-6 lg:px-8">
<div className="mb-12 text-center">
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold mb-4">
Frequently Asked <span className="text-brand-400">Questions</span>
</h2>
<p className="text-lg text-surface-400">
Have a question? We've got answers.
</p>
</div>
{/* FAQ Accordion */}
<div className="space-y-4">
{faqs.map((faq, idx) => (
<div
key={idx}
className="rounded-lg border border-surface-700/50 bg-surface-800/50 overflow-hidden transition-all duration-200 hover:border-surface-700"
>
<button
onClick={() => setExpandedFaq(expandedFaq === idx ? null : idx)}
className="w-full px-6 py-4 flex items-center justify-between hover:bg-surface-800/70 transition-colors"
>
<h3 className="text-lg font-semibold text-surface-50 text-left">{faq.question}</h3>
<svg
className={`h-6 w-6 flex-shrink-0 text-brand-400 transition-transform duration-200 ${
expandedFaq === idx ? 'rotate-180' : ''
}`}
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
</svg>
</button>
{expandedFaq === idx && (
<div className="border-t border-surface-700/50 bg-surface-900/50 px-6 py-4">
<p className="text-surface-300 leading-relaxed">{faq.answer}</p>
</div>
)}
</div>
))}
</div>
</div>
</section>
{/* Final CTA */}
<section className="relative py-16 sm:py-20 lg:py-24 bg-surface-950">
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl sm:text-4xl font-bold mb-6">
Ready to Get Started?
</h2>
<p className="text-xl text-surface-300 mb-8 max-w-2xl mx-auto">
Use DashCaddy free for core self-hosting, or unlock Premium for gated features.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link
href="/docs"
className="inline-flex items-center justify-center gap-2 rounded-lg bg-brand-500 px-8 py-3 text-base font-semibold text-white hover:bg-brand-600 transition-all duration-200 hover:shadow-lg hover:shadow-brand-500/30"
>
View Documentation
</Link>
<Link
href="/"
className="inline-flex items-center justify-center gap-2 rounded-lg border border-surface-700 bg-surface-800/50 px-8 py-3 text-base font-semibold text-surface-50 hover:border-brand-400 hover:bg-surface-800 transition-colors"
>
Back to Home
</Link>
</div>
</div>
</section>
<Footer />
</div>
);
}