Skip to content

Teeldinho/places

Repository files navigation

Places

Places 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.

Project Overview

Places provides a split experience:

  • a map with interactive pins and popups
  • a virtualized sidebar list for mapped/unmapped properties
  • URL-driven search and sorting so state is shareable/bookmarkable

Main Image

Tech Stack

Frontend

  • Next.js 15.1.12 + React 19.2.1: Server Components + client interactivity.
  • nuqs: URL query parameters as the main UI state store.
  • React Hook Form + Zod: Typed form state and validation.
  • Tailwind CSS v4: Utility-first styling.
  • DaisyUI 5.5.18 (stable): UI primitives built on Tailwind.
  • @vis.gl/react-maplibre + maplibre-gl: Interactive map rendering.
  • @tanstack/react-virtual: Efficient rendering for long property lists.

Backend

  • Supabase: Primary data store.
  • Next.js server functions/actions: Property query and mutation boundaries.

Testing

  • Vitest + Testing Library + jsdom: Behavior-oriented unit/component testing.

Key Features

  • Interactive Map: Property markers with selection and contextual popup cards.
  • Sidebar Property List: Mapped and unmapped tabs with virtualized rendering.
  • Search: URL-driven query state.
  • Sort: URL-driven sorting by property name, community, and subcommunity.
  • Add/Edit Property: Drawer-based editing flow with validated form inputs.
  • Responsive Layout: Desktop split-pane + mobile drawer experience.

Architectural Decisions

URL as State Store (nuqs)

The app keeps map/list state in URL params so users can share and restore exact UI state:

  • selected property
  • map coordinates/zoom
  • search query
  • sorting options

Zod schemas validate URL state for predictable behavior.

Separation of Concerns

The project now follows a clear component boundary pattern:

  • ui/ components focus on rendering and composition
  • model/hooks/ owns interaction and state orchestration
  • model/helpers/ contains pure model-support logic
  • config/ stores constants and UI tokens

This keeps components presentational while making behavior easy to test.

Current Component Structure (non-FSD, pragmatic)

src/components/
  map/
    ui/
    model/
      hooks/
      helpers/
    config/
    __tests__/
  properties/
    ui/
    model/
      hooks/
      helpers/
    config/
    __tests__/

Supabase SSR Integration

Supabase clients are split by runtime:

  • browser client (src/utils/supabase/client.ts)
  • server client (src/utils/supabase/server.ts)
  • request/session refresh flow through proxy.ts + updateSession

Environment key resolution is compatibility-first and checks:

  1. NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY
  2. NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
  3. NEXT_PUBLIC_SUPABASE_ANON_KEY

Data Flow

The app keeps a schema-first mapping pipeline:

  1. validate external data with Zod
  2. normalize DTO shapes
  3. map into render-friendly RTOs

This keeps UI resilient when data quality is inconsistent.

Recent Improvements

  • Upgraded and stabilized UI/tooling stack (DaisyUI stable, latest Supabase SSR libs).
  • Improved sort behavior for direction-only URL states.
  • Fixed dropdown placement/padding and active-state readability.
  • Fixed modal drawer id collisions that caused incorrect dialog behavior.
  • Improved query failure diagnostics and development fallback handling.
  • Expanded test coverage for extracted hooks/helpers and sort/dropdown behavior.

Security Note (React RSC Advisory)

To address the React Server Components security advisory, this project is pinned to patched versions:

  • next@15.1.12
  • react@19.2.1
  • react-dom@19.2.1

Testing

Run tests:

npm run test

Watch mode:

npm run test:watch

Coverage:

npm run test:coverage

Areas of Improvement

  • Geocoding: Replace fallback/random coordinate behavior with deterministic geocoding.
  • Data quality contracts: Tighten schema guarantees for production data.
  • Search depth: Add richer search dimensions beyond current text fields.
  • Mutation UX: Continue polishing add/edit flows and edge-case handling.

Getting Started

  1. Install dependencies:

    npm install
  2. Create .env.local with Supabase values:

    NEXT_PUBLIC_SUPABASE_URL=...
    NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=...

    (Alternative key names are supported by the app, but the above is the current default in this repo.)

  3. Start development server:

    npm run dev

    Optional Turbopack mode:

    npm run dev:turbo
  4. Build for production:

    npm run build
  5. Start production server:

    npm start

Screenshots

Mapped Properties - Home Page Unmapped Properties Search Results Database Table Add a Property

Conclusion

Places 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.

About

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.

Topics

Resources

Stars

Watchers

Forks

Contributors