Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0c22600
style : 스타일 초기화
hiwon-lee Sep 16, 2024
f085121
feat : 시계 컴퍼넌트
hiwon-lee Sep 16, 2024
788e4dd
feat : todo 생성, 삭제 기능
hiwon-lee Sep 17, 2024
e3bb0f2
style : 디자인 반영
hiwon-lee Sep 18, 2024
6c7139d
style : 버튼 스타일 수정 및 반영
hiwon-lee Sep 19, 2024
0508919
refactor : 변수, 기호수정
hiwon-lee Sep 19, 2024
0e1d066
feat : 메인화면 프레임 구성
hiwon-lee Sep 19, 2024
8da58e9
feat : Add progress bar
hiwon-lee Sep 19, 2024
309e75e
feat : Add toggleComplete 함수
hiwon-lee Sep 19, 2024
90ae739
build : add react-icon, styled-components
hiwon-lee Sep 20, 2024
2704357
style : 전역 디자인 수정
hiwon-lee Sep 20, 2024
6991533
feat : add progressbar
hiwon-lee Sep 20, 2024
c9c04c5
chore : edit 기능 삭제
hiwon-lee Sep 20, 2024
6e7d504
chore : edit 기능 삭제
hiwon-lee Sep 20, 2024
40f9c72
style : nav 디자인 수정
hiwon-lee Sep 20, 2024
10fb078
refactor(button) : 버튼 수정
hiwon-lee Sep 20, 2024
cbf5d17
chore : 날짜 추가
hiwon-lee Sep 20, 2024
89cae85
chore(button) : 컴퍼넌트명 수정
hiwon-lee Sep 21, 2024
b332cda
docs : 주석추가
hiwon-lee Sep 21, 2024
aaa2602
chore : ul 스타일코드 위치변경
hiwon-lee Sep 21, 2024
7c68171
chore : 미사용 import 삭제
hiwon-lee Sep 21, 2024
9ca4124
refactor : memoization
hiwon-lee Sep 21, 2024
593b319
chore : fix item order
hiwon-lee Sep 21, 2024
164f085
style : main width 줄임
hiwon-lee Sep 21, 2024
c2a555a
Update src/components/todo/TodoList.js
hiwon-lee Oct 2, 2024
9786c31
💄 ui: style
hiwon-lee Dec 8, 2024
a55319b
📝 docs: for redux
hiwon-lee Dec 8, 2024
ba530ce
🛠️ build: install redux, axios
hiwon-lee Dec 8, 2024
b3c25f9
♻️ refactor: localstorage to axios database
hiwon-lee Dec 8, 2024
859fb1f
Merge branch 'master' of https://github.com/hiwon-lee/react-todo-20th
hiwon-lee Dec 8, 2024
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
457 changes: 457 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@react-icons/all-files": "^4.1.0",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

아이콘 사용 라이브러리를 사용하셨네요! 저는 svg 파일을 따로 다운 받아서 하나하나 스타일링 했는데 이런 간편한 방법이 있다는 걸 하나 배워갑니다!! 👍🏻👍🏻

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

혹시 왜 모든 아이콘 파일을 한 번에 가져오는 라이브러리도 함께 사용하신 것일까요?-? 제가 몰랐던 라이브러리라 방금 찾아보니 @react-icons만으로도 각 아이콘 세트에서 필요한 것만 가져와서 사용할 수 있다고 나와있어 두 라이브러리 모두 설치하신 이유가 무엇인지 알고 싶습니다!!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

음 사실 처음 라이브러리 설치할 때에 실수한 부분이었는데 그게 그대로 남아있게 된 것 같아요ㅠㅠ
사실 저도 두 개의 차이점을 명확하게 알지 못했는데 이번 기회에 다시 찾아보게 되었습니다. 감사합니다 ㅎㅎ

react-icons: 필요한 아이콘만 개별적으로 가져오는 방식, 더 가볍고 효율적인 사용이 가능.
@react-icons/all-files: 모든 아이콘 파일을 한 번에 로드, 더 많은 리소스를 사용하게 됨.

관련 사이트 : react-icons
설치 명령어 :

npm install react-icons --save

