readysite / readysite.org / views / billing.html
13.6 KB
billing.html
{{template "app.html" .}}

{{define "title"}}Billing & Plan{{end}}

{{define "content"}}
<div class="max-w-4xl mx-auto px-4 sm:px-6 py-8 sm:py-12">
    <h1 class="text-2xl font-bold text-white mb-2">Billing & Plan</h1>
    <p class="text-[#888] text-sm mb-8">Each site has its own plan. Upgrade individual sites to unlock more features.</p>

    <!-- Success banner -->
    {{if eq (query "success") "true"}}
    <div class="mb-6 p-4 rounded-xl border border-emerald-500/30 bg-emerald-500/10 flex items-center gap-3">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
        <div>
            <div class="text-emerald-400 text-sm font-medium">Payment successful!</div>
            <div class="text-emerald-400/70 text-xs">Your site has been upgraded. It may take a moment to reflect.</div>
        </div>
    </div>
    {{end}}

    <!-- Canceled banner -->
    {{if eq (query "canceled") "true"}}
    <div class="mb-6 p-4 rounded-xl border border-yellow-500/30 bg-yellow-500/10 flex items-center gap-3">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
        <div>
            <div class="text-yellow-400 text-sm font-medium">Checkout canceled</div>
            <div class="text-yellow-400/70 text-xs">No charges were made. You can upgrade anytime.</div>
        </div>
    </div>
    {{end}}

    <!-- Current Sites / Plans -->
    {{if billing.UserSites}}
    <div class="mb-10">
        <h2 class="text-sm font-medium text-[#888] uppercase tracking-wider mb-4">Your Sites</h2>
        <div class="space-y-3">
            {{range $site := billing.UserSites}}
            <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 p-4 rounded-xl border border-white/10 bg-white/[0.02]">
                <div class="flex items-center gap-3 min-w-0">
                    <div class="w-8 h-8 rounded-lg flex items-center justify-center text-xs font-medium flex-shrink-0" style="background: rgba(139,92,246,0.15); color: #a78bfa;">
                        {{upper (slice $site.Name 0 1)}}
                    </div>
                    <div class="min-w-0">
                        <div class="text-white text-sm font-medium truncate">{{$site.Name}}</div>
                        <div class="text-[#666] text-xs font-mono truncate">{{$site.Subdomain}}.readysite.app</div>
                    </div>
                </div>
                <div class="flex items-center gap-3 flex-shrink-0 pl-11 sm:pl-0">
                    <span class="text-xs px-2.5 py-0.5 rounded-full font-medium {{if eq $site.Status "active"}}bg-emerald-500/15 text-emerald-400{{else if eq $site.Status "sleeping"}}bg-gray-500/15 text-gray-400{{else}}bg-yellow-500/15 text-yellow-400{{end}}">
                        {{$site.Status}}
                    </span>
                    {{if eq $site.Plan "pro"}}
                    <span class="text-xs px-2.5 py-0.5 rounded-full font-medium bg-violet-500/15 text-violet-400">Pro</span>
                    {{if and (billing.StripeEnabled) (billing.HasStripeCustomer)}}
                    <form method="POST" action="/billing/portal" class="inline">
                        <button type="submit" class="text-xs px-2.5 py-1 rounded-full font-medium transition-colors cursor-pointer text-[#888] hover:text-white" style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);">
                            Manage
                        </button>
                    </form>
                    {{end}}
                    {{else if eq $site.Plan "hobby"}}
                    <span class="text-xs px-2.5 py-0.5 rounded-full font-medium bg-emerald-500/15 text-emerald-400">Hobby</span>
                    {{if and (billing.StripeEnabled) (billing.HasStripeCustomer)}}
                    <form method="POST" action="/billing/portal" class="inline">
                        <button type="submit" class="text-xs px-2.5 py-1 rounded-full font-medium transition-colors cursor-pointer text-[#888] hover:text-white" style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);">
                            Manage
                        </button>
                    </form>
                    {{end}}
                    {{else}}
                    <button
                        hx-post="/api/sites/{{$site.ID}}/upgrade?plan=hobby"
                        hx-swap="none"
                        hx-confirm="Upgrade {{$site.Name}} to Hobby ($5/mo)? Your site will be always on with 500MB storage."
                        class="text-xs px-2.5 py-1 rounded-full font-medium transition-colors cursor-pointer" style="background: linear-gradient(135deg, rgba(16,185,129,0.2), rgba(34,211,238,0.2)); color: #6ee7b7; border: 1px solid rgba(16,185,129,0.3);">
                        Upgrade
                    </button>
                    {{end}}
                </div>
            </div>
            {{end}}
        </div>
    </div>
    {{end}}

    <!-- Pricing Comparison -->
    <h2 class="text-sm font-medium text-[#888] uppercase tracking-wider mb-4">Plans</h2>
    <div class="grid grid-cols-1 sm:grid-cols-3 gap-4 sm:gap-5 mb-10">
        <!-- Free Plan -->
        <div class="p-6 rounded-2xl border border-white/10 bg-white/[0.02]">
            <div class="flex items-center gap-2 mb-1">
                <h3 class="text-white font-semibold text-lg">Free</h3>
                <span class="text-xs px-2 py-0.5 rounded-full bg-white/5 text-[#888]">Default</span>
            </div>
            <div class="text-[#888] text-sm mb-5">Test ReadySite. Sites pause after 30 min of inactivity.</div>
            <div class="text-2xl font-bold text-white mb-6">$0 <span class="text-sm font-normal text-[#666]">/ month</span></div>
            <ul class="space-y-2.5 text-sm text-[#ccc]">
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    50MB persistent database
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Subdomain hosting
                </li>
                <li class="flex items-center gap-2 text-[#555]">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#555" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    Pauses after 30min idle
                </li>
                <li class="flex items-center gap-2 text-[#555]">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#555" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    No custom domains
                </li>
            </ul>
        </div>

        <!-- Hobby Plan -->
        <div class="p-6 rounded-2xl border border-emerald-500/30 bg-emerald-500/[0.03] relative overflow-hidden">
            <div class="absolute top-0 right-0 w-32 h-32 bg-emerald-500/10 rounded-full blur-3xl -mr-10 -mt-10 pointer-events-none"></div>
            <div class="flex items-center gap-2 mb-1 relative">
                <h3 class="text-white font-semibold text-lg">Hobby</h3>
                <span class="text-xs px-2 py-0.5 rounded-full bg-emerald-500/15 text-emerald-400">Popular</span>
            </div>
            <div class="text-[#888] text-sm mb-5">Always-on hosting for personal sites and side projects.</div>
            <div class="text-2xl font-bold text-white mb-6">$5 <span class="text-sm font-normal text-[#666]">/ month</span></div>
            <ul class="space-y-2.5 text-sm text-[#ccc] relative">
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    500MB persistent database
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Always on
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Subdomain hosting
                </li>
                <li class="flex items-center gap-2 text-[#555]">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#555" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    No custom domains
                </li>
            </ul>
        </div>

        <!-- Pro Plan -->
        <div class="p-6 rounded-2xl border border-violet-500/30 bg-violet-500/[0.03] relative overflow-hidden">
            <div class="absolute top-0 right-0 w-32 h-32 bg-violet-500/10 rounded-full blur-3xl -mr-10 -mt-10 pointer-events-none"></div>
            <div class="flex items-center gap-2 mb-1 relative">
                <h3 class="text-white font-semibold text-lg">Pro</h3>
                <span class="text-xs px-2 py-0.5 rounded-full bg-violet-500/15 text-violet-400">Pro</span>
            </div>
            <div class="text-[#888] text-sm mb-5">Custom domains, daily backups, and priority support for production sites.</div>
            <div class="text-2xl font-bold text-white mb-6">$20 <span class="text-sm font-normal text-[#666]">/ month</span></div>
            <ul class="space-y-2.5 text-sm text-[#ccc] relative">
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    2GB persistent database
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Custom domain + SSL
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Daily backups
                </li>
                <li class="flex items-center gap-2">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                    Priority support
                </li>
            </ul>
        </div>
    </div>

    <!-- Manage Billing / Upgrade CTA -->
    <div class="p-6 rounded-2xl border border-white/10 bg-white/[0.02] text-center">
        {{if and (billing.StripeEnabled) (billing.HasStripeCustomer)}}
        <h3 class="text-white font-semibold mb-2">Manage your subscription</h3>
        <p class="text-[#888] text-sm mb-4">Update payment methods, view invoices, or cancel subscriptions.</p>
        <form method="POST" action="/billing/portal" class="inline">
            <button type="submit" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg text-sm font-medium transition-colors cursor-pointer" style="background: linear-gradient(135deg, rgba(139,92,246,0.3), rgba(34,211,238,0.3)); color: #e0d5ff; border: 1px solid rgba(139,92,246,0.3);">
                Manage Subscription
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
            </button>
        </form>
        {{else}}
        <h3 class="text-white font-semibold mb-2">Ready to upgrade?</h3>
        <p class="text-[#888] text-sm mb-4">Upgrade individual sites from the site list above or from the site manager.</p>
        <a href="/sites" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg text-sm font-medium transition-colors" style="background: linear-gradient(135deg, rgba(139,92,246,0.3), rgba(34,211,238,0.3)); color: #e0d5ff; border: 1px solid rgba(139,92,246,0.3);">
            Go to Sites
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
        </a>
        {{end}}
    </div>
</div>
{{end}}
← Back