한신대학교 재학생 누구나 본인의 졸업요건을 조회할 수 있는 웹사이트v2
기존 프로젝트를 v2로 타입스크립트로 마이그레이션 및 기능 개선
졸업가능 서비스 바로가기 |
---|
- 기존 한신대학교 졸업사정 셀프 테스트는 졸업 예정자인 학우들만 결과를 확인할 수 있음
- 학과 사무실에 셀프 테스트 양식을 작성하여 직접 제출해야함
- 학과/학번별로 졸업요건이 상이하기 때문에 졸업요건을 정확하게 파악하기 어려움
- 졸업사정 셀프 테스트 결과를 조교가 직접 체크해야 하기 때문에 결과지를 받는 데 많은 시간이 소요됨
- 학우들이 웹 사이트에서 학업성적확인서 PDF만 올려서 빠르고 간편하게 본인의 졸업요건을 파악하고 부족한 부분을 알 수 있게 도와줌
- 조교들은 졸업 요건을 확인하는 업무를 하지 않아도 되기 때문에 업무 부담이 줄어서 다른 업무에 보다 더 집중할 수 있음
- 타 대학도 기존 우리 학교와 졸업 요건 확인을 수기로 하기 때문에 이 프로젝트를 통해 정확한 결과 도출 및 시간 절약을 할 수 있는 기대효과
프론트엔드 |
메인 페이지 |
공지사항 페이지 |
로그인 페이지 |
졸업 요건 조회페이지 |
인기교양 페이지 |
리뷰 등록 |
JavaScript
→TypeScript
로 마이그레이션- 자바스크립트 사용 중 느슨한 타입에 의해 예상하지 못한 버그들이 자주 발생
- 타입스크립트를 도입하여 컴파일 단계에서 오류를 방지할 수 있게 됨으로 타입 안정성 및 가독성을 개선
tanstack/react-query
도입- API를 불러오는 데 있어 불필요한 보일러 플레이트를 제거하고 캐싱과 오류 처리의 일관된 방법을 원했음
tanstack/react-query
를 도입하여 효율성 높은 코드 작성과 디버깅의 편의성이 증가
CSS
→Styled-components
로 변경- 새롭게 CSS-IN-JS를 적용하면서 디자이너와 협업하여 UI 개편
- 프로젝트가 커질수록 CSS파일 모듈화 및 유지 보수 측면에서 어려움을 느낌
Styled-components
를 도입하여 동적 스타일링을 사용할 수 있게 되고 재사용 및 모듈화 편의성이 향상됨
Google Analytics
도입- 버전 1에서는 유저 피드백으로 개선 작업하여 사용자 행동 파악에 어려움을 느낌
- 접속 기기 환경을 확인하여 UI를 개선하고 트래픽 분석으로 프로젝트 개선 방향성을 잡을 수 있게 됨
검색 시 디바운싱 적용
검색 기능 사용 시, input으로 값이 들어올 때마다 API를 호출하는 문제가 발생했습니다.
이를 해결하기 위해 따로 버튼을 누르지 않아도 검색이 되도록 구현 방향을 잡았습니다.
Debounce
를 적용하여 입력을 측정하여 일정 시간이 넘기전에 입력을 받으면 API호출을 하지 않도록 작성했습니다.
const useDebounce = (value: string, delay: number) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
};
반응형 웹
다양한 기기에서 동일한 사용자 경험을 제공하고자 미디어 쿼리와 윈도우 크기를 받아와 반응형 디자인을 적용했습니다.
import { useState, useEffect } from "react";
const useCheckMobile = () => {
const [checkMobile, setCheckMobile] = useState(window.innerWidth);
useEffect(() => {
window.addEventListener("resize", handleResize);
});
const handleResize = () => {
setCheckMobile(window.innerWidth);
};
return checkMobile;
};
export default useCheckMobile;
const deviceSizes = {
mobile: 375,
tablet: 768,
laptop: 1024,
largeLaptop: 1440,
};
const device = {
mobile: `screen and (min-width : ${deviceSizes.mobile}px)`,
tablet: `screen and (min-width : ${deviceSizes.tablet}px)`,
laptop: `screen and (min-width : ${deviceSizes.laptop}px)`,
largeLaptop: `screen and (min-width : ${deviceSizes.largeLaptop}px)`,
};
const theme = {
device,
deviceSizes,
colors,
fonts,
};
드래그 앤 드랍
클릭으로 파일을 핸들링하는 것 외에도 드래그 앤 드랍 기능으로 유저가 쉽게 파일을 핸들링할 수 있도록 만들었습니다.
const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
uploadFile(file);
}
};
const uploadFile = (file: File) => {
setActive(true);
const fd = new FormData();
fd.append("file", file);
axios
.post(`${api.graduate}`, fd, {
headers: {
"Content-Type": `multipart/form-data`,
Authorization: `Bearer ${cookies.accessToken}`,
},
})
.then((response) => {
setGraduateData(response.data.data);
})
.catch((error) => {
setMessage(error.response.data.message);
setIsOpen(true);
setActive(false);
});
};
return (
<Label
onDragEnter={handleDragStart}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
<Image backgroundImage={GraduateImage}>
<Input
type="file"
accept=".pdf"
id="file"
name="file"
onChange={handleFileInputChange}
/>
<FileButton>
<File width={30} height={30} fill="white" />
<p>학업성적확인서 PDF 업로드</p>
</FileButton>
</Image>
</Label>
)
git clone https://github.com/Graduate-Okay/Graduate-Okay-FE.git
yarn install
yarn start