Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
199 commits
Select commit Hold shift + click to select a range
833c049
set up Vercel for front and backend
govargas Sep 10, 2025
bf4f8d6
install runtime and dev dependecies in backend
govargas Sep 10, 2025
e08b6b8
create src and routes folders in backend and edit tsconfig.json
govargas Sep 10, 2025
65f594f
setup TS + basic health endpoint
govargas Sep 10, 2025
2184b76
add vercel.json to route traffic to Express app
govargas Sep 10, 2025
ac659c3
edit vercel.json in backend to test health route
govargas Sep 10, 2025
e3edf9d
add temporary direct health routhe to rule out router import issues
govargas Sep 10, 2025
72f2bd0
update health router with a log
govargas Sep 10, 2025
f9752b8
chore(backend): move Express handler to /api/index.ts for Vercel routing
govargas Sep 10, 2025
2c2f5f9
fix(backend): mount router at root inside /api function
govargas Sep 10, 2025
bbc12c6
fix(backend): route /api/* to Express app via vercel.json and export …
govargas Sep 10, 2025
8b75be2
clean project from using serverlesshttp and some more tidy-ups, also …
govargas Sep 11, 2025
4f5c197
add db-check route to backend API
govargas Sep 11, 2025
542bcf7
fix(api): ensure /db-check forces connectDB before reporting
govargas Sep 11, 2025
7d453c5
fix(types): strongly type User mongoose model to avoid union overloads
govargas Sep 11, 2025
7cd340b
feat(auth): mount /api/auth routes and add protected example
govargas Sep 11, 2025
128bf02
add a quick ping route inside the auth router
govargas Sep 11, 2025
c0eddbe
fix(mongoose): use mongoose.models via default export for ESM runtime
govargas Sep 11, 2025
d7fae20
fix(auth): switch to bcryptjs for serverless compatibility
govargas Sep 11, 2025
70bdaa7
fix(auth): ensure Mongo connect before queries and add error logging
govargas Sep 11, 2025
3ad6799
feat(favorites): add Favorite model and protected CRUD routes
govargas Sep 11, 2025
9cd2592
chore(favorites): fix TS handler types (cast req to AuthedRequest) an…
govargas Sep 11, 2025
6206ce5
add memory cache + fetch wrapper
govargas Sep 12, 2025
dbf25c2
add hav.ts
govargas Sep 12, 2025
a89c2d4
update tsconfig in backend to use node18 features and include DOM types
govargas Sep 12, 2025
fea7d34
chore(backend): relax Node engine to >=18 for local + Vercel compatib…
govargas Sep 12, 2025
3d25d5f
chore(backend): relax Node engine to >=18 and remove unused @types/bc…
govargas Sep 12, 2025
bdc3169
feat(backend): add /api/beaches routes to proxy HaV API
govargas Sep 12, 2025
219c55b
feat(backend): wire /api/beaches to HaV feature & detail endpoints
govargas Sep 12, 2025
ff99d9e
feat(frontend): add types folder and beaches.ts with GeoJSON types + …
govargas Sep 12, 2025
9891798
feat(frontend): add beaches types and setup VITE_API_BASE in .env
govargas Sep 13, 2025
299feea
feat(frontend): add beaches quality label utils
govargas Sep 13, 2025
069a876
chore(frontend): standardize on VITE_API_BASE and remove VITE_BACKEND…
govargas Sep 13, 2025
e161abe
chore(frontend): add TS + Vite types, env typing, and fix beaches API…
govargas Sep 13, 2025
93e843b
chore(frontend): wrap app with React Query provider
govargas Sep 13, 2025
46c22ed
feat(frontend): add BeachesList component and render it in App
govargas Sep 13, 2025
3c741d5
fix(frontend): add @tanstack/react-query dependency
govargas Sep 13, 2025
3a59de3
chore(frontend): add react-router-dom
govargas Sep 14, 2025
cdd155c
chore(frontend): wrap app with BrowserRouter
govargas Sep 14, 2025
705c12c
feat(frontend): add routes for list and beach detail
govargas Sep 14, 2025
4eb0f77
feat(frontend): link beach items to detail route
govargas Sep 14, 2025
37f4c82
feat(frontend): add deriveClassificationCode helper
govargas Sep 14, 2025
50f024a
feat(frontend): add BeachDetailPanel
govargas Sep 14, 2025
c8b068f
feat(frontend): add BeachDetailPage
govargas Sep 14, 2025
76983ef
chore(frontend): add i18next + react-i18next
govargas Sep 14, 2025
945cf88
feat(frontend): add sv translation files
govargas Sep 14, 2025
86512b7
feat(frontend): add english translation files
govargas Sep 14, 2025
809d3d3
chore(frontend): initialize i18next and load sv/en resources
govargas Sep 14, 2025
2d6b905
feat(frontend): add LanguageSwitcher
govargas Sep 14, 2025
b4afeee
feat(frontend): render LanguageSwitcher in App
govargas Sep 14, 2025
db91d9e
feat(frontend): add useTranslation in BeachesList
govargas Sep 14, 2025
7a4d1fb
feat(frontend): add useTranslation in BeachDetailPanel
govargas Sep 14, 2025
b80d2b5
feat(frontend): add useTranslation in BeachDetailPage
govargas Sep 14, 2025
1f69de3
chore(frontend): install Tailwind, PostCSS, and Autoprefixer
govargas Sep 14, 2025
6a04903
chore(frontend): add PostCSS config for Tailwind
govargas Sep 14, 2025
23bff03
chore(frontend): add Tailwind config with fonts, colors, and spacing
govargas Sep 14, 2025
c871983
chore(frontend): add Tailwind base styles and global CSS
govargas Sep 14, 2025
797669c
chore(frontend): import Tailwind CSS in main entry
govargas Sep 14, 2025
98c5436
chore(frontend): add Google Fonts (Inter & Spectral) in index.html
govargas Sep 14, 2025
0b2d97f
change tailwind config from js to ts
govargas Sep 14, 2025
6f0988e
chore(frontend): add @tailwindcss/postcss for Tailwind v4
govargas Sep 14, 2025
b351f98
chore(frontend): switch PostCSS plugin to @tailwindcss/postcss
govargas Sep 14, 2025
e157a4b
chore(frontend): simplify index.css to Tailwind v4 import only
govargas Sep 14, 2025
0abc425
feat(frontend): edit tailwind config ts file for setting up actual UI
govargas Sep 14, 2025
c9942c4
feat(frontend): restore index css file with UI layers
govargas Sep 14, 2025
7b3c35f
feat(frontend): edit fonts links
govargas Sep 14, 2025
b989f1d
feat(frontend): add accessible light/dark theme tokens + fonts in tai…
govargas Sep 14, 2025
c72805f
feat(frontend): add accessible light/dark theme tokens + fonts in ind…
govargas Sep 14, 2025
b0fca57
feat(frontend): update fonts links in index html file
govargas Sep 14, 2025
d0abd18
feat(frontend): integrate Header into App layout while keeping Routes…
govargas Sep 14, 2025
d5a503f
chore(frontend): ensure Tailwind theme includes quality colors + sema…
govargas Sep 14, 2025
a07a3c0
fix(frontend): replace theme() usages with utilities and keep @apply …
govargas Sep 14, 2025
d4e5fab
chore(frontend): switch to Tailwind v4 tokens — define palette/fonts …
govargas Sep 14, 2025
bf15636
feat(frontend): add accessible Header with brand, menus, language slo…
govargas Sep 14, 2025
f62a468
chore(backend): remove global Mongo connect; connect only in auth/fav…
govargas Sep 14, 2025
e68aaac
chore(backend): harden Mongo connect (fail-fast, no buffer, cached gl…
govargas Sep 14, 2025
c87b2ed
feat(frontend): add haversine distance helper (utils/geo)
govargas Sep 14, 2025
d0ccb79
feat(frontend): add on-demand geolocation hook
govargas Sep 14, 2025
6fe627d
fix(frontend): standardize on lon (keep lng alias) and update feature…
govargas Sep 14, 2025
f3c5c9e
delete tailwind test in App.tsx
govargas Sep 14, 2025
8b3e084
delete tailwind smoke test in main.tsx
govargas Sep 14, 2025
8c7c310
feat(frontend): style BeachesList as cards (custom palette, Spectral …
govargas Sep 14, 2025
de5104f
chore(frontend): keep BeachesList – distance guard & skeletons alread…
govargas Sep 14, 2025
8a931c6
chore(frontend): minor Tailwind component polish (card shadow helper)
govargas Sep 14, 2025
9ea064c
style(frontend): restore v4 @theme tokens and base styles in index.css
govargas Sep 14, 2025
c966aa5
feat(frontend): style Beaches list as cards + proximity pill, skeleto…
govargas Sep 14, 2025
7721fc6
feat(frontend): show water quality + latest rating on Beach detail, a…
govargas Sep 14, 2025
907dd49
chore(frontend): extend BeachDetail with optional sample date fields …
govargas Sep 14, 2025
a65a000
feat(frontend): show latest sample date (Provdatum) on Beach detail w…
govargas Sep 14, 2025
0155e61
chore(frontend): add formatDate util and use browser locale
govargas Sep 14, 2025
acfcad5
feat(frontend): style BeachDetailPage to match mock (quality pill, me…
govargas Sep 15, 2025
1218f27
feat(frontend): add auth token helper (localStorage)
govargas Sep 15, 2025
a718554
feat(frontend): favorites API hooks (list/add/remove) with React Query
govargas Sep 15, 2025
081e152
feat(frontend): wire favorite toggle on BeachDetailPage (prompt for J…
govargas Sep 15, 2025
2b00bbf
feat(frontend): wire Header search input to global store
govargas Sep 15, 2025
d3747a2
feat(frontend): add tiny UI store (zustand) for header search
govargas Sep 15, 2025
adb0eeb
feat(frontend): filter BeachesList via Zustand search (Header input)
govargas Sep 15, 2025
847c1b5
feat(frontend): add UI store (search state) with zustand
govargas Sep 15, 2025
18dd729
feat(backend): add havV2Get helper for HaV v2 API calls
govargas Sep 15, 2025
ede0282
feat(backend): add HaV v2 client + getLatestSampleDate helper; unify …
govargas Sep 15, 2025
51f33f0
feat(backend): include latestSampleDate on /api/beaches/:id using HaV…
govargas Sep 15, 2025
ab35d86
chore(backend): install dotenv for local env loading
govargas Sep 15, 2025
923f404
feat(backend): enrich /api/beaches/:id with latestSampleDate from HaV v2
govargas Sep 15, 2025
e85b6fa
fix(backend): read HaV v2 base from HAV_V2_BASE or HAV_V2_BASE_URL; t…
govargas Sep 15, 2025
521ab56
chore(backend): add request logger and /api/debug/env to troubleshoot…
govargas Sep 15, 2025
1562459
feat(backend): include latestSampleDate on /api/beaches/:id (prefer v…
govargas Sep 15, 2025
f043703
feat(frontend): add short style to formatDate and use for latestSampl…
govargas Sep 15, 2025
d2f9556
chore(frontend): add maplibre-gl (+ types)
govargas Sep 15, 2025
ef6f8f0
style(frontend): import maplibre-gl CSS
govargas Sep 15, 2025
7c0d3e4
feat(frontend): add MapView with MapLibre + MapTiler (compact attribu…
govargas Sep 15, 2025
85277f5
feat(frontend): show MapView above list and wire user location marker
govargas Sep 15, 2025
2c13f99
feat(frontend): square map layout + theme-aware styles and markers
govargas Sep 15, 2025
335eb8d
feat(map): use published MapTiler Customize styles (light/dark) + dar…
govargas Sep 16, 2025
88600d4
feat(map): edit map size
govargas Sep 16, 2025
f1fcf3a
feat(map): use Tailwind classes for markers and keep accent color in …
govargas Sep 16, 2025
36296f7
feat(map): restore edit map size
govargas Sep 16, 2025
f892328
feat(list): limit “near me” to 20 km and pass full filtered set to map
govargas Sep 16, 2025
57b58cf
feat(map+list): default Sergels torg ±20km, fit to radius on “Use loc…
govargas Sep 16, 2025
cf89a9e
feat(map+list): default Sergels torg ±20km, fit to radius on “Use loc…
govargas Sep 16, 2025
9fa11f6
feat(map): adaptive zoom for small radii + no-flicker map init
govargas Sep 17, 2025
7e9a5fe
chore(frontend): remove duplicate LanguageSwitcher under search bar
govargas Sep 17, 2025
ec41549
ui(frontend): move “Use current location” button below map for better…
govargas Sep 17, 2025
b50d78e
ui(frontend): edit BADA title size and weight
govargas Sep 17, 2025
da8499a
ui(frontend): tweak flex alignment of the header text titles
govargas Sep 19, 2025
b699d3a
ui(frontend): replace dummy icons with svg icons for the men
govargas Sep 19, 2025
54c26d2
ui(frontend): install svgr plugin so icons inherit theme colors when …
govargas Sep 19, 2025
8b3afe6
chore: add .env.example files for backend and frontend with safe plac…
govargas Sep 24, 2025
d626463
docs: update README
govargas Sep 24, 2025
cf91ea4
docs: add tech stack and deployment badges to README header
govargas Sep 24, 2025
1f89c66
docs: move README to root
govargas Sep 24, 2025
5e35c12
docs: update README
govargas Sep 24, 2025
015c1fa
update README
govargas Sep 24, 2025
5d088ab
feat(auth): add zustand auth store with localStorage hydration
govargas Sep 24, 2025
d3aa85c
chore: configure @ alias for src in Vite and TypeScript
govargas Sep 24, 2025
bec6c05
refactor(pages): move BeachDetailPage to /src/pages and fix imports
govargas Sep 24, 2025
92fbdb1
feat(pages): add HomePage, LoginPage, RegisterPage, and FavoritesPage…
govargas Sep 24, 2025
704d87c
fix(router): remove nested BrowserRouter from App and keep single rou…
govargas Sep 24, 2025
4a5bad9
feat(api): add apiFetch client with automatic JWT header support and …
govargas Sep 24, 2025
6b64dca
refactor(api): migrate beaches API to apiFetch for consistency with f…
govargas Sep 24, 2025
6399971
chore(api): add optional API request logging controlled by VITE_DEBUG…
govargas Sep 24, 2025
9e552e9
feat(header): integrate auth store and clear React Query cache on logout
govargas Sep 24, 2025
2fd8382
feat(auth): update LoginPage with form validation, error handling, an…
govargas Sep 25, 2025
0e5805b
feat(auth): update RegisterPage with validation and redirect to login
govargas Sep 25, 2025
ddb8cb4
feat(favorites): update protected FavoritesPage with list and remove …
govargas Sep 25, 2025
d023d8c
fix(deps): add react-hook-form, zod, and resolvers to frontend depend…
govargas Sep 25, 2025
976aabf
fix(backend): align start script with server.ts entrypoint
govargas Sep 25, 2025
e7f5000
fix(auth): use auth store in BeachDetailPage and redirect to /login i…
govargas Sep 25, 2025
15513d7
feat(api): add useBeachDetails hook to batch fetch beach details for …
govargas Sep 25, 2025
5fbd85b
feat(favorites): show beach name, municipality and classification on …
govargas Sep 25, 2025
a7304f3
feat(favorites): add friendly empty state with CTA to map
govargas Sep 25, 2025
2aa8718
chore(favorites): show subtle 'updating…' hint while beach details load
govargas Sep 25, 2025
947e417
feat(favorites): add client-side sorting by name or municipality
govargas Sep 25, 2025
56aa68e
chore(deps): add dnd-kit for drag and drop
govargas Sep 25, 2025
472b9b3
feat(favorites): add SortableFavorite component (dnd-kit useSortable)
govargas Sep 26, 2025
f2820bf
feat(favorites): add custom drag-and-drop reordering with dnd-kit and…
govargas Sep 26, 2025
eb44ad7
feat(backend): add field to Favorite model and composite unique index
govargas Sep 26, 2025
59793ad
feat(backend): add PATCH /api/favorites/reorder to persist custom order
govargas Sep 26, 2025
9ad7269
feat(backend): finalize PATCH /favorites/reorder with id de-duplicati…
govargas Sep 26, 2025
4e187c9
feat(api): add useReorderFavorites mutation to persist favorites order
govargas Sep 26, 2025
5c23ef9
feat(favorites): persist custom drag-and-drop order to server on drag…
govargas Sep 26, 2025
7f0b62d
fix(api): subscribe to token in useFavorites and harden apiFetch base…
govargas Sep 26, 2025
0d93b7a
style(favorites): stack title/sort/link on mobile with responsive fle…
govargas Sep 28, 2025
257f68a
feat(netlify): add SPA redirects for Vite in frontend/_redirects
govargas Sep 28, 2025
6e187a1
feat(backend): configure CORS via CORS_ORIGIN env (comma-separated) w…
govargas Sep 28, 2025
ab833cf
feat(backend): add env-driven CORS in index.ts (CORS_ORIGIN with fall…
govargas Sep 28, 2025
8c8be4a
chore: track frontend/package-lock.json for Netlify build
govargas Sep 28, 2025
e0eca22
fix(cors): remove invalid app.options('*') preflight handler causing …
govargas Sep 28, 2025
cf985e0
chore(server): add /api/health endpoint for easy uptime and Mongo check
govargas Sep 28, 2025
4c06241
fix(backend): remove invalid app.options('*') in src/index.ts (Expres…
govargas Sep 28, 2025
da83554
chore(backend): guard & log app.options registrations; dump mounted r…
govargas Sep 28, 2025
c0ee32d
chore(backend): remove temporary route guard
govargas Sep 28, 2025
de30ac4
chore(backend): remove temporary route dump logs
govargas Sep 28, 2025
25ae2e7
chore(backend): remove temporary dumpRoutes callfunction
govargas Sep 28, 2025
91be461
chore(backend): remove legacy server.js entrypoint
govargas Sep 28, 2025
4ad597b
update readme
govargas Sep 28, 2025
0dfc6aa
update readme
govargas Sep 28, 2025
2000b34
chore(backend): expose /api/debug/env before 404 for production diagn…
govargas Sep 28, 2025
41836d3
chore(backend): register /api/debug/env in index.ts before 404; keep …
govargas Sep 28, 2025
290d4e1
fix latest commit
govargas Sep 28, 2025
29ecb55
docs: update README test account to [email protected] (prod-verified)
govargas Sep 28, 2025
60000dc
feat(icons): add light- and dark-mode favicon variants and update ind…
govargas Sep 28, 2025
0da8c38
refactor(router): replace react-router-dom imports with react-router
govargas Oct 10, 2025
3bd3a5a
feat: Add Swedish localization and accessibility improvements
govargas Oct 31, 2025
f110370
docs: Update README
govargas Oct 31, 2025
586494a
feat: Complete Swedish localization and responsive improvements
govargas Oct 31, 2025
8c66ca7
fix: Make search work across all beaches in Sweden
govargas Oct 31, 2025
3bbdcf0
fix: Improve location button behavior and map filtering
govargas Oct 31, 2025
03af0e9
feat: Add clickable links to beach details in map marker popups
govargas Oct 31, 2025
773d561
fix(routing): add SPA redirects and cache external API calls
govargas Nov 2, 2025
dd57d5a
fix: move _redirects to public folder for Netlify SPA routing
govargas Nov 2, 2025
8546daf
fix(header): redirect to home page when searching from non-home pages
govargas Nov 2, 2025
8b5be41
feat(header): add search autocomplete with inline beach results
govargas Nov 2, 2025
ab212a0
fix: achieve 100% Lighthouse scores for accessibility and SEO
govargas Nov 3, 2025
eebf55c
fix: localize water classification badges and remove NUTS code
govargas Nov 3, 2025
028954b
feat: add marker clustering and expand touch targets for accessibility
govargas Nov 3, 2025
e8811a6
fix: increase max zoom level, adjust clustering settings, add smart c…
govargas Nov 3, 2025
7fb0444
fix: contrast improvements for markers
govargas Nov 3, 2025
1ea4889
fix: dark mode beach marker popup contrast
govargas Nov 3, 2025
c4ccd03
fix: language switcher layout fix
govargas Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

package-lock.json
package-lock.json
!frontend/package-lock.json
186 changes: 179 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,185 @@
# Final Project
# 🏖️ BADA – Find Safe Beaches in Sweden

Replace this readme with your own information about your project.
![React](https://img.shields.io/badge/Frontend-React-61DAFB?logo=react&logoColor=white)
![Express](https://img.shields.io/badge/Backend-Express-000000?logo=express&logoColor=white)
![MongoDB](https://img.shields.io/badge/Database-MongoDB-47A248?logo=mongodb&logoColor=white)
![TypeScript](https://img.shields.io/badge/Code-TypeScript-3178C6?logo=typescript&logoColor=white)
![TailwindCSS](https://img.shields.io/badge/UI-Tailwind_CSS-38B2AC?logo=tailwind-css&logoColor=white)
![MapLibre](https://img.shields.io/badge/Maps-MapLibre-4264FB?logo=openstreetmap&logoColor=white)
![i18next](https://img.shields.io/badge/Translations-i18next-26A69A?logo=i18next&logoColor=white)
![TanStack Query](https://img.shields.io/badge/State-TanStack_Query-FF4154?logo=reactquery&logoColor=white)
![Deployed](https://img.shields.io/badge/Deployed-Vercel-000000?logo=vercel&logoColor=white)

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
**BADA** helps beachgoers and families in Sweden find safe, EU-classified bathing waters with real-time quality updates.
It replaces outdated or clunky websites with a **clean, mobile-friendly experience** where you can browse nearby beaches on a map, check water quality, and save your favourites.

## The problem
[Try it out here](https://badaweb.netlify.app/) (deployed on Netlify)

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
---

## View it live
## ✨ Features

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
- 🗺 **Map of all EU-classified beaches in Sweden** (MapLibre + OpenStreetMap)
- 📍 **Find the nearest beach** using your device’s location
- 🔬 **View water quality, classification, and recent test results** (data from HaV)
- ❤️ **Create an account and save favourite beaches** to your profile
- 🌗 **Dark mode** and responsive design (mobile → desktop)
- 🌐 **Multi-language support** (Swedish / English)
- 🔀 **Drag-and-drop sorting for favorites**

---

## 🚀 Tech Stack

**Frontend**

- React 18 + Vite + TypeScript
- React Router
- Zustand (global state)
- TanStack Query (server state & caching)
- Tailwind CSS
- i18next (translations)
- MapLibre GL (maps)
- Custom React Hooks (geolocation, dark mode, outside click)

**Backend**

- Node.js + Express
- MongoDB + Mongoose
- JWT Authentication
- Zod (validation)
- In-memory caching for HaV API responses

**External APIs**

- [HaV Bathing Waters API](https://badplatsen.havochvatten.se/) (official Swedish Agency for Marine and Water Management)
- [MapTiler](https://www.maptiler.com/) (map styles)
- _(Planned)_ OpenWeatherMap for weather and water temperature

---

## 📸 Screenshots

_(Coming soon)_

---

## 🛠 Installation & Setup

Clone the repo and install dependencies:

```bash
git clone https://github.com/govargas/bada.git
cd bada

```

**Backend**

```bash
cd backend
cp .env.example .env.local # then fill in your values
npm install
npm run dev

```

Backend runs on http://localhost:3000

**Frontend**

```bash
cd frontend
cp .env.example .env.local # then fill in your values
npm install
npm run dev

```

Frontend runs on http://localhost:5173

---

## 🔑 Environment Variables

- See .env.example in both backend/ and frontend/.
- Fill in with your own values (MongoDB Atlas, JWT secret, MapTiler key).

---

## 👤 Test User Credentials

- Use these to try the app without registering:

Email: [email protected]

Password: Test1234

This account already has some favourite beaches saved.

---

## 🌍 Deployment

- Frontend: Deployed on Netlify: https://badaweb.netlify.app/
- Backend: Deployed on Vercel → https://bada-backend.vercel.app/api/health

---

## ✅ Requirements Checklist

### Technical Requirements (Grade G)

- ✅ React frontend
- ✅ Node.js + Express backend
- ✅ MongoDB database
- ✅ Authentication (JWT)
- ✅ React Router navigation
- ✅ Global state management (Zustand)
- ✅ ≥2 external libraries (TanStack Query, MapLibre, react-hook-form, i18next, react-hot-toast, @dnd-kit)
- ✅ Custom React hooks (useGeolocation, useOutsideClose, useDarkMode)
- ✅ Responsive (320px → 1600px+)
- ✅ Accessibility features (ARIA labels, skip navigation, semantic HTML, form labels)
- ✅ Clean Code practices

### Visual Requirements

- ✅ Clear structure using box model with consistent margins/paddings
- ✅ Consistent typography across views and breakpoints
- ✅ Cohesive color scheme
- ✅ Mobile-first responsive design
- ✅ Dark mode support
- ✅ Multi-language support (Swedish/English)

### Grade VG Enhancements

- ✅ Error Boundaries
- ✅ Toast notifications
- ✅ Reduced motion support
- ✅ Comprehensive documentation
- ✅ Meta tags for SEO

---

## 🧭 Roadmap

- ✅ Allow notes/tips per beach (e.g. "good for kids") - Planned for future
- Integrate OpenWeatherMap for weather & water temperature
- ✅ Accessibility extras (reduced motion, ARIA live regions) - Implemented
- ✅ Polish with animations and micro-interactions - Toast notifications added
- Filter beaches by classification
- Add user beach photos

---

## 💡 Inspiration & Credits

- Data from the Swedish Agency for Marine and Water Management (HaV)
- Maps powered by OpenStreetMap + MapTiler
- Built during the Technigo Fullstack JavaScript Bootcamp (2025)

---

## 👨‍💻 Author

Created by Talo Vargas, 2025
17 changes: 17 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Server
PORT=3000
NODE_ENV=development

# Database
MONGODB_URI=mongodb+srv://<user>:<password>@<cluster>/<dbname>?retryWrites=true&w=majority

# Auth
JWT_SECRET=replace-with-a-random-secret

# CORS
ALLOWED_ORIGIN=http://localhost:5173

# HaV API
HAV_BASE_URL=https://badplatsen.havochvatten.se/badplatsen/api
HAV_V2_BASE=https://api.havochvatten.se/bathingwaters/v2
HAV_USER_AGENT=BADA-App/1.0 (contact: my@email)
8 changes: 0 additions & 8 deletions backend/README.md

This file was deleted.

3 changes: 3 additions & 0 deletions backend/dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare const app: import("express-serve-static-core").Express;
export default app;
//# sourceMappingURL=index.d.ts.map
1 change: 1 addition & 0 deletions backend/dist/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions backend/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/dist/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions backend/dist/lib/cache.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export declare class SimpleCache {
private defaultTtlMs;
private store;
constructor(defaultTtlMs?: number);
get<T>(key: string): T | undefined;
set<T>(key: string, value: T, ttlMs?: number): void;
}
export declare const cache: SimpleCache;
//# sourceMappingURL=cache.d.ts.map
1 change: 1 addition & 0 deletions backend/dist/lib/cache.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions backend/dist/lib/cache.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/dist/lib/cache.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions backend/dist/lib/db.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import mongoose from "mongoose";
export declare function connectDB(): Promise<typeof mongoose>;
//# sourceMappingURL=db.d.ts.map
1 change: 1 addition & 0 deletions backend/dist/lib/db.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading