<div id="app"></div>
// constanta
$text-color: black

html, body
  height: 100%
  
body
  background: #f5f5f5
  display: flex
  justify-content: center
  align-items: center
  font-family: Helvetica Neue
  font-size: 10px
  color: $text-color
  
.travel-log
  display: flex
  flex-direction: column
  &__content
    display: flex
    flex-direction: row
  &__selected
    display: flex
    align-items: center
    justify-content: center
    width: 15rem
    padding: 1rem
    border: 1px solid $text-color
    border-radius: .5rem
    margin-right: 1rem
    &--none
      font-style: italic
      font-size: 1.2rem
  &__cities
    display: flex
    flex-direction: column
    justify-content: center
    &--single
      display: flex
      align-items: center
      justify-content: space-between
      &:not(:first-of-type)
        margin-top: .5rem
      h2
        margin-right: 1rem
        font-size: 1.5rem
        cursor: pointer
        &.selected
          color: #47c97e
      &-visit
        width: 1rem
        height: 1rem
        border: 2px solid #4189f3
        border-radius: 50%
        cursor: pointer
        &.visited
          background: #4189f3
  &__alert
    display: flex
    align-items: center
    justify-content: center
    height: 2rem
    margin-bottom: .5rem
    background: #4189f3
    transition: opacity .5s ease-in
    span
      color: white
      font-size: .8rem
          
.city
  display: flex
  flex-direction: column
  justify-content: center
  align-items: center
  &__icon
    width: 8rem
    height: 9rem
    margin-bottom: 1rem
  &__info
    &--bit
      &:not(:first-of-type)
        margin-top: .5rem
      span
        font-size: 1rem
        &:first-of-type
          font-weight: bold
          margin-right: .2rem
        
    
  
View Compiled
const cities = [
  {
    id: '1',
    name: 'France',
    language: 'French',
    currency: 'Euro (€)',
    population: '66,991,000',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/paris.png'
  },
  {
    id: '2',
    name: 'Russia',
    language: 'Russian',
    currency: 'Russian Ruble (₽)',
    population: '144,463,451',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/moscow.png'
  },
  {
    id: '3',
    name: 'England',
    language: 'English',
    currency: 'Pound (£)',
    population: '54,786,300',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/london.png'
  },
  {
    id: '4',
    name: 'Argentina',
    language: 'Spanish',
    currency: 'Peso ($)',
    population: '43,417,000',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/buenos_aires.png'
  },
  {
    id: '5',
    name: 'Turkey',
    language: 'Turkish',
    currency: 'Turkish Lira (₺)',
    population: '79,814,87',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/istanbul.png'
  },
  {
    id: '6',
    name: 'New York',
    language: 'English',
    currency: 'US Dollar ($)',
    population: '8,175,133',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/new_york.png'
  },
  {
    id: '7',
    name: 'Brazil',
    language: 'Portuguese',
    currency: 'Real (R$)',
    population: '207,350,000',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/rio.png'
  },
  {
    id: '8',
    name: 'Seattle',
    language: 'English',
    currency: 'US Dollar ($)',
    population: '704,352',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/seattle.png'
  },
  {
    id: '9',
    name: 'Washington DC',
    language: 'English',
    currency: 'US Dollar ($)',
    population: '681,170',
    icon: 'https://raw.githubusercontent.com/jakepeyser/vue-mobx/master/icons/washington.png'
  }
]

class City extends React.Component {
  render() {
    const { name, icon, language, currency, population  } = this.props
    return (
      <div className="city">
        <img className="city__icon" src={icon} />
        <ul className="city__info">
          <div className="city__info--bit"><span>Name:</span>{name}</div>
          <div className="city__info--bit"><span>Language:</span>{language}</div>
          <div className="city__info--bit"><span>Currency:</span>{currency}</div>
          <div className="city__info--bit"><span>Population:</span>{population}</div>
        </ul>
      </div>
    )
  }
}

/*
 * A simple React component
 */
class TravelLog extends React.Component {
  constructor(props) {
    super(props);
    this.cities = cities;
    this.state = {
      selectedCity: null,
      visited: {},
      showAlert: false,
      clearAlert: null
    };
  }
  
  showAlert() {
    if (this.state.clearAlert) {
      clearTimeout(this.state.clearAlert)
    }
    
    const clear = setTimeout(() => {
      this.setState({
        showAlert: false,
        clearAlert: null
      })
    }, 3000)
    
    this.setState({
      showAlert: true,
      clearAlert: clear
    })
  }
  
  selectCity(cityId) {
    this.setState({
      selectedCity: cityId
    });
  }
  
  toggleCity(cityId) {
    if (this.state.visited[cityId]) {
      delete this.state.visited[cityId];
    } else {
      this.state.visited[cityId] = true;
    }
    this.showAlert()
    this.setState({
      visited: this.state.visited
    });
  }

  render() {
    return (
      <div className="travel-log">
        <div className="travel-log__alert"
          style={{ opacity: this.state.showAlert ? 1 : 0 }}>
          <span>Travel log updated!</span>
        </div>
        <div className="travel-log__content">
          <div className="travel-log__selected">
            {this.state.selectedCity
              ? <City {...this.cities.find(city => city.id === this.state.selectedCity)}/>
              : <span className="travel-log__selected--none">Please select a city</span>
            }
          </div>
          <ul className="travel-log__cities">
          {this.cities
              .sort((a, b) => a.name > b.name ? 1 : -1)
              .map(city =>
              <div className="travel-log__cities--single" key={city.id}>
                <h2 className={city.id === this.state.selectedCity ? 'selected' : ''} onClick={() => this.selectCity(city.id)}>{city.name}</h2>
                <div className={`travel-log__cities--single-visit ${this.state.visited[city.id] ? 'visited' : ''}`} onClick={() => this.toggleCity(city.id)}/>
              </div>)}
          </ul>
        </div>
      </div>
    );
  }
}

/*
 * Render the above component into the div#app
 */
React.render(<TravelLog />, document.getElementById('app'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js