diff --git a/app/public-area/components/cta-form.tsx b/app/public-area/components/cta-form.tsx index 77dca04..e5cd361 100644 --- a/app/public-area/components/cta-form.tsx +++ b/app/public-area/components/cta-form.tsx @@ -1,4 +1,5 @@ -import { useMutation } from "blitz"; +import { useEffect, useRef } from "react"; +import { useMutation, useRouter } from "blitz"; import { useForm } from "react-hook-form"; import * as Panelbear from "@panelbear/panelbear-js"; @@ -9,12 +10,22 @@ type Form = { }; export default function CTAForm() { + const router = useRouter(); const [joinWaitlistMutation] = useMutation(joinWaitlist); const { handleSubmit, register, + setFocus, formState: { isSubmitted }, } = useForm
(); + + useEffect(() => { + if (typeof router.query.join_waitlist !== "undefined") { + setFocus("email"); + router.replace("/"); + } + }, []); + const onSubmit = handleSubmit(async ({ email }) => { if (isSubmitted) { return; diff --git a/app/public-area/components/layout.tsx b/app/public-area/components/layout.tsx index 18fe9d4..25c3271 100644 --- a/app/public-area/components/layout.tsx +++ b/app/public-area/components/layout.tsx @@ -3,16 +3,18 @@ import type { FunctionComponent } from "react"; import BaseLayout from "./base-layout"; type Props = { - title: string; + title?: string; }; const Layout: FunctionComponent = ({ children, title }) => (
-
-

{title}

-
+ {title ? ( +
+

{title}

+
+ ) : null}
{children}
diff --git a/app/public-area/pages/pricing.tsx b/app/public-area/pages/pricing.tsx index 5b4fda1..6ed3835 100644 --- a/app/public-area/pages/pricing.tsx +++ b/app/public-area/pages/pricing.tsx @@ -1,12 +1,132 @@ import type { BlitzPage } from "blitz"; +import { Link, Routes } from "blitz"; +import { HiCheck, HiX } from "react-icons/hi"; +import clsx from "clsx"; -import Layout from "../components/layout"; +import BaseLayout from "../components/base-layout"; -const Pricing: BlitzPage = () => { - return
Coming soon! Please come back later 👋
; +const paidFeatures = [ + "SMS", + "MMS (coming soon)", + "Calls", + "SMS forwarding (coming soon)", + "Call forwarding (coming soon)", + "Voicemail (coming soon)", + "Call recording (coming soon)", +]; + +const pricing = { + tiers: [ + { + title: "Free", + price: 0, + frequency: "", + description: "The essentials to let you try Shellphone.", + features: ["SMS (send only)"], + unavailableFeatures: paidFeatures.slice(1), + cta: "Join waitlist", + yearly: false, + }, + { + title: "Yearly", + price: 10, + frequency: "/month", + description: "Text and call anyone, anywhere in the world, all year long.", + features: paidFeatures, + unavailableFeatures: [], + cta: "Join waitlist", + yearly: true, + }, + { + title: "Monthly", + price: 15, + frequency: "/month", + description: "Text and call anyone, anywhere in the world.", + features: paidFeatures, + unavailableFeatures: [], + cta: "Join waitlist", + yearly: false, + }, + ], }; -Pricing.getLayout = (page) => {page}; +const Pricing: BlitzPage = () => { + return ( +
+
+

+ Simple no-tricks pricing +

+

+ One affordable and transparent plan that includes everything you need. +

+ +
+ {pricing.tiers.map((tier) => ( +
+
+

{tier.title}

+ {tier.yearly ? ( +

+ Get 2 months free! +

+ ) : null} +

+ {tier.price}€ + {tier.frequency} +

+ {tier.yearly ? ( +

Billed yearly ({tier.price * 10}€)

+ ) : null} +

{tier.description}

+ +
    + {tier.features.map((feature) => ( +
  • +
  • + ))} + {tier.unavailableFeatures.map((feature) => ( +
  • +
  • + ))} +
+
+ + + + {tier.cta} + + +
+ ))} +
+
+
+ ); +}; + +Pricing.getLayout = (page) => {page}; Pricing.suppressFirstRenderFlicker = true; export default Pricing;