From 56386fe686ae2aa47dfcf0cd8f217bc9383c85b8 Mon Sep 17 00:00:00 2001 From: Robert Honsby Date: Fri, 16 Apr 2021 09:21:05 -0400 Subject: [PATCH] Converts EditCustomerDetailsModal to a functional component using hooks (#742) * Converts EditCustomerDetailsModal to a functional component using hooks * Makes error message more prominent --- .../customers/CustomerDetailsPageV2.tsx | 25 +- .../customers/EditCustomerDetailsModal.tsx | 267 ++++++++---------- 2 files changed, 130 insertions(+), 162 deletions(-) diff --git a/assets/src/components/customers/CustomerDetailsPageV2.tsx b/assets/src/components/customers/CustomerDetailsPageV2.tsx index bed4a2f83..32b34602f 100644 --- a/assets/src/components/customers/CustomerDetailsPageV2.tsx +++ b/assets/src/components/customers/CustomerDetailsPageV2.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Link, RouteComponentProps} from 'react-router-dom'; import {Box, Flex} from 'theme-ui'; -import {notification, Button, Empty, Title} from '../common'; +import {Button, Empty, Title} from '../common'; import {ArrowLeftOutlined} from '../icons'; import * as API from '../../api'; import {BrowserSession, Conversation, Customer} from '../../types'; @@ -104,20 +104,11 @@ class CustomerDetailsPage extends React.Component { handleCustomerUpdated = async () => { const customer = await this.fetchCustomer(); this.setState({customer}); - this.toggleIsEditModalVisible(false); - notification.success({ - message: `Customer successfully updated`, - duration: 10, - }); - }; - - handleCustomerDeleted = () => { - this.props.history.push('/customers'); + this.handleCloseEditModal(); }; - toggleIsEditModalVisible = (isEditModalVisible: boolean) => { - this.setState({isEditModalVisible}); - }; + handleOpenEditModal = () => this.setState({isEditModalVisible: true}); + handleCloseEditModal = () => this.setState({isEditModalVisible: false}); render() { const { @@ -163,17 +154,13 @@ class CustomerDetailsPage extends React.Component { - this.toggleIsEditModalVisible(false)} - onDelete={this.handleCustomerDeleted} + onClose={this.handleCloseEditModal} onUpdate={this.handleCustomerUpdated} /> diff --git a/assets/src/components/customers/EditCustomerDetailsModal.tsx b/assets/src/components/customers/EditCustomerDetailsModal.tsx index 507ca27de..6e9efe265 100644 --- a/assets/src/components/customers/EditCustomerDetailsModal.tsx +++ b/assets/src/components/customers/EditCustomerDetailsModal.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, {useState} from 'react'; +import {useHistory} from 'react-router'; import {Box, Flex} from 'theme-ui'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; @@ -24,45 +25,26 @@ type Props = { customer: Customer; isVisible: boolean; onClose: () => void; - onDelete: () => void; onUpdate: () => void; }; -type State = { - email?: string; - error?: string; - isDeleting: boolean; - isSaving: boolean; - name?: string; - phone?: string | number; -}; - -class EditCustomerDetailsModal extends React.Component { - state: State = { - email: this.props.customer.email, - isDeleting: false, - isSaving: false, - name: this.props.customer.name, - phone: this.props.customer.phone, - }; - - handleChangeName = (e: React.ChangeEvent) => { - this.setState({name: e.target.value}); - }; - - handleChangeEmail = (e: React.ChangeEvent) => { - this.setState({email: e.target.value}); - }; - - handleChangePhone = (e: React.ChangeEvent) => { - this.setState({phone: e.target.value}); - }; - - handleSave = async () => { - this.setState({error: '', isSaving: true}); - - const {customer, onUpdate} = this.props; - const {name, email, phone} = this.state; +const EditCustomerDetailsModal = ({ + customer, + isVisible, + onClose, + onUpdate, +}: Props) => { + const history = useHistory(); + const [email, setEmail] = useState(customer.email ?? ''); + const [name, setName] = useState(customer.name ?? ''); + const [phone, setPhone] = useState(customer.phone ?? ''); + const [error, setError] = useState(''); + const [isDeleting, setIsDeleting] = useState(false); + const [isSaving, setIsSaving] = useState(false); + + const handleSave = async () => { + setError(''); + setIsSaving(true); try { await API.updateCustomer(customer.id, { @@ -70,23 +52,27 @@ class EditCustomerDetailsModal extends React.Component { email, phone, }); + notification.success({ + message: `Customer successfully updated`, + duration: 10, + }); onUpdate(); } catch (err) { logger.error('Failed to update customer', err); const error = err.response?.body?.error?.message || - 'Something went wrong. Please try again later.'; + 'Failed to update customer. Please try again later.'; - this.setState({error, isSaving: false}); + setError(error); } - this.setState({isSaving: false}); + setIsSaving(false); }; - handleDelete = async () => { - this.setState({isDeleting: true}); + const handleDelete = async () => { + setError(''); + setIsDeleting(true); - const {customer, onDelete} = this.props; const {id: customerId} = customer; const title = customer?.title ?? 'Customer'; @@ -96,116 +82,111 @@ class EditCustomerDetailsModal extends React.Component { message: `${title} successfully deleted.`, duration: 10, }); - onDelete(); + history.push('/customers'); } catch (err) { logger.error('Failed to delete customer', err); - notification.error({ - message: `Failed to delete ${title}. Please try again later.`, - duration: 10, - }); + const error = + err.response?.body?.error?.message || + 'Failed to delete customer. Please try again later.'; + + setError(error); } - this.setState({isDeleting: false}); + setIsDeleting(false); }; - render() { - const {isVisible, onClose} = this.props; - const {isSaving, isDeleting, name, email, phone, error} = this.state; - - return ( - - - - - - Are you sure you want to delete this customer and all of - their data? - - - Warning: this cannot be undone. - - - } - icon={} - okText="Delete" - okType="danger" - cancelText="Cancel" - cancelButtonProps={{type: 'text'}} - placement="bottomLeft" - onConfirm={this.handleDelete} - > - - - - - - } - > - + return ( + - Name - - - + + + + Are you sure you want to delete this customer and all of + their data? + + + Warning: this cannot be undone. + + + } + icon={} + okText="Delete" + okType="danger" + cancelText="Cancel" + cancelButtonProps={{type: 'text'}} + placement="bottomLeft" + onConfirm={handleDelete} + > + + + + + } + > + + + Name - - - - Email - - - - + + setName(event.currentTarget.value)} + /> - - - - Phone - - - - - - {error && ( - - {error} - - )} + + + + Email + + + setEmail(event.currentTarget.value)} + /> - - ); - } -} + + + + Phone + + + setPhone(event.currentTarget.value)} + /> + + + {error && ( + + + {error} + + + )} + + ); +}; export default EditCustomerDetailsModal;