(undefined)
+ const [size, setSize] = useState({ w: 0, h: 0 })
+
+ const points = useGlobePoints()
+ const rings = useGlobeRings()
+ const focusEvent = useGlobeEvents((s) => s.focusEvent)
+
+ useEffect(() => {
+ const wrap = wrapRef.current
+ if (!wrap) return
+ const ro = new ResizeObserver((entries) => {
+ const entry = entries[0]
+ if (!entry) return
+ setSize({
+ w: entry.contentRect.width,
+ h: entry.contentRect.height,
+ })
+ })
+ ro.observe(wrap)
+ return () => ro.disconnect()
+ }, [])
+
+ useEffect(() => {
+ if (size.w === 0) return
+ const controls = globeRef.current?.controls()
+ if (!controls) return
+ controls.autoRotate = false
+ }, [size.w])
+
+ useEffect(() => {
+ if (!focusEvent) return
+ panTo(globeRef, focusEvent.lat, focusEvent.lng)
+ }, [focusEvent])
+
+ return (
+
+ {size.w > 0 && size.h > 0 && (
+ RING_COLOR}
+ ringMaxRadius={RING_MAX_RADIUS}
+ ringPropagationSpeed={RING_PROPAGATION_SPEED}
+ ringRepeatPeriod={RING_REPEAT_PERIOD}
+ atmosphereColor={ATMOSPHERE_COLOR}
+ atmosphereAltitude={ATMOSPHERE_ALTITUDE}
+ backgroundColor="rgba(0,0,0,0)"
+ />
+ )}
+
+ )
+})
+
+Globe.displayName = 'Globe'
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeCamera.ts b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeCamera.ts
new file mode 100644
index 00000000..1c5bb43f
--- /dev/null
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeCamera.ts
@@ -0,0 +1,20 @@
+// ©AngelaMos | 2026
+// globeCamera.ts
+
+import type { MutableRefObject } from 'react'
+import type { GlobeMethods } from 'react-globe.gl'
+
+const DEFAULT_PAN_DURATION_MS = 1200
+const DEFAULT_FOCUS_ALTITUDE = 1.8
+
+export type GlobeRef = MutableRefObject
+
+export function panTo(
+ ref: GlobeRef,
+ lat: number,
+ lng: number,
+ durationMs: number = DEFAULT_PAN_DURATION_MS,
+ altitude: number = DEFAULT_FOCUS_ALTITUDE
+): void {
+ ref.current?.pointOfView({ lat, lng, altitude }, durationMs)
+}
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeLayers.ts b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeLayers.ts
new file mode 100644
index 00000000..42241877
--- /dev/null
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/globe/globeLayers.ts
@@ -0,0 +1,78 @@
+// ©AngelaMos | 2026
+// globeLayers.ts
+
+import { useMemo } from 'react'
+import { type GlobePointType, useGlobeEvents } from '@/stores/globeEvents'
+
+const COLOR_BY_TYPE: Record = {
+ earthquake: '#a3a3a3',
+ ransomware: '#e5e5e5',
+ scan: '#404040',
+ iss: '#4ade80',
+ outage: '#f59e0b',
+ hijack: '#f59e0b',
+}
+
+const ALTITUDE_BY_TYPE: Record = {
+ earthquake: 0.01,
+ ransomware: 0.01,
+ scan: 0.005,
+ iss: 0.06,
+ outage: 0.005,
+ hijack: 0.005,
+}
+
+const RADIUS_BY_TYPE: Record = {
+ earthquake: 0.4,
+ ransomware: 0.3,
+ scan: 0.15,
+ iss: 0.5,
+ outage: 0.4,
+ hijack: 0.4,
+}
+
+export interface GlobePointDatum {
+ id: string
+ type: GlobePointType
+ lat: number
+ lng: number
+ color: string
+ altitude: number
+ radius: number
+}
+
+export interface GlobeRingDatum {
+ id: string
+ lat: number
+ lng: number
+}
+
+export function useGlobePoints(): GlobePointDatum[] {
+ const points = useGlobeEvents((s) => s.points)
+ return useMemo(
+ () =>
+ points.map((p) => ({
+ id: p.id,
+ type: p.type,
+ lat: p.lat,
+ lng: p.lng,
+ color: COLOR_BY_TYPE[p.type],
+ altitude: ALTITUDE_BY_TYPE[p.type],
+ radius: RADIUS_BY_TYPE[p.type],
+ })),
+ [points]
+ )
+}
+
+export function useGlobeRings(): GlobeRingDatum[] {
+ const rings = useGlobeEvents((s) => s.rings)
+ return useMemo(
+ () =>
+ rings.map((r) => ({
+ id: r.id,
+ lat: r.lat,
+ lng: r.lng,
+ })),
+ [rings]
+ )
+}