{"id":25422259,"url":"https://github.com/teeldinho/places","last_synced_at":"2026-04-13T21:03:54.919Z","repository":{"id":277321727,"uuid":"931184212","full_name":"Teeldinho/places","owner":"Teeldinho","description":"Places is a Next.js 15 web application that allows users to browse property listings on an interactive map, with features for filtering, sorting, and viewing property details. It utilizes Supabase for data storage, nuqs for URL-based state management, and Maplibre GL JS for map rendering.","archived":false,"fork":false,"pushed_at":"2025-02-13T10:08:04.000Z","size":10457,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-13T10:32:57.422Z","etag":null,"topics":["maplibre","maps","next15","nuqs","supabase","zod"],"latest_commit_sha":null,"homepage":"https://places.teeldinho.co.za","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Teeldinho.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-11T21:14:30.000Z","updated_at":"2025-02-13T10:08:07.000Z","dependencies_parsed_at":"2025-02-13T10:44:05.799Z","dependency_job_id":null,"html_url":"https://github.com/Teeldinho/places","commit_stats":null,"previous_names":["teeldinho/places"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Teeldinho%2Fplaces","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Teeldinho%2Fplaces/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Teeldinho%2Fplaces/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Teeldinho%2Fplaces/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Teeldinho","download_url":"https://codeload.github.com/Teeldinho/places/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239197265,"owners_count":19598346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["maplibre","maps","next15","nuqs","supabase","zod"],"created_at":"2025-02-16T21:24:08.997Z","updated_at":"2026-04-13T21:03:54.913Z","avatar_url":"https://github.com/Teeldinho.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Places\n\nPlaces is a web application for browsing property listings on a map of Dubai. The core idea is to make map exploration, search, and sorting fast, shareable, and practical for large datasets.\n\n## Project Overview\n\nPlaces provides a split experience:\n\n- a map with interactive pins and popups\n- a virtualized sidebar list for mapped/unmapped properties\n- URL-driven search and sorting so state is shareable/bookmarkable\n\n![Main Image](public/assets/main-image-a.png)\n\n## Tech Stack\n\n### Frontend\n\n- **Next.js 15.1.12 + React 19.2.1**: Server Components + client interactivity.\n- **nuqs**: URL query parameters as the main UI state store.\n- **React Hook Form + Zod**: Typed form state and validation.\n- **Tailwind CSS v4**: Utility-first styling.\n- **DaisyUI 5.5.18 (stable)**: UI primitives built on Tailwind.\n- **@vis.gl/react-maplibre + maplibre-gl**: Interactive map rendering.\n- **@tanstack/react-virtual**: Efficient rendering for long property lists.\n\n### Backend\n\n- **Supabase**: Primary data store.\n- **Next.js server functions/actions**: Property query and mutation boundaries.\n\n### Testing\n\n- **Vitest + Testing Library + jsdom**: Behavior-oriented unit/component testing.\n\n## Key Features\n\n- **Interactive Map**: Property markers with selection and contextual popup cards.\n- **Sidebar Property List**: Mapped and unmapped tabs with virtualized rendering.\n- **Search**: URL-driven query state.\n- **Sort**: URL-driven sorting by property name, community, and subcommunity.\n- **Add/Edit Property**: Drawer-based editing flow with validated form inputs.\n- **Responsive Layout**: Desktop split-pane + mobile drawer experience.\n\n## Architectural Decisions\n\n### URL as State Store (`nuqs`)\n\nThe app keeps map/list state in URL params so users can share and restore exact UI state:\n\n- selected property\n- map coordinates/zoom\n- search query\n- sorting options\n\nZod schemas validate URL state for predictable behavior.\n\n### Separation of Concerns\n\nThe project now follows a clear component boundary pattern:\n\n- `ui/` components focus on rendering and composition\n- `model/hooks/` owns interaction and state orchestration\n- `model/helpers/` contains pure model-support logic\n- `config/` stores constants and UI tokens\n\nThis keeps components presentational while making behavior easy to test.\n\n### Current Component Structure (non-FSD, pragmatic)\n\n```text\nsrc/components/\n  map/\n    ui/\n    model/\n      hooks/\n      helpers/\n    config/\n    __tests__/\n  properties/\n    ui/\n    model/\n      hooks/\n      helpers/\n    config/\n    __tests__/\n```\n\n### Supabase SSR Integration\n\nSupabase clients are split by runtime:\n\n- browser client (`src/utils/supabase/client.ts`)\n- server client (`src/utils/supabase/server.ts`)\n- request/session refresh flow through `proxy.ts` + `updateSession`\n\nEnvironment key resolution is compatibility-first and checks:\n\n1. `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY`\n2. `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY`\n3. `NEXT_PUBLIC_SUPABASE_ANON_KEY`\n\n### Data Flow\n\nThe app keeps a schema-first mapping pipeline:\n\n1. validate external data with Zod\n2. normalize DTO shapes\n3. map into render-friendly RTOs\n\nThis keeps UI resilient when data quality is inconsistent.\n\n## Recent Improvements\n\n- Upgraded and stabilized UI/tooling stack (DaisyUI stable, latest Supabase SSR libs).\n- Improved sort behavior for direction-only URL states.\n- Fixed dropdown placement/padding and active-state readability.\n- Fixed modal drawer id collisions that caused incorrect dialog behavior.\n- Improved query failure diagnostics and development fallback handling.\n- Expanded test coverage for extracted hooks/helpers and sort/dropdown behavior.\n\n## Security Note (React RSC Advisory)\n\nTo address the React Server Components security advisory, this project is pinned to patched versions:\n\n- `next@15.1.12`\n- `react@19.2.1`\n- `react-dom@19.2.1`\n\n## Testing\n\nRun tests:\n\n```bash\nnpm run test\n```\n\nWatch mode:\n\n```bash\nnpm run test:watch\n```\n\nCoverage:\n\n```bash\nnpm run test:coverage\n```\n\n## Areas of Improvement\n\n- **Geocoding**: Replace fallback/random coordinate behavior with deterministic geocoding.\n- **Data quality contracts**: Tighten schema guarantees for production data.\n- **Search depth**: Add richer search dimensions beyond current text fields.\n- **Mutation UX**: Continue polishing add/edit flows and edge-case handling.\n\n## Getting Started\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Create `.env.local` with Supabase values:\n\n   ```bash\n   NEXT_PUBLIC_SUPABASE_URL=...\n   NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=...\n   ```\n\n   (Alternative key names are supported by the app, but the above is the current default in this repo.)\n\n3. Start development server:\n\n   ```bash\n   npm run dev\n   ```\n\n   Optional Turbopack mode:\n\n   ```bash\n   npm run dev:turbo\n   ```\n\n4. Build for production:\n\n   ```bash\n   npm run build\n   ```\n\n5. Start production server:\n\n   ```bash\n   npm start\n   ```\n\n## Screenshots\n\n![Mapped Properties - Home Page](public/assets/main-image-a.png)\n![Unmapped Properties](public/assets/image-1-a.png)\n![Search Results](public/assets/image-2-a.png)\n![Database Table](public/assets/image-5-a.png)\n![Add a Property](public/assets/image-3-a.png)\n\n## Conclusion\n\nPlaces remains focused on practical, map-first property browsing, now with clearer component boundaries, stronger runtime resilience, improved dropdown/modal behavior, and broader automated test coverage.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteeldinho%2Fplaces","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteeldinho%2Fplaces","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteeldinho%2Fplaces/lists"}