{"version":3,"sources":["services/history.js","services/coa-authorization.js","components/AppSkeleton.js","components/Dashboard/WidgetURL.js","pages/Home.js","pages/Profile.js","App.js","serviceWorker.js","index.js","services/State.js","pages/404.js","services/ajax.js"],"names":["history","createBrowserHistory","userLogin","a","handleNoAuth","navigator","onLine","localStorage","removeItem","redirect","window","location","href","fetchUserProfile","timeout","setTimeout","fetch","method","credentials","headers","then","response","clearTimeout","json","user","email","setItem","JSON","stringify","catch","userLogout","document","useStyles","makeStyles","theme","root","flexGrow","zIndex","overflow","position","grow","navIconHideSm","breakpoints","down","display","navIconHideLg","up","menuButton","marginLeft","marginRight","appBar","drawer","drawerPaper","width","transitionDuration","drawerDocked","height","toolbar","mixins","list","content","backgroundColor","palette","background","default","padding","spacing","minWidth","boxSizing","overflowY","contentShift","AppSkeleton","children","classes","useState","setDrawer","persistDrawer","setPersistDrawer","pathname","currentPath","setCurrentPath","accountIcon","setAccountIcon","useStateStore","useEffect","listen","body","addEventListener","event","which","globalPersistDrawer","handleListItemClick","index","route","push","process","drawerContents","List","component","ListItem","button","selected","onClick","startsWith","Fragment","AppBar","className","Toolbar","IconButton","color","aria-label","aria-owns","aria-haspopup","currentTarget","Menu","id","anchorEl","anchorOrigin","vertical","horizontal","transformOrigin","open","Boolean","onClose","MenuItem","Hidden","mdUp","SwipeableDrawer","onOpen","paper","ModalProps","keepMounted","smDown","implementation","Drawer","variant","anchor","docked","WidgetURL","widgetURLs","sort","b","name","map","url","key","HomePage","setWidgetURLs","requestOptions","ok","style","gridTemplateColumns","textAlign","title","submitButton","alignItems","ProfilePage","ID","Name","Email","Phone","Title","Department","AppPushNotifications","profile","setProfile","profileDB","p","serviceWorker","ready","swRegistration","pushManager","getSubscription","subscription","updateSubscriptionOnServer","error","console","data","Endpoint","parse","endpoint","Keys_p256dh","keys","p256dh","Keys_auth","auth","removeSubscriptionOnServer","handleSubscribeNotifications","applicationServerKey","base64String","base64","repeat","length","replace","rawData","atob","outputArray","Uint8Array","i","charCodeAt","urlB64ToUint8Array","subscribe","userVisibleOnly","err","log","togglePushNotifications","alert","target","checked","unsubscribe","successful","FormControlLabel","control","Switch","onChange","value","label","onSubmit","preventDefault","TextField","handleChange","margin","autoFocus","fullWidth","disabled","FormControl","Button","type","InformationTechnologyApp","lazy","EnvironmentalServicesApp","PublicSafetyApp","OCMApp","createMuiTheme","typography","useNextVariants","primary","main","secondary","App","initialState","userProfile","getItem","init","Promise","all","everyoneFinish","State","initFn","basename","fallback","exact","path","NotFoundPage","isLocalhost","hostname","match","registerValidSW","swUrl","config","register","registration","onupdatefound","installingWorker","installing","onstatechange","state","controller","onUpdate","onSuccess","update","ReactDOM","render","getElementById","URL","origin","status","get","indexOf","unregister","reload","checkValidServiceWorker","StateContext","createContext","reducer","prevState","StateProvider","useReducer","dispatch","asyncInitilizer","useCallback","Provider","attr","useContext","NotFound","React","Component"],"mappings":"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","file":"static/js/main.fa38a489.chunk.js","sourcesContent":["import { createBrowserHistory } from 'history';\r\n\r\nexport const history = createBrowserHistory();","//SHOULDNT BE NEEDED IF WE CAN SHARE COOKIE, but right now we need a different cookie per microframework... sooo\r\n//import { useState, useEffect, useCallback } from 'react';\r\n//IE compat (not needed because IE bug: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8680109/)\r\n//import 'whatwg-fetch';\r\n//import Promise from 'promise-polyfill';\r\n//if (!window.Promise) { window.Promise = Promise; }\r\n\r\n/**\r\n * Supports getting user information as well as triggering login when user is not logged in.\r\n *\r\n * @todo Redirecting to login means the potential to lose work if application doesn't saveState / loadState\r\n * @todo Microframeworks share the same cookie/auth but I'd need to create an auth microFramework or share with main apiv2 so we don't need to pass param\r\n * @todo Need to recreate logout (delete localStore and remove cookies)\r\n * @todo Logout timer? You are going to be logged out in? I mean, it already happens based on something from cookie or auth so might as well warn user, perhaps call saveState function\r\n * \r\n * @param {string} microFramework\r\n * @returns {object}\r\n */\r\n// function userAuthStatus(microFramework) {\r\n// const SCHEMA = {\"name\":{\"fullName\":\"\",\"firstName\":\"\",\"lastName\":\"\"},\"email\":\"\",\"phone\":null,\"department\":null,\"title\":null,\"employeeNumber\":null,\"userPrincipalName\":\"\",\"roles\":[]}\r\n// const [accountProfile, setAccountProfile] = useState(SCHEMA);\r\n\r\n// const handleNoAuth = () => {\r\n// //just assume all errors here are for not authorized\r\n// if (navigator.onLine) { // Don't try to redirect to auth server while offline, else user will have a bad time\r\n// //so this works but causes a refresh, we'd need the application to saveState, then update login, then load state. It's possible and likely the best way to handle it.\r\n// let redirect = window.location.href;\r\n// window.location.href = `https://api2.auburnalabama.org/${microFramework}/login?redirect=${redirect}`;\r\n// //However, I'd like to attempt a different solution and see if it's better.\r\n// //iframes and popups just won't set the cookie we need set so we're stuck with plan A till there is some middleware or a better idea\r\n// // let iframe = document.createElement('iframe');\r\n// // iframe.src = `https://api2.auburnalabama.org/${microFramework}/login?redirect=${redirect}`;\r\n// // document.body.appendChild(iframe);\r\n// }\r\n// }\r\n// const fetchUserProfile = () => {\r\n// //if can't get profile in 2.5s, attempt to reauthenticate\r\n// const timeout = setTimeout(handleNoAuth, 2500);\r\n// fetch(`https://api2.auburnalabama.org/${microFramework}/me`, { method: 'GET', credentials: 'include', headers: { 'Content-Type' : 'application/json' }})\r\n// .then((response) => {\r\n// clearTimeout(timeout);\r\n// return response;\r\n// })\r\n// .then((response) => {\r\n// try {\r\n// return response.json();\r\n// } catch { // if we fail to parse json, attempt reauth\r\n// handleNoAuth();\r\n// }\r\n// })\r\n// .then((user) => {\r\n// if (!user.email) { // if user has no email value, attempt reauth\r\n// handleNoAuth();\r\n// }\r\n// // set fetched credentials\r\n// localStorage.setItem('user', JSON.stringify(user));\r\n// setAccountProfile(user);\r\n// })\r\n// .catch(() => {\r\n// clearTimeout(timeout);\r\n// handleNoAuth();\r\n// });\r\n// }\r\n\r\n// //is called anytime a change is made (including load)\r\n// useEffect(() => {\r\n// if (!accountProfile || !accountProfile.email) {\r\n// //go ahead an update, even if credentials are stored in case server auth has timed out\r\n// fetchUserProfile();\r\n// //check for stored creds\r\n// let cached = JSON.parse(localStorage.getItem('user') || '{}');\r\n// if (cached.Email) {\r\n// // set cached credentials\r\n// setAccountProfile(cached);\r\n// }\r\n// }\r\n// },[]);\r\n\r\n// return accountProfile;\r\n// }\r\n\r\n// function userProvider() {\r\n// const SCHEMA = {\"name\":{\"fullName\":\"\",\"firstName\":\"\",\"lastName\":\"\"},\"email\":\"\",\"phone\":null,\"department\":null,\"title\":null,\"employeeNumber\":null,\"userPrincipalName\":\"\",\"roles\":[],\"can\":[],\"logout\":()=>{}}\r\n// const [ user, setUser ] = useState(localStorage.getItem('user') || SCHEMA);\r\n\r\n// const logout = () => {\r\n// localStorage.removeItem('user');\r\n// document.location = 'https://api2.auburnalabama.org/pressrelease/signout';\r\n// }\r\n\r\n// const asyncInitilizer = useCallback(async () => {\r\n// await fetch('https://api2.auburnalabama.org/pressrelease/me', { credentials: 'include' })\r\n// .then((response) => { if (response.ok) return response.json(); else throw new Error(); })\r\n// .then((user) => {\r\n// user.logout = logout;\r\n// //todo CAN permissions\r\n// setUser(user);\r\n// localStorage.setItem('user', user);\r\n// })\r\n// .catch(() => {\r\n// if (navigator.onLine) {\r\n// localStorage.removeItem('user');\r\n// window.location = `https://api2.auburnalabama.org/pressrelease/login?redirect=${window.location.href}`;\r\n// }\r\n// });\r\n// });\r\n\r\n// useEffect(() => {\r\n// if (user.email) {\r\n \r\n// }\r\n// if (navigator.onLine) {\r\n\r\n// }\r\n// }, []);\r\n// }\r\n\r\nasync function userLogin() {\r\n const handleNoAuth = () => {\r\n //just assume all errors here are for not authorized\r\n if (navigator.onLine) { // Don't try to redirect to auth server while offline, else user will have a bad time\r\n localStorage.removeItem('user');\r\n //so this works but causes a refresh, we'd need the application to saveState, then update login, then load state. It's possible and likely the best way to handle it.\r\n let redirect = window.location.href;\r\n window.location.href = `https://api2.auburnalabama.org/departments/login?redirect=${redirect}`;\r\n //However, I'd like to attempt a different solution and see if it's better.\r\n //iframes and popups just won't set the cookie we need set so we're stuck with plan A till there is some middleware or a better idea\r\n // let iframe = document.createElement('iframe');\r\n // iframe.src = `https://api2.auburnalabama.org/${microFramework}/login?redirect=${redirect}`;\r\n // document.body.appendChild(iframe);\r\n }\r\n }\r\n\r\n const fetchUserProfile = async () => {\r\n //if can't get profile in 2.5s, attempt to reauthenticate\r\n const timeout = setTimeout(handleNoAuth, 2500);\r\n let user = await fetch(`https://api2.auburnalabama.org/departments/me`, { method: 'GET', credentials: 'include', headers: { 'Content-Type' : 'application/json' }})\r\n .then((response) => {\r\n clearTimeout(timeout);\r\n return response;\r\n })\r\n .then((response) => {\r\n try {\r\n return response.json();\r\n } catch { // if we fail to parse json, attempt reauth\r\n handleNoAuth();\r\n }\r\n })\r\n .then((user) => {\r\n if (!user.email) { // if user has no email value, attempt reauth\r\n handleNoAuth();\r\n }\r\n // set fetched credentials\r\n localStorage.setItem('user', JSON.stringify(user));\r\n return user;\r\n })\r\n .catch(() => {\r\n clearTimeout(timeout);\r\n handleNoAuth();\r\n });\r\n if (user && user.email) return user;\r\n }\r\n\r\n //const SCHEMA = {\"name\":{\"fullName\":\"\",\"firstName\":\"\",\"lastName\":\"\"},\"email\":\"\",\"phone\":null,\"department\":null,\"title\":null,\"employeeNumber\":null,\"userPrincipalName\":\"\",\"roles\":[]};\r\n //let userProfile = localStorage.getItem('user') || SCHEMA;\r\n \r\n return await fetchUserProfile();\r\n}\r\n\r\nfunction userLogout() {\r\n localStorage.removeItem('user');\r\n //document.cookie = \"MICROAPI_AUTH= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\"; //cookies are secured so I can't mess with them, send it to server instead\r\n //document.location = 'https://www.auburnalabama.org/';\r\n document.location = 'https://api2.auburnalabama.org/departments/signout';\r\n}\r\n\r\nexport { userLogout, userLogin };","import React, { useEffect, useState } from 'react';\r\nimport { makeStyles } from '@material-ui/styles';\r\nimport { Menu, MenuItem, AppBar, Toolbar, IconButton, Hidden, SwipeableDrawer, Drawer } from '@material-ui/core';\r\nimport AccountCircle from '@material-ui/icons/AccountCircle';\r\nimport MenuIcon from '@material-ui/icons/Menu';\r\nimport List from '@material-ui/core/List';\r\nimport ListItem from '@material-ui/core/ListItem';\r\n\r\nimport { useStateStore } from '../services/State';\r\nimport { history } from '../services/history';\r\nimport { userLogout } from '../services/coa-authorization';\r\n\r\n\r\n//Layout styles\r\nconst drawerWidth = 240;\r\nconst useStyles = makeStyles(theme => ({\r\n root: {\r\n flexGrow: 1,\r\n zIndex: 1,\r\n overflow: 'hidden',\r\n position: 'relative',\r\n },\r\n grow: {\r\n flexGrow: 1,\r\n },\r\n navIconHideSm: {\r\n [theme.breakpoints.down('sm')]: {\r\n display: 'none',\r\n },\r\n },\r\n navIconHideLg: {\r\n [theme.breakpoints.up('md')]: {\r\n display: 'none',\r\n },\r\n },\r\n menuButton: {\r\n marginLeft: -12,\r\n marginRight: 20,\r\n },\r\n appBar: {\r\n position: 'absolute',\r\n zIndex: theme.zIndex.drawer + 1,\r\n },\r\n drawerPaper: {\r\n position: 'relative',\r\n width: drawerWidth,\r\n transitionDuration: '0ms !important',\r\n },\r\n drawerDocked: {\r\n height: '100%',\r\n },\r\n toolbar: theme.mixins.toolbar,\r\n list: {\r\n },\r\n content: {\r\n flexGrow: 1,\r\n backgroundColor: theme.palette.background.default,\r\n padding: theme.spacing(3),\r\n minWidth: 0, // So the Typography noWrap works\r\n height: '100%',\r\n boxSizing: 'border-box',\r\n overflowY: 'auto',\r\n },\r\n contentShift: {\r\n [theme.breakpoints.up('md')]: {\r\n marginLeft: -drawerWidth,\r\n },\r\n },\r\n}));\r\n\r\nfunction AppSkeleton({ children }) {\r\n const classes = useStyles();\r\n const [drawer, setDrawer] = useState(false);\r\n const [persistDrawer, setPersistDrawer] = useState(false);\r\n const [currentPath, setCurrentPath] = useState(history.location.pathname);\r\n const [accountIcon, setAccountIcon] = useState(null);\r\n const [user] = useStateStore('userProfile');// userAuthStatus(\"pressrelease\");\r\n \r\n useEffect(() => {\r\n history.listen(() => {\r\n setDrawer(false);\r\n setCurrentPath(history.location.pathname);\r\n });\r\n \r\n //can't get current state, only initial state\r\n document.body.addEventListener('keyup', (event) => {\r\n if (event.which === 27) {\r\n setPersistDrawer(!window.globalPersistDrawer)\r\n }\r\n });\r\n }, []);\r\n \r\n useEffect(() => {\r\n window.globalPersistDrawer = persistDrawer;\r\n }, [persistDrawer]);\r\n\r\n const handleListItemClick = (event, index, route) => {\r\n history.push(`${process.env.PUBLIC_URL}${route}`);\r\n };\r\n\r\n /** Side Navigation */\r\n const drawerContents = (\r\n \r\n handleListItemClick(event, 0, '/')}\r\n >\r\n Home\r\n \r\n handleListItemClick(event, 1, '/it')}\r\n >\r\n Information Technology\r\n \r\n handleListItemClick(event, 2, '/es')}\r\n >\r\n Environmental Services\r\n \r\n \r\n );\r\n\r\n return (\r\n \r\n \r\n \r\n { setDrawer(!drawer)}} className={`${classes.menuButton} ${classes.navIconHideLg}`} color=\"inherit\" aria-label=\"Menu\">\r\n \r\n \r\n { setPersistDrawer(!persistDrawer)}} className={`${classes.menuButton} ${classes.navIconHideSm}`} color=\"inherit\" aria-label=\"Menu\">\r\n \r\n \r\n

City of Auburn

\r\n
\r\n { setAccountIcon(event.currentTarget)}}\r\n color=\"inherit\"\r\n >\r\n \r\n \r\n { setAccountIcon(null)}}\r\n >\r\n { setAccountIcon(null);/*Close DD Menu*/ handleListItemClick(event, -1, '/profile');/*Navigate*/ }}>{user.email}\r\n Logout\r\n \r\n
\r\n
\r\n
\r\n \r\n { setDrawer(!drawer)}}\r\n onOpen={() => { setDrawer(!drawer)}}\r\n classes={{\r\n paper: classes.drawerPaper,\r\n }}\r\n ModalProps={{\r\n keepMounted: true, // Better open performance on mobile.\r\n }}\r\n >\r\n
\r\n {drawerContents}\r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n {drawerContents}\r\n
\r\n \r\n \r\n
\r\n
\r\n {children}\r\n
\r\n \r\n );\r\n}\r\n\r\nexport default AppSkeleton;\r\n","import React from 'react';\r\nimport './WidgetURL.scss';\r\n\r\nfunction WidgetURL({ widgetURLs }) {\r\n widgetURLs = widgetURLs.sort((a, b) => b.name > a.name ? -1 : 1)\r\n return (\r\n
\r\n
\r\n

Links

\r\n
\r\n
\r\n \r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default WidgetURL;\r\n","import React, { useEffect, useState } from 'react';\r\nimport { requestOptions } from '../services/ajax';\r\nimport { WidgetURL } from '../components/Dashboard';\r\n\r\nfunction HomePage() {\r\n const [widgetURLs, setWidgetURLs] = useState([]);\r\n useEffect(() => {\r\n fetch('https://api2.auburnalabama.org/departments/dashboard/widget/url', requestOptions)\r\n .then((response) => {\r\n if (response.ok) return response.json();\r\n })\r\n .then(setWidgetURLs); // TODO - error handling\r\n }, []);\r\n\r\n const mainStyle = {display:'grid', gridTemplateColumns: '30% 1% 30% 1% 30%'};\r\n const widgetURLStyle = {'grid-column':1};\r\n\r\n return (\r\n
\r\n
\r\n

Dashboard Widgets

\r\n
\r\n \r\n
\r\n
\r\n
\r\n );\r\n}\r\nexport default HomePage;\r\n","import React, { useEffect, useState } from 'react';\r\nimport { makeStyles } from '@material-ui/styles';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\r\nimport Switch from '@material-ui/core/Switch';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Button from '@material-ui/core/Button';\r\nimport { useStateStore } from '../services/State';\r\n\r\n/* eslint-disable max-len */\r\nconst applicationServerPublicKey = 'BEkWqEJJech8xX2Pyzj1vuTXkyzXB1udosgXlr-1iKgUfkfljb_-REfxzMt6iNVywjX49eYqCczh53NK5BzrPjM';\r\n/* eslint-enable max-len */\r\n\r\nfunction urlB64ToUint8Array(base64String) {\r\n const padding = '='.repeat((4 - base64String.length % 4) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, '+')\r\n .replace(/_/g, '/');\r\n\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n}\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n textAlign: 'left',\r\n width: '100%',\r\n display: 'block',\r\n },\r\n title: {\r\n color: '#111'//theme.palette.primary.dark,\r\n },\r\n submitButton: {\r\n display: 'flex',\r\n alignItems: 'flex-end',\r\n },\r\n });\r\n\r\nfunction ProfilePage() {\r\n const classes = useStyles();\r\n const [profile, setProfile] = useState({\r\n ID: 0,\r\n Name: '', \r\n Email: '',\r\n Phone: '',\r\n Title: '',\r\n Department: '',\r\n AppPushNotifications: false,\r\n });\r\n const [user] = useStateStore('userProfile');\r\n\r\n useEffect(() => {\r\n if (!user.email) return;\r\n fetch(`https://api2.auburnalabama.org/employee/${user.email}/view`).then((response) => { return response.ok ? response.json() : {}; })\r\n .then((profileDB) => {\r\n setProfile(p => { return {...p, ...profileDB }});\r\n });\r\n \r\n // TODO: I removed all those checks but I should still probably set a message or something for if the browser doesn't support Push Notification\r\n if ('PushManager' in window) {\r\n // Can't do this inside serviceWorker.js because that loads after our page first loads\r\n navigator.serviceWorker.ready.then((swRegistration) => {\r\n // Once we have a service worker ready we can check for active push subscriptions\r\n return swRegistration && swRegistration.pushManager.getSubscription()\r\n .then((subscription) => {\r\n // If we have an active subscription we should set the Settings toggle as well as update our database with the latest subscription ID\r\n setProfile(p => { return { ...p, AppPushNotifications: !!subscription }; });\r\n // TODO: Add update method to API\r\n updateSubscriptionOnServer(subscription);\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n });\r\n }\r\n }, [user.email]); //initial load fn\r\n\r\n const handleChange = (event) => {\r\n setProfile({ ...profile, [event.target.name]: event.target.value });\r\n };\r\n\r\n const handleFormSubmit = (event) => {\r\n event.preventDefault();\r\n fetch(`https://api2.auburnalabama.org/employee/${profile.ID}/view`, \r\n { method: 'PUT', body: JSON.stringify(profile), headers: { 'Content-Type': 'application/json' }})\r\n .then((response) => {\r\n alert(response.ok);\r\n });\r\n return false;\r\n }\r\n\r\n const updateSubscriptionOnServer = (subscription) => {\r\n if (subscription) {\r\n //I don't know what kind of wacky object PushSubscription is but this is how to get data...\r\n subscription = JSON.parse(JSON.stringify(subscription));\r\n let data = {\r\n // Email: this.props.user.Email,\r\n Name: 'My Departments',\r\n Endpoint: subscription.endpoint,\r\n Keys_p256dh: subscription.keys.p256dh,\r\n Keys_auth: subscription.keys.auth\r\n };\r\n\r\n return fetch(`https://api2.auburnalabama.org/notification/subscribe`, { method: \"POST\", body: JSON.stringify(data), headers: { \"Content-Type\" : \"application/json\" } })\r\n .then((response) => {\r\n //updates the button/switch\r\n // TODO: maybe look at this but right now I need a \"PUT\" method, I'm just posting and it fails if the endpoint is already registered\r\n //this.setState({ AppPushNotifications: response.ok });\r\n //TODO: handle !response.ok\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n //TODO: handle error\r\n });\r\n }\r\n }\r\n\r\n const removeSubscriptionOnServer = subscription => {\r\n //I don't know what kind of wacky object PushSubscription is but this is how to get data...\r\n subscription = JSON.parse(JSON.stringify(subscription));\r\n // TODO: Right now API can only delete by ID but I need to delete by endpoint... this also means a big change\r\n fetch(`https://api2.auburnalabama.org/notification/endpoint/${subscription.endpoint}`, { method: 'DELETE' })\r\n .then((response) => {\r\n //update the button/switch to reflect that the subscription was removed/delete\r\n // TODO: maybe look at this but right now I need a \"DELETE\" method that works for endpoints, I'm just letting them pile up in the database\r\n // this.setState({ AppPushNotifications: !response.ok });\r\n //TODO: handle !response.ok\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n //TODO: handle error\r\n });\r\n }\r\n\r\n const handleSubscribeNotifications = () => {\r\n const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);\r\n if ('PushManager' in window) {\r\n // Can't do this inside serviceWorker.js because that loads after our page first loads\r\n navigator.serviceWorker.ready.then((swRegistration) => {\r\n swRegistration.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n applicationServerKey: applicationServerKey\r\n })\r\n .then((subscription) => {\r\n setProfile(p => { return {...p, AppPushNotifications: true }; });\r\n return updateSubscriptionOnServer(subscription);\r\n })\r\n .catch(function(err) {\r\n console.log('Failed to subscribe the user: ', err);\r\n });\r\n })\r\n }\r\n }\r\n\r\n const handleUnsubsribeNotifications = () => {\r\n navigator.serviceWorker.ready.then((swRegistration) => {\r\n swRegistration.pushManager.getSubscription().then((subscription) => {\r\n subscription.unsubscribe().then((successful) => {\r\n removeSubscriptionOnServer(subscription);\r\n }).catch(() => {\r\n removeSubscriptionOnServer(subscription);\r\n });\r\n setProfile(p => { return {...p, AppPushNotifications: false }; });\r\n });\r\n });\r\n }\r\n\r\n const togglePushNotifications = (event) => {\r\n if (!('PushManager' in window)) {\r\n alert('Push Notifications are not supported on your browser.');\r\n setProfile(p => { return {...p, AppPushNotifications: false }; });\r\n return;\r\n }\r\n \r\n //TODO: Make sure that form load doesn't register/unregister\r\n if (event.target.checked) {\r\n handleSubscribeNotifications();\r\n } else {\r\n handleUnsubsribeNotifications();\r\n }\r\n }\r\n\r\n return (\r\n \r\n
\r\n
\r\n

Application Settings

\r\n
\r\n
\r\n togglePushNotifications(event)}\r\n value=\"Notifications\"\r\n />\r\n }\r\n label=\"Push Notification\"\r\n />\r\n
\r\n
\r\n
\r\n \r\n

Profile

\r\n
\r\n handleChange(event)}\r\n margin=\"normal\"\r\n autoFocus fullWidth>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\n// function mapStateToProps(state) {\r\n// const { authentication } = state;\r\n// const { user } = authentication;\r\n// return {\r\n// user\r\n// };\r\n// }\r\n\r\n// const connectedProfilePage = connect(mapStateToProps)(withStyles(styles)(ProfilePage));\r\nexport default ProfilePage;\r\n","import React, { Suspense, lazy } from 'react';\nimport { Router, Switch as SwitchRoute, Route } from 'react-router-dom';\n//Styles\nimport './App.css';\n//Routing/History/Services\nimport { history } from './services/';\nimport { userLogin } from './services/coa-authorization';\nimport { StateProvider } from './services/State'; //should be able to get from NPM but microServices aren't sharing cookie\n//Material-ui layout needs\nimport { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';\n//Components\nimport { SnackbarProvider } from 'notistack';\nimport AppSkeleton from './components/AppSkeleton';\n//Content Pages\nimport { NotFoundPage, HomePage, ProfilePage } from './pages';\n//import { default as InformationTechnologyApp } from './pages/InformationTechnology/InformationTechnology';\nconst InformationTechnologyApp = lazy(() => import('./pages/InformationTechnology/InformationTechnology'));\n//import EnvironmentalServicesApp from './pages/EnvironmentalServices/EnvironmentalServices';\nconst EnvironmentalServicesApp = lazy(() => import('./pages/EnvironmentalServices/EnvironmentalServices'));\nconst PublicSafetyApp = lazy(() => import('./pages/PublicSafety'));\nconst OCMApp = lazy(() => import('./pages/OCM'));\n\n//Layout styles\nconst theme = createMuiTheme({\n typography: {\n useNextVariants: true,\n },\n palette: {\n primary: { main: '#03a9f4' }, //lightblue from @material-ui/core/colors/\n secondary: { main: '#ff9800' }, //orange\n },\n});\n\nfunction App() {\n // TODO - move out to an appStore.js file?\n // TODO - rewrite `reducer` function in State.js to also update localStorage?\n // TODO - perhaps make a way to update localStorage without saving the data for local timeouts?\n const STORES = {\n CACHED_USER: 'userProfile',\n }\n const initialState = {\n userProfile: JSON.parse(localStorage.getItem(STORES.CACHED_USER)) || {\"name\":{\"fullName\":\"\",\"firstName\":\"\",\"lastName\":\"\"},\"email\":\"\",\"phone\":null,\"department\":null,\"title\":null,\"employeeNumber\":null,\"userPrincipalName\":\"\",\"roles\":[]},\n };\n const init = async () => {\n let userProfile = userLogin()\n .then((user) => {\n // Get additional permissions\n // if (user.canPublish === undefined) {\n // return fetch('https://api2.auburnalabama.org/pressrelease/canIPublish', { credentials: 'include' })\n // .then((response) => { return {...user, canPublish: response.ok}; })\n // .catch(() => {return {...user, canPublish: false }; });\n // }\n\n // Return\n return user;\n });\n let everyoneFinish = await Promise.all([userProfile]);\n return { userProfile: everyoneFinish[0] };\n }\n \n return (\n \n \n \n \n \n Loading...
}>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n}\n\nexport default App;\n","// In production, we register a service worker to serve assets from local cache.\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 the \"N+1\" visit to a page, since previously\n// cached resources are updated in the background.\n\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\n// This link also includes instructions on opting out of this behavior.\n//import initializeUI from './serviceWorker.Notifications';\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.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\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);\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}/custom-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://goo.gl/SC7cgQ'\n );\n });\n } else {\n // Is not local host. 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 installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and\n // the fresh content will have been added to the cache.\n // It's the perfect time to display a \"New content is\n // available; please refresh.\" message in your web app.\n console.log('New content is available; please refresh.');\n\n // Execute callback\n if (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.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n //might be a bad idea but the caching is killing my dev testing \n registration.update();\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 .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n if (\n response.status === 404 ||\n response.headers.get('content-type').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(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(, document.getElementById('root'));\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 about service workers: http://bit.ly/CRA-PWA\nserviceWorker.register();\n","import React, {createContext, useContext, useCallback, useReducer, useEffect} from 'react';\r\nexport const StateContext = createContext();\r\nconst reducer = (prevState, state) => {\r\n return {\r\n ...prevState,\r\n ...state\r\n }\r\n}\r\n/** This state provider will be used to handle most data stores in the app\r\n * Desired functions for a data store:\r\n * 1. Loads initially a static/cached value\r\n * 2. Asyncly refresh this static value where needed\r\n * 3. Component useage matches the standard [state, updateState] pattern\r\n * 4. Pushes changes changes, allows changes pushed.\r\n * \r\n * Useage: const [{ trackedObj }, updateState]\r\n * Then: updateState({ trackedObj: trackedObj })\r\n */\r\nexport const StateProvider = ({initFn, initialState, children}) => {\r\n const [ state, dispatch ] = useReducer(reducer, initialState);\r\n //next we'd like to async load our \r\n //can't put async function directly in `useEffect`\r\n //\r\n const asyncInitilizer = useCallback(async () => {\r\n let state = await initFn();\r\n dispatch(state);//merge defaultState with async state fetch\r\n }, [dispatch, initFn]);\r\n useEffect(() => { \r\n asyncInitilizer();\r\n // eslint-disable-next-line\r\n },[]);//run only once\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\nexport const useStateStore = (attr) => {\r\n //if no specific part of the state is defined it can be used as object\r\n //doesn't like conditionally, and I've never used it this way anyways\r\n //if (!attr) return useContext(StateContext); //ex: const trackedObj = [{ trackedObj }, updateState] = getState()\r\n //you can specify a part of the state obj by passing it in\r\n const [state, dispatch] = useContext(StateContext); //ex: const trackedObj = [trackedObj, updateTrackedObj] = getState('trackedObj');\r\n return [state[attr], (value) => { dispatch({ [attr] : value }) }];\r\n}\r\n","import React from 'react'\r\n\r\nclass NotFound extends React.Component {\r\n render() {\r\n return
404: Not Found
\r\n }\r\n}\r\n\r\nexport { NotFound as NotFoundPage };","export const requestOptions = {\r\n method: 'GET',\r\n headers: { 'Content-Type': 'application/json' },\r\n credentials: 'include'\r\n};"],"sourceRoot":""}