diff --git a/.codesandbox/workspace.json b/.codesandbox/workspace.json
new file mode 100644
index 0000000..e7d06a2
--- /dev/null
+++ b/.codesandbox/workspace.json
@@ -0,0 +1,20 @@
+{
+ "responsive-preview": {
+ "Mobile": [
+ 320,
+ 675
+ ],
+ "Tablet": [
+ 1024,
+ 765
+ ],
+ "Desktop": [
+ 1400,
+ 800
+ ],
+ "Desktop HD": [
+ 1920,
+ 1080
+ ]
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..af3ca13
--- /dev/null
+++ b/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "react",
+ "version": "1.0.0",
+ "description": "React Kanban",
+ "keywords": [
+ "react",
+ "starter"
+ ],
+ "main": "src/index.js",
+ "dependencies": {
+ "prop-types": "15.7.2",
+ "react": "17.0.2",
+ "react-dom": "17.0.2",
+ "react-scripts": "4.0.0",
+ "usestate": "1.1.3"
+ },
+ "devDependencies": {
+ "@babel/runtime": "7.13.8",
+ "typescript": "4.1.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..42ae2d2
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
new file mode 100644
index 0000000..5019bae
--- /dev/null
+++ b/src/App.js
@@ -0,0 +1,77 @@
+import "./styles.css";
+import React, { useState } from "react";
+import NavBar from "./components/NavBar/NavBar";
+import TaskList from "./components/TaskList/TaskList";
+
+let idAcc = 0;
+
+const generateId = () => {
+ idAcc = idAcc + 1;
+ return idAcc;
+};
+
+export default function App() {
+ const [tasks, setTasks] = useState([]);
+
+ const addTask = (title, state) => {
+ const newTask = {
+ id: generateId(),
+ title,
+ state
+ };
+ setTasks((existingTasks) => {
+ return [...existingTasks, newTask];
+ });
+ };
+
+ const updateTask = (id, title, state) => {
+ console.log("Update tasks sendo chamado dentro de APP");
+ setTasks((existingTasks) => {
+ return existingTasks.map((task) => {
+ if (task.id === id) {
+ return { ...task, title, state };
+ } else {
+ return task;
+ }
+ });
+ });
+ };
+
+ const deleteTask = (id) => {
+ setTasks((exitingTasks) => {
+ return exitingTasks.filter((task) => task.id !== id);
+ });
+ };
+
+ return (
+
+
+
+ t.state === "Pendente")}
+ onTaskUpdate={updateTask}
+ onDeleteTask={deleteTask}
+ />
+ t.state === "Fazendo")}
+ onTaskUpdate={updateTask}
+ onDeleteTask={deleteTask}
+ />
+ t.state === "Completa")}
+ onTaskUpdate={updateTask}
+ onDeleteTask={deleteTask}
+ />
+
+
+ );
+}
diff --git a/src/components/NavBar/NavBar.js b/src/components/NavBar/NavBar.js
new file mode 100644
index 0000000..cffe381
--- /dev/null
+++ b/src/components/NavBar/NavBar.js
@@ -0,0 +1,10 @@
+import React from "react";
+import "./navbar.css";
+
+export default function NavBar() {
+ return (
+
+ );
+}
diff --git a/src/components/NavBar/navbar.css b/src/components/NavBar/navbar.css
new file mode 100644
index 0000000..fa2588f
--- /dev/null
+++ b/src/components/NavBar/navbar.css
@@ -0,0 +1,7 @@
+.navbar {
+ display: flex;
+ background-color: rgba(0, 0, 0, 0.3);
+ padding: 8px;
+ color: white;
+ font-weight: bold;
+}
diff --git a/src/components/TaskItem/TaskItem.js b/src/components/TaskItem/TaskItem.js
new file mode 100644
index 0000000..3990dd6
--- /dev/null
+++ b/src/components/TaskItem/TaskItem.js
@@ -0,0 +1,66 @@
+import React, { useState } from "react";
+import PropTypes from "prop-types";
+
+import "./task-item.css";
+
+export default function TaskItem({
+ id,
+ title,
+ taskState,
+ onTaskUpdate,
+ onDeleteTask
+}) {
+ const [isEditing, setIsEditing] = useState(false);
+ const [editableTitle, setEditableTitle] = useState(title);
+
+ const onTitleChange = (event) => {
+ const newTitle = event.target.value;
+ setEditableTitle(newTitle);
+ onTaskUpdate(id, newTitle, taskState);
+ };
+
+ const onKeyPress = (event) => {
+ if (event.key === "Enter") {
+ setIsEditing(false);
+ if (editableTitle.length === 0) {
+ onDeleteTask(id);
+ }
+ }
+ };
+
+ const onTaskStateChange = (event) => {
+ onTaskUpdate(id, title, event.target.value);
+ };
+
+ if (isEditing) {
+ return (
+
+
+
+ );
+ } else {
+ return (
+
+
setIsEditing(true)}>{editableTitle}
+
+
+ );
+ }
+}
+
+TaskItem.propTypes = {
+ id: PropTypes.number.isRequired,
+ title: PropTypes.string.isRequired,
+ taskState: PropTypes.string.isRequired,
+ onTaskUpdate: PropTypes.func.isRequired,
+ onDeleteTask: PropTypes.func.isRequired
+};
diff --git a/src/components/TaskItem/task-item.css b/src/components/TaskItem/task-item.css
new file mode 100644
index 0000000..7344587
--- /dev/null
+++ b/src/components/TaskItem/task-item.css
@@ -0,0 +1,24 @@
+.task-item {
+ background-color: #fff;
+ border-radius: 3px;
+ box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
+ cursor: pointer;
+ margin-bottom: 8px;
+ width: 100%;
+ padding: 8px 4px;
+ color: #222;
+ font-size: 14px;
+}
+
+.task-item input[type="text"] {
+ border: none;
+ font-size: 14px;
+ display: block;
+ width: 100%;
+}
+
+.task-item select {
+ display: block;
+ width: 100%;
+ margin-top: 8px;
+}
diff --git a/src/components/TaskList/TaskList.js b/src/components/TaskList/TaskList.js
new file mode 100644
index 0000000..dc6addb
--- /dev/null
+++ b/src/components/TaskList/TaskList.js
@@ -0,0 +1,50 @@
+import React from "react";
+import "./task-list.css";
+import PropTypes from "prop-types";
+
+import TaskItem from "../TaskItem/TaskItem";
+
+export default function TaskList({
+ title,
+ taskState,
+ onAddTask,
+ tasks,
+ onTaskUpdate,
+ onDeleteTask
+}) {
+ const addTask = () => {
+ onAddTask("Nova Tarefa", taskState);
+ };
+
+ return (
+
+
{title}
+
+ {tasks.map((task) => {
+ return (
+
+ );
+ })}
+ {tasks.length === 0 &&
Lista Vazia
}
+
+
+
+ );
+}
+
+TaskList.propTypes = {
+ title: PropTypes.string.isRequired,
+ onAddTask: PropTypes.func.isRequired,
+ tasks: PropTypes.array.isRequired,
+ onTaskUpdate: PropTypes.func.isRequired,
+ onDeleteTask: PropTypes.func.isRequired
+};
diff --git a/src/components/TaskList/task-list.css b/src/components/TaskList/task-list.css
new file mode 100644
index 0000000..d2fa515
--- /dev/null
+++ b/src/components/TaskList/task-list.css
@@ -0,0 +1,49 @@
+.tasklist {
+ padding: 8px;
+ background-color: #5797b9;
+ border-radius: 2px;
+}
+
+.tasklist .title {
+ padding: 4px;
+ font-weight: bold;
+ background-color: rgba(0, 0, 0, 0.1);
+ text-align: center;
+}
+
+.tasklist .content {
+ padding: 16px 4px;
+ display: flex;
+ flex-direction: column;
+}
+
+.tasklist .content .empty-list {
+ text-align: center;
+ border: 1px dashed white;
+ border-radius: 4px;
+ padding: 4px;
+}
+
+.tasklist .btn {
+ margin-top: 8px;
+ padding: 8px;
+ display: flex;
+ justify-content: center;
+ background: none;
+ border: none;
+ border-radius: 3px;
+ color: white;
+ background: #00b8d4;
+ transition: background-color 0.3s;
+}
+
+.tasklist .btn:hover {
+ background-color: #0091a8;
+ cursor: pointer;
+}
+
+.tasklist .btn img {
+ width: 15px;
+ height: 15px;
+ margin-right: 4px;
+}
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..d65892e
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,12 @@
+import { StrictMode } from "react";
+import ReactDOM from "react-dom";
+
+import App from "./App";
+
+const rootElement = document.getElementById("root");
+ReactDOM.render(
+
+
+ ,
+ rootElement
+);
diff --git a/src/styles.css b/src/styles.css
new file mode 100644
index 0000000..05b8af0
--- /dev/null
+++ b/src/styles.css
@@ -0,0 +1,55 @@
+/* Minimo CSS Reset */
+html {
+ box-sizing: border-box;
+ font-size: 16px;
+}
+
+html,
+body {
+ height: 100%;
+ min-height: 100vh;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+body,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+ol,
+ul {
+ margin: 0;
+ padding: 0;
+ font-weight: normal;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+.App {
+ font-family: sans-serif;
+ background-color: #0079bf;
+ height: 100%;
+ min-height: 100vh;
+ color: white;
+}
+
+.App .container {
+ width: 100%;
+ max-width: 800px;
+ margin: auto;
+ padding: 8px;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ grid-gap: 8px;
+}