From ea14904730b0007176fc39436cc889b7e40d387d Mon Sep 17 00:00:00 2001 From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:22:54 +0100 Subject: [PATCH 1/2] feat: Add signup page and update navbar --- apps/web/app/(org)/login/form.tsx | 14 +- apps/web/app/(org)/signup/form.tsx | 494 +++++++++++++++++++++++++++++ apps/web/app/(org)/signup/page.tsx | 29 ++ apps/web/app/(site)/Navbar.tsx | 459 ++++++++++++++------------- 4 files changed, 773 insertions(+), 223 deletions(-) create mode 100644 apps/web/app/(org)/signup/form.tsx create mode 100644 apps/web/app/(org)/signup/page.tsx diff --git a/apps/web/app/(org)/login/form.tsx b/apps/web/app/(org)/login/form.tsx index 70b375e4b87..0601ded15d2 100644 --- a/apps/web/app/(org)/login/form.tsx +++ b/apps/web/app/(org)/login/form.tsx @@ -437,7 +437,19 @@ const NormalLogin = ({ )} */} -
+ + Don't have an account?{" "} + + Sign up here + + +

OR

diff --git a/apps/web/app/(org)/signup/form.tsx b/apps/web/app/(org)/signup/form.tsx new file mode 100644 index 00000000000..16bc429bb5d --- /dev/null +++ b/apps/web/app/(org)/signup/form.tsx @@ -0,0 +1,494 @@ +"use client"; + +import { Button, Input, LogoBadge } from "@cap/ui"; +import { + faArrowLeft, + faEnvelope, + faExclamationCircle, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { AnimatePresence, motion } from "framer-motion"; +import Cookies from "js-cookie"; +import { LucideArrowUpRight } from "lucide-react"; +import Image from "next/image"; +import Link from "next/link"; +import { useRouter, useSearchParams } from "next/navigation"; +import { signIn } from "next-auth/react"; +import { Suspense, useEffect, useState } from "react"; +import { toast } from "sonner"; +import { getOrganizationSSOData } from "@/actions/organization/get-organization-sso-data"; +import { trackEvent } from "@/app/utils/analytics"; + +const MotionInput = motion(Input); +const MotionLogoBadge = motion(LogoBadge); +const MotionLink = motion(Link); +const MotionButton = motion(Button); + +export function SignupForm() { + const searchParams = useSearchParams(); + const router = useRouter(); + const next = searchParams?.get("next"); + const [email, setEmail] = useState(""); + const [loading, setLoading] = useState(false); + const [emailSent, setEmailSent] = useState(false); + const [oauthError, setOauthError] = useState(false); + const [showOrgInput, setShowOrgInput] = useState(false); + const [organizationId, setOrganizationId] = useState(""); + const [organizationName, setOrganizationName] = useState(null); + const [lastEmailSentTime, setLastEmailSentTime] = useState( + null + ); + const theme = Cookies.get("theme") || "light"; + + useEffect(() => { + theme === "dark" + ? (document.body.className = "dark") + : (document.body.className = "light"); + //remove the dark mode when we leave the dashboard + return () => { + document.body.className = "light"; + }; + }, [theme]); + + useEffect(() => { + const error = searchParams?.get("error"); + const errorDesc = searchParams?.get("error_description"); + + const handleErrors = () => { + if (error === "OAuthAccountNotLinked" && !errorDesc) { + setOauthError(true); + return toast.error( + "This email is already associated with a different sign-in method" + ); + } else if ( + error === "profile_not_allowed_outside_organization" && + !errorDesc + ) { + return toast.error( + "Your email domain is not authorized for SSO access. Please use your work email or contact your administrator." + ); + } else if (error && errorDesc) { + return toast.error(errorDesc); + } + }; + handleErrors(); + }, [searchParams]); + + useEffect(() => { + const pendingPriceId = localStorage.getItem("pendingPriceId"); + const pendingQuantity = localStorage.getItem("pendingQuantity") ?? "1"; + if (emailSent && pendingPriceId) { + localStorage.removeItem("pendingPriceId"); + localStorage.removeItem("pendingQuantity"); + + // Wait a bit to ensure the user is created + setTimeout(async () => { + const response = await fetch(`/api/settings/billing/subscribe`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + priceId: pendingPriceId, + quantity: parseInt(pendingQuantity), + }), + }); + const data = await response.json(); + + if (data.url) { + window.location.href = data.url; + } + }, 2000); + } + }, [emailSent]); + + const handleGoogleSignIn = () => { + trackEvent("auth_started", { method: "google", is_signup: true }); + signIn("google", { + ...(next && next.length > 0 ? { callbackUrl: next } : {}), + }); + }; + + const handleOrganizationLookup = async (e: React.FormEvent) => { + e.preventDefault(); + if (!organizationId) { + toast.error("Please enter an organization ID"); + return; + } + + try { + const data = await getOrganizationSSOData(organizationId); + setOrganizationName(data.name); + + signIn("workos", undefined, { + organization: data.organizationId, + connection: data.connectionId, + }); + } catch (error) { + console.error("Lookup Error:", error); + toast.error("Organization not found or SSO not configured"); + } + }; + + return ( + + setShowOrgInput(false)} + className="absolute overflow-hidden top-5 rounded-full left-5 z-20 hover:bg-gray-1 gap-2 items-center py-1.5 px-3 text-gray-12 bg-transparent border border-gray-4 transition-colors duration-300 cursor-pointer" + > + + + Back + + + + + + + + Sign up to Cap + + + Beautiful screen recordings, owned by you. + + + + + +
+ + ); +}; + +const NormalSignup = ({ + setShowOrgInput, + email, + emailSent, + setEmail, + loading, + oauthError, + handleGoogleSignIn, +}: { + setShowOrgInput: (show: boolean) => void; + email: string; + emailSent: boolean; + setEmail: (email: string) => void; + loading: boolean; + oauthError: boolean; + handleGoogleSignIn: () => void; +}) => { + return ( + + + { + setEmail(e.target.value); + }} + /> + } + > + Sign up with email + + +
+ +

OR

+ +
+ + {!oauthError && ( + <> + + Google + Sign up with Google + + + )} + + {oauthError && ( +
+ +

+ It looks like you've previously used this email to sign up via + email. Please enter your email below to receive a sign up link. +

+
+ )} + setShowOrgInput(true)} + disabled={loading} + > + + Sign up with SAML SSO + +
+
+ ); +}; diff --git a/apps/web/app/(org)/signup/page.tsx b/apps/web/app/(org)/signup/page.tsx new file mode 100644 index 00000000000..aa4736bfc09 --- /dev/null +++ b/apps/web/app/(org)/signup/page.tsx @@ -0,0 +1,29 @@ +import { getCurrentUser } from "@cap/database/auth/session"; +import { faArrowLeft } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { SignupForm } from "./form"; + +export const dynamic = "force-dynamic"; + +export default async function SignupPage() { + const session = await getCurrentUser(); + if (session) { + redirect("/dashboard"); + } + return ( +
+
+ + + Home + +
+ +
+ ); +} \ No newline at end of file diff --git a/apps/web/app/(site)/Navbar.tsx b/apps/web/app/(site)/Navbar.tsx index 34ea845f172..39ed887a7f8 100644 --- a/apps/web/app/(site)/Navbar.tsx +++ b/apps/web/app/(site)/Navbar.tsx @@ -1,20 +1,18 @@ "use client"; import { - Button, - ListItem, - Logo, - NavigationMenu, - NavigationMenuContent, - NavigationMenuItem, - NavigationMenuLink, - NavigationMenuList, - NavigationMenuTrigger, - navigationMenuTriggerStyle, + Button, + ListItem, + Logo, + NavigationMenu, + NavigationMenuContent, + NavigationMenuItem, + NavigationMenuLink, + NavigationMenuList, + NavigationMenuTrigger, + navigationMenuTriggerStyle, } from "@cap/ui"; import { classNames } from "@cap/utils"; -import { faGithub } from "@fortawesome/free-brands-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { motion } from "framer-motion"; import Link from "next/link"; import { usePathname } from "next/navigation"; @@ -23,221 +21,238 @@ import MobileMenu from "@/components/ui/MobileMenu"; import { useAuthContext } from "../Layout/AuthContext"; const Links = [ - { - label: "Product", - dropdown: [ - { - label: "Download App", - sub: "Downloads for macOS & Windows", - href: "/download", - }, - { - label: "Open Source", - sub: "Cap is open source and available on GitHub", - href: "https://github.com/CapSoftware/Cap", - }, - { - label: "Self-host Cap", - sub: "Self-host Cap on your own infrastructure", - href: "/self-hosting", - }, - { - label: "Join the community", - sub: "Join the Cap community on Discord", - href: "https://cap.link/discord", - }, - ], - }, - { - label: "Download", - href: "/download", - }, - { - label: "Testimonials", - href: "/testimonials", - }, - { - label: "Help", - dropdown: [ - { - label: "Documentation", - sub: "Documentation for using Cap", - href: "/docs", - }, - { - label: "FAQs", - sub: "Frequently asked questions about Cap", - href: "/faq", - }, - { - label: "Email support", - sub: "Support via email", - href: "mailto:hello@cap.so", - }, - { - label: "Chat support", - sub: "Support via chat", - href: "https://discord.gg/y8gdQ3WRN3", - }, - ], - }, - { - label: "Pricing", - href: "/pricing", - }, - { - label: "About", - href: "/about", - }, - { - label: "Blog", - href: "/blog", - }, + { + label: "Product", + dropdown: [ + { + label: "Download App", + sub: "Downloads for macOS & Windows", + href: "/download", + }, + { + label: "Open Source", + sub: "Cap is open source and available on GitHub", + href: "https://github.com/CapSoftware/Cap", + }, + { + label: "Self-host Cap", + sub: "Self-host Cap on your own infrastructure", + href: "/self-hosting", + }, + { + label: "Join the community", + sub: "Join the Cap community on Discord", + href: "https://cap.link/discord", + }, + ], + }, + { + label: "Download", + href: "/download", + }, + { + label: "Testimonials", + href: "/testimonials", + }, + { + label: "Help", + dropdown: [ + { + label: "Documentation", + sub: "Documentation for using Cap", + href: "/docs", + }, + { + label: "FAQs", + sub: "Frequently asked questions about Cap", + href: "/faq", + }, + { + label: "Email support", + sub: "Support via email", + href: "mailto:hello@cap.so", + }, + { + label: "Chat support", + sub: "Support via chat", + href: "https://discord.gg/y8gdQ3WRN3", + }, + ], + }, + { + label: "Pricing", + href: "/pricing", + }, + { + label: "About", + href: "/about", + }, + { + label: "Blog", + href: "/blog", + }, +]; + +const AuthLinks = [ + { + label: "Log In", + href: "/login", + }, ]; export const Navbar = () => { - const pathname = usePathname(); - const [showMobileMenu, setShowMobileMenu] = useState(false); - const auth = use(useAuthContext().user); + const pathname = usePathname(); + const [showMobileMenu, setShowMobileMenu] = useState(false); + const auth = use(useAuthContext().user); - return ( - <> -
- -
- {showMobileMenu && ( - - )} - - ); + return ( + <> +
+ +
+ {showMobileMenu && ( + + )} + + ); }; function LoginOrDashboard() { - const auth = use(useAuthContext().user); - return ( - - ); + const auth = use(useAuthContext().user); + + return ( + + ); } From a758467c5d8b8ea9a87cfd041ca4f0525e55ab8a Mon Sep 17 00:00:00 2001 From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:25:09 +0100 Subject: [PATCH 2/2] format --- apps/web/app/(org)/signup/form.tsx | 888 +++++++++++----------- apps/web/app/(org)/signup/page.tsx | 2 +- apps/web/app/(site)/Navbar.tsx | 466 ++++++------ apps/web/components/ReadyToGetStarted.tsx | 96 +-- 4 files changed, 726 insertions(+), 726 deletions(-) diff --git a/apps/web/app/(org)/signup/form.tsx b/apps/web/app/(org)/signup/form.tsx index 16bc429bb5d..d5817ac0736 100644 --- a/apps/web/app/(org)/signup/form.tsx +++ b/apps/web/app/(org)/signup/form.tsx @@ -2,9 +2,9 @@ import { Button, Input, LogoBadge } from "@cap/ui"; import { - faArrowLeft, - faEnvelope, - faExclamationCircle, + faArrowLeft, + faEnvelope, + faExclamationCircle, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { AnimatePresence, motion } from "framer-motion"; @@ -25,470 +25,470 @@ const MotionLink = motion(Link); const MotionButton = motion(Button); export function SignupForm() { - const searchParams = useSearchParams(); - const router = useRouter(); - const next = searchParams?.get("next"); - const [email, setEmail] = useState(""); - const [loading, setLoading] = useState(false); - const [emailSent, setEmailSent] = useState(false); - const [oauthError, setOauthError] = useState(false); - const [showOrgInput, setShowOrgInput] = useState(false); - const [organizationId, setOrganizationId] = useState(""); - const [organizationName, setOrganizationName] = useState(null); - const [lastEmailSentTime, setLastEmailSentTime] = useState( - null - ); - const theme = Cookies.get("theme") || "light"; + const searchParams = useSearchParams(); + const router = useRouter(); + const next = searchParams?.get("next"); + const [email, setEmail] = useState(""); + const [loading, setLoading] = useState(false); + const [emailSent, setEmailSent] = useState(false); + const [oauthError, setOauthError] = useState(false); + const [showOrgInput, setShowOrgInput] = useState(false); + const [organizationId, setOrganizationId] = useState(""); + const [organizationName, setOrganizationName] = useState(null); + const [lastEmailSentTime, setLastEmailSentTime] = useState( + null, + ); + const theme = Cookies.get("theme") || "light"; - useEffect(() => { - theme === "dark" - ? (document.body.className = "dark") - : (document.body.className = "light"); - //remove the dark mode when we leave the dashboard - return () => { - document.body.className = "light"; - }; - }, [theme]); + useEffect(() => { + theme === "dark" + ? (document.body.className = "dark") + : (document.body.className = "light"); + //remove the dark mode when we leave the dashboard + return () => { + document.body.className = "light"; + }; + }, [theme]); - useEffect(() => { - const error = searchParams?.get("error"); - const errorDesc = searchParams?.get("error_description"); + useEffect(() => { + const error = searchParams?.get("error"); + const errorDesc = searchParams?.get("error_description"); - const handleErrors = () => { - if (error === "OAuthAccountNotLinked" && !errorDesc) { - setOauthError(true); - return toast.error( - "This email is already associated with a different sign-in method" - ); - } else if ( - error === "profile_not_allowed_outside_organization" && - !errorDesc - ) { - return toast.error( - "Your email domain is not authorized for SSO access. Please use your work email or contact your administrator." - ); - } else if (error && errorDesc) { - return toast.error(errorDesc); - } - }; - handleErrors(); - }, [searchParams]); + const handleErrors = () => { + if (error === "OAuthAccountNotLinked" && !errorDesc) { + setOauthError(true); + return toast.error( + "This email is already associated with a different sign-in method", + ); + } else if ( + error === "profile_not_allowed_outside_organization" && + !errorDesc + ) { + return toast.error( + "Your email domain is not authorized for SSO access. Please use your work email or contact your administrator.", + ); + } else if (error && errorDesc) { + return toast.error(errorDesc); + } + }; + handleErrors(); + }, [searchParams]); - useEffect(() => { - const pendingPriceId = localStorage.getItem("pendingPriceId"); - const pendingQuantity = localStorage.getItem("pendingQuantity") ?? "1"; - if (emailSent && pendingPriceId) { - localStorage.removeItem("pendingPriceId"); - localStorage.removeItem("pendingQuantity"); + useEffect(() => { + const pendingPriceId = localStorage.getItem("pendingPriceId"); + const pendingQuantity = localStorage.getItem("pendingQuantity") ?? "1"; + if (emailSent && pendingPriceId) { + localStorage.removeItem("pendingPriceId"); + localStorage.removeItem("pendingQuantity"); - // Wait a bit to ensure the user is created - setTimeout(async () => { - const response = await fetch(`/api/settings/billing/subscribe`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - priceId: pendingPriceId, - quantity: parseInt(pendingQuantity), - }), - }); - const data = await response.json(); + // Wait a bit to ensure the user is created + setTimeout(async () => { + const response = await fetch(`/api/settings/billing/subscribe`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + priceId: pendingPriceId, + quantity: parseInt(pendingQuantity), + }), + }); + const data = await response.json(); - if (data.url) { - window.location.href = data.url; - } - }, 2000); - } - }, [emailSent]); + if (data.url) { + window.location.href = data.url; + } + }, 2000); + } + }, [emailSent]); - const handleGoogleSignIn = () => { - trackEvent("auth_started", { method: "google", is_signup: true }); - signIn("google", { - ...(next && next.length > 0 ? { callbackUrl: next } : {}), - }); - }; + const handleGoogleSignIn = () => { + trackEvent("auth_started", { method: "google", is_signup: true }); + signIn("google", { + ...(next && next.length > 0 ? { callbackUrl: next } : {}), + }); + }; - const handleOrganizationLookup = async (e: React.FormEvent) => { - e.preventDefault(); - if (!organizationId) { - toast.error("Please enter an organization ID"); - return; - } + const handleOrganizationLookup = async (e: React.FormEvent) => { + e.preventDefault(); + if (!organizationId) { + toast.error("Please enter an organization ID"); + return; + } - try { - const data = await getOrganizationSSOData(organizationId); - setOrganizationName(data.name); + try { + const data = await getOrganizationSSOData(organizationId); + setOrganizationName(data.name); - signIn("workos", undefined, { - organization: data.organizationId, - connection: data.connectionId, - }); - } catch (error) { - console.error("Lookup Error:", error); - toast.error("Organization not found or SSO not configured"); - } - }; + signIn("workos", undefined, { + organization: data.organizationId, + connection: data.connectionId, + }); + } catch (error) { + console.error("Lookup Error:", error); + toast.error("Organization not found or SSO not configured"); + } + }; - return ( - - setShowOrgInput(false)} - className="absolute overflow-hidden top-5 rounded-full left-5 z-20 hover:bg-gray-1 gap-2 items-center py-1.5 px-3 text-gray-12 bg-transparent border border-gray-4 transition-colors duration-300 cursor-pointer" - > - - - Back - - - - - - - - Sign up to Cap - - - Beautiful screen recordings, owned by you. - - - - - -
- - ); + return ( + + setOrganizationId(e.target.value)} + className="w-full max-w-full" + /> + {organizationName && ( +

+ Signing up with: {organizationName} +

+ )} +
+ +
+
+ ); }; const NormalSignup = ({ - setShowOrgInput, - email, - emailSent, - setEmail, - loading, - oauthError, - handleGoogleSignIn, + setShowOrgInput, + email, + emailSent, + setEmail, + loading, + oauthError, + handleGoogleSignIn, }: { - setShowOrgInput: (show: boolean) => void; - email: string; - emailSent: boolean; - setEmail: (email: string) => void; - loading: boolean; - oauthError: boolean; - handleGoogleSignIn: () => void; + setShowOrgInput: (show: boolean) => void; + email: string; + emailSent: boolean; + setEmail: (email: string) => void; + loading: boolean; + oauthError: boolean; + handleGoogleSignIn: () => void; }) => { - return ( - - - { - setEmail(e.target.value); - }} - /> - } - > - Sign up with email - - -
- -

OR

- -
- - {!oauthError && ( - <> - - Google - Sign up with Google - - - )} + return ( + + + { + setEmail(e.target.value); + }} + /> + } + > + Sign up with email + + +
+ +

