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.
Try it out here (deployed on Netlify)
- 🗺 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)
- 🔍 Real-time beach search with autocomplete dropdown
- ❤️ Create an account and save favourite beaches to your profile
- 🔀 Drag-and-drop sorting for favorites
- 🌊 3D animated backgrounds (WebGL water simulation in dark mode, sand texture in light mode)
- 🎨 Glassmorphism UI with backdrop blur effects
- 🌗 Dark mode and responsive design (mobile → desktop)
- 🌐 Multi-language support (Swedish / English)
- 📚 API Documentation (Swagger UI at
/api/docs)
Frontend
- React 18 + Vite + TypeScript
- React Router v7
- Zustand (global state)
- TanStack Query (server state & caching)
- Tailwind CSS v4 (with CSS-based theme system)
- i18next (translations)
- MapLibre GL (maps)
- Three.js ecosystem (@react-three/fiber, @react-three/drei) for 3D backgrounds
- @dnd-kit (drag-and-drop)
- react-hook-form + Zod (form validation)
- react-hot-toast (notifications)
Custom React Hooks
useGeolocation– Device location accessuseOutsideClose– Close popovers on outside click/Escape keyuseDarkMode– Theme toggle with persistenceusePrefersReducedMotion– Respect user's motion preferencesuseBeaches– Beach data fetching
Backend
- Node.js + Express 5
- MongoDB + Mongoose
- JWT Authentication
- Zod (validation)
- In-memory caching for HaV API responses
- Swagger UI (API documentation)
External APIs
- HaV Bathing Waters API (official Swedish Agency for Marine and Water Management)
- MapTiler (map styles)
BADA is built with accessibility in mind:
- Skip navigation link – Jump directly to main content
- ARIA labels – Proper labeling of interactive elements
- ARIA live regions – Screen reader announcements for dynamic content
- ARIA busy states – Loading indicators for assistive technology
- Keyboard navigation – Full keyboard support with focus management
- Escape key handling – Close menus and return focus to trigger
- Focus visible rings – Clear focus indicators
- Reduced motion support – Respects
prefers-reduced-motion(both CSS and JS) - Semantic HTML – Proper document structure with roles
- Dynamic lang attribute – HTML lang updates with language selection
- Accessible notifications – Toast messages with proper ARIA live regions
(Coming soon)
Clone the repo and install dependencies:
git clone https://github.com/govargas/bada.git
cd badaBackend
cd backend
cp .env.example .env.local # then fill in your values
npm install
npm run devBackend runs on http://localhost:3000
API Documentation available at http://localhost:3000/api/docs
Frontend
cd frontend
cp .env.example .env.local # then fill in your values
npm install
npm run devFrontend runs on http://localhost:5173
- See .env.example in both backend/ and frontend/.
- Fill in with your own values (MongoDB Atlas, JWT secret, MapTiler key).
- Use these to try the app without registering:
Email: smoke@test.com
Password: Test1234
This account already has some favourite beaches saved.
- Frontend: Deployed on Netlify: https://badaweb.netlify.app/
- Backend: Deployed on Vercel → https://bada-backend.vercel.app/api/health
- ✅ React frontend
- ✅ Node.js + Express backend
- ✅ MongoDB database
- ✅ Authentication (JWT)
- ✅ React Router navigation
- ✅ Global state management (Zustand)
- ✅ ≥2 external libraries (TanStack Query, MapLibre, Three.js, react-hook-form, i18next, react-hot-toast, @dnd-kit)
- ✅ Custom React hooks (useGeolocation, useOutsideClose, useDarkMode, usePrefersReducedMotion, useBeaches)
- ✅ Responsive (320px → 1600px+)
- ✅ Accessibility features (comprehensive a11y implementation)
- ✅ Clean Code practices
- ✅ Clear structure using box model with consistent margins/paddings
- ✅ Consistent typography across views and breakpoints
- ✅ Cohesive color scheme with CSS design tokens
- ✅ Mobile-first responsive design
- ✅ Dark mode support with 3D backgrounds
- ✅ Multi-language support (Swedish/English)
- ✅ Glassmorphism UI design system
- ✅ Error Boundaries
- ✅ Toast notifications with a11y
- ✅ Reduced motion support
- ✅ Comprehensive documentation
- ✅ Meta tags for SEO (Open Graph, Twitter Cards)
- ✅ API Documentation (Swagger UI)
- ✅ Performance optimizations (lazy-loaded 3D backgrounds)
- ✅ 3D animated backgrounds (WebGL water/sand)
- ✅ Enhanced glassmorphism UI
- ✅ Header search with autocomplete
- ✅ Comprehensive accessibility implementation
- ✅ API documentation with Swagger
- ✅ Performance optimization (deferred 3D loading)
- ✅ Focus management and keyboard navigation
- 🔄 Integrate OpenWeatherMap for weather & water temperature
- 🔄 Filter beaches by classification
- 🔄 Add user beach photos
- 🔄 Allow notes/tips per beach (e.g. "good for kids")
- 🔄 PWA support with offline capability
- Data from the Swedish Agency for Marine and Water Management (HaV)
- Maps powered by OpenStreetMap + MapTiler
- Built during the Technigo Fullstack JavaScript Bootcamp (2025)
Created by Talo Vargas, 2025