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

[3주차] 전시원 미션 제출합니다. #23

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c6feae2
[⌚️feat] : Init project
Mar 24, 2022
f5b938e
[⌚️feat] : Add list
Mar 24, 2022
4427d83
[⌚️feat] : Save data
Mar 24, 2022
4b54ec9
[⌚️feat] : Add toggle
Mar 24, 2022
e8bbcba
[⌨️chore] : Modify rendering style
Mar 24, 2022
6b36e58
[⌚️feat] : Add delete button
Mar 24, 2022
28017c7
[⌚️feat] : Add count number of list
Mar 24, 2022
bb2753b
[📱fix] : Fix localStorage save updating
Mar 24, 2022
e9d358b
[🧨refactor] : Devide code into component
Mar 24, 2022
743fdc4
[🧨refactor] : Devide code into component
Mar 24, 2022
352336c
[🧨refactor] : Devide code into component
Mar 24, 2022
cd6291c
[🧨refactor] : Devide code into component
Mar 24, 2022
11967de
[📱fix] : Find bug
Mar 24, 2022
5274f66
[⌨️chore] : Set maxLength
Mar 24, 2022
544079f
[📱fix] : Find bug
Mar 24, 2022
b2cebe8
[📱fix] Fix bug
Mar 24, 2022
ac130c1
[🧨refactor] : Add css style in all component
Mar 24, 2022
8438aa6
Test commit
Mar 24, 2022
ac54062
[💻build] : typescript
Mar 31, 2022
e8a6881
[🧨refactor] : Apply type and refactor function
Apr 1, 2022
0ad9ee6
[🧨refactor] : Check Type
Apr 1, 2022
ddcb16c
[🧨refactor] : Check type
Apr 1, 2022
c3ef0e8
[🧨refactor] : Apply typescript all components
Apr 1, 2022
fe2b790
[⌨️chore] : delete ""
Apr 1, 2022
9b333ab
[⌨️chore] : delete inline style
Apr 1, 2022
85b97cd
[⌨️chore] : delete inline style
Apr 1, 2022
7554c72
[🧨refactor] : add globalStyle
Apr 1, 2022
f0f19a2
[⌨️chore] : edit
Apr 1, 2022
96519d5
[⌚️feat] : Add custom hooks
Apr 1, 2022
1976c20
[⌚️feat] : Prevent duplicated input data
Apr 1, 2022
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
28 changes: 28 additions & 0 deletions interface.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
import React from 'react';

export interface ITodoList {
contents: string;
id: number;
isDone: boolean;
}
export interface IYetListProps {
list: [];
Copy link

Choose a reason for hiding this comment

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

어떤 array인지 좀더 정확하게...!

Suggested change
list: [];
list: ITodoList;

yetNum: number;
onToggle: (e: React.MouseEvent<HTMLButtonElement>) => void;
onDelete: (e: React.MouseEvent<HTMLButtonElement>) => void;
}

export interface IInputFormProps {
onSubmit: (e: React.SyntheticEvent) => void;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
contents: string;
}

export interface IDoneList {
list: [];
onToggle: (e: React.MouseEvent<HTMLButtonElement>) => void;
doneNum: number;
}
// styled-component에 들어가는 property 에 대한 정의
export interface IListBtn {
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
}

// 클릭 : MouseEvent
// 입력 : ChangeEvent
// 제출 : SyntheticEvent (선종님이 말씀하신 건데 맞는지 모르겠음)
8 changes: 3 additions & 5 deletions src/App.js → src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import styled from 'styled-components';

import AllContents from './components/AllContents/index';
import Title from './components/Title';
import { Container } from './style';
function App() {
const D = new Date().toString().slice(0, -21);
console.log('test');
const lastLogin = new Date().toString().slice(0, -21);

return (
<>
<Container>
<Title />
<span style={{ color: 'white', marginBottom: '5px' }}>
Last login: {D}
Last login: {lastLogin}
</span>
<AllContents />
</Container>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
import styled from 'styled-components';
import { useEffect, useState } from 'react';

import Title from '../Title';
import React, { useEffect, useState } from 'react';
import InputForm from '../InputForm';
import YetList from '../YetList';
import DoneList from '../DoneList';
import { ITodoList } from 'interface';

const Index = () => {
const listText = 'list';
// 텍스트 이름과 변수 이름을 같게하면 좋을 것 같다는 피드백을 받았던 거 같은데
// list 를 다른 변수에 사용해 버렸음. 변수 이름 정하는 센스를 더 길러야 겠음

const localData = JSON.parse(localStorage.getItem(listText)) || [];
const localData = JSON.parse(localStorage.getItem(listText) || '') || [];
// localDate 를 처음에 가져와서 새로고침해도 데이터가 유지되게 설정

const [yetNum, setYetNum] = useState(0);
const [doneNum, setDoneNum] = useState(0);
const [contents, setContents] = useState('');
const [list, setList] = useState(localData);
const onChange = (e) => setContents(e.target.value);
const onSubmit = (e) => {

const onChange = (e: React.ChangeEvent<HTMLInputElement>) =>
setContents(e.target.value);
const onSubmit = (e: React.SyntheticEvent) => {
e.preventDefault();
const obj = {
contents,
id: Date.now(),
isDone: false,
};
setList((prev) => [...prev, obj]);
setList((prev: []) => [...prev, obj]);
setContents('');
};
const onToggle = (e) => {
const onToggle = (e: React.MouseEvent<HTMLButtonElement>) => {
// 클릭된 값
const text = e.target.textContent;

const text = (e.target as HTMLElement).textContent;
Copy link

Choose a reason for hiding this comment

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

TS에 as라는 문법이 있는지 처음 알게되었습니다. 감사합니다!

Copy link
Author

Choose a reason for hiding this comment

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

저도 구글에서 찾아보다 그냥 가져와서 알게됐어요 ㅎㅎ;

Copy link

Choose a reason for hiding this comment

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

HTML 구조에 의존적인 로직보다는, 클릭한 요소의 id를 필터링해서 토글시키는 방법이 좋을 것 같습니다.

// 로컬스토리지에 저장된 값
const data = JSON.parse(localStorage.getItem(listText));
const data = JSON.parse(localStorage.getItem(listText) || '');
// 두 값을 이용해서 클릭된 값만 isDone 상태 토글
let indexClicked = 0;
let obj;
data.map((item, index) => {
data.map((item: ITodoList, index: number) => {
if (item.contents === text) {
obj = { ...item };
obj.isDone = !item.isDone;
indexClicked = index;
} else {
// switch 에서 default 값 처럼 if 를 쓰면 else 도 써주는 게 좋다는 코멘트를 봤던 거 같은데
// 그럴 경우 여긴 뭘 넣어야 좋을까요?
// null ???!
}
});
const updatedDate = [...data];
updatedDate[indexClicked] = obj;
setList(updatedDate);
localStorage.setItem(listText, JSON.stringify(list));
};
const onDelete = (e) => {
const onDelete = (e: React.MouseEvent<HTMLButtonElement>) => {
// 클릭된 텍스트 찾기
const text = e.target.parentNode.innerText.slice(0, -4);

const text = (
(e.target as HTMLElement).parentNode as HTMLElement
).innerText.slice(0, -4);
Comment on lines +61 to +63
Copy link

Choose a reason for hiding this comment

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

맞습니다, 이상한 공백을 끌고 오더라구요 innerText하면


// 현재 데이터 가져오기
const data = JSON.parse(localStorage.getItem(listText));
const data = JSON.parse(localStorage.getItem(listText) || '');

// 데이터 삭제
const updatedDate = data.filter((item) => {
const updatedDate = data.filter((item: ITodoList) => {
return item.contents.trim() !== text.trim();
Copy link

Choose a reason for hiding this comment

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

trim이라는 함수를 찾아보니까 문자열 양끝 공백을 사라지게 하는 함수군요 ! 디테일 배워갑니당

});

Expand All @@ -81,12 +79,12 @@ const Index = () => {
}, [list]);

const findNum = () => {
const data = JSON.parse(localStorage.getItem(listText));
const data = JSON.parse(localStorage.getItem(listText) || '');
let yetCtn = 0;
let doneCtn = 0;

// isDone === true, false 인 경우에 따라서 개수를 세어 줘야 함
data.map((item) => {
data.map((item: ITodoList) => {
if (item.isDone === false) {
yetCtn += 1;
Copy link

Choose a reason for hiding this comment

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

(!item.isdone) 이런 식으로 바꾸어주면 훨씬 좋을 것 같아요!

} else {
Expand Down
14 changes: 0 additions & 14 deletions src/components/DoneList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { DivDoneList, DoneNumStyle, ListBtn, Unordered } from './style';
import { IDoneList, ITodoList } from 'interface';

Expand All @@ -25,16 +23,4 @@ const Index = ({ list, onToggle, doneNum }: IDoneList) => {
);
};

Index.propTypes = {
list: PropTypes.arrayOf(
PropTypes.shape({
contents: PropTypes.string,
id: PropTypes.number,
isDone: PropTypes.bool,
})
).isRequired,
doneNum: PropTypes.number.isRequired,
onToggle: PropTypes.func.isRequired,
};

export default Index;
4 changes: 2 additions & 2 deletions src/components/DoneList/style.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from 'styled-components';

import { IListBtn } from 'interface';
export const DivDoneList = styled.div`
//border: 2px solid indianred;
margin-bottom: 10px;
Expand All @@ -19,7 +19,7 @@ export const DoneNumStyle = styled.div`
font-size: 14px;
`;

export const ListBtn = styled.button`
export const ListBtn = styled.button<IListBtn>`
cursor: grab;
color: white;
background: blue;
Expand Down
4 changes: 2 additions & 2 deletions src/components/InputForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const Index = ({ onSubmit, onChange, contents }: IInputFormProps) => {
<div>
<DivInputForm>
<form style={{ display: 'flex' }} onSubmit={onSubmit} action="">
<SpanStyle>
<span style={{ display: 'flex', background: 'black' }}>
<Rec>~/</Rec>
<Triangle />
</SpanStyle>
</span>
<InputStyle
maxLength={maxLength}
required
Expand Down
1 change: 1 addition & 0 deletions src/components/InputForm/style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export const Triangle = styled.div`

export const SpanStyle = styled.span`
display: 'flex';
flex-direction: row;
background: 'black';
`;
1 change: 0 additions & 1 deletion src/components/Title/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Cir1, Cir2, Cir3, Etc, DivTitle, CircleContainer } from './style';
import { useState } from 'react';

const Index = () => {
return (
Expand Down
24 changes: 2 additions & 22 deletions src/components/YetList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,8 @@ import {
Unordered,
YetNumStyle,
} from './style';
import PropTypes from 'prop-types';
import { ITodoList } from 'interface';

interface IYetListProps {
list: [];
yetNum: number;
onToggle: () => void;
onDelete: () => void;
}
import { ITodoList, IYetListProps } from 'interface';

const Index = ({ list, yetNum, onToggle, onDelete }: IYetListProps) => {
return (
Expand All @@ -23,7 +16,7 @@ const Index = ({ list, yetNum, onToggle, onDelete }: IYetListProps) => {
<span style={{ color: '#BF9053', fontWeight: 'bold' }}>
TO DO ({yetNum})
</span>
<span> src/components/yetList.js</span>
<span> src/components/yetList.tsx</span>
</YetNumStyle>
<Unordered>
{list.map((item: ITodoList, index: number) => (
Expand All @@ -41,17 +34,4 @@ const Index = ({ list, yetNum, onToggle, onDelete }: IYetListProps) => {
);
};

Index.propTypes = {
list: PropTypes.arrayOf(
PropTypes.shape({
contents: PropTypes.string,
id: PropTypes.number,
isDone: PropTypes.bool,
})
).isRequired,
yetNum: PropTypes.number.isRequired,
onToggle: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
};

export default Index;
1 change: 0 additions & 1 deletion src/index.js → src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';


ReactDOM.render(
<React.StrictMode>
<App />
Expand Down
File renamed without changes.