OR

+ +
+ + {!oauthError && ( + <> + + Google + Sign up with Google + + + )} - {oauthError && ( -
- -

- It looks like you've previously used this email to sign up via - email. Please enter your email below to receive a sign up link. -

-
- )} - setShowOrgInput(true)} - disabled={loading} - > - - Sign up with SAML SSO - -
-
- ); + {oauthError && ( +
+ +

+ It looks like you've previously used this email to sign up via + email. Please enter your email below to receive a sign up link. +

+
+ )} + setShowOrgInput(true)} + disabled={loading} + > + + Sign up with SAML SSO + +
+
+ ); }; diff --git a/apps/web/app/(org)/signup/page.tsx b/apps/web/app/(org)/signup/page.tsx index aa4736bfc09..de68b63d08c 100644 --- a/apps/web/app/(org)/signup/page.tsx +++ b/apps/web/app/(org)/signup/page.tsx @@ -26,4 +26,4 @@ export default async function SignupPage() { ); -} \ No newline at end of file +} diff --git a/apps/web/app/(site)/Navbar.tsx b/apps/web/app/(site)/Navbar.tsx index 39ed887a7f8..f16dd135c2e 100644 --- a/apps/web/app/(site)/Navbar.tsx +++ b/apps/web/app/(site)/Navbar.tsx @@ -1,16 +1,16 @@ "use client"; import { - Button, - ListItem, - Logo, - NavigationMenu, - NavigationMenuContent, - NavigationMenuItem, - NavigationMenuLink, - NavigationMenuList, - NavigationMenuTrigger, - navigationMenuTriggerStyle, + Button, + ListItem, + Logo, + NavigationMenu, + NavigationMenuContent, + NavigationMenuItem, + NavigationMenuLink, + NavigationMenuList, + NavigationMenuTrigger, + navigationMenuTriggerStyle, } from "@cap/ui"; import { classNames } from "@cap/utils"; import { motion } from "framer-motion"; @@ -21,238 +21,238 @@ import MobileMenu from "@/components/ui/MobileMenu"; import { useAuthContext } from "../Layout/AuthContext"; const Links = [ - { - label: "Product", - dropdown: [ - { - label: "Download App", - sub: "Downloads for macOS & Windows", - href: "/download", - }, - { - label: "Open Source", - sub: "Cap is open source and available on GitHub", - href: "https://github.com/CapSoftware/Cap", - }, - { - label: "Self-host Cap", - sub: "Self-host Cap on your own infrastructure", - href: "/self-hosting", - }, - { - label: "Join the community", - sub: "Join the Cap community on Discord", - href: "https://cap.link/discord", - }, - ], - }, - { - label: "Download", - href: "/download", - }, - { - label: "Testimonials", - href: "/testimonials", - }, - { - label: "Help", - dropdown: [ - { - label: "Documentation", - sub: "Documentation for using Cap", - href: "/docs", - }, - { - label: "FAQs", - sub: "Frequently asked questions about Cap", - href: "/faq", - }, - { - label: "Email support", - sub: "Support via email", - href: "mailto:hello@cap.so", - }, - { - label: "Chat support", - sub: "Support via chat", - href: "https://discord.gg/y8gdQ3WRN3", - }, - ], - }, - { - label: "Pricing", - href: "/pricing", - }, - { - label: "About", - href: "/about", - }, - { - label: "Blog", - href: "/blog", - }, + { + label: "Product", + dropdown: [ + { + label: "Download App", + sub: "Downloads for macOS & Windows", + href: "/download", + }, + { + label: "Open Source", + sub: "Cap is open source and available on GitHub", + href: "https://github.com/CapSoftware/Cap", + }, + { + label: "Self-host Cap", + sub: "Self-host Cap on your own infrastructure", + href: "/self-hosting", + }, + { + label: "Join the community", + sub: "Join the Cap community on Discord", + href: "https://cap.link/discord", + }, + ], + }, + { + label: "Download", + href: "/download", + }, + { + label: "Testimonials", + href: "/testimonials", + }, + { + label: "Help", + dropdown: [ + { + label: "Documentation", + sub: "Documentation for using Cap", + href: "/docs", + }, + { + label: "FAQs", + sub: "Frequently asked questions about Cap", + href: "/faq", + }, + { + label: "Email support", + sub: "Support via email", + href: "mailto:hello@cap.so", + }, + { + label: "Chat support", + sub: "Support via chat", + href: "https://discord.gg/y8gdQ3WRN3", + }, + ], + }, + { + label: "Pricing", + href: "/pricing", + }, + { + label: "About", + href: "/about", + }, + { + label: "Blog", + href: "/blog", + }, ]; const AuthLinks = [ - { - label: "Log In", - href: "/login", - }, + { + label: "Log In", + href: "/login", + }, ]; export const Navbar = () => { - const pathname = usePathname(); - const [showMobileMenu, setShowMobileMenu] = useState(false); - const auth = use(useAuthContext().user); + const pathname = usePathname(); + const [showMobileMenu, setShowMobileMenu] = useState(false); + const auth = use(useAuthContext().user); - return ( - <> -
- -
- {showMobileMenu && ( - - )} - - ); + return ( + <> +
+ +
+ {showMobileMenu && ( + + )} + + ); }; function LoginOrDashboard() { - const auth = use(useAuthContext().user); + const auth = use(useAuthContext().user); - return ( - - ); + return ( + + ); } diff --git a/apps/web/components/ReadyToGetStarted.tsx b/apps/web/components/ReadyToGetStarted.tsx index 822ac0723cf..0d4cecd06d6 100644 --- a/apps/web/components/ReadyToGetStarted.tsx +++ b/apps/web/components/ReadyToGetStarted.tsx @@ -1,55 +1,55 @@ "use client"; import { Button } from "@cap/ui"; -import { homepageCopy } from "../data/homepage-copy"; import Link from "next/link"; +import { homepageCopy } from "../data/homepage-copy"; export function ReadyToGetStarted() { - return ( -
-
-
-

- {homepageCopy.readyToGetStarted.title} -

-
-
- - -
-
-

- or,{" "} - - Switch from Loom - -

-
-
-
- ); + return ( +
+
+
+

+ {homepageCopy.readyToGetStarted.title} +

+
+
+ + +
+
+

+ or,{" "} + + Switch from Loom + +

+
+
+
+ ); }