{"version":3,"file":"6529.js","sources":["webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/state/index.ts","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/icons/GreenMarker.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/icons/OrangeMarker.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/icons/RedMarker.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/icons/MajorWorksMarker.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/icons/MarkerCluster.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/Legend/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/map_utils/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/Search/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/SidePanel/Accordion/AccordionContent.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/SidePanel/Accordion/AccordionSection.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/SidePanel/Accordion/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/SidePanel/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/hooks/useMapData/index.ts","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/hooks/useGoogleMap/index.ts","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/hooks/useGeolocation/index.ts","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/hooks/useGooglePlacesAutoComplete/index.ts","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/Map/index.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/components/App.tsx","webpack://frontend/./src/react_repo/components/Outages/OutagesMapNew/index.tsx","webpack://frontend/./src/react_repo/components/residential/hooks/index.tsx","webpack://frontend/./src/react_repo/components/residential/shared/ErrorOrLoading/index.tsx","webpack://frontend/./src/react_repo/components/residential/shared/NavBtn/index.tsx","webpack://frontend/./src/react_repo/components/residential/shared/Overlay/index.tsx","webpack://frontend/./src/react_repo/components/residential/shared/Spinner/index.tsx"],"sourcesContent":["export function updateStore(state, payload) {\r\n return {\r\n ...state,\r\n ...payload\r\n }\r\n}\r\n","import { Icon, makeIconsString } from \"utils/Icon\"\r\n\r\nconst GreenMarker = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const greenMarkerString = makeIconsString(GreenMarker)\r\n\r\nexport default GreenMarker\r\n","import { Icon, makeIconsString } from \"utils/Icon\"\r\n\r\nconst OrangeMarker = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const orangeMarkerString = makeIconsString(OrangeMarker)\r\n\r\nexport default OrangeMarker\r\n","import { Icon, makeIconsString } from \"utils/Icon\"\r\n\r\nconst RedMarker = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const redMarkerString = makeIconsString(RedMarker)\r\n\r\nexport default RedMarker\r\n","import { Icon, makeIconsString } from \"utils/Icon\"\r\n\r\nconst MajorWorksMarker = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const majorWorksString = makeIconsString(MajorWorksMarker)\r\n\r\nexport default MajorWorksMarker\r\n","const MarkerCluster = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\n\r\n\r\nexport default MarkerCluster\r\n","import GreenMarker from '../../icons/GreenMarker'\r\nimport OrangeMarker from '../../icons/OrangeMarker'\r\nimport RedMarker from '../../icons/RedMarker'\r\nimport MajorWorksMarker from '../../icons/MajorWorksMarker'\r\nimport MarkerCluster from '../../icons/MarkerCluster'\r\n\r\nconst Legend = () => {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport default Legend\r\n","// @ts-nocheck\r\nimport MarkerClusterer from '@google/markerclusterer'\r\nimport {\r\n ContentType1,\r\n CreatePolygonType,\r\n SetClustererType,\r\n AnyUseRef,\r\n MapApiPropsType,\r\n CountTextType,\r\n OutageAreasType,\r\n RemoveMarkersType,\r\n AddMarkerType,\r\n PlaceChangedType,\r\n FeatureType\r\n} from '../interfaces/index'\r\n\r\nimport greenMarker from '../icons/greenMarker.svg'\r\nimport orangeMarker from '../icons/orangeMarker.svg'\r\nimport redMarker from '../icons/redMarker.svg'\r\nimport majorWorksMarker from '../icons/majorWorks.svg'\r\n\r\nexport const updateGTM = (category: string, action: string, label?: string) => {\r\n if ((global as any).digitalData) {\r\n ; (global as any).digitalData.tool = {\r\n name: 'outages map',\r\n category,\r\n action,\r\n label\r\n }\r\n ; (global as any).dataLayer.push({ event: 'outageMapSearch' })\r\n }\r\n}\r\n\r\nexport function getTitle(status: string): string {\r\n switch (status) {\r\n case 'Completed':\r\n case 'Closed':\r\n return 'Recently Completed Works'\r\n case 'Active':\r\n return 'Current Water Outage'\r\n case 'Registered':\r\n return 'Upcoming Water Outage'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport function getMessage(planned: boolen) {\r\n return planned ? 'Planned water on: ' : 'Estimated water on: '\r\n}\r\n\r\nexport function getDetails(content: ContentType1): string | null {\r\n switch (content.status) {\r\n case 'Completed':\r\n case 'Closed':\r\n return getLocalDateTimeString(parseDateTime(content.actual_on))\r\n case 'Major':\r\n case 'Active':\r\n return getLocalDateTimeString(parseDateTime(content.estimated_on))\r\n case 'Registered':\r\n if (content.extension === 'True' && content.estimated_on) {\r\n return getLocalDateTimeString(parseDateTime(content.estimated_on))\r\n }\r\n if (content.planned_on) {\r\n return getLocalDateTimeString(parseDateTime(content.planned_on))\r\n } else if (content.estimated_on) {\r\n return getLocalDateTimeString(parseDateTime(content.estimated_on))\r\n }\r\n return ''\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport const createPolygons = ({\r\n features,\r\n polygons,\r\n markers,\r\n markerEvents,\r\n infoWindow,\r\n map,\r\n state\r\n}: CreatePolygonType) => {\r\n if (features && google.maps) {\r\n features.forEach((d) => {\r\n // Calculate outage type\r\n const type = getOutageType(d?.properties?.status)\r\n if (type && Array.isArray(d?.geometry?.coordinates)) {\r\n // Create polygons for outages and add to map\r\n const coordinates = d.geometry.coordinates\r\n for (let i = 0; i < coordinates.length; i++) {\r\n if (Array.isArray(coordinates[0])) {\r\n const paths = coordinates[i].reduce(\r\n (arr: Array, tuple: Array) => {\r\n const latLng = new google.maps.LatLng(tuple[1], tuple[0])\r\n return arr.concat(latLng)\r\n },\r\n []\r\n )\r\n\r\n const polygon = new google.maps.Polygon({\r\n status: d.properties.status,\r\n paths: paths,\r\n strokeColor: type && type.color ? type.color : '#FF0000',\r\n strokeOpacity: 0.8,\r\n strokeWeight: 2,\r\n fillColor: type && type.color ? type.color : '#FF0000',\r\n fillOpacity: 0.35\r\n })\r\n polygons?.current.push(polygon)\r\n\r\n // Create feature and add as a marker\r\n const feature = {\r\n position: polygon.getApproximateCenter(),\r\n status: d.properties.status,\r\n region: d.properties.region,\r\n end_date: d.properties.end_date,\r\n town: d.properties.town,\r\n start_date: d.properties.start_date,\r\n extension_status: d.properties.extension_status,\r\n estimated_off: d.properties.estimated_off,\r\n start_date_interruption: d.properties.start_date_interruption,\r\n end_date_interruption: d.properties.end_date_interruption,\r\n estimated_on: d.properties.estimated_on,\r\n planned_off: d.properties.planned_off,\r\n planned_on: d.properties.planned_on,\r\n actual_off: d.properties.actual_off,\r\n actual_on: d.properties.actual_on,\r\n extension: d.properties.extension,\r\n affected_suburbs: d.properties.affected_suburbs,\r\n affected_customers_outage: d.properties.affected_customers_outage,\r\n name: d?.properties.name,\r\n notes: d?.properties.notes,\r\n url: d?.properties.url,\r\n outagesFormUrl: state?.outagesFormUrl\r\n }\r\n addMarker({\r\n feature,\r\n markers,\r\n markerEvents,\r\n infoWindow,\r\n\r\n map\r\n })\r\n\r\n // Add polygon to map\r\n polygon.setMap(map)\r\n } else {\r\n const myLatlng = new google.maps.LatLng(\r\n coordinates[0],\r\n coordinates[1]\r\n )\r\n // Create feature and add as a marker\r\n const feature = {\r\n position: myLatlng,\r\n status: d.properties.status,\r\n region: d.properties.region,\r\n end_date: d.properties.end_date,\r\n town: d.properties.town,\r\n start_date: d.properties.start_date,\r\n extension_status: d.properties.extension_status,\r\n estimated_off: d.properties.estimated_off,\r\n start_date_interruption: d.properties.start_date_interruption,\r\n end_date_interruption: d.properties.end_date_interruption,\r\n estimated_on: d.properties.estimated_on,\r\n planned_off: d.properties.planned_off,\r\n planned_on: d.properties.planned_on,\r\n actual_off: d.properties.actual_off,\r\n actual_on: d.properties.actual_on,\r\n extension: d.properties.extension,\r\n affected_suburbs: d.properties.affected_suburbs,\r\n affected_customers_outage: d.properties.affected_customers_outage,\r\n name: d?.properties.name,\r\n notes: d?.properties.notes,\r\n url: d?.properties.url,\r\n outagesFormUrl: state?.outagesFormUrl\r\n }\r\n addMarker({\r\n feature,\r\n markers,\r\n markerEvents,\r\n infoWindow,\r\n\r\n map\r\n })\r\n }\r\n }\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport const setClusterer = ({ markers, clusterer, map }: SetClustererType) => {\r\n // Add a marker clusterer to manage the markers\r\n clusterer.current = new MarkerClusterer(map, markers?.current, {\r\n zoom: map.getZoom() ?? 15,\r\n imagePath:\r\n 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'\r\n })\r\n}\r\n\r\nexport const setMap =\r\n (markers: AnyUseRef, map: google.maps.Map) => (position: any) => {\r\n map.setZoom(15)\r\n map.setCenter(position)\r\n for (let i = 0; i < markers?.current.length; i++) {\r\n const marker = markers?.current[i]\r\n if (\r\n position.lat() === marker.position.lat() &&\r\n position.lng() === marker.position.lng()\r\n ) {\r\n new google.maps.event.trigger(marker, 'click', { skipGtm: true })\r\n }\r\n }\r\n }\r\n\r\nexport const createCountText = ({\r\n completedCount,\r\n upcomingCount,\r\n outageCount,\r\n majorCount\r\n}: CountTextType) => {\r\n let text = ''\r\n if (majorCount) {\r\n text = text + `${majorCount} major work${majorCount > 1 ? 's' : ''}, `\r\n }\r\n if (outageCount) {\r\n text = text + `${outageCount} outage${outageCount > 1 ? 's' : ''}, `\r\n }\r\n if (completedCount) {\r\n text =\r\n text +\r\n `${completedCount} recently completed work${completedCount > 1 ? 's' : ''\r\n }, `\r\n }\r\n if (upcomingCount) {\r\n text =\r\n text +\r\n `${upcomingCount} upcoming water outage${upcomingCount > 1 ? 's' : ''}, `\r\n }\r\n return text.substring(0, text.length - 2)\r\n}\r\n\r\nexport const createGuid = () => {\r\n function s4() {\r\n return Math.floor((1 + Math.random()) * 0x10000)\r\n .toString(16)\r\n .substring(1)\r\n }\r\n return (\r\n s4() +\r\n s4() +\r\n '-' +\r\n s4() +\r\n '-' +\r\n s4() +\r\n '-' +\r\n s4() +\r\n '-' +\r\n s4() +\r\n s4() +\r\n s4()\r\n )\r\n}\r\n\r\nexport const getPin = (status: string) => {\r\n switch (status) {\r\n case 'Active':\r\n return redMarker\r\n case 'Registered':\r\n return orangeMarker\r\n case 'Major':\r\n return majorWorksMarker\r\n default:\r\n return greenMarker\r\n }\r\n}\r\n\r\nexport const removeMarkers = ({\r\n polygons,\r\n markers,\r\n markerEvents,\r\n clusterer,\r\n status\r\n}: RemoveMarkersType) => {\r\n // Iterate between each polygon and clear map that are removed\r\n const newPolygons = polygons?.current.reduce((array: Array, curr: any) => {\r\n if (curr.status === status || status === 'all' || curr.type === status) {\r\n curr.setMap(null)\r\n } else {\r\n array.push(curr)\r\n }\r\n return array\r\n }, [])\r\n\r\n // Iterate between each marker and clear marker that are removed\r\n const newMarkers = markers?.current.reduce((array: Array, curr: any) => {\r\n if (curr.markerData.status === status || status === 'all') {\r\n curr.setMap(null)\r\n clusterer?.current.removeMarker(curr)\r\n const position = curr.position.lat() + '-' + curr.position.lng()\r\n const eventListener = markerEvents?.current[position]\r\n google.maps && new google.maps.event.removeListener(eventListener)\r\n markerEvents.current[position] = null\r\n } else {\r\n array.push(curr)\r\n }\r\n return array\r\n }, [])\r\n\r\n markers.current = newMarkers\r\n polygons.current = newPolygons\r\n}\r\n\r\n// here\r\n\r\nexport const createOutageAreas = ({ markers, state }: OutageAreasType) => {\r\n // Create list of outages\r\n const tempOutages = markers?.current.reduce((array: Array, curr: any) => {\r\n if (\r\n (curr.markerData.status === 'Active' && state?.active) ||\r\n (curr.markerData.status === 'Completed' && state?.completed) ||\r\n (curr.markerData.status === 'Closed' && state?.completed) ||\r\n (curr.markerData.status === 'Major' && state?.major) ||\r\n (curr.markerData.status === 'Registered' && state?.registered)\r\n ) {\r\n // Iterate between all affected suburbs and add to result\r\n if (\r\n curr.markerData.affected_suburbs &&\r\n curr.markerData.affected_suburbs.length > 0\r\n ) {\r\n curr.markerData.affected_suburbs.forEach((s: string) => {\r\n array.push({\r\n content: curr.markerData,\r\n label: s\r\n })\r\n })\r\n }\r\n }\r\n return array\r\n }, [])\r\n\r\n // Create list of outage areas\r\n const tempOutageAreas = tempOutages.reduce((array: Array, curr: any) => {\r\n const suburb = curr.label\r\n const { status } = curr.content\r\n const index = array.map((x) => x.suburb).indexOf(suburb)\r\n if (index >= 0) {\r\n // Increment the counts and add to outages list\r\n if (status === 'Completed' || status === 'Closed') {\r\n array[index].completedCount++\r\n }\r\n if (status === 'Registered') {\r\n array[index].upcomingCount++\r\n }\r\n if (status === 'Active') {\r\n array[index].outageCount++\r\n }\r\n if (status === 'Major') {\r\n array[index].majorCount++\r\n }\r\n array[index].outages.push(curr)\r\n } else {\r\n // Add new suburb and sort\r\n array.push({\r\n suburb,\r\n isOpen: false,\r\n completedCount: status === 'Completed' || status === 'Closed' ? 1 : 0,\r\n upcomingCount: status === 'Registered' ? 1 : 0,\r\n outageCount: status === 'Active' ? 1 : 0,\r\n majorCount: status === 'Major' ? 1 : 0,\r\n outages: [curr]\r\n })\r\n array.sort((x, y) => {\r\n const xSuburb = x.suburb\r\n const ySuburb = y.suburb\r\n if (xSuburb < ySuburb) {\r\n return -1\r\n }\r\n if (xSuburb > ySuburb) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n }\r\n return array\r\n }, [])\r\n return tempOutageAreas\r\n}\r\n\r\nexport const resetMap = (map: google.maps.Map, ref: AnyUseRef) => {\r\n if (ref?.current) {\r\n ref?.current?.close()\r\n }\r\n map.setCenter({ lat: -27.2008942, lng: 122.0053344 })\r\n map.setZoom(4)\r\n}\r\n\r\nexport const getOutageType = (\r\n status: string\r\n): { type: string; color: string } | undefined => {\r\n if (status === 'Completed' || status === 'Closed') {\r\n return { type: 'complete', color: getColor.complete }\r\n }\r\n if (status === 'Active') {\r\n return { type: 'outage', color: getColor.outage }\r\n }\r\n if (status === 'Registered') {\r\n return { type: 'planned', color: getColor.planned }\r\n }\r\n if (status === 'Major') {\r\n return { type: 'major', color: getColor.major }\r\n }\r\n}\r\n\r\nexport const getColor: { [index: string]: string } = {\r\n outage: '#dd1e35',\r\n complete: '#6fbf4a',\r\n planned: '#fcb526',\r\n major: '#f57e3a'\r\n}\r\n\r\n// Add new methods to the Polygon object\r\nexport const addPolygonFeature = () => {\r\n // Calculate the bounding box of the polygon\r\n google.maps.Polygon.prototype.getBoundingBox = function () {\r\n const bounds = new google.maps.LatLngBounds()\r\n this.getPath().forEach(function (element: any) {\r\n bounds.extend(element)\r\n })\r\n return bounds\r\n }\r\n\r\n // Calculate the approximate centre of the polygon\r\n\r\n google.maps.Polygon.prototype.getApproximateCenter = function () {\r\n let boundsHeight = 0,\r\n boundsWidth = 0,\r\n centrePoint,\r\n heightIncr = 0,\r\n maxSearchSteps = 10,\r\n n = 1,\r\n northWest,\r\n polygonBounds = this.getBoundingBox(),\r\n testPos,\r\n widthIncr = 0\r\n\r\n // Get polygon centre point\r\n centrePoint = polygonBounds.getCenter()\r\n if (new google.maps.geometry.poly.containsLocation(centrePoint, this)) {\r\n // Nothing to do centre point is in polygon use it as is\r\n return centrePoint\r\n } else {\r\n // Calculate NorthWest point so we can work out height of polygon NW->SE\r\n\r\n northWest = new google.maps.LatLng(\r\n polygonBounds.getNorthEast().lat(),\r\n polygonBounds.getSouthWest().lng()\r\n )\r\n\r\n // Work out how tall and wide the bounds are and what our search\r\n // increment will be\r\n boundsHeight = new google.maps.geometry.spherical.computeDistanceBetween(\r\n northWest,\r\n polygonBounds.getSouthWest()\r\n )\r\n heightIncr = boundsHeight / maxSearchSteps\r\n boundsWidth = new google.maps.geometry.spherical.computeDistanceBetween(\r\n northWest,\r\n polygonBounds.getNorthEast()\r\n )\r\n widthIncr = boundsWidth / maxSearchSteps\r\n\r\n // Expand out from centre point and find a point within polygon at 0, 90,\r\n // 180, 270 degrees\r\n for (; n <= maxSearchSteps; n++) {\r\n // Test point North of centre point\r\n testPos = new google.maps.geometry.spherical.computeOffset(\r\n centrePoint,\r\n heightIncr * n,\r\n 0\r\n )\r\n if (new google.maps.geometry.poly.containsLocation(testPos, this)) {\r\n break\r\n }\r\n\r\n // Test point East of centre point\r\n testPos = new google.maps.geometry.spherical.computeOffset(\r\n centrePoint,\r\n widthIncr * n,\r\n 90\r\n )\r\n if (new google.maps.geometry.poly.containsLocation(testPos, this)) {\r\n break\r\n }\r\n\r\n // Test point South of centre point\r\n testPos = new google.maps.geometry.spherical.computeOffset(\r\n centrePoint,\r\n heightIncr * n,\r\n 180\r\n )\r\n if (new google.maps.geometry.poly.containsLocation(testPos, this)) {\r\n break\r\n }\r\n\r\n // Test point West of centre point\r\n testPos = new google.maps.geometry.spherical.computeOffset(\r\n centrePoint,\r\n widthIncr * n,\r\n 270\r\n )\r\n if (new google.maps.geometry.poly.containsLocation(testPos, this)) {\r\n break\r\n }\r\n }\r\n return testPos\r\n }\r\n }\r\n}\r\n\r\nexport const addMarker = ({\r\n feature,\r\n markers,\r\n markerEvents,\r\n infoWindow,\r\n map\r\n}: AddMarkerType) => {\r\n // Create marker and add to markers\r\n\r\n const marker = new google.maps.Marker({\r\n markerData: feature,\r\n position: feature.position,\r\n optimized: false,\r\n icon: getIcon(feature.status, google.maps),\r\n\r\n animation: google.maps.Animation.DROP,\r\n map: map\r\n })\r\n markers?.current.push(marker)\r\n\r\n // Create info window\r\n\r\n const info = new google.maps.InfoWindow({\r\n content: createTemplate(feature)\r\n })\r\n\r\n // Add event listener to the marker to display info window when clicked\r\n const eventListener = new google.maps.event.addListener(\r\n marker,\r\n 'click',\r\n ({ skipGtm }: { skipGtm: boolean }) => {\r\n if (!skipGtm) {\r\n updateGTM(\r\n 'marker click',\r\n joinList(feature.affected_suburbs),\r\n feature.status\r\n )\r\n }\r\n\r\n if (infoWindow?.current) {\r\n infoWindow?.current.close()\r\n }\r\n\r\n infoWindow.current = info\r\n map.setCenter(marker.getPosition())\r\n map.setZoom(15)\r\n infoWindow?.current.open(map, marker)\r\n }\r\n )\r\n\r\n // Add event listener to the marker events\r\n const position = feature.position.lat() + '-' + feature.position.lng()\r\n markerEvents.current[position] = eventListener\r\n}\r\n\r\n// When the user selects a city, get the place details for the city and\r\n// zoom the map in on the city.\r\nexport const onPlaceChanged = ({ autocomplete, map }: PlaceChangedType) => {\r\n const place = autocomplete.getPlace()\r\n if (place && place.geometry) {\r\n map.panTo(place.geometry.location)\r\n map.setZoom(13)\r\n }\r\n}\r\n\r\nexport const getIcon = (status: string, google: MapApiPropsType) => {\r\n if (status === 'Completed' || status == 'Closed') {\r\n return {\r\n url: greenMarker,\r\n\r\n scaledSize: new google.Size(50, 50)\r\n }\r\n }\r\n if (status === 'Active') {\r\n return {\r\n url: redMarker,\r\n\r\n scaledSize: new google.Size(50, 50)\r\n }\r\n }\r\n if (status === 'Registered') {\r\n return {\r\n url: orangeMarker,\r\n\r\n scaledSize: new google.Size(50, 50)\r\n }\r\n }\r\n if (status === 'Major') {\r\n return {\r\n url: majorWorksMarker,\r\n\r\n scaledSize: new google.Size(50, 50)\r\n }\r\n }\r\n}\r\n\r\nexport const parseDateTime = (dateString: string) => {\r\n const components = dateString.split(' ')\r\n if (components.length !== 2) return null\r\n const dateComponents = components[0].split('/')\r\n if (dateComponents.length !== 3) return null\r\n const timeComponents = components[1].split(':')\r\n if (timeComponents.length !== 3) return null\r\n return new Date(\r\n parseInt(dateComponents[2]),\r\n parseInt(dateComponents[1]) - 1,\r\n parseInt(dateComponents[0]),\r\n parseInt(timeComponents[0]),\r\n parseInt(timeComponents[1]),\r\n parseInt(timeComponents[0])\r\n )\r\n}\r\n\r\nexport const getLocalDateTimeString = (dateValue: Date | null) => {\r\n if (!dateValue) return null\r\n const date = dateValue.getDate()\r\n const months = dateValue.getMonth() + 1\r\n const years = dateValue.getFullYear()\r\n let hours = dateValue.getHours()\r\n let minutes: number | string = dateValue.getMinutes()\r\n const ampm = hours >= 12 ? 'pm' : 'am'\r\n hours = hours % 12\r\n hours = hours ? hours : 12 // the hour '0' should be '12'\r\n minutes = minutes < 10 ? '0' + String(minutes) : String(minutes)\r\n return (\r\n (date < 10 ? '0' + date : date) +\r\n '/' +\r\n (months < 10 ? '0' + months : months) +\r\n '/' +\r\n years +\r\n ' ' +\r\n hours +\r\n ':' +\r\n minutes +\r\n ' ' +\r\n ampm\r\n )\r\n}\r\n\r\nfunction joinList(listArray: Array) {\r\n if (!listArray || listArray.length === 0) return ''\r\n if (listArray.length === 1) return listArray[0]\r\n if (listArray.length === 2) return listArray[0] + ' and ' + listArray[1]\r\n\r\n const lastItem = listArray.slice(listArray.length - 1)\r\n const otherItems = listArray.slice(0, listArray.length - 1)\r\n return otherItems.join(', ') + ' and ' + lastItem\r\n}\r\n\r\nexport const createTemplate = (details: FeatureType) => {\r\n const lastUpdated = getLocalDateTimeString(new Date())\r\n const affectedSuburbs = joinList(details.affected_suburbs)\r\n const outagesFormUrl = details.outagesFormUrl\r\n if (details.status === 'Completed' || details.status === 'Closed') {\r\n let actualOn = ''\r\n if (details.actual_on) {\r\n actualOn = getLocalDateTimeString(\r\n parseDateTime(details.actual_on)\r\n ) as string\r\n }\r\n return `
\r\n
Recently completed works
\r\n
Work has recently been completed at ${affectedSuburbs}
\r\n
\r\n Maintenance was recently carried out at ${affectedSuburbs}, service has\r\n been restored and water was turned back on at ${actualOn}.\r\n
\r\n
\r\n As a result of the maintenance, you may notice discoloured water.\r\n Running a tap for approximately 2 minutes should return water to\r\n normal. If water does not return to normal, please contact us at 13 13\r\n 75.\r\n
\r\n
`\r\n }\r\n if (details.status === 'Active') {\r\n let outageStart = ''\r\n if (details.actual_off) {\r\n outageStart = getLocalDateTimeString(\r\n parseDateTime(details.actual_off)\r\n ) as string\r\n } else if (details.estimated_off) {\r\n outageStart = getLocalDateTimeString(\r\n parseDateTime(details.estimated_off)\r\n ) as string\r\n }\r\n let outageEnd = ''\r\n if (details.planned_on) {\r\n outageEnd = getLocalDateTimeString(\r\n parseDateTime(details.planned_on)\r\n ) as string\r\n } else if (details.estimated_on) {\r\n outageEnd = getLocalDateTimeString(\r\n parseDateTime(details.estimated_on)\r\n ) as string\r\n }\r\n\r\n if (details.extension === 'True') {\r\n outageEnd = getLocalDateTimeString(\r\n parseDateTime(details.estimated_on)\r\n ) as string\r\n }\r\n\r\n return `
\r\n
Water outage
\r\n
Work in progress to restore outage at ${affectedSuburbs}
\r\n
An outage is currently being worked on in ${affectedSuburbs}.
\r\n
\r\n Outage start: ${outageStart} \r\n Estimated water on: ${outageEnd}\r\n
\r\n
Updates will be provided as they become available
\r\n
Last updated: ${lastUpdated}
\r\n
\r\n We apologise for any inconvenience caused and appreciate your\r\n patience\r\n
\r\n If you are experiencing a water outage at this address, please\r\n report the outage to one of our 24 hour support crew, so we can\r\n investigate. Report a fault\r\n