Skip to content

Repository files navigation

BGS Frontend

사용자의 위치와 취향에 맞는 식당을 탐색하고, 리뷰와 찜을 통해 경험을 공유하는 BGS(배고파) 서비스의 웹 클라이언트입니다.

HTML, CSS, Vanilla JavaScript로 화면과 상태 흐름을 직접 구성했으며, Naver Maps JavaScript API와 브라우저 Geolocation을 활용해 목록·지도·상세·마이페이지·관리자 기능을 하나의 서비스 흐름으로 연결했습니다.

Links

Demo account

  • ID: demouser
  • Password: a1234567!

관리자 계정 정보는 README에 공개하지 않습니다.

Preview

BGS main page

Table of Contents

Project Overview

Item Description
Development Period 2025.07 ~ 2026.06
Release 2026.07.02
Team 개인 프로젝트 (1명)
Role UI 설계, 프론트엔드 구현, API 연동, Naver Maps 연동, Netlify 배포

BGS 프론트엔드는 서버의 추천·검색·리뷰 API를 사용자가 자연스럽게 탐색할 수 있는 화면으로 제공하는 데 집중했습니다.

  • 위치·지역·검색어·정렬 조건을 조합한 식당 탐색
  • 지도 이동 영역과 현재 위치를 활용한 주변 식당 조회
  • 식당 상세 정보, 메뉴, 영업시간, 리뷰 확인
  • 회원가입·로그인·계정 찾기와 로그인 유지 선택
  • 리뷰 작성·수정·삭제, 이미지 관리, 반응 처리
  • 찜·방문 식당·차단 사용자·식당 요청을 모은 마이페이지
  • 점주의 식당 정보·메뉴·영업시간·이미지 수정
  • 관리자의 사용자·리뷰·식당·등록 요청 관리

추천 점수, 데이터 모델, 트랜잭션 및 API 성능 개선에 관한 내용은 백엔드 README에서 확인할 수 있습니다.

Frontend Highlights

1. Context-preserving Restaurant Discovery

  • 검색어, 지역, 정렬 방식을 URL query string에 반영해 목록과 상세 화면을 오가도 탐색 조건 유지
  • 추천순·평점순·조회순·찜순·리뷰순·거리순 UI 제공
  • 최근 검색어를 Local Storage에 저장하고 개별 삭제 지원
  • IntersectionObserver로 다음 cursor를 요청해 목록을 점진적으로 추가
  • 현재 위치 사용이 불가능한 경우 서비스 기본 위치를 기준으로 목록 제공

2. Naver Maps Integration

  • Naver Maps JavaScript API로 식당 및 사용자 위치 마커 표시
  • 브라우저 Geolocation으로 현재 위치 이동
  • 지도 drag·zoom 이후 현재 영역을 기준으로 식당 데이터 갱신
  • 식당 마커 선택 시 요약 정보와 상세 페이지 이동 제공
  • Geocoder를 활용한 주소 검색과 좌표 선택
  • 식당 등록·수정 화면에서도 지도 클릭으로 위치 지정

지도 렌더링과 사용자 상호작용은 프론트엔드에서 담당하고, 백엔드는 좌표·검색어·반경 조건에 맞는 식당 데이터를 제공합니다.

3. Authentication State

  • 공통 AppAuth 모듈에서 JWT 저장·조회·삭제 처리
  • 로그인 유지 선택 시 Local Storage, 미선택 시 Session Storage 사용
  • 인증이 필요한 페이지에서 로그인 화면으로 이동하고 next 경로로 원래 화면 복귀
  • 401 Unauthorized 응답 시 만료된 토큰 제거 및 재로그인 유도

4. Image and Error Handling

  • 서버의 상대 이미지 URL을 배포 API Origin과 결합해 일관된 경로 생성
  • 허용된 API Origin의 HTTP(S) 이미지만 표시해 임의 외부 URL 차단
  • 이미지가 없거나 로드에 실패하면 식당·프로필 기본 이미지로 대체
  • 리뷰 작성·수정 및 식당 수정 화면에서 기존 이미지와 새 이미지 상태를 분리 관리

5. Responsive Multi-role UI

  • 데스크톱과 모바일 화면을 위한 반응형 레이아웃
  • 사용자·점주·관리자 역할에 따라 필요한 화면과 작업 동선 제공
  • 마이페이지의 리뷰·방문·찜·차단 목록에 cursor 기반 추가 조회 적용
  • 식당 영업 상태와 등록 요청 승인·반려 상태를 화면에 반영

User Flow

flowchart LR
    Guest[Guest] --> Search[Search and Filters]
    Search --> Map[Naver Map Discovery]
    Search --> Detail[Restaurant Detail]
    Detail --> View[View Info and Reviews]
    Guest --> Login[Login]
    Login --> Member[Authenticated User]
    Member --> Review[Write Review]
    Member --> Like[Like Restaurant]
    Member --> MyPage[My Page]
    MyPage --> Request[Submit Restaurant Request]
    Request --> Approval[Admin Approval]
    Approval --> Owner[Restaurant Owner]
    Owner --> Edit[Restaurant Management]
Loading

Pages

Page File Description
Main index.html 식당 검색·필터·정렬 및 추천 목록
Map map.html 현재 위치와 지도 영역 기반 식당 탐색
Restaurant Detail restaurant.html 식당 정보·메뉴·영업시간·리뷰 조회
Review Editor review_write.html 리뷰 및 이미지 작성·수정
My Page mypage.html 프로필과 사용자 활동 내역 관리
Restaurant Request restaurant_request.html 지도·주소를 이용한 식당 등록 요청
Restaurant Editor restaurant_edit.html 점주의 식당 정보·메뉴·영업시간 관리
Admin admin.html 사용자·리뷰·식당·등록 요청 관리
Authentication login.html, sign-up.html 로그인·회원가입
Account Recovery findId.html, findPw.html 아이디·비밀번호 찾기

Tech Stack

Category Technology
Markup HTML5
Styling CSS3, Bootstrap 5, Bootstrap Icons
Language Vanilla JavaScript
Map Naver Maps JavaScript API, Geocoder
Browser API Geolocation, Local Storage, Session Storage, Intersection Observer
API Communication Fetch API 기반 REST API 연동
Deployment Netlify

Architecture

flowchart LR
    User[Browser] --> Netlify[Netlify Static Hosting]
    Netlify --> App[HTML, CSS and JavaScript]
    App --> State[Auth and Browser Storage]
    App --> API[BGS REST API]
    App --> Maps[Naver Maps API]
    API --> Images[Railway Image URLs]
Loading

프론트엔드는 화면 렌더링과 브라우저 상태를 담당하고, 인증 검증·권한·추천·데이터 일관성은 서버가 최종 책임을 갖도록 역할을 분리했습니다.

Directory Structure

client/
├── assets/                 # 아이콘과 Bootstrap 정적 파일
├── css/                    # 페이지별 스타일과 반응형 레이아웃
├── images/                 # 기본 식당·프로필 이미지
├── js/                     # 페이지 로직과 공통 인증·이미지·위치 모듈
├── scripts/
│   └── generate-config.js  # Netlify 환경변수 기반 API 설정 생성
├── *.html                  # 페이지별 진입 문서
├── netlify.toml            # Netlify 빌드·배포 설정
└── README.md

Local Setup

별도의 프론트엔드 프레임워크나 번들 설치 없이 정적 파일 서버로 실행할 수 있습니다.

git clone https://github.com/JJeSeok/BGS-client.git
cd BGS-client

로컬 API 기본 주소는 js/config.js에서 확인할 수 있습니다.

window.APP_CONFIG = {
  API_BASE: 'http://localhost:8080',
};

백엔드 서버를 http://localhost:8080에서 실행한 뒤 VS Code Live Server 등으로 index.html을 엽니다.

브라우저에서 http://127.0.0.1:5500으로 접속합니다.

백엔드의 CORS_ALLOW_ORIGIN에는 위 프론트엔드 Origin을 등록해야 합니다.

Deployment

Netlify는 저장소의 정적 파일을 배포하며, 빌드 과정에서 환경변수를 사용해 운영 API 주소를 생성합니다.

[build]
  publish = '.'
  command = 'node scripts/generate-config.js'

Netlify 환경변수:

API_BASE=https://bgs.up.railway.app

scripts/generate-config.js는 빌드 시 이 값을 js/config.js에 기록하며, 운영 환경에서 값이 없으면 빌드를 실패시켜 잘못된 API 주소로 배포되는 것을 방지합니다.

