Skip to content

oliomap/PlanB

Repository files navigation

PlanB

Conversational trip planning with a live MapLibre preview.

Quick start

npm install
npm run dev

Then visit http://localhost:3000 and start describing your travel goals.

Tech stack

  • Next.js 14 (App Router) — modern routing primitives and server actions.
  • TypeScript — type-safety across UI and API boundaries.
  • TailwindCSS — rapid design iteration while keeping the UI consistent.
  • MapLibre GL JS — open-source mapping with an OSM demo style (no keys).

File tree

app/
  api/plan/route.ts      # Deterministic planner stub
  layout.tsx             # Global HTML shell
  page.tsx               # Chat + map layout
  globals.css            # Tailwind entrypoint
components/
  ChatPanel.tsx          # ChatGPT-inspired UI
  MapView.tsx            # MapLibre wrapper
lib/
  types.ts               # Shared data contracts
next.config.ts           # Next.js configuration
postcss.config.mjs       # Tailwind/PostCSS config
public/                  # Static assets
README.md

Running locally

  1. Install dependencies with npm install.
  2. Start the dev server via npm run dev.
  3. The planner stub is deterministic; refresh the page or tweak your prompt to see different destinations.

Note: The Codespaces-provided proxy occasionally blocks npm install. If you see 403 Forbidden errors, try re-running the command or using a personal network.

Deployment tips

  • The project is Next.js ready for Vercel, Netlify, or any Node 18+ platform.
  • Set the NEXT_PUBLIC_MAP_STYLE env var (not yet used) once you migrate to a custom map provider.
  • Tailwind is already configured; run npm run build before deploying to catch type issues.

Extending with a real LLM

Replace the stub in app/api/plan/route.ts with a call to your planner model. Example pseudo-flow using OpenAI:

import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export async function POST(request: Request) {
  const { messages } = await request.json();
  const completion = await client.responses.create({
    model: "gpt-4o-mini",
    input: messages.map((message) => ({
      role: message.role,
      content: message.content
    }))
  });

  // Parse completion, map to pins, and return JSON.
}

Map customization

  • Update the style URL in components/MapView.tsx to point to MapTiler, Mapbox, or self-hosted tiles.
  • Add extra controls (geolocate, scale bar) via MapLibre's control APIs inside the first useEffect hook.

Troubleshooting

  • Map not rendering: Ensure maplibre-gl CSS is imported (already done in MapView.tsx).
  • CORS issues: When switching providers, confirm the tile server allows requests from your domain.
  • Tailwind classes missing: Tailwind purges unused styles based on content globs in tailwind.config.ts.
  • Streaming needs: Replace the fetch call in ChatPanel.tsx with an SSE or websockets client; state updates are already centralized.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors