diff --git a/app/components/AutumnFallback.tsx b/app/components/AutumnFallback.tsx index 9cdeca18..6ea993eb 100644 --- a/app/components/AutumnFallback.tsx +++ b/app/components/AutumnFallback.tsx @@ -2,9 +2,11 @@ // This file provides working alternatives when autumn-js/react is not available import React, { createContext, useContext, useState, useEffect } from 'react'; +import Link from 'next/link'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; -import { CheckCircle, XCircle, AlertCircle } from "lucide-react"; +import { Check, Sparkles, Crown } from "lucide-react"; +import CheckoutButton from "@/components/stripe/CheckoutButton"; // Types interface Customer { @@ -45,16 +47,15 @@ export const AutumnProvider: React.FC<{ children: React.ReactNode }> = ({ childr // Mock loading customer data useEffect(() => { setIsLoading(true); - // Simulate API call setTimeout(() => { setCustomer({ id: 'cus_mock123', email: 'user@example.com', name: 'Test User', subscription: { - status: 'active', - planId: 'pro', - currentPeriodEnd: Date.now() + 30 * 24 * 60 * 60 * 1000 // 30 days from now + status: 'inactive', + planId: 'free', + currentPeriodEnd: Date.now() + 30 * 24 * 60 * 60 * 1000 } }); setIsLoading(false); @@ -78,98 +79,89 @@ export const useCustomer = () => { }; }; -// Mock pricing table component +// Mock pricing table component (two-tier) export const PricingTable: React.FC = () => { + const proPriceId = process.env.NEXT_PUBLIC_STRIPE_PRO_PRICE_ID || 'price_pro_monthly'; + const plans = [ { id: 'free', name: 'Free', price: '$0', - period: 'forever', - description: 'Perfect for getting started', - features: [ - '5 AI chat messages per day', - '1 sandbox environment', - 'Basic code generation', - 'Community support' - ], - buttonText: 'Get Started', - popular: false + subtext: 'No credit card required', + description: 'Everything you need to get started.', + features: ['Up to 5 chats', 'Basic templates', 'Standard sandbox time', 'Community support'], + buttonText: 'Get started', + popular: false, + icon: Sparkles, }, { id: 'pro', name: 'Pro', - price: '$29', - period: 'per month', - description: 'For serious developers', - features: [ - 'Unlimited AI chat messages', - '5 concurrent sandboxes', - 'Advanced code generation', - 'Priority support', - 'Autonomous agents', - 'Custom domains' - ], - buttonText: 'Start Free Trial', - popular: true + price: '$20', + subtext: 'per month, cancel anytime', + description: 'Build without limits with advanced AI.', + features: ['Unlimited chats', 'Advanced AI models', 'Extended sandbox time', 'Priority support'], + buttonText: 'Upgrade to Pro', + popular: true, + icon: Crown, }, - { - id: 'enterprise', - name: 'Enterprise', - price: 'Custom', - period: '', - description: 'For teams and organizations', - features: [ - 'Everything in Pro', - 'Unlimited sandboxes', - 'Team collaboration', - 'SLA guarantee', - 'Custom integrations', - 'Dedicated support' - ], - buttonText: 'Contact Sales', - popular: false - } ]; return ( -
- {plans.map((plan) => ( - - {plan.popular && ( -
- MOST POPULAR -
- )} - - {plan.name} -
- {plan.price} - {plan.period && {plan.period}} -
- {plan.description} -
- -
    - {plan.features.map((feature, index) => ( -
  • - - {feature} -
  • - ))} -
- -
-
- ))} +
+ {plans.map((plan) => { + const Icon = plan.icon; + const isFree = plan.id === 'free'; + return ( + + {plan.popular && ( +
+ + Most popular + +
+ )} + +
+
+
+
+ {plan.name} + {plan.description} +
+
+
+ {plan.price} + {plan.subtext} +
+
+ +
    + {plan.features.map((feature, index) => ( +
  • +
  • + ))} +
+ {isFree ? ( + + + + ) : ( + + {plan.buttonText} + + )} +
+
+ ); + })}
); }; @@ -181,7 +173,6 @@ export const useUsageLimits = (featureId: string) => { useEffect(() => { setIsLoading(true); - // Simulate API call setTimeout(() => { setLimits({ featureId, @@ -198,4 +189,4 @@ export const useUsageLimits = (featureId: string) => { mutate: () => {}, isValidating: false }; -}; \ No newline at end of file +}; diff --git a/app/pricing/page.tsx b/app/pricing/page.tsx index f704df78..6dd7b66f 100644 --- a/app/pricing/page.tsx +++ b/app/pricing/page.tsx @@ -1,144 +1,170 @@ "use client"; -import { PricingTable } from "@/app/components/AutumnFallback"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { CheckCircle, Zap, Sparkles } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Check, Sparkles, Crown } from "lucide-react"; +import CheckoutButton from "@/components/stripe/CheckoutButton"; export default function PricingPage() { + const router = useRouter(); + const proPriceId = process.env.NEXT_PUBLIC_STRIPE_PRO_PRICE_ID || "price_pro_monthly"; + return ( -
-
- {/* Header */} -
-
- -

- ZapDev Pricing -

-
-

- Unlock the full power of AI-assisted React development. - Choose a plan that fits your needs and start building amazing apps instantly. +

+
+
+

Pricing

+

+ Choose the plan that fits your workflow. Start free and upgrade + anytime.

-
+ - {/* Feature Highlights */} -
- - -
- -
- AI-Powered Development -
- - - Chat with AI agents to build React applications with advanced features and real-time code generation. - - -
+
+

+ Plans +

+
+ {/* Free */} + + +
+
+
+
+
+ Free + + Everything you need to get started. + +
+
+
+
+ $0 + No credit card required +
+
+ +
    + {[ + "Up to 5 chats", + "Basic templates", + "Standard sandbox time", + "Community support", + ].map((feature) => ( +
  • +
  • + ))} +
+
+ +
+
+
- - -
- -
- Isolated Sandboxes -
- - - Each project runs in its own secure E2B sandbox environment with persistent file storage. - - -
+ {/* Pro */} + + + Most popular + + +
+
+
+
+
+ Pro + + Build without limits with advanced AI. + +
+
+
+
+ $20 + per month, cancel anytime +
+
+ +
    + {[ + "Unlimited chats", + "Advanced AI models", + "Extended sandbox time", + "Priority support", + ].map((feature) => ( +
  • +
  • + ))} +
+
+ + Upgrade to Pro + +
+
+
+
+
- +
+ -
- -
- Autonomous Execution + Frequently Asked Questions
- - Advanced autonomous workflows that can execute complex development tasks independently. - +
+
+

What happens if I exceed my limits?

+

+ When you reach your plan limits, you can upgrade instantly to continue working. Your projects and progress are always preserved. +

+
+
+

Can I change plans anytime?

+

+ Yes. You can upgrade or downgrade at any time. Changes take effect immediately and billing is prorated. +

+
+
+

Do I need a credit card for Free?

+

+ No. The Free plan requires no credit card and is great for getting started. +

+
+
-
- - {/* Autumn Pricing Table */} -
- -
- - {/* Usage Limits Information */} - - - - - Usage-Based Pricing - - - -

- ZapDev uses a usage-based pricing model to ensure you only pay for what you use: -

-
-
-

What Counts as Usage

-
    -
  • • AI chat messages and code generations
  • -
  • • Sandbox creation and execution time
  • -
  • • Autonomous agent workflows
  • -
  • • File operations and storage
  • -
-
-
-

When You Hit Limits

-
    -
  • • You'll be automatically redirected here
  • -
  • • Upgrade instantly to continue working
  • -
  • • No interruption to your development flow
  • -
  • • All your work is safely preserved
  • -
-
-
-
-
- - {/* FAQ Section */} - - - Frequently Asked Questions - - -
-
-

What happens if I exceed my usage limits?

-

- When you reach your plan's usage limits, you'll be automatically redirected to this pricing page - where you can instantly upgrade to continue your work without losing any progress. -

-
-
-

Can I change plans anytime?

-

- Yes! You can upgrade or downgrade your plan at any time. Changes take effect immediately, - and billing is prorated automatically. -

-
-
-

Is my code and data secure?

-

- Absolutely. Each sandbox is isolated, your code is encrypted, and we follow industry-standard - security practices to keep your projects safe. -

-
-
-
-
+
); -} \ No newline at end of file +} diff --git a/components/PricingModal.tsx b/components/PricingModal.tsx index 88e68547..353e63a2 100644 --- a/components/PricingModal.tsx +++ b/components/PricingModal.tsx @@ -1,8 +1,9 @@ 'use client'; -import { useState } from 'react'; import { Button } from '@/components/ui/button'; -import { motion, AnimatePresence } from 'framer-motion'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { AnimatePresence, motion } from 'framer-motion'; +import { Check, Sparkles, Crown, X } from 'lucide-react'; interface PricingModalProps { isOpen: boolean; @@ -11,57 +12,6 @@ interface PricingModalProps { } export default function PricingModal({ isOpen, onClose, onUpgrade }: PricingModalProps) { - const [selectedBilling, setSelectedBilling] = useState<'monthly' | 'annual'>('monthly'); - - const plans = [ - { - name: 'Free', - description: 'Perfect for trying out our AI-powered development platform.', - monthlyPrice: 0, - annualPrice: 0, - features: [ - '✅ 10 deployed sites', - '✅ Website analytics', - '✅ Unlimited codebase downloads', - '✅ AI database generation', - '✅ Drizzle Studio access', - '5 chats limit', - 'Basic AI models', - 'Community support' - ] - }, - { - name: 'Pro', - description: 'Designed for fast-moving teams building together in real time.', - monthlyPrice: 20, - annualPrice: 16, - features: [ - '✅ Everything in Free, plus:', - '✅ Custom domains', - 'Unlimited chats', - 'Advanced AI models', - 'Priority support', - 'Export conversations', - 'Custom integrations', - 'Team collaboration' - ] - }, - { - name: 'Enterprise', - description: 'Built for large orgs needing flexibility, scale, and governance.', - isEnterprise: true, - features: [ - 'Everything in Pro, plus:', - 'Dedicated support', - 'Custom deployment', - 'Advanced compliance', - 'SSO integration', - 'SLA guarantees', - 'Custom AI training' - ] - } - ]; - if (!isOpen) return null; return ( @@ -70,132 +20,120 @@ export default function PricingModal({ isOpen, onClose, onUpgrade }: PricingModa initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" + className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4" onClick={onClose} > e.stopPropagation()} > - {/* Header */} -
-
+ +
-

Upgrade Your Plan

-

You've reached your free plan limit of 5 chats

+

Upgrade your plan

+

+ You've reached the Free plan limit. Unlock more with Pro. +

-
- - {/* Billing Toggle */} -
- Monthly - - Annual - {selectedBilling === 'annual' && ( - Save 20% - )}
-
- {/* Pricing Cards */} -
-
- {plans.map((plan) => ( -
-
-

{plan.name}

-

{plan.description}

- - {plan.isEnterprise ? ( -
- Flexible billing + +
+ {/* Free */} + + +
+
+
- ) : ( -
- - ${selectedBilling === 'monthly' ? plan.monthlyPrice : plan.annualPrice} - - per month - {selectedBilling === 'annual' && ( -
- Billed annually -
- )} +
+ Free + Everything you need to get started.
- )} +
+
+ $0 + No credit card required +
+ + +
    + {['Up to 5 chats', 'Basic templates', 'Standard sandbox time', 'Community support'].map((f) => ( +
  • +
  • + ))} +
+
+ +
+
+ - -
- -
- {plan.features.map((feature, index) => ( -
- - - - - {feature} - + {/* Pro */} + + + Most popular + + +
+
+
- ))} -
-
- ))} -
-
- - {/* Footer */} -
-

- All plans include a 7-day free trial. Cancel anytime. -

-
+
+ Pro + Build without limits with advanced AI. +
+
+
+ $20 + per month, cancel anytime +
+ + +
    + {['Unlimited chats', 'Advanced AI models', 'Extended sandbox time', 'Priority support'].map((f) => ( +
  • +
  • + ))} +
+
+ +
+
+ +
+ + ); -} \ No newline at end of file +} diff --git a/components/stripe/SubscriptionPlans.tsx b/components/stripe/SubscriptionPlans.tsx index 4af0244c..d6500a49 100644 --- a/components/stripe/SubscriptionPlans.tsx +++ b/components/stripe/SubscriptionPlans.tsx @@ -1,7 +1,9 @@ 'use client'; -import { Check, Zap, Crown, Rocket } from 'lucide-react'; +import Link from 'next/link'; +import { Check, Sparkles, Crown } from 'lucide-react'; import CheckoutButton from './CheckoutButton'; +import { Button } from '@/components/ui/button'; export interface PricingPlan { id: string; @@ -19,7 +21,7 @@ export interface PricingPlan { } interface SubscriptionPlansProps { - plans: PricingPlan[]; + plans?: PricingPlan[]; className?: string; } @@ -27,143 +29,102 @@ const defaultPlans: PricingPlan[] = [ { id: 'free', name: 'Free', - description: 'Perfect for trying out Zapdev', + description: 'Everything you need to get started.', price: 0, currency: 'usd', interval: 'month', - features: [ - '5 AI-powered projects', - 'Basic templates', - 'Community support', - 'Standard sandbox time', - ], - icon: Zap, - buttonText: 'Get Started', + features: ['Up to 5 chats', 'Basic templates', 'Standard sandbox time', 'Community support'], + icon: Sparkles, + buttonText: 'Get started', buttonVariant: 'outline', }, { id: 'pro', name: 'Pro', - description: 'For individual developers', + description: 'Build without limits with advanced AI.', price: 20, currency: 'usd', interval: 'month', - priceId: process.env.NEXT_PUBLIC_STRIPE_PRO_PRICE_ID || 'price_pro_monthly', // Use env var for Stripe price ID - features: [ - 'Unlimited chats', - 'Unlimited AI-powered projects', - 'Premium templates', - 'Priority support', - 'Extended sandbox time', - 'Advanced AI models', - 'Export to GitHub', - ], + priceId: process.env.NEXT_PUBLIC_STRIPE_PRO_PRICE_ID || 'price_pro_monthly', + features: ['Unlimited chats', 'Advanced AI models', 'Extended sandbox time', 'Priority support'], popular: true, icon: Crown, buttonText: 'Upgrade to Pro', - }, - { - id: 'team', - name: 'Team', - description: 'For teams and organizations', - price: 50, - currency: 'usd', - interval: 'month', - priceId: 'price_team_monthly', // Replace with actual Stripe price ID - features: [ - 'Everything in Pro', - 'Team collaboration', - 'Shared projects', - 'Advanced analytics', - 'Custom integrations', - 'Dedicated support', - 'SSO authentication', - ], - icon: Rocket, - buttonText: 'Upgrade to Team', buttonVariant: 'orange', }, ]; -export default function SubscriptionPlans({ - plans = defaultPlans, - className = '' -}: SubscriptionPlansProps) { - const formatPrice = (price: number, currency: string) => { - return new Intl.NumberFormat('en-US', { +export default function SubscriptionPlans({ plans = defaultPlans, className = '' }: SubscriptionPlansProps) { + const formatPrice = (price: number, currency: string) => + new Intl.NumberFormat('en-US', { style: 'currency', currency: currency.toUpperCase(), minimumFractionDigits: 0, }).format(price); - }; return ( -
+
{plans.map((plan) => { - const Icon = plan.icon || Zap; - + const Icon = plan.icon || Sparkles; + const isFree = plan.id === 'free'; + const isPro = plan.id === 'pro'; + return (
{plan.popular && ( -
- - Most Popular +
+ + Most popular
)}
- +
-
- +
+ {formatPrice(plan.price, plan.currency)} - {plan.price > 0 && ( - - /{plan.interval} - + {plan.price > 0 ? ( + /month + ) : ( + No credit card required )}
+ {isPro && ( +
per month, cancel anytime
+ )}
-
    +
      {plan.features.map((feature, index) => (
    • - - {feature} +
    • ))}
    - {plan.price === 0 ? ( - - {plan.buttonText} - + {isFree ? ( + + + ) : plan.priceId ? ( ); -} \ No newline at end of file +}