Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vanilla Todo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="app">
<header>
<h1>To Do List</h1>
<br /></br>
<p id="date"></p>
<h4><span id="currentTask">0</span> tasks</h4>
<br /></br>
<input type="date" id="userDate">
</header>
</div>


<div class="inputContainer">
<input type="text" id="taskInput" placeholder="Add a new task">
<button id="addTaskButton">enter
<!--<i class="fa fa-plus"></i>-->
</button>

</div>

<div class="taskList">
<ul id="taskList"></ul>
</div>
<script src="script.js"></script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

script tag를 어디 위치에 사용하는지에 따라 달라지는 부분이 있습니다. deferasync 같이 다양한 속성이 있으니 기회 되실 때 찾아보셔도 좋을 거 같아요 (많이 쓰지는 않겠지만)

</body>
</html>
106 changes: 106 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
const dateElement = document.getElementById('date');
const taskInput = document.getElementById('taskInput');
const addTaskButton = document.getElementById('addTaskButton');
const taskList = document.getElementById('taskList');
const currentTask = document.getElementById('currentTask');
const userDate = document.getElementById('userDate');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1)처음 랜더링되었을 때 > (2) 날짜 선택 X > (3)그럼에도 불구하고 Todo 추가 됨

오류가 발생하고 있어요.

document.getElementById('userDate').valueAsDate = new Date();

이렇게 input date 초기 값 설정해주시면 좋을 거 같아요


let todosByDate = JSON.parse(localStorage.getItem('todos') || '{}');

function renderTasks() {
const selectedDate = userDate.value;

taskList.innerHTML = "";

const tasksForSelectedDate = todosByDate[selectedDate] || [];

tasksForSelectedDate.forEach((task, index) => {
const li = document.createElement('li');

if(task.completed){
li.classList.add('completed');
}

li.dataset.index = index;

const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = task.completed;

const span = document.createElement('span');
span.textContent = task.text;

const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';

li.appendChild(checkbox);
li.appendChild(span);
li.appendChild(deleteButton);
taskList.appendChild(li);
});

updateTaskCount();
}

function updateTaskCount() {
const selectedDate = userDate.value;
const tasksSelectedDate = todosByDate[selectedDate] || [];

const uncompletedTasks = tasksSelectedDate.filter(task => !task.completed).length;
currentTask.textContent = uncompletedTasks;
}

function addTask() {
const taskText = taskInput.value.trim();
const selectedDate = userDate.value;

if (!selectedDate) {
alert('Select a date.');
return;
}
if (taskText === '') {
alert('Please enter a task.');
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 alert 사용하신 거 좋은 거 같아요

// 날짜의 배열이 없으면 빈 배열 생성
if (!todosByDate[selectedDate]) {
todosByDate[selectedDate] = [];
}
todosByDate[selectedDate].push({text: taskText, completed: false});

taskInput.value = "";

saveData();
renderTasks();
}

function saveData() {
localStorage.setItem('todos', JSON.stringify(todosByDate));
}

addTaskButton.addEventListener('click', addTask);
taskInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
addTask();
}
});

userDate.addEventListener('change', renderTasks);

taskList.addEventListener('click', function(event) {
const targetElement = event.target;
const li = targetElement.closest('li');

const selectedDate = userDate.value;
const taskIndex = li.dataset.index;

if(targetElement.type === 'checkbox') {
todosByDate[selectedDate][taskIndex].completed = !todosByDate[selectedDate][taskIndex].completed;
}
if(targetElement.tagName === 'BUTTON') {
todosByDate[selectedDate].splice(taskIndex,1);
}

saveData();
renderTasks();
});
74 changes: 74 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
* {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 css reset property 적용하신 게 좋은 거 같아요.

https://meyerweb.com/eric/tools/css/reset/ 다양한 reset.css 코드가 있는데요, 이런 거 참고하시면 더 좋을 거 같아요.


body {
background-color: #f4f4f4;
display: grid;
justify-content: center;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

body에만 grid display를 적용하셨는데요 (나머지는 flex) 관련하여 이유가 있을까요 ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뼈대를 잡기 위해 사용했었습니다. 그러나, justify-content: center;를 쓰기 때문에 flex로 일관성 있게 하는 것이 더 나을 것 같습니다

padding: 50px;
}

header {
display: flex;
flex-direction: column;
text-align: center;
margin-bottom: 40px;
color:brown;
}

div {
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
flex-wrap: wrap;
width: 400px;

}
input[type="text"] {
padding: 10px;
width: 300px;
border: 1px solid #ccc;
border-radius: 5px;
}

input[type="date"] {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
button {
padding: 5px;
background-color: brown;
color: white;
border: none;
width: 50px;
height: 30px;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: darkred;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 hover 인터렉션 효과 추가하신 거 좋은 거 같아요

ul {
list-style-type: none;
width: 100%;
}

li {
margin-bottom: 10px;
padding: 20px;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}

li.completed span {
text-decoration: line-through;
color: gray;
}
5 changes: 5 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rewrites": [
{"source": "/(.*)", "destination": "/"}
]
}