Skip to content

RafiulPaceProjects/React

Repository files navigation

Maps Explorer (React + Vite + Leaflet)

Modern React app for interactive mapping with a friendly chat side panel. Built with Vite, Leaflet, and a compact UI layer.

Features

  • Interactive map (Leaflet) with custom styled markers and smooth resize handling
  • Floating chat input over the map with keyboard shortcuts (Enter/Shift+Enter)
  • Chat sidebar with message list, basic stats, and delete actions
  • Clean header with gradient branding and responsive navigation
  • ErrorBoundary to catch runtime errors with a friendly fallback
  • LoadingSpinner with accessible labels
  • Simple design utilities (Button, Input, Icon) and small helper library

Tech stack

  • React 18, Vite 5
  • Leaflet + react-leaflet
  • Tailwind CSS (via CDN for utilities) plus minimal custom CSS in styles/globals.css

Quick start

Requirements

  • Node 18+ and npm 9+

Install and run (Windows PowerShell)

# Install deps
npm install

# Start dev server (Vite prints the local URL)
npm run dev

# Build for production (outputs to dist/)
npm run build

# Preview the production build
npm run preview

If the dev port is already in use

Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
npm run dev

Project structure

src/
  app.jsx                    # App shell (Header + MainContent) wrapped with ErrorBoundary
  main.jsx                   # React root (StrictMode)
  components/
    layout/
      Header.jsx            # Gradient header with responsive nav
      MainContent.jsx       # Wires Map + Sidebar + FloatingChatInput
    ui/
      MapContainer.jsx      # Leaflet map with custom markers + ResizeObserver helper
      Sidebar.jsx           # Chat list + stats (includes a small inline ChatMessage component)
      FloatingChatInput.jsx # Overlay chat input (z-40) with validation and loading state
      LoadingSpinner.jsx    # Reusable spinner
      ErrorBoundary.jsx     # Error fallback UI
      common.jsx            # Button, Input, Icon primitives
  hooks/
    useMessages.js          # Message state (add/remove/update) + memoized stats
  styles/
    globals.css             # Minimal global styles/animations/utilities
  utils/
    constants.js            # Centralized constants (layout, placeholders, mock data)
    helpers.js              # Small helpers (ids, formatting, classNames, validation)

index.html                  # HTML template, Tailwind CDN, and app mount
vite.config.js              # Vite config (React plugin)
tailwind.config.js          # Tailwind config (kept for future, CDN used at runtime)
postcss.config.js           # PostCSS config (optional future pipeline)

How it works

High level flow

  • App renders the layout: Header on top and MainContent in a full-height region.
  • MainContent composes: MapContainer (left), Sidebar (right), and FloatingChatInput overlayed on the map.
  • useMessages manages message state; FloatingChatInput calls onSendMessage; Sidebar displays messages and delete actions.
  • A simple mock “bot” reply in MainContent simulates responses.

Layout and sizing

  • The main region uses height: calc(100vh - 4rem) (header is 4rem) to ensure the map fills the screen.
  • MapContainer is absolutely positioned to fill its parent (inset-0, 100% width/height).
  • The floating chat input is positioned with absolute bottom-4 left-4 right-4 and elevated via z-40.

Configuration

Key files

  • src/utils/constants.js — sizes, z-index, placeholders, mock marker data.
  • src/utils/helpers.jsvalidateTextInput, classNames, id generation, etc.
  • tailwind.config.js — available if you later switch from CDN utilities to a compiled Tailwind pipeline.

Tailwind usage

  • The project currently uses Tailwind via CDN (see index.html).
  • styles/globals.css adds minimal utilities/animations and is automatically applied via the HTML <style> rules and class utilities; if you prefer a compiled Tailwind setup, wire globals.css into main.jsx and run a PostCSS/Tailwind build.

Components overview

  • Header — gradient background, responsive nav, accessible controls.
  • MapContainerreact-leaflet map, custom divIcon markers, ResizeObserver to keep the map sized.
  • FloatingChatInput — validation (validateTextInput), loading state, Enter to send / Shift+Enter new line.
  • Sidebar — message list, stats, empty state; includes an inline ChatMessage for simplicity.
  • ErrorBoundary — friendly fallback UI with retry/refresh.
  • LoadingSpinner — accessible spinner with optional message.

Troubleshooting

Map is a tiny strip or blank tiles

  • Ensure the map’s container has a real pixel height. This repo sets the main area height with calc(100vh - 4rem).
  • Check console for Leaflet CSS: import 'leaflet/dist/leaflet.css' is in MapContainer.jsx.

Floating chat box isn’t visible / can’t click

  • It must be above the map: wrapper uses z-40 and pointer-events-none; the form uses pointer-events-auto.
  • Hard refresh the browser (Ctrl+F5) to clear stale styles.

Dev server says port is in use

Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
npm run dev

Build works but preview looks different from dev

  • The CDN Tailwind is consistent across dev/preview, but if you move to compiled Tailwind, ensure the CSS is included in index.html or imported in main.jsx.

Scripts

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview",
  "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
  "format": "prettier --write \"src/**/*.{js,jsx,css,md}\""
}

Next steps (nice-to-haves)

  • Replace mock bot responses with a real backend
  • Persist messages to localStorage or server
  • Switch from Tailwind CDN to compiled Tailwind for full control and purging
  • Theme toggle (light/dark)
  • Map layer switcher and search integration

License

Private project (no license specified).


Points of Concern (what to watch out for)

  1. Map height/layout glitches
  • Leaflet must render into a container with a fixed pixel height. This project uses h-[calc(100vh-4rem)] on the main container and absolute inset-0 for the map.
  • If you change header height, keep calc(100vh - HEADER_HEIGHT) in app.jsx in sync.
  1. Floating Chat overlay click-through
  • Wrapper uses pointer-events-none and form uses pointer-events-auto so only the input captures clicks. If you add buttons outside the form, they won’t receive clicks unless you also make them pointer-events-auto.
  1. ChatMessage export/import
  • We inlined a minimal ChatMessage within Sidebar.jsx to avoid past bundler confusion. If you re-extract it, prefer a simple default export and import it as import ChatMessage from './ChatMessage'.
  1. Tailwind via CDN vs compiled Tailwind
  • CDN is great for speed and fewer build steps, but compiled Tailwind gives Purge/Design System scale. If you switch, import styles/globals.css in main.jsx and configure tailwind.config.js content paths.
  1. React-Leaflet SSR/build caveats
  • This app is client-only. Don’t render react-leaflet components on the server. Keep Leaflet imports inside client modules.
  1. ErrorBoundary scope
  • Only wrap the app once at a high level. Nesting multiple error boundaries around Leaflet/map nodes may hide real errors.
  1. Performance with large message lists
  • Virtualization is not implemented. If messages grow large, add windowing (e.g., react-virtualized) to keep scrolling smooth.

Tips & Tricks (simplify code and scale sanely)

State and hooks

  • Keep useMessages as the single source of truth; expose only minimal API: messages, addMessage, removeMessage, messageStats.
  • Wrap handlers with useCallback only when passing to children or when dependencies are stable; avoid unnecessary memoization.
  • Derive state, don’t duplicate it (e.g., compute message counts via useMemo).

Components

  • Prefer small presentational components with clear props. Co-locate minimal components (like ChatMessage) next to their only consumer (Sidebar) until they’re reused.
  • Centralize class combinations using the classNames helper; avoid string concatenation logic spread across components.
  • Keep primitives (Button, Input, Icon) prop-light. Add variants cautiously and document defaults.

Styling

  • Use utilities for 90% of cases. When a style repeats 3+ times, abstract it into a small component or class.
  • Z-index discipline: define in constants.js (e.g., HEADER=50, MAP=10, FLOATING_INPUT=40) and reference them (or Tailwind’s z classes) consistently.

Leaflet specifics

  • Always import 'leaflet/dist/leaflet.css' where the map mounts (MapContainer.jsx).
  • Call invalidateSize() when the container may have changed size; the included ResizeObserver handles most cases.
  • Use divIcon or SVG markers for consistent theming; keep icon size/anchor predictable.

UX and accessibility

  • Provide aria-labels for icons and buttons; keep button text or accessible labels.
  • Show non-blocking validation errors (like the input error area in FloatingChatInput).

Scalability patterns

  • Introduce a feature folder if chat grows: features/chat/{components,hooks,services}.
  • Add a persistence layer (localStorage now, server later) behind an interface (e.g., messageRepository.save/load).
  • For async calls, wrap them in a small service module; keep components thin.

Testing ideas

  • Unit test helpers.js (validation, classNames, createMessage) and useMessages (add/remove/update).
  • Snapshot test small presentational components (ChatMessage, Button).

Deployment

  • npm run build produces dist/. Serve with any static host (GitHub Pages, Netlify, Vercel). Don’t forget to include the base path if your host uses subpaths.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors