Skip to content

Commit

Permalink
feat: contact information form
Browse files Browse the repository at this point in the history
  • Loading branch information
Mecrano committed Jun 18, 2024
1 parent 4e00626 commit c13dc58
Show file tree
Hide file tree
Showing 16 changed files with 325 additions and 7 deletions.
3 changes: 2 additions & 1 deletion messages/context.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"address-form.field.municipalityDelegation": "Municipality/Delegation",
"address-form.field.province": "Province",
"address-form.field.receiverName": "Recipient",
"address-form.field.county": "County"
"address-form.field.county": "County",
"address-form.field.contactId": "Contact Id"
}
3 changes: 2 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"address-form.field.municipalityDelegation": "Municipality/Delegation",
"address-form.field.province": "Province",
"address-form.field.receiverName": "Recipient",
"address-form.field.county": "County"
"address-form.field.county": "County",
"address-form.field.contactId": "Contact Id"
}
3 changes: 2 additions & 1 deletion messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"address-form.field.municipalityDelegation": "Municipio/Delegación",
"address-form.field.province": "Provincia",
"address-form.field.receiverName": "Destinatario",
"address-form.field.county": "Condado"
"address-form.field.county": "Condado",
"address-form.field.contactId": "Id de Contacto"
}
43 changes: 40 additions & 3 deletions react/AddressContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ import { AddressContext } from './addressContainerContext'
import { injectRules } from './addressRulesContext'