"@reduxjs/toolkit": "^2.2.7",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-redux": "^9.1.2",
"react-scripts": "5.0.1",
"styled-components": "^6.1.13",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
34 changes: 29 additions & 5 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,43 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<script
type="module"
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"
></script>
<script
nomodule
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"
></script>
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<meta
name="theme-color"
content="#000000"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link
rel="apple-touch-icon"
href="%PUBLIC_URL%/logo192.png"
/>
<link
rel="stylesheet"
href="%PUBLIC_URL%/reset.css"
/>

<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link
rel="manifest"
href="%PUBLIC_URL%/manifest.json"
/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
134 changes: 134 additions & 0 deletions public/reset.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/* http://meyerweb.com/eric/tools/css/reset/
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

웹 브라우저의 기본 스타일링을 초기화해 일관된 스타일을 제공하기 위한 CSS 리셋 스타일시트를 사용하셨네요...!!!! 브라우저마다 기본적으로 제공하는 스타일이 달라 이를 통일하고 브라우저 차이로 인한 예기치 않은 디자인 문제를 방지해 원하는 디자인을 안정적으로 적용할 수 있겠네요!! 이런 개념을 희원 님의 코드 리뷰를 하며 얻어 갈 수 있어 기쁩니다... 🤩

v2.0 | 20110126
License: none (public domain)
*/

html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
background-color: #252423;
color: whitesmoke;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
button {
all: unset;
}
23 changes: 23 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
:root {
--main-color: #788bff;
--sub-color: #484644;
--bg-primary: #252525;
}

nav {
display: flex;
padding: 0.7rem 2.5rem;
background-color: #1b1a19;
font-size: 1.2rem;
gap: 0.5rem;
border-bottom: 1px solid var(--sub-color);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

var(변수명) 형식을 사용하셨네요! 저는 이것을 지난번 코드리뷰에서 알게 되었는데, 스타일 변경 등의 유지 보수에 있어 정말 유용한 개념인 것 같습니다 👍🏻👍🏻

}

main {
width: 820px;
min-height: 100vh;
margin: 0 auto;
text-align: center;
background-color: rgb(25, 25, 25);
padding: 2rem;
}
13 changes: 12 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import Todo from './components/todo/Todo';
import { IoCheckmarkSharp } from 'react-icons/io5';

import './App.css';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

App 컴포넌트에서 styled-components가 아니라 App.css 파일을 따로 만든 이유가 따로 있으실까요?-? 전역 스타일 설정 때문이실까요?!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

음.. 이건 reset.css를 활용하면서 비슷한 방식으로 적용하려고 했던 맥락이 제 머릿속에 있었던 것 같아요.
말씀하신 것처럼 전역으로 스타일을 줄 수 있다는 느낌..?을 주고싶었습니다.
근데 이 부분도 styled-components를 활용하면 좀 더 코드에 일관성이 생길것 같네요! 감사합니다~


function App() {
return (
<div className="App">
<h1>🐶CEOS 20기 프론트엔드 최고🐶</h1>
<nav>
<IoCheckmarkSharp />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

이부분을 임포트하는 이유가 있을까요?! 저는 이 라이브러리 사용할때 컴포넌트에서 바로 해당 아이콘을 임포트해서 썻거든요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

아이콘 말씀하시는거죠?! 음 그건 nav 컴퍼넌트를 만들지않아서 일단 그렇게 넣었던 것 같습니다..ㅠㅠ
말씀 들어보니 따로 컴포넌트를 두고 해당 아이콘을 바로 임포트하는게 나을것같습니다. 감사합니다ㅎㅎ

TO DO
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

이 nav 부분에 반응형 적용이 잘 안 되어 있는 것 같습니다. 🥲🥲 상대 단위를 사용하거나 화면이 작아질 때 flex 요소가 너무 좁아지지 않도록 flex-grow, flex-shrink 등을 조정해 사용해 보시면 어떨까요?!
더 나은 해결책을 발견하시면 공유 부탁 드립니다 🤩

image

Copy link
Copy Markdown
Author

@hiwon-lee hiwon-lee Sep 24, 2024

Choose a reason for hiding this comment

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

이 부분을 제가 확인해봤을 때는 nav부분에서 어떤 문제가 발생하는 지 명확히 모르겠어요ㅠㅠ
혹시 가장 오른쪽에 있는 하얀 막대같은 부분이 생기는 문제인가요?

image

이렇게 폭을 극한으로 줄였을 때 TO DO글자가 다음 줄로 줄바꿈하는 문제는 추가로 발견했습니다.

</nav>
<main>
<Todo />
</main>
</div>
);
}
Expand Down
46 changes: 46 additions & 0 deletions src/components/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import styled from 'styled-components';

