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주차] 김서연 미션 제출합니다! #6

Open
wants to merge 1 commit 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
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
359 changes: 352 additions & 7 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": "^5.3.9",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
106 changes: 102 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,107 @@
import React, { useEffect, useState } from 'react';

Choose a reason for hiding this comment

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

저도 이렇게 사용했었는데 React를 적어주지 않아도 되는 걸 이번 코드 리뷰 하면서 처음 알게 됐어요!!
예린님 과제에서 문기님이 코드 리뷰 해주신 부분 참고하시면 도움 되실 것 같아요!!! 코드 리뷰

import styled from 'styled-components';
import { Font } from './styles/font';
import DateBox from './components/DateBox';
import TodayGoal from './components/TodayGoal';
import TodoInput from './components/TodoInput';
import Tasks from './components/Tasks';
function App() {
const TODO = 0;
const DONE = 1;
Comment on lines +9 to +10

Choose a reason for hiding this comment

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

state를 0 1대신 이름을 적용해서 더 알아보기 좋은 것 같아요!

const [tasks, setTasks] = useState({
12345678: {
id: '12345678',
state: TODO,
text: 'CEOS 1주차 과제 : JS로 Todo 구현하기',
},
12345679: {
id: '12345679',
state: TODO,
text: 'CEOS 2주차 과제 : React로 Todo 구현하기',
},
});
const _saveTasks = (tasks) => {
setTasks(tasks);
localStorage.setItem('tasks', tasks);
};

const _loadTasks = () => {
var tasks = JSON.parse(localStorage.getItem('tasks') || `{}`); // 저장된 tasks 정보 불러오기
// 저장된 tasks가 없을 경우 비어있는 객체 불러올 수 있도록
setTasks(tasks);
};
const _toggleTask = (id) => {
var newTasks = { ...tasks };

newTasks[id].state = 1 - newTasks[id].state; // TODO <-> DONE 상태 전환
console.log(newTasks);
_saveTasks(newTasks);
};

const _deleteTask = (id) => {
var newTasks = { ...tasks };
delete newTasks[id]; //id가 key값인 객체 삭제
_saveTasks(newTasks);
};
const _addTask = (text) => {
if (text.trim() === '') {
return;
}
var newId = Date.now();
Comment on lines +41 to +50

Choose a reason for hiding this comment

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

혹시 여기서 newTasksnewId에서 var를 사용하신 이유가 따로 있으실까용???


/* 변수의 value값을 JS의 key값으로 사용하는 방법
https://koonsland.tistory.com/146 */

_saveTasks({
...tasks,
[newId]: {
id: [newId],
state: TODO,
text: text,
},
});
};
useEffect(() => {
//_loadTasks();
}, []);

console.log(tasks);
return (
<div>
<h1>17기 프론트 화이팅~ 우하하</h1>
</div>
<Background>
<MainBox>
<DateBox />
<TodayGoal />
<TodoInput _addTask={_addTask} />
<Tasks
tasks={tasks}
_toggleTask={_toggleTask}
_deleteTask={_deleteTask}
/>
</MainBox>
</Background>

Choose a reason for hiding this comment

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

전 이번 과제하면서 컴포넌트를 어떻게 나눌까 고민이 많았는데
서연 님 직관적이게 컴포넌트를 잘 나누신 것 같아요! 배워갑니다:)

);
}
const Background = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100vw;
`;

const MainBox = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;

padding: 5vh 5vw;
box-shadow: 0px 4px 4px rgba(45, 45, 45, 0.45);
width: 90vw;
height: 100vh;

max-width: 600px;
`;

export default App;
export default App;
11 changes: 11 additions & 0 deletions src/assets/images/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/assets/images/cherry-blossom.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/images/delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/uncheck.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions src/components/DateBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import { Font } from '../styles/font';
export default function DateBox() {
let days = [
'SUNDAY',
'MONDAY',
'TUESDAY',
'WEDNESDAY',
'THURSDAY',
'FRIDAY',
'SATURDAY',
];

let months = [
'',
'JANUARY',
'FEBRUARY',
'MARCH',
'APRILL',
'MAY',
'JUNE',
'JULY',
'AUGUST',
'SEMTEMBER',
'OCTOBER',
'NOBEMBER',
'DESEMBER',
];

const [currentMonthText, setCurrentMonthText] = useState('MARCH');
const [currentMonth, setCurrentMonth] = useState(0);
const [currentDate, setCurrentDate] = useState(0);
const [currentDay, setCurrentDay] = useState('MON');

useEffect(() => {
let today = new Date();

setCurrentMonth(today.getMonth() + 1);
setCurrentDate(today.getDate());

let currentDayIdx = today.getDay();
setCurrentDay(days[currentDayIdx]);
setCurrentMonthText(months[currentMonth]);
}, []);
return (
<Col>
<HeadLine fontSize={'var(--font-size-lg)'} color={`var(--pink)`}>
{currentMonthText}
</HeadLine>
<Row>
<Font fontSize={'var(--font-size-ml)'} color={`var(--gray)`}>
{currentMonth}.{currentDate}
</Font>
&nbsp;&nbsp;&nbsp;&nbsp;
<Font fontSize={'var(--font-size-ml)'} color={`var(--gray)`}>
{currentDay}
</Font>
</Row>
</Col>
);
}

