프로젝트 기간: 2024.01 - 2024.02
역할: 프론트엔드
언어: Javascript
빌드도구, 프레임워크: React, Vite
상태관리 라이브러리: Recoil
담당 기능:
- 약관동의 페이지
- 게시글 작성, 수정, 삭제기능
- 세부 게시글 조회 기능
- 백엔드 - 프론트엔드 API 연결
화면 구성
1. HOME
- 초기 화면: 회원가입, 로그인, 약관동의
- 메인 화면: 전체 게시글을 한 눈에 볼 수 있는 페이지
2. Survey
- 설문조사 게시글 등록 및 삭제, 수정
3. Market
- 설문조사 데이터 판매
4. My
- 포인트 내역 확인
- 작성한 게시글 히스토리 확인
구현 결과
1. 약관동의 페이지 UI
- onButtonClick: 모두 동의 버튼(onAllBoxChange), 서비스이용약관/개인정보 수집 동의 버튼(onSingleBoxChange) 제어
const onButtonClick = (key) => {
if (key === "all") {
onAllBoxChange();
} else {
onSingleBoxChange(key);
}
};
const onAllBoxChange = () => {
const newAllValue = check.all === originalBt ? checkBt : originalBt;
setCheck({
all: newAllValue,
first: newAllValue,
second: newAllValue,
});
};
const onSingleBoxChange = (key) => {
const newSingleValue = check[key] === originalBt ? checkBt : originalBt;
setCheck((prevCheck) => ({
...prevCheck,
[key]: newSingleValue,
all:
(check[key] === originalBt && prevCheck.second === checkBt) ||
(check[key] === originalBt && prevCheck.first === checkBt)
? checkBt
: originalBt,
}));
};
const [notAllow, setNotAllow] = useState(true);
const checkNotAllow = useEffect(()=>{
if(check.all===checkBt){
setNotAllow(false);
return;
}
setNotAllow(true);
},[check.all])
2. 게시글 작성, 열람 UI
- survey와 market 페이지의 구조가 동일하여 Survey.jsx 페이지에서 survey, market 열람 페이지 구성
- surveyViewClick
- useNavigate를 이용해 현재 navigate된 위치가 surveyview인지, marketview인지에 따라 화면 다른 api 불러오기
- plusClick
- 현재 접속이 student 계정이 아니라면 글쓰기(plus) 버튼 비활성화
const surveyViewClick = (e, isFinished) => {
setShowAlert(false);
navigate(survey ? "/surveyview1" : "/marketview1");
setCurrentId(e.surveyId ? e.surveyId : e.dataId);
setFinished(isFinished);
};
const plusClick=()=>{
if (survey){
{isStudent&&navigate("/surveycontent")}
}
else{
navigate("/marketcontent")
}
}
3. 로그인 API 연결
- 학생 인증을 위해 대학교 이메일 입력
- 대학교 이메일로 백엔드 측에서 인증번호 포함된 메일 발송
- 학생이 인증번호를 입력하면 response값으로 토큰 발급
- 로그인 완료하면 jwt를 localstorage에 저장하고 추후 로그인 여부 확인할 때 localstorage 확인하기
※ 비밀번호 변경 시에도 동일한 방식으로 인증코드 받아 토큰 발급
//로그인 시 localStorage에 토큰 저장
const handleSubmit = async () => {
try {
const response = await axios.post(
"https://sleigh.college/api/auth/login",
{
id: inputId,
password: inputPw,
}
);
if (response.data.success) {
navigate("/main");
console.log("서버 응답:", response);
console.log(response.data.data.jwt);
localStorage.setItem("token", response.data.data.jwt);
}
} catch (error) {
setIsLogin(false);
//로그인 권한 부여되어야 하는 경우 token 존재 확인
const token = localStorage.getItem("token");
if (token) {
axios
.get(`api/auth/profile`, {
headers: {
Authorization: token,
},
4. 상태관리(Recoil)
- 닉네임, 토스트팝업 여부, 팝업페이지 여부, 접속자 아이디 등 다른 페이지에서도 써야 하는 state를 관리하기 위한 목적
- RecoilDummys.js에 상태 저장 후 useState처럼 사용하고자 하는 페이지에서 변경하는 방식
//RecoilDummys에 초기 상태 저장
export const idState=atom({
key:"idState",
default:0,
})
//RecoilDummys의 정보를 가져와서
import { idState } from "../../components/RecoilDummys";
//변수명 설정
const [currentId, setCurrentId] = useRecoilState(idState);
//변경 가능
setCurrentId(e.surveyId ? e.surveyId : e.dataId);
5. google form 페이지 이동 로직
- 설문조사자 입장
- 설문 게시글 작성 시 google form 링크를 함께 게시한다.
- google form 마지막 페이지에 다시 썰매로 돌아올 수 있는 링크를 게시한다.
- 설문응답자 입장
- 설문조사자가 작성해놓은 게시글의 google form 링크를 클릭해 설문조사한다.
- 설문조사가 완료되면 마지막 페이지의 링크를 타고 다시 썰매로 돌아온다.
- 다시 돌아온 페이지에서 포인트를 수령할 수 있다.
const getData = async () => {
const token = localStorage.getItem("token");
if (token) {
try {
//const response = await axios.get(`/api/survey/${surveyId}`);
const response = await axios.get(`/api/survey/${surveyId}`, {
headers: {
Authorization: token,
},
});
console.log(response);
setSurveyContent(response.data.data);
setPointLink(`https://sleigh.college/surveyresult/${response.data.data.rewardUrl}`);
} catch (res) {
console.log(res);
}
}
};
useEffect(() => {
getData();
}, []);
트러블슈팅
netlify를 이용해서 배포한 후 url을 통한 페이지 이동이 불가능한 상황
[문제 상황] 사용자가 직접 url을 입력 시 404 not found가 뜸 (ex. /dashboard, /survey 등 입력 시)
[문제 원인] SPA 프레임워크(React)에서는 클라이언트 측 라우팅(CSR)을 이용해 페이지 이동을 처리하므로 url이 바뀌어도 서버에 바뀐 것을 알리지 않음. 그러나 사용자가 임의로 url을 변경하면 서버에서는 바뀐 url에서의 html이 존재하지 않아 404 not found 발생
[해결방법]
1. netlify.toml을 통한 redirect
- 프로젝트 최상단에 netlify.toml 작성
- 어떤 url을 제공하든 index.html로 리다이렉트
- 즉 서버는 어떤 url을 입력하든 index.html을 반환하고, 나머지 url 처리는 javascript에서 담당하는 구조
//netlify.toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
2. vite.config.js 파일 추가
1번 방법으로 해결되었기 때문에 실질적으로 필요한 파일은 아니었으나 historyApiFallback:true 설정을 통해서도 해결할 수 있다.
export default defineConfig({
plugins: [react()],
server: {
historyApiFallback:true,
proxy: {
'/api': {
target: 'https://sleigh.college/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
secure: false,
ws: true
}
}
}
})
깃허브 페이지
'Project' 카테고리의 다른 글
[SpringBoot]CRUD 게시판 구현 및 디벨롭 (1) | 2025.01.30 |
---|---|
[AWS, Angular]두부 생산 불량품 검출 시스템 (0) | 2025.01.28 |
[AWS]AWS 이용해 AI 챗봇 만들기: 텔레그램에서 chat-GPT와 대화하는 법 (0) | 2023.09.16 |