React

by Abdul Ahmad

HTML

<div id="app"></div>

SCSS

html, body, #app {
  height: 100%;
}

body {
  background: #20262E;
  margin: 0;
  font-family: Helvetica;
}

.button {
  padding: 5px 10px 6px;
  border: 0;
  background: teal;
  border-radius: 5px;
  color: white;
  font-weight: bold;
  
  &:hover {
    background: darken(teal, 5%);
    cursor: pointer;
  }
  
  &:active {
    background: darken(teal, 10%);
  }
  
  &.cancel {
    padding: 0;
    background: none;
    color: #aaa;
    
    &:hover {
      color: brown;
      background: none;
    }
    
    &:active {
      background: none;
    }
  }
}

.page-width {
  max-width: 600px;
  margin: 0 auto;
}

#app {
  background: #fff;
  padding: 20px;
  box-sizing: border-box;
  transition: all 0.2s;
}

.page-title {
  @extend .page-width;
  font-size: 25px;
}

.search-input {
  @extend .page-width;
  margin-top: 50px;
  display: flex;
  align-items: 'center';
}

.search-input__input {
  flex-grow: 1;
  flex-shrink: 1;
  padding: 10px;
  box-sizing: border-box;
  outline: none;
  font-size: 16px;
  box-shadow: none;
  
  &:focus {
    outline: none;
    box-shadow: none;
  }
}

.search-input__button {
  border: 1px solid teal;
  background: teal;
  color: white;
  font-weight: bold;
  padding: 10px 20px;
  
  &:hover {
    background: darken(teal, 5%);
    cursor: pointer;
  }
  
  &:active {
    background: darken(teal, 10%);
  }
}

.patient-list {
  @extend .page-width;
  margin-top: 30px;
}

.patient-result {
  padding: 12px 0 10px;
  box-sizing: border-box;
  border-top: 1px solid #eee;
  
  &:first-child {
    border: 0;
  }
  
  &:hover {
    color: teal;
    cursor: pointer;
  }
}

.patient-record {
  @extend .page-width;
  margin-top: 50px;
  
}


.back-button {
  margin-bottom: 20px;
}

.patient-list {
  
}

.patient-contacts {
  margin-top: 10px;
}

.patient-contacts__title {
  font-weight: bold;
  margin-top: 40px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  
  .add-contact {
    color: #aaa;
    font-size: 14px;
   ...

React

const allPatients = [
  { id: 1, firstName: 'Spider', lastName: 'Man', contacts: [] },
  { id: 2, firstName: 'Thor', lastName: 'Odinson', contacts: [] },
  { id: 3, firstName: 'Hulk', lastName: 'Stuff', contacts: [] },
  { id: 4, firstName: 'Iron', lastName: 'Man', contacts: [] },
  { id: 5, firstName: 'Agent', lastName: 'Romanof', contacts: [] },
];
  
class PageTitle extends React.PureComponent {
  render() {
		return (
    	<h2 className='page-title'>{this.props.text}</h2>
    );
  }
}

class SearchInput extends React.PureComponent {
	render() {
  	const { onChange, value } = this.props;
  	return (
    	<div className='search-input'>
    	  <input 
          className='search-input__input'
          onChange={onChange}
          value={value} />
        <button className='search-input__button'>
          Search
        </button>
    	</div>
    );
  }
}

class Patients extends React.PureComponent {
	get patients() {
  	const { searchTerm, patientClick } = this.props;
    return allPatients.filter(i => {
    	return (
      	i.firstName.toLowerCase().includes(searchTerm)
        || i.lastName.toLowerCase().includes(searchTerm)
      );
    }).map((p, i) => (
    	<li 
        className='patient-result' 
        key={i} 
        onClick={() => patientClick({ patient: p })}>
        {p.firstName} {p.lastName}
      </li>
    ));
  }
  
	render() {
    return (
    	<ul className='patient-list'>
    	  {this.patients}
    	</ul>
    );
  }
}

class Patient extends React.PureComponent {
	constructor(props) {
  	super(props);
    this.state = {
    	newContactRowVisible: false,
      firstName: '',
      lastName: '',
      relationship: '',
    };
  }
  
  showNewContactRow = () => {
  	this.setState({ newContactRowVisible: true });
  }
  
  hideNewContactRow = () => {
    this.setState({ 
    	newContactRowVisible: false,
      firstName: '',
      lastName: '',
      relationship: '',
    });
  }
  
  createNewContact = () => {
  	const { firstName, lastName,...