const Row = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
align-content: center;
`;

const Col = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
margin: 10px;
`;
const HeadLine = styled(Font)`

Choose a reason for hiding this comment

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

styled.(Font) 처럼 styled를 컴포넌트에도 적용을 할 수 있었군요!
저는 이번 과제에서 styled.div styled.h1 이런 식으로만 사용을 했는데,
나중에는 서연 님처럼 컴포넌트에도 적용을 해봐야겠어요 ㅎㅎ 배워갑니다!🙌

letter-spacing: 3px;
display: flex;
flex-direction: row;
justify-content: center;
align-content: center;
`;
110 changes: 110 additions & 0 deletions src/components/Tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import styled from 'styled-components';
import { Font } from '../styles/font';
import CheckIconSrc from '../assets/images/check.svg';
import DeleteIconSrc from '../assets/images/delete.svg';
import UnCheckIconSrc from '../assets/images/uncheck.svg';
export default function Tasks({ tasks, _toggleTask, _deleteTask }) {
return (
<TasksLayout>
<TaskBox>
<Font fontSize={'var(--font-size-md)'}>TO DO</Font>
<TaskContent>
{Object.values(tasks)
.filter((task) => task.state === 0)
.map(({ text, id }) => (
<TaskContentItem fontSize="var(--font-size-sm)">
<SvgIcon src={UnCheckIconSrc} onClick={() => _toggleTask(id)} />
{text}
<SvgIcon src={DeleteIconSrc} onClick={() => _deleteTask(id)} />
</TaskContentItem>
))}
</TaskContent>
</TaskBox>

<TaskBox>
<Font fontSize={'var(--font-size-md)'}>DONE</Font>
<TaskContent>
{' '}
{Object.values(tasks)
.filter((task) => task.state === 1)
.map(({ text, id }) => (
<Font fontSize="var(--font-size-sm)">
<SvgIcon
src={CheckIconSrc}
onClick={() => _toggleTask(id)}
width={'var(--font-size-sm)'}
/>

{text}
<SvgIcon
src={DeleteIconSrc}
onClick={() => _deleteTask(id)}
width={'var(--font-size-sm)'}
/>
</Font>
))}
</TaskContent>
</TaskBox>
</TasksLayout>
);
}
const TasksLayout = styled.div`
display: flex;
gap: 20px;
height: 100%;
width: 100%;

@media (max-width: 767px) {
//모바일

flex-direction: column;
justify-content: space-between;
}

@media (min-width: 1200px) {
// 데스크탑 일반
flex-direction: row;

justify-content: space-between;
}
`;
Comment on lines +58 to +71

Choose a reason for hiding this comment

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

오오 pc와 mobile 반응형 따로 구현해주신 디테일~!!👏🏻👏🏻👏🏻

Choose a reason for hiding this comment

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

모바일과 웹 반응형을 고려해주신 디테일에 감탄하고 갑니다.. 😭

Comment on lines +52 to +71

Choose a reason for hiding this comment

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

왜인지 모르겠는데 입력할 때 긴 문장이 들어가면 TODO width가 content내용만큼 늘어나더라고요 ..?? 저는 이부분
word-break : break-all; 로 처리했었는데 한번 참고 해보셔요!!


const TaskContent = styled.ul`
display: flex;
flex-direction: column;
gap: 20px;
border: 3px solid var(--medium-pink);
width: 100%;
height: 100%;
padding: 10px;
overflow-y: scroll;
list-style: none;
`;

const TaskContentItem = styled.div`
display: flex;
gap: 5px;
`;

const TaskBox = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
@media (max-width: 767px) {
//모바일

height: 50%;
}

@media (min-width: 1200px) {
// 데스크탑 일반
height: 50vh;
}
`;

const SvgIcon = styled.img`
cursor: pointer;
`;
38 changes: 38 additions & 0 deletions src/components/TodayGoal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import styled from 'styled-components';
import { Font } from '../styles/font';
export default function TodayGoal() {
return (
<Box>
<Label fontSize={'var(--font-size-md)'} color={'var(--darken-pink)'}>
TODAY GOAL
</Label>
<TextInput type="text" />
</Box>
);
}

const Box = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: center;
background-color: var(--light-pink);
width: 100%;
height: 30%;
padding: 10px;
`;
/* 상속 받아서 사용하기 */
const TextInput = styled.input`
border: none;
background: transparent;
height: 100%;
font-size: var(--font-size-md);
`;
Comment on lines +26 to +31

Choose a reason for hiding this comment

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

image

(말도 안되는 투두 입력.. 양해 부탁드립니당ㅎㅎㅎ)
오늘의 목표까지 만들어 주신 디테일 저번 주부터 너무 인상깊었습니다~!!
그런데 이렇게 길게 입력했을 때 투두 리스트에는 한 번에 잘 담겨져 보이는데 목표에서는 잘리더라구요ㅠㅠ 참고하시면 좋을 것 같아용!!💪🏻💪🏻💪🏻


const Label = styled(Font)`
font-weight: 500;
letter-spacing: 3px;

align-self: center;
`;
Loading