diff --git a/frontend/package.json b/frontend/package.json index 984cd55..4c629b3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,7 +18,7 @@ "axios": "^0.22.0", "babel-eslint": "^10.1.0", "craco-less": "^1.20.0", - "history": "4.10.1", + "history": "^5.1.0", "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.3.1", diff --git a/frontend/src/components/auth/sign-in.js b/frontend/src/components/auth/sign-in.js index e69de29..c85e32a 100644 --- a/frontend/src/components/auth/sign-in.js +++ b/frontend/src/components/auth/sign-in.js @@ -0,0 +1,126 @@ +import React from 'react'; +import { Input, Button, Space } from 'antd'; +import styled from 'styled-components'; +import { Link } from 'react-router-dom'; +import SiteLayout from '../common/layout'; +import { + EMAIL, + PASSWORD, + SEARCH_ID, + SEARCH_PASSWORD, + SIGN_IN, + SIGN_UP, +} from '../../constants'; +import { SIGN_UP_URL } from '../../constants/urls'; +import { + AppleOutlined, + FacebookOutlined, + GithubOutlined, + InstagramOutlined, +} from '@ant-design/icons'; +import { theme } from '../../style/theme'; + +const Title = styled.p` + font-family: ${theme.fontNotoSans}; + font-size: ${theme.fontSizeTitle02}; + font-weight: ${theme.weightBold}; + text-align: center; +`; + +const Div = styled.div` + padding: 12.5px; + width: 500px; +`; + +const ButtonAntd = styled(Button)` + color: white; + width: 480px; + height: 50px; + font-size: ${theme.fontSizeTitle02}; + border-radius: 6px; + margin-top: 10px; + &:hover, + &:focus { + background-color: ${theme.colorPrimary}; + } +`; + +const Wrapper = styled.div` + width: 100%; + height: 700px; + display: flex; + justify-content: center; + align-items: center; +`; + +const InnerWrapper = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 700px; + height: 400px; +`; + +const SNSLogin = styled.div` + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + border-top: 1px solid ${theme.colorLine}; + padding: 30px; +`; + +function SignIn() { + return ( + + + {SIGN_IN} +
+ {EMAIL} + +
+
+ {PASSWORD} + +
+
+ + {SIGN_IN} + +
+
+ {SIGN_UP} / + {SEARCH_ID} / + {SEARCH_PASSWORD} +
+ + + + Apple 로그인 + + Facebook 로그인 + + Github 로그인 + + Instagram 로그인 + + +
+
+ ); +} + +export default SignIn; diff --git a/frontend/src/components/auth/sign-up.js b/frontend/src/components/auth/sign-up.js index c152338..2df0709 100644 --- a/frontend/src/components/auth/sign-up.js +++ b/frontend/src/components/auth/sign-up.js @@ -1,10 +1,9 @@ import React, { useState } from 'react'; -import { Input, Checkbox, Button, Alert, message } from 'antd'; +import { Input, Checkbox, Button, Alert, message, Form } from 'antd'; import styled from 'styled-components'; import { EMAIL, ESSENTIAL, - ESSENTIAL_TEXT, NICK_NAME, PASSWORD, PASSWORD_CONFIRM, @@ -12,7 +11,6 @@ import { TERMS_OF_USE, USER_INFO, FULL_CONSENT, - REQUIRED_CHECK, } from '../../constants'; import { theme } from '../../style/theme'; @@ -35,8 +33,6 @@ const InnerWrapper = styled.div` display: flex; flex-direction: column; justify-content: center; - align-items: center; - width: 700px; `; const Title = styled.p` @@ -59,9 +55,8 @@ const EssentialText = styled.span` `; const Div = styled.div` - padding: 12.5px; padding-top: 21px; - width: 550px; + width: 100%; `; const TopLine = styled.div` @@ -69,14 +64,14 @@ const TopLine = styled.div` `; const ButtonAntd = styled(Button)` - width: 500px; + width: 100%; height: 50px; font-size: ${theme.fontSizeTitle02}; border-radius: 6px; - margin-top: 10px; + margin-top: 20px; `; -function SignUp({ handleChange, handleSignUp, emptyValueCheck }) { +function SignUp({ handleChange, handleSignUp }) { const [checkedList, setCheckedList] = useState(''); const [checkAll, setCheckAll] = useState(false); @@ -93,7 +88,15 @@ function SignUp({ handleChange, handleSignUp, emptyValueCheck }) { return ( - {SIGN_UP} +
+ {SIGN_UP} +
{USER_INFO} @@ -101,72 +104,63 @@ function SignUp({ handleChange, handleSignUp, emptyValueCheck }) { *{ESSENTIAL}
-
- * - {EMAIL} - + -
-
- * - {NICK_NAME} - + + + -
-
- * - {PASSWORD} - + + + -
-
- * - {PASSWORD_CONFIRM} - + + + -
-
- {TERMS_OF_USE} - -
-
- - {FULL_CONSENT} - -
-
- -
-
- - {SIGN_UP} - -
+ rules={[ + { required: true, message: '비밀번호 확인을 입력해주세요.' }, + ]} + > + + +
+ + {FULL_CONSENT} + +
+
+ +
+ + + {SIGN_UP} + + +
); diff --git a/frontend/src/constants/index.js b/frontend/src/constants/index.js index 1f05ea6..e03f8b9 100644 --- a/frontend/src/constants/index.js +++ b/frontend/src/constants/index.js @@ -25,6 +25,8 @@ export const EMPTY_PASSWORD = '비밀번호를 입력해주세요.'; export const EMPTY_PASSWORD_CONFIRM = '비밀번호 확인을 입력해주세요.'; export const SIGN_UP_SUCCESS = '회원가입이 완료되었습니다.'; export const REQUIRED_CHECK = '필수항목을 입력해주세요.'; +export const EMAIL_CHECK = '이메일 형식이 올바르지 않습니다.'; +export const PASSWORD_CHECK = '입력한 비밀번호가 다릅니다.'; export const HOME = '홈으로'; export const ERROR_CONTENT_F = '찾을수 없는 페이지 입니다.'; diff --git a/frontend/src/containers/auth/sign-in-container.js b/frontend/src/containers/auth/sign-in-container.js index e69de29..abe2c46 100644 --- a/frontend/src/containers/auth/sign-in-container.js +++ b/frontend/src/containers/auth/sign-in-container.js @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import styled from 'styled-components'; +import SignIn from '../../components/auth/sign-in'; + +const Wrapper = styled.div` + width: 100%; + display: flex; + justify-content: center; + align-items: center; +`; + +function SignInContainer() { + return ( + + + + ); +} + +export default SignInContainer; diff --git a/frontend/src/containers/auth/sign-up-container.js b/frontend/src/containers/auth/sign-up-container.js index 3eada90..0e18105 100644 --- a/frontend/src/containers/auth/sign-up-container.js +++ b/frontend/src/containers/auth/sign-up-container.js @@ -1,10 +1,10 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; -import { signUp } from '../../store/auth'; +import { signUpSuccess } from '../../store/auth'; import SignUp from '../../components/auth/sign-up'; -import { message, notification } from 'antd'; -import { REQUIRED_CHECK, SIGN_UP_SUCCESS } from '../../constants'; +import { message } from 'antd'; +import { EMAIL_CHECK, PASSWORD_CHECK } from '../../constants'; const Wrapper = styled.div` width: 100%; @@ -14,58 +14,52 @@ const Wrapper = styled.div` `; function SignUpContainer() { - const selector = useSelector((state) => state.auth); const dispatch = useDispatch(); + const authSelector = useSelector((state) => state.auth); + const [info, setInfo] = useState({ email: '', nickname: '', password: '', passwordConfirm: '', }); - const [isEmpty, setIsEmpty] = useState(false); const onChangeHandler = (e) => { setInfo({ ...info, - [e.target.name]: e.target.value, + [e.target.id]: e.target.value, }); }; const onSignUpHandler = (e) => { - const res = dispatch({ type: signUp.type, data: info }); - res !== undefined ? openNotification() : ''; - }; - - const openNotification = () => { - notification.success({ - message: 'CIAT', - description: SIGN_UP_SUCCESS, - }); - }; - - const emptyError = (e) => { - setIsEmpty(true); - message.error(REQUIRED_CHECK); + if (isEmail(info.email) === undefined) { + if (isSamePassword(info) === undefined) { + dispatch({ type: signUpSuccess.type, data: info }); + } + } }; - const notEmptyError = (e) => { - setIsEmpty(false); + // 이메일 검증 + const isEmail = (email) => { + const regExp = + /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i; + if (!regExp.test(email)) { + console.log(email); + return message.error(EMAIL_CHECK); + } }; - const emptyValueCheck = (e) => { - e.target.name === e.currentTarget.name && e.target.value === '' - ? emptyError(e) - : notEmptyError(e); + // 비밀번호 + const isSamePassword = (info) => { + if (info.password !== info.passwordConfirm) { + return message.error(PASSWORD_CHECK); + } }; return ( - + ); } diff --git a/frontend/src/index.js b/frontend/src/index.js index 4916945..003f52e 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -7,7 +7,7 @@ import { configureStore } from '@reduxjs/toolkit'; import logger from 'redux-logger'; import rootReducer, { rootSaga } from './store'; import './style/theme.less'; -import history from './lib/router/history'; +import { createBrowserHistory } from 'history'; const sagaMiddleware = createSagaMiddleware(); @@ -25,7 +25,7 @@ sagaMiddleware.run(rootSaga); ReactDom.render( - + , document.getElementById('root') ); diff --git a/frontend/src/lib/router/history.js b/frontend/src/lib/router/history.js deleted file mode 100644 index 9937105..0000000 --- a/frontend/src/lib/router/history.js +++ /dev/null @@ -1,3 +0,0 @@ -import { createBrowserHistory } from 'history'; - -export default createBrowserHistory(); diff --git a/frontend/src/lib/router/index.js b/frontend/src/lib/router/index.js index 075c0b6..3fc819e 100644 --- a/frontend/src/lib/router/index.js +++ b/frontend/src/lib/router/index.js @@ -19,11 +19,10 @@ import Setting from '../../pages/setting'; import SignUp from '../../pages/auth/sign-up'; import FeedDetail from '../../pages/feed-detail'; import NotFound from '../../pages/error'; -import history from './history'; function index() { return ( - + diff --git a/frontend/src/pages/auth/sign-in.js b/frontend/src/pages/auth/sign-in.js index 6abe586..971f2fb 100644 --- a/frontend/src/pages/auth/sign-in.js +++ b/frontend/src/pages/auth/sign-in.js @@ -1,127 +1,11 @@ -import React, { Children } from 'react'; -import { Input, Button, Space } from 'antd'; -import styled from 'styled-components'; -import { Link } from 'react-router-dom'; +import React from 'react'; import SiteLayout from '../../components/common/layout'; -import { - EMAIL, - PASSWORD, - SEARCH_ID, - SEARCH_PASSWORD, - SIGN_IN, - SIGN_UP, -} from '../../constants'; -import { SIGN_UP_URL } from '../../constants/urls'; -import { - AppleOutlined, - FacebookOutlined, - GithubOutlined, - InstagramOutlined, -} from '@ant-design/icons'; -import { theme } from '../../style/theme'; - -const Title = styled.p` - font-family: ${theme.fontNotoSans}; - font-size: ${theme.fontSizeTitle02}; - font-weight: ${theme.weightBold}; - text-align: center; -`; - -const Div = styled.div` - padding: 12.5px; - width: 500px; -`; - -const ButtonAntd = styled(Button)` - color: white; - width: 480px; - height: 50px; - font-size: ${theme.fontSizeTitle02}; - border-radius: 6px; - margin-top: 10px; - &:hover, - &:focus { - background-color: ${theme.colorPrimary}; - } -`; - -const Wrapper = styled.div` - width: 100%; - height: 700px; - display: flex; - justify-content: center; - align-items: center; -`; - -const InnerWrapper = styled.div` - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 700px; - height: 400px; -`; - -const SNSLogin = styled.div` - display: flex; - flex-direction: row; - justify-content: space-around; - align-items: center; - border-top: 1px solid ${theme.colorLine}; - padding: 30px; -`; +import SignInContainer from '../../containers/auth/sign-in-container'; function SignIn() { return ( - - - {SIGN_IN} -
- {EMAIL} - -
-
- {PASSWORD} - -
-
- - {SIGN_IN} - -
-
- {SIGN_UP} / - {SEARCH_ID} / - {SEARCH_PASSWORD} -
- - - - Apple 로그인 - - Facebook 로그인 - - Github 로그인 - - Instagram 로그인 - - -
-
- {/* 로그인 API 향후 개발 */} +
); } diff --git a/frontend/src/saga/auth.js b/frontend/src/saga/auth.js index 0bccdab..0538c4e 100644 --- a/frontend/src/saga/auth.js +++ b/frontend/src/saga/auth.js @@ -2,52 +2,57 @@ import { put } from 'redux-saga/effects'; import * as authStore from '../store/auth'; import { SIGN_UP_API } from '../utils/api/auth'; import axios from 'axios'; -import history from '../lib/router/history'; - -import { INNER_ERROR } from '../constants'; +import { INNER_ERROR, SIGN_UP_SUCCESS } from '../constants'; import { finishLoading, startLoading } from '../store/loding'; -import { message, notification } from 'antd'; +import { notification } from 'antd'; -function* signUpSaga(action) { - try { - yield put(startLoading(authStore.signUp)); - const { data } = yield axios.post(SIGN_UP_API, action.data); - yield put({ type: authStore.signUp, payload: data }); - } catch (e) { - console.log(e); - /* if(axios.isAxiosError(e)) { - const { errorMessage } = e.response.data; - yield put({ - type: authStore. +function* signInSaga(action) { + /* let params = new URLSearchParams(); + params.append('email', 'dawwdawdadawdaw'); + params.append('password', '1234'); */ + /* axios + .post('https://ciat-bakend.choicloudlab.com/api/v1/user/login', params) + .then((response) => { + console.log('Success'); + console.log(response.status); + console.log(response.headers); }) - } */ - } finally { - yield put(finishLoading(authStore.signUp)); - } + .catch((error) => { + console.log('error'); + console.log(error.response.status); + }); */ } -/* function* googleLoginSaga(action) { +function* signUpSaga(action) { try { - yield put(startLoading(authStore.getGoogleLogin)); - const { data } = yield axios.get(authAPI.GOOGLE_LOGIN(params.payload)); - console.log(data); - yield put({ type: authStore.getGoogleLoginSuccess, payload: data }); + yield put(startLoading(authStore.signUpSuccess)); + const { data } = yield axios.post(SIGN_UP_API, action.data); + yield put({ type: authStore.signUpSuccess, payload: data }); + notification.success({ + message: 'CIAT', + description: SIGN_UP_SUCCESS, + }); + //수정 예정 + window.location.href = '/'; } catch (e) { - if (axios.isAxiosError(e)) { + // 이메일 중복 확인 로직 추가예정 + alert('이미 등록된 이메일입니다.'); + /* if (axios.isAxiosError(e)) { const { errorMessage } = e.response.data; + console.log('errorMessage: ', errorMessage); yield put({ - type: authStore.getGoogleLoginFail, + type: authStore.signUp, payload: errorMessage, }); } else { - console.log(e); yield put({ - type: authStore.getGoogleLoginFail, + type: authStore.signUp, payload: INNER_ERROR, }); - } + } */ } finally { - yield put(finishLoading(authStore.getGoogleLogin)); + yield put(finishLoading(authStore.signUpSuccess)); } -} */ +} + export { signUpSaga }; diff --git a/frontend/src/store/auth.js b/frontend/src/store/auth.js index ec926f3..aa85ee5 100644 --- a/frontend/src/store/auth.js +++ b/frontend/src/store/auth.js @@ -9,13 +9,21 @@ const initialState = { password: '', passwordConfirm: '', }, + userId: '', + error: null, }; const authSlice = createSlice({ name: 'auth', initialState, reducers: { - signUp: (state, action) => { - state = action.data; + signUpSuccess: (state, action) => { + state.userId = action.payload; + state.error = null; + return state; + }, + signUpFail: (state, action) => { + state.error = action.payload; + console.debug('error', action.payload); return state; }, }, @@ -23,10 +31,10 @@ const authSlice = createSlice({ const { actions, reducer: authReducer } = authSlice; -export const { signUp } = actions; +export const { signUpSuccess, signUpFail } = actions; export { authReducer }; export function* authSaga() { - yield takeLatest(signUp.type, signUpSaga); + yield takeLatest(signUpSuccess.type, signUpSaga); } diff --git a/frontend/src/utils/api/auth.js b/frontend/src/utils/api/auth.js index ac76eab..96624a9 100644 --- a/frontend/src/utils/api/auth.js +++ b/frontend/src/utils/api/auth.js @@ -13,3 +13,6 @@ export const authAPI = { export const SIGN_UP_API = 'https://ciat-bakend.choicloudlab.com/api/v1/user/signup'; + +export const SIGN_IN_API = + 'https://ciat-bakend.choicloudlab.com/api/v1/user/login'; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 877b01e..ebac79b 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1010,6 +1010,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.7.6": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" @@ -3047,7 +3054,7 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -history@4.10.1, history@^4.9.0: +history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== @@ -3059,6 +3066,13 @@ history@4.10.1, history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" +history@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.1.0.tgz#2e93c09c064194d38d52ed62afd0afc9d9b01ece" + integrity sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg== + dependencies: + "@babel/runtime" "^7.7.6" + hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"