diff --git a/package-lock.json b/package-lock.json index 5adeeef..ed71cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "react": "^18.2.0", "react-canvas-confetti": "^1.3.0", "react-dom": "^18.2.0", + "react-intersection-observer": "^9.4.3", "react-redux": "^8.0.5", "react-router-dom": "^6.6.2", "react-scripts": "5.0.1", @@ -14604,6 +14605,14 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-intersection-observer": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.3.tgz", + "integrity": "sha512-WNRqMQvKpupr6MzecAQI0Pj0+JQong307knLP4g/nBex7kYfIaZsPpXaIhKHR+oV8z+goUbH9e10j6lGRnTzlQ==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -27846,6 +27855,11 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-intersection-observer": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.3.tgz", + "integrity": "sha512-WNRqMQvKpupr6MzecAQI0Pj0+JQong307knLP4g/nBex7kYfIaZsPpXaIhKHR+oV8z+goUbH9e10j6lGRnTzlQ==" + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index b92556f..c6ed776 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react": "^18.2.0", "react-canvas-confetti": "^1.3.0", "react-dom": "^18.2.0", + "react-intersection-observer": "^9.4.3", "react-redux": "^8.0.5", "react-router-dom": "^6.6.2", "react-scripts": "5.0.1", diff --git a/src/component/404/NotTime.tsx b/src/component/404/NotTime.tsx index ee084db..c21db67 100644 --- a/src/component/404/NotTime.tsx +++ b/src/component/404/NotTime.tsx @@ -1,36 +1,46 @@ /** @jsxImportSource @emotion/react */ import { css, keyframes } from "@emotion/react"; -import React from 'react' -import { Button, Modal, Section } from '../emotion/component' -import oops from '../../images/oops.png'; +import React from "react"; +import { Button, Modal, Section } from "../emotion/component"; +import notTime from "../../images/notTime.png"; import { Link } from "react-router-dom"; import { fadeUp } from "../../styles/Keyframes"; export default function NotTime() { - return ( -
- 404 - 현재는 예비 사자 모집 기간이 아니에요! -
- ) + display: flex; + flex-direction: column; + align-items: center; + `} + > + 404 + {/* + 현재는 예비 사자 모집 기간이 아니에요! + */} + + ); } diff --git a/src/component/404/NotWidth.tsx b/src/component/404/NotWidth.tsx index d5fae52..e6941c9 100644 --- a/src/component/404/NotWidth.tsx +++ b/src/component/404/NotWidth.tsx @@ -1,40 +1,50 @@ /** @jsxImportSource @emotion/react */ import { css, keyframes } from "@emotion/react"; -import React from 'react' -import { Button, Modal, Section } from '../emotion/component' -import oops from '../../images/oops.png'; +import React from "react"; +import { Button, Modal, Section } from "../emotion/component"; +import oops from "../../images/oops.png"; import { Link } from "react-router-dom"; import { fadeUp } from "../../styles/Keyframes"; export default function NotWidth() { - return ( -
- 404 - 원활한 지원환경을 위해
PC 또는 태블릿으로 접속해주세요!
-
- ) + @media (max-width: 1024px) { + display: flex; + } + `} + > + 404 + + 원활한 지원환경을 위해
PC 또는 태블릿으로 접속해주세요! +
+ + ); } diff --git a/src/component/admin/emotion/component.tsx b/src/component/admin/emotion/component.tsx index 649c07c..13a4583 100644 --- a/src/component/admin/emotion/component.tsx +++ b/src/component/admin/emotion/component.tsx @@ -1,67 +1,71 @@ /** @jsxImportSource @emotion/react */ -import React, { useCallback, useEffect, useMemo, useState } from 'react' -import { WrapperProps } from '../../../App' +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { WrapperProps } from "../../../App"; import { css, keyframes } from "@emotion/react"; -import { AgreeType, ButtonType, InputType } from '../../emotion/component'; -import { PositionType } from '../../emotion/component'; -import { Link, useLocation } from 'react-router-dom'; -import oops from '../../../images/oops.png'; -import { fadeUp } from '../../../styles/Keyframes'; -import { MailType, mailUserType } from '../partition/Type'; -import checkBox from '../../../images/checkBox.svg'; -import checkedBox from '../../../images/checkedBox.svg'; -import { useDispatch, useSelector } from 'react-redux'; -import { AppDispatch, TestState } from '../../../app/store'; -import { updatePassMailList } from '../../../features/fetcherSlice'; +import { AgreeType, ButtonType, InputType } from "../../emotion/component"; +import { PositionType } from "../../emotion/component"; +import { Link, useLocation } from "react-router-dom"; +import oops from "../../../images/oops.png"; +import { fadeUp } from "../../../styles/Keyframes"; +import { MailType, mailUserType } from "../partition/Type"; +import checkBox from "../../../images/checkBox.svg"; +import checkedBox from "../../../images/checkedBox.svg"; +import { useDispatch, useSelector } from "react-redux"; +import { AppDispatch, TestState } from "../../../app/store"; +import { updatePassMailList } from "../../../features/fetcherSlice"; export const Section = ({ children }: WrapperProps) => { - return ( -
- {children} -
- ) -} + return ( +
+ {children} +
+ ); +}; export const LoginBox = ({ children }: WrapperProps) => { - return ( -
- {children} -
- ) -} + return ( +
+ {children} +
+ ); +}; export const PassUserContent = ({ children }: WrapperProps) => { - return ( -
{ border-radius: 3.07em; border-width: 0.076em; - border-color: #4F85E8; - color: #4F85E8; - `}> - {children} -
- - ) -} + border-color: #4f85e8; + color: #4f85e8; + `} + > + {children} + + ); +}; export const PassUser = ({ children }: WrapperProps) => { - return ( -
- {children} -
- ) -} + return ( +
{ - return ( -
- {children} -
- ) -} + flex-wrap: wrap; + white-space: normal; + font-size: 15px; + white-space: pre-line; + column-gap: 1em; + row-gap: 1em; + margin-bottom: 1.7em; + `} + > + {children} +
+ ); +}; +export const Content = ({ children }: WrapperProps) => { + return ( +
+ {children} +
+ ); +}; export const FailMailSend = (props: MailType) => { - return ( -
{props.position} 포지션의 불합격 메일 전체 전송을 하고싶으신가요?
- ) -} + &:hover { + opacity: 80%; + } + `} + {...props} + > + {" "} + + {props.position} + {" "} + 포지션의 불합격 메일 전체 전송을 하고싶으신가요?{" "} + + ); +}; export const PassMailSend = (props: MailType) => { + const passMailList = useSelector( + (state: TestState) => state.fetcher.passMailList + ); + + return ( +
state.fetcher.passMailList); - - return ( -
{props.position} 포지션의 합격 메일 전송을 하고싶으신가요?
- ) -} + &:hover { + opacity: 80%; + } + `} + {...props} + > + {" "} + + {props.position} + {" "} + 포지션의 합격 메일 전송을 하고싶으신가요? +
+ ); +}; export const Button = (props: ButtonType) => { - return ( - - ) -} + &:hover { + opacity: 80%; + } + `} + {...props} + > + {props.children} + + ); +}; export interface HeaderType { - path?: string; - children?: React.ReactNode; - url?: string; + path?: string; + children?: React.ReactNode; + url?: string; } export const HeaderText = (props: HeaderType) => { - return ( -
{props.children}
- ) -} + text-decoration: none; + color: #6b7684; + cursor: pointer; + + ${props.path === props.url && + css` + border: none; + font-family: "Pretendard-Bold"; + border: color; + color: #4f85e8; + // border-bottom: 0.16em solid #4F85E8; + // margin-bottom: -0.16em; + `} + `} + tabIndex={-1} + > + {props.children} + + ); +}; interface ImgType { - src?: string; + src?: string; } export const Img = (props: ImgType) => { - return ( - 어드민 이미지 - ) -} + return ( + 어드민 이미지 + ); +}; export const HeaderDescription = ({ children }: WrapperProps) => { - return ( - - {children} - - ) -} + return ( + + {children} + + ); +}; export const Position = (props: PositionType) => { - return ( - - ) -} + `} + {...props} + tabIndex={-1} + > + {props.children} + + ); +}; export const NotData = () => { - return ( - <> - Oops! - - 데이터가 존재하지 않아요! - - - ) -} + return ( + <> + Oops! + + 데이터가 존재하지 않아요! + + + ); +}; export const PositionBox = (props: WrapperProps) => { - return ( -
- {props.children} -
- ) -} + return ( +
+ {props.children} +
+ ); +}; export const Input = (props: InputType) => { - return ( - - ) -} + &:focus { + outline-color: #4f85e8; + + &:hover { + box-shadow: none; + } + // box-shadow: inset 0 0 0 2px #4F85E8; + } + + &:hover { + box-shadow: inset 0 0 0 2px #90c2ff; + } + + &::placeholder { + font-family: "Pretendard-Regular"; + margin-left: 0.4em; + } + `} + {...props} + /> + ); +}; export interface ChangeCheckStateType { - (userName: string, userEmail: string, userId: string): void; + (userName: string, userEmail: string, userId: string): void; } export interface ListType { - name?: string; - id?: string; - department?: string; - email?: string; - position?: string; - check?: string; - onClick?: (event: React.MouseEvent) => void; - children?: React.ReactNode; - mailState?: boolean; + name?: string; + id?: string; + department?: string; + email?: string; + position?: string; + check?: string; + onClick?: (event: React.MouseEvent) => void; + children?: React.ReactNode; + mailState?: boolean; } export interface onModalType { - (userID: string): void; + (userID: string): void; } // 사용자 리스트를 나타내주는 컴포넌트 export const List = React.memo(function List(props: ListType) { + const [checkState, setCheckState] = useState(false); + const [checkList, setCheckList] = useState([]); + const [userEmail, setEmail] = useState(""); + const [userName, setName] = useState(""); + const [userId, setId] = useState(""); + + const dispatch = useDispatch(); + const passMailList = useSelector( + (state: TestState) => state.fetcher.passMailList + ); + const newList = useSelector((state: TestState) => state.fetcher.newList); + + const ChangeCheckState: ChangeCheckStateType = useCallback( + (userEmail: string, userName: string, userId: string) => { + setCheckState(!checkState); + setEmail(userEmail); + setName(userName); + setId(userId); + // await setCheckList(user) + // 전역 상태로 업데이트 할 것! + }, + [checkState] + ); + + useEffect(() => { + setCheckState(false); + }, [newList]); + + useEffect(() => { + if (checkState) { + dispatch( + updatePassMailList([ + ...passMailList, + { + id: userId as string, + name: userName as string, + email: userEmail as string, + }, + ]) + ); + } else if (!checkState) { + dispatch( + updatePassMailList( + passMailList.filter((items: mailUserType) => { + return items.id !== userId; + }) + ) + ); + } + }, [checkState]); + + return ( +
(false); - const [checkList, setCheckList] = useState([]); - const [userEmail, setEmail] = useState(''); - const [userName, setName] = useState(''); - const [userId, setId] = useState(''); - - const dispatch = useDispatch(); - const passMailList = useSelector((state: TestState) => state.fetcher.passMailList); - const newList = useSelector((state: TestState) => (state.fetcher.newList)); - - const ChangeCheckState: ChangeCheckStateType = useCallback((userEmail: string, userName: string, userId: string) => { - setCheckState(!checkState); - setEmail(userEmail); - setName(userName); - setId(userId); - // await setCheckList(user) - // 전역 상태로 업데이트 할 것! - }, [checkState]); - - useEffect(() => { - setCheckState(false); - }, [newList]) - - useEffect(() => { - if (checkState) { - dispatch(updatePassMailList([...passMailList, { id: userId as string, name: userName as string, email: userEmail as string }])) - } else if (!checkState) { - dispatch(updatePassMailList(passMailList.filter((items: mailUserType) => { return items.id !== userId }))) - } - }, [checkState]) - - return ( -
+ {props.name} + {props.position} + {props.department} + + {props.id !== "학번" && props.mailState ? ( + - {props.name} - {props.position} - {props.department} - - {props.id !== "학번" && props.mailState ? {props.id} : props.id} - - {/* {props.email} */} - {props.check === "체크 없음" && null} - {props.check === "전송 체크" ? {props.check} : !props.check && ChangeCheckState(props.email as string, props.name as string, props.id as string)}> } -
- ) + > + {" "} + {props.id}{" "} + + ) : ( + props.id + )} + + {/* {props.email} */} + {props.check === "체크 없음" && null} + {props.check === "전송 체크" ? ( + {props.check} + ) : ( + !props.check && ( + + ChangeCheckState( + props.email as string, + props.name as string, + props.id as string + ) + } + > + {" "} + {" "} + + ) + )} +
+ ); }); export const ListText = (props: ListType) => { - return ( -
- {props.children} -
- ) -} + return ( +
+ {props.children} +
+ ); +}; diff --git a/src/component/position/Backend.tsx b/src/component/position/Backend.tsx index 59b883b..ab5f9f6 100644 --- a/src/component/position/Backend.tsx +++ b/src/component/position/Backend.tsx @@ -1,115 +1,202 @@ -import React, { ChangeEvent } from 'react' -import { ButtonBox, Section, Button, Require, Article, InputTitle, TextAreaBox, InputBox, Banner, WordLength, Modal, Footer } from '../emotion/component' -import { useNavigate } from 'react-router-dom' -import { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { AppDispatch, TestState } from '../../app/store'; -import { saveCommon, saveIndex, view, saveBackEnd } from '../../features/fetcherSlice'; -import { useEffect, useMemo } from 'react'; -import axios from 'axios'; -import tempImg from '../../images/temp.png'; -import completeImg from '../../images/complete.png'; -import Confetti from '../../hooks/Confetti'; -import { currentTime, endTime } from '../time/time'; +import React, { ChangeEvent } from "react"; +import { + ButtonBox, + Section, + Button, + Require, + Article, + InputTitle, + TextAreaBox, + InputBox, + Banner, + WordLength, + Modal, + Footer, +} from "../emotion/component"; +import { useNavigate } from "react-router-dom"; +import { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AppDispatch, TestState } from "../../app/store"; +import { + saveCommon, + saveIndex, + view, + saveBackEnd, +} from "../../features/fetcherSlice"; +import { useEffect, useMemo } from "react"; +import axios from "axios"; +import tempImg from "../../images/temp.png"; +import completeImg from "../../images/complete.png"; +import Confetti from "../../hooks/Confetti"; +import { currentTime, endTime } from "../time/time"; export default function Backend() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const [difficultAndOvercoming, setDifficultAndOvercoming] = useState(""); + const [studyFramework, setStudyFramework] = useState(""); + const [importantGroup, setImportantGroup] = useState(""); + const [portfolioLink, setPortfolioLink] = useState(""); + const [buttonState, setButtonState] = useState(false); + const [backButtonState, setBackButtonState] = useState(false); + const [submitCount, setSubmitCount] = useState(0); + const [tempState, setTempState] = useState(false); + const [temp, setTemp] = useState(false); + const [complete, setComplete] = useState(false); - const navigate = useNavigate(); - const dispatch = useDispatch(); - const [difficultAndOvercoming, setDifficultAndOvercoming] = useState(''); - const [studyFramework, setStudyFramework] = useState(''); - const [importantGroup, setImportantGroup] = useState(''); - const [portfolioLink, setPortfolioLink] = useState(''); - const [buttonState, setButtonState] = useState(false); - const [backButtonState, setBackButtonState] = useState(false); - const [submitCount, setSubmitCount] = useState(0); - const [tempState, setTempState] = useState(false); - const [temp, setTemp] = useState(false); - const [complete, setComplete] = useState(false); + const userName = useSelector((state: TestState) => state.fetcher.userName); + const userID = useSelector((state: TestState) => state.fetcher.userID); + const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); + const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); + const userPosition = useSelector( + (state: TestState) => state.fetcher.userPosition + ); + const userDepartment = useSelector( + (state: TestState) => state.fetcher.userDepartment + ); - const userName = useSelector((state: TestState) => state.fetcher.userName); - const userID = useSelector((state: TestState) => state.fetcher.userID); - const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); - const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); - const userPosition = useSelector((state: TestState) => state.fetcher.userPosition); - const userDepartment = useSelector((state: TestState) => state.fetcher.userDepartment); + const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); + const userHardWork = useSelector( + (state: TestState) => state.fetcher.userHardWork + ); + const userKeyWord = useSelector( + (state: TestState) => state.fetcher.userKeyWord + ); + const userMostDeeplyWork = useSelector( + (state: TestState) => state.fetcher.userMostDeeplyWork + ); - const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); - const userHardWork = useSelector((state: TestState) => state.fetcher.userHardWork); - const userKeyWord = useSelector((state: TestState) => state.fetcher.userKeyWord); - const userMostDeeplyWork = useSelector((state: TestState) => state.fetcher.userMostDeeplyWork); + const userDifficultAndOvercoming = useSelector( + (state: TestState) => state.fetcher.userDifficultAndOvercoming + ); + const userStudyFramework = useSelector( + (state: TestState) => state.fetcher.userStudyFramework + ); + const userImportantGroup = useSelector( + (state: TestState) => state.fetcher.userImportantGroup + ); + const userPortfolioLink = useSelector( + (state: TestState) => state.fetcher.userPortfolioLinkBack + ); - const userDifficultAndOvercoming = useSelector((state: TestState) => state.fetcher.userDifficultAndOvercoming); - const userStudyFramework = useSelector((state: TestState) => state.fetcher.userStudyFramework); - const userImportantGroup = useSelector((state: TestState) => state.fetcher.userImportantGroup); - const userPortfolioLink = useSelector((state: TestState) => state.fetcher.userPortfolioLinkBack); + const [name, setName] = useState(""); - const [name, setName] = useState(''); + useEffect(() => { + document.body.style.overflow = "unset"; - useEffect(() => { - document.body.style.overflow = "unset"; + if (!userName && !userID && !userPhone && !userEmail && !userPosition) { + navigate("/404"); + } - if (!userName && !userID && !userPhone && !userEmail && !userPosition) { - navigate('/404') - } + if (currentTime > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); + } - if (currentTime > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } + // 이전 값들을 저장하기 위해서 Redux 사용 + if (userDifficultAndOvercoming) { + setDifficultAndOvercoming(userDifficultAndOvercoming); + } - // 이전 값들을 저장하기 위해서 Redux 사용 - if (userDifficultAndOvercoming) { - setDifficultAndOvercoming(userDifficultAndOvercoming); - } + if (userStudyFramework) { + setStudyFramework(userStudyFramework); + } - if (userStudyFramework) { - setStudyFramework(userStudyFramework); - } + if (userImportantGroup) { + setImportantGroup(userImportantGroup); + } - if (userImportantGroup) { - setImportantGroup(userImportantGroup); - } + if (userPortfolioLink) { + setPortfolioLink(userPortfolioLink); + } - if (userPortfolioLink) { - setPortfolioLink(userPortfolioLink) - } + if (userName) { + setName(userName); + } + }, []); - if (userName) { - setName(userName) - } - }, []) + useMemo(() => { + // 백엔드 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 + if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { + setTempState(false); + } else { + setTempState(true); + } - useMemo(() => { + if (difficultAndOvercoming && studyFramework && importantGroup) { + setButtonState(false); + } else { + setButtonState(true); + } + if (submitCount >= 1) { + setButtonState(true); + setBackButtonState(true); + } + }, [difficultAndOvercoming, studyFramework, importantGroup, submitCount]); - // 백엔드 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 - if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { - setTempState(false); - } else { - setTempState(true); - } + const Back = () => { + setSubmitCount((prev) => prev + 1); + dispatch( + saveBackEnd({ + userDifficultAndOvercoming: difficultAndOvercoming, + userStudyFramework: studyFramework, + userImportantGroup: importantGroup, + userPortfolioLinkBack: portfolioLink, + }) + ); + navigate("/common"); + }; - if (difficultAndOvercoming && studyFramework && importantGroup) { - setButtonState(false) - } else { - setButtonState(true) - } - if (submitCount >= 1) { - setButtonState(true); - setBackButtonState(true); + const TempSave = () => { + setSubmitCount((prev) => prev + 1); + axios + .post( + "/backendApplication", + JSON.stringify({ + department: userDepartment, + difficultAndOvercoming: difficultAndOvercoming, + email: userEmail, + hardWork: userHardWork, + importantGroup: importantGroup, + keyWord: userKeyWord, + mostDeeplyWork: userMostDeeplyWork, + motive: userMotiv, + name: userName, + passOrNot: false, + sendMail: false, + phoneNumber: userPhone, + portfolioFile: "", + portfolioLink: portfolioLink, + sid: userID, + studyFramework: studyFramework, + submissionStatus: false, + }), + { + headers: { + "Content-type": "application/json", + }, } - }, [difficultAndOvercoming, studyFramework, importantGroup, submitCount]) - + ) + .then((res) => { + setTemp(!temp); + document.body.style.overflow = "hidden"; + }); + }; - const Back = () => { - setSubmitCount((prev) => (prev + 1)) - dispatch(saveBackEnd({ userDifficultAndOvercoming: difficultAndOvercoming, userStudyFramework: studyFramework, userImportantGroup: importantGroup, userPortfolioLinkBack: portfolioLink })); - navigate('/common'); - } + const Submit = () => { + const time = new Date(); - const TempSave = () => { - setSubmitCount((prev) => (prev + 1)) - axios.post('/backendApplication', JSON.stringify({ + if (time > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); + } else if ( + window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?") + ) { + setSubmitCount((prev) => prev + 1); + axios + .post( + "/backendApplication", + JSON.stringify({ department: userDepartment, difficultAndOvercoming: difficultAndOvercoming, email: userEmail, @@ -126,181 +213,179 @@ export default function Backend() { portfolioLink: portfolioLink, sid: userID, studyFramework: studyFramework, - submissionStatus: false, - }), - { - headers: { - "Content-type": "application/json", - } - } + submissionStatus: true, + }), + { + headers: { + "Content-type": "application/json", + }, + } ) - .then((res) => { - dispatch(saveBackEnd({ - userDifficultAndOvercoming: '', - userImportantGroup: '', - userPortfolioLink: '', - userStudyFramework: '', - })); - dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - setTemp(!temp); - document.body.style.overflow = "hidden"; - }) + .then((res) => { + setComplete(!complete); + document.body.style.overflow = "hidden"; + }); } + }; - const Submit = () => { - - const time = new Date(); - - if (time > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } - - else if (window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?")) { - setSubmitCount((prev) => (prev + 1)) - axios.post('/backendApplication', JSON.stringify({ - department: userDepartment, - difficultAndOvercoming: difficultAndOvercoming, - email: userEmail, - hardWork: userHardWork, - importantGroup: importantGroup, - keyWord: userKeyWord, - mostDeeplyWork: userMostDeeplyWork, - motive: userMotiv, - name: userName, - passOrNot: false, - sendMail: false, - phoneNumber: userPhone, - portfolioFile: "", - portfolioLink: portfolioLink, - sid: userID, - studyFramework: studyFramework, - submissionStatus: true, - }), - { - headers: { - "Content-type": "application/json", - } - } - ) - .then((res) => { - setComplete(!complete); - document.body.style.overflow = "hidden"; - }) - } + const handleChange = ( + event: ChangeEvent | ChangeEvent + ) => { + if (event.target.name === "극복") { + if (event.target.value.length <= 1000) { + setDifficultAndOvercoming(event.target.value); + } } - const handleChange = (event: ChangeEvent | ChangeEvent) => { - if (event.target.name === "극복") { - if (event.target.value.length <= 1000) { - setDifficultAndOvercoming(event.target.value); - } - } - - if (event.target.name === "경험") { - if (event.target.value.length <= 1000) { - setStudyFramework(event.target.value); - } - } - - if (event.target.name === "팀워크") { - if (event.target.value.length <= 1000) { - setImportantGroup(event.target.value); - } - } - - if (event.target.name === "포트폴리오") { - setPortfolioLink(event.target.value); - } + if (event.target.name === "경험") { + if (event.target.value.length <= 1000) { + setStudyFramework(event.target.value); + } } - const TempBack = async () => { - setTemp(false); - setSubmitCount(0); - setTempState(false); - setButtonState(false); - document.body.style.overflow = "unset"; + if (event.target.name === "팀워크") { + if (event.target.value.length <= 1000) { + setImportantGroup(event.target.value); + } } - /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ - const TempHome = async () => { - await dispatch(saveBackEnd({ - userDifficultAndOvercoming: '', - userImportantGroup: '', - userPortfolioLink: '', - userStudyFramework: '', - })); - await dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - await dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - await navigate('/'); + if (event.target.name === "포트폴리오") { + setPortfolioLink(event.target.value); } + }; + + const TempBack = async () => { + setTemp(false); + setSubmitCount(0); + setTempState(false); + setButtonState(false); + document.body.style.overflow = "unset"; + }; + + /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ + const TempHome = async () => { + await dispatch( + saveBackEnd({ + userDifficultAndOvercoming: "", + userImportantGroup: "", + userPortfolioLink: "", + userStudyFramework: "", + }) + ); + await dispatch( + saveCommon({ + userMotiv: "", + userHardWork: "", + userKeyWord: "", + userMostDeeplyWork: "", + }) + ); + await dispatch( + saveIndex({ + userName: "", + userID: "", + userDepartment: "", + userEmail: "", + userPhone: "", + userPosition: "", + }) + ); + await navigate("/"); + }; - return ( -
- {complete && } - {complete ? - - - - : null - } - {temp ? - - - - - : null - } - -
- 개발 관련 공부를 하며 개인적으로 힘들었던 경험과 그걸 극복했던 자신만의 방법이 있나요? - - {difficultAndOvercoming.length} -
-
- 웹 백앤드 프레임워크를 공부해보신적 있으신가요? 있으시다면 어디까지 공부해보셨나요? - - {studyFramework.length} -
-
- 단체생활에서 가장 중요하다고 생각하는 것은 무엇인가요? - - {importantGroup.length} -
-
- 깃허브 또는 포트폴리오 링크가 있다면 첨부해주세요 - -
- - - - - -
- ) + return ( +
+ {complete && } + {complete ? ( + + + + ) : null} + {temp ? ( + + + + + ) : null} + +
+ + 개발 관련 공부를 하며 개인적으로 힘들었던 경험과 그걸 극복했던 + 자신만의 방법이 있나요? + {" "} + + + {difficultAndOvercoming.length} +
+
+ + 웹 백앤드 프레임워크를 공부해보신적 있으신가요? 있으시다면 어디까지 + 공부해보셨나요? + {" "} + + + {studyFramework.length} +
+
+ + 단체생활에서 가장 중요하다고 생각하는 것은 무엇인가요? + {" "} + + + {importantGroup.length} +
+
+ + 깃허브 또는 포트폴리오 링크가 있다면 첨부해주세요{" "} + + +
+ + + + + +
+ ); } diff --git a/src/component/position/Design.tsx b/src/component/position/Design.tsx index 8e81da2..5209be6 100644 --- a/src/component/position/Design.tsx +++ b/src/component/position/Design.tsx @@ -1,119 +1,215 @@ -import React, { ChangeEvent } from 'react' -import { ButtonBox, Section, Button, Require, Article, InputTitle, TextAreaBox, InputBox, Banner, WordLength, Modal, Footer } from '../emotion/component' -import { useNavigate } from 'react-router-dom' -import { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { AppDispatch, TestState } from '../../app/store'; -import { saveCommon, saveIndex, view, saveDesign } from '../../features/fetcherSlice'; -import { useEffect, useMemo } from 'react'; -import axios from 'axios'; -import tempImg from '../../images/temp.png'; -import completeImg from '../../images/complete.png'; -import Confetti from '../../hooks/Confetti'; -import { currentTime, endTime } from '../time/time'; - +import React, { ChangeEvent } from "react"; +import { + ButtonBox, + Section, + Button, + Require, + Article, + InputTitle, + TextAreaBox, + InputBox, + Banner, + WordLength, + Modal, + Footer, +} from "../emotion/component"; +import { useNavigate } from "react-router-dom"; +import { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AppDispatch, TestState } from "../../app/store"; +import { + saveCommon, + saveIndex, + view, + saveDesign, +} from "../../features/fetcherSlice"; +import { useEffect, useMemo } from "react"; +import axios from "axios"; +import tempImg from "../../images/temp.png"; +import completeImg from "../../images/complete.png"; +import Confetti from "../../hooks/Confetti"; +import { currentTime, endTime } from "../time/time"; export default function Design() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const [whyDesign, setWhyDesign] = useState(""); + const [toolExperience, setToolExperience] = useState(""); + const [teamworkExperience, setTeamworkExperience] = useState(""); + const [designGrowth, setDesignGrowth] = useState(""); + const [buttonState, setButtonState] = useState(false); + const [portfolioLink, setPortfolioLink] = useState(""); + const [submitCount, setSubmitCount] = useState(0); + const [tempState, setTempState] = useState(false); + const [temp, setTemp] = useState(false); + const [complete, setComplete] = useState(false); + + const userName = useSelector((state: TestState) => state.fetcher.userName); + const userID = useSelector((state: TestState) => state.fetcher.userID); + const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); + const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); + const userPosition = useSelector( + (state: TestState) => state.fetcher.userPosition + ); + const userDepartment = useSelector( + (state: TestState) => state.fetcher.userDepartment + ); + + const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); + const userHardWork = useSelector( + (state: TestState) => state.fetcher.userHardWork + ); + const userKeyWord = useSelector( + (state: TestState) => state.fetcher.userKeyWord + ); + const userMostDeeplyWork = useSelector( + (state: TestState) => state.fetcher.userMostDeeplyWork + ); + + const userWhyDesign = useSelector( + (state: TestState) => state.fetcher.userWhyDesign + ); + const userToolExperience = useSelector( + (state: TestState) => state.fetcher.userToolExperience + ); + const userTeamworkExperience = useSelector( + (state: TestState) => state.fetcher.userTeamworkExperience + ); + const userDesignGrowth = useSelector( + (state: TestState) => state.fetcher.userDesignGrowth + ); + const userPortfolioLink = useSelector( + (state: TestState) => state.fetcher.userPortfolioLinkDesign + ); + + const [name, setName] = useState(""); + + useEffect(() => { + document.body.style.overflow = "unset"; + if (!userName && !userID && !userPhone && !userEmail && !userPosition) { + navigate("/404"); + } - const navigate = useNavigate(); - const dispatch = useDispatch(); - const [whyDesign, setWhyDesign] = useState(''); - const [toolExperience, setToolExperience] = useState(''); - const [teamworkExperience, setTeamworkExperience] = useState(''); - const [designGrowth, setDesignGrowth] = useState(''); - const [buttonState, setButtonState] = useState(false); - const [portfolioLink, setPortfolioLink] = useState(''); - const [submitCount, setSubmitCount] = useState(0); - const [tempState, setTempState] = useState(false); - const [temp, setTemp] = useState(false); - const [complete, setComplete] = useState(false); - - const userName = useSelector((state: TestState) => state.fetcher.userName); - const userID = useSelector((state: TestState) => state.fetcher.userID); - const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); - const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); - const userPosition = useSelector((state: TestState) => state.fetcher.userPosition); - const userDepartment = useSelector((state: TestState) => state.fetcher.userDepartment); - - const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); - const userHardWork = useSelector((state: TestState) => state.fetcher.userHardWork); - const userKeyWord = useSelector((state: TestState) => state.fetcher.userKeyWord); - const userMostDeeplyWork = useSelector((state: TestState) => state.fetcher.userMostDeeplyWork); - - const userWhyDesign = useSelector((state: TestState) => state.fetcher.userWhyDesign); - const userToolExperience = useSelector((state: TestState) => state.fetcher.userToolExperience); - const userTeamworkExperience = useSelector((state: TestState) => state.fetcher.userTeamworkExperience); - const userDesignGrowth = useSelector((state: TestState) => state.fetcher.userDesignGrowth); - const userPortfolioLink = useSelector((state: TestState) => state.fetcher.userPortfolioLinkDesign); - - const [name, setName] = useState(''); - - useEffect(() => { - document.body.style.overflow = "unset"; - if (!userName && !userID && !userPhone && !userEmail && !userPosition) { - navigate('/404') - } - - if (currentTime > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } - - // 이전 값들을 저장하기 위해서 Redux 사용 - if (userWhyDesign) { - setWhyDesign(userWhyDesign); - } - - if (userToolExperience) { - setToolExperience(userToolExperience); - } - - if (userTeamworkExperience) { - setTeamworkExperience(userTeamworkExperience); - } - - if (userDesignGrowth) { - setDesignGrowth(userDesignGrowth); - } - - if (userPortfolioLink) { - setPortfolioLink(userPortfolioLink) - } + if (currentTime > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); + } - if (userName) { - setName(userName) - } + // 이전 값들을 저장하기 위해서 Redux 사용 + if (userWhyDesign) { + setWhyDesign(userWhyDesign); + } - }, []) + if (userToolExperience) { + setToolExperience(userToolExperience); + } - useMemo(() => { - // 디자인 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 - if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { - setTempState(false); - } else { - setTempState(true); - } + if (userTeamworkExperience) { + setTeamworkExperience(userTeamworkExperience); + } - if (whyDesign && toolExperience && teamworkExperience && designGrowth) { - setButtonState(false) - } else { - setButtonState(true) - } - if (submitCount >= 1) { - setButtonState(true); - } - }, [whyDesign, toolExperience, teamworkExperience, designGrowth, submitCount]) + if (userDesignGrowth) { + setDesignGrowth(userDesignGrowth); + } + if (userPortfolioLink) { + setPortfolioLink(userPortfolioLink); + } - const Back = () => { - setSubmitCount((prev) => (prev + 1)) - dispatch(saveDesign({ userWhyDesign: whyDesign, userToolExperience: toolExperience, userTeamworkExperience: teamworkExperience, userDesignGrowth: designGrowth, userPortfolioLinkDesign: portfolioLink })); - navigate('/common'); + if (userName) { + setName(userName); + } + }, []); + + useMemo(() => { + // 디자인 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 + if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { + setTempState(false); + } else { + setTempState(true); } - const TempSave = () => { - setSubmitCount((prev) => (prev + 1)) - axios.post('/designApplication', JSON.stringify({ + if (whyDesign && toolExperience && teamworkExperience && designGrowth) { + setButtonState(false); + } else { + setButtonState(true); + } + if (submitCount >= 1) { + setButtonState(true); + } + }, [ + whyDesign, + toolExperience, + teamworkExperience, + designGrowth, + submitCount, + ]); + + const Back = () => { + setSubmitCount((prev) => prev + 1); + dispatch( + saveDesign({ + userWhyDesign: whyDesign, + userToolExperience: toolExperience, + userTeamworkExperience: teamworkExperience, + userDesignGrowth: designGrowth, + userPortfolioLinkDesign: portfolioLink, + }) + ); + navigate("/common"); + }; + + const TempSave = () => { + setSubmitCount((prev) => prev + 1); + axios + .post( + "/designApplication", + JSON.stringify({ + department: userDepartment, + whyDesign: whyDesign, + email: userEmail, + hardWork: userHardWork, + toolExperience: toolExperience, + keyWord: userKeyWord, + mostDeeplyWork: userMostDeeplyWork, + motive: userMotiv, + name: userName, + passOrNot: false, + sendMail: false, + phoneNumber: userPhone, + portfolioFile: "", + portfolioLink: portfolioLink, + sid: userID, + teamworkExperience: teamworkExperience, + designGrowth: designGrowth, + submissionStatus: false, + }), + { + headers: { + "Content-type": "application/json", + }, + } + ) + .then((res) => { + setTemp(!temp); + document.body.style.overflow = "hidden"; + }); + }; + + const Submit = async () => { + const time = new Date(); + + if (time > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); + } else if ( + window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?") + ) { + setSubmitCount((prev) => prev + 1); + axios + .post( + "/designApplication", + JSON.stringify({ department: userDepartment, whyDesign: whyDesign, email: userEmail, @@ -131,194 +227,224 @@ export default function Design() { sid: userID, teamworkExperience: teamworkExperience, designGrowth: designGrowth, - submissionStatus: false, - }), - { - headers: { - "Content-type": "application/json", - } - } + submissionStatus: true, + }), + { + headers: { + "Content-type": "application/json", + }, + } ) - .then((res) => { - setTemp(!temp); - document.body.style.overflow = "hidden"; + .then((res) => { + dispatch( + saveDesign({ + userWhyDesign: "", + userToolExperience: "", + userTeamworkExperience: "", + userPortfolioLinkDesign: "", + userDesignGrowth: "", + }) + ); + dispatch( + saveCommon({ + userMotiv: "", + userHardWork: "", + userKeyWord: "", + userMostDeeplyWork: "", }) + ); + dispatch( + saveIndex({ + userName: "", + userID: "", + userDepartment: "", + userEmail: "", + userPhone: "", + userPosition: "", + }) + ); + setComplete(!complete); + document.body.style.overflow = "hidden"; + }); } - - const Submit = async () => { - - const time = new Date(); - - if (time > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } - else if (window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?")) { - setSubmitCount((prev) => (prev + 1)) - axios.post('/designApplication', JSON.stringify({ - department: userDepartment, - whyDesign: whyDesign, - email: userEmail, - hardWork: userHardWork, - toolExperience: toolExperience, - keyWord: userKeyWord, - mostDeeplyWork: userMostDeeplyWork, - motive: userMotiv, - name: userName, - passOrNot: false, - sendMail: false, - phoneNumber: userPhone, - portfolioFile: "", - portfolioLink: portfolioLink, - sid: userID, - teamworkExperience: teamworkExperience, - designGrowth: designGrowth, - submissionStatus: true, - }), - { - headers: { - "Content-type": "application/json", - } - } - ) - .then((res) => { - dispatch(saveDesign({ - userWhyDesign: '', - userToolExperience: '', - userTeamworkExperience: '', - userPortfolioLinkDesign: '', - userDesignGrowth: '', - })); - dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - setComplete(!complete) - document.body.style.overflow = "hidden"; - }) - } + }; + + const handleChange = ( + event: ChangeEvent | ChangeEvent + ) => { + if (event.target.name === "동기") { + if (event.target.value.length <= 1000) { + setWhyDesign(event.target.value); + } } - const handleChange = (event: ChangeEvent | ChangeEvent) => { - if (event.target.name === "동기") { - if (event.target.value.length <= 1000) { - setWhyDesign(event.target.value); - } - } - - if (event.target.name === "경험") { - if (event.target.value.length <= 1000) { - setToolExperience(event.target.value); - } - } - - if (event.target.name === "팀워크") { - if (event.target.value.length <= 1000) { - setTeamworkExperience(event.target.value); - } - } - - if (event.target.name === "성장") { - if (event.target.value.length <= 1000) { - setDesignGrowth(event.target.value); - } - } - - if (event.target.name === "포트폴리오") { - setPortfolioLink(event.target.value); - } + if (event.target.name === "경험") { + if (event.target.value.length <= 1000) { + setToolExperience(event.target.value); + } } - const TempBack = async () => { - setTemp(false); - setSubmitCount(0); - setTempState(false); - setButtonState(false); - document.body.style.overflow = "unset"; + if (event.target.name === "팀워크") { + if (event.target.value.length <= 1000) { + setTeamworkExperience(event.target.value); + } } - /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ - const TempHome = async () => { - await dispatch(saveDesign({ - userWhyDesign: '', - userToolExperience: '', - userTeamworkExperience: '', - userPortfolioLinkDesign: '', - userDesignGrowth: '', - })); - await dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - await dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - await navigate('/'); + if (event.target.name === "성장") { + if (event.target.value.length <= 1000) { + setDesignGrowth(event.target.value); + } } - return ( -
- {complete && } - {complete ? - - - - : null - } - {temp ? - - - - - : null - } - -
- 디자인 트랙을 선택하게 된 이유를 구체적으로 서술해주세요 - - {whyDesign.length} -
-
- 피그마나 Adobe XD와 같은 목업 툴에 관련된 경험을 해본 적이 있다면 그 경험에 대해 자세히 설명을 해주세요 - - {toolExperience.length} -
-
- 본인이 협업과 팀워크를 진행해 보았던 경험과, 그 경험을 멋쟁이 사자처럼 대학에서 어떻게 적용시킬 수 있는지 알려주세요 - - {teamworkExperience.length} -
-
- 디자인 트랙을 통해 어떠한 성장을 희망하시는지 구체적으로 서술해주세요 - - {designGrowth.length} -
-
- 포트폴리오 링크가 있다면 첨부해주세요 - -
- - - - - -
- ) + if (event.target.name === "포트폴리오") { + setPortfolioLink(event.target.value); + } + }; + + const TempBack = async () => { + setTemp(false); + setSubmitCount(0); + setTempState(false); + setButtonState(false); + document.body.style.overflow = "unset"; + }; + + /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ + const TempHome = async () => { + await dispatch( + saveDesign({ + userWhyDesign: "", + userToolExperience: "", + userTeamworkExperience: "", + userPortfolioLinkDesign: "", + userDesignGrowth: "", + }) + ); + await dispatch( + saveCommon({ + userMotiv: "", + userHardWork: "", + userKeyWord: "", + userMostDeeplyWork: "", + }) + ); + await dispatch( + saveIndex({ + userName: "", + userID: "", + userDepartment: "", + userEmail: "", + userPhone: "", + userPosition: "", + }) + ); + await navigate("/"); + }; + + return ( +
+ {complete && } + {complete ? ( + + + + ) : null} + {temp ? ( + + + + + ) : null} + +
+ + 디자인 트랙을 선택하게 된 이유를 구체적으로 서술해주세요 + {" "} + + + {whyDesign.length} +
+
+ + 피그마나 Adobe XD와 같은 목업 툴에 관련된 경험을 해본 적이 있다면 그 + 경험에 대해 자세히 설명을 해주세요 + {" "} + + + {toolExperience.length} +
+
+ + 본인이 협업과 팀워크를 진행해 보았던 경험과, 그 경험을 멋쟁이 사자처럼 + 대학에서 어떻게 적용시킬 수 있는지 알려주세요 + {" "} + + + {teamworkExperience.length} +
+
+ + 디자인 트랙을 통해 어떠한 성장을 희망하시는지 구체적으로 서술해주세요 + {" "} + + + {designGrowth.length} +
+
+ 포트폴리오 링크가 있다면 첨부해주세요 + +
+ + + + + +
+ ); } diff --git a/src/component/position/Frontend.tsx b/src/component/position/Frontend.tsx index b5eec79..094e3ca 100644 --- a/src/component/position/Frontend.tsx +++ b/src/component/position/Frontend.tsx @@ -1,332 +1,451 @@ -import React, { ChangeEvent } from 'react' -import { ButtonBox, Section, Button, Require, Article, InputTitle, TextAreaBox, InputBox, Banner, WordLength, Modal, Footer } from '../emotion/component' -import { useNavigate } from 'react-router-dom' -import { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { AppDispatch, TestState } from '../../app/store'; -import { saveCommon, saveIndex, view, saveFrontEnd } from '../../features/fetcherSlice'; -import { useEffect, useMemo } from 'react'; -import axios from 'axios'; -import tempImg from '../../images/temp.png'; -import completeImg from '../../images/complete.png'; -import Confetti from '../../hooks/Confetti'; -import { currentTime, endTime } from '../time/time'; +import React, { ChangeEvent } from "react"; +import { + ButtonBox, + Section, + Button, + Require, + Article, + InputTitle, + TextAreaBox, + InputBox, + Banner, + WordLength, + Modal, + Footer, +} from "../emotion/component"; +import { useNavigate } from "react-router-dom"; +import { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { AppDispatch, TestState } from "../../app/store"; +import { + saveCommon, + saveIndex, + view, + saveFrontEnd, +} from "../../features/fetcherSlice"; +import { useEffect, useMemo } from "react"; +import axios from "axios"; +import tempImg from "../../images/temp.png"; +import completeImg from "../../images/complete.png"; +import Confetti from "../../hooks/Confetti"; +import { currentTime, endTime } from "../time/time"; export default function Frontend() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + + const [buttonState, setButtonState] = useState(false); + const [submitCount, setSubmitCount] = useState(0); + const [tempState, setTempState] = useState(false); + const [temp, setTemp] = useState(false); + const [complete, setComplete] = useState(false); + + const [whyFrontend, setWhyFrontend] = useState(""); + const [usingStack, setUsingStack] = useState(""); + const [teamProject, setTeamProject] = useState(""); + const [achieve, setAchieve] = useState(""); + const [portfolioLink, setPortfolioLink] = useState(""); + + const [name, setName] = useState(""); + + const userName = useSelector((state: TestState) => state.fetcher.userName); + const userID = useSelector((state: TestState) => state.fetcher.userID); + const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); + const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); + const userPosition = useSelector( + (state: TestState) => state.fetcher.userPosition + ); + const userDepartment = useSelector( + (state: TestState) => state.fetcher.userDepartment + ); + + const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); + const userHardWork = useSelector( + (state: TestState) => state.fetcher.userHardWork + ); + const userKeyWord = useSelector( + (state: TestState) => state.fetcher.userKeyWord + ); + const userMostDeeplyWork = useSelector( + (state: TestState) => state.fetcher.userMostDeeplyWork + ); + + const userWhyFrontend = useSelector( + (state: TestState) => state.fetcher.userWhyFrontend + ); + const userUsingStack = useSelector( + (state: TestState) => state.fetcher.userUsingStack + ); + const userTeamProject = useSelector( + (state: TestState) => state.fetcher.userTeamProject + ); + const userAchieve = useSelector( + (state: TestState) => state.fetcher.userAchieve + ); + const userPortfolioLink = useSelector( + (state: TestState) => state.fetcher.userPortfolioLinkFront + ); + + useEffect(() => { + document.body.style.overflow = "unset"; + if (!userName && !userID && !userPhone && !userEmail && !userPosition) { + navigate("/404"); + } - const navigate = useNavigate(); - const dispatch = useDispatch(); - - const [buttonState, setButtonState] = useState(false); - const [submitCount, setSubmitCount] = useState(0); - const [tempState, setTempState] = useState(false); - const [temp, setTemp] = useState(false); - const [complete, setComplete] = useState(false); - - const [whyFrontend, setWhyFrontend] = useState(''); - const [usingStack, setUsingStack] = useState(''); - const [teamProject, setTeamProject] = useState(''); - const [achieve, setAchieve] = useState(''); - const [portfolioLink, setPortfolioLink] = useState(''); - - const [name, setName] = useState(''); - - - const userName = useSelector((state: TestState) => state.fetcher.userName); - const userID = useSelector((state: TestState) => state.fetcher.userID); - const userPhone = useSelector((state: TestState) => state.fetcher.userPhone); - const userEmail = useSelector((state: TestState) => state.fetcher.userEmail); - const userPosition = useSelector((state: TestState) => state.fetcher.userPosition); - const userDepartment = useSelector((state: TestState) => state.fetcher.userDepartment); - - const userMotiv = useSelector((state: TestState) => state.fetcher.userMotiv); - const userHardWork = useSelector((state: TestState) => state.fetcher.userHardWork); - const userKeyWord = useSelector((state: TestState) => state.fetcher.userKeyWord); - const userMostDeeplyWork = useSelector((state: TestState) => state.fetcher.userMostDeeplyWork); - - const userWhyFrontend = useSelector((state: TestState) => state.fetcher.userWhyFrontend); - const userUsingStack = useSelector((state: TestState) => state.fetcher.userUsingStack); - const userTeamProject = useSelector((state: TestState) => state.fetcher.userTeamProject); - const userAchieve = useSelector((state: TestState) => state.fetcher.userAchieve); - const userPortfolioLink = useSelector((state: TestState) => state.fetcher.userPortfolioLinkFront); - - useEffect(() => { - document.body.style.overflow = "unset"; - if (!userName && !userID && !userPhone && !userEmail && !userPosition) { - navigate('/404') - } - - if (currentTime > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } - - // 이전 값들을 저장하기 위해서 Redux 사용 - - if (userWhyFrontend) { - setWhyFrontend(userWhyFrontend) - } - if (userUsingStack) { - setUsingStack(userUsingStack) - } - if (userTeamProject) { - setTeamProject(userTeamProject) - } - if (userAchieve) { - setAchieve(userAchieve) - } - if (userPortfolioLink) { - setPortfolioLink(userPortfolioLink) - } - - if (userName) { - setName(userName) - } - }, []) - - useMemo(() => { - - // 프론트엔드 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 - if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { - setTempState(false); - } else { - setTempState(true); - } - - if (whyFrontend && usingStack && teamProject && achieve) { - setButtonState(false) - } else { - setButtonState(true) - } - if (submitCount >= 1) { - setButtonState(true); - } - }, [whyFrontend, usingStack, teamProject, achieve, submitCount]) - - - const Back = () => { - setSubmitCount((prev) => (prev + 1)) - dispatch(saveFrontEnd({ userWhyFrontend: whyFrontend, userUsingStack: usingStack, userTeamProject: teamProject, userAchieve: achieve, userPortfolioLinkFront: portfolioLink })); - navigate('/common'); + if (currentTime > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); } + // 이전 값들을 저장하기 위해서 Redux 사용 - const TempSave = () => { - setSubmitCount((prev) => (prev + 1)); - if (userPosition === "프론트엔드") { - axios.post('/frontendApplication', JSON.stringify({ - department: userDepartment, - whyFrontend: whyFrontend, - email: userEmail, - hardWork: userHardWork, - usingStack: usingStack, - keyWord: userKeyWord, - mostDeeplyWork: userMostDeeplyWork, - motive: userMotiv, - name: userName, - passOrNot: false, - sendMail: false, - phoneNumber: userPhone, - portfolioFile: "", - portfolioLink: portfolioLink, - sid: userID, - teamProject: teamProject, - achieve: achieve, - submissionStatus: false, - }), - { - headers: { - "Content-type": "application/json", - } - } - ) - .then((res) => { - setTemp(!temp); - document.body.style.overflow = "hidden"; - }) - } + if (userWhyFrontend) { + setWhyFrontend(userWhyFrontend); } - - const OpenSubmit = () => { - setComplete(!complete); + if (userUsingStack) { + setUsingStack(userUsingStack); } - - const Submit = () => { - - const time = new Date(); - - if (time > endTime) { - alert("제출 기간이 마감되었습니다!"); - navigate('/notTime'); - } - - else if (window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?")) { - setSubmitCount((prev) => (prev + 1)) - axios.post('/frontendApplication', JSON.stringify({ - department: userDepartment, - whyFrontend: whyFrontend, - email: userEmail, - hardWork: userHardWork, - usingStack: usingStack, - keyWord: userKeyWord, - mostDeeplyWork: userMostDeeplyWork, - motive: userMotiv, - name: userName, - passOrNot: false, - sendMail: false, - phoneNumber: userPhone, - portfolioFile: "", - portfolioLink: portfolioLink, - sid: userID, - teamProject: teamProject, - achieve: achieve, - submissionStatus: true, - }), - { - headers: { - "Content-type": "application/json", - } - } - ) - .then((res) => { - dispatch(saveFrontEnd({ - userWhyFrontend: '', - userUsingStack: '', - userAchieve: '', - userPortfolioLinkFront: '', - userTeamProject: '', - })); - dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - setComplete(!complete) - document.body.style.overflow = "hidden"; - }) - } + if (userTeamProject) { + setTeamProject(userTeamProject); + } + if (userAchieve) { + setAchieve(userAchieve); + } + if (userPortfolioLink) { + setPortfolioLink(userPortfolioLink); } - const handleChange = (event: ChangeEvent | ChangeEvent) => { - if (event.target.name === "동기") { - if (event.target.value.length <= 1000) { - setWhyFrontend(event.target.value); - } - } - - if (event.target.name === "프레임워크") { - if (event.target.value.length <= 1000) { - - setUsingStack(event.target.value); - } - } - - if (event.target.name === "경험") { - if (event.target.value.length <= 1000) { - setTeamProject(event.target.value); - } - } + if (userName) { + setName(userName); + } + }, []); + + useMemo(() => { + // 프론트엔드 파트로 들어왔을 때는 공통 질문이 하나라도 작성된 상태이기 때문에 바로 임시저장이 가능함 + if (userMotiv || userHardWork || userKeyWord || userMostDeeplyWork) { + setTempState(false); + } else { + setTempState(true); + } - if (event.target.name === "성장") { - if (event.target.value.length <= 1000) { - setAchieve(event.target.value); - } - } + if (whyFrontend && usingStack && teamProject && achieve) { + setButtonState(false); + } else { + setButtonState(true); + } + if (submitCount >= 1) { + setButtonState(true); + } + }, [whyFrontend, usingStack, teamProject, achieve, submitCount]); + + const Back = () => { + setSubmitCount((prev) => prev + 1); + dispatch( + saveFrontEnd({ + userWhyFrontend: whyFrontend, + userUsingStack: usingStack, + userTeamProject: teamProject, + userAchieve: achieve, + userPortfolioLinkFront: portfolioLink, + }) + ); + navigate("/common"); + }; + + const TempSave = () => { + setSubmitCount((prev) => prev + 1); + if (userPosition === "프론트엔드") { + axios + .post( + "/frontendApplication", + JSON.stringify({ + department: userDepartment, + whyFrontend: whyFrontend, + email: userEmail, + hardWork: userHardWork, + usingStack: usingStack, + keyWord: userKeyWord, + mostDeeplyWork: userMostDeeplyWork, + motive: userMotiv, + name: userName, + passOrNot: false, + sendMail: false, + phoneNumber: userPhone, + portfolioFile: "", + portfolioLink: portfolioLink, + sid: userID, + teamProject: teamProject, + achieve: achieve, + submissionStatus: false, + }), + { + headers: { + "Content-type": "application/json", + }, + } + ) + .then((res) => { + setTemp(!temp); + document.body.style.overflow = "hidden"; + }); + } + }; + + const OpenSubmit = () => { + setComplete(!complete); + }; + + const Submit = () => { + const time = new Date(); + + if (time > endTime) { + alert("제출 기간이 마감되었습니다!"); + navigate("/notTime"); + } else if ( + window.confirm("최중 제출을 하면 수정이 불가해요, 제출하시겠어요?") + ) { + setSubmitCount((prev) => prev + 1); + axios + .post( + "/frontendApplication", + JSON.stringify({ + department: userDepartment, + whyFrontend: whyFrontend, + email: userEmail, + hardWork: userHardWork, + usingStack: usingStack, + keyWord: userKeyWord, + mostDeeplyWork: userMostDeeplyWork, + motive: userMotiv, + name: userName, + passOrNot: false, + sendMail: false, + phoneNumber: userPhone, + portfolioFile: "", + portfolioLink: portfolioLink, + sid: userID, + teamProject: teamProject, + achieve: achieve, + submissionStatus: true, + }), + { + headers: { + "Content-type": "application/json", + }, + } + ) + .then((res) => { + dispatch( + saveFrontEnd({ + userWhyFrontend: "", + userUsingStack: "", + userAchieve: "", + userPortfolioLinkFront: "", + userTeamProject: "", + }) + ); + dispatch( + saveCommon({ + userMotiv: "", + userHardWork: "", + userKeyWord: "", + userMostDeeplyWork: "", + }) + ); + dispatch( + saveIndex({ + userName: "", + userID: "", + userDepartment: "", + userEmail: "", + userPhone: "", + userPosition: "", + }) + ); + setComplete(!complete); + document.body.style.overflow = "hidden"; + }); + } + }; + + const handleChange = ( + event: ChangeEvent | ChangeEvent + ) => { + if (event.target.name === "동기") { + if (event.target.value.length <= 1000) { + setWhyFrontend(event.target.value); + } + } - if (event.target.name === "포트폴리오") { - setPortfolioLink(event.target.value); - } + if (event.target.name === "프레임워크") { + if (event.target.value.length <= 1000) { + setUsingStack(event.target.value); + } } - const TempBack = async () => { - setTemp(false); - setSubmitCount(0); - setTempState(false); - setButtonState(false); - document.body.style.overflow = "unset"; + if (event.target.name === "경험") { + if (event.target.value.length <= 1000) { + setTeamProject(event.target.value); + } } - /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ - const TempHome = async () => { - await dispatch(saveFrontEnd({ - userWhyFrontend: '', - userUsingStack: '', - userAchieve: '', - userPortfolioLinkFront: '', - userTeamProject: '', - })); - await dispatch(saveCommon({ - userMotiv: '', - userHardWork: '', - userKeyWord: '', - userMostDeeplyWork: '', - })) - await dispatch(saveIndex({ - userName: '', - userID: '', - userDepartment: '', - userEmail: '', - userPhone: '', - userPosition: '', - })) - await navigate('/'); + if (event.target.name === "성장") { + if (event.target.value.length <= 1000) { + setAchieve(event.target.value); + } } - return ( -
- {complete && } - {complete ? - - - - : null - } - {temp ? - - - - - : null - } - -
- 프론트엔드 트랙을 선택하게 된 이유를 구체적으로 서술해주세요 - - {whyFrontend.length} -
-
- 프론트엔드 개발과 관련된 프레임워크나 HTML, CSS, JavaScript 등의 언어를 사용해보신 경험에 대해 구체적으로 적어주세요 - - {usingStack.length} -
-
- 팀 활동이나 프로젝트를 경험해본 내용과 이를 통해 자신의 성장 경험에 대해서 서술해주세요 - - {teamProject.length} -
-
- 멋사 프론트엔드 아기사자로 활동하면서 얻어 가고 싶은 것은 무엇인가요? - - {achieve.length} -
-
- 깃허브 또는 포트폴리오 링크가 있다면 첨부해주세요 - -
- - - - - -
- ) -} \ No newline at end of file + if (event.target.name === "포트폴리오") { + setPortfolioLink(event.target.value); + } + }; + + const TempBack = async () => { + setTemp(false); + setSubmitCount(0); + setTempState(false); + setButtonState(false); + document.body.style.overflow = "unset"; + }; + + /* 처음에는 임시 저장에서 메인화면으로 가는 용도로 만들었지만, 최종 제출 후 redux를 초기화하는 로직이 동일해 최종 제출 후 홈으로 갈 때도 같이 사용*/ + const TempHome = async () => { + await dispatch( + saveFrontEnd({ + userWhyFrontend: "", + userUsingStack: "", + userAchieve: "", + userPortfolioLinkFront: "", + userTeamProject: "", + }) + ); + await dispatch( + saveCommon({ + userMotiv: "", + userHardWork: "", + userKeyWord: "", + userMostDeeplyWork: "", + }) + ); + await dispatch( + saveIndex({ + userName: "", + userID: "", + userDepartment: "", + userEmail: "", + userPhone: "", + userPosition: "", + }) + ); + await navigate("/"); + }; + + return ( +
+ {complete && } + {complete ? ( + + + + ) : null} + {temp ? ( + + + + + ) : null} + +
+ + 프론트엔드 트랙을 선택하게 된 이유를 구체적으로 서술해주세요 + {" "} + + + {whyFrontend.length} +
+
+ + 프론트엔드 개발과 관련된 프레임워크나 HTML, CSS, JavaScript 등의 + 언어를 사용해보신 경험에 대해 구체적으로 적어주세요 + {" "} + + + {usingStack.length} +
+
+ + 팀 활동이나 프로젝트를 경험해본 내용과 이를 통해 자신의 성장 경험에 + 대해서 서술해주세요 + {" "} + + + {teamProject.length} +
+
+ + 멋사 프론트엔드 아기사자로 활동하면서 얻어 가고 싶은 것은 무엇인가요? + {" "} + + + {achieve.length} +
+
+ + 깃허브 또는 포트폴리오 링크가 있다면 첨부해주세요{" "} + + +
+ + + + + +
+ ); +} diff --git a/src/hooks/KeyboardIOS.ts b/src/hooks/KeyboardIOS.ts index e3f9262..7af9178 100644 --- a/src/hooks/KeyboardIOS.ts +++ b/src/hooks/KeyboardIOS.ts @@ -1,16 +1,12 @@ -import { useEffect } from "react"; - export const KeyboardIOS = () => { - useEffect(() => { - const scrollToTopFn = () => { - if (window.Keyboard && !window.Keyboard.isVisible) { - window.scrollTo(0, 0); - window.document.body.scrollTop = 0; - } - }; - - window.addEventListener('keyboardDidHide', () => { - window.setTimeout(scrollToTopFn, 100); - }); - }, []) + const scrollToTopFn = () => { + if (window.Keyboard && !window.Keyboard.isVisible) { + window.scrollTo(0, 0); + window.document.body.scrollTop = 0; + } + }; + + window.addEventListener('keyboardDidHide', () => { + window.setTimeout(scrollToTopFn, 100); + }); } \ No newline at end of file diff --git a/src/images/notTime.png b/src/images/notTime.png new file mode 100644 index 0000000..9fc6969 Binary files /dev/null and b/src/images/notTime.png differ diff --git a/tsconfig.json b/tsconfig.json index 2677c30..d133799 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,7 @@ }, "include": [ "src", - "src/custom.d.ts", + "src/hooks/@types/custom.d.ts", "src/index.d.ts", ] } \ No newline at end of file