Enhance pop-up components with connection indicators and improve styling
- Refactored IncidentPopup, TimelinePopup, and UnitPopup components to include connection lines and dots for better visual indication of their relation to the map. - Updated the layout and styling of the pop-ups for improved readability and consistency. - Adjusted the TIME_ZONES data to reflect more accurate geographical locations. - Enhanced the digital clock display in the TimeZonesDisplay component with improved styling and shadow effects. - Added new CSS styles for digital clock presentation to enhance user experience.
This commit is contained in:
parent
da94277f4d
commit
4cc01babf1
|
@ -82,6 +82,7 @@ export default function IncidentPopup({ longitude, latitude, onClose, incident }
|
||||||
maxWidth="320px"
|
maxWidth="320px"
|
||||||
className="incident-popup z-50"
|
className="incident-popup z-50"
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<Card
|
<Card
|
||||||
className={`bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 ${getBorderColor(incident.status)}`}
|
className={`bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 ${getBorderColor(incident.status)}`}
|
||||||
>
|
>
|
||||||
|
@ -177,6 +178,29 @@ export default function IncidentPopup({ longitude, latitude, onClose, incident }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* Connection line */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '2px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Connection dot */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
borderRadius: '50%',
|
||||||
|
marginTop: '20px',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ export default function DistrictPopup({
|
||||||
maxWidth="300px"
|
maxWidth="300px"
|
||||||
className="district-popup z-50"
|
className="district-popup z-50"
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<Card className="bg-background p-0 w-full max-w-[300px] shadow-xl border-0 overflow-hidden">
|
<Card className="bg-background p-0 w-full max-w-[300px] shadow-xl border-0 overflow-hidden">
|
||||||
<div className="bg-tertiary text-white p-3 relative">
|
<div className="bg-tertiary text-white p-3 relative">
|
||||||
{/* Custom close button */}
|
{/* Custom close button */}
|
||||||
|
@ -128,10 +129,6 @@ export default function DistrictPopup({
|
||||||
</div>
|
</div>
|
||||||
{getCrimeRateBadge(district.level)}
|
{getCrimeRateBadge(district.level)}
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="mt-1 text-white/80 text-xs flex items-center gap-2">
|
|
||||||
<Calendar className="h-3 w-3" />
|
|
||||||
<span>{getTimePeriod()}</span>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-3 gap-1 p-2 bg-background">
|
<div className="grid grid-cols-3 gap-1 p-2 bg-background">
|
||||||
|
@ -155,7 +152,6 @@ export default function DistrictPopup({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||||
{/* Improved tab headers */}
|
|
||||||
<TabsList className="w-full grid grid-cols-3 h-10 rounded-none bg-background border-b">
|
<TabsList className="w-full grid grid-cols-3 h-10 rounded-none bg-background border-b">
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="overview"
|
value="overview"
|
||||||
|
@ -177,7 +173,6 @@ export default function DistrictPopup({
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
{/* Tab content with improved section headers */}
|
|
||||||
<TabsContent value="overview" className="mt-0 p-4">
|
<TabsContent value="overview" className="mt-0 p-4">
|
||||||
<div className="text-sm space-y-3">
|
<div className="text-sm space-y-3">
|
||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
|
@ -337,6 +332,29 @@ export default function DistrictPopup({
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* Connection line */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '2px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Connection dot */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
borderRadius: '50%',
|
||||||
|
marginTop: '20px',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ export default function IncidentPopup({
|
||||||
maxWidth="320px"
|
maxWidth="320px"
|
||||||
className="incident-popup z-50"
|
className="incident-popup z-50"
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<Card
|
<Card
|
||||||
className="bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 border-l-red-600"
|
className="bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 border-l-red-600"
|
||||||
>
|
>
|
||||||
|
@ -175,6 +176,29 @@ export default function IncidentPopup({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* Connection line */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '2px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Connection dot */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
borderRadius: '50%',
|
||||||
|
marginTop: '20px',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../..
|
||||||
import { Button } from "../../ui/button"
|
import { Button } from "../../ui/button"
|
||||||
import { Badge } from "../../ui/badge"
|
import { Badge } from "../../ui/badge"
|
||||||
|
|
||||||
|
|
||||||
interface TimelinePopupProps {
|
interface TimelinePopupProps {
|
||||||
longitude: number
|
longitude: number
|
||||||
latitude: number
|
latitude: number
|
||||||
|
@ -63,6 +62,7 @@ export default function TimelinePopup({
|
||||||
className="z-10"
|
className="z-10"
|
||||||
maxWidth="300px"
|
maxWidth="300px"
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<Card className="border-0 shadow-none">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader className="p-3 pb-2">
|
<CardHeader className="p-3 pb-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
@ -117,6 +117,29 @@ export default function TimelinePopup({
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* Connection line */}
|
||||||
|
<div
|
||||||
|
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '2px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Connection dot */}
|
||||||
|
<div
|
||||||
|
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
borderRadius: '50%',
|
||||||
|
marginBottom: '20px',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ export default function UnitPopup({
|
||||||
maxWidth="320px"
|
maxWidth="320px"
|
||||||
className="unit-popup z-50"
|
className="unit-popup z-50"
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<Card
|
<Card
|
||||||
className="bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 border-l-blue-700"
|
className="bg-background p-0 w-full max-w-[320px] shadow-xl border-0 overflow-hidden border-l-4 border-l-blue-700"
|
||||||
>
|
>
|
||||||
|
@ -162,6 +163,29 @@ export default function UnitPopup({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* Connection line */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '2px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Connection dot */}
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full"
|
||||||
|
style={{
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
borderRadius: '50%',
|
||||||
|
marginTop: '20px',
|
||||||
|
boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ interface TimeZoneMarker {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TIME_ZONES: TimeZoneMarker[] = [
|
const TIME_ZONES: TimeZoneMarker[] = [
|
||||||
{ name: "WIB", offset: 7, longitude: 106.8456, latitude: -6.2088 }, // Jakarta
|
{ name: "WIB", offset: 7, longitude: 110.5, latitude: -3.3 }, // Between Java and Sumatra
|
||||||
{ name: "WITA", offset: 8, longitude: 115.1889, latitude: -8.4095 }, // Denpasar
|
{ name: "WITA", offset: 8, longitude: 118.8, latitude: -2.5 }, // Between Java and Kalimantan
|
||||||
{ name: "WIT", offset: 9, longitude: 140.7887, latitude: -2.5916 }, // Jayapura
|
{ name: "WIT", offset: 9, longitude: 128.0, latitude: -2.0 }, // Between Sulawesi and Papua
|
||||||
]
|
]
|
||||||
|
|
||||||
export default function TimeZonesDisplay() {
|
export default function TimeZonesDisplay() {
|
||||||
|
@ -49,12 +49,19 @@ export default function TimeZonesDisplay() {
|
||||||
<>
|
<>
|
||||||
{TIME_ZONES.map((zone) => (
|
{TIME_ZONES.map((zone) => (
|
||||||
<Marker key={zone.name} longitude={zone.longitude} latitude={zone.latitude}>
|
<Marker key={zone.name} longitude={zone.longitude} latitude={zone.latitude}>
|
||||||
<div className="relative group">
|
<div className="relative">
|
||||||
<div className="absolute -translate-x-1/2 -translate-y-full mb-2 pointer-events-none">
|
<div className="absolute -translate-x-1/2 -translate-y-1/2 pointer-events-none">
|
||||||
<div className="bg-black/80 text-white px-2 py-1 rounded-md text-xs font-mono">
|
<div className="bg-black/90 border-2 border-orange-600/70 rounded-lg p-2 shadow-lg">
|
||||||
<div className="text-center font-bold">{zone.name}</div>
|
<div className="text-center text-orange-500 text-xs font-bold">{zone.name} / GMT+{zone.offset}</div>
|
||||||
<div className="digital-clock">{currentTimes[zone.name] || "00:00:00"}</div>
|
<div
|
||||||
<div className="text-center text-xs text-gray-300">GMT+{zone.offset}</div>
|
className="digital-clock font-mono font-bold text-amber-500 text-xl md:text-2xl tracking-wider"
|
||||||
|
style={{
|
||||||
|
textShadow: '0 0 5px rgba(255,170,0,0.7)',
|
||||||
|
fontFamily: "'Digital', monospace"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentTimes[zone.name] || "00:00:00"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -217,3 +217,16 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Digital Clock Styling */
|
||||||
|
.digital-clock {
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue