Skip to content

Commit

Permalink
User Onboarding Flow (#90)
Browse files Browse the repository at this point in the history
* feat: add onboarding dialog skeleton

* feat: add basic onboarding flow

* feat: change onboarding flow order sequence

* chore: format

* chore: add isloading to return null branch

* feat: order by created at prayge

* feat: add a reusuable onboarding wrapper

* feat: add cooped field

* feat: add post onboarding dialogs

* feat: add jank af (pls destroy this code when reviewing) post onboarding dialog

* chore: remove unused logo

* docs: add basic jsdocs

* refactor: rename variables and add dialog title

* chore: also do onboarding flow on the homepage

* chore: remove that last change don't need it cause it stacks?

* feat: graduation year is current + 6

* feat: switch out png for svg

* Reworking Onboarding

* Change 'Cooped' Radio Buttons

* I still got it

* Don't need user router anymore (wasn't working anyways)

* Lint + Types

* fix: prevent rerender by disabling refetching

* Fix Styles + Change Border Radius to lg to match new designs

---------

Co-authored-by: banushi-a <[email protected]>
  • Loading branch information
RishikeshNK and banushi-a authored Feb 4, 2025
1 parent 0d51964 commit 8683211
Show file tree
Hide file tree
Showing 14 changed files with 564 additions and 6 deletions.
28 changes: 28 additions & 0 deletions apps/web/public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions apps/web/src/app/(pages)/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Toaster } from "@cooper/ui/toaster";

import HeaderLayout from "~/app/_components/header-layout";
import OnboardingWrapper from "~/app/_components/onboarding/onboarding-wrapper";

export default function RootLayout({
children,
Expand All @@ -9,8 +10,10 @@ export default function RootLayout({
}) {
return (
<HeaderLayout>
{children}
<Toaster />
<OnboardingWrapper>
{children}
<Toaster />
</OnboardingWrapper>
</HeaderLayout>
);
}
21 changes: 21 additions & 0 deletions apps/web/src/app/_components/onboarding/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const monthOptions = [
{ value: "1", label: "January" },
{ value: "2", label: "February" },
{ value: "3", label: "March" },
{ value: "4", label: "April" },
{ value: "5", label: "May" },
{ value: "6", label: "June" },
{ value: "7", label: "July" },
{ value: "8", label: "August" },
{ value: "9", label: "September" },
{ value: "10", label: "October" },
{ value: "11", label: "November" },
{ value: "12", label: "December" },
];

export const majors = [
"Computer Science",
"Computer Science + Math",
"Computer Science + Business",
"Computer Science + Design",
];
57 changes: 57 additions & 0 deletions apps/web/src/app/_components/onboarding/dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use client";

import { useState } from "react";

import type { Session } from "@cooper/auth";
import { Dialog, DialogContent } from "@cooper/ui/dialog";

import { OnboardingForm } from "~/app/_components/onboarding/onboarding-form";
import { api } from "~/trpc/react";

interface OnboardingDialogProps {
isOpen?: boolean;
session: Session | null;
}

/**
* OnboardingDialog component that handles user onboarding.
* Implementation note: Use OnboardingWrapper to wrap the component and initiate the dialog.
* @param isOpen - Whether the dialog is open
* @param session - The current user session
* @returns The OnboardingDialog component or null
*/
export function OnboardingDialog({
isOpen = true,
session,
}: OnboardingDialogProps) {
const [open, setOpen] = useState<boolean>(isOpen);

const profile = api.profile.getCurrentUser.useQuery(undefined, {
refetchOnWindowFocus: false,
});

const shouldShowOnboarding = session && !profile.data;

const closeDialog = () => {
setOpen(false);
};

if (profile.isPending || !shouldShowOnboarding) {
return null;
}

return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent
className="max-h-[90dvh] max-w-[85dvw] overflow-y-scroll rounded-lg p-8 md:max-w-[70dvw] lg:max-w-[46rem] lg:p-12"
aria-describedby="The form to create a Cooper profile once you have logged in with a husky google account."
>
<OnboardingForm
userId={session.user.id}
closeDialog={closeDialog}
session={session}
/>
</DialogContent>
</Dialog>
);
}
Loading

0 comments on commit 8683211

Please sign in to comment.