traveling-around-the-world

一個以 React 為核心的單頁式應用程式SPA用來記錄自己走訪過的國家、城市與時間軸。初期資料儲存在瀏覽器 LocalStorage並預留後端 Express + MongoDB 的擴充架構,後續可平滑升級成多人同步的雲端服務。

Monorepo 結構

traveling-around-the-world/
├─ client/   # Vite + React + TS 的前端 SPA
├─ server/   # Express + MongoDB (未來) API 服務
└─ shared/   # 前後端共用的型別定義
  • client 預設採 LocalStorage 擷取資料,並透過 VisitProvider 可快速切換成 API 模式。
  • server 已放好 Express + Mongoose 架構與 RESTful routes只需接上 MongoDB 並啟動即可提供資料。
  • shared 放行程型別 VisitDto,讓前後端保持相同資料契約。

前端client

技術與工具

  • Vite + React 18 + TypeScript
  • React Router 規劃 SPA 路由
  • Zustand 追蹤 UI 狀態(訪問表單 Modal 與初始座標)
  • React Query 統一處理資料讀寫與快取
  • React Hook Form + Zod 表單驗證
  • react-leaflet + OpenStreetMap 圖資,支援地圖點擊新增足跡
  • Tailwind CSS (JIT) 打造快速 UI

模組切分

  • features/mapLeaflet 地圖、點擊事件、旅遊標記
  • features/visits資料型別、LocalStorage Repository、React Query hooks、統計卡片與表單元件
  • components/layout:頁面主框架、側邊欄
  • stateZustand store 控制訪問建立/編輯的 Modal
  • components/overlay/VisitModal:以 Modal 呈現足跡表單,地圖右下角的 + 漂浮按鈕或點擊地圖即可開啟

LocalStorage → API 的切換

  • 預設 VisitProvider mode="local" 會載入 localVisitRepository
  • 改為 mode="api" 並設定 apiBaseUrl 後,就會改用 VisitApiClient 透過 REST API 存取。
  • Vite proxy 已轉發 /apihttp://localhost:4000,未來後端啟動後無需改動前端呼叫。

多語系支援

  • 透過 react-i18next 提供繁體中文與英文,語系檔位於 client/src/locales/
  • 右上角的語言選單 (LanguageSwitcher) 可即時切換語言,並記錄在 LocalStorage 方便下次載入。

開發啟動

  1. 安裝相依套件:cd client && npm install
  2. 啟動開發伺服器:npm run dev
  3. 瀏覽器開啟 http://localhost:5173

注意Leaflet 需要載入 CSS已在 TravelMap 中引入 leaflet/dist/leaflet.css)。

Docker Compose 啟動

若想直接以容器方式啟動整個堆疊MongoDB + Node API + Nginx 前端):

  1. 建立映像:docker compose build
  2. 啟動服務:docker compose up -d
  3. 前端:http://localhost:3000
  4. APIhttp://localhost:4000

預設前端仍採 LocalStorage。如果要改用 API 資料來源,請在 client/src/app/App.tsxVisitProvider mode="local" 改成 mode="api"

後端server

技術堆疊

  • Express 4
  • Mongoose 8 + MongoDB內建 visit schema資料結構與前端共用
  • Zod 驗證 API 請求 payload
  • Helmet、CORS、Morgan 提供基礎安全與紀錄

架構亮點

  • src/app.ts 建立 Express App、共用中介層、/health 健康檢查
  • src/modules/visits模型、Service、Controller、Router 切分清晰
  • visit.mapper.ts 將 Mongoose Doc 轉成 shared/visit.ts 的 DTO
  • infra/db/mongo.ts 佈建 Mongo 連線抽象

啟動指令

  1. 安裝套件:cd server && npm install
  2. 建立 .env(可複製 .env.example)並設定 MONGODB_URI
  3. 開發模式:npm run dev
  4. 編譯產出:npm run build -> dist/

RESTful 端點:

  • GET /api/visits:取得全部足跡
  • POST /api/visits:新增足跡
  • GET /api/visits/:id
  • PUT /api/visits/:id
  • DELETE /api/visits/:id

共享型別shared

  • shared/visit.ts 定義 Visit DTO前端 Visit 及後端回傳皆採相同結構。
  • Vite 透過 @shared/* alias 匯入,後端則直接使用相對路徑,確保型別同步。

開發流程建議

  1. LocalStorage MVP:僅啟動前端即可使用,點擊地圖開啟表單、資料存在瀏覽器。
  2. 串接 API:建立 MongoDB啟動 npm run dev 後將前端 VisitProvider 切換到 API 模式。
  3. Geocoding:前端已透過 Nominatim 反向地理編碼在點擊地圖時預填國家 / 城市;若需更高配額可在後端建立 Proxy。
  4. 照片/檔案:後端可擴增 S3/Cloudinary 上傳,再於前端 VisitCreateInput 增加檔案欄位。

待辦與下一步

  • 實作 geocoding proxy於點擊地圖後自動填入國家 / 城市
  • 加入使用者認證(如 Auth0 或自建 JWT以支援多人服務
  • 將訪問紀錄導出成時間線或統計圖表D3 / Recharts
  • 建立 Vitest / Jest 單元測試與 React Testing Library 元件測試
  • 規劃 CIGitHub Actions自動執行 linttest

授權

本專案採用 MIT License詳見 LICENSE

Description
No description provided
Readme MIT 401 KiB
Languages
TypeScript 98.1%
Dockerfile 0.8%
HTML 0.7%
CSS 0.3%
JavaScript 0.1%