-
-
-
- {
- console.log(e.target.value);
- setTemperature(Number(e.target.value));
- },
- required: 'This is required',
- })}
- >
-
+
+
+
-
-
-
-
-
-
-
{response ? response : 'GPT Response will load here'}
-
+
+
+
+
+
+
+
+
{response ? response : 'GPT Response will load here'}
diff --git a/app/src/client/app/PricingPage.tsx b/app/src/client/app/PricingPage.tsx
new file mode 100644
index 0000000..47efe7d
--- /dev/null
+++ b/app/src/client/app/PricingPage.tsx
@@ -0,0 +1,152 @@
+import { TierIds, STRIPE_CUSTOMER_PORTAL_LINK } from '@wasp/shared/constants';
+import { AiFillCheckCircle } from 'react-icons/ai';
+import { useState } from 'react';
+import stripePayment from '@wasp/actions/stripePayment';
+import useAuth from '@wasp/auth/useAuth';
+import { useHistory } from 'react-router-dom';
+
+export const tiers = [
+ {
+ name: 'Hobby',
+ id: TierIds.HOBBY,
+ priceMonthly: '$9.99',
+ description: 'All you need to get started',
+ features: ['Limited monthly usage', 'Basic support'],
+ },
+ {
+ name: 'Pro',
+ id: TierIds.PRO,
+ priceMonthly: '$19.99',
+ description: 'Our most popular plan',
+ features: ['Unlimited monthly usage', 'Priority customer support'],
+ bestDeal: true,
+ },
+ {
+ name: 'Enterprise',
+ id: TierIds.ENTERPRISE,
+ priceMonthly: '$500',
+ description: 'Big business means big money',
+ features: ['Unlimited monthly usage', '24/7 customer support', 'Advanced analytics'],
+ },
+];
+
+const PricingPage = () => {
+ const [isStripePaymentLoading, setIsStripePaymentLoading] = useState
(false);
+
+ const { data: user, isLoading: isUserLoading } = useAuth();
+
+ const history = useHistory();
+
+ async function handleBuyNowClick(tierId: string) {
+ if (!user) {
+ history.push('/login');
+ return;
+ }
+ try {
+ setIsStripePaymentLoading(tierId);
+ let stripeResults = await stripePayment(tierId);
+
+ if (stripeResults?.sessionUrl) {
+ window.open(stripeResults.sessionUrl, '_self');
+ }
+ } catch (error: any) {
+ console.error(error?.message ?? 'Something went wrong.');
+ } finally {
+ setIsStripePaymentLoading(false);
+ }
+ }
+
+ return (
+
+
+
+
+ Pick your pricing
+
+
+
+ Stripe subscriptions and secure webhooks are built-in. Just add your Stripe Product IDs! Try it out below with
+ test credit card number{' '}
+ 4242 4242 4242 4242 4242
+
+
+ {tiers.map((tier) => (
+
+ {tier.bestDeal && (
+
+ )}
+
+
+
+ {tier.name}
+
+
+
{tier.description}
+
+ {tier.priceMonthly}
+ /month
+
+
+ {tier.features.map((feature) => (
+ -
+
+ {feature}
+
+ ))}
+
+
+ {!!user && user.hasPaid ? (
+
+ {tier.id === 'enterprise-tier' ? 'Contact us' : 'Manage Subscription'}
+
+ ) : (
+
+ )}
+
+ ))}
+
+
+
+ );
+};
+
+export default PricingPage;
diff --git a/app/src/client/components/AppNavBar.tsx b/app/src/client/components/AppNavBar.tsx
index 48de70f..f7df401 100644
--- a/app/src/client/components/AppNavBar.tsx
+++ b/app/src/client/components/AppNavBar.tsx
@@ -8,6 +8,7 @@ import { DOCS_URL, BLOG_URL } from '@wasp/shared/constants';
const navigation = [
{ name: 'GPT Wrapper', href: '/gpt' },
+ { name: 'Pricing', href: '/pricing'},
{ name: 'Documentation', href: DOCS_URL },
{ name: 'Blog', href: BLOG_URL },
];
diff --git a/app/src/client/landing-page/LandingPage.tsx b/app/src/client/landing-page/LandingPage.tsx
index 7fb6b68..e778cb5 100644
--- a/app/src/client/landing-page/LandingPage.tsx
+++ b/app/src/client/landing-page/LandingPage.tsx
@@ -1,30 +1,23 @@
import { useState, useEffect } from 'react';
import { Dialog } from '@headlessui/react';
-import { AiFillCheckCircle, AiFillCloseCircle } from 'react-icons/ai';
+import { AiFillCloseCircle } from 'react-icons/ai';
import { HiBars3 } from 'react-icons/hi2';
import { BiLogIn } from 'react-icons/bi';
import { Link } from '@wasp/router';
import logo from '../static/logo.png';
-import daBoi from '../static/da-boi.png';
import openSaasBanner from '../static/open-saas-banner.png';
-// import openSaasBanner from '../static/open-saas-alt-banner.p ng';
-import { features, navigation, tiers, faqs, footerNavigation } from './contentSections';
-import useAuth from '@wasp/auth/useAuth';
+import { features, navigation, faqs, footerNavigation, testimonials } from './contentSections';
import DropdownUser from '../components/DropdownUser';
-import { useHistory } from 'react-router-dom';
-import stripePayment from '@wasp/actions/stripePayment';
-import { DOCS_URL, STRIPE_CUSTOMER_PORTAL_LINK } from '@wasp/shared/constants';
+import { DOCS_URL } from '@wasp/shared/constants';
import { UserMenuItems } from '../components/UserMenuItems';
+import useAuth from '@wasp/auth/useAuth';
export default function LandingPage() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
- const [isStripePaymentLoading, setIsStripePaymentLoading] = useState(false);
const [isDemoInfoVisible, setIsDemoInfoVisible] = useState(false);
const { data: user, isLoading: isUserLoading } = useAuth();
- const history = useHistory();
-
useEffect(() => {
try {
if (localStorage.getItem('isDemoInfoVisible') === 'false') {
@@ -37,25 +30,6 @@ export default function LandingPage() {
}
}, []);
- async function handleBuyNowClick(tierId: string) {
- if (!user) {
- history.push('/login');
- return;
- }
- try {
- setIsStripePaymentLoading(tierId);
- let stripeResults = await stripePayment(tierId);
-
- if (stripeResults?.sessionUrl) {
- window.open(stripeResults.sessionUrl, '_self');
- }
- } catch (error: any) {
- console.error(error?.message ?? 'Something went wrong.');
- } finally {
- setIsStripePaymentLoading(false);
- }
- }
-
const handleDemoInfoClose = () => {
try {
localStorage.setItem('isDemoInfoVisible', 'false');
@@ -70,16 +44,18 @@ export default function LandingPage() {
return (
{/* Floating Demo Announcement */}
- {isDemoInfoVisible &&
-
-
- This demo app is the SaaS template. Feel free to play around!
-
-
+ {isDemoInfoVisible && (
+
+
+
+ This demo app is the SaaS template. Feel free to play around!
+
+
+
-
}
+ )}
{/* Header */}