Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Program onboarding flow #2054

Draft
wants to merge 88 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
0c6222d
add dummy pages
devkiran Feb 20, 2025
ec176f2
add the layouts
devkiran Feb 20, 2025
17ce99e
make sidebar responsive
devkiran Feb 20, 2025
d6cd277
fix layout and add page heading
devkiran Feb 20, 2025
2f4daa6
Update page.tsx
devkiran Feb 20, 2025
676ce4d
wip getting started page
devkiran Feb 20, 2025
7545f6e
move to new location within workspace path
devkiran Feb 20, 2025
0fd4871
adjust the layout arrangment
devkiran Feb 20, 2025
b8c0e7a
add get started page
devkiran Feb 20, 2025
df2abb0
rename files
devkiran Feb 20, 2025
2803bb4
configure reward page
devkiran Feb 20, 2025
a4be43f
invite partner page
devkiran Feb 20, 2025
11ce8e6
Update form.tsx
devkiran Feb 20, 2025
1351220
add form to remaining pages
devkiran Feb 20, 2025
3e721e0
add Connecting Dub page
devkiran Feb 20, 2025
729e07b
add overview page
devkiran Feb 20, 2025
27d58db
Update route.ts
devkiran Feb 20, 2025
2ac6e46
Update form.tsx
devkiran Feb 20, 2025
ba36d73
Update form.tsx
devkiran Feb 20, 2025
e2fc793
Update form.tsx
devkiran Feb 20, 2025
0f33fa4
add import rewardful import
devkiran Feb 20, 2025
2cbec5a
Update steps.tsx
devkiran Feb 20, 2025
ab31513
Update steps.tsx
devkiran Feb 20, 2025
c9ce12b
Update steps.tsx
devkiran Feb 20, 2025
7335f0b
add server actions to save the progress
devkiran Feb 20, 2025
b042a88
Update steps.tsx
devkiran Feb 20, 2025
fdbb1e3
move to right route group for the layout to work
devkiran Feb 20, 2025
436e0c9
use useWorkspaceStore
devkiran Feb 20, 2025
002604b
Merge branch 'main' into program-onboarding
steven-tey Feb 20, 2025
b8ed04b
Merge branch 'main' into program-onboarding
steven-tey Feb 21, 2025
55abb71
fix the zod schema
devkiran Feb 21, 2025
222bae6
save the reward settings wip
devkiran Feb 21, 2025
eb9a42d
Update form.tsx
devkiran Feb 21, 2025
c2aba1c
display the rewardful campaigns
devkiran Feb 21, 2025
594d8ca
Merge branch 'program-onboarding' of https://github.com/dubinc/dub in…
devkiran Feb 21, 2025
28500e3
Update form.tsx
devkiran Feb 21, 2025
e49dc47
Update form.tsx
devkiran Feb 21, 2025
3d12255
Update form.tsx
devkiran Feb 21, 2025
8ba40fc
Update form.tsx
devkiran Feb 21, 2025
c355c59
Update form.tsx
devkiran Feb 21, 2025
ce9c186
rearrange the form for invite partners
devkiran Feb 21, 2025
a4be119
invite partners
devkiran Feb 21, 2025
cdd2d57
Update form.tsx
devkiran Feb 21, 2025
cc3e271
display existing partners if any
devkiran Feb 21, 2025
6d5d4e0
connect dub guide
devkiran Feb 21, 2025
f6eda48
create program wip
devkiran Feb 21, 2025
ffaafd1
wip create program
devkiran Feb 21, 2025
898725c
Update form.tsx
devkiran Feb 21, 2025
5b2978f
Update form.tsx
devkiran Feb 21, 2025
709d92b
create program action
devkiran Feb 21, 2025
a6b82c4
create program
devkiran Feb 21, 2025
6d84aff
add program welcome modal
devkiran Feb 21, 2025
2ed0fba
Update sidebar-nav.tsx
devkiran Feb 21, 2025
004b67a
add create program card
devkiran Feb 21, 2025
deffab4
simplify the path
devkiran Feb 21, 2025
53cf80c
Update form.tsx
devkiran Feb 21, 2025
86e829a
Update program-welcome-modal.tsx
devkiran Feb 21, 2025
73a19c0
Update create-program-card.tsx
devkiran Feb 21, 2025
8a4a26e
add upload logo
devkiran Feb 21, 2025
d6113a6
invite partners
devkiran Feb 21, 2025
5958334
Merge branch 'main' into program-onboarding
devkiran Feb 22, 2025
aa772f3
Update layout.tsx
devkiran Feb 22, 2025
17e45cf
Update steps.tsx
devkiran Feb 22, 2025
9c863c4
use the InputSelect for select dropdown
devkiran Feb 22, 2025
ecbaa86
Update form.tsx
devkiran Feb 22, 2025
98d85f7
add header
devkiran Feb 22, 2025
eb4f1ef
implement save and exit
devkiran Feb 22, 2025
c53b93f
Merge branch 'main' into program-onboarding
steven-tey Feb 22, 2025
8d2b2bf
wip
devkiran Feb 22, 2025
3cfe606
improve the form handling
devkiran Feb 22, 2025
1522622
set the rewardful token for campaign fetch
devkiran Feb 22, 2025
dd9d10c
form improvements
devkiran Feb 22, 2025
64f740b
Merge branch 'program-onboarding' of https://github.com/dubinc/dub in…
devkiran Feb 22, 2025
5734361
Update form.tsx
devkiran Feb 22, 2025
ffc4612
Update step-page.tsx
devkiran Feb 22, 2025
7593324
fix partners rendering
devkiran Feb 22, 2025
05e0ae9
Update form.tsx
devkiran Feb 22, 2025
2a0fe90
Update form.tsx
devkiran Feb 22, 2025
2ba7322
Update form.tsx
devkiran Feb 22, 2025
d557b8f
final step
devkiran Feb 22, 2025
2ac1136
Update header.tsx
devkiran Feb 22, 2025
5ef5aad
cleanup
devkiran Feb 22, 2025
d4a6015
prevent accessing page
devkiran Feb 22, 2025
9742df0
Update header.tsx
devkiran Feb 22, 2025
0e9c407
Update route.ts
devkiran Feb 22, 2025
4c5f88f
fix import
devkiran Feb 22, 2025
3f048ca
Refactor Rewardful integration and remove waitUntil
devkiran Feb 22, 2025
bd6f5a5
Update onboard-program.ts
devkiran Feb 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/app/api/mock/rewardful/campaigns/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function GET() {
visitors: 150,
leads: 39,
conversions: 7,
affiliates: 12,
affiliates: 45,
},
];

Expand Down
21 changes: 0 additions & 21 deletions apps/web/app/api/programs/[programId]/rewardful/campaigns/route.ts

This file was deleted.

20 changes: 20 additions & 0 deletions apps/web/app/api/programs/rewardful/campaigns/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { DubApiError } from "@/lib/api/errors";
import { withWorkspace } from "@/lib/auth";
import { RewardfulApi } from "@/lib/rewardful/api";
import { rewardfulImporter } from "@/lib/rewardful/importer";
import { NextResponse } from "next/server";

// GET /api/programs/rewardful/campaigns - list rewardful campaigns
export const GET = withWorkspace(async ({ workspace }) => {
if (!workspace.partnersEnabled) {
throw new DubApiError({
code: "forbidden",
message: "Partners are not enabled for this workspace",
});
}

const { token } = await rewardfulImporter.getCredentials(workspace.id);
const rewardfulApi = new RewardfulApi({ token });

return NextResponse.json(await rewardfulApi.listCampaigns());
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import RootProviders from "app/providers";
import { FormWrapper } from "./new/form-wrapper";
import { Header } from "./new/header";
import { Steps } from "./new/steps";

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<RootProviders>
<FormWrapper>
<div className="min-h-screen bg-white">
<Header />
<div className="md:grid md:grid-cols-[240px_minmax(0,1fr)]">
<Steps />
<main className="px-4 py-6 md:px-8">{children}</main>
</div>
</div>
</FormWrapper>
</RootProviders>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"use client";

import useWorkspace from "@/lib/swr/use-workspace";
import { Shopify } from "@/ui/layout/sidebar/conversions/icons/shopify";
import { Stripe } from "@/ui/layout/sidebar/conversions/icons/stripe";
import { Button } from "@dub/ui";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";

const GUIDES = [
{
name: "Connecting to Stripe",
icon: Stripe,
href: "https://d.to/stripe",
},
{
name: "Connecting to Shopify",
icon: Shopify,
href: "https://d.to/shopify",
},
] as const;

export function Form() {
const router = useRouter();
const [isPending, setIsPending] = useState(false);
const { id: workspaceId, slug: workspaceSlug } = useWorkspace();

const onClick = async () => {
if (!workspaceId) return;
setIsPending(true);
router.push(`/${workspaceSlug}/programs/new/overview`);
};

return (
<div className="space-y-10">
<div className="space-y-6">
<p className="text-sm text-neutral-600">
Ensuring your program is connect is simple, select the best guide that
suits your connection setup or something else.
</p>

<div className="flex flex-col gap-4">
{GUIDES.map(({ name, icon: Icon, href }) => (
<div
key={name}
className="flex items-center justify-between rounded-lg border border-neutral-200 bg-neutral-50 p-4"
>
<div className="flex items-center gap-3">
<Icon className="size-8" />
<span className="text-sm font-medium text-neutral-900">
{name}
</span>
</div>
<Link href={href} target="_blank" rel="noopener noreferrer">
<Button
type="button"
text="Read guide"
variant="secondary"
className="h-8 w-fit px-3"
/>
</Link>
</div>
))}
</div>
</div>

<Button
text="Continue"
className="w-full"
loading={isPending}
type="button"
onClick={onClick}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { StepPage } from "../step-page";
import { Form } from "./form";

export default async function Page() {
return (
<StepPage title="Connecting Dub">
<Form />
</StepPage>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";

import { useWorkspaceStore } from "@/lib/swr/use-workspace-store";
import { ProgramData } from "@/lib/zod/schemas/program-onboarding";
import { FormProvider, useForm } from "react-hook-form";

export function FormWrapper({ children }: { children: React.ReactNode }) {
const [programOnboarding] =
useWorkspaceStore<ProgramData>("programOnboarding");

const methods = useForm<ProgramData>({
defaultValues: {
...programOnboarding,
linkType: programOnboarding?.linkType ?? "short",
programType: programOnboarding?.programType ?? "new",
type: programOnboarding?.type ?? "flat",
amount: programOnboarding?.amount ?? null,
partners: programOnboarding?.partners?.length
? programOnboarding.partners
: [{ email: "", key: "" }],
},
});

return <FormProvider {...methods}>{children}</FormProvider>;
}
Loading
Loading