Prepare dark theme, add pricing page
This commit is contained in:
@@ -119,4 +119,7 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
.pricing-page {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
import { Header } from "@/components/ui/header";
|
||||
import { ThemeProvider } from "@/lib/theme-context";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -29,10 +30,10 @@ export default function RootLayout({
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<Header/>
|
||||
|
||||
{children}
|
||||
|
||||
<ThemeProvider>
|
||||
<Header/>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
134
app/pricing/page.tsx
Normal file
134
app/pricing/page.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PricingCard from '@/components/pricing-card';
|
||||
import { useTheme } from '@/lib/theme-context';
|
||||
import { Sun, Moon } from 'lucide-react';
|
||||
|
||||
const PricingPage = () => {
|
||||
const [isYearly, setIsYearly] = useState(false);
|
||||
const { theme } = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.add('pricing-page');
|
||||
}, []);
|
||||
|
||||
const toggleBillingPeriod = () => {
|
||||
setIsYearly(!isYearly);
|
||||
};
|
||||
|
||||
const getPrice = (basePrice: number) => {
|
||||
return isYearly ? basePrice * 10 : basePrice;
|
||||
};
|
||||
|
||||
const getBillingPeriod = () => {
|
||||
return isYearly ? 'year' : 'month';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`min-h-screen ${theme === 'dark' ? 'bg-gray-900 text-gray-100' : 'bg-gray-50 text-gray-900'}`}>
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-extrabold sm:text-5xl">
|
||||
Find a plan to power your apps.
|
||||
</h1>
|
||||
<p className="mt-4 text-xl">
|
||||
Dishpix supports teams of all sizes, with pricing that scales.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Pricing Toggle (Monthly/Yearly) */}
|
||||
<div className="mt-12 flex justify-center">
|
||||
<div className="relative inline-flex items-center">
|
||||
<button
|
||||
onClick={toggleBillingPeriod}
|
||||
className={`relative px-4 py-2 text-sm font-medium rounded-l-full focus:outline-none transition-colors ${
|
||||
!isYearly
|
||||
? 'bg-white text-gray-700 shadow'
|
||||
: 'bg-gray-200 text-gray-500'
|
||||
}`}
|
||||
>
|
||||
Monthly
|
||||
</button>
|
||||
<span
|
||||
className={`w-12 h-6 px-1 bg-gray-300 rounded-full transition-transform duration-300 ease-in-out ${
|
||||
isYearly ? 'translate-x-12' : 'translate-x-0'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`w-5 h-5 bg-white rounded-full shadow transform transition-transform duration-300 ease-in-out ${
|
||||
isYearly ? 'translate-x-6' : 'translate-x-0'
|
||||
}`}
|
||||
></span>
|
||||
</span>
|
||||
<button
|
||||
onClick={toggleBillingPeriod}
|
||||
className={`relative px-4 py-2 text-sm font-medium rounded-r-full focus:outline-none transition-colors ${
|
||||
isYearly
|
||||
? 'bg-white text-gray-700 shadow'
|
||||
: 'bg-gray-200 text-gray-500'
|
||||
}`}
|
||||
>
|
||||
Yearly
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pricing Cards Grid */}
|
||||
<div className="mt-16 space-y-16 sm:space-y-0 sm:grid sm:grid-cols-1 md:grid-cols-3 sm:gap-6 lg:gap-8">
|
||||
<PricingCard
|
||||
title="Start"
|
||||
price={`$${getPrice(9)}`}
|
||||
billingPeriod={getBillingPeriod()}
|
||||
features={[
|
||||
'Import your repo, deploy in seconds',
|
||||
'Automatic CI/CD',
|
||||
'Web Application Firewall',
|
||||
'Global, automated CDN',
|
||||
'Fluid compute',
|
||||
'DDoS Mitigation',
|
||||
'Traffic & performance insights',
|
||||
]}
|
||||
ctaText="Start Deploying"
|
||||
ctaHref="#"
|
||||
/>
|
||||
<PricingCard
|
||||
title="Pro"
|
||||
price={`$${getPrice(29)}`}
|
||||
billingPeriod={getBillingPeriod()}
|
||||
features={[
|
||||
'Everything in Start, plus:',
|
||||
'10x more included usage',
|
||||
'Observability tools',
|
||||
'Faster builds',
|
||||
'Cold start prevention',
|
||||
'Advanced WAF Protection',
|
||||
'Email support',
|
||||
]}
|
||||
ctaText="Start a free trial"
|
||||
ctaHref="#"
|
||||
isPopular={true}
|
||||
/>
|
||||
<PricingCard
|
||||
title="Premium"
|
||||
price={`$${getPrice(99)}`}
|
||||
billingPeriod={getBillingPeriod()}
|
||||
features={[
|
||||
'Everything in Pro, plus:',
|
||||
'Guest & Team access controls',
|
||||
'SCIM & Directory Sync',
|
||||
'Managed WAF Rulesets',
|
||||
'Multi-region compute & failover',
|
||||
'99.99% SLA',
|
||||
'Advanced Support',
|
||||
]}
|
||||
ctaText="Contact Sales"
|
||||
ctaHref="#"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PricingPage;
|
||||
Reference in New Issue
Block a user