React/Next.js 환경을 선택했고, 폴더구조는 다음처럼 잡았다(frontend-service부분 주목)
(coin) sevity@raspberrypi:~/workspace/online_judge $ tree -L 2
.
├── auth-service
│ ├── application.log
│ ├── cookies.txt
│ ├── HELP.md
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ ├── src
│ └── target
├── frontend-service
│ ├── jsconfig.json
│ ├── next.config.js
│ ├── node_modules
│ ├── package.json
│ ├── package-lock.json
│ ├── public
│ ├── README.md
│ └── src
├── install
│ └── auth-service.zip
└── README.md
8 directories, 13 files
한가지 주목할만한 점은 프론트엔드의 경우 스프링부트 서비스로 만들 필요가 없다는 점이었다.
다음 명령어를 통해 node관련 설치(apt-get으로 시스템전역에 node를 설치하지 않고 nvm을 사용하기로 함)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
. ~/.bashrc
nvm install node
nvm install 16.8.0
다음명령을 통해 next.js react 설치
npm install --save next react react-dom
다음 명령어를 통해 Next.js 앱을 생성
(coin) sevity@raspberrypi:~/workspace/online_judge/frontend-service $ npx create-next-app@latest .
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias? … No / Yes
Creating a new Next.js app in /home/sevity/workspace/online_judge/frontend-service.
Using npm.
Initializing project with template: app
Installing dependencies:
- react
- react-dom
- next
added 22 packages, and audited 23 packages in 41s
4 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Success! Created frontend-service at /home/sevity/workspace/online_judge/frontend-service
bootstrap을 통한 디자인 적용
먼저 아래 명령을 통해 프로젝트에 bootstrap을 설치
npm install bootstrap
Next.js 프로젝트에서 Bootstrap을 사용하려면, _app.js 파일에 Bootstrap CSS를 import해야함.
_app.js 파일을 만들고, 다음 코드를 추가(맨위가 디자인 커스텀이며 나머지 내용은 _app.js를 만든이상 필수로 넣어야함)
_app.js는 모든 페이지에 공통으로 적용되는 컴포넌트를 정의하는 곳으로 전역 상태 관리, 레이아웃, 스타일링, 인증 등과 같이 여러 페이지에서 공유되는 로직을 처리하는 데 사용됨.
import 'bootstrap/dist/css/bootstrap.css'
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
login.js를 만들고 로그인 정보는 브라우저의 local storage를 활용해서 다음과 같이 저장했다.
import { useState, useEffect } from 'react';
import axios from 'axios';
export default function Login() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [userInfo, setUserInfo] = useState(null);
// 페이지 로드 시 Local Storage에서 로그인 정보 불러오기
useEffect(() => {
const storedUserInfo = localStorage.getItem('userInfo');
const storedIsLoggedIn = localStorage.getItem('isLoggedIn');
if (storedUserInfo && storedIsLoggedIn === 'true') {
setIsLoggedIn(true);
setUserInfo(JSON.parse(storedUserInfo));
}
}, []);
const handleSubmit = async (event) => {
event.preventDefault();
try {
const response = await axios.post('http://sevity.com:9991/login', `username=${username}&password=${password}`, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
// 서버에서 받은 세션정보를 local storage에 저장
console.log('Login successful:', response.data);
setIsLoggedIn(true);
setUserInfo(response.data);
// Local Storage에 사용자 정보 저장
localStorage.setItem('userInfo', JSON.stringify(response.data));
localStorage.setItem('isLoggedIn', 'true');
} catch (error) {
console.error('Login error:', error);
}
};
...
if (isLoggedIn) {
return (
<div>
Welcome, {userInfo}!
<button onClick={handleLogout}>Logout</button>
</div>
);
}
...
}
반응형
'Programming > JAVA' 카테고리의 다른 글
IntelliJ 팁 (0) | 2023.11.03 |
---|---|
java공부 (0) | 2023.08.12 |
react/next.js로 만드는 online-judge 사이트 #4 문제관리 프론트엔드 (0) | 2023.08.05 |
Kotlin/Spring으로 만드는 online-judge 사이트 #3 문제관리 백엔드 서비스 (0) | 2023.08.05 |
Java/Spring으로 만들어 보는 online-judge 사이트 #1 인증서비스 (1) | 2023.07.14 |