{"version":3,"sources":["images/fire-hydrant-yellow.svg","images/fire-hydrant-orange.svg","images/fire-hydrant-red.svg","images/fire_hydrante_green.svg","images/cluster_3.png","images/close.svg","images/refresh.svg","images/letters_green.svg","images/logo_wth_text.svg","images/letters.svg","images/Hydro-Defence.mp4","images/play.svg","images/pause.svg","images/play_white.svg","images/pause_white.svg","images/mute_white.svg","images/sound_white.svg","images/control-panel-image.png","images/map-image.png","images/hydrants-dashboard-image.png","images/hydrant-dashboard-image.png","images/notifications.png","images/dashboard.svg","images/control-panel.svg","images/map.svg","ControlPanel.js","Map.js","HydrantWaterConsumptionChart.js","InfoHydrantCard.js","HydrantDashboard.js","CustomSignIn.js","NavBar.js","LandingPage.js","Sidebar.js","TotalWaterConsumptionCard.js","HydrantMonthlyConsumptionChart.js","ParishConsumptionChart.js","HydrantsDashboard.js","App.js","reportWebVitals.js","aws-exports.js","serviceWorkerRegistration.js","index.js"],"names":["module","exports","getLatitudeFromLocation","location","match","parseFloat","getLongitudeFromLocation","separateDateFromHours","timestamp","date","time","split","reverse","join","getDifferenceInMinutesSinceIsOpen","difference","Date","now","minutes","Math","floor","hours","days","getColorByOpenTime","yellowIcon","orangeIcon","redIcon","ControlPanel","_ref","userEmail","userToken","hydrants","setHydrants","useState","open","setOpen","modalMessage","setModalMessage","filter","setFilter","searchTerm","setSearchTerm","isLoading","setIsLoading","previousHydrantsRef","useRef","handleClose","useEffect","fetchHydrants","async","response","fetch","method","headers","ok","Error","data","json","newHydrants","map","item","id","parseInt","hydrant_id","name","status","current_state","latitude","longitude","consumption","estimation","toFixed","lastOpen","openTime","open_time","currentEstimation","debit_m3_s","openColor","openTimeMinutes","getCurrentEstimation","forEach","newHydrant","oldHydrant","current","find","h","message","error","console","interval","setInterval","clearInterval","filteredHydrants","hydrant","matchesSearch","toLowerCase","includes","React","createElement","Grid","container","justifyContent","alignItems","style","height","PuffLoader","color","size","Fragment","Dialog","onClose","DialogTitle","sx","DialogContent","DialogContentText","DialogActions","Button","onClick","className","TextField","placeholder","variant","value","onChange","e","target","InputProps","startAdornment","InputAdornment","position","SearchIcon","fullWidth","marginBottom","xs","sm","marginRight","Tooltip","title","IconButton","prevFilter","src","greenIcon","alt","width","opacity","spacing","md","lg","key","Card","elevation","CardContent","Typography","Link","to","component","aria-label","PlaceIcon","href","rel","mapContainerStyle","defaultCenter","lat","lng","result","endsWith","slice","getIcon","iconUrl","url","scaledSize","window","google","maps","Size","Map","navigate","useNavigate","useLocation","mapCenter","setMapCenter","mapZoom","setMapZoom","selectedHydrant","setSelectedHydrant","isBlinking","setIsBlinking","hydrantsRef","mapRef","hydrantId","hash","replace","panTo","setZoom","prev","LoadScriptNext","googleMapsApiKey","GoogleMap","zoom","center","onLoad","MarkerClusterer","options","styles","textColor","cluster","textSize","fontFamily","backgroundPosition","anchor","backgroundColor","borderRadius","lineHeight","textAlign","clusterer","MarkerF","icon","closeIcon","formatDate","HydrantWaterConsumptionChart","hydrantData","zoomDomain","setZoomDomain","chartRef","chartContainerRef","selectionStart","setSelectionStart","selectionEnd","setSelectionEnd","selectionActive","setSelectionActive","selectionPixels","setSelectionPixels","left","selectionDates","setSelectionDates","start","end","currentZoomSelection","setCurrentZoomSelection","document","textContent","head","appendChild","removeChild","observer","MutationObserver","xAxisElement","querySelector","distanceToXAxis","getBoundingClientRect","top","setProperty","observe","childList","subtree","disconnect","historical_data","chartData","record","sort","a","b","handleMouseDown","chartRect","clientX","right","clientY","bottom","x","log","chartWidth","dataIndex","length","handleMouseMove","max","min","abs","startPct","endPct","dataToUse","startIdx","endIdx","validStartIdx","validEndIdx","date1","date2","d1Parts","d2Parts","d1","d2","handleMouseUp","findIndex","d","minIdx","maxIdx","selectedData","setTimeout","ref","WaterDropIcon","resetZoom","RefreshIcon","background","padding","margin","fontSize","onMouseDown","preventDefault","onMouseMove","onMouseUp","onMouseLeave","handleMouseLeave","onTouchStart","touch","touches","onTouchMove","onTouchEnd","ResponsiveContainer","AreaChart","x1","y1","x2","y2","offset","stopColor","stopOpacity","XAxis","dataKey","tickFormatter","reversed","tick","YAxis","RechartsTooltip","formatter","Area","type","stroke","fillOpacity","fill","zIndex","pointerEvents","transform","InfoHydrantCard","text","HydrantDashboard","useParams","setHydrantData","dateFilter","setDateFilter","estimationFilter","setEstimationFilter","estimationOperator","setEstimationOperator","Authorization","fetchHydrantHistory","cap_registed","caps_total","specs","numberOfCaps","totalEstimatedConsumptionText","reduce","acc","debit_m3_sText","SensorsIcon","WavesIcon","Paper","DataUsageIcon","Table","TableHead","TableRow","TableCell","align","TableBody","recordDate","meetsDate","meetsEstimation","index","hover","CustomSignIn","setUser","username","setUsername","password","setPassword","newPassword","setNewPassword","isChangePassword","setIsChangePassword","currentUser","setCurrentUser","lettersLogo","label","InputLabelProps","shrink","Auth","completeNewPassword","user","signIn","challengeName","Navbar","isLoggedIn","onSignOut","pageTitle","isMobileMenuOpen","setIsMobileMenuOpen","isMobile","setIsMobile","innerWidth","isSignInPage","pathname","handleResize","addEventListener","removeEventListener","logo","toggleMobileMenu","LandingPage","isPlaying","setIsPlaying","isMuted","setIsMuted","showControls","setShowControls","showCenterIcon","setShowCenterIcon","modalShow","setModalShow","selectedImage","setSelectedImage","videoRef","emailStatus","setEmailStatus","formData","setFormData","email","handleVideoClick","pause","pauseIcon","play","playIcon","handleChange","prevData","letters","onMouseEnter","autoPlay","muted","heroVideo","pauseBarIcon","playBarIcon","handleMuteUnmute","muteIcon","unmuteIcon","img","controlPanelImage","desc","mapImage","hydrantsDashboardImage","hydrantDashboardImage","notificationImage","feature","handleShowImage","imageSrc","onSubmit","body","JSON","stringify","required","Modal","show","onHide","centered","Header","closeButton","Title","Body","Footer","getFullYear","Sidebar","signOut","isActive","path","OverviewIcon","DashboardIcon","MapIcon","TotalWaterConsumptionCard","totalWaterConsumption","percentageChange","isIncrease","selectedYear","onYearChange","InfoIcon","toLocaleString","ArrowUpwardIcon","ArrowDownwardIcon","Select","disableUnderline","year","MenuItem","monthNames","HydrantMonthlyConsumptionChart","_ref3","formattedData","Object","entries","totalEstimationByYear","months","_ref2","month","monthIndex","monthName","values","indexOf","prepareMonthlyConsumptionData","FireHydrantAltIcon","BarChart","domain","Legend","wrapperStyle","Bar","barSize","radius","COLORS","ParishConsumptionChart","topFreguesiasData","total","sum","entry","totalConsumption","percentage","formatData","PieChart","Pie","nameKey","cx","cy","outerRadius","innerRadius","labelLine","percent","_","Cell","layout","iconType","transformApiResponse","apiResponse","Promise","all","freguesia","results","addressComponents","address_components","freguesiaComponent","types","long_name","fetchFreguesia","historyResponse","totalEstimation","openings","historyData","recordYear","recordMonth","getMonth","lastUsed","HydrantsDashboard","sortBy","setSortBy","sortOrder","setSortOrder","setSelectedYear","transformedData","sortedHydrants","hydrantsByFreguesia","push","dateParts","_h$totalEstimationByY","yearData","monthSum","monthValue","lastYearConsumption","_h$totalEstimationByY2","FormatListBulletedIcon","keys","Accordion","AccordionSummary","expandIcon","ExpandMoreIcon","AccordionDetails","event","AppContent","startsWith","getPageTitle","Routes","Route","element","Navigate","App","setUserEmail","setUserToken","loading","setLoading","currentAuthenticatedUser","jwtToken","signInUserSession","idToken","attributes","fetchUserDetails","Router","reload","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","awsmobile","isLocalhost","Boolean","hostname","registerValidSW","swUrl","config","navigator","serviceWorker","register","registration","onupdatefound","installingWorker","installing","onstatechange","state","controller","onUpdate","onSuccess","catch","Amplify","configure","ReactDOM","createRoot","getElementById","render","StrictMode","URL","process","origin","contentType","get","ready","unregister","checkValidServiceWorker","serviceWorkerRegistration"],"mappings":"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","file":"static/js/main.7a5a3033.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/fire-hydrant-yellow.cf1791db.svg\";","module.exports = __webpack_public_path__ + \"static/media/fire-hydrant-orange.fa6df085.svg\";","module.exports = __webpack_public_path__ + \"static/media/fire-hydrant-red.5760da04.svg\";","module.exports = __webpack_public_path__ + \"static/media/fire_hydrante_green.f34eed7b.svg\";","module.exports = __webpack_public_path__ + \"static/media/cluster_3.d885feb0.png\";","module.exports = __webpack_public_path__ + \"static/media/close.cf9638f9.svg\";","module.exports = __webpack_public_path__ + \"static/media/refresh.f00c95b3.svg\";","module.exports = __webpack_public_path__ + \"static/media/letters_green.858fc751.svg\";","module.exports = __webpack_public_path__ + \"static/media/logo_wth_text.78cf787b.svg\";","module.exports = __webpack_public_path__ + \"static/media/letters.7cbef351.svg\";","module.exports = __webpack_public_path__ + \"static/media/Hydro-Defence.e308b459.mp4\";","module.exports = __webpack_public_path__ + \"static/media/play.2741d6e9.svg\";","module.exports = __webpack_public_path__ + \"static/media/pause.12e55217.svg\";","module.exports = __webpack_public_path__ + \"static/media/play_white.b403b35a.svg\";","module.exports = __webpack_public_path__ + \"static/media/pause_white.b3515ed6.svg\";","module.exports = __webpack_public_path__ + \"static/media/mute_white.2850ce42.svg\";","module.exports = __webpack_public_path__ + \"static/media/sound_white.f670a205.svg\";","module.exports = __webpack_public_path__ + \"static/media/control-panel-image.1b978d1e.png\";","module.exports = __webpack_public_path__ + \"static/media/map-image.2cc8edf5.png\";","module.exports = __webpack_public_path__ + \"static/media/hydrants-dashboard-image.8a7b9fd3.png\";","module.exports = __webpack_public_path__ + \"static/media/hydrant-dashboard-image.10bd6bc6.png\";","module.exports = __webpack_public_path__ + \"static/media/notifications.55889430.png\";","module.exports = __webpack_public_path__ + \"static/media/dashboard.8f1f1239.svg\";","module.exports = __webpack_public_path__ + \"static/media/control-panel.f47b6897.svg\";","module.exports = __webpack_public_path__ + \"static/media/map.1bc2ebe0.svg\";","import React, { useState, useEffect, useRef } from 'react';\nimport { Link } from 'react-router-dom';\nimport { PuffLoader } from 'react-spinners'; // Added PuffLoader\nimport {\n Card, CardContent, Typography, IconButton, Dialog, DialogActions,\n DialogContent, DialogContentText, DialogTitle, Button, Tooltip,\n Grid, TextField, InputAdornment\n} from '@mui/material';\nimport PlaceIcon from '@mui/icons-material/Place';\nimport SearchIcon from '@mui/icons-material/Search';\nimport yellowIcon from './images/fire-hydrant-yellow.svg';\nimport orangeIcon from './images/fire-hydrant-orange.svg';\nimport redIcon from './images/fire-hydrant-red.svg';\nimport greenIcon from './images/fire_hydrante_green.svg';\nimport './ControlPanel.css';\n\n// Helper Functions (unchanged)\nconst getLatitudeFromLocation = (location) => {\n const match = location.match(/q=(.*),/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst getLongitudeFromLocation = (location) => {\n const match = location.match(/,(.*)$/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst separateDateFromHours = (timestamp) => {\n const [date, time] = timestamp.split('T');\n return `${date.split('-').reverse().join('/')} ${time}`;\n};\n\nconst getCurrentEstimation = (timestamp, debit_m3_s) => {\n const now = Date.now();\n const elapsedTimeInSeconds = (now - timestamp) / 1000;\n return (debit_m3_s * elapsedTimeInSeconds).toFixed(1);\n};\n\nconst getDifferenceInMinutesSinceIsOpen = (timestamp) => {\n const now = Date.now();\n const difference = now - timestamp;\n const minutes = Math.floor(difference / (1000 * 60));\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n return days > 0\n ? `${days}d ${hours % 24}h ago`\n : hours > 0\n ? `${hours}h ${minutes % 60}m ago`\n : `${minutes}m ago`;\n};\n\nconst getColorByOpenTime = (timestamp) => {\n const now = Date.now();\n const minutes = (now - timestamp) / (1000 * 60);\n\n if (minutes <= 10) return yellowIcon;\n if (minutes <= 30) return orangeIcon;\n return redIcon;\n};\n\nconst transformApiResponse = (apiResponse) => {\n return apiResponse.map(item => ({\n id: parseInt(item.hydrant_id),\n name: `Hydrant ${item.hydrant_id}`,\n status: item.current_state ? 'open' : 'closed',\n latitude: getLatitudeFromLocation(item.location),\n longitude: getLongitudeFromLocation(item.location),\n consumption: `${item.estimation.toFixed(2)} m³`,\n lastOpen: separateDateFromHours(item.date),\n openTime: getDifferenceInMinutesSinceIsOpen(item.open_time),\n currentEstimation: getCurrentEstimation(item.open_time, item.debit_m3_s),\n openColor: getColorByOpenTime(item.open_time),\n openTimeMinutes: (Date.now() - item.open_time) / (1000 * 60)\n }));\n};\n\n// Main Component\nfunction ControlPanel({ userEmail, userToken }) {\n const [hydrants, setHydrants] = useState([]);\n const [open, setOpen] = useState(false);\n const [modalMessage, setModalMessage] = useState(\"\");\n const [filter, setFilter] = useState('all');\n const [searchTerm, setSearchTerm] = useState('');\n const [isLoading, setIsLoading] = useState(true); // Added loading state\n const previousHydrantsRef = useRef([]);\n\n const handleOpen = (message) => {\n setModalMessage(message);\n setOpen(true);\n };\n\n const handleClose = () => setOpen(false);\n\n useEffect(() => {\n const fetchHydrants = async () => {\n try {\n const response = await fetch(`https://4cfxljq8qi.execute-api.eu-west-1.amazonaws.com/dev/hydrants?client_email=${userEmail}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${userToken}` }\n });\n\n if (!response.ok) throw new Error('Network response was not ok');\n\n const data = await response.json();\n const newHydrants = transformApiResponse(data);\n\n newHydrants.forEach(newHydrant => {\n const oldHydrant = previousHydrantsRef.current.find(h => h.id === newHydrant.id);\n if (oldHydrant && oldHydrant.status !== newHydrant.status) {\n handleOpen(`Hydrant ${newHydrant.id} is now ${newHydrant.status}`);\n }\n });\n\n previousHydrantsRef.current = newHydrants;\n setHydrants(newHydrants);\n } catch (error) {\n console.error('There was a problem fetching hydrants:', error);\n } finally {\n setIsLoading(false); // Set loading to false after fetching\n }\n };\n\n fetchHydrants();\n const interval = setInterval(fetchHydrants, 20000);\n\n return () => clearInterval(interval);\n }, [userToken, userEmail]);\n\n const filteredHydrants = hydrants.filter(hydrant => {\n const matchesSearch = hydrant.name.toLowerCase().includes(searchTerm.toLowerCase());\n\n if (filter === 'all') return matchesSearch;\n if (filter === 'open') return hydrant.status === 'open' && matchesSearch;\n if (filter === 'closed') return hydrant.status === 'closed' && matchesSearch;\n if (filter === 'recent') return hydrant.status === 'open' && hydrant.openTimeMinutes <= 10 && matchesSearch;\n if (filter === 'moderate') return hydrant.status === 'open' && hydrant.openTimeMinutes > 10 && hydrant.openTimeMinutes <= 30 && matchesSearch;\n if (filter === 'long') return hydrant.status === 'open' && hydrant.openTimeMinutes > 30 && matchesSearch;\n\n return matchesSearch;\n });\n\n // Display PuffLoader while loading\n if (isLoading) {\n return (\n \n \n \n );\n }\n\n return (\n <>\n \n ALERT\n \n {modalMessage}\n \n \n \n \n \n\n
\n {/* Search Bar & Filter */}\n
\n setSearchTerm(e.target.value)}\n InputProps={{\n startAdornment: (\n \n \n \n ),\n }}\n fullWidth\n sx={{\n marginBottom: { xs: '10px', sm: '0' },\n marginRight: { sm: '20px' },\n }}\n />\n\n {/* Icon Filters */}\n
\n \n setFilter(prevFilter => prevFilter === 'closed' ? 'all' : 'closed')}\n >\n \n \n \n\n \n setFilter(prevFilter => prevFilter === 'recent' ? 'all' : 'recent')}\n >\n \n \n \n\n \n setFilter(prevFilter => prevFilter === 'moderate' ? 'all' : 'moderate')}\n >\n \n \n \n\n 30 min\">\n setFilter(prevFilter => prevFilter === 'long' ? 'all' : 'long')}\n >\n 30 min\"\n style={{width: '30px', height: '30px', opacity: filter === 'long' ? 1 : 0.5}}\n />\n \n \n
\n
\n\n\n {/* Hydrant Cards */}\n \n {filteredHydrants.map(hydrant => (\n \n \n \n
\n \n Hydrant {hydrant.id}\n \n \n \n \n {hydrant.status === 'open' ? (\n 30 min'}`}>\n \"Open\"/\n \n ) : (\n \n \"Closed\"/\n \n )}\n
\n\n \n {hydrant.status === 'open' ? 'Current Usage:' : 'Last Estimation:'}\n {hydrant.status === 'open' ? ` ${hydrant.currentEstimation} m³` : ` ${hydrant.consumption}`}\n \n\n \n {hydrant.status === 'open' ? 'Open for:' : 'Last Used:'}\n {hydrant.status === 'open' ? ` ${hydrant.openTime}` : ` ${hydrant.lastOpen}`}\n \n\n \n \n View on Google Maps\n \n \n
\n
\n
\n ))}\n
\n
\n \n );\n}\n\nexport default ControlPanel;\n","import React, {useState, useEffect, useRef} from 'react';\nimport {useLocation, useNavigate} from 'react-router-dom';\nimport {GoogleMap, LoadScriptNext, MarkerF, MarkerClusterer} from '@react-google-maps/api';\nimport {Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button} from '@mui/material';\nimport yellowIcon from './images/fire-hydrant-yellow.svg';\nimport orangeIcon from './images/fire-hydrant-orange.svg';\nimport redIcon from './images/fire-hydrant-red.svg';\nimport greenIcon from './images/fire_hydrante_green.svg';\nimport cluster from './images/cluster_3.png';\nimport closeIcon from './images/close.svg';\nimport {Link} from 'react-router-dom';\nimport './Map.css';\n\nconst mapContainerStyle = {height: \"100%\", width: \"100%\"};\nconst defaultCenter = {lat: 40.213180, lng: -8.888282};\n\nconst handleCopyLink = (hydrant) => {\n const googleMapsLink = `https://www.google.com/maps?q=${hydrant.latitude},${hydrant.longitude}`;\n navigator.clipboard.writeText(googleMapsLink)\n .then(() => alert('Google Maps link copied to clipboard!'))\n .catch(err => console.error('Could not copy text: ', err));\n};\n\nconst getLatitudeFromLocation = (location) => {\n const match = location.match(/q=(.*),/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst getLongitudeFromLocation = (location) => {\n const match = location.match(/,(.*)$/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst separateDateFromHours = (timestamp) => {\n const [date] = timestamp.split('T');\n return date.split('-').reverse().join('/');\n};\n\nconst getCurrentEstimation = (timestamp, debit_m3_s) => {\n const now = Date.now();\n const elapsedTimeInSeconds = (now - timestamp) / 1000;\n const estimatedVolume = debit_m3_s * elapsedTimeInSeconds;\n return parseFloat(estimatedVolume.toFixed(1));\n};\n\nconst getDifferenceInMinutesSinceIsOpen = (timestamp) => {\n const now = Date.now();\n const difference = now - timestamp;\n const minutes = Math.floor(difference / (1000 * 60));\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n let result = '';\n if (days > 0) result += `${days} day${days > 1 ? 's' : ''}, `;\n if (hours % 24 > 0) result += `${hours % 24} hour${hours % 24 > 1 ? 's' : ''}, `;\n if (minutes % 60 >= 0) result += `${minutes % 60} minute${minutes % 60 > 1 ? 's' : ''} ago`;\n\n return result.endsWith(', ') ? result.slice(0, -2) + ' ago' : result;\n};\n\nconst getColorByOpenTime = (timestamp) => {\n const now = Date.now();\n const difference = now - timestamp;\n const minutes = difference / (1000 * 60);\n\n if (minutes <= 10) return 'yellow';\n if (minutes > 10 && minutes <= 30) return 'orange';\n return 'red';\n};\n\nconst getIcon = (status, color) => {\n let iconUrl;\n if (status === 'Open') {\n iconUrl = color === 'yellow' ? yellowIcon : color === 'orange' ? orangeIcon : redIcon;\n } else {\n iconUrl = greenIcon;\n }\n\n return {\n url: iconUrl,\n scaledSize: new window.google.maps.Size(32, 32)\n };\n};\n\nconst transformApiResponse = (apiResponse) => {\n return apiResponse.map(item => ({\n id: parseInt(item.hydrant_id),\n name: `Hydrant ${item.hydrant_id}`,\n status: item.current_state ? 'Open' : 'Close',\n latitude: getLatitudeFromLocation(item.location),\n longitude: getLongitudeFromLocation(item.location),\n consumption: `${item.estimation.toFixed(2)} m³`,\n lastOpen: separateDateFromHours(item.date),\n openTime: getDifferenceInMinutesSinceIsOpen(item.open_time),\n currentEstimation: `${getCurrentEstimation(item.open_time, item.debit_m3_s)} m³`,\n openColor: getColorByOpenTime(item.open_time),\n }));\n};\n\nfunction Map({userEmail, userToken}) {\n const navigate = useNavigate();\n const location = useLocation();\n const [mapCenter, setMapCenter] = useState(defaultCenter);\n const [mapZoom, setMapZoom] = useState(12);\n const [selectedHydrant, setSelectedHydrant] = useState(null);\n const [hydrants, setHydrants] = useState([]);\n const [isBlinking, setIsBlinking] = useState(true);\n const [open, setOpen] = useState(false);\n const [modalMessage, setModalMessage] = useState(\"\");\n const hydrantsRef = useRef(hydrants);\n const mapRef = useRef(null); // Add this to get direct access to the map instance\n\n const handleOpen = (message) => {\n setModalMessage(message);\n setOpen(true);\n };\n\n const handleClose = () => setOpen(false);\n\n useEffect(() => {\n const fetchHydrants = async () => {\n try {\n const response = await fetch(`https://4cfxljq8qi.execute-api.eu-west-1.amazonaws.com/dev/hydrants?client_email=${userEmail}`, {\n method: 'GET',\n headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${userToken}`}\n });\n\n if (!response.ok) throw new Error('Network response was not ok');\n const data = await response.json();\n const newHydrants = transformApiResponse(data);\n\n newHydrants.forEach(newHydrant => {\n const oldHydrant = hydrantsRef.current.find(h => h.id === newHydrant.id);\n if (oldHydrant && oldHydrant.status !== newHydrant.status) {\n handleOpen(`Hydrant ${newHydrant.id} is now ${newHydrant.status}`);\n setSelectedHydrant(newHydrant);\n }\n });\n\n setHydrants(newHydrants);\n hydrantsRef.current = newHydrants;\n\n const hydrantId = parseInt(location.hash.replace(\"#\", \"\"), 10);\n const hydrant = newHydrants.find(h => h.id === hydrantId);\n\n if (hydrant && mapRef.current) {\n mapRef.current.panTo({lat: hydrant.latitude, lng: hydrant.longitude});\n mapRef.current.setZoom(17);\n } else {\n setMapCenter(defaultCenter);\n setMapZoom(12);\n }\n } catch (error) {\n console.error('Problem fetching hydrants:', error);\n }\n };\n\n fetchHydrants();\n const interval = setInterval(fetchHydrants, 20000);\n return () => clearInterval(interval);\n }, [location, userEmail, userToken]);\n\n useEffect(() => {\n const interval = setInterval(() => setIsBlinking(prev => !prev), 750);\n return () => clearInterval(interval);\n }, []);\n\n return (\n <>\n \n ALERT\n \n {modalMessage}\n \n \n \n \n \n\n \n mapRef.current = map} // Capture the map instance\n >\n \n {(clusterer) =>\n hydrants.map(hydrant => (\n {\n navigate(`/map#${hydrant.id}`);\n setSelectedHydrant(hydrant);\n if (mapRef.current) {\n mapRef.current.panTo({lat: hydrant.latitude, lng: hydrant.longitude});\n mapRef.current.setZoom(17);\n }\n }}\n />\n ))\n }\n \n\n {selectedHydrant && (\n
\n \n \n {selectedHydrant.name}\n \n

Status: {selectedHydrant.status}

\n

{selectedHydrant.status === 'Open' ? 'Current Usage: ' : 'Last Usage: '}\n {selectedHydrant.status === 'Open' ? selectedHydrant.openTime : selectedHydrant.lastOpen}\n

\n

\n {selectedHydrant.status === 'Open' ? 'Current Water Estimation Consumption: ' : 'Last Estimated Water Consumption: '}\n {selectedHydrant.status === 'Open' ? selectedHydrant.currentEstimation : selectedHydrant.consumption}\n

\n \n View on Google Maps\n \n
\n )}\n\n {/* Map Legend */}\n
\n
\n \"Closed\n Closed Hydrant\n
\n
\n \"Open\n Open ≤ 10 min\n
\n
\n \"Open\n Open 10-30 min\n
\n
\n \"Open\n Open > 30 min\n
\n
\n \n
\n \n );\n}\n\nexport default Map;\n","import React, { useState, useRef, useEffect } from \"react\";\nimport {\n AreaChart,\n Area,\n XAxis,\n YAxis,\n Tooltip as RechartsTooltip,\n ResponsiveContainer\n} from \"recharts\";\nimport { Card, CardContent, Typography, IconButton } from \"@mui/material\";\nimport RefreshIcon from \"../src/images/refresh.svg\";\nimport WaterDropIcon from \"@mui/icons-material/Opacity\";\nimport html2canvas from \"html2canvas\";\nimport \"./HydrantWaterConsumptionChart.css\";\n\nconst formatDate = (timestamp) => {\n const [date] = timestamp.split(\"T\");\n return date.split(\"-\").reverse().join(\"/\");\n};\n\nfunction HydrantWaterConsumptionChart({ hydrantData }) {\n const [zoomDomain, setZoomDomain] = useState(null);\n const chartRef = useRef(null);\n const chartContainerRef = useRef(null);\n \n // New state for selection\n const [selectionStart, setSelectionStart] = useState(null);\n const [selectionEnd, setSelectionEnd] = useState(null);\n const [selectionActive, setSelectionActive] = useState(false);\n const [selectionPixels, setSelectionPixels] = useState({ left: 0, width: 0 });\n const [selectionDates, setSelectionDates] = useState({ start: '', end: '' });\n // Add a new state to track the current zoom selection\n const [currentZoomSelection, setCurrentZoomSelection] = useState(null);\n\n // Add special style tag to ensure overlay is visible\n useEffect(() => {\n const style = document.createElement('style');\n style.textContent = `\n .chart-container {\n position: relative !important;\n user-select: none !important; /* Prevent text selection */\n -webkit-user-select: none !important;\n -moz-user-select: none !important;\n -ms-user-select: none !important;\n }\n \n .selection-overlay {\n position: absolute !important;\n background-color: rgba(100, 100, 100, 0.5) !important;\n border: 1px solid #444 !important;\n pointer-events: none !important;\n z-index: 9999 !important;\n /* Modified to properly align with x-axis */\n top: 10px !important;\n bottom: 30px !important; /* Adjusted to align with x-axis */\n height: auto !important; /* Let top and bottom define height */\n }\n \n .selection-label {\n position: absolute !important;\n background-color: rgba(50, 50, 50, 0.9) !important;\n color: white !important;\n padding: 5px 10px !important;\n border-radius: 4px !important;\n font-size: 13px !important;\n z-index: 10000 !important;\n pointer-events: none !important;\n transform: translateX(-50%) !important;\n }\n `;\n document.head.appendChild(style);\n return () => document.head.removeChild(style);\n }, []);\n\n // Add this effect after the style effect but before the conditional return\n useEffect(() => {\n if (chartContainerRef.current) {\n const observer = new MutationObserver(() => {\n // Find the x-axis element\n const xAxisElement = chartContainerRef.current.querySelector('.recharts-xAxis');\n if (xAxisElement) {\n // Store the y position of the x-axis in a ref\n const xAxisTop = xAxisElement.getBoundingClientRect().top;\n const containerTop = chartContainerRef.current.getBoundingClientRect().top;\n const xAxisHeight = xAxisElement.getBoundingClientRect().height;\n \n // Calculate the distance from the top of the container to the x-axis\n const distanceToXAxis = xAxisTop - containerTop - xAxisHeight;\n \n // Apply this as a CSS variable\n chartContainerRef.current.style.setProperty('--x-axis-position', `${distanceToXAxis}px`);\n }\n });\n \n observer.observe(chartContainerRef.current, { childList: true, subtree: true });\n return () => observer.disconnect();\n }\n }, []);\n\n if (!hydrantData || !hydrantData.historical_data) return null;\n\n const chartData = hydrantData.historical_data\n .map(record => ({\n date: formatDate(record.date),\n estimation: parseFloat(record.estimation.toFixed(2)),\n }))\n .sort((a, b) => new Date(a.date) - new Date(b.date));\n\n // Handle mouse events for selection\n const handleMouseDown = (e) => {\n if (!chartContainerRef.current) return;\n \n const chartRect = chartContainerRef.current.getBoundingClientRect();\n // Check if we're inside the chart area (not on axes)\n if (e.clientX < chartRect.left + 50 || e.clientX > chartRect.right - 30 || \n e.clientY < chartRect.top + 10 || e.clientY > chartRect.bottom - 20) {\n return;\n }\n \n const x = e.clientX - chartRect.left;\n \n console.log(\"Selection started at\", x);\n setSelectionStart(x);\n setSelectionEnd(x);\n setSelectionActive(true);\n \n // Calculate position and width for the overlay\n setSelectionPixels({ left: x, width: 0 });\n \n // Find closest data point\n const chartWidth = chartRect.width - 80; // Adjust for margins\n const dataIndex = Math.floor(((x - 50) / chartWidth) * chartData.length);\n if (dataIndex >= 0 && dataIndex < chartData.length) {\n setSelectionDates({ start: chartData[dataIndex].date, end: chartData[dataIndex].date });\n }\n };\n\n const handleMouseMove = (e) => {\n if (!selectionActive || !chartContainerRef.current) return;\n \n const chartRect = chartContainerRef.current.getBoundingClientRect();\n let x = Math.max(50, Math.min(e.clientX - chartRect.left, chartRect.width - 30));\n \n console.log(\"Selection moving to\", x);\n setSelectionEnd(x);\n \n // Calculate position and width for the overlay\n const left = Math.min(selectionStart, x);\n const width = Math.abs(x - selectionStart);\n setSelectionPixels({ left, width });\n \n // Calculate the percentage across the chart width for both start and end\n const chartWidth = chartRect.width - 80;\n const startPct = (selectionStart - 50) / chartWidth;\n const endPct = (x - 50) / chartWidth;\n \n // Get the sorted data based on the zoom domain or original data\n const dataToUse = zoomDomain || chartData;\n \n // Calculate indices based on the current data being displayed\n // IMPORTANT: Since X-axis is reversed, we need to invert the percentage\n // 0% (left) → last item, 100% (right) → first item\n const startIdx = Math.floor((1 - startPct) * dataToUse.length);\n const endIdx = Math.floor((1 - endPct) * dataToUse.length);\n \n // Ensure indices are within bounds\n const validStartIdx = Math.max(0, Math.min(startIdx, dataToUse.length - 1));\n const validEndIdx = Math.max(0, Math.min(endIdx, dataToUse.length - 1));\n \n if (validStartIdx !== validEndIdx) {\n // Get the actual dates from current displayed data\n const date1 = dataToUse[validStartIdx].date;\n const date2 = dataToUse[validEndIdx].date;\n \n // Convert to comparable format (YYYY-MM-DD)\n const d1Parts = date1.split('/');\n const d2Parts = date2.split('/');\n const d1 = new Date(`${d1Parts[2]}-${d1Parts[1]}-${d1Parts[0]}`);\n const d2 = new Date(`${d2Parts[2]}-${d2Parts[1]}-${d2Parts[0]}`);\n \n // Always put earlier date first\n setSelectionDates({ \n start: d1 <= d2 ? date1 : date2, \n end: d1 <= d2 ? date2 : date1 \n });\n }\n };\n\n const handleMouseUp = () => {\n if (!selectionActive) return;\n \n console.log(\"Selection complete\", selectionDates);\n \n // Use the current displayed data\n const dataToUse = zoomDomain || chartData;\n \n // Find indices for the selected dates in the current view\n const startIdx = dataToUse.findIndex(d => d.date === selectionDates.start);\n const endIdx = dataToUse.findIndex(d => d.date === selectionDates.end);\n \n if (startIdx !== -1 && endIdx !== -1 && Math.abs(startIdx - endIdx) > 0) {\n const minIdx = Math.min(startIdx, endIdx);\n const maxIdx = Math.max(startIdx, endIdx);\n const selectedData = dataToUse.slice(minIdx, maxIdx + 1);\n \n if (selectedData.length > 1) {\n console.log(\"Zooming to\", selectedData);\n \n // Set the current zoom selection to exactly match the selection dates\n setCurrentZoomSelection({\n start: selectionDates.start,\n end: selectionDates.end\n });\n \n setZoomDomain(selectedData);\n }\n }\n \n // Clear selection\n setSelectionActive(false);\n setTimeout(() => {\n setSelectionStart(null);\n setSelectionEnd(null);\n setSelectionPixels({ left: 0, width: 0 });\n }, 200);\n };\n\n const handleMouseLeave = () => {\n if (selectionActive) {\n handleMouseUp();\n }\n };\n\n const resetZoom = () => {\n setZoomDomain(null);\n setCurrentZoomSelection(null);\n }\n\n const downloadChartAsPNG = async () => {\n if (!chartRef.current) return;\n try {\n const canvas = await html2canvas(chartRef.current, { scale: 2 });\n const imgData = canvas.toDataURL(\"image/png\");\n const link = document.createElement(\"a\");\n link.href = imgData;\n link.download = `Water_Consumption_Chart_${new Date().toISOString()}.png`;\n link.click();\n } catch (error) {\n console.error(\"Error downloading chart as PNG:\", error);\n }\n };\n\n return (\n \n \n \n \n Water Consumption\n\n {zoomDomain && (\n \n \"Reset\n \n )}\n \n \n {currentZoomSelection && (\n
\n Selection: {currentZoomSelection.start} to {currentZoomSelection.end}\n
\n )}\n \n
{\n e.preventDefault(); // Prevent default text selection\n handleMouseDown(e);\n }}\n onMouseMove={(e) => {\n e.preventDefault(); // Prevent default behaviors\n handleMouseMove(e);\n }}\n onMouseUp={(e) => {\n e.preventDefault(); // Prevent default behaviors\n handleMouseUp(e);\n }}\n onMouseLeave={handleMouseLeave}\n onTouchStart={(e) => {\n // Add touch support for mobile devices\n const touch = e.touches[0];\n handleMouseDown({ clientX: touch.clientX, clientY: touch.clientY });\n }}\n onTouchMove={(e) => {\n const touch = e.touches[0];\n handleMouseMove({ clientX: touch.clientX, clientY: touch.clientY });\n }}\n onTouchEnd={() => {\n handleMouseUp();\n }}\n >\n \n \n \n \n \n \n \n \n date.split(\" \")[0]}\n reversed={true}\n tick={{ fontSize: '10px' }}\n />\n \n value >= 1e6 ? `${value / 1e6}M m³` :\n value >= 1e3 ? `${value / 1e3}K m³` :\n `${value} m³`\n }\n tick={{ fontSize: '10px' }}\n />\n `${value} m³`} />\n \n \n \n \n {/* Updated overlay div */}\n {selectionActive && selectionStart !== null && selectionEnd !== null && (\n <>\n
\n
\n {selectionDates.start} to {selectionDates.end}\n
\n \n )}\n
\n \n \n );\n}\n\nexport default HydrantWaterConsumptionChart;\n","import React from 'react';\nimport { Card, CardContent, Typography} from '@mui/material';\nimport \"./InfoHydrantCard.css\";\n\nconst InfoHydrantCard = ({ title, text, icon}) => {\n return (\n \n \n {/* Header with Icon, Title, and Info Tooltip */}\n
\n {title}{icon}\n
\n \n {text}\n \n\n
\n
\n );\n};\n\nexport default InfoHydrantCard;\n","import React, {useState, useEffect} from \"react\";\nimport {useParams} from \"react-router-dom\";\nimport WaterDropIcon from '@mui/icons-material/Opacity';\nimport SensorsIcon from '@mui/icons-material/Sensors';\nimport WavesIcon from '@mui/icons-material/Waves';\nimport DataUsageIcon from '@mui/icons-material/DataUsage';\nimport HydrantWaterConsumptionChart from \"./HydrantWaterConsumptionChart\";\nimport \"./HydrantDashboard.css\";\nimport InfoHydrantCard from \"./InfoHydrantCard\";\nimport { \n Paper, \n CardContent, \n Typography, \n Table, \n TableHead, \n TableRow, \n TableCell, \n TableBody \n} from '@mui/material';\n\nconst separateDateFromHours = (timestamp) => {\n const [date, time] = timestamp.split(\"T\");\n return `${date.split(\"-\").reverse().join(\"/\")} ${time}`;\n};\n\nfunction HydrantDashboard({userEmail, userToken}) {\n const {hydrantId} = useParams();\n const [hydrantData, setHydrantData] = useState(null);\n const [dateFilter, setDateFilter] = useState('');\n const [estimationFilter, setEstimationFilter] = useState('');\n const [estimationOperator, setEstimationOperator] = useState('=');\n\n useEffect(() => {\n const fetchHydrantHistory = async () => {\n try {\n const response = await fetch(\n `https://4cfxljq8qi.execute-api.eu-west-1.amazonaws.com/dev/hydrantSpecs?hydrant_id=${hydrantId}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${userToken}`,\n },\n }\n );\n\n if (!response.ok) throw new Error(\"Network response was not ok\");\n\n const data = await response.json();\n setHydrantData(data);\n } catch (error) {\n console.error(\"Error fetching hydrant history:\", error);\n }\n };\n\n fetchHydrantHistory();\n }, [hydrantId, userToken]);\n\n if (!hydrantData) return null;\n\n const {location, cap_registed, caps_total, debit_m3_s} = hydrantData.specs;\n const totalEstimatedConsumption = hydrantData.historical_data.reduce(\n (acc, record) => acc + record.estimation, 0\n ).toFixed(1);\n const numberOfCaps = cap_registed + \"/\" + caps_total\n const totalEstimatedConsumptionText = totalEstimatedConsumption + \" m³\"\n const debit_m3_sText = debit_m3_s + \" m³/s \"\n\n return (\n
\n
\n {/* Hydrant Info */}\n
\n \n />\n
\n
\n \n />\n
\n
\n \n />\n
\n {/* Water Consumption Chart */}\n
\n \n
\n\n {/* Hydrant Usage Table */}\n
\n \n \n
\n \n Usage History\n
\n\n {/* Fixed Header and Filters */}\n
\n \n \n \n Usage Date\n \n Estimated Consumption (m³)\n \n \n \n {/* Filter for Usage Date */}\n \n setDateFilter(e.target.value)}\n className=\"filter-input\"\n placeholder=\"Filter by Date\"\n />\n \n {/* Filter for Estimated Consumption */}\n \n
\n setEstimationOperator(e.target.value)}\n className=\"filter-select\"\n >\n \n \n \n \n setEstimationFilter(e.target.value)}\n placeholder=\"Estimation (m³)\"\n className=\"filter-input\"\n />\n
\n
\n
\n
\n
\n
\n\n {/* Scrollable Table Body */}\n
\n \n \n {hydrantData.historical_data\n .filter((record) => {\n const recordDate = separateDateFromHours(record.date).split(\" \")[0].split(\"/\").reverse().join(\"-\");\n const meetsDate = !dateFilter || recordDate === dateFilter;\n\n const estimation = parseFloat(record.estimation.toFixed(2));\n const meetsEstimation =\n !estimationFilter ||\n (estimationOperator === \"=\" && estimation === parseFloat(estimationFilter)) ||\n (estimationOperator === \"<\" && estimation < parseFloat(estimationFilter)) ||\n (estimationOperator === \">\" && estimation > parseFloat(estimationFilter));\n\n return meetsDate && meetsEstimation;\n })\n .sort((a, b) => new Date(b.date) - new Date(a.date))\n .map((record, index) => (\n \n {separateDateFromHours(record.date)}\n {parseFloat(record.estimation.toFixed(2))} m³\n \n ))}\n \n
\n
\n
\n
\n
\n\n\n
\n
\n );\n}\n\nexport default HydrantDashboard;\n","import React, { useState } from 'react';\nimport { Auth } from 'aws-amplify';\nimport { Button, TextField, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions } from '@mui/material';\nimport { useNavigate } from 'react-router-dom';\nimport './CustomSignIn.css';\nimport lettersLogo from '../src/images/letters_green.svg';\n\nfunction CustomSignIn({ setUser }) {\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n const [newPassword, setNewPassword] = useState('');\n const [isChangePassword, setIsChangePassword] = useState(false);\n const [open, setOpen] = useState(false);\n const [modalMessage, setModalMessage] = useState('');\n const [currentUser, setCurrentUser] = useState(null);\n const navigate = useNavigate();\n\n const handleSignIn = async () => {\n try {\n const user = await Auth.signIn(username, password);\n if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {\n setIsChangePassword(true);\n setCurrentUser(user);\n } else {\n setUser(user);\n navigate('/control-panel');\n }\n } catch (error) {\n console.error('Error signing in', error);\n setModalMessage('Error signing in: ' + (error.message || 'An error occurred while signing in.'));\n setOpen(true);\n }\n };\n\n const handleChangePassword = async () => {\n try {\n await Auth.completeNewPassword(currentUser, newPassword);\n navigate('/control-panel');\n } catch (error) {\n console.error('Error changing password:', error);\n setModalMessage('Error changing password: ' + (error.message || 'An error occurred while changing the password.'));\n setOpen(true);\n }\n };\n\n const handleClose = () => setOpen(false);\n\n return (\n
\n
\n \"Hydro-Defence\"\n\n {isChangePassword ? (\n <>\n setNewPassword(e.target.value)}\n InputLabelProps={{ shrink: true }}\n />\n \n \n ) : (\n <>\n setUsername(e.target.value)}\n InputLabelProps={{shrink: true}}\n margin=\"normal\"\n />\n setPassword(e.target.value)}\n InputLabelProps={{shrink: true}}\n margin=\"normal\"\n />\n Sign In\n \n \n )}\n
\n\n \n ALERT\n \n {modalMessage}\n \n \n \n \n \n
\n );\n}\n\nexport default CustomSignIn;\n","import React, { useState, useEffect } from 'react';\nimport { useNavigate, useLocation } from 'react-router-dom'; // Import useLocation\nimport './NavBar.css';\nimport logo from './images/logo_wth_text.svg';\n\nfunction Navbar({ isLoggedIn, onSignOut, pageTitle }) {\n const navigate = useNavigate();\n const location = useLocation(); // Get current location\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);\n\n // Check if the current path is '/signin'\n const isSignInPage = location.pathname === '/signin';\n \n // Track window resize for responsive behavior\n useEffect(() => {\n const handleResize = () => {\n setIsMobile(window.innerWidth <= 768);\n if (window.innerWidth > 768) {\n setIsMobileMenuOpen(false);\n }\n };\n\n window.addEventListener('resize', handleResize);\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n // Toggle mobile menu\n const toggleMobileMenu = () => {\n setIsMobileMenuOpen(!isMobileMenuOpen);\n };\n\n return (\n \n );\n}\n\nexport default Navbar;\n","import React, {useState, useRef} from 'react';\nimport Modal from 'react-bootstrap/Modal';\nimport Button from 'react-bootstrap/Button';\nimport Navbar from './NavBar';\nimport './LandingPage.css';\nimport letters from '../src/images/letters.svg';\nimport heroVideo from '../src/images/Hydro-Defence.mp4';\nimport playIcon from '../src/images/play.svg';\nimport pauseIcon from '../src/images/pause.svg';\nimport playBarIcon from '../src/images/play_white.svg';\nimport pauseBarIcon from '../src/images/pause_white.svg';\nimport muteIcon from '../src/images/mute_white.svg';\nimport unmuteIcon from '../src/images/sound_white.svg';\nimport controlPanelImage from '../src/images/control-panel-image.png';\nimport mapImage from '../src/images/map-image.png';\nimport hydrantsDashboardImage from '../src/images/hydrants-dashboard-image.png';\nimport hydrantDashboardImage from '../src/images/hydrant-dashboard-image.png';\nimport notificationImage from '../src/images/notifications.png';\n\nfunction LandingPage() {\n const [isPlaying, setIsPlaying] = useState(true);\n const [isMuted, setIsMuted] = useState(true);\n const [showControls, setShowControls] = useState(false);\n const [showCenterIcon, setShowCenterIcon] = useState(null);\n const [modalShow, setModalShow] = useState(false);\n const [selectedImage, setSelectedImage] = useState('');\n const videoRef = useRef(null);\n const [emailStatus, setEmailStatus] = useState(null);\n const [formData, setFormData] = useState({name: '', email: '', message: ''});\n\n const handleVideoClick = () => {\n if (videoRef.current) {\n if (isPlaying) {\n videoRef.current.pause();\n setShowCenterIcon(pauseIcon);\n } else {\n videoRef.current.play();\n setShowCenterIcon(playIcon);\n }\n setIsPlaying(!isPlaying);\n\n setTimeout(() => {\n setShowCenterIcon(null);\n }, 1000);\n }\n };\n\n const handleMuteUnmute = () => {\n if (videoRef.current) {\n videoRef.current.muted = !isMuted;\n setIsMuted(!isMuted);\n }\n };\n\n const handleShowImage = (imageSrc) => {\n setSelectedImage(imageSrc);\n setModalShow(true);\n };\n\n const handleChange = (e) => {\n const {name, value} = e.target;\n setFormData((prevData) => ({...prevData, [name]: value}));\n };\n\n const handleSubmit = async (e) => {\n e.preventDefault();\n try {\n const response = await fetch('https://hqiqxdc2ol.execute-api.eu-west-1.amazonaws.com/dev/sendEmail', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(formData)\n });\n\n if (response.ok) {\n setEmailStatus(\"Contact sent successfully! We'll get in touch as soon as possible!\");\n setFormData({name: '', email: '', message: ''});\n } else {\n setEmailStatus('Failed to send contact. Please try again.');\n }\n } catch (error) {\n setEmailStatus('An error occurred. Please try again later.');\n }\n };\n\n return (\n
\n \n\n
\n \"Hero\n
\n
\n

\n Reduce costs and protect resources with cutting-edge water conservation technology. Minimize\n losses and maximize efficiency.\n

\n
\n setShowControls(true)}\n onMouseLeave={() => setShowControls(false)}\n onTouchStart={() => setShowControls(true)} // Added for mobile\n >\n \n {showCenterIcon && \"Center}\n {showControls && (\n
\n
\n \n \n
\n
\n )}\n
\n
\n \n\n\n
\n

