From 0c6222dc30eaae72b1d514b50c2748e2118b36ac Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 13:37:09 +0530 Subject: [PATCH 01/82] add dummy pages --- .../(program onboarding)/layout.tsx | 13 +++++ .../program/(steps)/connect/page.tsx | 17 ++++++ .../onboarding/program/(steps)/layout.tsx | 18 +++++++ .../program/(steps)/overview/page.tsx | 4 ++ .../program/(steps)/partners/page.tsx | 3 ++ .../program/(steps)/program/page.tsx | 3 ++ .../program/(steps)/rewards/page.tsx | 3 ++ .../onboarding/program/(steps)/step-page.tsx | 52 +++++++++++++++++++ .../onboarding/program/page.tsx | 3 ++ 9 files changed, 116 insertions(+) create mode 100644 apps/web/app/app.dub.co/(program onboarding)/layout.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx diff --git a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx new file mode 100644 index 0000000000..1c041d81b9 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx @@ -0,0 +1,13 @@ +import Toolbar from "@/ui/layout/toolbar/toolbar"; +import { NewBackground } from "@/ui/shared/new-background"; +import { PropsWithChildren } from "react"; + +export default function Layout({ children }: PropsWithChildren) { + return ( + <> + + {children} + + + ); +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx new file mode 100644 index 0000000000..303d1e23b1 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx @@ -0,0 +1,17 @@ + +import { Users } from "@dub/ui/icons"; +import { StepPage } from "../step-page"; + + +export default function Connect() { + return ( + + {/*
*/} + + ); +} \ No newline at end of file diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx new file mode 100644 index 0000000000..ea3617fe21 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx @@ -0,0 +1,18 @@ +import { Wordmark } from "@dub/ui"; +import { PropsWithChildren } from "react"; + +export default function Layout({ children }: PropsWithChildren) { + return ( + <> +
+ {/*
+ +
*/} + +
+ {children} +
+
+ + ); +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx new file mode 100644 index 0000000000..70ac297f58 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx @@ -0,0 +1,4 @@ +export default async function ProgramOverview() { + return <>Overview; +} + diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx new file mode 100644 index 0000000000..62f7253f63 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx @@ -0,0 +1,3 @@ +export default async function ProgramPartners() { + return <>Partners; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx new file mode 100644 index 0000000000..9eb7871196 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx @@ -0,0 +1,3 @@ +export default async function Program() { + return <>Program; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx new file mode 100644 index 0000000000..6685b6907b --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx @@ -0,0 +1,3 @@ +export default async function ProgramNewRewards() { + return <>New Program Rewards; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx new file mode 100644 index 0000000000..f8401a4b92 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx @@ -0,0 +1,52 @@ +import { Icon } from "@dub/ui"; +import { cn } from "@dub/utils"; +import { Crown } from "lucide-react"; +import { PropsWithChildren, ReactNode } from "react"; + +export function StepPage({ + children, + icon: Icon, + title, + description, + paidPlanRequired, + className, +}: PropsWithChildren<{ + icon?: Icon; + title: ReactNode; + description: ReactNode; + paidPlanRequired?: boolean; + className?: string; +}>) { + return ( +
+ {Icon && } + {paidPlanRequired && ( +
+ + Paid plan required +
+ )} +

+ {title} +

+

+ {description} +

+
{children}
+
+ ); +} + +function StepIcon({ icon: Icon }: { icon: Icon }) { + return ( +
+ +
+ ); +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx new file mode 100644 index 0000000000..9eb7871196 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx @@ -0,0 +1,3 @@ +export default async function Program() { + return <>Program; +} From ec176f29b6c144cbbad38fb7aa3829baaf7523a5 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 13:43:07 +0530 Subject: [PATCH 02/82] add the layouts --- apps/web/app/app.dub.co/(program onboarding)/layout.tsx | 4 ++-- .../onboarding/program/(steps)/layout.tsx | 2 +- .../(program onboarding)/onboarding/program/(steps)/page.tsx | 3 +++ .../onboarding/program/(steps)/program/page.tsx | 3 --- .../(program onboarding)/onboarding/program/page.tsx | 3 --- 5 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx delete mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx delete mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx diff --git a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx index 1c041d81b9..803f8a2f2e 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx @@ -5,9 +5,9 @@ import { PropsWithChildren } from "react"; export default function Layout({ children }: PropsWithChildren) { return ( <> - + {/* */} {children} - + {/* */} ); } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx index ea3617fe21..51a5333410 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx @@ -8,7 +8,7 @@ export default function Layout({ children }: PropsWithChildren) { {/*
*/} - + {/* */}
{children}
diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx new file mode 100644 index 0000000000..51b5f00072 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx @@ -0,0 +1,3 @@ +export default async function GetStarted() { + return <>Get Started; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx deleted file mode 100644 index 9eb7871196..0000000000 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/program/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default async function Program() { - return <>Program; -} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx deleted file mode 100644 index 9eb7871196..0000000000 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default async function Program() { - return <>Program; -} From 17ce99e68a2212493952e95c8a56edbc0c81aa70 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 14:01:23 +0530 Subject: [PATCH 03/82] make sidebar responsive --- .../(program onboarding)/layout.tsx | 43 +++++-- .../program/(steps)/getting-started/page.tsx | 12 ++ .../onboarding/program/(steps)/layout.tsx | 15 +-- .../program/_components/sidebar.tsx | 107 ++++++++++++++++++ 4 files changed, 156 insertions(+), 21 deletions(-) create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx diff --git a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx index 803f8a2f2e..42dddad607 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx @@ -1,13 +1,38 @@ -import Toolbar from "@/ui/layout/toolbar/toolbar"; -import { NewBackground } from "@/ui/shared/new-background"; -import { PropsWithChildren } from "react"; +import { Button, Wordmark } from "@dub/ui"; +import Link from "next/link"; +import { PropsWithChildren, ReactNode } from "react"; +import { Sidebar } from "./onboarding/program/_components/sidebar"; -export default function Layout({ children }: PropsWithChildren) { +export default function Layout({ + children, + title = "Create partner program", +}: PropsWithChildren<{ + title?: ReactNode; +}>) { return ( - <> - {/* */} - {children} - {/* */} - +
+
+
+ + + +
+

{title}

+
+
+
+
+ +
+ +
{children}
+
+
); } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx new file mode 100644 index 0000000000..b9a6fa7f86 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx @@ -0,0 +1,12 @@ +import { StepPage } from "../step-page"; + +export default function GettingStarted() { + return ( + + {/* Form content will go here */} + + ); +} \ No newline at end of file diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx index 51a5333410..bdb34f0ad3 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/layout.tsx @@ -1,18 +1,9 @@ -import { Wordmark } from "@dub/ui"; import { PropsWithChildren } from "react"; export default function Layout({ children }: PropsWithChildren) { return ( - <> -
- {/*
- -
*/} - {/* */} -
- {children} -
-
- +
+ {children} +
); } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx new file mode 100644 index 0000000000..f54794188b --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { Menu, X } from "lucide-react"; +import { useMediaQuery } from "@dub/ui"; +import { cn } from "@dub/utils"; +import { useEffect, useState } from "react"; + +export function Sidebar() { + const [isOpen, setIsOpen] = useState(false); + const { isMobile } = useMediaQuery(); + + // Prevent body scroll when side nav is open + useEffect(() => { + document.body.style.overflow = isOpen && isMobile ? "hidden" : "auto"; + }, [isOpen, isMobile]); + + return ( + <> + {/* Mobile menu button */} + + + {/* Side nav backdrop */} +
{ + if (e.target === e.currentTarget) { + e.stopPropagation(); + setIsOpen(false); + } + }} + > + {/* Side nav */} +
+
+
+

Program Setup

+ +
+ +
+
+
+ + ); +} + +export function SidebarTrigger({ onClick }: { onClick: () => void }) { + return ( + + ); +} \ No newline at end of file From d6cd277c211692b3da805ad3017fe50f47d9f28e Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 14:13:17 +0530 Subject: [PATCH 04/82] fix layout and add page heading --- .../(program onboarding)/layout.tsx | 4 +-- .../program/(steps)/connect/page.tsx | 16 ++-------- .../program/(steps)/getting-started/page.tsx | 12 -------- .../program/(steps)/overview/page.tsx | 7 +++-- .../onboarding/program/(steps)/page.tsx | 4 ++- .../program/(steps)/partners/page.tsx | 6 ++-- .../program/(steps)/rewards/page.tsx | 6 ++-- .../onboarding/program/(steps)/step-page.tsx | 30 ++----------------- .../sidebar.tsx => (steps)/steps.tsx} | 2 +- 9 files changed, 22 insertions(+), 65 deletions(-) delete mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx rename apps/web/app/app.dub.co/(program onboarding)/onboarding/program/{_components/sidebar.tsx => (steps)/steps.tsx} (99%) diff --git a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx index 42dddad607..4ed252eb0e 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/layout.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/layout.tsx @@ -1,7 +1,7 @@ import { Button, Wordmark } from "@dub/ui"; import Link from "next/link"; import { PropsWithChildren, ReactNode } from "react"; -import { Sidebar } from "./onboarding/program/_components/sidebar"; +import { Steps } from "./onboarding/program/(steps)/steps"; export default function Layout({ children, @@ -30,7 +30,7 @@ export default function Layout({
- +
{children}
diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx index 303d1e23b1..9a450a9607 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/connect/page.tsx @@ -1,17 +1,5 @@ - -import { Users } from "@dub/ui/icons"; import { StepPage } from "../step-page"; - export default function Connect() { - return ( - - {/* */} - - ); -} \ No newline at end of file + return ; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx deleted file mode 100644 index b9a6fa7f86..0000000000 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/getting-started/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { StepPage } from "../step-page"; - -export default function GettingStarted() { - return ( - - {/* Form content will go here */} - - ); -} \ No newline at end of file diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx index 70ac297f58..83ed583ef8 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/overview/page.tsx @@ -1,4 +1,5 @@ -export default async function ProgramOverview() { - return <>Overview; -} +import { StepPage } from "../step-page"; +export default async function Overview() { + return ; +} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx index 51b5f00072..ca2343043b 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx @@ -1,3 +1,5 @@ +import { StepPage } from "./step-page"; + export default async function GetStarted() { - return <>Get Started; + return ; } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx index 62f7253f63..443e320c34 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/partners/page.tsx @@ -1,3 +1,5 @@ -export default async function ProgramPartners() { - return <>Partners; +import { StepPage } from "../step-page"; + +export default async function Partners() { + return ; } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx index 6685b6907b..569d4abec0 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/rewards/page.tsx @@ -1,3 +1,5 @@ -export default async function ProgramNewRewards() { - return <>New Program Rewards; +import { StepPage } from "../step-page"; + +export default async function Rewards() { + return ; } diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx index f8401a4b92..fd0f2553e1 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/step-page.tsx @@ -1,52 +1,26 @@ -import { Icon } from "@dub/ui"; import { cn } from "@dub/utils"; -import { Crown } from "lucide-react"; import { PropsWithChildren, ReactNode } from "react"; export function StepPage({ children, - icon: Icon, title, - description, - paidPlanRequired, className, }: PropsWithChildren<{ - icon?: Icon; title: ReactNode; - description: ReactNode; - paidPlanRequired?: boolean; className?: string; }>) { return (
- {Icon && } - {paidPlanRequired && ( -
- - Paid plan required -
- )} -

+

{title}

-

- {description} -

{children}
); } - -function StepIcon({ icon: Icon }: { icon: Icon }) { - return ( -
- -
- ); -} diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/steps.tsx similarity index 99% rename from apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx rename to apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/steps.tsx index f54794188b..2c0fb51a3e 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/_components/sidebar.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/steps.tsx @@ -5,7 +5,7 @@ import { useMediaQuery } from "@dub/ui"; import { cn } from "@dub/utils"; import { useEffect, useState } from "react"; -export function Sidebar() { +export function Steps() { const [isOpen, setIsOpen] = useState(false); const { isMobile } = useMediaQuery(); From 2f4daa617d6067dace046ca1e2b6db88baceefca Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 14:23:11 +0530 Subject: [PATCH 05/82] Update page.tsx --- .../(program onboarding)/onboarding/program/(steps)/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx index ca2343043b..f1397027ba 100644 --- a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page.tsx @@ -1,5 +1,5 @@ import { StepPage } from "./step-page"; export default async function GetStarted() { - return ; + return Hell; } From 676ce4dfb1b990a7ffa68a00c40bdfb62b857fd9 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 14:46:02 +0530 Subject: [PATCH 06/82] wip getting started page --- .../program/(steps)/page-client.tsx | 125 ++++++++++++++++++ .../onboarding/program/(steps)/page.tsx | 7 +- .../onboarding/program/(steps)/step-page.tsx | 2 +- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page-client.tsx diff --git a/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page-client.tsx b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page-client.tsx new file mode 100644 index 0000000000..aede48ecd2 --- /dev/null +++ b/apps/web/app/app.dub.co/(program onboarding)/onboarding/program/(steps)/page-client.tsx @@ -0,0 +1,125 @@ +"use client"; + +import useDomains from "@/lib/swr/use-domains"; +import { Button, Input, Switch, useMediaQuery } from "@dub/ui"; +import { cn } from "@dub/utils"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +const gettingStartedSchema = z.object({ + name: z.string().min(1, "Program name is required"), + logo: z.string().min(1, "Logo is required"), + defaultDomain: z.string().min(1, "Default domain is required"), + destinationUrl: z + .string() + .url("Invalid URL") + .min(1, "Destination URL is required"), + allowCustomLinks: z.boolean().default(false), +}); + +type GettingStartedFormData = z.infer; + +export function GettingStarted() { + const { isMobile } = useMediaQuery(); + + const { activeWorkspaceDomains, loading, error } = useDomains(); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = useForm({ + resolver: zodResolver(gettingStartedSchema), + }); + + const onSubmit = async (data: GettingStartedFormData) => { + console.log(data); + // TODO: Handle form submission + }; + + return ( + +
+ + + {errors.name && ( +

{errors.name.message}

+ )} +
+ + {/*
+ + + {errors.logo && ( +

{errors.logo.message}

+ )} +
*/} + +
+
+

+ Referral Link +

+

+ Set the default referral link domain and destination URL +

+
+ +
+ + {loading ? ( +
+ Loading... +
+ ) : ( + + )} +
+
+ +
+
+ + +
+
+ + - {/* Side nav backdrop */}
- {/* Side nav */}

Program Setup

- ); -} \ No newline at end of file +} From b8c0e7a754ae61fa23ea85ec622b6f5e2e76dfce Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 15:56:50 +0530 Subject: [PATCH 09/82] add get started page --- apps/web/app/api/domains/route.ts | 16 +- .../onboarding/(steps)/connect/page.tsx | 2 +- .../onboarding/(steps)/new/page-client.tsx | 213 ++++++++++++++++++ .../onboarding/(steps)/{ => new}/page.tsx | 4 +- .../onboarding/(steps)/overview/page.tsx | 2 +- .../onboarding/(steps)/page-client.tsx | 125 ---------- .../onboarding/(steps)/partners/page.tsx | 2 +- .../onboarding/(steps)/rewards/page.tsx | 2 +- .../onboarding/(steps)/step-page.tsx | 2 +- 9 files changed, 228 insertions(+), 140 deletions(-) create mode 100644 apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/new/page-client.tsx rename apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/{ => new}/page.tsx (63%) delete mode 100644 apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/page-client.tsx diff --git a/apps/web/app/api/domains/route.ts b/apps/web/app/api/domains/route.ts index 18df9f0575..84601db00e 100644 --- a/apps/web/app/api/domains/route.ts +++ b/apps/web/app/api/domains/route.ts @@ -124,14 +124,14 @@ export const POST = withWorkspace( }); } - const vercelResponse = await addDomainToVercel(slug); - - if ( - vercelResponse.error && - vercelResponse.error.code !== "domain_already_in_use" // ignore this error - ) { - return new Response(vercelResponse.error.message, { status: 422 }); - } + // const vercelResponse = await addDomainToVercel(slug); + + // if ( + // vercelResponse.error && + // vercelResponse.error.code !== "domain_already_in_use" // ignore this error + // ) { + // return new Response(vercelResponse.error.message, { status: 422 }); + // } const domainId = createId({ prefix: "dom_" }); diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/connect/page.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/connect/page.tsx index 9a450a9607..9b04cabfd8 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/connect/page.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/connect/page.tsx @@ -1,5 +1,5 @@ import { StepPage } from "../step-page"; -export default function Connect() { +export default async function Page() { return ; } diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/new/page-client.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/new/page-client.tsx new file mode 100644 index 0000000000..3d9459d4bc --- /dev/null +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/new/page-client.tsx @@ -0,0 +1,213 @@ +"use client"; + +import useDomains from "@/lib/swr/use-domains"; +import { Badge, Button, CircleCheckFill, Input, useMediaQuery } from "@dub/ui"; +import { cn } from "@dub/utils"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +const formSchema = z.object({ + name: z.string().min(1, "Program name is required"), + logo: z.string().min(1, "Logo is required"), + domain: z.string().min(1, "Enter the program's default domain"), + url: z + .string() + .url("Enter a valid URL") + .min(1, "Enter the program's destination URL"), + allowCustomLinks: z.boolean().default(false), + linkType: z.enum(["short", "query", "dynamic"]).default("short"), +}); + +type GettingStartedFormData = z.infer; + +const LINK_TYPES = [ + { + value: "short", + label: "Short link", + preview: "refer.dub.co/steven", + disabled: false, + }, + { + value: "query", + label: "Query parameter", + preview: "dub.co/?via=steven", + disabled: false, + }, + { + value: "dynamic", + label: "Dynamic path", + preview: "dub.co/refer/steven", + disabled: true, + badge: "Coming soon", + }, +]; + +export function GettingStarted() { + const { isMobile } = useMediaQuery(); + const { activeWorkspaceDomains, loading } = useDomains(); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting, isValid }, + watch, + } = useForm({ + defaultValues: { + linkType: "short", + }, + mode: "onChange", + }); + + const onSubmit = async (data: GettingStartedFormData) => { + console.log(data); + // TODO: Handle form submission + }; + + return ( +
+
+ + +
+ + {/*
+ + + {errors.logo && ( +

{errors.logo.message}

+ )} +
*/} + +
+
+

+ Referral Link +

+

+ Set the default referral link domain and destination URL +

+
+ +
+ + {loading ? ( +
+ ) : ( + + )} +
+ +
+ + +
+
+ +
+
+

+ Link structure +

+

+ Set how the link shows up in the partner portal +

+
+ +
+ {LINK_TYPES.map((type) => { + const isSelected = watch("linkType") === type.value; + + return ( + + ); + })} +
+
+ +
+ )} +
+
+
+ ))} + +
+ +
+ + + -
- {COMMISSION_TYPES.map(({ value, label, description }) => { - const isSelected = (value === "recurring") === isRecurring; +
+ + +
+ Find your Rewardful API secret on your{" "} + + Company settings page + +
+
- return ( -
+ + {selectedCampaign && ( +
+
+
Type
+
Flat
+
+
+
Duration
+
24 months
+
+
+
Commission
+
$50.00
+
+
+
Affiliates
+
12
+
+
+ )} + + ) : ( +
+
+

+ Commission structure +

+

+ Set how the affiliate will get rewarded +

+
+ +
+ {COMMISSION_TYPES.map(({ value, label, description }) => { + const isSelected = (value === "recurring") === isRecurring; + + return ( + + ); + })} +
+ + {isRecurring && ( +
+ - ); - })} + +
+ )}
- - {isRecurring && ( -
- - -
- )} - + )}
From ba36d73031887e35f480e626c2f755c482baa41c Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:13:26 +0530 Subject: [PATCH 19/82] Update form.tsx --- .../onboarding/(steps)/rewards/form.tsx | 343 ++++++++++-------- 1 file changed, 182 insertions(+), 161 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx index a60c9b3d28..0fae0d5a06 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx @@ -3,7 +3,6 @@ import { handleMoneyInputChange, handleMoneyKeyDown } from "@/lib/form-utils"; import { COMMISSION_TYPES, - createOrUpdateRewardSchema, RECURRING_MAX_DURATIONS, } from "@/lib/zod/schemas/rewards"; import { Button, CircleCheckFill, Input } from "@dub/ui"; @@ -11,7 +10,7 @@ import { cn } from "@dub/utils"; import { ChevronDown } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; -import { useForm } from "react-hook-form"; +import { useForm, UseFormRegister, UseFormWatch } from "react-hook-form"; import { z } from "zod"; const formSchema = z.object({ @@ -26,6 +25,11 @@ const formSchema = z.object({ type Form = z.infer; +type FormProps = { + register: UseFormRegister; + watch: UseFormWatch; +}; + const PROGRAM_TYPES = [ { value: "new", @@ -40,7 +44,6 @@ const PROGRAM_TYPES = [ ] as const; export function Form() { - const [isRecurring, setIsRecurring] = useState(false); const { register, handleSubmit, @@ -55,15 +58,12 @@ export function Form() { }); const programType = watch("programType"); - const selectedCampaign = watch("campaignId"); const onSubmit = async (data: Form) => { console.log(data); // TODO: Handle form submission }; - const type = watch("type"); - return (
@@ -113,163 +113,106 @@ export function Form() {
{programType === "import" ? ( - <> -
- -
- - -
- -
+ + ) : ( + + )} -
- - -
- Find your Rewardful API secret on your{" "} - - Company settings page - -
-
+ -
+function NewProgramForm({ register, watch }: FormProps) { + const [isRecurring, setIsRecurring] = useState(false); + const type = watch("type"); - {selectedCampaign && ( -
-
-
Type
-
Flat
-
-
-
Duration
-
24 months
-
-
-
Commission
-
$50.00
-
-
-
Affiliates
-
12
-
-
- )} - - ) : ( -
-
-

- Commission structure -

-

- Set how the affiliate will get rewarded -

-
+ return ( + <> +
+
+

+ Commission structure +

+

+ Set how the affiliate will get rewarded +

+
-
- {COMMISSION_TYPES.map(({ value, label, description }) => { - const isSelected = (value === "recurring") === isRecurring; +
+ {COMMISSION_TYPES.map(({ value, label, description }) => { + const isSelected = (value === "recurring") === isRecurring; - return ( - - ); - })} -
- - {isRecurring && ( -
- - -
- )} + ); + })}
- )} + + {isRecurring && ( +
+ + +
+ )} +
@@ -318,13 +261,91 @@ export function Form() {
+ + ); +} - +
+ +
+ + +
+ Find your Rewardful API secret on your{" "} + + Company settings page + +
+
+ +
+ +
+ + +
+ +
+ + {selectedCampaign && ( +
+
+
Type
+
Flat
+
+
+
Duration
+
+ 24 months +
+
+
+
Commission
+
$50.00
+
+
+
Affiliates
+
12
+
+
+ )} + ); } From e2fc79302ca110c0bef2b1d5e1d5e129a80c83c3 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:27:33 +0530 Subject: [PATCH 20/82] Update form.tsx --- .../onboarding/(steps)/rewards/form.tsx | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx index 0fae0d5a06..c2d071544c 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/rewards/form.tsx @@ -128,8 +128,9 @@ export function Form() { ); } -function NewProgramForm({ register, watch }: FormProps) { +const NewProgramForm = ({ register, watch }: FormProps) => { const [isRecurring, setIsRecurring] = useState(false); + const type = watch("type"); return ( @@ -263,13 +264,13 @@ function NewProgramForm({ register, watch }: FormProps) { ); -} +}; -function ImportProgramForm({ register, watch }: FormProps) { - const selectedCampaign = watch("campaignId"); +const ImportProgramForm = ({ register, watch }: FormProps) => { + const selectedCampaignId = watch("campaignId"); return ( - <> +
- +
@@ -296,11 +302,16 @@ function ImportProgramForm({ register, watch }: FormProps) { {...register("apiToken")} type="password" placeholder="API token" - className="mt-2" + className="mt-2 max-w-full" /> -
+
Find your Rewardful API secret on your{" "} - + Company settings page
@@ -319,33 +330,38 @@ function ImportProgramForm({ register, watch }: FormProps) {
- +
- {selectedCampaign && ( -
+ {selectedCampaignId && ( +
-
Type
-
Flat
+
Type
+
Flat
-
Duration
-
+
Duration
+
24 months
-
Commission
-
$50.00
+
Commission
+
$50.00
-
Affiliates
-
12
+
Affiliates
+
12
)} - +
); -} +}; From 0f33fa470b68d830f0de2a703c671ed0115b9651 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:40:31 +0530 Subject: [PATCH 21/82] add import rewardful import --- .../onboarding/(steps)/partners/form.tsx | 158 ++++++++++-------- 1 file changed, 91 insertions(+), 67 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/partners/form.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/partners/form.tsx index ab2431abca..f5c805424a 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/partners/form.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/partners/form.tsx @@ -1,6 +1,6 @@ "use client"; -import { Button, Input } from "@dub/ui"; +import { Button, CircleCheckFill, Input } from "@dub/ui"; import { cn } from "@dub/utils"; import { Plus, Trash2 } from "lucide-react"; import { useFieldArray, useForm } from "react-hook-form"; @@ -43,79 +43,103 @@ export function Form() { }; return ( -
-
- {fields.map((field, index) => ( -
-
- - +
+
+

+ Invite new partners in addition to those being imported. +

+ +
+
+
+
+ + Affiliates importing + +
+ 12 +
+
+ + +
+ {fields.map((field, index) => ( +
+
+ + +
-
- -
- + + + + {index > 0 && ( +
-
- ))} + ))} + +
- -
); } From 2cbec5a0d9c3bcb44ae342e78d3fe313ce058242 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:46:02 +0530 Subject: [PATCH 22/82] Update steps.tsx --- .../(onboarding)/onboarding/(steps)/steps.tsx | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx index 8a83b4d27a..1800f05b84 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx @@ -3,16 +3,47 @@ import { useMediaQuery } from "@dub/ui"; import { cn } from "@dub/utils"; import { Menu, X } from "lucide-react"; +import Link from "next/link"; +import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; export function Steps() { - const [isOpen, setIsOpen] = useState(false); const { isMobile } = useMediaQuery(); + const [isOpen, setIsOpen] = useState(false); + const { slug } = useParams<{ slug: string }>(); useEffect(() => { document.body.style.overflow = isOpen && isMobile ? "hidden" : "auto"; }, [isOpen, isMobile]); + const steps = [ + { + step: 1, + label: "Getting started", + href: `/${slug}/programs/onboarding/new`, + }, + { + step: 2, + label: "Configure reward", + href: `/${slug}/programs/onboarding/rewards`, + }, + { + step: 3, + label: "Invite partners", + href: `/${slug}/programs/onboarding/partners`, + }, + { + step: 4, + label: "Connect Dub", + href: `/${slug}/programs/onboarding/connect`, + }, + { + step: 5, + label: "Overview", + href: `/${slug}/programs/onboarding/overview`, + }, + ]; + return ( <>
@@ -90,14 +103,3 @@ export function Steps() { ); } - -export function SidebarTrigger({ onClick }: { onClick: () => void }) { - return ( - - ); -} From ab3151308b1e1bd48b1c976bf30a286af70bf0d5 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:48:30 +0530 Subject: [PATCH 23/82] Update steps.tsx --- .../programs/(onboarding)/onboarding/(steps)/steps.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx index 1800f05b84..c7ea24641a 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx @@ -88,12 +88,14 @@ export function Steps() {
{step}
- {label} + + {label} + ))} From c9ce12b510a040c1eaa5d24e8b9fb32a51e3c38b Mon Sep 17 00:00:00 2001 From: Kiran K Date: Thu, 20 Feb 2025 19:52:25 +0530 Subject: [PATCH 24/82] Update steps.tsx --- .../(onboarding)/onboarding/(steps)/steps.tsx | 67 ++++++++++++++----- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx index c7ea24641a..661cd861f0 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/programs/(onboarding)/onboarding/(steps)/steps.tsx @@ -2,15 +2,16 @@ import { useMediaQuery } from "@dub/ui"; import { cn } from "@dub/utils"; -import { Menu, X } from "lucide-react"; +import { Check, Lock, Menu, X } from "lucide-react"; import Link from "next/link"; -import { useParams } from "next/navigation"; +import { useParams, usePathname } from "next/navigation"; import { useEffect, useState } from "react"; export function Steps() { const { isMobile } = useMediaQuery(); const [isOpen, setIsOpen] = useState(false); const { slug } = useParams<{ slug: string }>(); + const pathname = usePathname(); useEffect(() => { document.body.style.overflow = isOpen && isMobile ? "hidden" : "auto"; @@ -41,9 +42,12 @@ export function Steps() { step: 5, label: "Overview", href: `/${slug}/programs/onboarding/overview`, + isLocked: true, }, ]; + const currentStep = steps.find((s) => s.href === pathname)?.step || 1; + return ( <>