Skip to content

Kernel360/KBE5_HomeAid_FE

Repository files navigation

๐Ÿ  KBE5 HomeAid Frontend

React Vite Tailwind CSS Zustand

๐Ÿ“‹ ๋ชฉ์ฐจ

๐ŸŽฏ ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

KBE5 HomeAid Frontend๋Š” ์ „๋ฌธ ๋งค๋‹ˆ์ €๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ™ˆ์ผ€์–ด ์„œ๋น„์Šค ํ”Œ๋žซํผ์˜ ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. ๊ณ ๊ฐ, ๋งค๋‹ˆ์ €, ๊ด€๋ฆฌ์ž๊ฐ€ ๊ฐ๊ฐ์˜ ์—ญํ• ์— ๋งž๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ†ตํ•ฉ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐ€์น˜

  • ๐Ÿ  ํŽธ๋ฆฌํ•œ ํ™ˆ์ผ€์–ด ์„œ๋น„์Šค: ์ฒญ์†Œ, ๋Œ๋ด„, ์—์–ด์ปจ ์ฒญ์†Œ ๋“ฑ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค
  • ๐Ÿ‘ฅ ์ „๋ฌธ ๋งค๋‹ˆ์ € ๋งค์นญ: ๊ฒ€์ฆ๋œ ๋งค๋‹ˆ์ €์™€์˜ ์•ˆ์ „ํ•œ ๋งค์นญ
  • ๐Ÿ’ณ ์•ˆ์ „ํ•œ ๊ฒฐ์ œ ์‹œ์Šคํ…œ: ๋‹ค์–‘ํ•œ ๊ฒฐ์ œ ์ˆ˜๋‹จ ์ง€์›
  • ๐Ÿ“ฑ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ: ๋ชจ๋ฐ”์ผ ์šฐ์„  ์„ค๊ณ„๋กœ ๋ชจ๋“  ๊ธฐ๊ธฐ์—์„œ ์ตœ์ ํ™”

โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

๐Ÿ” ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๊ด€๋ฆฌ

  • ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ์—ญํ• : ๊ณ ๊ฐ(CUSTOMER), ๋งค๋‹ˆ์ €(MANAGER), ๊ด€๋ฆฌ์ž(ADMIN)
  • JWT ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ: ์•ˆ์ „ํ•œ ์„ธ์…˜ ๊ด€๋ฆฌ
  • OAuth ์†Œ์…œ ๋กœ๊ทธ์ธ: ์นด์นด์˜ค, ๋„ค์ด๋ฒ„ ๋“ฑ ์ง€์›
  • ๊ถŒํ•œ๋ณ„ ๋ผ์šฐํŠธ ๋ณดํ˜ธ: ์—ญํ• ์— ๋”ฐ๋ฅธ ํŽ˜์ด์ง€ ์ ‘๊ทผ ์ œ์–ด

๐Ÿ  ์„œ๋น„์Šค ์˜ˆ์•ฝ ์‹œ์Šคํ…œ

  • ์„œ๋น„์Šค ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ: ์ฒญ์†Œ, ๋Œ๋ด„, ์—์–ด์ปจ ์ฒญ์†Œ ๋“ฑ
  • ์ƒ์„ธ ์˜ต์…˜ ์„ ํƒ: ์„œ๋น„์Šค๋ณ„ ์„ธ๋ถ€ ์˜ต์…˜ ๋ฐ ์ถ”๊ฐ€ ์„œ๋น„์Šค
  • ์‹ค์‹œ๊ฐ„ ๋งค๋‹ˆ์ € ๋งค์นญ: ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋งค๋‹ˆ์ € ์ถ”์ฒœ
  • ๊ฒฐ์ œ ์‹œ์Šคํ…œ: ์นด๋“œ, ์นด์นด์˜คํŽ˜์ด, ๋„ค์ด๋ฒ„ํŽ˜์ด ๋“ฑ

๐Ÿ‘จโ€๐Ÿ’ผ ๋งค๋‹ˆ์ € ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

  • ์„œ๋น„์Šค ์ฒดํฌ์ธ: ํ˜„์žฅ ๋„์ฐฉ ๋ฐ ์„œ๋น„์Šค ์‹œ์ž‘/์™„๋ฃŒ
  • ๋งค์นญ ์š”์ฒญ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต
  • ์ •์‚ฐ ๊ด€๋ฆฌ: ์„œ๋น„์Šค ์™„๋ฃŒ ํ›„ ์ •์‚ฐ ์ฒ˜๋ฆฌ
  • ํ”„๋กœํ•„ ๊ด€๋ฆฌ: ๊ฐœ์ธ์ •๋ณด ๋ฐ ์„œ๋น„์Šค ์ •๋ณด ๊ด€๋ฆฌ

๐Ÿ› ๏ธ ๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ

  • ํ†ต๊ณ„ ๋Œ€์‹œ๋ณด๋“œ: ์‹ค์‹œ๊ฐ„ ์„œ๋น„์Šค ํ˜„ํ™ฉ ๋ฐ ๋งค์ถœ ํ†ต๊ณ„
  • ๊ณ ๊ฐ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ชฉ๋ก, ๊ฒฐ์ œ ๋‚ด์—ญ, ๋ฌธ์˜ ๊ด€๋ฆฌ
  • ๋งค๋‹ˆ์ € ๊ด€๋ฆฌ: ๋งค๋‹ˆ์ € ๋ชฉ๋ก, ์ •์‚ฐ ๊ด€๋ฆฌ, ์Šน์ธ ์ฒ˜๋ฆฌ
  • ์˜ˆ์•ฝ ๊ด€๋ฆฌ: ์ „์ฒด ์˜ˆ์•ฝ ํ˜„ํ™ฉ ๋ฐ ๋งค์นญ ๊ด€๋ฆฌ
  • ๋ฆฌ๋ทฐ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ฆฌ๋ทฐ ๊ด€๋ฆฌ ๋ฐ ์‘๋‹ต

๐Ÿ“ฑ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜

  • ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ: SSE(Server-Sent Events) ๊ธฐ๋ฐ˜ ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ
  • ๋ฐ˜์‘ํ˜• ๋””์ž์ธ: ๋ชจ๋ฐ”์ผ ์šฐ์„  ์„ค๊ณ„
  • ๋‹คํฌ๋ชจ๋“œ ์ง€์›: ํ…Œ๋งˆ ํ† ๊ธ€ ๊ธฐ๋Šฅ
  • ์ง€๋„ ์—ฐ๋™: Google Maps API ๊ธฐ๋ฐ˜ ์œ„์น˜ ์„œ๋น„์Šค

๐Ÿ› ๏ธ ๊ธฐ์ˆ  ์Šคํƒ

Frontend Framework

  • React 19.1.0: ์ตœ์‹  React ๊ธฐ๋Šฅ ํ™œ์šฉ
  • Vite 6.3.5: ๋น ๋ฅธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๋ฐ ๋นŒ๋“œ ๋„๊ตฌ
  • React Router DOM 7.6.0: ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…

UI/UX

  • Tailwind CSS 4.1.8: ์œ ํ‹ธ๋ฆฌํ‹ฐ ํผ์ŠคํŠธ CSS ํ”„๋ ˆ์ž„์›Œํฌ
  • Lucide React 0.511.0: ์•„์ด์ฝ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • React DatePicker 8.4.0: ๋‚ ์งœ ์„ ํƒ ์ปดํฌ๋„ŒํŠธ

์ƒํƒœ ๊ด€๋ฆฌ

  • Zustand 5.0.5: ๊ฒฝ๋Ÿ‰ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • React Hooks: ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ ๊ด€๋ฆฌ

