simle-chat
117 строк · 4.5 Кб
1import { useRef, useEffect } from 'react';2import { Modal, Form, Button } from 'react-bootstrap';3import { useSelector, useDispatch } from 'react-redux';4import { useTranslation } from 'react-i18next';5import { toast } from 'react-toastify';6import { useFormik } from 'formik';7import leoProfanity from 'leo-profanity';8import * as yup from 'yup';9import axios from 'axios';10
11import { getCurrentChannelsNames, getActiveChannelId } from '../../selectors/chatSelectors';12import { getChangeableСhannelId, getChangeableСhannelName } from '../../selectors/modalSelectors';13import { actions as modalActions } from '../../slices/modalSlice';14import { actions as chatActions } from '../../slices/chatSlice';15import useAuth from '../../hooks/index';16import routes from '../../routes';17
18const getValidationSchema = (t, currentChannels) => yup.object({19newChannelName: yup.string().trim()20.min(3, t('validationError.wronglengthName'))21.max(20, t('validationError.wronglengthName'))22.required(t('validationError.requiredField'))23.notOneOf(currentChannels, t('validationError.thisNameExists')),24});25
26const AddAndRenameChannel = ({ modalType }) => {27const dispatch = useDispatch();28const { t } = useTranslation();29const inputRef = useRef();30const { getAuthHeader } = useAuth();31
32const currentChannelsNames = useSelector(getCurrentChannelsNames);33const activeChannelId = useSelector(getActiveChannelId);34const changeableСhannelId = useSelector(getChangeableСhannelId);35const changeableСhannelName = useSelector(getChangeableСhannelName);36
37const formik = useFormik({38initialValues: { newChannelName: (changeableСhannelName) },39validationSchema: getValidationSchema(t, currentChannelsNames),40onSubmit: async (values) => {41const newChannelName = { name: leoProfanity.clean(values.newChannelName) };42const headers = await getAuthHeader();43const requestPath = (modalType === 'addChannel')44? routes.dataRequestPath('channels')45: routes.dataRequestPathWithId('channels', changeableСhannelId);46try {47if (modalType === 'addChannel') {48const response = await axios.post(requestPath, newChannelName, { headers });49const { name, id } = response.data;50dispatch(chatActions.setActiveChannel({ name, id }));51}52if (modalType === 'renameChannel') {53const response = await axios.patch(requestPath, newChannelName, { headers });54if (response.data.id === activeChannelId) {55const { name, id } = response.data;56dispatch(chatActions.setActiveChannel({ name, id }));57}58}59dispatch(modalActions.closedModal());60toast.success(t(`toasts.${modalType}.success`));61} catch (error) {62toast.error(t(`toasts.${modalType}.error`));63console.error(error);64}65},66});67
68useEffect(() => {69if (modalType === 'addChannel') inputRef.current.focus();70if (modalType === 'renameChannel') inputRef.current.select();71}, [inputRef, modalType]);72
73return (74<>75<Modal.Header closeButton>76<Modal.Title>{t(`modals.addAndRename.${modalType}`)}</Modal.Title>77</Modal.Header>78<Modal.Body>79<Form onSubmit={formik.handleSubmit}>80<Form.Group controlId="newChannelName">81<Form.Control82ref={inputRef}83onChange={formik.handleChange}84onBlur={formik.handleBlur}85value={formik.values.newChannelName}86name="newChannelName"87isInvalid={formik.touched.newChannelName && formik.errors.newChannelName}88disabled={formik.isSubmitting}89/>90<Form.Label className="visually-hidden">{t('modals.addAndRename.inputPlaceholder')}</Form.Label>91<Form.Control.Feedback type="invalid">92{formik.errors.newChannelName}93</Form.Control.Feedback>94<div className="mt-3 d-flex justify-content-end">95<Button96onClick={() => dispatch(modalActions.closedModal())}97variant="secondary"98className="me-2"99>100{t('modals.cancelButton')}101</Button>102{' '}103<Button104type="submit"105variant="primary"106>107{t('modals.addAndRename.button')}108</Button>109</div>110</Form.Group>111</Form>112</Modal.Body>113</>114);115};116
117export default AddAndRenameChannel;118