export function Button({ type, children, onClick }) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

props로 {children}을 받아오셨네요! 이 특수한 props는 잘 사용을 안 했어서 몰랐는데 정말 유용한 것 같습니다. 해당 컴포넌트의 태그 사이에 넣은 내용이 모두 children으로 전달 되니 필요할 때 Button 태그를 사용한 후 버튼의 기능에 맞게 태그 안에 텍스트나 아이콘을 넣기만 하면 props로 전달 되어 렌더링 되니 버튼의 유연성이 증가하는 것 같아요! 이건 저도 꼭 사용해 봐야겠습니다 👍🏻👍🏻

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

이게 버튼에 있었군요..ㅋㅋ
발표때 왜 이걸 못찾았을까요......
민재님이 제가 얘기하고 싶었던 부분을 코드 리뷰로 다 짚어주셔서 급하게 설명할때 도움을 많이 받았답니다..ㅎㅎ

return (
<MainButton
onClick={onClick}
type={type}
>
{children} {/* children을 버튼 내부의 텍스트로 표시 */}
</MainButton>
);
}

// MainButton : 메인 버튼
const MainButton = styled.button`
font-size: 1em;
margin: 0.5em;
padding: 0.5em;
border-radius: 3px;
cursor: pointer;
background-color: transparent;
color: var(--main-color);
border: 2px solid var(--main-color);
align-items: center;
text-wrap: nowrap;
`;

// DeleteButton : 삭제 버튼
export const DeleteButton = styled(MainButton)`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MainButton에서 기본 스타일을 상속 받아 추가 스타일을 적용하고 계시네요!! 코드의 중복을 줄이고 스타일을 일관 되게 유지하는 데 좋은 것 같습니다 👍🏻 저는 버튼을 사용하는 컴포넌트에서 각각 스타일링 해주었는데 희원 님의 방식을 배워야할 것 같네요! 🔥🔥

border-radius: 1rem;
color: var(--main-color);
border-color: var(--main-color);
`;

// IsCompletedButton : 완료 토글 버튼
export const IsCompletedButton = styled(MainButton)`
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
font-size: 1.5em;
${(props) =>
props.$isCompleted === 'true' &&
`padding: 0; /* 아이콘이 들어가려면 패딩 값이 없어야 함 */
`}
`;
46 changes: 46 additions & 0 deletions src/components/Clock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useState, useEffect } from 'react';
import styled from 'styled-components';

// 날짜
const days = [
'일요일',
'월요일',
'화요일',
'수요일',
'목요일',
'금요일',
'토요일',
];
const date = new Date();
const month = date.getMonth() + 1;
const day = date.getDate();
const getDay = days[date.getDay()];

// Clock : 날짜 + 시간
export default function Clock() {
const [time, setTime] = useState(() => new Date());

useEffect(() => {
const id = setInterval(() => {
setTime(new Date());
}, 1000);
return () => clearInterval(id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

컴포넌트가 언마운트될 때 setInterval이 계속 실행되면 메모리 누수가 발생할 수 있음을 방지하기 위해 clearInterval을 호출하는 것은 좋은 습관인 것 같습니다!!!! 저도 시간을 업데이트하는 로직을 짤 때 참고해야겠어요 👍🏻🔥

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

민재님의 리액트 생애주기 발표를 듣고 저는 더 깊게 이해할 수 있었습니다 ㅎㅎㅎㅎㅎ

}, []);

return (
<StyledClock>
<p className="date">
{month}월 {day}일 {getDay}
</p>
<p>{time.toLocaleTimeString()}</p>
</StyledClock>
);
}

const StyledClock = styled.div`
display: flex;
flex-direction: column;
gap: 0.5rem;
font-size: 0.7rem;
color: rgb(220, 220, 220);
`;
Loading