์ฐจํŠธ ๋ฐ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”

  • Chart.js 4.5.0: ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”
  • React Chart.js 2 5.3.0: React์šฉ Chart.js ๋ž˜ํผ

์ง€๋„ ๋ฐ ์œ„์น˜ ์„œ๋น„์Šค

  • @react-google-maps/api 2.20.6: Google Maps React ์ปดํฌ๋„ŒํŠธ

์œ ํ‹ธ๋ฆฌํ‹ฐ

  • Axios 1.9.0: HTTP ํด๋ผ์ด์–ธํŠธ
  • clsx 2.1.1: ์กฐ๊ฑด๋ถ€ ํด๋ž˜์Šค๋ช… ์œ ํ‹ธ๋ฆฌํ‹ฐ
  • html2canvas 1.4.1: HTML์„ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜
  • jspdf 3.0.1: PDF ์ƒ์„ฑ

๊ฐœ๋ฐœ ๋„๊ตฌ

  • TypeScript 5.8.3: ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ
  • ESLint: ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ
  • Prettier 3.5.3: ์ฝ”๋“œ ํฌ๋งทํŒ…

๐Ÿš€ ์„ค์น˜ ๋ฐ ์‹คํ–‰

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

  • Node.js 18.0.0 ์ด์ƒ
  • npm ๋˜๋Š” yarn

์„ค์น˜

# ์ €์žฅ์†Œ ํด๋ก 
git clone https://github.com/Kernel360/KBE5_HomeAid_FE.git

# ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์ด๋™
cd KBE5_HomeAid_FE

# ์˜์กด์„ฑ ์„ค์น˜
npm install
# ๋˜๋Š”
yarn install

๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰

# ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹œ์ž‘
npm run dev
# ๋˜๋Š”
yarn dev

๋นŒ๋“œ

# ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ
npm run build
# ๋˜๋Š”
yarn build

# ๋นŒ๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
npm run preview
# ๋˜๋Š”
yarn preview

์ฝ”๋“œ ํ’ˆ์งˆ

# ๋ฆฐํŠธ ๊ฒ€์‚ฌ
npm run lint
# ๋˜๋Š”
yarn lint

๐Ÿ‘ฅ ์‚ฌ์šฉ์ž ์—ญํ• ๋ณ„ ๊ธฐ๋Šฅ

๐Ÿ  ๊ณ ๊ฐ (CUSTOMER)

  • ์„œ๋น„์Šค ์˜ˆ์•ฝ: ๋‹ค์–‘ํ•œ ํ™ˆ์ผ€์–ด ์„œ๋น„์Šค ์˜ˆ์•ฝ
  • ๊ฒฐ์ œ ๊ด€๋ฆฌ: ์•ˆ์ „ํ•œ ์˜จ๋ผ์ธ ๊ฒฐ์ œ
  • ์˜ˆ์•ฝ ๊ด€๋ฆฌ: ์˜ˆ์•ฝ ๋‚ด์—ญ ์กฐํšŒ ๋ฐ ์ทจ์†Œ
  • ๋ฆฌ๋ทฐ ์ž‘์„ฑ: ์„œ๋น„์Šค ํ›„๊ธฐ ๋ฐ ํ‰์ 
  • ๋ฌธ์˜ ๊ด€๋ฆฌ: 1:1 ๋ฌธ์˜ ์ž‘์„ฑ ๋ฐ ์กฐํšŒ
  • ์ฃผ์†Œ ๊ด€๋ฆฌ: ์„œ๋น„์Šค ์ฃผ์†Œ ๋“ฑ๋ก ๋ฐ ๊ด€๋ฆฌ

