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주차] 김지원 미션 제출합니다. #10

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
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
421 changes: 388 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"styled-components": "^6.0.8",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
Binary file modified public/favicon.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>To-Do list</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
44 changes: 39 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
import TodoList from "./TodoList";
import { styled, createGlobalStyle } from "styled-components";

function App() {
return (
<div>
<h1>18기 프론트 화이팅~ 푸하항ㅋ</h1>
</div>
);
return (
<>
<GlobalStyle />
<Wrapper>
<TodoList />
</Wrapper>
</>
);
}

export default App;

//CSS

const GlobalStyle = createGlobalStyle`
@font-face{
font-family: "양진체";
src: url("https://cdn.jsdelivr.net/gh/supernovice-lab/[email protected]/yangjin.woff")
format("woff");
font-weight: normal;
font-style: normal;
}
html, body, #root{
height: 100%;
margin: 0;
padding: 0;
}
Comment on lines +27 to +31

Choose a reason for hiding this comment

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

css reset도 꼼꼼하게 하셨군요 👍👍
스타일 리셋할때 npm i styled-reset 을 하고, reset 임포트해 createGlobalStyle에 안에 넣는 식으로 초기화화 할 수도 있을 것 같습니다!

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 저는 안했는데 저도 다음 과제에서는 해야겠어요~!

`;
Comment on lines +19 to +32
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을 해주신점 너무 좋아요!
이를 통해 통일된 디자인을 바탕으로 개발자의 의도대로 프로세싱을 할 수 있을 것 같습니다.
Styled-Component에서 사용할 수 있는 Styled-normalize 참고자료
도 있으니 한번 써보면 좋을것같습니다~!

Copy link
Author

Choose a reason for hiding this comment

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

오 문기님이 알려주신 styled-normalize 이용하면 더 쉽게 css reset 할 수 있겠네요! 피드백 감사합니다:)

const Wrapper = styled.div`
background-image: url("https://www.10wallpaper.com/wallpaper/1366x768/2106/Macos_Monterey_2021_Apple_WWDC_5K_Poster_1366x768.jpg");
height: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
font-family: "양진체";
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
`;
37 changes: 37 additions & 0 deletions src/Clock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect } from "react";
import { styled } from "styled-components";

//화면 상단 시계

const Clock = () => {
const [time, setTime] = useState(new Date());

useEffect(() => {
const id = setInterval(() => {
setTime(new Date());
Copy link
Member

Choose a reason for hiding this comment

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

이 부분은 매초 Date객체를 생성하는데, 기존의 time에서 1초를 더해주는 코드로 대체해도 괜찮을 것 같아요~!

}, 1000);
return () => clearInterval(id);
}, []);
Comment on lines +10 to +14

Choose a reason for hiding this comment

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

언마운트 될 때 clear 해준 거 좋습니다 ㅎㅎ


const timeOptions = {
Copy link
Member

Choose a reason for hiding this comment

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

저도 fns라이브러리를 사용했는데 이렇게 옵션으로 하는것도 좋은 방법인 것 같습니다~

hour12: false, // 24 시간 형식 사용
hour: "2-digit", // 항상 두자릿수로 표현
minute: "2-digit",
second: "2-digit",
};
Comment on lines +16 to +21
Copy link
Member

Choose a reason for hiding this comment

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

저는 시간이나 날짜 관련해서는 moment 라이브러리를 주로 사용해서 이러한 timeOption을 줄 수 있는지 몰랐는데, 이를 사용하는것도 좋은 방법이네요!


return (
<SectionName>
<h1>{time.toLocaleTimeString([], timeOptions)}</h1>
</SectionName>
);
};

export default Clock;

//CSS
const SectionName = styled.div`
font-size: 30px;
display: flex;
justify-content: center;
`;
90 changes: 90 additions & 0 deletions src/ListContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import TodoItem from "./TodoItem";
import { styled } from "styled-components";

