🍱 프로젝트 개요
이번 프로젝트는 “뭐먹지?”라는 주제로 구내식당 메뉴 조회 / 룰렛 추천 / 사다리 타기 기능을 제공하는 웹 애플리케이션을 React로 구현한 것이다.
백엔드는 Spring Boot 기반 API 서버이며, 프론트엔드는 React + React Router + MUI(Material UI)를 활용하여 반응형 UI와 직관적인 사용자 경험을 제공하도록 설계하였다.
📁 전체 구조
프로젝트는 다음과 같은 컴포넌트 구조를 갖는다:
- Navigation.js – 헤더 및 페이지 이동 메뉴 (반응형 Drawer 포함)
- MainLayout.js – 전체 앱의 진입점 (라우팅 + 네비게이션 통합)
- Routing.js – 페이지별 라우팅 정의
- CafeteriaList.js – 구내식당 메뉴 조회 페이지
- Roulette.js – 랜덤 추천 룰렛 기능
- Ladder.js – 사다리 타기 기능
- MainPage.js – 메인 배너 및 소개 페이지
🔗 라우팅 구조 – Routing.js
React Router를 사용해 페이지를 분리하고 URL 경로에 따라 각 컴포넌트를 렌더링한다. `` 컴포넌트는 URL과 렌더링할 컴포넌트를 매핑한다.
import React from "react"; import { Route, Routes } from "react-router-dom"; import ProjectMain from "./views/MainPage"; import CafeteriaList from "./views/CafeteriaList"; import Roulette from "./views/Roulette"; import Ladder from "./views/Ladder"; export default function Routing() { return ( <div style={{ marginTop: "85px" }}> <Routes> <Route path="/" element={<ProjectMain />} /> <Route path="/cafeteria" element={<CafeteriaList />} /> <Route path="/roulette" element={<Roulette />} /> <Route path="/ladder" element={<Ladder />} /> </Routes> </div> ); }
📐 전체 앱 진입점 – MainLayout.js
앱 실행 시 가장 먼저 로드되는 컴포넌트다.
라우터(`BrowserRouter`)를 감싸고, 네비게이션과 실제 라우팅 컴포넌트를 포함한다.
import React from "react"; import { BrowserRouter } from "react-router-dom"; import Navigation from "../Navigation"; import Routing from "../../Routing"; export default function MainLayout() { return ( <BrowserRouter> <Navigation /> <Routing /> </BrowserRouter> ); }
📌 네비게이션 바 – Navigation.js
MUI를 활용해 반응형 네비게이션을 구현했다. 데스크탑에서는 버튼, 모바일에서는 햄버거 아이콘 + Drawer를 제공한다.
import React, { useState } from "react"; import { AppBar, Toolbar, Button, Drawer, List, ListItem, IconButton } from "@mui/material"; import MenuIcon from "@mui/icons-material/Menu"; import { useNavigate } from "react-router-dom"; export default function Navigation() { const navigate = useNavigate(); const [openDrawer, setOpenDrawer] = useState(false); const menuItems = [ { label: "구내식당 메뉴", path: "/cafeteria" }, { label: "룰렛 돌리기", path: "/roulette" }, { label: "사다리 타기", path: "/ladder" }, ]; return ( <AppBar position="fixed" sx={{ backgroundColor: "white", color: "black" }}> <Toolbar sx={{ justifyContent: "space-between" }}> <img src="/navigation_logo.png" style={{ width: 130 }} onClick={() => navigate("/")} /> {/* 📱 모바일: 햄버거 메뉴 */} <IconButton onClick={() => setOpenDrawer(true)}> <MenuIcon /> </IconButton> <Drawer anchor="right" open={openDrawer} onClose={() => setOpenDrawer(false)}> <List> {menuItems.map((item) => ( <ListItem button key={item.path} onClick={() => navigate(item.path)}> {item.label} </ListItem> ))} </List> </Drawer> </Toolbar> </AppBar> ); }
🍱 구내식당 메뉴 조회 – CafeteriaList.js
Spring Boot 백엔드에서 `/api/cafeterias` API를 호출하여 오늘의 식당 정보를 가져오고 캐러셀 형태로 보여준다. 또한 오전 11시 전에는 “데이터 준비중” 메시지를 표시한다.
// ✅ API 호출 useEffect(() => { fetch("http://localhost:8080/api/cafeterias") .then((r) => r.json()) .then((data) => setItems(data)) .catch(console.error); }, []);
🎯 랜덤 추천 – Roulette.js
사용자가 입력한 여러 옵션을 기반으로 룰렛을 돌려 무작위 결과를 추천한다. CSS 회전 애니메이션과 conic-gradient를 활용하여 다이나믹한 UI를 구현하였다.
// ✅ 룰렛 회전 const spinRoulette = () => { const randomIndex = Math.floor(Math.random() * optionCount); const anglePerSlice = 360 / optionCount; const targetAngle = 360 - randomIndex * anglePerSlice - anglePerSlice / 2; totalRotationRef.current += 360 * 5 + targetAngle; wheelRef.current.style.transform = `rotate(${totalRotationRef.current}deg)`; };
🪜 사다리 타기 – Ladder.js
랜덤으로 사다리 구조를 생성하고 참가자와 결과를 매핑하는 게임 기능이다. 캔버스 대신 div를 조합하여 사다리 선을 직접 렌더링하였다.
// ✅ 사다리 생성 로직 const generateLadder = () => { let newLadder = Array(rows).fill(null).map(() => Array(playerCount - 1).fill(false)); for (let c = 0; c < playerCount - 1; c++) { for (let r = 0; r < rows; r++) { if (Math.random() < 0.5) newLadder[r][c] = true; } } setLadder(newLadder); };
✅ 정리
이번 프로젝트는 React를 활용해 하나의 웹앱 안에서 3개의 독립적인 기능을 가진 페이지를 구성했다. 각 기능은 다음과 같은 포인트를 가진다:
- 구내식당 메뉴: API 연동, 데이터 캐싱, 반응형 UI
- 룰렛 추천: CSS 애니메이션 + 수학적 계산 기반 랜덤 추천
- 사다리 타기: DOM 기반 그래픽 렌더링 및 경로 탐색 알고리즘
또한 Navigation – Routing – Page 단위 컴포넌트 구조를 통해 확장성 있는 프론트엔드 아키텍처를 설계했으며, 추후 로그인, 사용자 저장 기능 등을 손쉽게 추가할 수 있도록 구조를 분리했다.
'2025 현대오토에버 모빌리티 SW 스쿨(클라우드 2기) > 미니프로젝트' 카테고리의 다른 글
| [클라우드] GitOps + ArgoCD를 이용한 EC2 배포 과정 (+HA) (0) | 2025.09.30 |
|---|---|
| [클라우드] CI/CD 자동화 과정 (0) | 2025.09.30 |
| [Spring Boot] 백엔드 설계 (0) | 2025.09.27 |
| [프로젝트 설계] 주제 선정 및 프로젝트 설계 (0) | 2025.09.27 |