Skip to content
This repository was archived by the owner on Sep 19, 2021. It is now read-only.
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
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"start": "node server"
},
"dependencies": {
"axios": "^0.19.2",
"compression": "^1.7.4",
"dotenv": "^8.2.0",
"express": "^4.17.1",
Expand Down
18 changes: 14 additions & 4 deletions pages/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from "react";
import styled from "styled-components";
import React, { useState } from "react";

import LoginForm from "../src/components/login-form";
import VoteForm from "../src/components/vote-form";

import styled from "styled-components";
import Axios from "axios";
Comment on lines -2 to +7
Copy link
Member

Choose a reason for hiding this comment

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

import React, { useState } from 'react';
import styled from 'styled-components';
import Axios from 'axios';

import LoginForm from '../src/components/login-form';
import VoteForm from '../src/components/vote-form';

외부 라이브러리와, 그렇지 않은 import들을 구분지어 묶어주세요!


export default function Home() {
const [login, setLogin] = useState(false);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const [login, setLogin] = useState(false);
const [isLoggedIn, setLoggedIn] = useState(false);

boolean값을 표현하는 변수라 이름에 is를 붙여주면 더 좋을 것 같아요!


return (
<Wrapper>
리액트 투-표
<LoginForm />
<Header>리액트 투-표</Header>
{!login && <LoginForm loginAccess={setLogin} />}
{login && <VoteForm />}
</Wrapper>
);
}
Expand All @@ -17,3 +23,7 @@ const Wrapper = styled.div`
padding: 10rem 40rem;
background-color: Azure;
`;

const Header = styled.h1`
font-size: 4rem;
`;
64 changes: 64 additions & 0 deletions src/components/candidate-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useEffect, useState } from "react";

import styled from "styled-components";
import axios from "axios";

export default function CandidateForm(props) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export default function CandidateForm(props) {
export default function CandidateCard(props) {

Form은 input으로 입력받은 정보를 제출하는 section을 의미합니다.
이 component의 역할과는 맞지 않는 것 같아요!

const { name, voteCount, rank, id } = props;

const voteCandidate = () => {
axios
.put(process.env.API_HOST + "/candidates/" + id + "/vote/")
Copy link
Member

Choose a reason for hiding this comment

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

템플릿 리터럴을 사용해볼까요? 참고링크

.then(function (response) {
Copy link
Member

Choose a reason for hiding this comment

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

화살표함수로 바꿔주세요!

console.log(response);
alert(name + "님에게 투표완료.");
})
Comment on lines +14 to +15
Copy link
Member

Choose a reason for hiding this comment

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

투표 완료시 candidateList를 다시 가져오는 로직이 빠져있네요!
정상작동하고 있는 이유는 엄청난 우연..?! 덕분인데, 오프라인 스터디에서 자세히 설명해드리겠습니다 ㅋㅋㅋㅎ

.catch(function (error) {
console.log(error);
alert("다시 시도해주세요.");
});
};

return (
<Wrapper>
<Rank>{rank}위:</Rank>
<Info>
{name}[{voteCount}표]
</Info>
<VoteButton
onClick={() => {
voteCandidate();
}}
Comment on lines +29 to +31
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
onClick={() => {
voteCandidate();
}}
onClick={voteCandidate}

함수명을 그대로 써주셔도 같습니다 ㅎㅎ

>
투표
</VoteButton>
</Wrapper>
);
}

const Wrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
`;

const Rank = styled.p`
font-weight: bolder;
font-size: 2.5rem;
border: none;
`;
const Info = styled.p`
font-size: 2.5rem;
width: 40%;
border: none;
`;
const VoteButton = styled.button`
background: blue;
color: white;
border: none;
border-radius: 0.7rem;
font-size: 2rem;
height: 3.5rem;
width: 5.5rem;
`;
123 changes: 120 additions & 3 deletions src/components/login-form.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,86 @@
import React from "react";
import React, { useState } from "react";

import axios from "axios";

import styled from "styled-components";

export default function LoginForm() {
return <Wrapper>안녕 나는 로그인 폼!</Wrapper>;
export default function LoginForm(props) {
const { loginAccess } = props;

const [userData, setUserData] = useState({
email: "",
password: "",
});

const { email, password } = userData;

const handleFormChange = (e) => {
const { name, value } = e.target;
setUserData({ ...userData, [name]: value });
};

const checkData = () => {
if (email === "" || password === "") {
alert("모든 칸을 채워주세요.");
return false;
} else {
return true;
}
Comment on lines +23 to +28
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (email === "" || password === "") {
alert("모든 칸을 채워주세요.");
return false;
} else {
return true;
}
return email !== "" && password !== "";

위와 같이 바꿔주면 더 좋을 것 같아요 ㅎ

};

const submitData = () => {
if (!checkData()) return;
Copy link
Member

Choose a reason for hiding this comment

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

좋네용 바로 리턴~ 더 읽어볼만한 글 첨부해드릴게요!
조건문 간결화


axios
.post(process.env.API_HOST + "/auth/signin/", userData)
Copy link
Member

Choose a reason for hiding this comment

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

템플릿 리터럴을 사용해볼까요? 2

.then(function (response) {
Copy link
Member

Choose a reason for hiding this comment

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

화살표 함수로 바꿔주세요!

console.log(response);
alert("로그인에 성공하셨습니다!");
loginAccess(true); //왜 loginAccess = ture;는 안될까요?
Copy link
Member

Choose a reason for hiding this comment

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

위에서 loginAccess로 setLogin을 넘겨주셨네요!
login값을 set 하는 함수이기 때문에
함수 자체에 true값을 대입하면 당연히 동작하지 않습니다 ㅠ

})
.catch(function (error) {
if (error.response.status === 404) {
alert("이메일이 존재하지 않습니다.");
setUserData({
email: "",
password: "",
});
console.log(error.response);
return;
} else if (error.response.status === 422) {
alert("비밀번호가 존재하지 않습니다.");
setUserData({
email,
password: "",
});
console.log(error.response);
return;
}
console.log(error);
Comment on lines +42 to +59
Copy link
Member

Choose a reason for hiding this comment

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

switch문을 사용해 이쁘게 리팩토링할 수 있을 것 같아요 ㅎㅎ

});
};

return (
<Wrapper>
<Header>로그인</Header>
<Row>
<UserInfo>
<Lable>EMAIL</Lable>
<Input name="email" value={email} onChange={handleFormChange} />
</UserInfo>
<UserInfo>
<Lable>PASSWORD</Lable>
<Input
name="password"
type="password"
value={password}
onChange={handleFormChange}
/>
</UserInfo>
</Row>
<SunmitButton onClick={submitData}>로그인</SunmitButton>
</Wrapper>
);
}

const Wrapper = styled.div`
Expand All @@ -12,3 +90,42 @@ const Wrapper = styled.div`
font-size: 18px;
padding: 3rem 4rem;
`;

const Header = styled.h2`
font-size: 3rem;
margin-bottom: 4rem;
`;

const Row = styled.div`
width: 100%;
`;

const Lable = styled.label`
font-size: 2rem;
margin-right: auto;
`;

const Input = styled.input`
width: 75%;
padding: 0.5rem 1rem;
border: 1px, solid, grey;
border-radius: 1rem;
`;

const UserInfo = styled.div`
display: flex;
flex-direction: row;
width: 100%;
margin-bottom: 2rem;
`;

const SunmitButton = styled.button`
display: block;
margin-left: auto;
font-size: 1.8rem;
cursor: pointer;
padding: 0.5rem 1rem;
border-radius: 1rem;
border: 0;
outline: 0;
`;
72 changes: 69 additions & 3 deletions src/components/vote-form.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
import React from "react";
import React, { useEffect, useState } from "react";

import CandidateForm from "./candidate-form";

import styled from "styled-components";
import axios from "axios";

export default function VoteForm(props) {
const [candidateList, setCandidateList] = useState([]);
const { name, voteCount, rank, id } = candidateList;

useEffect(() => {
getCandidateList();
}, [candidateList]);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
}, [candidateList]);
}, []);