class AddressContainer extends Component {
constructor(props) {
super(props)
this.contactInfo = {
id: null,
email: null,
firstName: null,
lastName: null,
document: null,
phone: null,
documentType: null,
}
}

componentDidMount() {
if (
this.props.shouldHandleAddressChangeOnMount &&
Expand Down Expand Up @@ -106,12 +119,34 @@ class AddressContainer extends Component {
onChangeAddress(validatedAddress, ...args)
}

handleContactInfoChange = (field) => {
return (this.contactInfo = {
...this.contactInfo,
...field,
})
}

render() {
const { children, Input, address } = this.props
const { handleAddressChange } = this
const { children, Input, address, handleCompleteOmnishipping } = this.props
const { handleAddressChange, handleContactInfoChange, contactInfo } = this

if (!address?.contactId?.value) {
address.contactId = { value: null }
} else {
address.contactId = { value: address.contactId.value }
}

return (
<AddressContext.Provider value={{ address, handleAddressChange, Input }}>
<AddressContext.Provider
value={{
address,
contactInfo,
handleContactInfoChange,
handleCompleteOmnishipping,
handleAddressChange,
Input,
}}
>
{children}
</AddressContext.Provider>
)
Expand All @@ -136,6 +171,8 @@ AddressContainer.propTypes = {
autoCompletePostalCode: PropTypes.bool,
shouldHandleAddressChangeOnMount: PropTypes.bool,
shouldAddFocusToNextInvalidField: PropTypes.bool,
contactInfo: PropTypes.object,
handleCompleteOmnishipping: PropTypes.func,
}

export default injectRules(AddressContainer)
209 changes: 209 additions & 0 deletions react/ContactInfoForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import React, { useEffect, useState } from 'react'

import styles from './ContactInfoForm.module.css'

const Input = ({
id,
label,
type = 'text',
value = '',
name = '',
onChange = (_) => {},
}) => (
<p className={`${id} input text`}>
<label htmlFor={id}>{label}</label>
<input
id={id}
autoComplete="on"
type={type}
className="input-large"
placeholder="Optional"
value={value ?? ''}
name={name ?? id}
onChange={(e) => onChange(e)}
/>
</p>
)

let gguid = 1

function getGGUID(prefix = 0) {
return `${prefix}${(gguid++ * new Date().getTime() * -1)
.toString()
.replace('-', '')}`
}

const ContactInfoForm = ({
address,
onChangeAddress,
contactInfo = {},
onChangeContactInfo = (_, __) => {},
clientProfileData,
prevContactInfo,
}) => {
const isPrevUserData = areEqual(prevContactInfo, clientProfileData)
const [useUserInfo, setUseUserInfo] = useState(
prevContactInfo?.id
? address?.contactId?.value === prevContactInfo?.id && isPrevUserData
: true
)

const [localUserInfo, setLocalUserInfo] = useState(
prevContactInfo && !isPrevUserData
? prevContactInfo
: {
email: '',
firstName: '',
lastName: '',
document: '',
phone: '',
documentType: '',
}
)

useEffect(() => {
if (address?.contactId?.value) {
return
}

address.contactId.value = getGGUID(1234)
onChangeAddress(address)
onChangeContactInfo({ id: address.contactId.value })
}, [address, onChangeAddress, onChangeContactInfo])

useEffect(() => {
if (useUserInfo) {
onChangeContactInfo({
id: address?.contactId?.value ?? '',
email: clientProfileData?.email ?? '',
firstName: clientProfileData?.firstName ?? '',
lastName: clientProfileData?.lastName ?? '',
document: clientProfileData?.document ?? '',
phone: clientProfileData?.phone ?? '',
documentType: clientProfileData?.documentType ?? '',
})
} else {
onChangeContactInfo(localUserInfo)
}

onChangeAddress(address)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
useUserInfo,
localUserInfo,
onChangeContactInfo,
clientProfileData,
onChangeAddress,
])

useEffect(() => {
// eslint-disable-next-line no-console
console.log('address contactInfo', contactInfo)
}, [contactInfo])

const handleInputChange = (e) => {
const { name, value } = e.target

setLocalUserInfo((prev) => ({ ...prev, [name]: value }))
}

return (
<div className={styles.mainContactInfoContainer}>
<label className={styles.contactInfoCheckbox}>
<input
type="checkbox"
checked={useUserInfo}
onChange={() => setUseUserInfo((prev) => !prev)}
/>
Receiver Information same as contact Information
</label>
{!useUserInfo ? (
<div className={styles.mainContactInfoForm}>
<h4 className={styles.contactInfoTitle}>Receiver Information</h4>
<div>
<Input
id="custom-contact-information-email"
label="Receiver e-mail"
name="email"
type="email"
onChange={handleInputChange}
value={localUserInfo.email ?? ''}
/>
<div className={styles.contactInfoFlex}>
<Input
id="custom-contact-information-first-name"
label="Receiver first name"
name="firstName"
onChange={handleInputChange}
value={localUserInfo.firstName ?? ''}
/>
<Input
id="custom-contact-information-last-name"
label="Receiver last name"
name="lastName"
onChange={handleInputChange}
value={localUserInfo.lastName ?? ''}
/>
</div>
<div className={styles.contactInfoFlex}>
<Input
id="custom-contact-information-document"
label="Receiver document"
name="document"
onChange={handleInputChange}
value={localUserInfo.document ?? ''}
/>
<Input
id="custom-contact-information-phone"
label="Receiver phone"
type="tel"
name="phone"
onChange={handleInputChange}
value={localUserInfo.phone ?? ''}
/>
</div>
</div>
</div>
) : null}
</div>
)
}

const areEqual = (obj1, obj2) => {
// eslint-disable-next-line no-console
console.log('obj1', obj1, obj2)
if (obj1 === obj2) {
return true
}

if (!obj1 || !obj2) {
return false
}

for (const key in obj1) {
if (key !== 'id') {
if (obj1[key] && obj1[key] !== obj2[key]) {
// eslint-disable-next-line no-console
console.log('key', key, obj1[key], obj2[key])

return false
}
}
}

return true
}

export const getPreviousContactInfo = (state) => {
const { orderForm, addressForm } = state

return (
orderForm?.shippingData?.contactInformation?.find(
({ id }) =>
addressForm?.addresses?.[addressForm?.residentialId]?.contactId
?.value === id
) ?? null
)
}

export default ContactInfoForm
40 changes: 40 additions & 0 deletions react/ContactInfoForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.mainContactInfoContainer {
}
.mainContactInfoForm {
}

.contactInfoCheckbox input {
margin: 0;
margin-right: 6px;
width: 16px;
height: 16px;
}

.contactInfoCheckbox {
display: flex;
align-items: center;
font-size: 12px;
margin-top: 16px;
margin-bottom: 12px;
}

.contactInfoTitle {
font-size: 18px !important;
font-weight: 500 !important;
}

.contactInfoFlex {
display: flex;
align-items: center;
gap: 12px;
}

.contactInfoFlex .input {
width: 100%;
}

@media (max-width: 768px) {
.contactInfoFlex {
flex-wrap: wrap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export default {
street: { value: null },
isDisposable: { value: true },
addressQuery: { value: null },
contactId: { value: null },
} as AddressWithValidation
1 change: 1 addition & 0 deletions react/__mocks__/newAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export default {
street: { value: null },
addressQuery: { value: null },
isDisposable: { value: true },
contactId: { value: null },
} as AddressWithValidation
1 change: 1 addition & 0 deletions react/__mocks__/whitespaceAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export default {
street: { value: ' ' },
addressQuery: { value: null },
isDisposable: { value: true },
contactId: { value: null },
} as AddressWithValidation
8 changes: 7 additions & 1 deletion react/addressContainerContext.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React from 'react'
import React, { useContext } from 'react'

import type { AddressWithValidation } from './types/address'

type Context = {
address: AddressWithValidation
handleAddressChange: (address: AddressWithValidation) => void
Input: React.ComponentType
contactInfo?: any
handleContactInfoChange?: any
handleCompleteOmnishipping?: any
}

export const AddressContext = React.createContext<Context | undefined>(
Expand All @@ -27,7 +30,10 @@ export function injectAddressContext<T>(
<Component
{...props}
address={ctx?.address}
contactInfo={ctx?.contactInfo}
onChangeAddress={ctx?.handleAddressChange}
onChangeContactInfo={ctx?.handleContactInfoChange}
handleCompleteOmnishipping={ctx?.handleCompleteOmnishipping}
Input={props.Input || ctx?.Input}
/>
)}
Expand Down
Loading

0 comments on commit c13dc58

Please sign in to comment.