import React, { useState, useEffect, useCallback } from 'react'; import SunCalc from 'suncalc'; import { SunClockIcon, AlertTriangleIcon } from '../components/icons'; type PermissionStatus = 'idle' | 'prompting' | 'granted' | 'denied'; const SunTrackerView: React.FC = () => { const [permission, setPermission] = useState('idle'); const [sunData, setSunData] = useState(null); const [compassHeading, setCompassHeading] = useState(0); const [error, setError] = useState(''); const handleOrientation = (event: DeviceOrientationEvent) => { // webkitCompassHeading is for iOS const heading = (event as any).webkitCompassHeading || (360 - event.alpha!); setCompassHeading(heading); }; const requestPermissions = useCallback(async () => { setPermission('prompting'); // Geolocation if (!("geolocation" in navigator)) { setError("Geolocation is not supported by your browser."); setPermission('denied'); return; } navigator.geolocation.getCurrentPosition( (position) => { const { latitude, longitude } = position.coords; const now = new Date(); const times = SunCalc.getTimes(now, latitude, longitude); const pos = SunCalc.getPosition(now, latitude, longitude); setSunData({ ...times, ...pos }); // Device Orientation (Compass) if (typeof (DeviceOrientationEvent as any).requestPermission === 'function') { (DeviceOrientationEvent as any).requestPermission() .then((response: string) => { if (response === 'granted') { window.addEventListener('deviceorientation', handleOrientation); setPermission('granted'); } else { setError("Compass permission denied."); setPermission('denied'); } }); } else { window.addEventListener('deviceorientation', handleOrientation); setPermission('granted'); } }, (error) => { setError("Geolocation permission denied. Please enable it in your browser settings."); setPermission('denied'); } ); }, []); useEffect(() => { return () => { window.removeEventListener('deviceorientation', handleOrientation); }; }, []); const renderCompass = () => (
N S W E
{sunData && (
)}
); const renderSunPath = () => { if (!sunData) return null; const now = new Date(); const totalDaylight = sunData.sunset.getTime() - sunData.sunrise.getTime(); const fromSunrise = now.getTime() - sunData.sunrise.getTime(); const percentOfDay = Math.max(0, Math.min(1, fromSunrise / totalDaylight)); return (
{percentOfDay > 0 && percentOfDay < 1 && ( )}
{sunData.sunrise.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} {sunData.sunset.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
); } return (

Sun Tracker

Find the optimal light for your trees. Use this tool to see the sun's path and current position.

{permission === 'granted' ? (
{renderCompass()}

Heading: {compassHeading.toFixed(0)}°

Point the top of your device North

{renderSunPath()}
) : (

This tool requires permission to access your device's location and orientation to function.

{error && (

{error}

)}
)}
); }; export default SunTrackerView;