Our Solution

\n
\n {[\n {\n img: controlPanelImage,\n title: \"Control Panel\",\n desc: \"Manage and monitor all hydrants from one centralized dashboard.\"\n },\n {\n img: mapImage,\n title: \"Map Overview\",\n desc: \"Visualize all hydrant locations with real-time status updates.\"\n },\n {\n img: hydrantsDashboardImage,\n title: \"Hydrants Dashboard\",\n desc: \"Detailed insights on hydrant usage and performance metrics.\"\n },\n {\n img: hydrantDashboardImage,\n title: \"Hydrant Detail Dashboard\",\n desc: \"Comprehensive data for individual hydrant analysis and management.\"\n },\n {\n img: notificationImage,\n title: \"Real-Time Notifications\",\n desc: \"Stay informed with instant alerts on hydrant activity, ensuring timely responses to critical situations.\"\n }\n ].map((feature, index) => (\n
handleShowImage(feature.img)}>\n {feature.title}/\n

{feature.title}

\n

{feature.desc}

\n
\n ))}\n
\n
\n\n
\n

Contact Us

\n

We'd love to hear from you! Fill out the form below to contact us.

\n
\n
\n \n \n
\n \n \n
\n {emailStatus &&

{emailStatus}

}\n
\n\n setModalShow(false)} centered>\n \n Expanded View\n \n \n \"Expanded\n \n \n \n \n \n\n
\n

