Skip to content

Commit

Permalink
feat: added edit feature on todo
Browse files Browse the repository at this point in the history
  • Loading branch information
winatungmiharja committed Sep 17, 2021
1 parent 4e1f886 commit 446d30e
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 65 deletions.
18 changes: 18 additions & 0 deletions src/components/Input/TitleInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import "./TitleInput.scss";

const TitleInput = ({ id, type, label, value, setChange }) => {
return (
<>
<div className="input-title">
<input
id={id}
type={type}
value={value}
onChange={(e) => setChange(e.target.value)}
/>
</div>
</>
);
};

export default TitleInput;
31 changes: 31 additions & 0 deletions src/components/Input/TitleInput.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@import url("https://fonts.googleapis.com/css?family=Sora:300,300i,400,400i,500,500i,700,700i,900,900i&display=swap");

%focus {
outline: 0;
}

.input-title {
position: relative;
width: 100%;
color: black;
font-size: 12px;
font-family: "Poppins", sans-serif;

input {
color: #000;
font-weight: 700;
font-size: 18px;
font-family: "Sora", sans-serif;
background-color: transparent;
border: none;
border-bottom: 1px solid black;

&:focus {
@extend %focus;
}
}

&:focus {
@extend %focus;
}
}
18 changes: 18 additions & 0 deletions src/components/InputArea/DescriptionInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import "./DescriptionInput.scss";

const DescriptionInput = ({ id, type, label, value, setChange }) => {
return (
<>
<div className="input-desc">
<textarea
id={id}
type={type}
value={value}
onChange={(e) => setChange(e.target.value)}
/>
</div>
</>
);
};

export default DescriptionInput;
28 changes: 28 additions & 0 deletions src/components/InputArea/DescriptionInput.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
%focus {
outline: 0;
}
.input-desc {
padding-top: 20px;
textarea {
background-color: transparent;
box-sizing: border-box;

padding: 0.5em;
font-family: "Poppins", sans-serif;
min-width: 100%;
font-size: 12px;
&:focus {
@extend %focus;
}
}
textarea:placeholder {
font-family: "Poppins", sans-serif;
color: #ccc;
&:focus {
@extend %focus;
}
}
&:focus {
@extend %focus;
}
}
37 changes: 22 additions & 15 deletions src/data/Todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const addTodo = (state, info) => {
type: info.type,
};
id++;
return { ...state, todo: [...state.todo, newData] };
return { ...state, todo: [newData, ...state.todo] };
};

