Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2주차] 송지석 미션 제출합니다. #5

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 22 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,28 @@ import React, { useState, useEffect } from "react";
import TodoList from "./components/todoList";
import DoneList from "./components/doneList";
import InputTodo from "./components/inputTodo";
import { createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
main {
display: flex;
flex-direction: column;
width: 400px;
height: 620px;
margin: 30px auto;
padding: 25px;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 15px;
}

h1 {
font-size: 35px;
color: #000000;
text-align: center;
margin-bottom: 20px;
}
`;
function App() {
const [todos, setTodos] = useState([]);
const [dones, setDones] = useState([]);
Expand Down Expand Up @@ -45,6 +66,7 @@ function App() {

Copy link

Choose a reason for hiding this comment

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

boolean 값으로 완료 여부 관리하는 state 하나 설정해주고 그 설정에 따라 특정 값만 출력하는 식으로 하면 코드가 간결해질 것 같아요!

return (
<>
<GlobalStyle />
<main>
<h1>할 일</h1>
<InputTodo addTodo={addTodo} />
Expand Down
38 changes: 38 additions & 0 deletions src/components/doneList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import ItemList from "./itemList";
import styled from 'styled-components';

const ListSection = styled.section`
display: flex;
flex-direction: column;
height: 170px;
overflow-y: auto;
Copy link

Choose a reason for hiding this comment

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

overflow-y를 auto로 해두었을 때, scroll이 생기기 전과 후에 스크롤 넓이 때문에 버튼의 위치가 달라지는데,
scrollbar-width: none 혹은 width 지정을 통해 scroll이 있을 때와 없을 때 위치 변화가 없게 해주면 좋을 것 같아요!

margin-bottom: 20px;
`;

const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
`;

function DoneList({ dones, switchList, deleteItem }) {
return (
<Container>
<h2>Done</h2>
<ListSection>
{dones.map((done, index) => (
<ItemList
key={index}
item={done.text}
index={index}
switchList={() => switchList("dones", index)}
deleteItem={() => deleteItem("dones", index)}
/>
))}
</ListSection>
</Container>
);
}

export default DoneList;
68 changes: 68 additions & 0 deletions src/components/inputTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useState } from 'react';
import styled from 'styled-components';

const AddButton = styled.button`
width: 90px;
padding: 13px;
margin-left: 25px;
border: none;
background-color: #000000;
color: #fff;
border-radius: 5px;
line-height: 18px;

&:hover {
background-color: #FF2D00;
}
`;

const TodoInput = styled.input`
width: 240px;
padding: 10px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 18px;
line-height: 18px;

&:focus {
border-color: #007bff;
}
`;

const TodoContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
`;

function InputTodo({ addTodo }) {
const [input, setInput] = useState('');

const addTodoTrim = () => {
if (input.trim().length > 0) {
addTodo(input.trim());
setInput('');
}
};

const enterKey = (e) => {
if (e.key === 'Enter') {
addTodoTrim();
}
};
Comment on lines +49 to +53

Choose a reason for hiding this comment

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

form태그로 감싸면 엔터 키를 눌렀을때 폼 제출이 발생해서 따로 엔터 키 처리를 하지 않아도 될 것 같아요! 참고해보시면 될것 같습니다~

Copy link

Choose a reason for hiding this comment

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

조건문 처리를 해준 김에 빈칸으로 제출될 시 alert 창이나 스낵바를 이용해 할 일을 입력해달라는 안내문구가 출력되면 사용자의 서비스 이해도가 올라갈 것 같습니다. trim을 적용하는 함수를 따로 만든 뒤 제출했을 때 적용하는 것도 좋지만, 제출 조건이 충족되는 것을 확인한 trim 조건문 안에 list에 등록되는 함수가 실행되도록 하는 방법도 좋을 것 같아요!


return (
<TodoContainer>
<TodoInput
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={enterKey}
/>
<AddButton onClick={addTodoTrim}>Add</AddButton>
</TodoContainer>
);
}

export default InputTodo;
56 changes: 56 additions & 0 deletions src/components/itemList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import styled from 'styled-components';

const DeleteButton = styled.button`
background-color: #FFB6C1;
color: white;
border: none;
box-sizing: border-box;
padding: 6px 5px;
width: 60px;
font-size: 14px;
border-radius: 20px;
box-shadow: 0 4px 10px rgba(255, 182, 193, 0.2);
margin-right: 5px;

&:hover {
background-color: #FF69B4;
box-shadow: 0 4px 10px rgba(255, 105, 180, 0.4);
}

&:active {
box-shadow: 0 4px 10px rgba(255, 105, 180, 0.2);
}
Copy link

Choose a reason for hiding this comment

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

hover일 때와 active일 때 투명도를 다르게 주는 디테일 좋아요~!!

`;

const TodoItemContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
margin: 8px 0;
cursor: pointer;
`;

const TodoText = styled.span`
flex-grow: 1;
margin-right: 10px;
`;

const ActionsContainer = styled.div`
display: flex;
align-items: center;
`;

function ItemList({ item, index, switchList, deleteItem }) {
return (
<TodoItemContainer onClick={switchList}>
<TodoText>{item}</TodoText>
<ActionsContainer>
<DeleteButton onClick={(e) => { e.stopPropagation(); deleteItem(); }}>x</DeleteButton>
Copy link

Choose a reason for hiding this comment

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

handleDeleteClick 과 같은 함수를 따로 만들어서 이벤트 발생 시 실행되는 함수를 넣고 onClick 시에는 handleDeleteClick 함수만 불러와도 좋을 것 같아요. 개인적인 선호일 수도 있지만 저는 이 방식이 코드가 더 읽기 쉽고 유지보수하기 편해지더라구요!

</ActionsContainer>
</TodoItemContainer>
);
}

export default ItemList;
38 changes: 38 additions & 0 deletions src/components/todoList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import ItemList from "./itemList";
import styled from 'styled-components';

const ListSection = styled.section`
display: flex;
flex-direction: column;
height: 170px;
overflow-y: auto;
margin-bottom: 20px;
`;
const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
`;

function TodoList({ todos, switchList, deleteItem }) {
return (
<Container>
<h2>Todo</h2>
<ListSection>

{todos.map((todo, index) => (
<ItemList
key={index}
item={todo.text}
index={index}
switchList={() => switchList("todos", index)}
deleteItem={() => deleteItem("todos", index)}
/>
))}
</ListSection>
</Container>
);
}

export default TodoList;