이 배열안에 candidateList가 들어있으면 getCandidateList 함수가 계속해서 실행된답니다 😅
참고링크


export default function VoteForm() {
return <Wrapper>안녕 나는 투표 폼!</Wrapper>;
const getCandidateList = async () => {
const data = await axios
.get(process.env.API_HOST + "/candidates/")
.then(function (response) {
return response.data;
})
.catch(function (error) {
console.log(error);
});
setCandidateList(data);
};

var i = 1;

return (
<Wrapper>
<Header1>
<Strong>프론트앤드 인기쟁이는</Strong> 누구?
</Header1>
<Header2>CEOS 프론트엔드 개발자 인기 순위 및 투표 창입니다.</Header2>
<CandidateListWrapper>
{candidateList
.sort((a, b) => {
return b.voteCount - a.voteCount;
})
Comment on lines +38 to +40
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
.sort((a, b) => {
return b.voteCount - a.voteCount;
})
.sort((a, b) => b.voteCount - a.voteCount)

화살표함수에서 바로 return할땐 중괄호와 return문을 생략할 수 있습니다~

.map((candidate, index) => (
<CandidateForm
key={JSON.stringify(candidate)}
id={candidate._id}
rank={i++}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
rank={i++}
rank={index+1}

이렇게 바꿀 수 있어요!

name={candidate.name}
voteCount={candidate.voteCount}
/>
))}
</CandidateListWrapper>
</Wrapper>
);
}

const Wrapper = styled.div`
Expand All @@ -12,3 +59,22 @@ const Wrapper = styled.div`
font-size: 18px;
padding: 3rem 4rem;
`;
const Header1 = styled.h2`
font-size: 30px;
font-weight: bolder;
`;

const Strong = styled.strong`
color: red;
`;

const Header2 = styled.p`
font-size: 26px;
font-weight: bolder;
color: grey;
`;

const CandidateListWrapper = styled.div`
padding: 5rem 10rem;
border: 1px solid black;
`;