Skip to content

Commit 2c959bc

Browse files
authored
refactor(console,phrases): refactor custom profile field creation modal (#7647)
1 parent f4d28c1 commit 2c959bc

File tree

20 files changed

+96
-40
lines changed

20 files changed

+96
-40
lines changed

packages/console/src/pages/SignInExperience/PageContent/CollectUserProfile/CreateProfileFieldModal/index.tsx

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import modalStyles from '@/scss/modal.module.scss';
2323
import { isPaidPlan } from '@/utils/subscription';
2424

2525
import CustomDataProfileNameField from '../../components/CustomDataProfileNameField';
26+
import { userAvailableBuiltInFieldKeys } from '../consts';
2627
import { getInitialRequestPayloadByFieldName } from '../data-parser';
2728

2829
import styles from './index.module.scss';
@@ -32,6 +33,7 @@ type Props = {
3233
readonly onClose?: (field?: CustomProfileField) => void;
3334
};
3435

36+
const reservedBuiltInProfileFieldKeySet = new Set<string>(builtInCustomProfileFieldKeys);
3537
const reservedCustomDataKeySet = new Set<string>(reservedCustomDataKeys);
3638

3739
function CreateProfileFieldModal({ existingFieldNames, onClose }: Props) {
@@ -76,6 +78,13 @@ function CreateProfileFieldModal({ existingFieldNames, onClose }: Props) {
7678
return false;
7779
}
7880

81+
if (reservedBuiltInProfileFieldKeySet.has(customDataFieldName)) {
82+
setFieldNameInputError(
83+
errorT('custom_profile_fields.name_conflict_built_in_prop', { name: customDataFieldName })
84+
);
85+
return false;
86+
}
87+
7988
if (reservedCustomDataKeySet.has(customDataFieldName)) {
8089
setFieldNameInputError(
8190
errorT('custom_profile_fields.name_conflict_custom_data', {
@@ -90,22 +99,13 @@ function CreateProfileFieldModal({ existingFieldNames, onClose }: Props) {
9099

91100
const builtInFields = useMemo(
92101
() =>
93-
[
94-
{
95-
name: 'fullname',
96-
label: t('profile.fields.fullname'),
97-
description: t('profile.fields.fullname_description'),
98-
isDisabled: existingFieldNames.includes('fullname'),
99-
},
100-
...builtInCustomProfileFieldKeys.map((name) => ({
102+
userAvailableBuiltInFieldKeys
103+
.map((name) => ({
101104
name,
102105
label: t(`profile.fields.${name === 'address' ? 'address.formatted' : name}`),
103106
description: t(`profile.fields.${name}_description`),
104-
isDisabled: existingFieldNames.includes(name),
105-
})),
106-
]
107-
.slice()
108-
.sort((fieldA, fieldB) => fieldA.name.localeCompare(fieldB.name)),
107+
}))
108+
.filter(({ name }) => !existingFieldNames.includes(name)),
109109
[t, existingFieldNames]
110110
);
111111

@@ -152,25 +152,29 @@ function CreateProfileFieldModal({ existingFieldNames, onClose }: Props) {
152152
size="xlarge"
153153
onClose={onClose}
154154
>
155-
<div className={styles.groupLabel}>
156-
{t('sign_in_exp.custom_profile_fields.modal.built_in_properties')}
157-
</div>
158-
<RadioGroup
159-
className={styles.group}
160-
type="card"
161-
name="fieldName"
162-
value={selectedField}
163-
onChange={setSelectedField}
164-
>
165-
{builtInFields.map(({ name, label, description, isDisabled }) => (
166-
<Radio key={name} value={name} isDisabled={isDisabled}>
167-
<div className={styles.item}>
168-
<div className={styles.title}>{label}</div>
169-
<div className={styles.description}>{description}</div>
170-
</div>
171-
</Radio>
172-
))}
173-
</RadioGroup>
155+
{builtInFields.length > 0 && (
156+
<>
157+
<div className={styles.groupLabel}>
158+
{t('sign_in_exp.custom_profile_fields.modal.built_in_properties')}
159+
</div>
160+
<RadioGroup
161+
className={styles.group}
162+
type="card"
163+
name="fieldName"
164+
value={selectedField}
165+
onChange={setSelectedField}
166+
>
167+
{builtInFields.map(({ name, label, description }) => (
168+
<Radio key={name} value={name}>
169+
<div className={styles.item}>
170+
<div className={styles.title}>{label}</div>
171+
<div className={styles.description}>{description}</div>
172+
</div>
173+
</Radio>
174+
))}
175+
</RadioGroup>
176+
</>
177+
)}
174178
<div className={styles.groupLabel}>
175179
{t('sign_in_exp.custom_profile_fields.modal.custom_properties')}
176180
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
11
export const collectUserProfilePathname = '/sign-in-experience/collect-user-profile';
2+
3+
export const userAvailableBuiltInFieldKeys = Object.freeze([
4+
'name',
5+
'fullname',
6+
'nickname',
7+
'birthdate',
8+
'gender',
9+
'profile',
10+
'website',
11+
'address',
12+
] as const);

packages/console/src/pages/SignInExperience/PageContent/components/CustomDataProfileNameField/index.module.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@
2424
flex: 1;
2525
}
2626
}
27+
28+
.errorMessage {
29+
font: var(--font-body-2);
30+
color: var(--color-error);
31+
margin-top: _.unit(1);
32+
}

packages/console/src/pages/SignInExperience/PageContent/components/CustomDataProfileNameField/index.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@ import TextInput, { type Props } from '@/ds-components/TextInput';
33
import styles from './index.module.scss';
44

55
function CustomDataProfileNameField(props: Props) {
6+
const { error, ...rest } = props;
67
return (
7-
<div className={styles.wrapper}>
8-
<div className={styles.prefix}>customData.</div>
9-
<TextInput
10-
className={styles.input}
11-
inputContainerClassName={styles.inputContainer}
12-
{...props}
13-
/>
14-
</div>
8+
<>
9+
<div className={styles.wrapper}>
10+
<div className={styles.prefix}>customData.</div>
11+
<TextInput
12+
className={styles.input}
13+
inputContainerClassName={styles.inputContainer}
14+
{...rest}
15+
/>
16+
</div>
17+
{Boolean(error) && typeof error !== 'boolean' && (
18+
<div className={styles.errorMessage}>{error}</div>
19+
)}
20+
</>
1521
);
1622
}
1723

packages/phrases/src/locales/ar/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const custom_profile_fields = {
1010
invalid_name: 'اسم الحقل غير صالح ، يُسمح فقط بالأحرف أو الأرقام ، مع مراعاة حالة الأحرف.',
1111
name_conflict_sign_in_identifier:
1212
'اسم الحقل غير صالح. "{{name}}" هو مفتاح معرف تسجيل دخول محجوز.',
13+
name_conflict_built_in_prop:
14+
'اسم الحقل غير صالح. "{{name}}" هو خاصية ملف تعريف مستخدم مدمجة محجوزة.',
1315
name_conflict_custom_data: 'اسم الحقل غير صالح. "{{name}}" هو مفتاح بيانات مخصصة محجوز.',
1416
name_required: 'اسم الحقل مطلوب.',
1517
};

packages/phrases/src/locales/de/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const custom_profile_fields = {
1212
'Ungültiger Feldname, nur Buchstaben oder Zahlen sind erlaubt, Groß- und Kleinschreibung beachten.',
1313
name_conflict_sign_in_identifier:
1414
'Ungültiger Feldname. "{{name}}" ist ein reservierter Schlüssel für die Anmeldung.',
15+
name_conflict_built_in_prop:
16+
'Ungültiger Feldname. "{{name}}" ist eine reservierte eingebaute Benutzerprofil-Eigenschaft.',
1517
name_conflict_custom_data:
1618
'Ungültiger Feldname. "{{name}}" ist ein reservierter Schlüssel für benutzerdefinierte Daten.',
1719
name_required: 'Feldname ist erforderlich.',

packages/phrases/src/locales/en/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const custom_profile_fields = {
1010
invalid_name: 'Invalid field name, only letters or numbers are allowed, case sensitive.',
1111
name_conflict_sign_in_identifier:
1212
'Invalid field name. "{{name}}" is a reserved sign-in identifier key.',
13+
name_conflict_built_in_prop:
14+
'Invalid field name. "{{name}}" is a reserved built-in user profile property.',
1315
name_conflict_custom_data: 'Invalid field name. "{{name}}" is a reserved custom data key.',
1416
name_required: 'Field name is required.',
1517
};

packages/phrases/src/locales/es/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const custom_profile_fields = {
1212
'Nombre de campo no válido, solo se permiten letras o números, distingue entre mayúsculas y minúsculas.',
1313
name_conflict_sign_in_identifier:
1414
'Nombre de campo no válido. "{{name}}" es una clave reservada para el identificador de inicio de sesión.',
15+
name_conflict_built_in_prop:
16+
'Nombre de campo no válido. "{{name}}" es una propiedad de perfil de usuario integrada reservada.',
1517
name_conflict_custom_data:
1618
'Nombre de campo no válido. "{{name}}" es una clave reservada para datos personalizados.',
1719
name_required: 'El nombre del campo es obligatorio.',

packages/phrases/src/locales/fr/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const custom_profile_fields = {
1212
'Nom de champ invalide, seules les lettres ou les chiffres sont autorisés, sensible à la casse.',
1313
name_conflict_sign_in_identifier:
1414
'Nom de champ invalide. "{{name}}" est une clé d\'identifiant de connexion réservée.',
15+
name_conflict_built_in_prop:
16+
'Nom de champ invalide. "{{name}}" est une propriété de profil utilisateur intégrée réservée.',
1517
name_conflict_custom_data:
1618
'Nom de champ invalide. "{{name}}" est une clé de données personnalisées réservée.',
1719
name_required: 'Le nom du champ est requis.',

packages/phrases/src/locales/it/errors/custom-profile-fields.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const custom_profile_fields = {
1111
'Nome del campo non valido, sono consentite solo lettere o numeri, sensibili alle maiuscole.',
1212
name_conflict_sign_in_identifier:
1313
'Nome del campo non valido. "{{name}}" è una chiave riservata di identificatore di accesso.',
14+
name_conflict_built_in_prop:
15+
'Nome del campo non valido. "{{name}}" è una proprietà riservata del profilo utente integrata.',
1416
name_conflict_custom_data:
1517
'Nome del campo non valido. "{{name}}" è una chiave riservata per i dati personalizzati.',
1618
name_required: 'Il nome del campo è obbligatorio.',

0 commit comments

Comments
 (0)