diff --git a/apps/web/src/pages/pricing/index.tsx b/apps/web/src/pages/pricing/index.tsx new file mode 100644 index 00000000..6ffcb6d7 --- /dev/null +++ b/apps/web/src/pages/pricing/index.tsx @@ -0,0 +1,5 @@ +import PricingView from "~/views/pricing"; + +export default function Pricing() { + return ; +} diff --git a/apps/web/src/views/home/components/Header.tsx b/apps/web/src/views/home/components/Header.tsx index ebe32d9e..4a427d60 100644 --- a/apps/web/src/views/home/components/Header.tsx +++ b/apps/web/src/views/home/components/Header.tsx @@ -12,7 +12,7 @@ const Header = ({ isLoggedIn }: { isLoggedIn: boolean }) => { const menuItems = [ { label: t`Roadmap`, href: "/kan/roadmap", openInNewTab: true }, { label: t`Features`, href: "#features" }, - { label: t`Pricing`, href: "#pricing" }, + { label: t`Pricing`, href: "/pricing" }, { label: t`Docs`, href: "https://docs.kan.bn", openInNewTab: true }, ]; diff --git a/apps/web/src/views/home/index.tsx b/apps/web/src/views/home/index.tsx index 9ddde092..b813ee56 100644 --- a/apps/web/src/views/home/index.tsx +++ b/apps/web/src/views/home/index.tsx @@ -2,16 +2,16 @@ import Image from "next/image"; import Link from "next/link"; import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; -import { IoLogoGithub, IoLogoHackernews } from "react-icons/io"; +import { useTheme } from "next-themes"; +import { IoLogoGithub } from "react-icons/io"; import Button from "~/components/Button"; import { PageHead } from "~/components/PageHead"; -import { useTheme } from "next-themes"; +import Pricing from "../pricing/components/Pricing"; import Cta from "./components/Cta"; import FAQs from "./components/Faqs"; import Features from "./components/Features"; import Layout from "./components/Layout"; -import Pricing from "./components/Pricing"; export default function HomeView() { const { resolvedTheme } = useTheme(); @@ -111,10 +111,6 @@ export default function HomeView() {
-
-
- -
diff --git a/apps/web/src/views/home/components/Pricing.tsx b/apps/web/src/views/pricing/components/Pricing.tsx similarity index 93% rename from apps/web/src/views/home/components/Pricing.tsx rename to apps/web/src/views/pricing/components/Pricing.tsx index b61bc2fa..7ea79313 100644 --- a/apps/web/src/views/home/components/Pricing.tsx +++ b/apps/web/src/views/pricing/components/Pricing.tsx @@ -85,19 +85,17 @@ const Pricing = () => {

{t`Pricing`}

-

+

{t`Simple pricing`}

-

+

{t`Get started for free, with no usage limits. For collaboration, upgrade to a plan that fits the size of your team.`}

-
-
+
+
-

- {t`Launch offer: unlimited seats for just $29/month with Pro`} -

+

{t`Launch offer: unlimited seats for just $29/month with Pro`}

{

{ + const frequencies = [ + { + value: "monthly" as Frequency, + label: t`Monthly`, + priceSuffix: t`per user/month`, + }, + { + value: "annually" as Frequency, + label: t`Yearly`, + priceSuffix: t`per user/month`, + }, + ]; + + const [frequency, setFrequency] = useState(frequencies[1]); + + const tiers = [ + { + name: t`Individuals`, + id: "tier-individuals", + href: "signup", + buttonText: t`Get Started`, + price: { monthly: t`Free`, annually: t`Free` }, + description: t`Everything you need, free forever. Unlimited boards, unlimited lists, unlimited cards. Upgrade any time.`, + featureHeader: t`Free, forever`, + features: [ + t`1 user`, + t`Unlimited boards`, + t`Unlimited lists`, + t`Unlimited cards`, + t`Unlimited comments`, + t`Unlimited activity log`, + ], + showPrice: true, + }, + { + name: t`Teams`, + id: "tier-teams", + href: "signup", + buttonText: t`Get Started`, + price: { monthly: "$10.00", annually: "$8.00" }, + description: t`Kanban is better with a team. Perfect for small and growing teams looking to collaborate.`, + featureHeader: t`Everything in the free plan, plus:`, + features: [ + t`Workspace members`, + t`Admin roles`, + t`Priority email support`, + t`Support the development of the project`, + ], + highlighted: true, + showPrice: true, + showPriceSuffix: true, + }, + { + name: t`Self Host`, + id: "tier-self-host", + href: "https://github.com/kanbn/kan", + buttonText: t`View docs`, + price: { monthly: "-", annually: "-" }, + description: t`Host Kan on your own infrastructure. Ideal for organisations that need complete control over their data.`, + featureHeader: t`Complete control and ownership:`, + features: [ + t`Run on your own infrastructure`, + t`Own your data`, + t`Custom domain`, + ], + mostPopular: false, + showPrice: false, + }, + ]; + + return ( + <> +

+
+
+ +

{t`Launch offer: unlimited seats for just $29/month with Pro`}

+
+
+ setFrequency(value)} + className="grid grid-cols-2 gap-x-1 rounded-full p-1 text-center text-xs/5 font-semibold ring-1 ring-inset ring-light-600 dark:ring-dark-600" + > + {frequencies.map((option) => ( + + {option.label} + + ))} + +
+
+
+ +
+ {tiers.map((tier) => ( +
+
+

+ {tier.name} +

+ {tier.highlighted && frequency?.value === "annually" ? ( +

+ -20% +

+ ) : null} +
+

+ {tier.description} +

+

+ + {tier.price[frequency?.value ?? "monthly"]} + + {tier.showPriceSuffix && ( + + {frequency?.priceSuffix} + + )} +

+ + {tier.buttonText} + +

+ {tier.featureHeader} +

+
    + {tier.features.map((feature) => ( +
  • + + {feature} +
  • + ))} +
+
+ ))} +
+ + ); +}; + +export default Pricing; diff --git a/apps/web/src/views/pricing/index.tsx b/apps/web/src/views/pricing/index.tsx new file mode 100644 index 00000000..ca12789f --- /dev/null +++ b/apps/web/src/views/pricing/index.tsx @@ -0,0 +1,31 @@ +import { t } from "@lingui/core/macro"; + +import { PageHead } from "~/components/PageHead"; +import Layout from "../home/components/Layout"; +import PricingTiers from "./components/PricingTiers"; + +export default function PricingView() { + return ( + + + +
+
+
+
+

{t`Pricing`}

+
+ +

+ {t`Simple pricing`} +

+

+ {t`Get started for free, with no usage limits. For collaboration, upgrade to a plan that fits the size of your team.`} +

+
+ +
+
+
+ ); +}