© {new Date().getFullYear()} Hydro-Defence. All rights reserved.

\n

Contact us: +351 937 373 623 | info@hydro-defence.com

\n
\n
\n );\n}\n\nexport default LandingPage;\n","import React, { useState, useEffect } from 'react';\nimport { Link, useLocation } from 'react-router-dom';\nimport './Sidebar.css';\nimport DashboardIcon from './images/dashboard.svg';\nimport OverviewIcon from './images/control-panel.svg';\nimport MapIcon from './images/map.svg';\n\nconst Sidebar = ({ signOut }) => {\n const location = useLocation();\n const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);\n\n // Track if we're on mobile view\n useEffect(() => {\n const handleResize = () => {\n setIsMobile(window.innerWidth <= 768);\n };\n\n window.addEventListener('resize', handleResize);\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n // Function to determine if a menu item is active\n const isActive = (path) => {\n return location.pathname === path ? 'active' : '';\n };\n\n return (\n \n );\n};\n\nexport default Sidebar;\n","import React from 'react';\nimport { Card, CardContent, Typography, Tooltip, MenuItem, Select } from '@mui/material';\nimport WaterDropIcon from '@mui/icons-material/Opacity';\nimport InfoIcon from '@mui/icons-material/Info';\nimport ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';\nimport ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';\nimport \"./TotalWaterConsumptionCard.css\";\n\nconst TotalWaterConsumptionCard = ({ totalWaterConsumption, percentageChange, isIncrease, selectedYear, onYearChange }) => {\n return (\n \n \n {/* Header with Icon, Title, and Info Tooltip */}\n
\n \n Total Water Consumption\n\n\n \n \n \n
\n {/* Consumption Value */}\n \n {totalWaterConsumption.toLocaleString()} m³\n \n\n {/* Percentage Change with Year Selector */}\n
\n {isIncrease ? : }\n {Math.abs(percentageChange.toFixed(1))}%\n\n {/* Year Dropdown (Now includes 2025) */}\n \n {[2025, 2024, 2023, 2022, 2021].map(year => (\n {year}\n ))}\n \n
\n
\n
\n );\n};\n\nexport default TotalWaterConsumptionCard;\n","import React from \"react\";\nimport { BarChart, Bar, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer } from \"recharts\";\nimport { Card, CardContent, Typography } from \"@mui/material\";\nimport FireHydrantAltIcon from '@mui/icons-material/FireHydrantAlt';\nimport \"./HydrantMonthlyConsumptionChart.css\";\n\n// Mapping month numbers to names\nconst monthNames = [\n \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\n];\n\nconst prepareMonthlyConsumptionData = (hydrants) => {\n let formattedData = {};\n\n hydrants.forEach(hydrant => {\n Object.entries(hydrant.totalEstimationByYear || {}).forEach(([year, months]) => {\n Object.entries(months).forEach(([month, consumption]) => {\n const monthIndex = parseInt(month, 10); // Ensure it's a number\n const monthName = monthNames[monthIndex]; // Get month name\n\n if (!formattedData[monthIndex]) {\n formattedData[monthIndex] = { name: monthName };\n }\n formattedData[monthIndex][year] = (formattedData[monthIndex][year] || 0) + consumption;\n });\n });\n });\n\n // Convert object to array and sort by month order\n return Object.values(formattedData).sort((a, b) => monthNames.indexOf(a.name) - monthNames.indexOf(b.name));\n};\n\nfunction HydrantMonthlyConsumptionChart({ hydrants }) {\n const data = prepareMonthlyConsumptionData(hydrants);\n\n return (\n \n \n
\n \n Hydrant Monthly Consumption\n
\n \n \n \n \n value >= 1e6 ? `${value / 1e6}M m³` :\n value >= 1e3 ? `${value / 1e3}K m³` :\n `${value} m³`}/>\n `${value.toFixed(2)} m³`}/>\n \n \n \n \n \n
\n
\n);\n}\n\nexport default HydrantMonthlyConsumptionChart;\n","import React from \"react\";\nimport { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer } from \"recharts\";\nimport { Card, CardContent, Typography } from \"@mui/material\";\nimport PlaceIcon from '@mui/icons-material/LocationCity';\nimport \"./ParishConsumptionChart.css\";\n\nconst COLORS = [\"rgba(255,160,122,0.63)\", \"rgba(123,97,255,0.63)\", \"rgba(65,182,230,0.63)\", \"rgba(50,205,50,0.63)\", \"#FFD700\"]; // Define colors\n\nconst formatData = (data) => {\n const total = data.reduce((sum, entry) => sum + entry.totalConsumption, 0);\n return data.map((entry) => ({\n ...entry,\n percentage: ((entry.totalConsumption / total) * 100).toFixed(1),\n }));\n};\n\nfunction ParishConsumptionChart({ topFreguesiasData }) {\n const formattedData = formatData(topFreguesiasData);\n const totalConsumption = formattedData.reduce((sum, entry) => sum + entry.totalConsumption, 0).toLocaleString();\n\n return (\n \n \n {/* Title with Parish Icon */}\n
\n \n Parish Consumption\n
\n\n
\n \n \n `${percent.toFixed(1)}%`}\n >\n {formattedData.map((_, index) => (\n \n ))}\n \n `${value.toLocaleString()} m³`} />\n \n \n \n
\n\n
\n
\n );\n}\n\nexport default ParishConsumptionChart;\n","import React, {useState, useEffect} from 'react';\nimport {Link} from 'react-router-dom';\nimport {\n Card, CardContent, Typography, Grid, IconButton,\n Table, TableBody, TableCell, TableHead, TableRow, Paper\n} from '@mui/material';\nimport {PuffLoader} from 'react-spinners'; // Import BounceLoader\nimport './HydrantsDashboard.css';\nimport {Accordion, AccordionSummary, AccordionDetails} from '@mui/material';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport TotalWaterConsumptionCard from './TotalWaterConsumptionCard';\nimport HydrantMonthlyConsumptionChart from \"./HydrantMonthlyConsumptionChart\";\nimport ParishConsumptionChart from \"./ParishConsumptionChart\";\nimport FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';\nimport DataUsageIcon from '@mui/icons-material/DataUsage';\nimport ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';\nimport ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';\n\n\nconst GOOGLE_API_KEY = 'AIzaSyCFpNNh-VbkBZtcmHTORaYoYjVCa-Q2P3A';\n\n// Utility Functions (No changes)\nconst getLatitudeFromLocation = (location) => {\n const match = location.match(/q=(.*),/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst getLongitudeFromLocation = (location) => {\n const match = location.match(/,(.*)$/);\n return match ? parseFloat(match[1]) : null;\n};\n\nconst separateDateFromHours = (timestamp) => {\n const [date, time] = timestamp.split('T');\n return `${date.split('-').reverse().join('/')} ${time}`;\n};\n\nconst fetchFreguesia = async (latitude, longitude) => {\n try {\n const response = await fetch(\n `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${GOOGLE_API_KEY}`\n );\n const data = await response.json();\n\n if (data.results.length > 0) {\n const addressComponents = data.results[0].address_components;\n\n let freguesiaComponent = addressComponents.find(component =>\n component.types.includes('administrative_area_level_3')\n );\n\n if (!freguesiaComponent) {\n freguesiaComponent = addressComponents.find(component =>\n component.types.includes('locality')\n );\n }\n\n return freguesiaComponent ? freguesiaComponent.long_name : 'Unknown Freguesia';\n }\n\n } catch (error) {\n console.error('Error fetching freguesia:', error);\n }\n return 'Unknown Freguesia';\n};\n\n// API Response Transformation (No changes)\nconst transformApiResponse = async (apiResponse, userToken) => {\n const transformed = await Promise.all(apiResponse.map(async (item) => {\n const latitude = getLatitudeFromLocation(item.location);\n const longitude = getLongitudeFromLocation(item.location);\n const freguesia = await fetchFreguesia(latitude, longitude);\n\n const historyResponse = await fetch(`https://4cfxljq8qi.execute-api.eu-west-1.amazonaws.com/dev/hydrantSpecs?hydrant_id=${item.hydrant_id}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${userToken}`\n }\n });\n\n let totalEstimationByYear = {}; // Store estimation per year & month\n let totalEstimation = 0;\n let openings = 0;\n\n if (historyResponse.ok) {\n const historyData = await historyResponse.json();\n\n historyData.historical_data.forEach(record => {\n const recordDate = new Date(record.timestamp);\n const recordYear = recordDate.getFullYear();\n const recordMonth = recordDate.getMonth(); // 0 (Jan) - 11 (Dec)\n\n if (!totalEstimationByYear[recordYear]) {\n totalEstimationByYear[recordYear] = {}; // Initialize year\n }\n\n if (!totalEstimationByYear[recordYear][recordMonth]) {\n totalEstimationByYear[recordYear][recordMonth] = 0; // Initialize month\n }\n\n totalEstimationByYear[recordYear][recordMonth] += record.estimation;\n totalEstimation += record.estimation;\n });\n\n openings = historyData.historical_data.length;\n } else {\n console.error(`Error fetching history for hydrant ${item.hydrant_id}`);\n }\n\n return {\n id: parseInt(item.hydrant_id),\n name: `Hydrant ${item.hydrant_id}`,\n freguesia,\n latitude,\n longitude,\n totalEstimationByYear, // Store yearly & monthly breakdown\n totalEstimation: parseFloat(totalEstimation.toFixed(2)),\n lastUsed: separateDateFromHours(item.date),\n openings\n };\n }));\n\n return transformed;\n};\n\nfunction HydrantsDashboard({userEmail, userToken}) {\n const [hydrants, setHydrants] = useState([]);\n const [sortBy, setSortBy] = useState('totalEstimation');\n const [sortOrder, setSortOrder] = useState('desc');\n const [isLoading, setIsLoading] = useState(true); // Added loading state\n const [selectedYear, setSelectedYear] = useState(new Date().getFullYear()); // Default to current year\n useEffect(() => {\n const fetchHydrants = async () => {\n try {\n const response = await fetch(`https://4cfxljq8qi.execute-api.eu-west-1.amazonaws.com/dev/hydrants?client_email=${userEmail}`, {\n method: 'GET',\n headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${userToken}`}\n });\n\n if (!response.ok) throw new Error('Network response was not ok');\n\n const data = await response.json();\n const transformedData = await transformApiResponse(data, userToken);\n setHydrants(transformedData);\n } catch (error) {\n console.error('Error fetching hydrants:', error);\n } finally {\n setIsLoading(false); // Stop loading spinner after fetch\n }\n };\n\n fetchHydrants();\n }, [userToken, userEmail]);\n\n const sortedHydrants = [...hydrants].sort((a, b) => {\n return sortOrder === 'asc' ? a[sortBy] - b[sortBy] : b[sortBy] - a[sortBy];\n });\n\n const hydrantsByFreguesia = hydrants.reduce((acc, hydrant) => {\n acc[hydrant.freguesia] = acc[hydrant.freguesia] || [];\n acc[hydrant.freguesia].push(hydrant);\n return acc;\n }, {});\n\n const downloadCSV = () => {\n const csvRows = [\n ['Hydrant', 'Total Estimation (m³)', 'Number of Openings'],\n ...sortedHydrants.map(h => [h.name, h.totalEstimation, h.openings])\n ];\n const csvContent = csvRows.map(e => e.join(\",\")).join(\"\\n\");\n const blob = new Blob([csvContent], {type: 'text/csv;charset=utf-8;'});\n const link = document.createElement(\"a\");\n link.href = URL.createObjectURL(blob);\n link.download = \"hydrants_data.csv\";\n link.click();\n };\n\n\n // ✅ Year selection handler\n const handleYearChange = (event) => {\n setSelectedYear(parseInt(event.target.value)); // Ensure it's a number\n };\n\n // ✅ Ensure `lastUsed` is correctly parsed into a Date object before filtering\n const filteredHydrants = hydrants.filter(h => {\n // Extract date and convert it properly\n const dateParts = h.lastUsed.split(' ')[0].split('/');\n if (dateParts.length !== 3) return false; // Skip invalid dates\n const hydrantYear = parseInt(dateParts[2]); // Extract the year correctly\n return hydrantYear === selectedYear;\n });\n\n// ✅ Correctly sum the total estimation for the selected year\n // ✅ Filter hydrants by selected year and sum their values correctly\n const totalWaterConsumption = hydrants.reduce((sum, h) => {\n const yearData = h.totalEstimationByYear?.[selectedYear]; // Get data for selected year\n if (!yearData) return sum; // Skip if no data for this year\n\n // Sum up all monthly values (ensure default to 0)\n const yearlyTotal = Object.values(yearData).reduce((monthSum, monthValue) => monthSum + (monthValue ?? 0), 0);\n\n return sum + yearlyTotal;\n }, 0);\n\n\n// ✅ Fetch last year's consumption dynamically\n const lastYearConsumption = hydrants.reduce((sum, h) => {\n const yearData = (h.totalEstimationByYear?.[selectedYear- 1] || 0); // Get data for selected year\n if (!yearData) return sum; // Skip if no data for this year\n\n // Sum up all monthly values (ensure default to 0)\n const yearlyTotal = Object.values(yearData).reduce((monthSum, monthValue) => monthSum + (monthValue ?? 0), 0);\n\n return sum + yearlyTotal; }, 0);\n\n// ✅ Calculate percentage change correctly\n const percentageChange = lastYearConsumption\n ? ((totalWaterConsumption - lastYearConsumption) / lastYearConsumption) * 100\n : 0;\n\n const isIncrease = percentageChange >= 0;\n\n const topFreguesiasData = Object.entries(hydrantsByFreguesia)\n .map(([freguesia, hydrants]) => ({\n freguesia,\n totalConsumption: hydrants.reduce((sum, h) => sum + h.totalEstimation, 0)\n }))\n .sort((a, b) => b.totalConsumption - a.totalConsumption)\n .slice(0, 5);\n\n const topHydrantsData = hydrants\n .sort((a, b) => b.totalEstimation - a.totalEstimation)\n .slice(0, 5)\n .map(hydrant => ({name: hydrant.name, value: hydrant.totalEstimation}));\n\n return (\n
\n {isLoading ? (\n \n \n \n ) : (\n
\n {/* Row 1 */}\n
\n \n \n
\n \n Hydrants List\n
\n\n {Object.keys(hydrantsByFreguesia).map(freguesia => (\n \n } className=\"accordion-summary\">\n {freguesia}\n \n \n {hydrantsByFreguesia[freguesia].map(hydrant => (\n \n \n {hydrant.name}\n \n \n ))}\n \n \n ))}\n
\n
\n
\n\n
\n \n
\n\n
\n \n
\n\n {/* Usage Table spans cells 2-2, 2-3, 3-2, and 3-3 */}\n
\n \n \n
\n \n Usages\n
\n\n \n \n \n Hydrant Name\n \n Total Consumption Estimation (m³)\n {\n setSortBy('totalEstimation');\n setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');\n }}>\n {sortOrder === 'asc' ? : }\n \n \n \n Number of Usages\n {\n setSortBy('openings');\n setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');\n }}>\n {sortOrder === 'asc' ? : }\n \n \n \n \n \n {sortedHydrants.map(hydrant => (\n \n \n \n {hydrant.name}\n \n \n {hydrant.totalEstimation.toFixed(2)} m³\n {hydrant.openings}\n \n ))}\n \n
\n
\n
\n
\n\n {/* Row 3 */}\n
\n \n
\n
\n )}\n
\n );\n}\nexport default HydrantsDashboard;\n","import React, { useState, useEffect } from 'react';\nimport './App.css';\nimport { HashRouter as Router, Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport ControlPanel from './ControlPanel';\nimport Map from './Map';\nimport HydrantDashboard from './HydrantDashboard';\nimport { Auth } from 'aws-amplify';\nimport CustomSignIn from './CustomSignIn';\nimport LandingPage from './LandingPage';\nimport Navbar from './NavBar';\nimport Sidebar from './Sidebar';\nimport HydrantsDashboard from './HydrantsDashboard';\n\n// Component to handle dynamic page titles\nfunction AppContent({ user, userEmail, userToken, signOut, setUser }) {\n const location = useLocation();\n\n const getPageTitle = (path) => {\n if (path.startsWith('/hydrant/')) {\n const hydrantId = path.split('/hydrant/')[1];\n return hydrantId ? `Hydrant ${hydrantId}` : 'Hydrant Details';\n }\n switch (path) {\n case '/control-panel': return 'Control Panel';\n case '/map': return 'Map';\n case '/hydrants-dashboard': return 'Dashboard';\n default: return 'Fire Hydrant Management';\n }\n };\n\n const pageTitle = getPageTitle(location.pathname);\n\n return (\n <>\n \n {user ? (\n
\n \n
\n \n } />\n } />\n } />\n } />\n } />\n\n \n
\n
\n ) : (\n \n } />\n } />\n } />\n \n )}\n \n );\n}\n\nfunction App() {\n const [user, setUser] = useState(null);\n const [userEmail, setUserEmail] = useState(null);\n const [userToken, setUserToken] = useState(null);\n const [loading, setLoading] = useState(true); // Added loading state\n\n useEffect(() => {\n const fetchUserDetails = async () => {\n try {\n const currentUser = await Auth.currentAuthenticatedUser();\n const jwtToken = currentUser.signInUserSession.idToken.jwtToken;\n const email = currentUser.attributes.email;\n\n setUser(currentUser);\n setUserToken(jwtToken);\n setUserEmail(email);\n } catch {\n setUser(null);\n setUserToken(null);\n setUserEmail(null);\n }finally {\n setLoading(false); // Set loading to false after check\n }\n };\n\n fetchUserDetails();\n }, []);\n\n const signOut = async () => {\n try {\n await Auth.signOut();\n setUser(null);\n window.location.reload();\n } catch (error) {\n console.error('Error signing out: ', error);\n }\n };\n // While loading, show a slightly improved loading indicator\n if (loading) {\n return
Loading...
; // You can style this class in App.css\n }\n return (\n \n \n \n );\n}\n\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","/* eslint-disable */\n// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.\n\nconst awsmobile = {\n \"aws_project_region\": \"eu-west-1\",\n \"aws_cognito_identity_pool_id\": \"eu-west-1:b6378544-cac6-4dd6-8e26-bec15376f990\",\n \"aws_cognito_region\": \"eu-west-1\",\n \"aws_user_pools_id\": \"eu-west-1_GKYh0qEn8\",\n \"aws_user_pools_web_client_id\": \"6r80ta4ho6pi0rnoi6li0j07cf\",\n \"oauth\": {},\n \"aws_cognito_username_attributes\": [\n \"EMAIL\"\n ],\n \"aws_cognito_social_providers\": [],\n \"aws_cognito_signup_attributes\": [\n \"EMAIL\"\n ],\n \"aws_cognito_mfa_configuration\": \"OFF\",\n \"aws_cognito_mfa_types\": [\n \"SMS\"\n ],\n \"aws_cognito_password_protection_settings\": {\n \"passwordPolicyMinLength\": 8,\n \"passwordPolicyCharacters\": []\n },\n \"aws_cognito_verification_mechanisms\": [\n \"EMAIL\"\n ]\n};\n\n\nexport default awsmobile;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://cra.link/PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://cra.link/PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then((registration) => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://cra.link/PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch((error) => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then((response) => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then((registration) => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then((registration) => {\n registration.unregister();\n })\n .catch((error) => {\n console.error(error.message);\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\nimport { Amplify } from \"aws-amplify\";\nimport config from \"./aws-exports\";\nimport * as serviceWorkerRegistration from './serviceWorkerRegistration';\n\nAmplify.configure(config);\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(\n \n \n \n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more: https://cra.link/PWA\nserviceWorkerRegistration.register();\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}