const ListContainer = ({ onEdit, onDelete, moveItem, data }) => {
// isDone 값이 false인 데이터만 필터링 (todo container에 띄우기)
const todoData = data.filter((item) => !item.isDone);

Copy link
Member

Choose a reason for hiding this comment

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

전 아예 따로 만들어줬는데 isDone boolean값을 이용해서 나누는게 더 좋은 것 같습니다~!

// isDone 값이 true인 데이터만 필터링 (done container에 띄우기)
const doneData = data.filter((item) => item.isDone);

return (
<div className="ListContainer">
Copy link
Member

Choose a reason for hiding this comment

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

이번 과제에 지원님께서는 TodoBox와 DoneBox 사이를 margin값을 통해서 띄워주셨는데,
ListContinaer class에 flex값을 주고 flex layout을 적용해보면 확장성에 더욱 도움이 될 것 같습니다!

예를들어 클라이언트측에서 화면을 400 * 600에서 600 * 800으로 변경요청이 들어오면
현재의 코드상으로는 margin값들을 직접 찾아서 조정해주어야하지만,
flex layout으로 구성했다고 하면 부모 컴포넌트의 숫자만 조정해주면 됩니다.

이러한 경우를 생각해서 에자일한 개발습관을 들이는 연습 해보아도 재밌을 것 같아요~!

<Container>
<TitleContainer>
<Subtitle>"Todo 🟡"</Subtitle>
<CountTitle>
You have <CountNum>{todoData.length}</CountNum> things to do.
</CountTitle>
</TitleContainer>
<div>
{todoData &&
todoData.map((it) => (
<TodoItem
key={it.id}
{...it}
onDelete={onDelete}
onEdit={onEdit}
moveItem={moveItem}
/>
))}
</div>
</Container>
<Container>
<TitleContainer>
<Subtitle>"Done 🔵"</Subtitle>
<CountTitle>
You completed <CountNum>{doneData.length}</CountNum> things.
</CountTitle>
</TitleContainer>
<div>
{doneData &&
doneData.map((it) => (
<TodoItem
key={it.id}
{...it}
onEdit={onEdit}
onDelete={onDelete}
moveItem={moveItem}
/>
))}
</div>
</Container>
</div>
);
};

export default ListContainer;

//CSS
const Container = styled.div`
width: 20rem;
height: 10rem;

Choose a reason for hiding this comment

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

스타일링을 할 때 웹 접근성을 위해 rem 단위로 개발하신 것이 인상깊었습니다! 저도 rem 단위로 스타일링하는 습관을 들여야겠어요:)

background-color: rgba(255, 255, 255, 0.5);
padding: 2rem;
padding-bottom: 1rem;
margin-bottom: 2.5rem;
border-radius: 20px;
overflow-y: auto;
max-height: 130px;
`;

const TitleContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
`;

const Subtitle = styled.div`
font-size: 20px;
`;

const CountTitle = styled.div`
font-size: 13px;
color: grey;
`;

const CountNum = styled.span`
color: black;
`;
76 changes: 76 additions & 0 deletions src/TodoInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useState } from "react";
import { styled } from "styled-components";

const TodoInput = ({ onCreate }) => {
const [content, setContent] = useState("");

//input_box에 엔터키 입력시 함수
const handleKeyDown = (e) => {
if (e.key === "Enter") {
if (e.nativeEvent.isComposing) return;
handleSubmit();
Comment on lines +9 to +11

Choose a reason for hiding this comment

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

이벤드 핸들러의 코드가 좀 낯설어서 구글링해봤는데, 한글 입력 시 함수가 두 번 호출되는 경우까지 고려하셨네요!!
배워갑니다 👍👍

Copy link
Author

Choose a reason for hiding this comment

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

헉 맞아요! 한글만 중복 랜더링이 되어서
e.nativeEvent.isComposing을 통해 해결했어요! 링크 남겨드려용
한글중복랜더링

}
};

//새로운 데이터가 입력될 때의 함수
const handleSubmit = () => {
if (content.trim() !== "") {
onCreate(content);
setContent("");
} else {
alert("할 일을 1자 이상 입력하세요.");
Copy link
Member

Choose a reason for hiding this comment

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

Alert로 알려주는거 좋은 것 같습니다

return;
}
};

return (
<Container>
<InputBox
name="input_box"
value={content}
placeholder="type here..."
onChange={(e) => {
setContent(e.target.value);
}}
onKeyDown={handleKeyDown}
/>
<InputBtn onClick={handleSubmit}>✚</InputBtn>
</Container>
);
};
export default TodoInput;

//CSS

const Container = styled.div`
width: 380px;
padding: 0.5rem;
margin-top: 1.5rem;
margin-bottom: 1.5rem;
Comment on lines +48 to +49

Choose a reason for hiding this comment

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

컴포넌트에 margin 값을 설정할 때, 되도록이면 한 방향으로 하는 게 이후에 발생할 수도 있는 마진겹침 현상을 예방할 수 있다고 합니다! 혹은 margin 자체를 아예 컴포넌트 단위로 설정하여, 컴포넌트의 재사용성을 늘릴 수도 있을 거 같습니당
참고자료1

display: flex;
justify-content: center;
align-items: center;
`;

const InputBox = styled.input`
width: 200px;
flex: 1;
padding: 0.8rem;
Copy link
Member

Choose a reason for hiding this comment

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

지원님은 다 rem으로 하셔서 좋은 것 같습니다..! 저는 아직 익숙하지가 않아 사용하지 못했는데 저도 앞으로 사용하는 연습을 해야할 것 같아요!

border: none;
outline: none;
border-radius: 10px;
`;

const InputBtn = styled.button`
width: 40px;
background-color: black;
color: #ffffff;
border: none;
border-radius: 10px;
padding: 0.8rem;
cursor: pointer;
margin-left: 10px;
&:hover {
background-color: gray; /* 마우스 호버 시 배경색 변경 */
}
`;
Loading