Skip to content

Commit

Permalink
chore(clerk-js): Remove custom Alert from invitation page and display…
Browse files Browse the repository at this point in the history
… error as global (#1903)

* chore(clerk-js): Remove custom Alert from invitation page and display error as global

* chore(clerk-js): Remove custom Alert from invitation page and display error as global (pr comments)
  • Loading branch information
panteliselef authored Oct 18, 2023
1 parent d78bd84 commit ec10f67
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 78 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-experts-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Remove custom Alert from invitation page and display it as a global error instead (at the top of the component).
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React from 'react';

import { Flex, Text } from '../../customizables';
import {
Alert,
Form,
FormButtonContainer,
Select,
Expand Down Expand Up @@ -34,7 +33,6 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
const card = useCardState();
const { t, locale } = useLocalizations();
const [isValidUnsubmittedEmail, setIsValidUnsubmittedEmail] = React.useState(false);
const [localizedEmails, setLocalizedEmails] = React.useState<string | null>(null);

if (!organization) {
return null;
Expand All @@ -45,7 +43,6 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
const roles: Array<{ label: string; value: MembershipRole }> = [
{ label: t(roleLocalizationKey('admin')), value: 'admin' },
{ label: t(roleLocalizationKey('basic_member')), value: 'basic_member' },
// { label: t(roleLocalizationKey('guest_member')), value: 'guest_member' },
];

const emailAddressField = useFormControl('emailAddress', '', {
Expand Down Expand Up @@ -75,9 +72,7 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {

const roleField = useFormControl('role', 'basic_member', {
options: roles,
// label: localizationKeys('formFieldLabel__firstName'),
// placeholder: localizationKeys('formFieldInputPlaceholder__firstName'),
label: 'Role',
label: localizationKeys('formFieldLabel__role'),
placeholder: '',
});

Expand All @@ -95,12 +90,15 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {

if (isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'duplicate_record') {
const unlocalizedEmailsList = err.errors[0].meta?.emailAddresses || [];

// Create a localized list of email addresses
const localizedList = createListFormat(unlocalizedEmailsList, locale);
setLocalizedEmails(localizedList);
card.setError(
t(
localizationKeys('organizationProfile.invitePage.detailsTitle__inviteFailed', {
// Create a localized list of email addresses
email_addresses: createListFormat(unlocalizedEmailsList, locale),
}),
),
);
} else {
setLocalizedEmails(null);
handleError(err, [], card.setError);
}
});
Expand All @@ -113,74 +111,61 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
};

return (
<>
{localizedEmails && (
<Alert
variant='danger'
align='start'
title={localizationKeys('organizationProfile.invitePage.detailsTitle__inviteFailed', {
email_addresses: localizedEmails,
})}
sx={{ border: 0 }}
/>
)}
<Form.Root onSubmit={onSubmit}>
<Form.ControlRow elementId={emailAddressField.id}>
<Flex
direction='col'
gap={2}
sx={{ width: '100%' }}
>
<Text localizationKey={localizationKeys('formFieldLabel__emailAddresses')} />

<Text
localizationKey={localizationKeys('formFieldInputPlaceholder__emailAddresses')}
colorScheme='neutral'
sx={t => ({ fontSize: t.fontSizes.$xs })}
/>

<Form.Root onSubmit={onSubmit}>
<Form.ControlRow elementId={emailAddressField.id}>
<Flex
direction='col'
gap={2}
<TagInput
{...restEmailAddressProps}
autoFocus
validate={isEmail}
sx={{ width: '100%' }}
>
<Text localizationKey={localizationKeys('formFieldLabel__emailAddresses')} />

<Text
localizationKey={localizationKeys('formFieldInputPlaceholder__emailAddresses')}
colorScheme='neutral'
sx={t => ({ fontSize: t.fontSizes.$xs })}
/>

<TagInput
{...restEmailAddressProps}
autoFocus
validate={isEmail}
sx={{ width: '100%' }}
validateUnsubmittedEmail={validateUnsubmittedEmail}
/>
</Flex>
</Form.ControlRow>
<Form.ControlRow elementId={roleField.id}>
<Flex
direction='col'
gap={2}
>
<Text localizationKey={localizationKeys('formFieldLabel__role')} />
{/*// @ts-expect-error */}
<Select
elementId='role'
{...roleField.props}
onChange={option => roleField.setValue(option.value)}
>
<SelectButton sx={t => ({ width: t.sizes.$48, justifyContent: 'space-between', display: 'flex' })}>
{roleField.props.options?.find(o => o.value === roleField.value)?.label}
</SelectButton>
<SelectOptionList sx={t => ({ minWidth: t.sizes.$48 })} />
</Select>
</Flex>
</Form.ControlRow>
<FormButtonContainer>
<Form.SubmitButton
block={false}
isDisabled={!canSubmit}
localizationKey={localizationKeys('organizationProfile.invitePage.formButtonPrimary__continue')}
validateUnsubmittedEmail={validateUnsubmittedEmail}
/>
<Form.ResetButton
localizationKey={resetButtonLabel || localizationKeys('userProfile.formButtonReset')}
block={false}
onClick={onReset}
/>
</FormButtonContainer>
</Form.Root>
</>
</Flex>
</Form.ControlRow>
<Form.ControlRow elementId={roleField.id}>
<Flex
direction='col'
gap={2}
>
<Text localizationKey={roleField.label} />
{/*@ts-expect-error Select expects options to be an array but useFormControl returns an optional field. */}
<Select
elementId='role'
{...roleField.props}
onChange={option => roleField.setValue(option.value)}
>
<SelectButton sx={t => ({ width: t.sizes.$48, justifyContent: 'space-between', display: 'flex' })}>
{roleField.props.options?.find(o => o.value === roleField.value)?.label}
</SelectButton>
<SelectOptionList sx={t => ({ minWidth: t.sizes.$48 })} />
</Select>
</Flex>
</Form.ControlRow>
<FormButtonContainer>
<Form.SubmitButton
block={false}
isDisabled={!canSubmit}
localizationKey={localizationKeys('organizationProfile.invitePage.formButtonPrimary__continue')}
/>
<Form.ResetButton
localizationKey={resetButtonLabel || localizationKeys('userProfile.formButtonReset')}
block={false}
onClick={onReset}
/>
</FormButtonContainer>
</Form.Root>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const useCardState = () => {
const { translateError } = useLocalizations();

const setIdle = (metadata?: Metadata) => setState(s => ({ ...s, status: 'idle', metadata }));
const setError = (metadata: ClerkRuntimeError | ClerkAPIError | Metadata) =>
const setError = (metadata: ClerkRuntimeError | ClerkAPIError | Metadata | string) =>
setState(s => ({ ...s, error: translateError(metadata) }));
const setLoading = (metadata?: Metadata) => setState(s => ({ ...s, status: 'loading', metadata }));
const runAsync = async <T = unknown,>(cb: Promise<T> | (() => Promise<T>), metadata?: Metadata) => {
Expand Down

0 comments on commit ec10f67

Please sign in to comment.