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>
    );
  }
...
}
반응형

+ Recent posts