const updateItem = (state, info) => {
const updateStatus = (state, info) => {
const newData = {
...info.item,
status: info.status,
Expand All @@ -32,6 +32,21 @@ const updateItem = (state, info) => {
};
};

const updateData = (state, info) => {
console.log(info.item);
const newState = state[info.item.status].map((key) => {
if (key.id === info.item.id) {
return { ...info.item };
} else {
return { ...key };
}
});
return {
...state,
[info.item.status]: [...newState],
};
};

const deleteItem = (state, info) => {
let deleteStatus = state[info.item.status].filter(
(item) => item.id !== info.item.id
Expand All @@ -47,24 +62,16 @@ const intialState = {
completed: [],
};

// action.data {
// status : " ",
// item : {
// ...
// }
// }

const reducer = (state, action) => {
switch (action.type) {
case "ADD TODO":
let text = addTodo(state, action.data);
return text;
return addTodo(state, action.data);
case "UPDATE STATUS":
let text1 = updateItem(state, action.data);
return text1;
return updateStatus(state, action.data);
case "UPDATE DATA":
return updateData(state, action.data);
case "DELETE TODO":
let text2 = deleteItem(state, action.data);
return text2;
return deleteItem(state, action.data);
default:
return state;
}
Expand Down
23 changes: 8 additions & 15 deletions src/view/NewTodoCard/NewTodoCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,9 @@ const NewTodoCard = (params) => {
}
};

const setTitle = (title) => {
const setChange = (option, value) => {
setTask((prevState) => {
return { ...prevState, title: title };
});
};
const setDescription = (description) => {
setTask((prevState) => {
return { ...prevState, description: description };
});
};
const setType = (type) => {
setTask((prevState) => {
return { ...prevState, type: type };
return { ...prevState, [option]: value };
});
};

Expand All @@ -72,18 +62,21 @@ const NewTodoCard = (params) => {
id="title"
label="title"
value={task.title}
setChange={setTitle}
setChange={(value) => setChange("title", value)}
/>
</div>
<Dropdown value={task.type} setChange={setType} />
<Dropdown
value={task.type}
setChange={(value) => setChange("type", value)}
/>
</div>
<div classname="new-description">
<p>Description</p>
<InputArea
id="description"
label="write your task's description"
value={task.description}
setChange={setDescription}
setChange={(value) => setChange("description", value)}
/>
</div>
<button onClick={checkInput} style={style}>
Expand Down
47 changes: 47 additions & 0 deletions src/view/TodoCard/ContentTodoCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Trash2, Edit } from "react-feather";

const ContentTodoCard = ({
item,
isChecked,
addToCompleted,
deleteFromBoard,
setIsEdited,
}) => {
return (
<>
<div className="todo-card-wrapper">
<div className="todo-card-check">
<h4>{item.title}</h4>
<label class="check-container">
{isChecked ? (
<input type="checkbox" checked />
) : (
<input type="checkbox" onClick={() => addToCompleted(item)} />
)}
<span class="checkmark"></span>
</label>
</div>
{item.description && (
<p className="item-description">{item.description}</p>
)}
<p></p>
<div class="todo-card-wrapper-button">
<button disabled="disabled">{item.type}</button>
<div className="button-group">
{item.status !== "completed" && (
<i onClick={() => setIsEdited(true)}>
<Edit />
</i>
)}

<i onClick={() => deleteFromBoard(item)}>
<Trash2 />
</i>
</div>
</div>
</div>
</>
);
};

export default ContentTodoCard;
57 changes: 57 additions & 0 deletions src/view/TodoCard/EditedTodoCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useState } from "react";
import { Save } from "react-feather";
import TitleInput from "../../components/Input/TitleInput";
import DescriptionInput from "../../components/InputArea/DescriptionInput";
import { useDispatchTodo } from "../../data/Todo";
import "./TodoCard.scss";

const EditedTodoCard = ({ item, setIsEdited, status }) => {
const dispatch = useDispatchTodo();
const editItem = (item) => {
dispatch({ type: "UPDATE DATA", data: { item } });
setIsEdited(false);
};
const [task, setTask] = useState({
id: item.id,
status: item.status,
type: item.type,
title: item.title,
description: item.description,
});

const setChange = (option, value) => {
setTask((prevState) => {
return { ...prevState, [option]: value };
});
};

return (
<div className="todo-card-wrapper">
<div className="todo-card-check">
<h4>
<TitleInput
value={task.title}
id="edit-title"
setChange={(value) => setChange("title", value)}
/>
</h4>
</div>
<DescriptionInput
value={task.description}
id="edit-desc"
setChange={(value) => setChange("description", value)}
/>
<p></p>
<div class="todo-card-wrapper-button">
<button disabled="disabled">{item.type}</button>
<div className="button-group">
<i onClick={() => editItem(task)}>
<Save />
</i>
</div>
</div>
</div>
);
};

export default EditedTodoCard;
42 changes: 15 additions & 27 deletions src/view/TodoCard/TodoCard.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import React, { useState } from "react";
import { Card } from "../../components/Card/Card";
import { Trash2 } from "react-feather";
import ContentTodoCard from "./ContentTodoCard";
import { useDispatchTodo } from "../../data/Todo";
import "./TodoCard.scss";
import EditedTodoCard from "./EditedTodoCard";

const TodoCard = ({ item }) => {
const [isChecked, setIsChecked] = useState(
item.status === "completed" ? 1 : 0
);
const [isEdited, setIsEdited] = useState(0);
const dispatch = useDispatchTodo();

const addToBoard = (item) => {
const addToCompleted = (item) => {
setIsChecked(true);
setTimeout(() => {
dispatch({ type: "UPDATE STATUS", data: { item, status: "completed" } });
setIsChecked(false);
}, 200);
};

const deleteFromBoard = (item) => {
dispatch({ type: "DELETE TODO", data: { item } });
};
Expand All @@ -28,29 +28,17 @@ const TodoCard = ({ item }) => {
item.status === "completed" ? "done" : "progress"
} todo-card`}
>
<div className="todo-card-wrapper">
<div className="todo-card-check">
<h4>{item.title}</h4>
<label class="check-container">
{isChecked ? (
<input type="checkbox" checked />
) : (
<input type="checkbox" onClick={() => addToBoard(item)} />
)}
<span class="checkmark"></span>
</label>
</div>
{item.description && (
<p className="item-description">{item.description}</p>
)}
<p></p>
<div class="todo-card-wrapper-button">
<button disabled="disabled">{item.type}</button>
<i onClick={() => deleteFromBoard(item)}>
<Trash2 />
</i>
</div>
</div>
{isEdited ? (
<EditedTodoCard item={item} setIsEdited={setIsEdited} />
) : (
<ContentTodoCard
item={item}
isChecked={isChecked}
addToCompleted={addToCompleted}
deleteFromBoard={deleteFromBoard}
setIsEdited={setIsEdited}
/>
)}
</div>
);
};
Expand Down
Loading

0 comments on commit 446d30e

Please sign in to comment.