From cb82e06f80b7e046037884e2349baf7d8fa35d07 Mon Sep 17 00:00:00 2001 From: gyuZzang Date: Sun, 18 Apr 2021 02:43:34 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat(user/auth):=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=9D=B8=EC=A6=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20[#51]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 2 + src/utils/api.js | 3 ++ src/views/EmailAuth.jsx | 85 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/views/EmailAuth.jsx diff --git a/src/App.jsx b/src/App.jsx index 78c1251..3ae541d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -9,6 +9,7 @@ import Timetable from './views/Timetable'; import Login from './views/login/index'; import PrivacyPolicy from './views/PrivacyPolicy'; import Admin from './views/admin'; +import EmailAuth from './views/EmailAuth'; function ErrorPage() { return

404 Not Found

; @@ -25,6 +26,7 @@ function App() { + diff --git a/src/utils/api.js b/src/utils/api.js index d3b1e73..5bbbac1 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -51,9 +51,12 @@ const DELETE = url => ({ method: 'DELETE', url }); // API CONFIG LIST export const API_LOGIN = makeAPI(POST, '/user/login'); +export const API_MY_INFO = makeAPI(GET, '/user'); export const API_SIGN_UP = makeAPI(POST, '/user'); export const API_FIND_ID = makeAPI(GET, '/user/id'); export const API_FIND_PW = makeAPI(GET, '/user/password'); +export const API_SEND_CODE = makeAPI(POST, 'user/auth'); +export const API_AUTH_EMAIL = (userID, code) => makeAPI(POST, `user/auth/${userID}/${code}`); export const API_GET_SEMESTERS = makeAPI(GET, '/semesters'); export const API_GET_ALL_NOTICES = makeAPI(GET, '/notice/all'); export const API_CREATE_NOTICE = makeAPI(POST, '/notice'); diff --git a/src/views/EmailAuth.jsx b/src/views/EmailAuth.jsx new file mode 100644 index 0000000..6b75438 --- /dev/null +++ b/src/views/EmailAuth.jsx @@ -0,0 +1,85 @@ +import React, { useEffect, useState } from 'react'; +import { requestAPI, API_SEND_CODE, API_AUTH_EMAIL, API_MY_INFO } from '@utils/api'; +import { Button, Box, makeStyles, Container, Typography } from '@material-ui/core'; +import UosInput from '@components/UosInput'; + + +export default function EmailAuth() { + const userID = window.localStorage.getItem('userID'); + const [userEmail,setUserEmail] = useState(null); + const [isCodeSend, setIsCodeSend] = useState(false); + const [code, setCode] = useState(null); + + useEffect(async()=> { + try{ + const res = await requestAPI(API_MY_INFO, userID); + setUserEmail(res.data.email); + } + catch(err){ + alert(err); + throw err; + } + },[]) + + const inputOnChange = (e) => { + setCode(e.target.value); + }; + + const onEnterPress = (e) => { + if(e.key == 'Enter') { + handleAuth(); + } + }; + + const handleSendCode = async () => { + console.log(userEmail); + try{ + await requestAPI(API_SEND_CODE(), {email: userEmail}); + } + catch(err){ + alert(err.message); + throw err; + } + } + + const handleAuth = async () => { + console.log(userID, code); + try{ + const res = await requestAPI(API_AUTH_EMAIL(userID, code)); + if(res.status === 204){ + alert('이메일이 성공적으로 인증되었습니다!'); + } + } + catch(err){ + alert(err) + throw err; + } + } + + return( //TODO: 컴포넌트로 나누기 + + + 이메일 인증 + + {userEmail} + + + + + {isCodeSend && + + + + } + + ) +} \ No newline at end of file From 2f61fed5deaf0ae5fd23db037b78a3383214c0cc Mon Sep 17 00:00:00 2001 From: GyuZzang Date: Mon, 3 May 2021 21:37:15 +0900 Subject: [PATCH 2/4] test for click up --- src/utils/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/api.js b/src/utils/api.js index fbf580c..83f86aa 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -3,7 +3,7 @@ /* eslint-disable prefer-const */ import axios from 'axios'; - +//test const { API_URL_BASE } = process.env; const makeAPI = (method, path) => { From 53c03d3bcb5434b48ba6ae142dbeb92902d0e0b1 Mon Sep 17 00:00:00 2001 From: gyuZzang Date: Mon, 4 Oct 2021 20:00:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20API=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 27 ++--- src/utils/api.js | 96 ++++++++-------- src/views/EmailAuth.jsx | 163 +++++++++++++++------------- src/views/timetable/ShareDialog.jsx | 125 +++++++++++---------- 4 files changed, 222 insertions(+), 189 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 6b78d58..f13aef6 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,17 +1,17 @@ -import React from 'react'; -import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; -import { getToken } from '@utils/api'; -import './scss/main.scss'; -import Footer from './components/Footer'; +import React from "react"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; +import { getToken } from "@utils/api"; +import "./scss/main.scss"; +import Footer from "./components/Footer"; -import Timetable from './views/timetable'; -import Login, { LoginBox } from './views/login/index'; -import PrivacyPolicy from './views/terms/PrivacyPolicy'; -import TermsOfService from './views/terms/TermsOfService'; -import Admin from './views/admin'; -import EmailAuth from './views/EmailAuth'; -import usePopup from './components/usePopup'; -import Notice from './views/notice'; +import Timetable from "./views/timetable"; +import Login, { LoginBox } from "./views/login/index"; +import PrivacyPolicy from "./views/terms/PrivacyPolicy"; +import TermsOfService from "./views/terms/TermsOfService"; +import Admin from "./views/admin"; +import EmailAuth from "./views/EmailAuth"; +import usePopup from "./components/usePopup"; +import Notice from "./views/notice"; function ErrorPage() { return

404 Not Found

; @@ -32,6 +32,7 @@ function App() { + diff --git a/src/utils/api.js b/src/utils/api.js index e7b443c..af0d8a2 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -1,28 +1,30 @@ /* eslint-disable no-console */ /* eslint-disable no-unused-vars */ -import axios from 'axios'; -import usePopup from '@components/usePopup'; +import axios from "axios"; +import usePopup from "@components/usePopup"; const { API_URL_BASE } = process.env; -const makeConfig = ({ method, url }, needToken = true) => (initialData = {}) => { +const makeConfig = ({ method, url }, needToken = true) => ( + initialData = {} +) => { const config = { method, url, needToken, setPath: (...path) => { - config.url += ['', ...path].join('/'); + config.url += ["", ...path].join("/"); return config; }, - setQuery: query => { + setQuery: (query) => { config.params = query; return config; }, - setData: data => { - if (method === 'GET') { + setData: (data) => { + if (method === "GET") { config.setQuery(data); } else { config.data = data; @@ -35,34 +37,36 @@ const makeConfig = ({ method, url }, needToken = true) => (initialData = {}) => }; // API CONFIG OBJECT -const GET = url => ({ method: 'GET', url }); -const POST = url => ({ method: 'POST', url }); -const PUT = url => ({ method: 'PUT', url }); -const PATCH = url => ({ method: 'PATCH', url }); -const DELETE = url => ({ method: 'DELETE', url }); +const GET = (url) => ({ method: "GET", url }); +const POST = (url) => ({ method: "POST", url }); +const PUT = (url) => ({ method: "PUT", url }); +const PATCH = (url) => ({ method: "PATCH", url }); +const DELETE = (url) => ({ method: "DELETE", url }); // API CONFIG LIST -export const API_LOGIN = makeConfig(POST('/user/login'), false); -export const API_GET_SEMESTER = makeConfig(GET('/semester')); -export const API_GET_SEMESTERS = makeConfig(GET('/semesters')); -export const API_GET_NOTICE = makeConfig(GET('/notice')); -export const API_GET_USE_NOTICE = makeConfig(GET('/notice/use')); -export const API_GET_HOT_NOTICE = makeConfig(GET('/notice/hot')); -export const API_CREATE_NOTICE = makeConfig(POST('/notice')); -export const API_UPDATE_NOTICE = makeConfig(PATCH('/notice')); -export const API_DELETE_NOTICE = makeConfig(DELETE('/notice')); -export const API_GET_ALL_LECTURES = makeConfig(GET('/lecture')); -export const API_UPDATE_LECTURES = makeConfig(PATCH('/lecture')); -export const API_DELETE_TLECTURE = makeConfig(DELETE('/timetable/tlecture')); -export const API_ADD_TLECTURE = makeConfig(POST('/timetable/tlecture')); -export const API_CREATE_TIMETABLE = makeConfig(POST('/timetable')); -export const API_DELETE_TIMETABLE = makeConfig(DELETE('/timetable')); -export const API_GET_TIMETABLES = makeConfig(GET('/timetable')); -export const API_PATCH_TIMETABLE_NAME = makeConfig(PATCH('/timetable/name')); -export const API_GET_HISTORIES = makeConfig(GET('/history')); -export const API_SIGN_UP = makeConfig(POST('/user'), false); -export const API_FIND_ID = makeConfig(GET('/user/id'), false); -export const API_FIND_PW = makeConfig(GET('/user/password'), false); +export const API_LOGIN = makeConfig(POST("/user/login"), false); +export const API_GET_SEMESTER = makeConfig(GET("/semester")); +export const API_GET_SEMESTERS = makeConfig(GET("/semesters")); +export const API_GET_NOTICE = makeConfig(GET("/notice")); +export const API_GET_USE_NOTICE = makeConfig(GET("/notice/use")); +export const API_GET_HOT_NOTICE = makeConfig(GET("/notice/hot")); +export const API_CREATE_NOTICE = makeConfig(POST("/notice")); +export const API_UPDATE_NOTICE = makeConfig(PATCH("/notice")); +export const API_DELETE_NOTICE = makeConfig(DELETE("/notice")); +export const API_GET_ALL_LECTURES = makeConfig(GET("/lecture")); +export const API_UPDATE_LECTURES = makeConfig(PATCH("/lecture")); +export const API_DELETE_TLECTURE = makeConfig(DELETE("/timetable/tlecture")); +export const API_ADD_TLECTURE = makeConfig(POST("/timetable/tlecture")); +export const API_CREATE_TIMETABLE = makeConfig(POST("/timetable")); +export const API_DELETE_TIMETABLE = makeConfig(DELETE("/timetable")); +export const API_GET_TIMETABLES = makeConfig(GET("/timetable")); +export const API_PATCH_TIMETABLE_NAME = makeConfig(PATCH("/timetable/name")); +export const API_GET_HISTORIES = makeConfig(GET("/history")); +export const API_SIGN_UP = makeConfig(POST("/user"), false); +export const API_FIND_ID = makeConfig(GET("/user/id"), false); +export const API_FIND_PW = makeConfig(GET("/user/password"), false); +export const API_MAKE_AUTH_CODE = makeConfig(POST("/user/auth/code")); +export const API_MATCH_AUTH_CODE = makeConfig(POST("/user/auth")); const axiosInstance = axios.create({ baseURL: `${API_URL_BASE}/api`, @@ -70,31 +74,31 @@ const axiosInstance = axios.create({ }); axiosInstance.interceptors.request.use( - config => { + (config) => { const token = getToken(); if (token) { config.headers.Authorization = token; } return config; }, - error => { + (error) => { const [, showPopup] = usePopup(); console.error(error); - showPopup('에러', '서버를 찾을 수 없어요...'); + showPopup("에러", "서버를 찾을 수 없어요..."); return null; - }, + } ); axiosInstance.interceptors.response.use( - config => config, - error => Promise.resolve(error.response), + (config) => config, + (error) => Promise.resolve(error.response) ); export async function requestAPI(config) { try { if (config.needToken && !getToken()) { // token required but not found: API wouldn't be requested - window.location.href = '/login'; + window.location.href = "/login"; return null; } @@ -114,25 +118,25 @@ export async function requestAPI(config) { } export function setToken(token) { - localStorage.setItem('token', token); + localStorage.setItem("token", token); } export function getToken() { - return localStorage.getItem('token'); + return localStorage.getItem("token"); } export function removeToken() { - localStorage.removeItem('token'); + localStorage.removeItem("token"); } export function setUserID(userID) { - localStorage.setItem('userID', userID); + localStorage.setItem("userID", userID); } export function getUserID() { - return localStorage.getItem('userID'); + return localStorage.getItem("userID"); } export function removeUserID() { - localStorage.removeItem('userID'); + localStorage.removeItem("userID"); } diff --git a/src/views/EmailAuth.jsx b/src/views/EmailAuth.jsx index 6b75438..7420e4f 100644 --- a/src/views/EmailAuth.jsx +++ b/src/views/EmailAuth.jsx @@ -1,85 +1,98 @@ -import React, { useEffect, useState } from 'react'; -import { requestAPI, API_SEND_CODE, API_AUTH_EMAIL, API_MY_INFO } from '@utils/api'; -import { Button, Box, makeStyles, Container, Typography } from '@material-ui/core'; -import UosInput from '@components/UosInput'; - +import React, { useEffect, useState } from "react"; +import StatusCodes from "http-status-codes"; +import { + requestAPI, + API_MAKE_AUTH_CODE, + API_MATCH_AUTH_CODE, + API_MY_INFO, +} from "@utils/api"; +import { + Button, + Box, + makeStyles, + Container, + Typography, +} from "@material-ui/core"; +import UosInput from "@components/UosInput"; export default function EmailAuth() { - const userID = window.localStorage.getItem('userID'); - const [userEmail,setUserEmail] = useState(null); - const [isCodeSend, setIsCodeSend] = useState(false); - const [code, setCode] = useState(null); + const [userEmail, setUserEmail] = useState(null); + const [isCodeSend, setIsCodeSend] = useState(false); + const [code, setCode] = useState(null); + + const codeOnChange = (e) => { + setCode(e.target.value); + }; - useEffect(async()=> { - try{ - const res = await requestAPI(API_MY_INFO, userID); - setUserEmail(res.data.email); - } - catch(err){ - alert(err); - throw err; - } - },[]) + const emailOnChange = (e) => { + setUserEmail(e.target.value); + }; - const inputOnChange = (e) => { - setCode(e.target.value); - }; - - const onEnterPress = (e) => { - if(e.key == 'Enter') { - handleAuth(); - } - }; + const codeOnEnterPress = (e) => { + if (e.key == "Enter") { + handleAuth(); + } + }; - const handleSendCode = async () => { - console.log(userEmail); - try{ - await requestAPI(API_SEND_CODE(), {email: userEmail}); - } - catch(err){ - alert(err.message); - throw err; - } + const emailOnEnterPress = (e) => { + if (e.key == "Enter") { + handleSendCode(); } + }; - const handleAuth = async () => { - console.log(userID, code); - try{ - const res = await requestAPI(API_AUTH_EMAIL(userID, code)); - if(res.status === 204){ - alert('이메일이 성공적으로 인증되었습니다!'); - } - } - catch(err){ - alert(err) - throw err; - } + const handleSendCode = async () => { + console.log(userEmail); + try { + const res = await requestAPI(API_MAKE_AUTH_CODE({ email: userEmail })); + if (res.status === StatusCodes.NO_CONTENT) setIsCodeSend(true); + } catch (err) { + alert(err.message); + throw err; } + }; + + const handleAuth = async () => { + try { + const res = await requestAPI(API_MATCH_AUTH_CODE().setPath(code)); + if (res.status === StatusCodes.NO_CONTENT) { + alert("이메일이 성공적으로 인증되었습니다!"); + } + } catch (err) { + alert(err); + throw err; + } + }; + + return ( + + + 이메일 인증 + + + + + - return( //TODO: 컴포넌트로 나누기 - - - 이메일 인증 - - {userEmail} - - - - - {isCodeSend && - - - - } + {isCodeSend && ( + + + - ) -} \ No newline at end of file + )} + + ); +} diff --git a/src/views/timetable/ShareDialog.jsx b/src/views/timetable/ShareDialog.jsx index d1002fc..fa84130 100644 --- a/src/views/timetable/ShareDialog.jsx +++ b/src/views/timetable/ShareDialog.jsx @@ -1,8 +1,14 @@ -import { toPng } from 'html-to-image'; -import React, { useEffect, useState } from 'react'; -import CustomDialog from '@components/CustomDialog'; -import { Box, Button, makeStyles, TextField, Typography } from '@material-ui/core'; -import { TimetableElementID } from './Timetable'; +import { toPng } from "html-to-image"; +import React, { useEffect, useState } from "react"; +import CustomDialog from "@components/CustomDialog"; +import { + Box, + Button, + makeStyles, + TextField, + Typography, +} from "@material-ui/core"; +import { TimetableElementID } from "./Timetable"; export default function ShareDialog(props) { // props @@ -13,9 +19,10 @@ export default function ShareDialog(props) { const classes = useStyles(); // states - const [imageSrc, setImageSrc] = useState(''); + const [imageSrc, setImageSrc] = useState(""); const [imageResolutionWidth, setImageResolutionWidth] = useState(screenWidth); - const [imageResolutionHeight, setImageResolutionHeight] = useState(screenHeight); + const [imageResolutionHeight, setImageResolutionHeight] = + useState(screenHeight); // TODO: use debounce // generate timetable image @@ -27,10 +34,14 @@ export default function ShareDialog(props) { // get real size of timetable in pixel // const beforeWidth = parseInt(window.getComputedStyle(timetableElement).width); - const beforeHeight = parseInt(window.getComputedStyle(timetableElement).height); + const beforeHeight = parseInt( + window.getComputedStyle(timetableElement).height + ); // resize timetable (fix height) - timetableElement.style.width = `${Math.floor(beforeHeight * (imageResolutionWidth / imageResolutionHeight))}px`; + timetableElement.style.width = `${Math.floor( + beforeHeight * (imageResolutionWidth / imageResolutionHeight) + )}px`; // configure option for rendering const option = { @@ -42,7 +53,7 @@ export default function ShareDialog(props) { const src = await toPng(timetableElement, option); // revert timetable size - timetableElement.style.width = ''; + timetableElement.style.width = ""; setImageSrc(src); }, [open, imageResolutionWidth, imageResolutionHeight]); @@ -61,8 +72,12 @@ export default function ShareDialog(props) { - 이미지 해상도 변경 - 기기 해상도: {screenWidth} * {screenHeight} + + 이미지 해상도 변경 + + + 기기 해상도: {screenWidth} * {screenHeight} + setImageResolutionWidth(e.target.value)} + onChange={(e) => setImageResolutionWidth(e.target.value)} required /> setImageResolutionHeight(e.target.value)} + onChange={(e) => setImageResolutionHeight(e.target.value)} required /> @@ -100,64 +115,64 @@ export default function ShareDialog(props) { ); } -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ root: { - display: 'flex', - alignItems: 'stretch', - padding: '1em 0', - [theme.breakpoints.down('sm')]: { - flexDirection: 'column', - maxHeight: '80vh', + display: "flex", + alignItems: "stretch", + padding: "1em 0", + [theme.breakpoints.down("sm")]: { + flexDirection: "column", + maxHeight: "80vh", }, - [theme.breakpoints.up('md')]: { - flexDirection: 'row', + [theme.breakpoints.up("md")]: { + flexDirection: "row", }, }, image: { - objectFit: 'contain', - display: 'block', - maxWidth: '100%', - maxHeight: '100%', - margin: 'auto', - boxShadow: '0 0.5em 1em rgba(0, 0, 0, .2)', - overflow: 'hidden', - borderRadius: '0.5em', - [theme.breakpoints.down('sm')]: { - maxHeight: '40vh', + objectFit: "contain", + display: "block", + maxWidth: "100%", + maxHeight: "100%", + margin: "auto", + boxShadow: "0 0.5em 1em rgba(0, 0, 0, .2)", + overflow: "hidden", + borderRadius: "0.5em", + [theme.breakpoints.down("sm")]: { + maxHeight: "40vh", }, - [theme.breakpoints.up('md')]: { - maxHeight: '80vh', - maxWidth: '60%', + [theme.breakpoints.up("md")]: { + maxHeight: "80vh", + maxWidth: "60%", }, }, controlBox: { - display: 'flex', - flexDirection: 'column', - [theme.breakpoints.down('sm')]: { - width: '100%', - marginTop: '3em', + display: "flex", + flexDirection: "column", + [theme.breakpoints.down("sm")]: { + width: "100%", + marginTop: "3em", }, - [theme.breakpoints.up('md')]: { - width: '40%', - marginLeft: '1.5em', + [theme.breakpoints.up("md")]: { + width: "40%", + marginLeft: "1.5em", }, }, inputBox: { - display: 'flex', - margin: '1em 0', - gap: '1em', - '& > *': { - width: '50%', + display: "flex", + margin: "1em 0", + gap: "1em", + "& > *": { + width: "50%", }, }, saveButton: { - display: 'block', - width: '100%', - [theme.breakpoints.down('sm')]: { - marginTop: '2em', + display: "block", + width: "100%", + [theme.breakpoints.down("sm")]: { + marginTop: "2em", }, - [theme.breakpoints.up('md')]: { - marginTop: 'auto', + [theme.breakpoints.up("md")]: { + marginTop: "auto", }, }, })); From e4177eb7ce16ef31706aba2e2ddfa56de5366194 Mon Sep 17 00:00:00 2001 From: GyuZzang Date: Tue, 23 Nov 2021 21:38:17 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat(emailAuth):=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=9D=B8=EC=A6=9D=20=EC=BD=94=EB=93=9C=20api=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=A0=81=EC=9A=A9(userID),=20css=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/EmailAuth.jsx | 87 +++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 20 deletions(-) diff --git a/src/views/EmailAuth.jsx b/src/views/EmailAuth.jsx index 7420e4f..d9e0f34 100644 --- a/src/views/EmailAuth.jsx +++ b/src/views/EmailAuth.jsx @@ -4,7 +4,6 @@ import { requestAPI, API_MAKE_AUTH_CODE, API_MATCH_AUTH_CODE, - API_MY_INFO, } from "@utils/api"; import { Button, @@ -20,6 +19,8 @@ export default function EmailAuth() { const [isCodeSend, setIsCodeSend] = useState(false); const [code, setCode] = useState(null); + const classes = useStyles(); + const codeOnChange = (e) => { setCode(e.target.value); }; @@ -41,7 +42,6 @@ export default function EmailAuth() { }; const handleSendCode = async () => { - console.log(userEmail); try { const res = await requestAPI(API_MAKE_AUTH_CODE({ email: userEmail })); if (res.status === StatusCodes.NO_CONTENT) setIsCodeSend(true); @@ -53,7 +53,8 @@ export default function EmailAuth() { const handleAuth = async () => { try { - const res = await requestAPI(API_MATCH_AUTH_CODE().setPath(code)); + const userId = window.localStorage.getItem("userID"); + const res = await requestAPI(API_MATCH_AUTH_CODE().setPath(userId, code)); if (res.status === StatusCodes.NO_CONTENT) { alert("이메일이 성공적으로 인증되었습니다!"); } @@ -64,25 +65,31 @@ export default function EmailAuth() { }; return ( - - - 이메일 인증 - - - - + + 이메일 인증 + + 서울시립대학교 포털 이메일 인증을 하신 후 강의 교환 서비스를 이용하실 수 + 있습니다. + + + + - {isCodeSend && ( - + - + )} ); } + +const useStyles = makeStyles({ + container: { + margin: "auto", + }, + title: { + alignItems: "center", + textAlign: "center", + fontSize: "1.5rem", + fontWeight: "700", + marginBottom: "1rem", + }, + subTitle: { + alignItems: "center", + textAlign: "center", + fontSize: "1rem", + marginButtom: "1rem", + color: "#A3A2A2", + }, + inputWrapper: { + display: "flex", + width: "60%", + flexDirection: "row", + marginTop: "2rem", + }, + input: { + flex: 9, + }, + button: { + flex: 3, + marginLeft: "1rem", + backgroundColor: "#CFCFCF", + textAlign: "center", + boxShadow: "3px 4px 4px rgba(0, 0, 0, 0.25)", + borderRadius: "1.5rem", + color: "#FFF", + }, +});