Skip to content

Commit

Permalink
fix(clerk-js): Cleanup org profile forms (#2391)
Browse files Browse the repository at this point in the history
  • Loading branch information
desiprisg authored Dec 18, 2023
1 parent 303c8f4 commit d316d5b
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 99 deletions.
2 changes: 2 additions & 0 deletions .changeset/fair-bears-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
44 changes: 20 additions & 24 deletions packages/clerk-js/src/ui/common/RemoveResourcePage.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
import React from 'react';

import { Text } from '../customizables';
import { Form, FormButtons, FormContent, SuccessPage, useCardState, withCardStateProvider } from '../elements';
import type { FormProps } from '../elements';
import { Form, FormButtons, FormContent, useCardState, withCardStateProvider } from '../elements';
import { useActionContext } from '../elements/Action/ActionRoot';
import type { LocalizationKey } from '../localization';
import { handleError } from '../utils';
import { useWizard, Wizard } from './Wizard';

type RemovePageProps = {
type RemovePageProps = Omit<FormProps, 'onSuccess'> & {
title: LocalizationKey;
breadcrumbTitle?: LocalizationKey;
messageLine1: LocalizationKey;
messageLine2: LocalizationKey;
successMessage: LocalizationKey;
successMessage?: LocalizationKey;
deleteResource: () => Promise<any>;
onSuccess?: () => void;
Breadcrumbs?: React.ComponentType<any> | null;
};

export const RemoveResourcePage = withCardStateProvider((props: RemovePageProps) => {
const { title, messageLine1, messageLine2, successMessage, deleteResource } = props;
const wizard = useWizard();
const card = useCardState();
const { title, messageLine1, messageLine2, deleteResource, onSuccess, onReset } = props;
const { close } = useActionContext();
const card = useCardState();

const handleSubmit = async () => {
try {
await deleteResource().then(() => wizard.nextStep());
await deleteResource().then(() => {
onSuccess?.();
});
} catch (e) {
handleError(e, [], card.setError);
}
};

return (
<Wizard {...wizard.props}>
<FormContent headerTitle={title}>
<Form.Root onSubmit={handleSubmit}>
<Text localizationKey={messageLine1} />
<Text localizationKey={messageLine2} />
<FormButtons
variant='primaryDanger'
onReset={close}
/>
</Form.Root>
</FormContent>
<SuccessPage
title={title}
text={successMessage}
/>
</Wizard>
<FormContent headerTitle={title}>
<Form.Root onSubmit={handleSubmit}>
<Text localizationKey={messageLine1} />
<Text localizationKey={messageLine2} />
<FormButtons
variant='primaryDanger'
onReset={onReset || close}
/>
</Form.Root>
</FormContent>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ export const AddDomainForm = withCardStateProvider((props: AddDomainFormProps) =

<VerifyDomainForm
domainId={domainId}
onSubmit={() => {
onSuccess={() => {
domains?.revalidate?.();
onSuccess?.();
}}
onReset={onReset}
/>
</Wizard>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import { useActionContext } from '../../elements/Action/ActionRoot';
import { useInView } from '../../hooks';
import type { PropsOfComponent } from '../../styledSystem';
import { EnrollmentBadge } from './EnrollmentBadge';
import { RemoveDomainForm } from './RemoveDomainForm';
import { VerifiedDomainForm } from './VerifiedDomainForm';
import { VerifyDomainForm } from './VerifyDomainForm';
import { RemoveDomainScreen } from './RemoveDomainScreen';
import { VerifiedDomainScreen } from './VerifiedDomainScreen';
import { VerifyDomainScreen } from './VerifyDomainScreen';

type DomainListProps = GetDomainsParams & {
verificationStatus?: OrganizationDomainVerificationStatus;
Expand Down Expand Up @@ -105,6 +105,8 @@ export const DomainList = withGate(
return null;
}

const hasNextOrFetching = domains?.hasNextPage || domains?.isFetching;

return (
<ProfileSection.ItemList id='organizationDomains'>
{domainList.length === 0 && !domains?.isLoading && fallback}
Expand All @@ -122,28 +124,32 @@ export const DomainList = withGate(

<Action.Open value='remove'>
<Action.Card>
<RemoveDomainForm domainId={domain.id} />
<RemoveDomainScreen domainId={domain.id} />
</Action.Card>
</Action.Open>

<Action.Open value='verify'>
<Action.Card>
<VerifyDomainForm domainId={domain.id} />
<VerifyDomainScreen domainId={domain.id} />
</Action.Card>
</Action.Open>

<Action.Open value='manage'>
<Action.Card>
<VerifiedDomainForm domainId={domain.id} />
<VerifiedDomainScreen domainId={domain.id} />
</Action.Card>
</Action.Open>
</Action.Root>
);
})}

{(domains?.hasNextPage || domains?.isFetching) && domains.data.length === 0 && (
<Box
ref={domains?.hasNextPage && !domains.isFetching ? ref : undefined}
sx={{ visibility: 'hidden' }}
/>

{hasNextOrFetching && domains.data.length === 0 && (
<Box
ref={domains?.isFetching ? undefined : ref}
sx={[
t => ({
width: '100%',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { useOrganization } from '@clerk/shared/react';
import React from 'react';

import { isDefaultImage } from '../../../utils';
import { useWizard, Wizard } from '../../common';
import { localizationKeys } from '../../customizables';
import type { FormProps } from '../../elements';
import { Form, FormButtons, FormContent, SuccessPage, useCardState, withCardStateProvider } from '../../elements';
import { Form, FormButtons, FormContent, useCardState, withCardStateProvider } from '../../elements';
import { handleError, useFormControl } from '../../utils';
import { OrganizationProfileAvatarUploader } from './OrganizationProfileAvatarUploader';

Expand All @@ -19,8 +18,6 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => {
const [avatarChanged, setAvatarChanged] = React.useState(false);
const { organization } = useOrganization();

const wizard = useWizard({ onNextStep: () => card.setError(undefined) });

const nameField = useFormControl('name', organization?.name || '', {
type: 'text',
label: localizationKeys('formFieldLabel__organizationName'),
Expand All @@ -43,7 +40,7 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => {
const onSubmit = async (e: React.FormEvent) => {
e.preventDefault();
return (dataChanged ? organization.update({ name: nameField.value, slug: slugField.value }) : Promise.resolve())
.then(wizard.nextStep)
.then(onSuccess)
.catch(err => {
handleError(err, [nameField, slugField], card.setError);
});
Expand Down Expand Up @@ -79,41 +76,34 @@ export const ProfileForm = withCardStateProvider((props: ProfileFormProps) => {
};

return (
<Wizard {...wizard.props}>
<FormContent
headerTitle={title}
headerSubtitle={subtitle}
>
<Form.Root onSubmit={onSubmit}>
<OrganizationProfileAvatarUploader
organization={organization}
onAvatarChange={uploadAvatar}
onAvatarRemove={isDefaultImage(organization.imageUrl) ? null : onAvatarRemove}
<FormContent
headerTitle={title}
headerSubtitle={subtitle}
>
<Form.Root onSubmit={onSubmit}>
<OrganizationProfileAvatarUploader
organization={organization}
onAvatarChange={uploadAvatar}
onAvatarRemove={isDefaultImage(organization.imageUrl) ? null : onAvatarRemove}
/>
<Form.ControlRow elementId={nameField.id}>
<Form.PlainInput
{...nameField.props}
autoFocus
isRequired
/>
<Form.ControlRow elementId={nameField.id}>
<Form.PlainInput
{...nameField.props}
autoFocus
isRequired
/>
</Form.ControlRow>
<Form.ControlRow elementId={slugField.id}>
<Form.PlainInput
{...slugField.props}
onChange={onChangeSlug}
/>
</Form.ControlRow>
<FormButtons
isDisabled={!canSubmit}
onReset={onReset}
</Form.ControlRow>
<Form.ControlRow elementId={slugField.id}>
<Form.PlainInput
{...slugField.props}
onChange={onChangeSlug}
/>
</Form.Root>
</FormContent>
<SuccessPage
title={title}
text={localizationKeys('organizationProfile.profilePage.successMessage')}
onFinish={onSuccess}
/>
</Wizard>
</Form.ControlRow>
<FormButtons
isDisabled={!canSubmit}
onReset={onReset}
/>
</Form.Root>
</FormContent>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ import React from 'react';
import { RemoveResourcePage } from '../../common';
import { useEnvironment } from '../../contexts';
import { descriptors, Flex, Spinner } from '../../customizables';
import { useActionContext } from '../../elements/Action/ActionRoot';
import type { FormProps } from '../../elements';
import { useFetch } from '../../hooks';
import { localizationKeys } from '../../localization';
import { OrganizationProfileBreadcrumbs } from './OrganizationProfileNavbar';

type RemoveDomainFormProps = {
type RemoveDomainFormProps = FormProps & {
domainId: string;
};

export const RemoveDomainForm = (props: RemoveDomainFormProps) => {
const { organizationSettings } = useEnvironment();
const { organization } = useOrganization();
const { close } = useActionContext();
const { domainId: id } = props;
const { domainId: id, onSuccess, onReset } = props;

const ref = React.useRef<OrganizationDomainResource>();
const { data: domain, status: domainStatus } = useFetch(
Expand Down Expand Up @@ -66,17 +64,14 @@ export const RemoveDomainForm = (props: RemoveDomainFormProps) => {
domain: ref.current?.name,
})}
messageLine2={localizationKeys('organizationProfile.removeDomainPage.messageLine2')}
successMessage={localizationKeys('organizationProfile.removeDomainPage.successMessage', {
domain: ref.current?.name,
})}
deleteResource={() =>
domain?.delete().then(async () => {
await domains?.revalidate?.();
close();
onSuccess();
})
}
breadcrumbTitle={localizationKeys('organizationProfile.profilePage.domainSection.title')}
Breadcrumbs={OrganizationProfileBreadcrumbs}
onSuccess={onSuccess}
onReset={onReset}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useActionContext } from '../../elements/Action/ActionRoot';
import { RemoveDomainForm } from './RemoveDomainForm';

type RemoveDomainScreenProps = { domainId: string };
export const RemoveDomainScreen = (props: RemoveDomainScreenProps) => {
const { close } = useActionContext();
return (
<RemoveDomainForm
onSuccess={close}
onReset={close}
{...props}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CalloutWithAction } from '../../common';
import { useEnvironment } from '../../contexts';
import type { LocalizationKey } from '../../customizables';
import { Col, descriptors, Flex, localizationKeys, Spinner, Text } from '../../customizables';
import type { FormProps } from '../../elements';
import {
Form,
FormButtons,
Expand Down Expand Up @@ -94,15 +95,13 @@ const useEnrollmentOptions = () => {
return buildEnrollmentOptions(organizationSettings);
};

type VerifiedDomainFormProps = {
type VerifiedDomainFormProps = FormProps & {
domainId: string;
mode?: 'select' | 'edit';
onSubmit?: () => void;
onReset?: () => void;
};

export const VerifiedDomainForm = withCardStateProvider((props: VerifiedDomainFormProps) => {
const { domainId: id, mode = 'edit', onSubmit, onReset } = props;
const { domainId: id, mode = 'edit', onSuccess, onReset } = props;
const card = useCardState();
const { organizationSettings } = useEnvironment();

Expand Down Expand Up @@ -161,7 +160,7 @@ export const VerifiedDomainForm = withCardStateProvider((props: VerifiedDomainFo

await domains.revalidate();

(onSubmit || onReset)?.();
onSuccess();
} catch (e) {
handleError(e, [enrollmentMode], card.setError);
}
Expand All @@ -177,10 +176,9 @@ export const VerifiedDomainForm = withCardStateProvider((props: VerifiedDomainFo
direction={'row'}
align={'center'}
justify={'center'}
sx={t => ({
sx={{
height: '100%',
minHeight: t.sizes.$120,
})}
}}
>
<Spinner
size={'lg'}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useActionContext } from '../../elements/Action/ActionRoot';
import { VerifiedDomainForm } from './VerifiedDomainForm';

type VerifiedDomainScreenProps = { domainId: string };
export const VerifiedDomainScreen = (props: VerifiedDomainScreenProps) => {
const { close } = useActionContext();
return (
<VerifiedDomainForm
onSuccess={close}
onReset={close}
{...props}
/>
);
};
Loading

0 comments on commit d316d5b

Please sign in to comment.