MIF_E31221222/sigap-website/app/_components/map/controls/map-sidebar.tsx

185 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { ChevronLeft, ChevronRight, Cloud, Droplets, Wind } from "lucide-react"
import { Button } from "@/app/_components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/app/_components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/app/_components/ui/tabs"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/app/_components/ui/collapsible"
import { cn } from "@/app/_lib/utils"
interface MapSidebarProps {
isOpen: boolean
onToggle: () => void
crimes?: Array<{
id: string
district_name: string
district_id?: string
number_of_crime?: number
level?: "low" | "medium" | "high" | "critical"
incidents: any[]
}>
selectedYear?: number | string
selectedMonth?: number | string
weatherData?: {
temperature: number
condition: string
humidity: number
windSpeed: number
forecast: Array<{
time: string
temperature: number
condition: string
}>
}
}
export default function MapSidebar({
isOpen,
onToggle,
crimes = [],
selectedYear,
selectedMonth,
weatherData = {
temperature: 78,
condition: "Mostly cloudy",
humidity: 65,
windSpeed: 8,
forecast: [
{ time: "Now", temperature: 78, condition: "Cloudy" },
{ time: "9:00 PM", temperature: 75, condition: "Cloudy" },
{ time: "10:00 PM", temperature: 73, condition: "Cloudy" },
{ time: "11:00 PM", temperature: 72, condition: "Cloudy" },
{ time: "12:00 AM", temperature: 70, condition: "Cloudy" },
],
},
}: MapSidebarProps) {
return (
<div
className={cn(
"h-full bg-background border-r transition-all duration-300 flex flex-col",
isOpen ? "w-80" : "w-0 overflow-hidden",
)}
>
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold">Weather Information</h2>
<Button variant="ghost" size="icon" onClick={onToggle} className="h-8 w-8">
<ChevronLeft className="h-4 w-4" />
<span className="sr-only">Close sidebar</span>
</Button>
</div>
<div className="flex-1 overflow-auto p-4">
<Tabs defaultValue="current">
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="current">Current</TabsTrigger>
<TabsTrigger value="forecast">Forecast</TabsTrigger>
</TabsList>
<TabsContent value="current" className="space-y-4 mt-4">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl font-bold flex items-center justify-between">
<span>{weatherData.temperature}°F</span>
<span className="text-sm font-normal">{weatherData.condition}</span>
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-2">
<div className="flex items-center gap-2">
<Droplets className="h-4 w-4 text-blue-500" />
<span>Humidity: {weatherData.humidity}%</span>
</div>
<div className="flex items-center gap-2">
<Wind className="h-4 w-4 text-gray-500" />
<span>Wind: {weatherData.windSpeed} mph</span>
</div>
</div>
</CardContent>
</Card>
<div className="space-y-2">
<h3 className="text-sm font-medium">Today's Recommendations</h3>
<div className="grid grid-cols-2 gap-2">
<Card className="bg-muted/50">
<CardContent className="p-3">
<div className="flex flex-col items-center text-center">
<div className="mb-1">🌂</div>
<div className="text-xs font-medium">Umbrella</div>
<div className="text-xs">No need</div>
</div>
</CardContent>
</Card>
<Card className="bg-muted/50">
<CardContent className="p-3">
<div className="flex flex-col items-center text-center">
<div className="mb-1">🏞</div>
<div className="text-xs font-medium">Outdoors</div>
<div className="text-xs text-red-500">Very poor</div>
</div>
</CardContent>
</Card>
</div>
</div>
<Collapsible className="w-full">
<CollapsibleTrigger asChild>
<Button variant="ghost" size="sm" className="flex w-full justify-between p-0 h-8">
<span>Crime Statistics</span>
<ChevronRight className="h-4 w-4 transition-transform ui-open:rotate-90" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="space-y-2 mt-2">
{crimes.length > 0 ? (
crimes.map((crime) => (
<Card key={crime.id} className="bg-muted/50">
<CardContent className="p-3">
<div className="flex justify-between items-center">
<span className="text-sm">{crime.district_name}</span>
<span
className={cn(
"text-xs px-2 py-0.5 rounded-full",
crime.level === "low" && "bg-green-100 text-green-800",
crime.level === "medium" && "bg-yellow-100 text-yellow-800",
crime.level === "high" && "bg-orange-100 text-orange-800",
crime.level === "critical" && "bg-red-100 text-red-800",
)}
>
{crime.number_of_crime}
</span>
</div>
</CardContent>
</Card>
))
) : (
<div className="text-sm text-muted-foreground">No crime data available</div>
)}
</CollapsibleContent>
</Collapsible>
</TabsContent>
<TabsContent value="forecast" className="mt-4">
<div className="space-y-3">
{weatherData.forecast.map((item, index) => (
<Card key={index}>
<CardContent className="p-3 flex justify-between items-center">
<div className="flex items-center gap-2">
<Cloud className="h-5 w-5 text-blue-500" />
<span>{item.time}</span>
</div>
<div className="flex items-center gap-2">
<span>{item.condition}</span>
<span className="font-medium">{item.temperature}°</span>
</div>
</CardContent>
</Card>
))}
</div>
</TabsContent>
</Tabs>
</div>
</div>
)
}