Naver Maps JavaScript API는 허용된 Web 서비스 URL에서만 호출되도록 설정했습니다.

  • Local: http://127.0.0.1:5500
  • Production: https://baegopa-eats.netlify.app

Screenshots

Restaurant Discovery

검색과 지역·정렬 조건을 바탕으로 식당을 탐색할 수 있습니다.

Restaurant discovery

Map Discovery

Naver Map에서 주변 식당의 위치와 요약 정보를 확인할 수 있습니다.

Map discovery

Restaurant Detail

식당 이미지, 평점, 위치, 영업시간과 메뉴를 한 화면에서 확인할 수 있습니다.

Restaurant detail

Review Creation

평가 유형과 별점, 리뷰 내용 및 이미지를 함께 등록할 수 있습니다.

Review creation

Admin Console

관리자는 식당 등록 요청을 조회하고 승인하거나 반려할 수 있습니다.

Admin console

Troubleshooting

Build-time API Configuration

  • 문제: 로컬 API 주소가 포함된 config.js를 그대로 배포하면 운영 프론트엔드가 localhost를 호출할 수 있었습니다.
  • 해결: Netlify 빌드에서 API_BASE 환경변수로 config.js를 생성하고, 운영 빌드에서 변수가 누락되면 실패하도록 구성했습니다.
  • 결과: 로컬·배포 환경의 API 주소를 코드 수정 없이 분리하고 잘못된 설정의 배포를 차단했습니다.

Cross-origin Image URLs

  • 문제: 프론트엔드와 서버의 Origin이 달라 상대 이미지 경로를 그대로 사용하면 프론트엔드 주소에서 파일을 찾았습니다.
  • 해결: /uploads/ 경로를 운영 API Origin과 결합하는 공통 이미지 모듈을 만들고, 로드 실패 시 기본 이미지로 대체했습니다.
  • 결과: 페이지마다 중복되던 이미지 URL 처리를 통일하고 배포 환경에서도 이미지를 안정적으로 표시했습니다.

Remember-me Token Storage

  • 문제: 로그인 유지 선택 여부와 관계없이 토큰을 하나의 저장소에 보관하면 브라우저 종료 후 세션 정책을 구분할 수 없었습니다.
  • 해결: 로그인 유지 시 Local Storage, 미선택 시 Session Storage를 사용하고 공통 AppAuth 모듈에서 우선순위와 삭제를 관리했습니다.
  • 결과: 사용자가 선택한 로그인 유지 정책을 화면 전반에서 일관되게 적용했습니다.

DOM-based XSS Prevention

  • 문제: 식당·리뷰 등 사용자 입력값을 innerHTML로 렌더링하면 악의적인 HTML이나 스크립트가 DOM에 삽입될 수 있었습니다.
  • 해결: 동적 화면 생성에서 innerHTML 사용을 줄이고, DOM API의 createElementtextContent를 사용해 입력값을 텍스트로 렌더링했습니다.
  • 결과: 신뢰할 수 없는 입력이 HTML로 해석되는 경로를 줄여 DOM 기반 XSS 공격 위험을 완화했습니다.

Security Notes

  • 사용자 입력은 화면에서 검증하되 서버 검증을 최종 기준으로 사용합니다.
  • 인증 토큰은 로그인 유지 선택에 따라 Local Storage 또는 Session Storage에 저장됩니다.
  • 이미지 URL은 배포 API와 동일한 Origin만 허용하고 잘못된 URL은 기본 이미지로 대체합니다.
  • Netlify 환경변수에는 공개 가능한 API Base URL만 저장하며 서버 비밀값은 포함하지 않습니다.
  • Naver Maps Client ID에는 허용 Web 서비스 URL을 제한합니다.

Remaining Work

  • 접근성 검사와 키보드 탐색 개선
  • 초기 마이페이지 요청 병렬화 및 화면별 지연 로딩
  • 사용자 업로드 이미지의 목록용 썸네일 적용
  • 반복되는 DOM 생성 로직과 API 요청·오류 처리의 공통 모듈화

About

위치와 사용자 취향을 기반으로 한 식당 추천 서비스 BGS의 웹 클라이언트

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages