From 4886548889e02e8e8061e9847c55deb7b93e1991 Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Wed, 29 Mar 2023 15:42:20 -0400 Subject: [PATCH] Add validation support to Group names --- .../manage-group-modal/manage-group-modal.tsx | 11 ++++- .../manage-group-modal/steps/details-step.tsx | 19 +++++--- .../manage-group-modal/steps/privacy-step.tsx | 4 +- .../hooks/api/groups/useGroupValidation.ts | 45 +++++++++++++++++++ app/soapbox/hooks/api/index.ts | 1 + 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 app/soapbox/hooks/api/groups/useGroupValidation.ts diff --git a/app/soapbox/features/ui/components/modals/manage-group-modal/manage-group-modal.tsx b/app/soapbox/features/ui/components/modals/manage-group-modal/manage-group-modal.tsx index 2863060c5..fcc7c14da 100644 --- a/app/soapbox/features/ui/components/modals/manage-group-modal/manage-group-modal.tsx +++ b/app/soapbox/features/ui/components/modals/manage-group-modal/manage-group-modal.tsx @@ -3,7 +3,8 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { submitGroupEditor } from 'soapbox/actions/groups'; import { Modal, Stack } from 'soapbox/components/ui'; -import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import { useAppDispatch, useAppSelector, useDebounce } from 'soapbox/hooks'; +import { useGroupValidation } from 'soapbox/hooks/api'; import ConfirmationStep from './steps/confirmation-step'; import DetailsStep from './steps/details-step'; @@ -34,6 +35,7 @@ interface IManageGroupModal { const ManageGroupModal: React.FC = ({ onClose }) => { const intl = useIntl(); + const debounce = useDebounce; const dispatch = useAppDispatch(); const id = useAppSelector((state) => state.group_editor.groupId); @@ -43,6 +45,11 @@ const ManageGroupModal: React.FC = ({ onClose }) => { const [currentStep, setCurrentStep] = useState(id ? Steps.TWO : Steps.ONE); + const name = useAppSelector((state) => state.group_editor.displayName); + const debouncedName = debounce(name, 300); + + const { data: { isValid } } = useGroupValidation(debouncedName); + const handleClose = () => { onClose('MANAGE_GROUP'); }; @@ -92,7 +99,7 @@ const ManageGroupModal: React.FC = ({ onClose }) => { : } confirmationAction={handleNextStep} confirmationText={confirmationText} - confirmationDisabled={isSubmitting} + confirmationDisabled={isSubmitting || (currentStep === Steps.TWO && !isValid)} confirmationFullWidth onClose={handleClose} > diff --git a/app/soapbox/features/ui/components/modals/manage-group-modal/steps/details-step.tsx b/app/soapbox/features/ui/components/modals/manage-group-modal/steps/details-step.tsx index 2450dffea..56c755086 100644 --- a/app/soapbox/features/ui/components/modals/manage-group-modal/steps/details-step.tsx +++ b/app/soapbox/features/ui/components/modals/manage-group-modal/steps/details-step.tsx @@ -7,9 +7,9 @@ import { changeGroupEditorDescription, changeGroupEditorMedia, } from 'soapbox/actions/groups'; -import Icon from 'soapbox/components/icon'; -import { Avatar, Form, FormGroup, HStack, Input, Text, Textarea } from 'soapbox/components/ui'; -import { useAppDispatch, useAppSelector, useInstance } from 'soapbox/hooks'; +import { Avatar, Form, FormGroup, HStack, Icon, Input, Text, Textarea } from 'soapbox/components/ui'; +import { useAppDispatch, useAppSelector, useDebounce, useInstance } from 'soapbox/hooks'; +import { useGroupValidation } from 'soapbox/hooks/api'; import { isDefaultAvatar, isDefaultHeader } from 'soapbox/utils/accounts'; import resizeImage from 'soapbox/utils/resize-image'; @@ -30,7 +30,7 @@ const messages = defineMessages({ const HeaderPicker: React.FC = ({ src, onChange, accept, disabled }) => { return (