Skip to content

Commit

Permalink
feat(dashboard): switch to synchronous onboarding flow (#1173)
Browse files Browse the repository at this point in the history
  • Loading branch information
IGassmann committed Feb 27, 2024
1 parent d343969 commit 1a3fd83
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 134 deletions.
33 changes: 33 additions & 0 deletions ui/apps/dashboard/src/app/(auth)/ReloadClerkAndRedirect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use client';

import { useEffect } from 'react';
import { useUser } from '@clerk/nextjs';

import LoadingIcon from '@/icons/LoadingIcon';

type ReloadClerkAndRedirectProps = {
redirectURL: string;
};

/**
* This is used to reload Clerk on the client before redirecting to a new page. This is needed when
* we update some Clerk data on the server and need to ensure that the client has the latest data
* before redirecting.
*
* @param {string} redirectURL - The URL to redirect to after reloading Clerk
*/
export default function ReloadClerkAndRedirect({ redirectURL }: ReloadClerkAndRedirectProps) {
const { user } = useUser();

useEffect(() => {
user?.reload().then(() => {
window.location.href = redirectURL;
});
}, [user, redirectURL]);

return (
<div className="flex h-full w-full items-center justify-center">
<LoadingIcon />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function CreateOrganizationPage() {
return (
<SplitView>
<div className="mx-auto my-auto text-center">
<CreateOrganization afterCreateOrganizationUrl={process.env.NEXT_PUBLIC_HOME_PATH} />
<CreateOrganization afterCreateOrganizationUrl="/create-organization/set-up" />
</div>
</SplitView>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import { useEffect } from 'react';
import { ExclamationCircleIcon } from '@heroicons/react/20/solid';
import { Button } from '@inngest/components/Button';
import * as Sentry from '@sentry/nextjs';

type OrganizationSetupErrorProps = {
error: Error & { digest?: string };
reset: () => void;
};

export default function OrganizationSetupError({ error }: OrganizationSetupErrorProps) {
useEffect(() => {
Sentry.captureException(new Error('Failed to set up organization', { cause: error }));
}, [error]);

return (
<div className="flex h-full w-full flex-col items-center justify-center gap-5">
<div className="inline-flex items-center gap-2 text-red-600">
<ExclamationCircleIcon className="h-4 w-4" />
<h2 className="text-sm">Failed to set up your organization</h2>
</div>
<Button label="Contact Support" appearance="outlined" href="/support" />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import LoadingIcon from '@/icons/LoadingIcon';

export default function OrganizationSetupLoading() {
return (
<div className="flex h-full w-full items-center justify-center">
<LoadingIcon />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import ReloadClerkAndRedirect from '@/app/(auth)/ReloadClerkAndRedirect';
import { graphql } from '@/gql';
import graphqlAPI from '@/queries/graphqlAPI';

const SetUpAccountDocument = graphql(`
mutation SetUpAccount {
setUpAccount {
account {
id
}
}
}
`);

export default async function OrganizationSetupPage() {
await graphqlAPI.request(SetUpAccountDocument);
return <ReloadClerkAndRedirect redirectURL="/env/production/apps" />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default async function OrganizationListPage({ searchParams }: Organizatio
<div className="mx-auto my-auto text-center">
<OrganizationList
hidePersonal={true}
afterCreateOrganizationUrl="/sign-up/account-setup"
afterCreateOrganizationUrl="/create-organization/set-up"
afterSelectOrganizationUrl={redirectURL}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export default async function SignUpPage() {
<SplitView>
<div className="mx-auto my-8 mt-auto text-center">
<SignUp
afterSignUpUrl="/organization-list"
unsafeMetadata={{
...(anonymousIDCookie?.value && { anonymousID: anonymousIDCookie.value }),
}}
Expand Down
108 changes: 0 additions & 108 deletions ui/apps/dashboard/src/app/(auth)/sign-up/account-setup/page.tsx

This file was deleted.

38 changes: 38 additions & 0 deletions ui/apps/dashboard/src/app/(auth)/sign-up/set-up/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@clerk/nextjs';
import { ExclamationCircleIcon } from '@heroicons/react/20/solid';
import { Button } from '@inngest/components/Button';
import * as Sentry from '@sentry/nextjs';

type UserSetupErrorProps = {
error: Error & { digest?: string };
reset: () => void;
};

export default function UserSetupError({ error }: UserSetupErrorProps) {
const { signOut } = useAuth();
const router = useRouter();

useEffect(() => {
Sentry.captureException(new Error('Failed to set up user', { cause: error }));
}, [error]);

return (
<div className="flex h-full w-full flex-col items-center justify-center gap-5">
<div className="inline-flex items-center gap-2 text-red-600">
<ExclamationCircleIcon className="h-4 w-4" />
<h2 className="text-sm">Failed to set up your user</h2>
</div>
<Button
label="Contact Support"
appearance="outlined"
btnAction={() => {
signOut(() => router.push('/support'));
}}
/>
</div>
);
}
9 changes: 9 additions & 0 deletions ui/apps/dashboard/src/app/(auth)/sign-up/set-up/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import LoadingIcon from '@/icons/LoadingIcon';

export default function UserSetupLoading() {
return (
<div className="flex h-full w-full items-center justify-center">
<LoadingIcon />
</div>
);
}
18 changes: 18 additions & 0 deletions ui/apps/dashboard/src/app/(auth)/sign-up/set-up/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import ReloadClerkAndRedirect from '@/app/(auth)/ReloadClerkAndRedirect';
import { graphql } from '@/gql';
import graphqlAPI from '@/queries/graphqlAPI';

const CreateUserDocument = graphql(`
mutation CreateUser {
createUser {
user {
id
}
}
}
`);

export default async function UserSetupPage() {
await graphqlAPI.request(CreateUserDocument);
return <ReloadClerkAndRedirect redirectURL="/organization-list" />;
}
10 changes: 0 additions & 10 deletions ui/apps/dashboard/src/app/(organization-active)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import type { ReactNode } from 'react';
import { redirect } from 'next/navigation';
import { auth } from '@clerk/nextjs';

import { URQLProvider } from '@/queries/URQLProvider';

Expand All @@ -9,13 +7,5 @@ type OrganizationActiveLayoutProps = {
};

export default function OrganizationActiveLayout({ children }: OrganizationActiveLayoutProps) {
const { userId, orgId } = auth();
const isSignedIn = !!userId;
const hasActiveOrganization = !!orgId;

if (isSignedIn && !hasActiveOrganization) {
redirect('/organization-list');
}

return <URQLProvider>{children}</URQLProvider>;
}
10 changes: 10 additions & 0 deletions ui/apps/dashboard/src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
"\n mutation SetUpAccount {\n setUpAccount {\n account {\n id\n }\n }\n }\n": types.SetUpAccountDocument,
"\n mutation CreateUser {\n createUser {\n user {\n id\n }\n }\n }\n": types.CreateUserDocument,
"\n mutation CreateEnvironment($name: String!) {\n createWorkspace(input: { name: $name }) {\n id\n }\n }\n": types.CreateEnvironmentDocument,
"\n mutation ArchiveEnvironment($id: ID!) {\n archiveEnvironment(id: $id) {\n id\n }\n }\n": types.ArchiveEnvironmentDocument,
"\n mutation UnarchiveEnvironment($id: ID!) {\n unarchiveEnvironment(id: $id) {\n id\n }\n }\n": types.UnarchiveEnvironmentDocument,
Expand Down Expand Up @@ -104,6 +106,14 @@ const documents = {
*/
export function graphql(source: string): unknown;

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation SetUpAccount {\n setUpAccount {\n account {\n id\n }\n }\n }\n"): (typeof documents)["\n mutation SetUpAccount {\n setUpAccount {\n account {\n id\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation CreateUser {\n createUser {\n user {\n id\n }\n }\n }\n"): (typeof documents)["\n mutation CreateUser {\n createUser {\n user {\n id\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
Loading

0 comments on commit 1a3fd83

Please sign in to comment.