๐Ÿ‘จโ€๐Ÿ’ผ ๋งค๋‹ˆ์ € (MANAGER)

  • ๋งค์นญ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต
  • ์„œ๋น„์Šค ์ฒดํฌ์ธ: ํ˜„์žฅ ๋„์ฐฉ ๋ฐ ์„œ๋น„์Šค ์ง„ํ–‰
  • ์ •์‚ฐ ๊ด€๋ฆฌ: ์„œ๋น„์Šค ์™„๋ฃŒ ํ›„ ์ •์‚ฐ ์ฒ˜๋ฆฌ
  • ํ”„๋กœํ•„ ๊ด€๋ฆฌ: ๊ฐœ์ธ์ •๋ณด ๋ฐ ์„œ๋น„์Šค ์ •๋ณด ๊ด€๋ฆฌ
  • ๋ฌธ์˜ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ฌธ์˜์— ๋Œ€ํ•œ ์‘๋‹ต

๐Ÿ‘จโ€๐Ÿ’ป ๊ด€๋ฆฌ์ž (ADMIN)

  • ๋Œ€์‹œ๋ณด๋“œ: ์‹ค์‹œ๊ฐ„ ํ†ต๊ณ„ ๋ฐ ํ˜„ํ™ฉ ๋ชจ๋‹ˆํ„ฐ๋ง
  • ๊ณ ๊ฐ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ชฉ๋ก, ๊ฒฐ์ œ ๋‚ด์—ญ ๊ด€๋ฆฌ
  • ๋งค๋‹ˆ์ € ๊ด€๋ฆฌ: ๋งค๋‹ˆ์ € ์Šน์ธ, ์ •์‚ฐ ๊ด€๋ฆฌ
  • ์˜ˆ์•ฝ ๊ด€๋ฆฌ: ์ „์ฒด ์˜ˆ์•ฝ ํ˜„ํ™ฉ ๋ฐ ๋งค์นญ ๊ด€๋ฆฌ
  • ํ†ต๊ณ„ ๋ถ„์„: ๋งค์ถœ, ์„œ๋น„์Šค, ๊ณ ๊ฐ ํ†ต๊ณ„
  • ๋ฆฌ๋ทฐ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ฆฌ๋ทฐ ๊ด€๋ฆฌ ๋ฐ ์‘๋‹ต

๐Ÿ“ฑ ์ฃผ์š” ํŽ˜์ด์ง€

๐Ÿ  ๋ฉ”์ธ ํŽ˜์ด์ง€

  • ํ™ˆํŽ˜์ด์ง€: ์„œ๋น„์Šค ์†Œ๊ฐœ ๋ฐ ์ฃผ์š” ๊ธฐ๋Šฅ ์•ˆ๋‚ด
  • ์ด๋ฒคํŠธ ํŽ˜์ด์ง€: ์ง„ํ–‰์ค‘์ธ ์ด๋ฒคํŠธ ๋ฐ ํ”„๋กœ๋ชจ์…˜
  • ๊ณต์ง€์‚ฌํ•ญ: ์„œ๋น„์Šค ๊ด€๋ จ ๊ณต์ง€ ๋ฐ FAQ

๐Ÿ” ์ธ์ฆ ํŽ˜์ด์ง€

  • ๋กœ๊ทธ์ธ: ์ผ๋ฐ˜ ๋กœ๊ทธ์ธ ๋ฐ ์†Œ์…œ ๋กœ๊ทธ์ธ
  • ํšŒ์›๊ฐ€์ž…: ๊ณ ๊ฐ/๋งค๋‹ˆ์ € ์„ ํƒ ๋ฐ ๋‹จ๊ณ„๋ณ„ ๊ฐ€์ž…
  • OAuth ์ฝœ๋ฐฑ: ์†Œ์…œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ

๐Ÿ›’ ์˜ˆ์•ฝ ์‹œ์Šคํ…œ

  • ์„œ๋น„์Šค ์„ ํƒ: ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์„œ๋น„์Šค ์„ ํƒ
  • ์˜ต์…˜ ์„ ํƒ: ์„œ๋น„์Šค๋ณ„ ์„ธ๋ถ€ ์˜ต์…˜ ์„ ํƒ
  • ์˜ˆ์•ฝ ์ •๋ณด: ๋‚ ์งœ, ์‹œ๊ฐ„, ์ฃผ์†Œ ์ž…๋ ฅ
  • ๊ฒฐ์ œ: ๋‹ค์–‘ํ•œ ๊ฒฐ์ œ ์ˆ˜๋‹จ ์ง€์›

