React Task Manager

In this example below you will see how to do a React Task Manager with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by -J0hn-, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright -J0hn- ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>React Task Manager</title>
  
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <div id="root"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/-J0hn-/react-task-manager-qxaXeW */
@import url("https://fonts.googleapis.com/css?family=Montserrat");
*, *:before, *:after {
  box-sizing: border-box;
}

::-webkit-scrollbar {
  width: 0;
}

body, input, button {
  font-family: 'Montserrat', sans-serif;
}

body {
  height: 100vh;
}

input, select {
  color: gray;
  margin: 0 5px;
  border: none;
  padding: 5px;
  outline: none;
  background: none;
  border-bottom: solid 2px lightgray;
}
input:focus, select:focus {
  color: #53a7ee;
  border-bottom-color: #53a7ee;
}

select {
  color: #53a7ee;
}

button {
  color: white;
  cursor: pointer;
  border: none;
  padding: 5px;
  background: #53a7ee;
}

#app {
  height: 100vh;
  display: flex;
  margin: auto;
  max-width: 500px;
  background: white;
  box-shadow: 0 0 20px 1px #9e9e9e;
  flex-direction: column;
}

header {
  height: 200px;
  display: flex;
  position: relative;
  background: url("https://images.pexels.com/photos/756799/pexels-photo-756799.jpeg?h=350&auto=compress&cs=tinysrgb") no-repeat center center;
  background-size: cover;
}
header > * {
  flex: 1;
}

.task-completion {
  color: #d1d1d1;
  right: 20px;
  bottom: 12px;
  position: absolute;
  font-size: 14px;
  font-weight: 100;
}

.date {
  padding: 0 0 10px 10px;
  border-bottom: solid 4px #53a7ee;
}
.date p {
  color: white;
  height: 100%;
  display: flex;
  font-size: 40px;
  margin-top: 0;
  flex-direction: column;
  justify-content: flex-end;
}
.date p span {
  color: #d1d1d1;
  font-size: 13px;
  font-weight: initial;
}

.type-of-tasks {
  display: flex;
  background: linear-gradient(0deg, rgba(0, 0, 60, 0.6), rgba(0, 0, 0, 0.3));
  padding-right: 10px;
  justify-content: flex-end;
}
.type-of-tasks p {
  color: white;
  display: flex;
  font-size: 40px;
  align-self: center;
  align-items: flex-end;
  margin-left: 10px;
  margin-right: 10px;
  flex-direction: column;
}
.type-of-tasks p span {
  color: #d1d1d1;
  font-size: 13px;
}

/*
SEARCH FIELD
*/
#search-field {
  padding: 10px 10px;
  display: inline-block;
  margin-right: auto;
  position: relative;
}
#search-field .fa-search {
  position: absolute;
  right: 5px;
  top: 50%;
  -webkit-transform: translate(0, -50%) rotate(90deg);
          transform: translate(0, -50%) rotate(90deg);
  color: #b8b8b8;
}
#search-field input {
  color: #53a7ee;
  width: 100%;
  font-size: 14px;
}

::-webkit-input-placeholder {
  color: lightgray;
  font-style: italic;
}

/*
TASKS
*/
ul {
  padding: 0 10px;
  list-style: none;
  overflow-y: scroll;
}
ul li {
  padding: 10px 0 10px 15px;
  border-bottom: solid 1px lightgray;
}
ul li:last-child {
  border-bottom: none;
}
ul li div {
  display: flex;
  align-items: center;
}
ul li div p {
  margin: 0 auto 0 0;
  display: flex;
  font-size: 19px;
  flex-direction: column;
}
ul li div p span {
  color: #9e9e9e;
  font-size: 13px;
  margin-top: 2px;
}
ul li div button {
  color: #53a7ee;
  margin: 0 10px;
  background: none;
}

/*
ADD TASK FORM
*/
#add-task-form {
  height: 55px;
  padding: 10px;
  display: flex;
  margin-top: auto;
}
#add-task-form > * {
  flex: 1;
}
#add-task-form button {
  color: white;
  padding: 5px;
}
#add-task-form button:hover {
  background: #258fe9;
}

#edit-task-form {
  padding: 0 8px 0 0;
  display: flex;
}
#edit-task-form input {
  flex: 1;
}
#edit-task-form button {
  color: white;
}

ul li button:hover:not(.delete-btn) {
  color: #157ad1;
}

/*
CLASSES
*/
.completed {
  color: gray;
  text-decoration: line-through;
}

.delete-btn:hover {
  color: red;
}

.disable-btn {
  color: gray;
  cursor: not-allowed;
  opacity: .2;
}


/*Downloaded from https://www.codeseek.co/-J0hn-/react-task-manager-qxaXeW */
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var App = function (_React$Component) {
  _inherits(App, _React$Component);

  function App(props) {
    _classCallCheck(this, App);

    var _this = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, props));

    _this.deleteTask = function (id) {
      var _this$state = _this.state,
          tasks = _this$state.tasks,
          completedTask = _this$state.completedTask;

      var filterTasks = tasks.filter(function (task) {
        return task.id !== id;
      });
      var clearCompleted = completedTask.length > 0 && completedTask.filter(function (task) {
        return task.id !== id;
      });

      _this.setState({
        tasks: filterTasks,
        completedTask: clearCompleted
      });
    };

    _this.addTask = function (task, id, type) {
      var tasks = _this.state.tasks;


      tasks.unshift({ task: task, id: id, type: type });

      _this.setState({
        tasks: tasks
      });
    };

    _this.saveEditTask = function (task, id) {
      var tasks = _this.state.tasks;

      tasks.map(function (todo) {
        if (todo.id === id) {
          todo.task = task;
        }
      });
      _this.setState({ tasks: tasks });
    };

    _this.searchTask = function (taskName) {
      _this.setState({ searchTaskValue: taskName });
    };

    _this.completeTask = function (id) {
      var _this$state2 = _this.state,
          completedTask = _this$state2.completedTask,
          tasks = _this$state2.tasks;

      var completed = tasks.filter(function (task) {
        return task.id === id;
      });

      completedTask.push.apply(completedTask, _toConsumableArray(completed));
      _this.setState({
        completedTask: completedTask
      });
    };

    _this.state = {
      tasks: [{
        id: 1,
        task: 'Meeting Today',
        type: 'Business'
      }, {
        id: 2,
        task: 'Work Out',
        type: 'Personal'
      }, {
        id: 3,
        task: 'Learn React',
        type: 'Personal'
      }],
      searchTaskValue: '',
      completedTask: []
    };
    return _this;
  }

  _createClass(App, [{
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _state = this.state,
          tasks = _state.tasks,
          searchTaskValue = _state.searchTaskValue,
          completedTask = _state.completedTask;


      var calculateCompletedTask = completedTask.length / tasks.length * 100;
      var percentage = calculateCompletedTask.toFixed(0);
      // console.log(`${percentage}%`)

      // get todays date
      var d = new Date();
      var weekDay = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
      var months = ['Jan', 'Feb', 'Mar', 'Apr', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
      var day = weekDay[d.getDay()];
      var month = months[d.getMonth()];
      var date = d.getDate();
      var year = d.getFullYear();

      var searchFilter = tasks.filter(function (todo) {
        return todo.task.toLowerCase().includes(searchTaskValue.toLowerCase()) || todo.type.toLowerCase().includes(searchTaskValue.toLowerCase());
      });

      return React.createElement(
        'div',
        { id: 'app' },
        React.createElement(
          'header',
          null,
          React.createElement(
            'div',
            { className: 'date' },
            React.createElement(TodaysDate, { day: day, month: month, date: date, year: year })
          ),
          React.createElement(
            'div',
            { className: 'type-of-tasks' },
            React.createElement(PersonalTask, { tasks: tasks }),
            React.createElement(BusinessTask, { tasks: tasks })
          ),
          React.createElement(
            'div',
            { className: 'task-completion' },
            React.createElement(
              'span',
              null,
              percentage === 'NaN' ? 0 : percentage,
              '% done'
            )
          )
        ),
        tasks.length > 1 && React.createElement(SearchTask, { searchTask: this.searchTask }),
        React.createElement(
          'ul',
          null,
          searchFilter.map(function (todo) {
            return React.createElement(TodoTask, _extends({ key: todo.id
            }, todo, {
              deleteTask: _this2.deleteTask,
              saveEditTask: _this2.saveEditTask,
              completeTask: _this2.completeTask
            }));
          })
        ),
        React.createElement(AddTaskForm, { addTask: this.addTask })
      );
    }
  }]);

  return App;
}(React.Component);

// filter list to check type & retrieve length


var TypeCount = function TypeCount(list, type) {
  return React.createElement(
    'p',
    null,
    list.filter(function (l) {
      return l.type == type;
    }).length,
    ' ',
    React.createElement(
      'span',
      null,
      type
    )
  );
};

var PersonalTask = function PersonalTask(_ref) {
  var tasks = _ref.tasks;
  return TypeCount(tasks, 'Personal');
};
var BusinessTask = function BusinessTask(_ref2) {
  var tasks = _ref2.tasks;
  return TypeCount(tasks, 'Business');
};

var TodaysDate = function TodaysDate(_ref3) {
  var day = _ref3.day,
      month = _ref3.month,
      date = _ref3.date,
      year = _ref3.year;
  return React.createElement(
    'p',
    null,
    day,
    ' ',
    React.createElement(
      'span',
      null,
      month,
      ' ',
      date,
      ', ',
      year
    )
  );
};

var SearchTask = function (_React$Component2) {
  _inherits(SearchTask, _React$Component2);

  function SearchTask() {
    var _ref4;

    var _temp, _this3, _ret;

    _classCallCheck(this, SearchTask);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this3 = _possibleConstructorReturn(this, (_ref4 = SearchTask.__proto__ || Object.getPrototypeOf(SearchTask)).call.apply(_ref4, [this].concat(args))), _this3), _this3.searchTask = function () {
      var searchValue = _this3.searchInput.value;
      var searchTask = _this3.props.searchTask;

      searchTask(searchValue);
    }, _temp), _possibleConstructorReturn(_this3, _ret);
  }

  _createClass(SearchTask, [{
    key: 'render',
    value: function render() {
      var _this4 = this;

      return React.createElement(
        'div',
        { id: 'search-field' },
        React.createElement('input', {
          type: 'text',
          placeholder: 'Search Task',
          onChange: this.searchTask,
          ref: function ref(input) {
            return _this4.searchInput = input;
          } }),
        React.createElement('i', { className: 'fa fa-search' })
      );
    }
  }]);

  return SearchTask;
}(React.Component);

var TodoTask = function (_React$Component3) {
  _inherits(TodoTask, _React$Component3);

  function TodoTask(props) {
    _classCallCheck(this, TodoTask);

    var _this5 = _possibleConstructorReturn(this, (TodoTask.__proto__ || Object.getPrototypeOf(TodoTask)).call(this, props));

    _this5.deleteTask = function () {
      var _this5$props = _this5.props,
          id = _this5$props.id,
          deleteTask = _this5$props.deleteTask;

      deleteTask(id);
    };

    _this5.editTask = function () {
      _this5.setState({
        isEdit: true
      });
    };

    _this5.completeTask = function () {
      var _this5$props2 = _this5.props,
          completeTask = _this5$props2.completeTask,
          id = _this5$props2.id;

      completeTask(id);
      _this5.setState({
        isComplete: true
      });
    };

    _this5.saveEditTask = function (e) {
      e.preventDefault();

      var id = _this5.props.id;
      var saveEditTask = _this5.props.saveEditTask;


      if (!_this5.editInput.value) {
        null;
      } else {
        saveEditTask(_this5.editInput.value, id);
        _this5.setState({
          isEdit: false
        });
      }
    };

    _this5.state = {
      isEdit: false,
      isComplete: false
    };
    return _this5;
  }

  _createClass(TodoTask, [{
    key: 'render',
    value: function render() {
      var _this6 = this;

      var _props = this.props,
          task = _props.task,
          type = _props.type;
      var _state2 = this.state,
          isEdit = _state2.isEdit,
          isComplete = _state2.isComplete;

      var disableBtn = isComplete && 'disable-btn';

      return React.createElement(
        'li',
        null,
        isEdit ? React.createElement(
          'form',
          {
            id: 'edit-task-form',
            onSubmit: this.saveEditTask },
          React.createElement('input', {
            defaultValue: task,
            ref: function ref(editInput) {
              return _this6.editInput = editInput;
            }
          }),
          React.createElement(
            'button',
            null,
            'Save'
          )
        ) : React.createElement(
          'div',
          null,
          React.createElement(
            'p',
            {
              className: isComplete && 'completed' },
            task,
            ' ',
            React.createElement(
              'span',
              null,
              type
            )
          ),
          React.createElement(
            'button',
            {
              className: 'delete-btn',
              onClick: this.deleteTask },
            'Delete'
          ),
          React.createElement(
            'button',
            {
              className: disableBtn,
              disabled: isComplete,
              onClick: this.editTask },
            'Edit'
          ),
          React.createElement(
            'button',
            {
              className: disableBtn,
              disabled: isComplete,
              onClick: this.completeTask },
            'Complete'
          )
        )
      );
    }
  }]);

  return TodoTask;
}(React.Component);

var AddTaskForm = function (_React$Component4) {
  _inherits(AddTaskForm, _React$Component4);

  function AddTaskForm(props) {
    _classCallCheck(this, AddTaskForm);

    var _this7 = _possibleConstructorReturn(this, (AddTaskForm.__proto__ || Object.getPrototypeOf(AddTaskForm)).call(this, props));

    _this7.handleSelectChange = function (e) {
      _this7.setState({ selected: e.target.value });
    };

    _this7.addTask = function (e) {
      var addTask = _this7.props.addTask;


      e.preventDefault();

      if (!_this7.taskInput.value || !_this7.state.selected) {
        null;
      } else {
        var date = new Date();
        var id = date.getTime();
        var type = _this7.state.selected;
        addTask(_this7.taskInput.value, id, type);
        _this7.taskInput.value = '';
        _this7.setState({ selected: '' });
      }
    };

    _this7.state = {
      selected: ''
    };
    return _this7;
  }

  _createClass(AddTaskForm, [{
    key: 'render',
    value: function render() {
      var _this8 = this;

      var selected = this.state.selected;

      return React.createElement(
        'form',
        { id: 'add-task-form', onSubmit: this.addTask },
        React.createElement('input', {
          id: 'task',
          type: 'text',
          placeholder: 'Add a task',
          ref: function ref(taskInput) {
            return _this8.taskInput = taskInput;
          } }),
        React.createElement(
          'select',
          {
            value: selected,
            onChange: this.handleSelectChange
            // ref={select => this.selectOption = select}
          },
          React.createElement(
            'option',
            { value: '' },
            'Type'
          ),
          React.createElement(
            'option',
            { value: 'Personal' },
            'Personal'
          ),
          React.createElement(
            'option',
            { value: 'Business' },
            'Business'
          )
        ),
        React.createElement(
          'button',
          null,
          'Add'
        )
      );
    }
  }]);

  return AddTaskForm;
}(React.Component);

var root = document.getElementById('root');
ReactDOM.render(React.createElement(App, null), root);

Comments