diff --git a/apps/website/app/pricing/layout.tsx b/apps/website/app/pricing/layout.tsx new file mode 100644 index 0000000..0f0f0bd --- /dev/null +++ b/apps/website/app/pricing/layout.tsx @@ -0,0 +1,16 @@ +import type { Metadata } from 'next' + +export const metadata: Metadata = { + title: 'Pricing - Dokploy', + description: + 'Start for Free, Scale Pricing as You Build. Pricing plans for all your deployment and development needs.', +} + +export default function PricingLayout({ + children, +}: { + children: React.ReactNode +}) { + return <>{children} +} + diff --git a/apps/website/app/pricing/page.tsx b/apps/website/app/pricing/page.tsx new file mode 100644 index 0000000..71ee73b --- /dev/null +++ b/apps/website/app/pricing/page.tsx @@ -0,0 +1,279 @@ +'use client' + +import { Container } from '@/components/Container' +import { Button } from '@/components/ui/button' +import { cn } from '@/lib/utils' +import AnimatedGridPattern from '@/components/ui/animated-grid-pattern' +import { Check } from 'lucide-react' +import Link from 'next/link' +import { useState } from 'react' + +export default function PricingPage() { + const [billing, setBilling] = useState<'monthly' | 'annual'>('monthly') + const [servers, setServers] = useState(1) + + const calculatePrice = () => { + const basePrice = 0 + const serverPrice = 3.5 + const additionalServers = Math.max(0, servers - 1) + const monthlyTotal = basePrice + additionalServers * serverPrice + + if (billing === 'annual') { + return (monthlyTotal * 12 * 0.8).toFixed(2) // 20% discount + } + return monthlyTotal.toFixed(2) + } + + return ( +
+
+ {/* Hero Section */} +
+
+
+ +
+

+ Start for Free, Scale Pricing as You Build +

+

+ Pricing plans for all your deployment and + development needs. +

+ + {/* Billing Toggle */} +
+ + | + +
+
+
+
+ +
+
+ + {/* Pricing Cards */} +
+ +
+ {/* Open Source Plan */} +
+
+
+

+ Open source +

+

+ Free Forever +

+
+ +

+ Install and manage Dokploy UI on your own + server. +

+ +
+ {openSourceFeatures.map((feature, index) => ( +
+ + + {feature} + +
+ ))} +
+ + +
+
+ {/* Scale Plan */} +
+
+ Popular +
+
+
+

+ Plan +

+

+ Scale as You Build +

+
+ +

+ The same features as OSS, just managed by us. +

+ +
+ {scaleFeatures.map((feature, index) => ( +
+ + + {feature} + +
+ ))} +
+ + {/* Server Selector */} +
+ + + setServers(Number(e.target.value)) + } + className="h-2 w-full cursor-pointer appearance-none rounded-lg bg-muted-foreground/20" + style={{ + background: `linear-gradient(to right, hsl(var(--primary)) 0%, hsl(var(--primary)) ${((servers - 1) / 19) * 100}%, rgb(255 255 255 / 0.2) ${((servers - 1) / 19) * 100}%, rgb(255 255 255 / 0.2) 100%)`, + }} + /> +
+ 1 server + + {servers}{' '} + {servers === 1 ? 'server' : 'servers'} + + 20 servers +
+ +
+
+ + {billing === 'annual' + ? 'Annual' + : 'Monthly'}{' '} + total + +
+ + ${calculatePrice()} + + + /{billing === 'annual' ? 'year' : 'month'} + +
+
+ {billing === 'annual' && ( +

+ Save 20% with annual billing +

+ )} +

+ $3.50 per additional server +

+
+
+ + +
+
+
+
+
+ + {/* FAQ or Additional Info Section */} +
+ +
+

+ Questions about pricing? +

+

+ Our team is here to help you choose the right plan for + your needs. +

+ +
+
+
+
+
+ ) +} + +// Data +const openSourceFeatures = [ + 'Self-hosted Infrastructure', + 'Community support', + 'Access to core features', + 'Access to all updates', + 'Unlimited servers', +] + +const scaleFeatures = [ + 'Managed hosting', + 'Unlimited deployments', + 'Unlimited databases', + 'Unlimited applications', + 'Unlimited users', + 'Remote servers monitoring', + 'Priority support', +] + diff --git a/apps/website/app/sitemap.ts b/apps/website/app/sitemap.ts index 78a207e..0ce21f3 100644 --- a/apps/website/app/sitemap.ts +++ b/apps/website/app/sitemap.ts @@ -16,6 +16,12 @@ export default async function sitemap(): Promise { changeFrequency: 'monthly', priority: 0.8, }, + { + url: 'https://dokploy.com/pricing', + lastModified: new Date(), + changeFrequency: 'monthly', + priority: 0.9, + }, ...posts.map((post) => ({ url: `https://dokploy.com/blog/${post.slug}`, lastModified: new Date(post.published_at), diff --git a/apps/website/components/Footer.tsx b/apps/website/components/Footer.tsx index 8663f4b..1a81eba 100644 --- a/apps/website/components/Footer.tsx +++ b/apps/website/components/Footer.tsx @@ -37,18 +37,19 @@ export function Footer() { - +
diff --git a/apps/website/components/Header.tsx b/apps/website/components/Header.tsx index f45c43d..19e349c 100644 --- a/apps/website/components/Header.tsx +++ b/apps/website/components/Header.tsx @@ -121,7 +121,7 @@ function MobileNavigation() { as="div" className="absolute inset-x-0 top-full mt-4 flex origin-top flex-col rounded-2xl border border-border bg-background p-4 text-lg tracking-tight text-primary shadow-xl ring-1 ring-border/5" > - Pricing + Pricing FAQ
- Pricing + Pricing FAQ