JSFiddle - React, Tailwind, and code Playground

by Pixie_Dust

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List App</title>
    <!-- Custom css -->
    <link rel="stylesheet" href="style.css">
    <!-- fontawesome script-->
    <script src="https://kit.fontawesome.com/39350fd9df.js"></script>
  </head>

  <body>

    <div class="main-container">
      <h2 class="title">Todo App</h2>
      <div class="container">
        <div class="input-group">
          <input type="text" id="todoInput" placeholder="Enter new task...">
          <a href="#" class="btn addBtn"><i class="fas fa-plus"></i></a>
        </div>
        <table class="taskLister">
          <thead>
            <tr>
              <th>Status</th>
              <th>Task</th>
              <th>Edit</th>
              <th>Delete</th>
            </tr>
          </thead>
          <tbody id="tasks"></tbody>
        </table>
      </div>
    </div>

    <!-- Custom script -->
    <script src="app.js"></script>
  </body>

</html>

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  list-style: none;
}

:root {
  --primary-color: #143d59;
  --bg-color: #f4b41a;
  --text-font: Poppins;
  --round: 5px;
}

body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn {
  /* min-width: 20%; -- why is this not working? */
  padding: .8em 2em;
  font-size: 1.25em;
  font-weight: bold;
  border-radius: var(--round);
  color: var(--bg-color);
  background-color: var(--primary-color);
}

.main-container {
  min-width: 50vw;
  min-height: 75vh;
  padding: 0 2em;
  background-color: var(--bg-color);
  border-radius: var(--round);
}

.main-container .title {
  padding-top: .8em;
  color: var(--primary-color);
  font-size: 2em;
  font-family: var(--text-font);
  text-transform: uppercase;
  text-align: center;
}

.main-container #todoInput {
  margin-top: 1em;
  padding: .8em;
  border: transparent;
  font-size: 1.25em;
  min-width: 80%;
  border-radius: var(--round);
  outline: transparent;
}

.main-container #todoInput:focus {
  box-shadow: 0px 0px 0px 1px #1c577e;
}

.main-container .container {
  text-align: center;
}

.addBtn {
  padding: .8em 1em;
  transition: .3s linear;
}

.addBtn:hover {
  background-color: #182c3a;
  color: #f5b00e;
}

.taskLister {
  margin-top: 2em;
  border-collapse: collapse;
  background-color: #fff;
  min-width: 100%;
  font-size: 1.15em;
}

.taskLister th {
  background-color: #182c3a;
  color: var(--bg-color);
}

.taskLister th,
.taskLister td {
  padding: .8em 1em;
}

.taskLister #tasks tr:nth-child(even) {
  background-color: #e7e7e7;
}

/* standalone styles */
#editBtn,
#deleteBtn,
#saveBtn {
  background-color: transparent;
  font-size: 1.15em;
  padding: .6em .8em;
  cursor: pointer;
}

.statusIcon {
  font-weight: bold;
  color: rgb(48, 158, 81);
}

td.task {
  opacity: .6;
  text-decoration: line-through;
}

JavaScript

const taskBtn = document.querySelector('.addBtn');
taskBtn.addEventListener('click', event => {
  UI.addTask(event.currentTarget.previousElementSibling.value);
});

class UI {
  // dummy data; for now.
  static displayTasks() {
    const tasks = ['Take out trash', 'Do laundry', 'Visit part'];

    tasks.forEach(task => UI.addTask(task));
  }

  static addTask(task) {
    const tbody = document.querySelector('#tasks');

    const taskRow = document.createElement('tr');
    taskRow.className += 'task';
    taskRow.innerHTML = `
            <td><i class="far fa-check-circle complete"></i></td>
            <td>${task}</td>
            <td><a href="#" class="btn" id="editBtn"><i class="fas fa-edit edit"></i></a></td>
            <td><a href="#" class="btn" id="deleteBtn"><i class="fas fa-trash delete"></i></a></td>
        `;
    tbody.appendChild(taskRow);
    document.querySelector('#todoInput').value = '';
  }

  static taskEvents(eventTarget) {
    const targetClassName = eventTarget.classList

    if (targetClassName.contains('complete')) {
      targetClassName.toggle('statusIcon');
      eventTarget.parentElement.nextElementSibling.classList.toggle('task');
    } else if (targetClassName.contains('edit')) {
      // let textEditableStatus = eventTarget.parentElement.parentElement.previousElementSibling;
      // textEditableStatus.contentEditable=true;

      // const editBtn = eventTarget.parentElement

      // const saveBtn = document.createElement('a');
      // saveBtn.className = "btn";
      // saveBtn.id = "saveBtn";
      // saveBtn.innerHTML = '<i class="fas fa-save save"></i>';

      // editBtn.replaceWith(saveBtn)

    } else if (targetClassName.contains('delete')) {
      eventTarget.parentElement.parentElement.parentElement.remove();
    }
  }
}

// Ui events 
document.addEventListener('DOMContentLoaded', UI.displayTasks);

const tbody = document.querySelector('#tasks');
tbody.addEventListener('click', event => {
  UI.taskEvents(event.target);
})