fix: replaced the 'info card enabled' radio group with a switch
fix: increased width of inputs fix: avoid formik fields wiggling fix: avoid content bellow form to wiggle when editing fix: fixed the wiggling on the fields labels fix: add ellipsis on text overflow on the contact info form fix: validate phone number, considering locale country if no country code is provided fix: contact info can now be edited independent of the "info card enabled" switch state fix: removed unused style
This commit is contained in:
parent
78f3cfd5c1
commit
37ea3a04c3
2 changed files with 81 additions and 44 deletions
|
|
@ -3,15 +3,23 @@ import { makeStyles } from '@material-ui/core'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { Form, Formik, Field as FormikField } from 'formik'
|
import { Form, Formik, Field as FormikField } from 'formik'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
import { parsePhoneNumberFromString } from 'libphonenumber-js'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
import ErrorMessage from 'src/components/ErrorMessage'
|
import ErrorMessage from 'src/components/ErrorMessage'
|
||||||
import { Link } from 'src/components/buttons'
|
import { Link } from 'src/components/buttons'
|
||||||
import RadioGroupFormik from 'src/components/inputs/formik/RadioGroup'
|
import Switch from 'src/components/inputs/base/Switch'
|
||||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||||
import { Info2, Info3, Label1, Label3 } from 'src/components/typography'
|
import {
|
||||||
|
P,
|
||||||
|
Info2,
|
||||||
|
Info3,
|
||||||
|
Label1,
|
||||||
|
Label2,
|
||||||
|
Label3
|
||||||
|
} from 'src/components/typography'
|
||||||
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
||||||
import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'
|
import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'
|
||||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||||
|
|
@ -21,36 +29,30 @@ import {
|
||||||
contactInfoStyles
|
contactInfoStyles
|
||||||
} from './OperatorInfo.styles'
|
} from './OperatorInfo.styles'
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const FIELD_WIDTH = 280
|
||||||
active: Yup.boolean(),
|
|
||||||
name: Yup.string(),
|
|
||||||
phone: Yup.string(),
|
|
||||||
email: Yup.string()
|
|
||||||
.email('Please enter a valid email address')
|
|
||||||
.required(),
|
|
||||||
website: Yup.string(),
|
|
||||||
companyNumber: Yup.string()
|
|
||||||
})
|
|
||||||
|
|
||||||
const fieldStyles = {
|
const fieldStyles = {
|
||||||
field: {
|
field: {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
width: 280,
|
width: 280,
|
||||||
height: 46,
|
height: 48,
|
||||||
padding: [[0, 4, 4, 0]]
|
padding: [[0, 4, 4, 0]]
|
||||||
},
|
},
|
||||||
notEditing: {
|
notEditing: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
'& > p:first-child': {
|
'& > p:first-child': {
|
||||||
height: 16,
|
height: 17,
|
||||||
lineHeight: '16px',
|
lineHeight: '16px',
|
||||||
transform: 'scale(0.75)',
|
transform: 'scale(0.75)',
|
||||||
transformOrigin: 'left',
|
transformOrigin: 'left',
|
||||||
paddingLeft: 0,
|
paddingLeft: 0,
|
||||||
margin: [[0, 0, 5, 0]]
|
margin: [[1, 0, 5, 0]]
|
||||||
},
|
},
|
||||||
'& > p:last-child': {
|
'& > p:last-child': {
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
margin: 0
|
margin: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +84,7 @@ const Field = ({ editing, field, displayValue, ...props }) => {
|
||||||
placeholder={field.placeholder}
|
placeholder={field.placeholder}
|
||||||
type={field.type}
|
type={field.type}
|
||||||
label={field.label}
|
label={field.label}
|
||||||
|
width={FIELD_WIDTH}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -108,6 +111,7 @@ const contactUseStyles = makeStyles(styles)
|
||||||
const ContactInfo = () => {
|
const ContactInfo = () => {
|
||||||
const [editing, setEditing] = useState(false)
|
const [editing, setEditing] = useState(false)
|
||||||
const [info, setInfo] = useState(null)
|
const [info, setInfo] = useState(null)
|
||||||
|
const [locale, setLocale] = useState(null)
|
||||||
const [error, setError] = useState(null)
|
const [error, setError] = useState(null)
|
||||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||||
onCompleted: data => {
|
onCompleted: data => {
|
||||||
|
|
@ -120,6 +124,7 @@ const ContactInfo = () => {
|
||||||
useQuery(GET_CONFIG, {
|
useQuery(GET_CONFIG, {
|
||||||
onCompleted: data => {
|
onCompleted: data => {
|
||||||
setInfo(fromNamespace(namespaces.OPERATOR_INFO, data.config))
|
setInfo(fromNamespace(namespaces.OPERATOR_INFO, data.config))
|
||||||
|
setLocale(fromNamespace(namespaces.LOCALE, data.config))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -133,13 +138,24 @@ const ContactInfo = () => {
|
||||||
|
|
||||||
if (!info) return null
|
if (!info) return null
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
active: Yup.boolean(),
|
||||||
|
name: Yup.string(),
|
||||||
|
phone: Yup.string().test(
|
||||||
|
'phone',
|
||||||
|
'Please enter a valid phone number',
|
||||||
|
function(phone) {
|
||||||
|
return parsePhoneNumberFromString(phone, locale.country).isValid()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
email: Yup.string()
|
||||||
|
.email('Please enter a valid email address')
|
||||||
|
.required(),
|
||||||
|
website: Yup.string(),
|
||||||
|
companyNumber: Yup.number()
|
||||||
|
})
|
||||||
|
|
||||||
const fields = [
|
const fields = [
|
||||||
{
|
|
||||||
name: 'active',
|
|
||||||
label: 'Info Card Enabled',
|
|
||||||
value: String(info.active),
|
|
||||||
component: RadioGroupFormik
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Full name',
|
label: 'Full name',
|
||||||
|
|
@ -149,7 +165,11 @@ const ContactInfo = () => {
|
||||||
{
|
{
|
||||||
name: 'phone',
|
name: 'phone',
|
||||||
label: 'Phone number',
|
label: 'Phone number',
|
||||||
value: info.phone ?? '',
|
value:
|
||||||
|
parsePhoneNumberFromString(
|
||||||
|
info.phone,
|
||||||
|
locale.country
|
||||||
|
).formatInternational() ?? '',
|
||||||
component: TextInputFormik
|
component: TextInputFormik
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -179,7 +199,7 @@ const ContactInfo = () => {
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
initialValues: {
|
initialValues: {
|
||||||
active: findValue('active'),
|
active: info.active,
|
||||||
name: findValue('name'),
|
name: findValue('name'),
|
||||||
phone: info.phone ?? '',
|
phone: info.phone ?? '',
|
||||||
email: findValue('email'),
|
email: findValue('email'),
|
||||||
|
|
@ -192,15 +212,32 @@ const ContactInfo = () => {
|
||||||
<>
|
<>
|
||||||
<div className={classes.header}>
|
<div className={classes.header}>
|
||||||
<Info2>Contact information</Info2>
|
<Info2>Contact information</Info2>
|
||||||
{!editing && (
|
|
||||||
<div>
|
|
||||||
<button onClick={() => setEditing(true)}>
|
|
||||||
<EditIcon />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.section}>
|
<div className={classes.section}>
|
||||||
|
<div className={classes.switchRow}>
|
||||||
|
<P>Info card enabled?</P>
|
||||||
|
<div className={classes.switch}>
|
||||||
|
<Switch
|
||||||
|
checked={info.active}
|
||||||
|
onChange={event =>
|
||||||
|
save({
|
||||||
|
active: event.target.checked
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Label2>{info.active ? 'Yes' : 'No'}</Label2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={classes.header}>
|
||||||
|
<Info2>Info card</Info2>
|
||||||
|
{!editing && (
|
||||||
|
<div className={classes.transparentButton}>
|
||||||
|
<button onClick={() => setEditing(true)}>
|
||||||
|
<EditIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<Formik
|
<Formik
|
||||||
enableReinitialize
|
enableReinitialize
|
||||||
initialValues={form.initialValues}
|
initialValues={form.initialValues}
|
||||||
|
|
@ -211,19 +248,6 @@ const ContactInfo = () => {
|
||||||
setError(null)
|
setError(null)
|
||||||
}}>
|
}}>
|
||||||
<Form>
|
<Form>
|
||||||
<div className={classnames(classes.row, classes.radioButtonsRow)}>
|
|
||||||
<Field
|
|
||||||
field={findField('active')}
|
|
||||||
editing={editing}
|
|
||||||
displayValue={it => (it === 'true' ? 'On' : 'Off')}
|
|
||||||
options={[
|
|
||||||
{ display: 'On', code: 'true' },
|
|
||||||
{ display: 'Off', code: 'false' }
|
|
||||||
]}
|
|
||||||
className={classes.radioButtons}
|
|
||||||
resetError={() => setError(null)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={classes.row}>
|
<div className={classes.row}>
|
||||||
<Field
|
<Field
|
||||||
field={findField('name')}
|
field={findField('name')}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { offColor } from 'src/styling/variables'
|
|
||||||
import typographyStyles from 'src/components/typography/styles'
|
import typographyStyles from 'src/components/typography/styles'
|
||||||
import theme from 'src/styling/theme'
|
import theme from 'src/styling/theme'
|
||||||
|
import { offColor } from 'src/styling/variables'
|
||||||
|
|
||||||
const { p } = typographyStyles
|
const { p } = typographyStyles
|
||||||
|
|
||||||
|
|
@ -24,6 +24,7 @@ const styles = {
|
||||||
},
|
},
|
||||||
row: {
|
row: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
marginBottom: 28,
|
marginBottom: 28,
|
||||||
width: 600,
|
width: 600,
|
||||||
|
|
@ -31,9 +32,21 @@ const styles = {
|
||||||
marginBottom: 0
|
marginBottom: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
switchRow: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 28,
|
||||||
|
width: 600
|
||||||
|
},
|
||||||
|
switch: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginLeft: 120
|
||||||
|
},
|
||||||
submit: {
|
submit: {
|
||||||
justifyContent: 'flex-start',
|
justifyContent: 'flex-start',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
height: 19,
|
||||||
padding: [[0, 4, 4, 4]],
|
padding: [[0, 4, 4, 4]],
|
||||||
'& > button': {
|
'& > button': {
|
||||||
marginRight: 40
|
marginRight: 40
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue