-
Notifications
You must be signed in to change notification settings - Fork 7
[3주차] 정시원 미션 제출합니다 #8
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import styled from "styled-components"; | ||
import axios from "axios" | ||
import Candidate from './candidate'; | ||
|
||
|
||
|
||
export default function CandidateList() { | ||
const [candidates, setCandidates] = useState([]); | ||
|
||
const getData = async () => { | ||
const response = await axios.get(process.env.API_HOST + '/candidates') | ||
return response.data | ||
} | ||
|
||
const sendVoteRequest = async (id) => { | ||
const response = await axios.put(process.env.API_HOST + `/candidates/${id}/vote`); | ||
return response.data | ||
} | ||
|
||
const handleVote = (id) => { | ||
sendVoteRequest(id).then(()=>{ | ||
getData().then((data)=> { | ||
console.log('hhh') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코드 올릴때는 console.log 빼주세요! |
||
setCandidates(data); | ||
}) | ||
}) | ||
} | ||
|
||
|
||
useEffect(() => { | ||
getData().then((data) => { | ||
setCandidates(data); | ||
}) | ||
}, []) | ||
|
||
return <Wrapper> | ||
<Title><Red>프론트엔드 인기쟁이</Red>는 누구?</Title> | ||
<SubTitle>CEOS 프론트엔드 개발자 인기 순위 및 투표 창입니다.</SubTitle> | ||
<Board> | ||
{candidates.sort((a, b) => { | ||
return b.voteCount - a.voteCount | ||
}).map((candidate, rank) => { | ||
return <Candidate rank={rank+1} {...candidate} handleVote={handleVote}></Candidate> | ||
})} | ||
</Board> | ||
</Wrapper> | ||
} | ||
|
||
const Wrapper = styled.div` | ||
width: 100%; | ||
min-height: 30rem; | ||
background-color: white; | ||
font-size: 18px; | ||
padding: 3rem 4rem 10rem; | ||
` | ||
|
||
const Title = styled.h2` | ||
font-size: 3rem; | ||
` | ||
|
||
const Red = styled.span` | ||
color: red; | ||
` | ||
|
||
const SubTitle = styled.h3` | ||
font-size: 2.5rem; | ||
color: grey; | ||
` | ||
|
||
const Board = styled.div` | ||
width: 100%; | ||
padding: 5rem 10rem; | ||
border-width: 1px; | ||
border-style: solid; | ||
border-color: black; | ||
border-image: initial; | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from "react"; | ||
import styled from "styled-components"; | ||
import axios from 'axios'; | ||
|
||
export default function Candidate({ rank, name, voteCount, _id, handleVote}) { | ||
console.log('id: ', _id) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 console도 마찬가지로 지워주시면 좋을 거 같아요! |
||
return <Wrapper> | ||
<Rank>{rank}위:</Rank> | ||
<Name>{name} [{voteCount}표]</Name> | ||
<VoteButton onClick={() => {handleVote(_id)}}>투표</VoteButton> | ||
</Wrapper> | ||
} | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
` | ||
|
||
const Rank = styled.strong` | ||
font-size: 2.5rem; | ||
width: 10rem; | ||
margin-bottom: 1rem; | ||
` | ||
|
||
const Name = styled.p` | ||
font-size: 2.5rem; | ||
margin: 0rem auto 1rem 0rem; | ||
` | ||
|
||
const VoteButton = styled.button` | ||
background-color: navy; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. navy라는 이름보다는 16진수를 사용한 색상표를 사용하시는 것이 좋을 것 같아요 |
||
color: white; | ||
font-size: 2rem; | ||
padding: 0.5rem 1rem; | ||
border-width: initial; | ||
border-style: none; | ||
border-color: initial; | ||
border-image: initial; | ||
border-radius: 1rem; | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,95 @@ | ||
import React from "react"; | ||
import React, { useState } from "react"; | ||
import styled from "styled-components"; | ||
import axios from 'axios' | ||
|
||
export default function LoginForm() { | ||
return <Wrapper>안녕 나는 로그인 폼!</Wrapper>; | ||
export default function LoginForm({ setIsLoggedIn }) { | ||
const [loginData, setLoginData] = useState({ email: "", password: "" }) | ||
|
||
const handleInputChange = (e) => { | ||
const { name, value } = e.target; | ||
setLoginData({ ...loginData, [name]: value }); | ||
console.log(loginData); | ||
} | ||
|
||
|
||
const handleSubmit = () => { | ||
if (validateInput(loginData)) { | ||
axios.post(process.env.API_HOST + '/auth/signin', loginData). | ||
then((response) => { | ||
console.log(response.data) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. console.log는 commit할 때 지워주세용 |
||
setIsLoggedIn(true) | ||
}) | ||
.catch((error) => { | ||
console.error(error); | ||
alert('로그인에 실패했습니다') | ||
}) | ||
} | ||
} | ||
|
||
const validateInput = (data) => { | ||
const { email, password } = data; | ||
if ((!email) || (!password)) { | ||
alert('폼을 다 채워주세요') | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
return <Wrapper> | ||
<Title>로그인</Title> | ||
<Row> | ||
<Label>EMAIL</Label> | ||
<Input name="email" onChange={handleInputChange} /> | ||
</Row> | ||
<Row> | ||
<Label>PASSWORD</Label> | ||
<Input name="password" type="password" onChange={handleInputChange} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. type="password" |
||
</Row> | ||
<Row> | ||
<div style={{ marginRight: 'auto' }}></div> | ||
<Button onClick={handleSubmit}>로그인</Button> | ||
</Row> | ||
|
||
</Wrapper>; | ||
Comment on lines
+39
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
const Row = styled.div` | ||
margin-bottom: 10px; | ||
margin-top: 20px; | ||
font-size: 15px; | ||
display: flex; | ||
` | ||
const Label = styled.div` | ||
margin-right: auto; | ||
` | ||
const Input = styled.input` | ||
width: 75%; | ||
border: 1px solid grey; | ||
padding: 5px; | ||
outline: none; | ||
` | ||
|
||
const Wrapper = styled.div` | ||
width: 100%; | ||
min-height: 30rem; | ||
background-color: white; | ||
font-size: 18px; | ||
padding: 3rem 4rem; | ||
`; | ||
|
||
const Title = styled.div` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 글씨에 관한 스타일링은 p태그를 써주면 됩니다! |
||
font-size: 25px; | ||
` | ||
|
||
const Button = styled.button` | ||
outline:none; | ||
background-color:#d6d6d6; | ||
border-radius:3px; | ||
border:none; | ||
width: 150px; | ||
margin-left: auto; | ||
font-size: 15px; | ||
padding: 5px; | ||
` | ||
Comment on lines
+57
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. , <Title>, 순으로 컴포넌트가 나타나니까 컴포넌트 정의를 할 때도 먼저 나타나는 컴포넌트 순으로 정리하면 나중에 수정할 때 찾기 더 용이할 거 같아요! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const Title=styled.h1`
과 같이 semantic tag로 쓰면 더 좋을 거 같아요👍