11import { stormsApi } from "@/services/apis/storms.api" ;
2- import { mdiWeatherHurricaneOutline } from "@mdi/js" ;
2+ import { mdiChevronUp , mdiWeatherHurricaneOutline } from "@mdi/js" ;
33import Icon from "@mdi/react" ;
44import dayjs from "dayjs" ;
5- import { useEffect } from "react" ;
5+ import { useEffect , useState } from "react" ;
66import { useWeatherMapStore } from "../store" ;
77
88export function StormSelector ( ) {
9- const { isStormSelectorOpen, setSelectedStormId, setStorms, storms, selectedStormId } = useWeatherMapStore ( ) ;
9+ const {
10+ isStormSelectorOpen,
11+ setSelectedStormId,
12+ setStorms,
13+ storms,
14+ selectedStormId,
15+ } = useWeatherMapStore ( ) ;
16+
17+ const [ isCollapsed , setIsCollapsed ] = useState ( false ) ;
18+
1019 const handleStormClick = ( stormId : number | null ) => {
1120 setSelectedStormId ( stormId ) ;
21+ setIsCollapsed ( true ) ;
1222 } ;
1323
1424 useEffect ( ( ) => {
@@ -17,93 +27,72 @@ export function StormSelector() {
1727 const response = await stormsApi . storms . list ( ) ;
1828 const data = response . data . sort ( ( a , b ) => b . storm_id - a . storm_id ) ;
1929 setStorms ( data ) ;
20- }
21- catch ( error ) {
30+ } catch ( error ) {
2231 console . error ( "Error fetching storms:" , error ) ;
2332 }
2433 } ;
2534
2635 fetchStorms ( ) ;
2736 } , [ setStorms ] ) ;
2837
38+ if ( ! isStormSelectorOpen ) {
39+ return null ;
40+ }
41+
2942 return (
30- < >
31- { /* Storm Selector Panel */ }
32- { isStormSelectorOpen && (
33- < div className = "absolute top-6 right-6 z-[1000] pointer-events-auto w-[400px]" >
34- < div className = "p-4 flex flex-col gap-2 bg-white/70 backdrop-blur-sm shadow-2xl rounded-2xl" >
35- < div className = "flex justify-between items-start" >
36- < div >
37- < h2 className = "text-2xl font-medium text-black" > Select Storm</ h2 >
38- < p className = "text-base text-black/80 mt-2" >
39- Choose a storm to display its trajectory
40- </ p >
41- </ div >
42- { /* <button
43- onClick={onToggle}
44- className="w-8 h-8 flex items-center justify-center rounded-full bg-white hover:bg-gray-200 transition-colors"
45- >
46- <Icon path={mdiClose} size={1} className="text-black" />
47- </button> */ }
48- </ div >
43+ < div className = "absolute top-20 right-4 md:top-6 md:right-6 z-20 pointer-events-auto w-[280px] md:w-[240px]" >
44+ { " " }
45+ < div className = "p-3 flex flex-col gap-2 bg-white/70 backdrop-blur-sm shadow-lg rounded-2xl transition-all duration-300" >
46+ < button
47+ type = "button"
48+ onClick = { ( ) => setIsCollapsed ( ! isCollapsed ) }
49+ className = "flex justify-between items-center w-full"
50+ >
51+ < span className = "font-medium text-base text-black" > Select Storm</ span >
52+ < Icon
53+ path = { mdiChevronUp }
54+ size = { 1 }
55+ className = { `text-black transition-transform duration-300 ${
56+ isCollapsed ? "rotate-180" : ""
57+ } `}
58+ />
59+ </ button >
4960
50- < div className = "flex-1 flex flex-col gap-2 overflow-y-auto max-h-[500px] mt-4" >
51- { /* All Storms Option */ }
52- { /* <button
53- onClick={() => handleStormClick(null)}
54- className={`p-4 rounded-lg text-left transition-colors ${selectedStormId === null
55- ? "bg-orange-500 text-white"
56- : "bg-white/50 hover:bg-white/80 text-black"
61+ { ! isCollapsed && (
62+ < div className = "flex-1 flex flex-col gap-2 overflow-y-auto max-h-[400px] md:max-h-[300px] mt-2" >
63+ { storms . map ( ( storm ) => (
64+ < button
65+ key = { storm . storm_id }
66+ onClick = { ( ) => handleStormClick ( storm . storm_id ) }
67+ className = { `p-3 rounded-lg text-left transition-colors ${
68+ selectedStormId === storm . storm_id
69+ ? "bg-orange-500 text-white"
70+ : "bg-white/50 hover:bg-white/80 text-black"
5771 } `}
5872 >
59- <div className="flex items-center gap-2 mb-2 ">
60- <Icon path={mdiWeatherHurricaneOutline} size={0.8 } />
61- <h3 className="text-lg font-semibold">All Storms </h3>
73+ < div className = "flex items-center gap-2 mb-1 " >
74+ < Icon path = { mdiWeatherHurricaneOutline } size = { 0.7 } />
75+ < h3 className = "text-sm font-semibold" > { storm . storm_name } </ h3 >
6276 </ div >
63- <p className="text-sm opacity-80">Display all available storms</p>
64- </button> */ }
65-
66- { /* Individual Storms */ }
67- { storms . map ( storm => (
68- < button
69- key = { storm . storm_id }
70- onClick = { ( ) => handleStormClick ( storm . storm_id ) }
71- className = { `p-4 rounded-lg text-left transition-colors ${ selectedStormId === storm . storm_id
72- ? "bg-orange-500 text-white"
73- : "bg-white/50 hover:bg-white/80 text-black"
74- } `}
75- >
76- < div className = "flex items-center gap-2 mb-2" >
77- < Icon path = { mdiWeatherHurricaneOutline } size = { 0.8 } />
78- < h3 className = "text-lg font-semibold" > { storm . storm_name } </ h3 >
79- </ div >
80- < div className = "text-sm space-y-1" >
81- < p >
82- < span className = "opacity-80" > ID:</ span >
83- { " " }
84- < span className = "font-medium" > { storm . storm_id } </ span >
85- </ p >
86- < p >
87- < span className = "opacity-80" > Start:</ span >
88- { " " }
89- < span className = "font-medium" >
90- { dayjs ( storm . start_date ) . format ( "DD/MM/YYYY" ) }
91- </ span >
92- </ p >
93- < p >
94- < span className = "opacity-80" > End:</ span >
95- { " " }
96- < span className = "font-medium" >
97- { dayjs ( storm . end_date ) . format ( "DD/MM/YYYY" ) }
98- </ span >
99- </ p >
100- </ div >
101- </ button >
102- ) ) }
103- </ div >
77+ < div className = "text-xs space-y-0.5 pl-1" >
78+ < p >
79+ < span className = "opacity-80" > Start:</ span > { " " }
80+ < span className = "font-medium" >
81+ { dayjs ( storm . start_date ) . format ( "DD/MM/YYYY" ) }
82+ </ span >
83+ </ p >
84+ < p >
85+ < span className = "opacity-80" > End:</ span > { " " }
86+ < span className = "font-medium" >
87+ { dayjs ( storm . end_date ) . format ( "DD/MM/YYYY" ) }
88+ </ span >
89+ </ p >
90+ </ div >
91+ </ button >
92+ ) ) }
10493 </ div >
105- </ div >
106- ) }
107- </ >
94+ ) }
95+ </ div >
96+ </ div >
10897 ) ;
10998}
0 commit comments