Verbosity,

— Niya Panamdanam

 Maybe the Key to Better Code?

Tech Lead @ Healthie

A bit about me

@findniya 

Tech Lead, Frontend Platform

www.findniya.com

Tech Lead, Frontend Platform

Working in React with Typescript.

Serious coffee addict

DRY Code

"Dry" stands for "Don't Repeat Yourself," which is a principle in software development that encourages the elimination of redundant or duplicated code. Writing "dry code" means creating code that avoids unnecessary repetition and promotes code reusability, readability, and maintainability.

Code Sample

const LandingPage = () => {
  return (
    <div>
      <h1>Sample layout with repeating components</h1>

      <section>
        <h2>Sed ut perspiciatis</h2>
        <p>Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit
          aut fugit, sed quia consequuntur magni dolores eos qui ratione
          voluptatem sequi nesciunt. Neque porro quisquam est.</p>
        <button onClick={onClickFunction}>Click here</button>
      </section>

      <section>
        <h2>Nemo enim ipsam</h2>
        <p>Consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
          Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
          consectetur, adipisci velit, sed quia non numquam.</p>
        <button onClick={onClickFunctionTwo}>Learn More</button>
      </section>

      <section>
        <h2>Lorem ipsum dolor</h2>
        <p>Amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
          ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
          nostrud exercitation ullamco laboris nisi.</p>
        <button onClick={onClickFunctionThree}>Learn More</button>
      </section>

      <section>
        <h2>Lorem ipsum dolor</h2>
        <p>Amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
          labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
          exercitation ullamco laboris nisi.</p>
        <button onClick={onClickFunctionThree}>Learn More</button>
      </section>

    </div>
  )
}

DRY Code Sample

const Section = ({title, para, onClick, buttonText}) => (
  <section>
    <h2>{title}</h2>
    <p>{para}</p>
    <button onClick={onClick}>{buttonText}</button>
  </section>
)

const LandingPage = () => {
  return (
    <div>
      <h1>Sample layout with repeating components</h1>

      {sectionData.map((section, i)=><Section
        key={i}
        title={section.title}
        para={section.para}
        onClick={section.onClickFunctionOne}
        buttonText={section.btnText}
      />)}
      ...etc
    </div>
  )
}

Verbosity

The quality of using more words than needed; wordiness.

Concise

Giving a lot of information clearly and in a few words.

Brief but comprehensive.

    <Form onSubmit={onSubmit} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        <Field name='clientId' component='select'>
          {clients.map(client => <option value={client.id}>{client.name}</option>)}
        </Field>
        <Field name={'date'}>
          {props => <DatePicker {...props} selected={new Date()} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='startTime'>
          {props => <DatePicker {...props}
          selected={new Date()}
          showTimeSelect 
          showTimeSelectOnly 
          timeIntervals={15} 
          dateFormat="h:mm aa"
          onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='endTime'>
          {props => <DatePicker {...props}
          selected={new Date()}
          showTimeSelect 
          showTimeSelectOnly 
          timeIntervals={15} 
          dateFormat="h:mm aa"
          onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='meetingTypeId' component='select'>
          {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
        </Field>
        <Field name='meetingFormatId' component='select'>
          {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
        </Field>
        <Field name={'notes'} component='textarea' placeholder="Notes"/>
        <button type='submit' disabled={submitting || pristine}>Submit</button>
      </form>
    }
    />
  const onSubmit = async (values) => {
    try {
      const response = await axios.post('/api/accountant/createMeeting', values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
import React from 'react'
import { Field, Form } from 'react-final-form'
import DatePicker from 'react-datepicker'
import axios from 'axios'

const MeetingForm = ({ clients, meetingTypes, meetingFormats }) => {
  const onSubmit = async (values) => {
    try {
      const response = await axios.post('/api/accountant/createMeeting', values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        <Field name='email' type='text'>
          {props => <input type='email' {...props.input}/>}
        </Field>
        <Field name='clients' component='select'>
          {clients.map(client => <option value={client.id}>{client.name}</option>)}
        </Field>
        <Field name={'date'}>
          {props => <DatePicker {...props} selected={new Date()} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='startTime'>
          {props => <DatePicker {...props} 
          selected={new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} dateFormat="h:mm aa" onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='endTime'>
          {props => <DatePicker {...props} 
          selected={new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} dateFormat="h:mm aa" onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='meetingType' component='select'>
          {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
        </Field>
        <Field name='meetingFormat' component='select'>
          {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
        </Field>
        <Field name={'notes'} component='textarea' placeholder="Notes"/>
        <button type='submit' disabled={submitting || pristine}>Submit</button>
      </form>
    }
    />
  )
}
export default MeetingForm
import React from 'react'
import { Field, Form } from 'react-final-form'
import DatePicker from 'react-datepicker'
import axios from 'axios'

const MeetingForm = ({ clients, meetingTypes, meetingFormats }) => {
  const onSubmit = async (values) => {
    try {
      const response = await axios.post('/api/accountant/createMeeting')
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        <Field name='email' type='text'>
          {props => <input type='email' {...props.input}/>}
        </Field>
        <Field name='clients' component='select'>
          {clients.map(client => <option value={client.id}>{client.name}</option>)}
        </Field>
        <Field name={'date'}>
          {props => <DatePicker {...props} selected={new Date()} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='startTime'>
          {props => <DatePicker {...props} 
          selected={new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} dateFormat="h:mm aa" onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='endTime'>
          {props => <DatePicker {...props} 
          selected={new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} dateFormat="h:mm aa" onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='meetingType' component='select'>
          {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
        </Field>
        <Field name='meetingFormat' component='select'>
          {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
        </Field>
        <Field name={'notes'} component='textarea' placeholder="Notes"/>
        <button type='submit' disabled={submitting || pristine}>Submit</button>
      </form>
    }
    />
  )
}
export default MeetingForm
const clients = {
 id: ID
 name: string
 ...otherClientInformation
}[]
const meetingTypes = {
 id: ID
 label: string
 ...otherMeetingTypesInformation
}[]
const meetingFormats = {
 id:ID
 name: string
 ...otherMeetingFormatsInformation
}[]

Company growing.

Customers want more...

User Client List View

Client Calendar View

Client Dashboard View

Select clients

Select accountants

User Meeting Form

Client Meeting Form

Product Requirements

User Calendar

  • The date and start time should not be prefilled.
  • The client should be pre-selected.

 

  • On submission, we should save the form information and the current user who booked this meeting.

User Client List

  • The date and start time should not be prefilled.

 

  • On submission, we should save the form information and the client information who booked this meeting.

Client Dashboard

  • Prefill the date and start time, based on which calendar area is clicked.

 

  • On submission, we should save the form information and the client information who booked this meeting.

Client Calendar

  • Prefill the date and start time, based on which calendar area is clicked.

 

  • On submission, we should save the form information and the current user who booked this meeting.

User Calendar

  • Prefill the date and start time, based on which calendar area is clicked.

 

  • On submission, we should save the form information and the current user who booked this meeting.
const MeetingForm: React.FC = ({ clients, meetingTypes, meetingFormats, initialValues, currentUser }) => {
  const onSubmit = async (values) => {
    try {
      const updatedValues = {...values, accountantId:currentUser.id}
      const response = await axios.post('/api/accountant/createMeeting', meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
      
       ...the rest of the form fields
      
      </form>
    }
    />
  )
}
const initialValues = {
 date: Date
 startTime: Date
 endTime: Date
 clientId: null
 meetingType: null
 meetingFormat: null
 notes: null
}

User Calendar View

<Field name={'date'}>
 {props => <DatePicker {...props} 
   selected={initialValues?.date ?? new Date()} 
   onChange={e => props.input.onChange(e)}/>
 }
</Field>

<Field name='startTime'>
 {props => <DatePicker {...props}
   selected={initialValues?.date ?? new Date()}
   showTimeSelect 
   showTimeSelectOnly 
   timeIntervals={15} 
   dateFormat="h:mm aa"
   onChange={e => props.input.onChange(e)}/>
 }          
</Field>

<Field name='endTime'>
 {props => <DatePicker {...props}
   selected={initialValues?.date ?? new Date()}
   showTimeSelect 
   showTimeSelectOnly 
   timeIntervals={15} 
   dateFormat="h:mm aa"
   onChange={e => props.input.onChange(e)}/>
 }
</Field>

User Client List

  • The date and start time should not be prefilled.
  • The client should be pre-selected.

 

  • On submission, we should save the form information and the current user who booked this meeting.
const MeetingForm: React.FC = ({ clients, meetingTypes, meetingFormats, initialValues, currentUser }) => {
  const onSubmit = async (values) => {
    try {
      const updatedValues = {...values, accountantId:currentUser.id}
      const response = await axios.post('/api/createMeeing', meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
      
       ...the rest of the form fields
      
      </form>
    }
    />
  )
}
const initialValues = {
 date: null
 startTime: null
 endTime: null
 clientId: ID
 meetingType: null
 notes: null
}

User Client List

Client Dashboard

  • The date and start time should not be prefilled.

 

  • On submission, we should save the form information and the client information who booked this meeting.

Client Dashboard View


const MeetingForm: React.FC = ({ 
clients, 
meetingTypes, 
meetingFormats, 
initialValues, 
currentUser, 
accountants, 
isClientView 
}) => {
  const onSubmit = async (values) => {
    try {
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post('/api/createMeeing', meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        {isClientView
          ? <Field name='accountantId' component='select'>
            {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
          </Field>
          :<Field name='clientId' component='select'>
            {clients.map(client => <option value={client.id}>{client.name}</option>)}
          </Field>
        }
        ... the rest of the fields
      </form>
    }
    />
  )
}

Client Dashboard View


const MeetingForm: React.FC = ({ 
clients, 
meetingTypes, 
meetingFormats, 
initialValues, 
currentUser, 
accountants, 
isClientView 
}) => {

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} 
     render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        {isClientView
          ? <Field name='accountantId' component='select'>
            {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
          </Field>
          :<Field name='clientId' component='select'>
            {clients.map(client => <option value={client.id}>{client.name}</option>)}
          </Field>
        }
        ... the rest of the fields
      </form>
    }
    />
  )
}

const initialValues = {
 date: null
 startTime: null
 endTime: null
 accountantId: null
 meetingType: null
 meetingFormat: null
 notes: null
}

Client Dashboard View

 const onSubmit = async (values) => {
    try {
      const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

Client Calendar

  • Prefill the date and start time, based on which calendar area is clicked.

 

  • On submission, we should save the form information and the client information who booked this meeting.

Client Calendar View


const MeetingForm: React.FC = ({ 
clients, 
meetingTypes, 
meetingFormats, 
initialValues, 
currentUser, 
accountants, 
isClientView 
}) => {
  const onSubmit = async (values) => {
    try {
      const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        {isClientView
          ? <Field name='accountantId' component='select'>
            {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
          </Field>
          :<Field name='clientId' component='select'>
            {clients.map(client => <option value={client.id}>{client.name}</option>)}
          </Field>
        }
        ... the rest of the fields
      </form>
    }
    />
  )
}

const initialValues = {
 date: Date
 startTime: Date
 endTime: Date
 accountantId: null
 meetingType: null
 meetingFormat: null
 notes: null
}

Current Meeting Form

import React from 'react'
import { Field, Form } from 'react-final-form'
import DatePicker from 'react-datepicker'
import axios from 'axios'
const MeetingForm: React.FC = ({
  clients,
  meetingTypes,
  meetingFormats,
  initialValues,
  currentUser,
  accountants,
  isClientView,
}) => {
  const onSubmit = async (values) => {
    try {
      const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    ...Form
  )
}
export default MeetingForm

Current Meeting Form

<Form onSubmit={onSubmit} 
initialValues={initialValues} 
render={({ handleSubmit, submitting, pristine }) =>
 <form onSubmit={handleSubmit}>
  {isClientView
   ? <Field name='accountantId' component='select'>
      {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
     </Field>
   :<Field name='clientId' component='select'>
      {clients.map(client => <option value={client.id}>{client.name}</option>)}
    </Field>
  }
  <Field name={'date'}>
   {props => <DatePicker {...props} 
   selected={initialValues?.date ?? new Date()} onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='startTime'>
   {props => <DatePicker {...props} 
   selected={initialValues?.startTime ?? new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='endTime'>
   {props => <DatePicker {...props} 
   selected={initialValues?.endTime ?? new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='meetingType' component='select'>
   {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
  </Field>
  <Field name='meetingFormat' component='select'>
   {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
  </Field>
  <Field name={'notes'} component='textarea' placeholder="Notes"/>
  <button type='submit' disabled={submitting || pristine}>Submit</button>
 </form>
}
/>

Edit Booked Meeting

User Calendar

  • Prefill the form with existing meeting data.

 

  • On submission, save updated form fields.

Client Dashboard

  • Prefill the form with existing meeting data.

 

  • On submission, save updated form fields.

Client Calendar

  • Prefill the form with existing meeting data.

 

  • On submission, save updated form fields.

Updated For Edit

 const creatMeeting = async (values) =>{
    try {
     const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  const editMeeting = async (values) =>{
    try {
      const path = isClientView 
        ? '/api/accountant/editMeeting' 
        : '/api/client/editMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id, id: meetingId}
        : {...values, accountantId: currentUser.id, id:meetingId}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

Updated For Edit

 const creatMeeting = async (values) =>{
    try {
     const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  const editMeeting = async (values) =>{
    try {
      const path = isClientView 
        ? '/api/accountant/editMeeting' 
        : '/api/client/editMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id, id: meetingId}
        : {...values, accountantId: currentUser.id, id:meetingId}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
 const onSubmit = async (values) => {
    try {
      const response = meetingId === null
        ? await creatMeeting(values)
        : await editMeeting(values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
import React from 'react'
import { Field, Form } from 'react-final-form'
import DatePicker from 'react-datepicker'
import axios from 'axios'
const MeetingForm: React.FC = ({
  clients,
  meetingTypes,
  meetingFormats,
  initialValues,
  currentUser,
  accountants,
  isClientView,
  meetingId
}) => {
  const creatMeeting = async (values) =>{
    try {
     const path = isClientView 
        ? '/api/accountant/createMeeting' 
        : '/api/client/createMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id}
        : {...values, accountantId: currentUser.id}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  const editMeeting = async (values) =>{
    try {
      const path = isClientView 
        ? '/api/accountant/editMeeting' 
        : '/api/client/editMeeting'
      const updatedValues = isClientView
        ? {...values, clientId: currentUser.id, id: meetingId}
        : {...values, accountantId: currentUser.id, id:meetingId}
      const response = await axios.post(path, meetingData: updatedValues)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  const onSubmit = async (values) => {
    try {
      const response = meetingId === null
        ? await creatMeeting(values)
        : await editMeeting(values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }

  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        {isClientView
          ? <Field name='accountantId' component='select'>
            {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
          </Field>
          :<Field name='clientId' component='select'>
            {clients.map(client => <option value={client.id}>{client.name}</option>)}
          </Field>
        }
        <Field name={'date'}>
          {props => <DatePicker {...props} selected={initialValues?.date ?? new Date()} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='startTime'>
          {props => <DatePicker {...props} selected={initialValues?.startTime ?? new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='endTime'>
          {props => <DatePicker {...props} selected={initialValues?.endTime ?? new Date()} showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='meetingType' component='select'>
          {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
        </Field>
        <Field name='meetingFormat' component='select'>
          {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
        </Field>
        <Field name={'notes'} component='textarea' placeholder="Notes"/>
        <button type='submit' disabled={submitting || pristine}>Submit</button>
      </form>
    }
    />
  )
}
export default MeetingForm
  return (
    <Form onSubmit={onSubmit} initialValues={initialValues} render={({ handleSubmit, submitting, pristine }) =>
      <form onSubmit={handleSubmit}>
        {isClientView
          ? <Field name='accountantId' component='select'>
            {accountants.map(accountant => <option value={accountant.id}>{accountant.name}</option>)}
          </Field>
          :<Field name='clientId' component='select'>
            {clients.map(client => <option value={client.id}>{client.name}</option>)}
          </Field>
        }
        <Field name={'date'}>
          {props => <DatePicker {...props} 
          selected={initialValues?.date ?? new Date()} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='startTime'>
          {props => <DatePicker {...props} 
          selected={initialValues?.startTime ?? new Date()} 
          showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='endTime'>
          {props => <DatePicker {...props} 
          selected={initialValues?.endTime ?? new Date()} 
          showTimeSelect showTimeSelectOnly timeIntervals={15} onChange={e => props.input.onChange(e)}/>}
        </Field>
        <Field name='meetingType' component='select'>
          {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
        </Field>
        <Field name='meetingFormat' component='select'>
          {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
        </Field>
        <Field name={'notes'} component='textarea' placeholder="Notes"/>
        <button type='submit' disabled={submitting || pristine}>Submit</button>
      </form>
    }
    />
  )
}
export default MeetingForm

Even more...

As the business grows there can be more and more feature-specific requirements.

For Example: On List view disable date and times where the accountant already has meetings.

Common Problems

Complexity

The complexity of the component increases with each new product requirement.

1.

Debugging

Increased complexity, leads hard to read code, which makes debugging even harder.

2.

Product Locked

Each of the different product areas are now locked together. A change in one means a bug or change in the other.

3.

Developer Frustration

Developer productivity suffers and it becomes increasingly harder to make changes to the component.

Business Logic

Focuses on the rules and workflows for a user, specific to a particular business.

Developer Logic

Is the technical decisions and coding practices employed by developers to implement the business logic.

User Calendar

User Client List

Client Dashboard

Client Calendar

User Calendar

User Client List

Client Dashboard

Client Calendar

User Calendar

User Client List

1.

User clicks on Calendar day/ time slot

2.

Modal with Meeting Form appears with day/time pre-filled

3.

User inputs blank fields and submits form

4.

Meeting is booked and appears on the calendar.

1.

User clicks on Book Meeting button for a specific client.

2.

Modal with Meeting Form appears with client data pre-filled

3.

User inputs blank fields and submits form

4.

Meeting is booked.

Client Calendar

Client Dashboard

1.

Client clicks on Calendar day/ time slot

2.

Modal with Meeting Form appears with day/time pre-filled

3.

Client inputs blank fields and submits form

4.

Meeting is booked and appears on the calendar

1.

Client clicks on Book Meeting button

2.

Modal with Meeting Form appears

3.

Client inputs blank fields and submits form

4.

Meeting is booked and appears on the dashboard

Business Decisions

By making the Meeting Form Component the same for each unique feature area, the developer has made the Business Decision to make the features dependent on each other.

A Meeting Form Component for each area

Be Verbose.

Duplicate your code.

Add comments.

  • Smart parent component specific for each area.

 

  • Simple component that just renders the form.

 

  • Create duplicate component if what it renders is different.

 

  • Document your simple components.

Get concise after.

Parent Component Specific For Each Feature

const AccountantCalendarMeeting = () => {
   const creatMeeting = async (values) =>{
    ...post call for creating meeting
    }
  }
  const editMeeting = async (values) =>{
    try {
     ...poset call for editing
    }
  }
  const onSubmit = async (values) => {
    try {
      const response = meetingId === null
        ? await creatMeeting(values)
        : await editMeeting(values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  
  // fetch and format data for form dependencies.
  // handle the opening and closing of the modal
  
  return (
   <MeetingForm
    onSubmit={onSubmit}
    initialValues={initialValues}
    clients={clients}
    userId={currentUser.id}
    meetingTypes={meetingTypes}
    meetingFormats={meetingFormats}
    meetingId={meetingId ?? null}
   />
  )
}

Parent Component Specific For Client

const ClientCalendarMeeting = () => {
   const creatMeeting = async (values) =>{
    ...post call for creating meeting
    }
  }
  const editMeeting = async (values) =>{
    try {
     ...poset call for editing
    }
  }
  const onSubmit = async (values) => {
    try {
      const response = meetingId === null
        ? await creatMeeting(values)
        : await editMeeting(values)
      return response.data
    } catch (e) {
      console.error('Error creating meeting', e)
      throw e
    }
  }
  
  // fetch and format data for form dependencies.
  // handle the opening and closing of the modal
  
  return (
   <ClientMeetingForm
    onSubmit={onSubmit}
    initialValues={initialValues}
    accountants={accoutants}
    userId={currentUser.id}
    meetingTypes={meetingTypes}
    meetingFormats={meetingFormats}
    meetingId={meetingId ?? null}
   />
  )
}

Meeting Form Component, just for the Accountants.

Accountant Meeting Form Component

<Form onSubmit={onSubmit} 
initialValues={initialValues} 
render={({ handleSubmit, submitting, pristine }) =>
 <form onSubmit={handleSubmit}>
  <Field name='accountantId' component='select'>
    {accountants.map(accountant => 
    <option value={accountant.id}>{accountant.name}</option>)}
  </Field>
  <Field name={'date'}>
   {props => <DatePicker {...props} 
   selected={initialValues?.date ?? new Date()} onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='startTime'>
   {props => <DatePicker {...props} 
   selected={initialValues?.startTime ?? new Date()} 
   showTimeSelect showTimeSelectOnly timeIntervals={15} 
   onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='endTime'>
   {props => <DatePicker {...props} 
   selected={initialValues?.endTime ?? new Date()} 
   showTimeSelect showTimeSelectOnly timeIntervals={15} 
   onChange={e => props.input.onChange(e)}/>}
  </Field>
  <Field name='meetingType' component='select'>
   {meetingTypes.map(type => <option value={type.id}>{type.name}</option>)}
  </Field>
  <Field name='meetingFormat' component='select'>
   {meetingFormats.map(format => <option value={format.id}>{format.name}</option>)}
  </Field>
  <Field name={'notes'} component='textarea' placeholder="Notes"/>
  <button type='submit' disabled={submitting || pristine}>Submit</button>
 </form>
}
/>

Sample docs

Use Storybook or something like it for your component documentation

 

Image from: https://design-system.atoka.io/?path=/story/forms-form--full-form

As product grows the complexity of code doesn't have to grow.

Concise code is better.

  • Duplication is necessary. We write code for other people to read.

 

  • Add comments and docs explaining your code. Answer why you did it this way.
  • DRY your code after a certain amount of duplication.

 

  • Be ver careful that in the process of DRY code you are not making Business Decisions.

Q&A