From dbbf7638a635542ed083822c191a5aa771dceea6 Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sat, 5 Sep 2026 17:15:55 +0000 Subject: [PATCH] Build FloodIntel intelligence, map, and safety pages --- frontend/app/alerts/page.tsx | 2 + frontend/app/assistant/page.tsx | 2 + frontend/app/emergency/page.tsx | 3 + frontend/app/globals.css | 27 +- frontend/app/history/page.tsx | 3 + frontend/app/layout.tsx | 28 +- frontend/app/map/page.tsx | 4 + frontend/app/page.tsx | 939 +---------------------- frontend/app/report/page.tsx | 4 + frontend/app/risk/page.tsx | 3 + frontend/components/AIChat.tsx | 4 + frontend/components/AppShell.tsx | 4 + frontend/components/FloodMap.tsx | 5 + frontend/components/LanguageSelector.tsx | 3 + frontend/components/LocationSearch.tsx | 3 + frontend/components/OfflineBanner.tsx | 3 + frontend/components/StatusCard.tsx | 3 + frontend/lib/api.ts | 66 +- frontend/lib/types.ts | 48 +- frontend/lib/useFloodData.ts | 6 + frontend/package-lock.json | 114 --- 21 files changed, 76 insertions(+), 1198 deletions(-) create mode 100644 frontend/app/assistant/page.tsx create mode 100644 frontend/app/risk/page.tsx create mode 100644 frontend/components/AppShell.tsx create mode 100644 frontend/components/LocationSearch.tsx create mode 100644 frontend/components/StatusCard.tsx create mode 100644 frontend/lib/useFloodData.ts diff --git a/frontend/app/alerts/page.tsx b/frontend/app/alerts/page.tsx index e69de29..a6f2cb1 100644 --- a/frontend/app/alerts/page.tsx +++ b/frontend/app/alerts/page.tsx @@ -0,0 +1,2 @@ +import AppShell from "@/components/AppShell"; import { BellOff } from "lucide-react"; +export default function AlertsPage(){return

Alerts

Active flood alerts

No live alerts available

No live alerts are currently available from the connected backend. Check official local emergency communications for urgent instructions.

} diff --git a/frontend/app/assistant/page.tsx b/frontend/app/assistant/page.tsx new file mode 100644 index 0000000..7afdbc3 --- /dev/null +++ b/frontend/app/assistant/page.tsx @@ -0,0 +1,2 @@ +import AppShell from "@/components/AppShell"; import AIChat from "@/components/AIChat"; +export default function AssistantPage(){return
} diff --git a/frontend/app/emergency/page.tsx b/frontend/app/emergency/page.tsx index e69de29..28fa4ea 100644 --- a/frontend/app/emergency/page.tsx +++ b/frontend/app/emergency/page.tsx @@ -0,0 +1,3 @@ +import AppShell from "@/components/AppShell"; import { TriangleAlert } from "lucide-react"; +const steps=["Move to higher ground when flooding is possible.","Avoid walking or driving through floodwater.","Follow evacuation instructions from local authorities.","Keep essential documents, medicines, water, and a charged phone ready.","Turn off electricity only if it is safe to do so."]; +export default function EmergencyPage(){return

Emergency guidance

Stay safe during flooding

For immediate danger, follow official emergency instructions and contact locally published emergency services. FloodIntel does not invent emergency contact numbers.

Safety checklist

    {steps.map((s,i)=>
  1. {i+1}{s}
  2. )}

Evacuation guidance

Use routes designated by local authorities. Never enter a closed road, bridge, drain, or fast-moving water. Help children, older adults, and people who may need assistance move to safety early.

Emergency contacts

Data unavailable. Use official local government and disaster-management channels for verified contact details.

} diff --git a/frontend/app/globals.css b/frontend/app/globals.css index a2dc41e..7cf37e1 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -1,26 +1,3 @@ @import "tailwindcss"; - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; -} +:root { --background:#061423; --foreground:#e8f4ff; } +* { box-sizing:border-box; } html { background:var(--background); } body { margin:0; background:var(--background); color:var(--foreground); font-family:Arial, Helvetica, sans-serif; } button, input, select { font:inherit; } button { cursor:pointer; } button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible { outline:2px solid #67e8f9; outline-offset:3px; } .card { border:1px solid rgb(255 255 255 / .12); border-radius:1rem; background:rgb(255 255 255 / .045); padding:1.25rem; } .eyebrow { color:#67e8f9; font-size:.7rem; font-weight:700; letter-spacing:.16em; text-transform:uppercase; } dt { color:#94a3b8; font-size:.75rem; } dd { margin-top:.2rem; color:#f1f5f9; font-weight:600; } diff --git a/frontend/app/history/page.tsx b/frontend/app/history/page.tsx index e69de29..10df032 100644 --- a/frontend/app/history/page.tsx +++ b/frontend/app/history/page.tsx @@ -0,0 +1,3 @@ +"use client"; +import AppShell from "@/components/AppShell"; import { Search } from "lucide-react"; import { useState } from "react"; +export default function HistoryPage(){const [query,setQuery]=useState("");return

History

Historical flood events

No data available

The connected backend does not currently provide historical flood-event data. Your search has not been applied to unavailable data.

} diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 9852c15..245db7b 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -1,29 +1,5 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; - -export default function RootLayout({ children }: LayoutProps<"/">) { - return ( - - {children} - - ); -} +export const metadata: Metadata = { title: "FloodIntel | Flood Intelligence", description: "AI-powered flood intelligence and early warning platform" }; +export default function RootLayout({ children }: { children: React.ReactNode }) { return
{children}
; } diff --git a/frontend/app/map/page.tsx b/frontend/app/map/page.tsx index e69de29..405be40 100644 --- a/frontend/app/map/page.tsx +++ b/frontend/app/map/page.tsx @@ -0,0 +1,4 @@ +"use client"; +import dynamic from "next/dynamic"; import { useSearchParams } from "next/navigation"; import AppShell from "@/components/AppShell"; import LocationSearch from "@/components/LocationSearch"; +const FloodMap=dynamic(()=>import("@/components/FloodMap"),{ssr:false,loading:()=>
Loading interactive map…
}); +export default function MapPage(){const p=useSearchParams();const lat=Number(p.get("lat")),lng=Number(p.get("lng"));const valid=Number.isFinite(lat)&&Number.isFinite(lng);const query=p.get("q");return

Live map

Flood intelligence map

OpenStreetMap with your selected position. Place search requires a verified geocoding service, which is not configured.

} diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 20779cc..b0b1919 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -1,937 +1,4 @@ "use client"; - -import { useState } from "react"; - -type RiskLevel = "Low" | "Moderate" | "High" | "Severe"; - -const navItems = [ - "Overview", - "Risk Map", - "Alerts", - "History", - "Reports", -]; - -const languages = [ - "English", - "తెలుగు", - "हिन्दी", - "தமிழ்", - "ಕನ್ನಡ", -]; - -const riskFactors = [ - { name: "Rainfall", value: 78, level: "High" }, - { name: "Water proximity", value: 55, level: "Medium" }, - { name: "Terrain / elevation", value: 32, level: "Low" }, - { name: "Historical flooding", value: 61, level: "Medium" }, -]; - -const alerts = [ - { - title: "Heavy rainfall watch", - location: "Selected region", - time: "Monitoring", - severity: "High", - }, - { - title: "Water level observation", - location: "Nearby waterbody", - time: "Monitoring", - severity: "Moderate", - }, - { - title: "Flood preparedness advisory", - location: "Local area", - time: "Active", - severity: "Info", - }, -]; - -const historicalEvents = [ - { year: "2025", event: "Major rainfall event", impact: "High" }, - { year: "2024", event: "Urban inundation", impact: "Moderate" }, - { year: "2023", event: "River flooding", impact: "High" }, -]; - -export default function Home() { - const [location, setLocation] = useState(""); - const [language, setLanguage] = useState("English"); - const [riskLevel] = useState("Moderate"); - const [showLanguages, setShowLanguages] = useState(false); - const [mobileMenu, setMobileMenu] = useState(false); - const [assistantOpen, setAssistantOpen] = useState(false); - - const riskStyles = { - Low: { - badge: "bg-emerald-400/10 text-emerald-300 border-emerald-400/20", - text: "text-emerald-400", - }, - Moderate: { - badge: "bg-amber-400/10 text-amber-300 border-amber-400/20", - text: "text-amber-400", - }, - High: { - badge: "bg-orange-400/10 text-orange-300 border-orange-400/20", - text: "text-orange-400", - }, - Severe: { - badge: "bg-red-400/10 text-red-300 border-red-400/20", - text: "text-red-400", - }, - }; - - const currentRisk = riskStyles[riskLevel]; - - return ( -
- {/* ========================================================= */} - {/* HEADER */} - {/* ========================================================= */} - -
-
- {/* Brand */} - -
- F -
- -
-
- FloodIntel -
-
- Flood Intelligence Platform -
-
-
- - {/* Desktop navigation */} - - - {/* Header actions */} -
-
- - - {showLanguages && ( -
- {languages.map((item) => ( - - ))} -
- )} -
- - - - -
-
- - {/* Mobile navigation */} - {mobileMenu && ( -
- -
- )} -
- - {/* ========================================================= */} - {/* HERO */} - {/* ========================================================= */} - -
- {/* Background decoration */} -
-
-
-
-
- -
-
- {/* Status */} -
- - Flood intelligence platform - • - India -
- -

- Know the risk. -
- - Act before the flood. - -

- -

- FloodIntel brings together rainfall, satellite observations, - terrain, water bodies and historical flood information to help - communities understand flood risk and respond earlier. -

- - {/* Location search */} -
-
-
- ⌖ - - setLocation(e.target.value)} - placeholder="Search city, district, ward or use your location" - className="w-full bg-transparent py-3 text-sm text-white outline-none placeholder:text-slate-500" - /> -
- - -
- -
- - • - India-wide intelligence -
-
-
-
-
- - {/* ========================================================= */} - {/* OVERVIEW */} - {/* ========================================================= */} - -
-
-
-

- Risk overview -

- -

- Flood conditions at a glance -

-
- -
- Data connection will appear here -
-
- -
- {/* Risk */} -
-
-

Current risk

- - - {riskLevel} - -
- -

- {riskLevel} -

- -

- Awaiting location-specific data -

-
- - {/* Rainfall */} -
-

Recent rainfall

- -

- — -

- -

- Connect IMD rainfall data -

-
- - {/* Flood zones */} -
-

Flood-prone zones

- -

- — -

- -

- GIS intelligence -

-
- - {/* Alerts */} -
-

Active alerts

- -

- — -

- -

- No live connection yet -

-
-
-
- - {/* ========================================================= */} - {/* RISK MAP */} - {/* ========================================================= */} - -
-
- {/* Map */} -
- {/* Map grid */} -
- - {/* Simulated map shapes */} -
-
-
- - {/* Map content */} -
-
-
-
- - - Interactive risk map - -
- -

- India Flood Intelligence -

-
- - -
- -
-
- 🌊 -
- -

- Your map will live here -

- -

- This map component will connect to our real GIS layers, - flood-risk predictions, rivers, water bodies, administrative - boundaries and satellite-derived information. -

- - -
- -
- {["Risk", "Rainfall", "Water bodies", "Rivers", "History"].map( - (layer) => ( - - ), - )} -
-
-
- - {/* Risk explanation */} -
-
-
-

- AI analysis -

- -

- Why this risk? -

-
- - - {riskLevel} - -
- -

- FloodIntel will explain the major factors contributing to the - risk level instead of showing only a score. -

- -
- {riskFactors.map((factor) => ( -
-
- {factor.name} - {factor.level} -
- -
-
-
-
- ))} -
- - -
-
-
- - {/* ========================================================= */} - {/* ALERTS + RAINFALL */} - {/* ========================================================= */} - -
-
- {/* Alerts */} -
-
-
-

- Safety -

- -

- Flood alerts & advisories -

-
- - -
- -
- {alerts.map((alert) => ( -
-
- {alert.severity === "High" ? "!" : "i"} -
- -
-

- {alert.title} -

- -

- {alert.location} • {alert.time} -

-
- - - {alert.severity} - -
- ))} -
-
- - {/* Rainfall */} -
-

- Weather intelligence -

- -

- Rainfall monitoring -

- -
-
-

—

-

- Recent rainfall -

-
- -
- IMD data -
-
- - {/* Chart placeholder */} -
- {[35, 52, 42, 68, 45, 80, 58, 72, 50, 65, 42, 74].map( - (height, index) => ( -
- ), - )} -
- -
- Past - Today -
-
-
-
- - {/* ========================================================= */} - {/* HISTORY */} - {/* ========================================================= */} - -
-
-
-

- Historical intelligence -

- -

- Understand what happened before -

- -

- Explore previous flood events and compare historical conditions - with current observations. -

-
- -
- {historicalEvents.map((event) => ( -
-
- - {event.year} - - - - {event.impact} impact - -
- -

- {event.event} -

- -

- Historical event details will be loaded from the FloodIntel - database and verified data sources. -

-
- ))} -
-
-
- - {/* ========================================================= */} - {/* CITIZEN REPORTING */} - {/* ========================================================= */} - -
-
-
-
- 📸 -
- -

- Report flooding in your area -

- -

- Help authorities understand ground conditions by submitting a - flood report with a photo, location and description. -

- - -
- -
-
- 📊 -
- -

- Municipality intelligence -

- -

- Monitor high-risk wards, rainfall, citizen reports, flood - history and emerging risk from one operational dashboard. -

- - -
-
-
- - {/* ========================================================= */} - {/* AI ASSISTANT */} - {/* ========================================================= */} - -
-
-
- -
-
-
- ✦ -
- -
-

- FloodIntel AI -

-

- Ask about flood risk -

-
-
- -

- Ask questions about your local flood risk, rainfall, alerts, - historical events and preparedness. The assistant will be - connected to FloodIntel data instead of relying only on generic - AI answers. -

- -
- {[ - "What is my flood risk?", - "Why is the risk high?", - "What should I do now?", - ].map((question) => ( - - ))} -
- - -
-
-
- - {/* ========================================================= */} - {/* OFFLINE + EMERGENCY */} - {/* ========================================================= */} - -
-
-
-
-
- ◉ -
- -
-

- Offline-ready intelligence -

- -

- Essential alerts, saved locations and emergency information - can remain available when connectivity is limited. -

-
-
-
- -
-
-
- ! -
- -
-

- Emergency preparedness -

- -

- Emergency contacts, safety guidance and evacuation - information will be available from the platform. -

-
-
-
-
-
- - {/* ========================================================= */} - {/* FOOTER */} - {/* ========================================================= */} - - - - {/* ========================================================= */} - {/* FLOATING AI BUTTON */} - {/* ========================================================= */} - - - - {/* ========================================================= */} - {/* AI ASSISTANT PANEL */} - {/* ========================================================= */} - - {assistantOpen && ( -
-
-
-
-
- ✦ -
- -
-

- FloodIntel AI -

-

- Data-connected assistant -

-
-
- - -
- -
-
-

- The FloodIntel AI assistant is ready for integration with - the FastAPI backend, risk engine, rainfall data and - Supabase. -

-
- -
- - - - - -
- -
- - - -
-
-
-
- )} -
- ); -} \ No newline at end of file +import dynamic from "next/dynamic"; import Link from "next/link"; import { ArrowRight, Bell, CloudRain, Map, ShieldAlert } from "lucide-react"; import AppShell from "@/components/AppShell"; import LocationSearch from "@/components/LocationSearch"; import StatusCard from "@/components/StatusCard"; import { useFloodData } from "@/lib/useFloodData"; +const FloodMap=dynamic(()=>import("@/components/FloodMap"),{ssr:false,loading:()=>
Loading interactive map…
}); +export default function Home(){const {state,data,refresh}=useFloodData();return

Flood intelligence platform

Know the risk.
Act before the flood.

Clear, honest flood detection information from the connected FloodIntel backend, designed to help communities prepare and respond.

Risk overview

Current information

Rainfall

Data unavailable. The connected backend does not provide current rainfall observations.

Flood-prone zones

Data unavailable. No GIS zone layer is exposed by the backend.

Active alerts

No live alerts are currently available from the connected backend.

Map layers

Interactive map

Pan and zoom the OpenStreetMap base map. Flood, river, waterbody, and event overlays will only appear after the backend exposes verified GIS data.

Open full map

Future flood risk / forecast

Future forecast data is currently unavailable. Current detection is not presented as a forecast.

View risk details

Recent flood information

Historical events

No historical flood-event data is currently available from the connected backend.

View history
} diff --git a/frontend/app/report/page.tsx b/frontend/app/report/page.tsx index e69de29..a5c6af7 100644 --- a/frontend/app/report/page.tsx +++ b/frontend/app/report/page.tsx @@ -0,0 +1,4 @@ +"use client"; +import AppShell from "@/components/AppShell"; import { Camera, Crosshair, Trash2 } from "lucide-react"; import { FormEvent, useEffect, useState } from "react"; +type Status="idle"|"submitting"|"success"|"failed"|"queued"; type Report={description:string;severity:string;location:string;createdAt:string}; +export default function ReportPage(){const [description,setDescription]=useState(""),[severity,setSeverity]=useState(""),[location,setLocation]=useState(""),[photo,setPhoto]=useState(),[status,setStatus]=useState("idle"),[notice,setNotice]=useState(""); useEffect(()=>{const sync=()=>setNotice("Connection restored. Locally saved reports remain queued because backend submission is currently unavailable.");addEventListener("online",sync);return()=>removeEventListener("online",sync)},[]);const locate=()=>navigator.geolocation?.getCurrentPosition(p=>setLocation(`${p.coords.latitude.toFixed(5)}, ${p.coords.longitude.toFixed(5)}`),()=>setNotice("Location permission was not granted. Enter a location manually."));const submit=(e:FormEvent)=>{e.preventDefault();if(!description||!severity){setStatus("failed");setNotice("Add a description and severity before saving your report.");return}const report={description,severity,location,createdAt:new Date().toISOString()};const existing=JSON.parse(localStorage.getItem("floodintel-report-queue")||"[]") as Report[];localStorage.setItem("floodintel-report-queue",JSON.stringify([...existing,report]));setStatus(navigator.onLine?"success":"queued");setNotice(navigator.onLine?"Report saved locally. Backend submission is currently unavailable.":"You are offline. Your report has been queued locally and will be reviewed for submission when a report API is available.")};return

Citizen report

Report flooding

Share what you see. Image analysis is not claimed because no connected backend endpoint provides it.

{photo?
Selected flood report
:}
setLocation(e.target.value)} className="min-w-0 flex-1 rounded-xl border border-white/10 bg-slate-950 px-3 py-3 text-sm" placeholder="Address, area, or coordinates"/>