๐Ÿ“Š ๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ

  • ํ†ต๊ณ„ ๋Œ€์‹œ๋ณด๋“œ: ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”
  • ๊ณ ๊ฐ ๊ด€๋ฆฌ: ๊ณ ๊ฐ ๋ชฉ๋ก ๋ฐ ์ƒ์„ธ ์ •๋ณด
  • ๋งค๋‹ˆ์ € ๊ด€๋ฆฌ: ๋งค๋‹ˆ์ € ์Šน์ธ ๋ฐ ์ •์‚ฐ
  • ์˜ˆ์•ฝ ๊ด€๋ฆฌ: ์ „์ฒด ์˜ˆ์•ฝ ํ˜„ํ™ฉ ๊ด€๋ฆฌ

๐Ÿ”Œ API ์—ฐ๋™

API ํด๋ผ์ด์–ธํŠธ ์„ค์ •

// src/api/config/api.js
import axios from 'axios';

const api = axios.create({
  baseURL: process.env.VITE_API_BASE_URL,
  timeout: 10000,
});

// ์š”์ฒญ ์ธํ„ฐ์…‰ํ„ฐ - JWT ํ† ํฐ ์ž๋™ ์ถ”๊ฐ€
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('accessToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ - ํ† ํฐ ๋งŒ๋ฃŒ ์ฒ˜๋ฆฌ
api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      // ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
      window.location.href = '/auth/signin';
    }
    return Promise.reject(error);
  }
);

์ฃผ์š” API ์—”๋“œํฌ์ธํŠธ

  • ์ธ์ฆ: /auth/signin, /auth/signup, /auth/refresh
  • ์„œ๋น„์Šค: /services, /services/{id}/options
  • ์˜ˆ์•ฝ: /reservations, /reservations/{id}
  • ๊ฒฐ์ œ: /payments, /payments/{id}
  • ๋งค์นญ: /matching, /matching/{id}
  • ๊ด€๋ฆฌ์ž: /admin/dashboard, /admin/customers, /admin/managers

๐Ÿ—ƒ๏ธ ์ƒํƒœ ๊ด€๋ฆฌ

Zustand ์Šคํ† ์–ด ๊ตฌ์กฐ

// src/stores/authStore.js
import { create } from 'zustand';

export const useAuthStore = create((set, get) => ({
  user: null,
  accessToken: null,
  refreshToken: null,

  setUser: (user) => set({ user }),
  setTokens: (accessToken, refreshToken) => set({ accessToken, refreshToken }),
  logout: () => set({ user: null, accessToken: null, refreshToken: null }),
}));

์ฃผ์š” ์Šคํ† ์–ด

  • authStore: ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด
  • themeStore: ๋‹คํฌ๋ชจ๋“œ/๋ผ์ดํŠธ๋ชจ๋“œ ์„ค์ •
  • reservationStore: ์˜ˆ์•ฝ ๊ด€๋ จ ์ƒํƒœ
  • matchingStore: ๋งค์นญ ๊ด€๋ จ ์ƒํƒœ
  • alertStore: ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ ์ƒํƒœ

๐Ÿงฉ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ

๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ

  • Button: ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ
  • Modal: ๋ชจ๋‹ฌ ๋‹ค์ด์–ผ๋กœ๊ทธ ์ปดํฌ๋„ŒํŠธ
  • Header: ๋„ค๋น„๊ฒŒ์ด์…˜ ํ—ค๋”
  • Footer: ํ•˜๋‹จ ๋„ค๋น„๊ฒŒ์ด์…˜
  • ThemeToggle: ํ…Œ๋งˆ ์ „ํ™˜ ํ† ๊ธ€

๊ธฐ๋Šฅ๋ณ„ ์ปดํฌ๋„ŒํŠธ

  • ๊ด€๋ฆฌ์ž: Dashboard, CustomerList, ManagerList ๋“ฑ
  • ์˜ˆ์•ฝ: ServiceOption, ServiceRequest, Payment ๋“ฑ
  • ๋งค์นญ: MatchingList, MatchingDetail, ServiceCheckIn ๋“ฑ
  • ๋ฆฌ๋ทฐ: ReviewList, ReviewWrite, ReviewDetail ๋“ฑ

๐Ÿ› ๏ธ ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ

์ฝ”๋“œ ์Šคํƒ€์ผ

  • ESLint: ์ฝ”๋“œ ํ’ˆ์งˆ ๋ฐ ์ผ๊ด€์„ฑ ์œ ์ง€
  • Prettier: ์ฝ”๋“œ ํฌ๋งทํŒ… ์ž๋™ํ™”
  • TypeScript: ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ

ํด๋” ๊ตฌ์กฐ ๊ทœ์น™

  • features/: ๊ธฐ๋Šฅ๋ณ„ ๋ชจ๋“ˆํ™”
  • components/: ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ
  • pages/: ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ
  • services/: API ์„œ๋น„์Šค
  • utils/: ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜

์ƒํƒœ ๊ด€๋ฆฌ ํŒจํ„ด

  • Zustand: ๊ฒฝ๋Ÿ‰ ์ƒํƒœ ๊ด€๋ฆฌ
  • React Hooks: ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ
  • Context API: ์ „์—ญ ์ƒํƒœ (ํ•„์š”์‹œ)

๋ผ์šฐํŒ… ๊ตฌ์กฐ

  • ๊ณต๊ฐœ ๋ผ์šฐํŠธ: ์ธ์ฆ ๋ถˆํ•„์š”
  • ๋ณดํ˜ธ๋œ ๋ผ์šฐํŠธ: ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ํ•„์š”
  • ์ค‘์ฒฉ ๋ผ์šฐํŠธ: ๋ ˆ์ด์•„์›ƒ ๊ณต์œ 

๐Ÿš€ ๋ฐฐํฌ

Vercel ๋ฐฐํฌ

# Vercel CLI ์„ค์น˜
npm i -g vercel

# ๋ฐฐํฌ
vercel --prod

ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

# .env.local
VITE_API_BASE_URL=https://api.example.com
VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key

๋นŒ๋“œ ์ตœ์ ํ™”

  • ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…: ๋ผ์šฐํŠธ๋ณ„ ์ฒญํฌ ๋ถ„๋ฆฌ
  • ์ด๋ฏธ์ง€ ์ตœ์ ํ™”: WebP ํฌ๋งท ์‚ฌ์šฉ
  • ๋ฒˆ๋“ค ๋ถ„์„: ๋นŒ๋“œ ํฌ๊ธฐ ์ตœ์ ํ™”

๐Ÿ‘ฅ ํŒ€์› (Team Member)

์ƒ์šฐ์ง„ (ํŒ€์žฅ) ๊น€์ˆ™ํ˜„ ์•ˆ์ง€ํ˜„ ๊ฐ•ํฌ์ง„
@SangWJDev @soohoioa @jhroom @heeejinin

๐Ÿ“ž ๋ฌธ์˜

  • ํ”„๋กœ์ ํŠธ ์ด์Šˆ: GitHub Issues
  • ๋ฌธ์˜์‚ฌํ•ญ: ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์ž์—๊ฒŒ ์—ฐ๋ฝ

KBE5 HomeAid Frontend - ์ „๋ฌธ ๋งค๋‹ˆ์ €๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ™ˆ์ผ€์–ด ์„œ๋น„์Šค ํ”Œ๋žซํผ ๐Ÿ โœจ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •