a tool for shared writing and social publishing
0

Configure Feed

Select the types of activity you want to include in your feed.

add login checkout flow

Jared Pereira (May 21, 2026, 1:48 AM EDT) 7c883dc0 b69d7d03

+112 -5
+11 -5
app/about/Pricing.tsx
··· 2 2 3 3 import { ButtonPrimary } from "components/Buttons"; 4 4 import { ToggleGroup } from "components/ToggleGroup"; 5 + import Link from "next/link"; 5 6 import { useState } from "react"; 6 7 7 8 export const Pricing = () => { ··· 84 85 <p className="text-[1rem]! text-center text-tertiary text-snug pb-3"> 85 86 Serious publishers, serious tools 86 87 </p> 87 - <ButtonPrimary 88 - fullWidth 89 - className=" bg-[#57822B]! border-[#57822B]! hover:outline-[#57822B]! text-white! text-[1rem] sm:text-[1.25rem]!" 88 + <Link 89 + href={`/checkout/pro?cadence=${cadence === "yearly" ? "year" : "month"}`} 90 + className="no-underline!" 90 91 > 91 - Get Pro 92 - </ButtonPrimary> 92 + <ButtonPrimary 93 + fullWidth 94 + className=" bg-[#57822B]! border-[#57822B]! hover:outline-[#57822B]! text-white! text-[1rem] sm:text-[1.25rem]!" 95 + > 96 + Get Pro 97 + </ButtonPrimary> 98 + </Link> 93 99 94 100 <hr className="border-border-light" /> 95 101
+15
app/checkout/pro/ProCheckoutLogin.tsx
··· 1 + "use client"; 2 + 3 + import { LoginContent } from "components/LoginButton"; 4 + 5 + export function ProCheckoutLogin({ redirectRoute }: { redirectRoute: string }) { 6 + return ( 7 + <LoginContent 8 + pageView 9 + redirectRoute={redirectRoute} 10 + onSuccess={() => { 11 + window.location.href = redirectRoute; 12 + }} 13 + /> 14 + ); 15 + }
+45
app/checkout/pro/ProCheckoutTrigger.tsx
··· 1 + "use client"; 2 + 3 + import { useEffect, useRef, useState } from "react"; 4 + import { createCheckoutSession } from "actions/createCheckoutSession"; 5 + import { DotLoader } from "components/utils/DotLoader"; 6 + 7 + export function ProCheckoutTrigger({ 8 + cadence, 9 + }: { 10 + cadence: "month" | "year"; 11 + }) { 12 + const [error, setError] = useState<string | null>(null); 13 + const started = useRef(false); 14 + 15 + useEffect(() => { 16 + if (started.current) return; 17 + started.current = true; 18 + (async () => { 19 + const result = await createCheckoutSession(cadence, "/home"); 20 + if (result.ok) { 21 + window.location.href = result.value.url; 22 + } else { 23 + setError(result.error); 24 + } 25 + })(); 26 + }, [cadence]); 27 + 28 + return ( 29 + <div className="flex flex-col items-center justify-center gap-3 text-center max-w-sm w-full mx-auto"> 30 + {error ? ( 31 + <> 32 + <h3>We couldn't start checkout</h3> 33 + <div className="text-secondary leading-snug">{error}</div> 34 + </> 35 + ) : ( 36 + <> 37 + <DotLoader /> 38 + <div className="text-secondary leading-snug"> 39 + Redirecting you to Stripe checkout… 40 + </div> 41 + </> 42 + )} 43 + </div> 44 + ); 45 + }
+41
app/checkout/pro/page.tsx
··· 1 + import { redirect } from "next/navigation"; 2 + import { getIdentityData } from "actions/getIdentityData"; 3 + import { ProCheckoutLogin } from "./ProCheckoutLogin"; 4 + import { ProCheckoutTrigger } from "./ProCheckoutTrigger"; 5 + 6 + export const metadata = { 7 + title: "Get Leaflet Pro", 8 + }; 9 + 10 + export default async function ProCheckoutPage({ 11 + searchParams, 12 + }: { 13 + searchParams: Promise<{ cadence?: string }>; 14 + }) { 15 + const { cadence: rawCadence } = await searchParams; 16 + const cadence: "month" | "year" = rawCadence === "month" ? "month" : "year"; 17 + 18 + const identity = await getIdentityData(); 19 + 20 + if (identity?.entitlements?.publication_analytics) { 21 + redirect("/home?upgrade=already-pro"); 22 + } 23 + 24 + const redirectRoute = `/checkout/pro?cadence=${cadence}`; 25 + 26 + return ( 27 + <div className="proCheckoutPage relative w-full min-h-[100dvh] flex items-center justify-center bg-bg-leaflet p-4"> 28 + {!identity ? ( 29 + <div className="flex flex-col items-center gap-3 max-w-sm w-full text-center"> 30 + <h2>Log in to get Leaflet Pro</h2> 31 + <div className="text-secondary leading-snug"> 32 + You'll be redirected to checkout after you sign in. 33 + </div> 34 + <ProCheckoutLogin redirectRoute={redirectRoute} /> 35 + </div> 36 + ) : ( 37 + <ProCheckoutTrigger cadence={cadence} /> 38 + )} 39 + </div> 40 + ); 41 + }