Skip to content

Commit

Permalink
feat: Add validation for federation name and dynamic warning message …
Browse files Browse the repository at this point in the history
…in setup forms
  • Loading branch information
kleyberthsantos authored and Kodylow committed Sep 6, 2024
1 parent bed8d93 commit f9ed146
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import {
FormControl,
FormLabel,
Expand All @@ -22,18 +22,32 @@ interface BasicSettingsFormProps {
setMyName: (name: string) => void;
password: string | null;
setPassword: (password: string) => void;
isNextDisabled: (disabled: boolean) => void;
}

export const BasicSettingsForm: React.FC<BasicSettingsFormProps> = ({
myName,
setMyName,
password,
setPassword,
isNextDisabled,
}) => {
const { t } = useTranslation();
const theme = useTheme();
const [showPassword, setShowPassword] = useState(false);

const validateName = useCallback(
(name: string) => {
const isValid = name.trim() !== '' && /^[a-zA-Z0-9]/.test(name);
isNextDisabled(!isValid);
},
[isNextDisabled]
);

useEffect(() => {
validateName(myName);
}, [myName, validateName]);

return (
<FormGroup
icon={LightbulbLogo}
Expand All @@ -46,7 +60,11 @@ export const BasicSettingsForm: React.FC<BasicSettingsFormProps> = ({
value={myName}
onChange={(ev) => setMyName(ev.currentTarget.value)}
/>
<FormHelperText>{t('set-config.guardian-name-help')}</FormHelperText>
<FormHelperText>
{myName.trim() === ''
? t('set-config.give-federation-name')
: t('set-config.guardian-name-help')}
</FormHelperText>
</FormControl>
<FormControl>
<FormLabel>{t('set-config.admin-password')}</FormLabel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import {
FormControl,
FormHelperText,
Text,
FormLabel,
Input,
Select,
useTheme,
} from '@chakra-ui/react';
import { useTranslation } from '@fedimint/utils';
import { FormGroup } from '@fedimint/ui';
Expand Down Expand Up @@ -36,6 +38,23 @@ export const FederationSettingsForm: React.FC<FederationSettingsFormProps> = ({
setNumPeers,
}) => {
const { t } = useTranslation();
const theme = useTheme();
const [nameHelpText, setNameHelpText] = useState<string | null>(null);

const validateFederationName = useCallback(
(name: string) => {
if (name.trim() === '') {
setNameHelpText(t('set-config.give-federation-name'));
} else {
setNameHelpText(null);
}
},
[t]
);

useEffect(() => {
validateFederationName(federationName);
}, [federationName, validateFederationName]);

return (
<FormGroup
Expand All @@ -50,7 +69,15 @@ export const FederationSettingsForm: React.FC<FederationSettingsFormProps> = ({
<Input
value={federationName}
onChange={handleChangeFederationName}
onBlur={() => validateFederationName(federationName)}
/>
{nameHelpText && (
<FormHelperText>
<Text color={theme.colors.yellow[500]}>
{nameHelpText || t('set-config.guardian-name-help')}
</Text>
</FormHelperText>
)}
</FormControl>
{isHost && (
<FormControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const SetConfiguration: React.FC<Props> = ({ next }: Props) => {
stateNumPeers ? stateNumPeers.toString() : isSolo ? '1' : MIN_BFT_NUM_PEERS
);

const [isNextDisabled, setIsNextDisabled] = useState(true);
const { isOpen, onOpen, onClose } = useDisclosure();

useEffect(() => {
Expand Down Expand Up @@ -117,6 +118,12 @@ export const SetConfiguration: React.FC<Props> = ({ next }: Props) => {
setPassword(statePassword);
}, [statePassword]);

// Validate if the name of the Federation is valid
const validateFederationName = (name: string) => {
const isValid = name.trim() !== '' && /^[a-zA-Z0-9]/.test(name);
setIsNextDisabled(!isValid);
};

const hostCriteria = [
myName,
password,
Expand Down Expand Up @@ -149,6 +156,7 @@ export const SetConfiguration: React.FC<Props> = ({ next }: Props) => {
) => {
const newName = ev.currentTarget.value;
setFederationName(newName);
validateFederationName(newName);
setMetaFields((prev) =>
prev.map(([key, val]) =>
key === 'federation_name' ? [key, newName] : [key, val]
Expand Down Expand Up @@ -253,9 +261,10 @@ export const SetConfiguration: React.FC<Props> = ({ next }: Props) => {
setMyName={setMyName}
password={password}
setPassword={setPassword}
isNextDisabled={setIsNextDisabled}
/>
<Button
isDisabled={!isValid}
isDisabled={!isValid || isNextDisabled}
onClick={onOpen}
leftIcon={<Icon as={ArrowRightIcon} />}
width='60%'
Expand Down
1 change: 1 addition & 0 deletions apps/guardian-ui/src/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
"basic-settings": "Basics",
"federation-settings": "Federation settings",
"federation-name": "Federation name",
"give-federation-name": "Gives a name to your Federation",
"guardian-number": "Number of guardians",
"guardian-number-help": "Federations require a minimum of 4 guardians. This cannot be changed later.",
"bitcoin-settings": "Bitcoin settings",
Expand Down

0 comments on commit f9ed146

Please sign in to comment.