From 8fbb008b5b05418d65434910db10170bced12d27 Mon Sep 17 00:00:00 2001 From: Namil Kim Date: Sun, 19 Apr 2020 02:49:27 +0900 Subject: [PATCH 1/3] Modified index.js and login-form.js --- .vscode/launch.json | 15 +++++ package-lock.json | 31 +++++++++ package.json | 1 + pages/index.js | 14 +++- src/components/login-form.js | 123 ++++++++++++++++++++++++++++++++++- src/components/vote-form.js | 3 +- 6 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..17e15f2 --- /dev/null +++ b/.vscode/launch.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a439258..136f0db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1920,6 +1920,37 @@ } } }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", diff --git a/package.json b/package.json index 0e22c09..817c4b9 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "start": "node server" }, "dependencies": { + "axios": "^0.19.2", "compression": "^1.7.4", "dotenv": "^8.2.0", "express": "^4.17.1", diff --git a/pages/index.js b/pages/index.js index 6474ebb..610855b 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,13 +1,17 @@ -import React from "react"; +import React, { useState } from "react"; import styled from "styled-components"; import LoginForm from "../src/components/login-form"; +import VoteForm from "../src/components/vote-form"; export default function Home() { + const [login, setLogin] = useState(false); + return ( - 리액트 투-표 - +
리액트 투-표
+ {!login && } + {login && }
); } @@ -17,3 +21,7 @@ const Wrapper = styled.div` padding: 10rem 40rem; background-color: Azure; `; + +const Header = styled.h1` + font-size: 4rem; +`; diff --git a/src/components/login-form.js b/src/components/login-form.js index 418d945..c13cce1 100644 --- a/src/components/login-form.js +++ b/src/components/login-form.js @@ -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 안녕 나는 로그인 폼!; +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; + } + }; + + const submitData = () => { + if (!checkData()) return; + + axios + .post(process.env.API_HOST + "/auth/signin/", userData) + .then(function (response) { + console.log(response); + alert("로그인에 성공하셨습니다!"); + loginAccess(true); //왜 loginAccess = ture;는 안될까요? + }) + .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); + }); + }; + + return ( + +
로그인
+ + + EMAIL + + + + PASSWORD + + + + 로그인 +
+ ); } const Wrapper = styled.div` @@ -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; +`; diff --git a/src/components/vote-form.js b/src/components/vote-form.js index 65bc549..57767aa 100644 --- a/src/components/vote-form.js +++ b/src/components/vote-form.js @@ -1,4 +1,5 @@ -import React from "react"; +import React, { useState } from "react"; + import styled from "styled-components"; export default function VoteForm() { From 8e252e30af43478a4c809d359f90419df83af5bf Mon Sep 17 00:00:00 2001 From: Namil Kim Date: Sun, 19 Apr 2020 03:28:18 +0900 Subject: [PATCH 2/3] init vote & candidate - form --- pages/index.js | 7 +++--- src/components/candidate-form.js | 41 ++++++++++++++++++++++++++++++++ src/components/vote-form.js | 38 ++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 src/components/candidate-form.js diff --git a/pages/index.js b/pages/index.js index 610855b..967074e 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,17 +1,18 @@ import React, { useState } from "react"; -import styled from "styled-components"; import LoginForm from "../src/components/login-form"; import VoteForm from "../src/components/vote-form"; +import styled from "styled-components"; + export default function Home() { const [login, setLogin] = useState(false); return (
리액트 투-표
- {!login && } - {login && } + {login && } + {!login && }
); } diff --git a/src/components/candidate-form.js b/src/components/candidate-form.js new file mode 100644 index 0000000..6de2f52 --- /dev/null +++ b/src/components/candidate-form.js @@ -0,0 +1,41 @@ +import React, { useEffect, useState } from "react"; + +import axios from "axios"; +import styled from "styled-components"; + +export default function CandidateForm(props) { + return ( + + + + 투표 + + ); +} + +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; +`; diff --git a/src/components/vote-form.js b/src/components/vote-form.js index 57767aa..11a6f3b 100644 --- a/src/components/vote-form.js +++ b/src/components/vote-form.js @@ -1,9 +1,22 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; +import CandidateForm from "./candidate-form"; + +import axios from "axios"; import styled from "styled-components"; -export default function VoteForm() { - return 안녕 나는 투표 폼!; +export default function VoteForm(props) { + return ( + + + 프론트앤드 인기쟁이는 누구? + + CEOS 프론트엔드 개발자 인기 순위 및 투표 창입니다. + + + + + ); } const Wrapper = styled.div` @@ -13,3 +26,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; +`; From f24eda78e4ee27ea2c2aefbec394f585c3a47ded Mon Sep 17 00:00:00 2001 From: Namil Kim Date: Sun, 19 Apr 2020 12:55:40 +0900 Subject: [PATCH 3/3] Modified ALL --- pages/index.js | 5 +++-- src/components/candidate-form.js | 31 ++++++++++++++++++++++---- src/components/vote-form.js | 37 ++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/pages/index.js b/pages/index.js index 967074e..16ce9cd 100644 --- a/pages/index.js +++ b/pages/index.js @@ -4,6 +4,7 @@ import LoginForm from "../src/components/login-form"; import VoteForm from "../src/components/vote-form"; import styled from "styled-components"; +import Axios from "axios"; export default function Home() { const [login, setLogin] = useState(false); @@ -11,8 +12,8 @@ export default function Home() { return (
리액트 투-표
- {login && } - {!login && } + {!login && } + {login && }
); } diff --git a/src/components/candidate-form.js b/src/components/candidate-form.js index 6de2f52..e0ba0ff 100644 --- a/src/components/candidate-form.js +++ b/src/components/candidate-form.js @@ -1,14 +1,37 @@ import React, { useEffect, useState } from "react"; -import axios from "axios"; import styled from "styled-components"; +import axios from "axios"; export default function CandidateForm(props) { + const { name, voteCount, rank, id } = props; + + const voteCandidate = () => { + axios + .put(process.env.API_HOST + "/candidates/" + id + "/vote/") + .then(function (response) { + console.log(response); + alert(name + "님에게 투표완료."); + }) + .catch(function (error) { + console.log(error); + alert("다시 시도해주세요."); + }); + }; + return ( - - - 투표 + {rank}위: + + {name}[{voteCount}표] + + { + voteCandidate(); + }} + > + 투표 + ); } diff --git a/src/components/vote-form.js b/src/components/vote-form.js index 11a6f3b..8913452 100644 --- a/src/components/vote-form.js +++ b/src/components/vote-form.js @@ -2,10 +2,31 @@ import React, { useEffect, useState } from "react"; import CandidateForm from "./candidate-form"; -import axios from "axios"; 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]); + + 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 ( @@ -13,7 +34,19 @@ export default function VoteForm(props) { CEOS 프론트엔드 개발자 인기 순위 및 투표 창입니다. - + {candidateList + .sort((a, b) => { + return b.voteCount - a.voteCount; + }) + .map((candidate, index) => ( + + ))} );