{"version":3,"sources":["app-header.js","auth/firebase-config.js","auth/auth-api.js","auth/auth-provider.js","helpers/general-helpers.js","helpers/error-card.js","helpers/api-helper.js","auth/admin-signin.js","helpers/general-hooks.js","auth/auth-container.js","helpers/error-boundary.js","vod/vod-frame.js","vod/vod-container.js","components/reports/reports-frame.js","components/reports/reports-container.js","player/player-frame-embeded.js","appRouting.js","app.js","store/actions/report-actions.js","store/reducers/reports-reducer.js","store/reducers/reducer-helpers.js","helpers/TelemetryService.js","helpers/telemetry-provider.js","index.js","store/configure-store.js","store/reducers/root-reducer.js"],"names":["AppHeader","classes","buildStyles","useCustomizations","strings","links","flags","images","blobUrl","favicon","logo","Helmet","charSet","header","title","name","content","rel","href","homeUrl","url","CssBaseline","Grid","item","xs","sm","container","className","headerRoot","direction","spacing","align","centerLogo","target","clsx","responsiveLogo","logoImage","src","alt","logoAlt","hasOwnProperty","Link","headerInfoText","makeStyles","theme","padding","backgroundColor","styles","page","borderBottom","borderBottomWidth","borderColor","breakpoints","down","alignItems","justifyContent","fontSize","fontWeight","color","textAlign","height","maxHeight","marginLeft","firebaseApp","firebase","initializeApp","apiKey","authDomain","projectId","databaseURL","storageBucket","messagingSenderId","appId","COLS","DOCS","validateUser","doc","email","exists","found","data","whitelist","find","u","Boolean","authApi","checkWhitelist","school","db","firestore","collection","get","users","admins","createAppUser","user","auth","currentUser","getIdToken","authToken","console","log","appUser","uid","displayName","emailVerified","phoneNumber","photoUrl","token","AuthContext","React","createContext","AuthProvider","children","useState","isInitialized","setInitialized","setUser","useMemo","pathParts","window","location","pathname","split","length","indexOf","toLowerCase","host","partCount","parts","getSchoolFromUrl","onAuthChanged","signOut","useEffect","onAuthStateChanged","createAccount","emailAddress","password","createUserWithEmailAndPassword","result","isError","error","message","signInEmail","signInWithEmailAndPassword","Promise","reject","a","ctx","isAuthenticated","Provider","value","style","marginTop","CircularProgress","Typography","component","useAuth","useContext","useAuthWithActions","root","marginBottom","errorCard","width","border","palette","dark","borderRadius","background","common","white","errorContent","light","errorHeader","borderBottomColor","main","errorBody","errorText","details","ErrorCard","id","justify","Accordion","variant","AccordionSummary","AccordionDetails","URIS","ENV_PATH","development","qa","production","localhost","getSearchParam","key","keepCase","searchVal","search","slice","URLSearchParams","getEnvironment","includingLocalhost","env","hostName","hostname","fetchJsonFile","fileUrl","fetch","method","json","ok","status","statusText","errMsg","text","getStaticWebAppUrl","app","bootstrap_path","clientSpecificFileName","jsonClientUrl","jsonRootUrl","jsonClientSpecific","jsonRoot","Error","loginValidation","Yup","shape","required","singUpValidation","passwordConfirm","initValues","AdminSignIn","errorMessage","setErrorMessage","view","setView","isLogin","onSignUp","values","actions","setSubmitting","onSignIn","titleRow","mb","errorGrid","initialValues","validationSchema","onSubmit","props","md","TextField","label","onChange","handleChange","onBlur","handleBlur","helperText","touched","errors","undefined","autoComplete","input","InputProps","inputRoot","InputLabelProps","labelRoot","margin","fullWidth","type","actionsRow","Button","actionPrimary","onClick","action","schoolColors","primary","secondary","spacer","minWidth","divider","maxWidth","contrastText","AnchorPositions","bottomRight","getContentAnchorEl","anchorOrigin","vertical","horizontal","transformOrigin","bottomLeft","bottomCenter","defaultMenuItems","actionPath","defaultAppMenuItem","getAppPath","appConfig","subdomain","isDefault","urlSlug","AuthContainer","useLocation","useParams","history","useHistory","menuItems","setMenuItems","position","anchor","setAnchor","onOpen","e","currentTarget","onClose","positionProps","useAnchor","isOpen","availableMenuItems","filter","itm","menuClicked","useCallback","push","menu","appsUrl","appsJson","applications","reduce","output","menuItem","doEffect","authHeader","wrap","Tooltip","headerButton","username","Menu","anchorEl","keepMounted","open","map","MenuItem","paddingTop","paddingBottom","ErrorBoundary","state","hasError","errorInfo","this","Component","VodFrame","application","appUrl","setAppUrl","setError","lastApp","setLastApp","appPath","encodeURIComponent","toString","appBody","iframeContainer","iframe","allow","flexWrap","VodContainer","ReportsFrame","reportAppUrl","setReportAppUrl","rowId","rowPart","ReportsContainer","PlayerFrameEmbeded","playerAppUrl","setPlayerAppUrl","isEmbeded","pathName","useIsEmbeded","campaignId","sid","sidQueryParam","campaignQueryParam","keys","isDebugFlagParam","has","getPlayerParamsFromUrl","swaUrl","mySid","myCampaignId","embedOrNot","params","cl","en","parentWindow","document","referrer","parentReferrer","urlSerchParams","URL","iframeContainerEmbeded","iframeEmbeded","allowFullScreen","overflow","top","left","minHeight","AppRouting","path","App","isReady","setReady","setPath","getClientFromUrl","client","getEnvironmentFromUrl","sd","getSubdomainFromUrl","getBaseUrl","basePath","initialize","gaTrackerId","gaTrackerSecondaryId","LOADING","LOADED","FAILED","FILTERS_LOADING","FILTERS_LOADED","FILTERS_FAILED","DOWNLOADING","DOWNLOADED","DOWNLOAD_FAILED","RPT_ACTIONS","initialState","handlers","reducerMap","isWorking","loadedAt","reportItems","items","i","renderId","pagination","timestamp","optsWorking","filterOptions","isDownloading","createReducer","reactPlugin","appInsights","ai","instrumentationKey","browserHistory","ReactPlugin","ApplicationInsights","config","maxBatchInterval","disableFetchTracking","autoTrackPageVisitTime","extensions","extensionConfig","identifier","loadAppInsights","addTelemetryInitializer","envelope","EnvironmentName","trackPageView","TelemetryProvider","initialized","AppInsightsInstrumentationKey","setState","after","withRouter","withAITracking","rootElement","getElementById","store","initialReduxState","rootReducer","reducers","reports","rptReducer","combineReducers","configureReducers","middlewares","logger","createLogger","collapsed","middleware","thunk","composeWithDevTools","applyMiddleware","configureMiddleware","createStore","configureStore","ReactDOM","render"],"mappings":"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","file":"static/js/main.d6b5c054.chunk.js","sourcesContent":["import React, { Fragment } from 'react';\r\nimport clsx from 'clsx';\r\nimport { Helmet } from 'react-helmet';\r\nimport Favicon from 'react-favicon';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport CssBaseline from '@material-ui/core/CssBaseline';\r\nimport Link from '@material-ui/core/Link';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport { useCustomizations } from \"@personicom/customizations\";\r\n\r\n\r\n\r\n//TODO: Why do we use this at all, header should be shared across the SWA's.\r\n\r\n//***********/\r\n//NOTE: Not used by player routes\r\n// only used in /reports and /app routes\r\n\r\nconst AppHeader = () => {\r\n const classes = buildStyles();\r\n const { strings, links, flags, images, blobUrl } = useCustomizations();\r\n const favicon = blobUrl(images.favicon);\r\n const logo = blobUrl(images.logo);\r\n\r\n return (\r\n \r\n \r\n \r\n {strings.header?.title}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n {strings.logoAlt}\r\n \r\n \r\n \r\n {strings.hasOwnProperty('headerInfoText') ? {strings.headerInfoText} : null}\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default AppHeader;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n headerRoot: {\r\n padding: \"20px 40px 16px 40px\",\r\n backgroundColor: `${theme.styles.header?.backgroundColor ?? theme.styles.page.backgroundColor}`,\r\n borderBottom: theme.styles.header?.borderBottom ?? `${theme.styles.header?.borderBottomWidth ?? \"5px\"} solid ${theme.styles.page.borderColor}`, //`\r\n [theme.breakpoints.down('xs')]: {\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n }\r\n },\r\n headerInfoText: {\r\n fontSize: 24,\r\n fontWeight: 700,\r\n color: theme.styles.header?.color ?? theme.styles.page.color,\r\n [theme.breakpoints.down('xs')]: {\r\n fontSize: 20,\r\n textAlign: \"center\",\r\n },\r\n },\r\n logoImage: {\r\n height: `${theme.styles.header?.logo?.height ?? \"70px\"}`, //`\r\n maxHeight: `${theme.styles.header?.logo?.maxHeight ?? \"none\"}`, //`\r\n marginLeft: 15,\r\n [theme.breakpoints.down('xs')]: {\r\n height: 55,\r\n marginLeft: 0,\r\n }\r\n }\r\n}));","import firebase from \"firebase/app\";\r\nimport \"firebase/auth\";\r\nimport \"firebase/firestore\";\r\n\r\nconst fbConfig = {\r\n apiKey: \"AIzaSyBkfcMHFNFsiwu6_mkdyCXXOIxDYWbJPYo\",\r\n authDomain: \"personicom-umsg.firebaseapp.com\",\r\n projectId: \"personicom-umsg\",\r\n databaseURL: \"https://personicom-umsg.firebaseio.com\",\r\n storageBucket: \"personicom-umsg.appspot.com\",\r\n messagingSenderId: \"911835698555\",\r\n appId: \"1:911835698555:web:30188dad25983e2b3659de\"\r\n};\r\n\r\nconst firebaseApp = firebase.initializeApp(fbConfig);\r\n\r\nexport default firebaseApp;","import firebaseApp from \"./firebase-config\";\r\nimport \"firebase/firestore\";\r\n// import { boolean } from \"yup/lib/locale\";\r\n\r\nconst COLS = {\r\n vod: \"vod\",\r\n};\r\nconst DOCS = {\r\n admins: \"all\",\r\n}\r\n\r\nconst validateUser = (doc, email) => {\r\n if(doc.exists){\r\n const whitelist = doc.data().whitelist;\r\n const found = whitelist.find(u => u === email);\r\n return Boolean(found);\r\n }\r\n return false;\r\n}\r\n\r\n//== Api to access authentication information in Firestore\r\nexport const authApi = ({\r\n\r\n //--Checks to see if an email address is on the whitelist\r\n checkWhitelist: async (school, email) => {\r\n const db = firebaseApp.firestore();\r\n const users = await db.collection(COLS.vod).doc(school).get();\r\n if(validateUser(users, email)){\r\n return true;\r\n }\r\n else{\r\n //Check to see if they're an admin that can see anything\r\n const admins = await db.collection(COLS.vod).doc(DOCS.admins).get();\r\n return validateUser(admins, email);\r\n }\r\n },\r\n\r\n});","import React, { useContext, useEffect, useMemo, useState } from \"react\";\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport { getSchoolFromUrl } from \"../helpers/general-helpers\";\r\nimport { authApi } from \"./auth-api\";\r\nimport firebaseApp from \"./firebase-config\";\r\n\r\nconst createAppUser = async (user) => {\r\n if(user === null) return user;\r\n else{\r\n const authToken = await firebaseApp.auth().currentUser.getIdToken(false);\r\n console.log(authToken);\r\n \r\n const appUser = {\r\n uid: user.uid,\r\n displayName: user.displayName,\r\n email: user.email,\r\n emailVerified: user.emailVerified,\r\n phoneNumber: user.phoneNumber,\r\n photoUrl: user.photoUrl, \r\n token: authToken,\r\n };\r\n return appUser;\r\n }\r\n}\r\n\r\n//Context to hold the auth info for the app\r\nexport const AuthContext = React.createContext(null);\r\n\r\n//Context Provider that will provide context to the relevant portion of the app\r\nexport const AuthProvider = ({children}) => {\r\n const [isInitialized, setInitialized] = useState(false);\r\n const [user, setUser] = useState(null);\r\n const school = useMemo(() => getSchoolFromUrl(), []);\r\n\r\n const onAuthChanged = async (user) => {\r\n //Validate that this user is permitted for this school\r\n const isValid = !user || await authApi.checkWhitelist(school, user.email);\r\n \r\n if(isValid === true){\r\n const appUser = await createAppUser(user);\r\n setUser(appUser);\r\n }\r\n else{\r\n signOut(); //sign the user out if they don't belong in this school\r\n }\r\n\r\n setInitialized(true); //indicate that we're setup\r\n }\r\n\r\n useEffect(() => {\r\n //setup a listener that will update the context when the user logs in or out.\r\n firebaseApp.auth().onAuthStateChanged(onAuthChanged); \r\n }, []);\r\n\r\n //===\r\n // Sign In and Sign Out methods\r\n const createAccount = async (emailAddress, password) => {\r\n try {\r\n const isValid = await authApi.checkWhitelist(school, emailAddress);\r\n if(isValid === true){\r\n const result = await firebaseApp.auth().createUserWithEmailAndPassword(emailAddress, password);\r\n return result;\r\n }\r\n else{\r\n return {isError: true, error: {message: \"You are not permitted to access this feature. Please contact your administrator if you believe this is a mistake.\"}};\r\n }\r\n }\r\n catch (error) {\r\n return {isError: true, error};\r\n }\r\n };\r\n\r\n const signInEmail = async (emailAddress, password) => {\r\n if(!user){\r\n try {\r\n const result = await firebaseApp.auth().signInWithEmailAndPassword(emailAddress, password, );\r\n if(result && result.user){\r\n const isValid = await authApi.checkWhitelist(school, emailAddress);\r\n if(isValid === true){\r\n return result;\r\n }\r\n else{\r\n await firebaseApp.auth().signOut();\r\n return {isError: true, error: {message: \"You are not permitted to access this feature. Please contact your administrator if you believe this is a mistake.\"}};\r\n } \r\n }\r\n }\r\n catch (error) {\r\n // console.error(\"Failed to login with email.\", error);\r\n return {isError: true, error};\r\n }\r\n }\r\n return Promise.reject({isError: true, error: \"User already authenticated\"});\r\n };\r\n\r\n const signOut = async () => {\r\n if (user) {\r\n return await firebaseApp.auth().signOut();\r\n }\r\n return Promise.reject(\"No authenticated user to sign out\");\r\n }\r\n\r\n const ctx = {\r\n user,\r\n isAuthenticated: Boolean(user),\r\n createAccount,\r\n signInEmail,\r\n signOut,\r\n };\r\n\r\n if(!isInitialized){\r\n return (\r\n \r\n \r\n Initializing...\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\n//Hook that will provide auth information\r\n// NOTE: This can only run from inside the AuthProvider component.\r\nexport function useAuth() {\r\n const ctx = useContext(AuthContext);\r\n\r\n return {\r\n isAuthenticated: Boolean(ctx.isAuthenticated),\r\n user: ctx.user || null,\r\n };\r\n}\r\n\r\n//Hook that will provide auth information and actions (sign in, sign out)\r\n// NOTE: This can only run from inside the AuthProvider component.\r\nexport function useAuthWithActions() {\r\n const ctx = useContext(AuthContext);\r\n return ctx;\r\n}","import React, { useState, useEffect } from 'react';\r\n// import { useLocation, useRouteMatch } from 'react-router-dom';\r\n\r\nexport function getSchoolFromUrl() {\r\n var school = \"default\";\r\n\r\n //Need to support direct access to iFrame version in local, qa and dev\r\n const pathParts = window.location.pathname.split('/');\r\n if(pathParts.length === 3 && [\"iframe\", \"player\"].indexOf(pathParts[2].toLowerCase()) >= 0){\r\n school = pathParts[1];\r\n }\r\n else{\r\n const host = window.location.host.toLowerCase();\r\n //For dev/stage we're going to use the first path to specify subdomain. https://dev.universitymsg.com/nextstopnjit/\r\n if (host.indexOf(\"dev.\") >= 0 || host.indexOf(\"qa.\") >= 0) {\r\n school = window.location.pathname.split('/')[1]\r\n } else {\r\n const partCount = host.indexOf(\"localhost\") >= 0 ? 1 : 2; //localhost doesn't have the .com, so expect different parts\r\n const parts = host.split('.');\r\n school = parts.length > partCount ? parts[0] : \"default\";\r\n }\r\n }\r\n console.log(\"School: \" + school);\r\n\r\n return school\r\n}\r\n\r\n\r\nexport function getPlayerParamsFromUrl() {\r\n const search = new URLSearchParams(window.location.search);\r\n var sidQueryParam;\r\n var campaignQueryParam;\r\n\r\n //Hack to make the sid query param be case insensitive....\r\n for (var key of search.keys()) {\r\n if (key.toLowerCase() === \"sid\") {\r\n sidQueryParam = search.get(key);\r\n }\r\n else if (key.toLowerCase() === \"campaignid\") {\r\n campaignQueryParam = search.get(key);\r\n }\r\n }\r\n const isDebugFlagParam = search.has(\"debug\") ? search.get(\"debug\") : false;\r\n return { sidQueryParam, campaignQueryParam, isDebugFlagParam }\r\n}\r\n","import React from \"react\";\r\nimport { makeStyles } from \"@material-ui/core/styles\";\r\nimport Grid from \"@material-ui/core/Grid\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport Accordion from '@material-ui/core/Accordion';\r\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\r\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n root : {\r\n padding: theme.spacing(1),\r\n marginTop: theme.spacing(2),\r\n marginBottom: theme.spacing(2),\r\n // height: \"100%\",\r\n // width: \"100%\",\r\n },\r\n errorCard: {\r\n width: \"40%\",\r\n border: `1px solid ${theme.palette.error.dark}`, //`\r\n borderRadius: 5,\r\n // borderColor: theme.palette.error.main,\r\n background: theme.palette.common.white,\r\n },\r\n errorContent: {\r\n background: `${theme.palette.error.light}33`, //`\r\n },\r\n errorHeader: {\r\n backgroundColor: `${theme.palette.error.light}55`, //`\r\n borderBottomColor: theme.palette.error.main,\r\n color: theme.palette.error.dark,\r\n padding: `${theme.spacing(1)}px ${theme.spacing(0)}px`, //`\r\n },\r\n errorBody: {\r\n padding: theme.spacing(2),\r\n },\r\n title: {\r\n fontSize: \"1.2rem\",\r\n },\r\n errorText: {\r\n textAlign: \"center\",\r\n fontSize: \"0.9rem\",\r\n fontWeight: 300,\r\n },\r\n details: {\r\n backgroundColor: `${theme.palette.error.light}11`, //` \r\n width: \"100%\",\r\n }\r\n}));\r\n\r\nconst ErrorCard = ({message, details}) => {\r\n const classes = buildStyles();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n Error\r\n \r\n \r\n {message}\r\n \r\n {details && \r\n \r\n \r\n \r\n Details\r\n \r\n \r\n {details}\r\n \r\n \r\n \r\n }\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default ErrorCard;","import _ from 'lodash';\r\n// import { useAuth } from \"../auth/auth-provider\";\r\n\r\nconst URIS = {\r\n base: \"/api/common\",\r\n renderQueue: \"api/common/RenderQueueItem\",\r\n environmentFileName: \"environments.json\"\r\n};\r\nconst ENV_PATH = {\r\n development: \"dev\",\r\n qa: \"qa\",\r\n production: \"prod\",\r\n localhost: \"localhost\"\r\n};\r\n\r\nconst ENV_PREFIX = \"en\";\r\n\r\n//===\r\n// Gets a search parameter from the url by its name. assumes search will be in the form: \"?key=value&key2=value2\"\r\nexport function getSearchParam(key, keepCase = false) {\r\n let searchVal = window.location.search.slice(1);\r\n if(!keepCase) searchVal = searchVal.toLowerCase();\r\n const search = new URLSearchParams(searchVal);\r\n return search.get(key);\r\n}\r\n\r\nexport function getEnvironment(includingLocalhost = false) {\r\n let env = getSearchParam(ENV_PREFIX);\r\n if(!env){\r\n const hostName = window.location.hostname.toLowerCase();\r\n // let env = \"\";\r\n\r\n if (hostName.indexOf(\"qa.\") >= 0) {\r\n env = \"qa\";\r\n } else if (hostName.indexOf(\"dev.\") >= 0) {\r\n env = \"development\";\r\n } else if (hostName.indexOf(\"localhost\") >= 0) {\r\n env = includingLocalhost ? \"localhost\" : \"development\";\r\n } else {\r\n env = \"production\";\r\n }\r\n }\r\n\r\n return env;\r\n};\r\nexport const getReportData = async (subdomain, user, pageNum, pageSize, sort, filter) => {\r\n const fullUrl = `${URIS.base}/ReportData/${subdomain}/?${buildQueryString(pageNum, pageSize, sort, filter)}`; \r\n const response = await doFetchWithToken(fullUrl, \"GET\", null, user.token);\r\n return response;\r\n}\r\n\r\nexport const getReportFilters = async (subdomain, user ) => {\r\n const fullUrl = `${URIS.base}/ReportFilterOptions/${subdomain}/`; \r\n const response = await doFetchWithToken(fullUrl, \"GET\", null, user.token);\r\n return response;\r\n}\r\n\r\nexport const getReportDownload = async (subdomain, user, sort, filter) => {\r\n const fullUrl = `${URIS.base}/ReportExport/${subdomain}/?${buildQueryString(null, null, sort, filter)}`;\r\n const response = await doFileFetchWithToken(fullUrl, \"GET\", null, user.token, \"text/csv\");\r\n return response;\r\n}\r\n\r\n//------------------\r\n// Creates a query string out of the various pagination properties\r\nexport function buildQueryString(pageNum, pageSize, sort, filter) {\r\n let qs = new URLSearchParams(\"\");\r\n if (pageNum) qs.append(\"offset\", (pageNum * pageSize));\r\n if (pageSize) qs.append(\"limit\", pageSize);\r\n if (sort) qs.append(\"sort\", encodeURIComponent(sort));\r\n if (filter) qs.append(\"filter\", encodeURIComponent(filter));\r\n return qs.toString();\r\n}\r\n\r\n//------------------\r\n// Handle a blob/arraybuffer response and trigger the download\r\nconst CD_HEADER = \"content-disposition\";\r\nconst CD_HEADER_CAP = \"Content-Disposition\"; //historically, it has come back both ways\r\n\r\nexport async function doFetch(url, method, body) {\r\n\r\n try {\r\n const result = await fetch(url, { method: method, body: body });\r\n if (result.json) {\r\n const json = await result.json();\r\n\r\n if (!result.ok) {\r\n return {\r\n isError: true,\r\n status: result.status,\r\n message: result.statusText,\r\n ...json\r\n };\r\n }\r\n\r\n return json; //all good, just return the result\r\n }\r\n else if (result.ok === true) {\r\n //Nothing to return, but all is good\r\n return result;\r\n }\r\n }\r\n catch (err) {\r\n let errMsg = \"Unhandled exception during fetch. Our technical team has been notified.\";\r\n if (err.text) errMsg = await err.text();\r\n\r\n return {\r\n isError: true,\r\n message: errMsg\r\n };\r\n }\r\n}\r\n\r\n\r\nexport async function doFetchWithToken(url, method, body, token) {\r\n\r\n try {\r\n const headers = {\r\n \"Authorization\": \"Bearer \" + token,\r\n };\r\n\r\n const result = await fetch(url, { method: method, body, headers });\r\n if (result.json) {\r\n const json = await result.json();\r\n\r\n if (!result.ok) {\r\n return {\r\n isError: true,\r\n status: result.status,\r\n message: result.statusText,\r\n ...json\r\n };\r\n }\r\n\r\n return json; //all good, just return the result\r\n }\r\n else if (result.ok === true) {\r\n //Nothing to return, but all is good\r\n return result;\r\n }\r\n }\r\n catch (err) {\r\n let errMsg = \"Unhandled exception during fetch. Our technical team has been notified.\";\r\n if (err.text) errMsg = await err.text();\r\n\r\n return {\r\n isError: true,\r\n message: errMsg\r\n };\r\n }\r\n}\r\n\r\n\r\nasync function doFileFetchWithToken(url, method, body, token, contentType) {\r\n try {\r\n const headers = {\r\n \"Authorization\": \"Bearer \" + token,\r\n };\r\n\r\n const result = await fetch(url, { method: method, body, headers });\r\n if (result.ok) {\r\n const isOk = await downloadFile(result, contentType);\r\n if (!isOk) {\r\n return {\r\n isError: true,\r\n status: result.status,\r\n message: result.statusText,\r\n ...result,\r\n };\r\n }\r\n else {\r\n return {\r\n isError: false,\r\n ...result,\r\n }\r\n }\r\n }\r\n else {\r\n return {\r\n isError: true,\r\n error: result.statusText || \"Failed to fetch file for download\",\r\n ...result,\r\n }\r\n }\r\n }\r\n catch (err) {\r\n let errMsg = \"Unhandled exception during fetch. Our technical team has been notified.\";\r\n if (err.text) errMsg = await err.text();\r\n\r\n return {\r\n isError: true,\r\n error: errMsg\r\n };\r\n }\r\n}\r\n\r\n\r\nexport async function downloadFile(result, mimeType, isRedirect) {\r\n const cd = result.headers.get(CD_HEADER) || result.headers.get(CD_HEADER_CAP);\r\n\r\n if (cd) {\r\n //The file to download was returned as a Blob in the response.\r\n let fileName = null;\r\n const cdParts = cd.split(';');\r\n const fname = _.find(cdParts, cdp => cdp.indexOf(\"filename=\") >= 0);\r\n if (fname) {\r\n fileName = fname.trim().substr(\"filename=\".length);\r\n }\r\n\r\n if (fileName && mimeType) {\r\n var linkElement = document.createElement('a');\r\n try {\r\n var data = await result.blob();\r\n var blob = new Blob([data], { type: mimeType });\r\n var url = window.URL.createObjectURL(blob);\r\n\r\n linkElement.setAttribute('href', url);\r\n linkElement.setAttribute(\"download\", fileName);\r\n\r\n var clickEvent = new MouseEvent(\"click\", {\r\n \"view\": window,\r\n \"bubbles\": true,\r\n \"cancelable\": false\r\n });\r\n linkElement.dispatchEvent(clickEvent);\r\n\r\n return true; //indicate it worked\r\n\r\n } catch (ex) {\r\n console.log(ex);\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function buildVideoUrl(subdomain, sid){\r\n // const backendUrl = window.location.origin + \"/api/common/RenderQueueItem/\";\r\n const url = `${window.location.origin}/${URIS.renderQueue}/${subdomain}/${sid}`;\r\n return url;\r\n}\r\n\r\n//===\r\n// Fetches a file from a specific url as JSON and returns a JSON object\r\n//\r\nexport async function fetchJsonFile(fileUrl) {\r\n try {\r\n const result = await fetch(fileUrl, { method: \"GET\" });\r\n if (result.json) {\r\n const json = await result.json();\r\n\r\n if (!result.ok) {\r\n return {\r\n isError: true,\r\n status: result.status,\r\n message: result.statusText,\r\n ...json\r\n };\r\n }\r\n\r\n return json; //all good, just return the result\r\n }\r\n else if (result.ok === true) {\r\n //Nothing to return, but all is good\r\n return result;\r\n }\r\n }\r\n catch (err) {\r\n let errMsg = \"Unhandled exception during fetch. Our technical team has been notified.\";\r\n if (err.text) errMsg = await err.text();\r\n\r\n return {\r\n isError: true,\r\n message: errMsg\r\n };\r\n }\r\n}\r\n\r\n//\r\n// We have three static web app types: reporting, player, app\r\n// And three environments: development, production, qa\r\n// Each point to a distince Static Web App host.\r\n//\r\nexport async function getStaticWebAppUrl(env, app = \"reporting\") {\r\n\r\n var bootstrap_path;\r\n\r\n const hostName = window.location.hostname.toLowerCase();\r\n if (hostName.indexOf(\"localhost\") >= 0) {\r\n bootstrap_path = \"http://localhost:8100/personicom.com/bootstrap/\";\r\n } else {\r\n bootstrap_path = \"https://personicommedia.blob.core.windows.net/bootstrap/\";\r\n }\r\n\r\n\r\n \r\n\r\n ///TODO: replace universitymsg with cl/client.\r\n var clientSpecificFileName = \"universitymsg.\" + URIS.environmentFileName;\r\n const jsonClientUrl = bootstrap_path + ENV_PATH[env.toLowerCase()] + \"/\" + clientSpecificFileName;\r\n const jsonRootUrl = bootstrap_path + ENV_PATH[env.toLowerCase()] + \"/\" + URIS.environmentFileName;\r\n\r\n console.log(\"jsonClientUrl: \" + jsonClientUrl);\r\n console.log(\"jsonRootUrl: \" + jsonRootUrl);\r\n\r\n const jsonClientSpecific = await fetchJsonFile(jsonClientUrl);\r\n const jsonRoot = await fetchJsonFile(jsonRootUrl);\r\n\r\n if (jsonRoot.isError) {\r\n throw new Error(jsonRoot.message);\r\n }\r\n\r\n var json = jsonRoot;\r\n if (!jsonClientSpecific.isError) {\r\n json = { ...jsonRoot, ...jsonClientSpecific };\r\n } \r\n return json[`${app.toLowerCase()}-static-web-app`][env] || \"\";\r\n}","import React, { useState, useMemo } from 'react';\r\nimport * as Yup from \"yup\";\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Button from '@material-ui/core/Button';\r\nimport { Form, Formik } from 'formik';\r\nimport { useAuthWithActions } from './auth-provider';\r\n\r\nconst loginValidation = Yup.object().shape({\r\n email: Yup.string(\"Email\").required(\"Email is required\"),\r\n password: Yup.string(\"Password\").required(\"Password is required\"),\r\n});\r\n\r\nconst singUpValidation = Yup.object().shape({\r\n email: Yup.string(\"Email\").required(\"Email is required\"),\r\n password: Yup.string(\"Password\").required(\"Password is required\"),\r\n passwordConfirm: Yup.string(\"Confirm Password\").required(\"Password Confirmation is required\"),\r\n});\r\n\r\nconst initValues = {\r\n email: \"\",\r\n password: \"\",\r\n passwordConfirm: \"\",\r\n};\r\n\r\n\r\nconst AdminSignIn = () => {\r\n const classes = buildStyles();\r\n const auth = useAuthWithActions();\r\n const [errorMessage, setErrorMessage] = useState(null);\r\n const [view, setView] = useState(\"login\"); //\"login\" or \"signup\"\r\n const isLogin = useMemo(() => Boolean(view === \"login\"), [view]);\r\n\r\n const onSignUp = async (values, actions) => {\r\n if(!isLogin){\r\n if(values.password !== values.passwordConfirm){\r\n setErrorMessage(\"Passwords do not match\");\r\n actions.setSubmitting(false);\r\n return;\r\n }\r\n const result = await auth.createAccount(values.email, values.password);\r\n if(result.isError){\r\n setErrorMessage(\"You are not permitted to access this feature. Please contact your administrator if you believe this is a mistake.\");\r\n actions.setSubmitting(false);\r\n return;\r\n }\r\n\r\n actions.setSubmitting(false);\r\n console.log(\"create account result\", result);\r\n }\r\n }\r\n\r\n const onSignIn = async (values, actions) => {\r\n setErrorMessage(null); //clear out any errors from past attempts\r\n\r\n if(isLogin){\r\n const result = await auth.signInEmail(values.email, values.password);\r\n if(result.isError){\r\n console.log(\"Login Error\", result);\r\n setErrorMessage(result.error.message);\r\n return;\r\n }\r\n console.log(\"Login Success\", result);\r\n }\r\n else{\r\n return onSignUp(values, actions); \r\n }\r\n }\r\n\r\n \r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {isLogin && Please sign in}\r\n {!isLogin && Sign up below}\r\n \r\n {errorMessage && \r\n \r\n {errorMessage}\r\n \r\n } \r\n \r\n \r\n \r\n \r\n {props => (\r\n
\r\n \r\n \r\n \r\n \r\n {!isLogin && \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 {isLogin && \r\n \r\n First time here?\r\n \r\n \r\n }\r\n {!isLogin && \r\n \r\n Already have an account?\r\n \r\n \r\n }\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default AdminSignIn;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n root : {\r\n padding : theme.spacing(1),\r\n },\r\n titleRow: {\r\n marginBottom: theme.spacing(2),\r\n },\r\n title : {\r\n fontSize : 22,\r\n fontWeight : 500,\r\n textAlign : \"center\",\r\n marginTop: theme.spacing(1),\r\n },\r\n mb: {\r\n marginBottom: theme.spacing(1),\r\n },\r\n input: {\r\n marginBottom: theme.spacing(1),\r\n \"& .MuiFormHelperText-root\": {\r\n color: theme.palette.error.light, //theme.schoolColors.color,\r\n }, \r\n \"& fieldset\": {\r\n borderColor: `${theme.schoolColors.color}66`,\r\n \r\n },\r\n \"&:hover\": {\r\n \"& fieldset\": {\r\n borderColor: `${theme.palette.primary.main} !important`,\r\n },\r\n } \r\n },\r\n inputRoot: {\r\n \"& input\": {\r\n color: theme.schoolColors.color, \r\n },\r\n },\r\n labelRoot: {\r\n fontSize: 15,\r\n color: theme.schoolColors.color,\r\n \"&$labelFocused\": {\r\n color: theme.palette.secondary\r\n }\r\n },\r\n spacer: {\r\n margin: `${theme.spacing(2)}px ${theme.spacing(0)}px`, //`\r\n },\r\n actionsRow: {\r\n marginTop: theme.spacing(2),\r\n },\r\n action: {\r\n margin: `${theme.spacing(2)}px ${theme.spacing(0)}px`, //`\r\n minWidth: theme.spacing(15),\r\n },\r\n actionPrimary: {\r\n minWidth: theme.spacing(20),\r\n marginBottom: theme.spacing(2),\r\n }, \r\n divider: {\r\n width: \"100%\",\r\n backgroundColor: theme.palette.primary.main,\r\n },\r\n errorGrid: {\r\n padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`, //`\r\n borderRadius: 5,\r\n border: `1px solid ${theme.palette.error.dark}`, //`\r\n backgroundColor: theme.palette.error.light,\r\n marginBottom: theme.spacing(2),\r\n maxWidth: \"50%\",\r\n },\r\n errorMessage: {\r\n fontSize: \"1rem\",\r\n fontWeight: 400,\r\n color: theme.palette.error.contrastText,\r\n }\r\n}));","import React, { useEffect, useRef } from \"react\";\r\nimport { useState } from 'react';\r\nimport { useLocation } from 'react-router-dom';\r\n\r\nexport function useQueryString() {\r\n const urlp = new URLSearchParams(useLocation().search);\r\n const sort = urlp.get(\"sort\") || \"\";\r\n const filter = urlp.get(\"filter\") || \"\";\r\n const find = urlp.get(\"find\") || \"\"; //TODO: Need to convert this to \"find\" since search is a keyword that will make it tough\r\n\r\n let result = {};\r\n if (sort) result.sort = sort;\r\n if (filter) result.filter = filter;\r\n if (find) result.find = find; //TODO: Need to convert this to \"find\" since search is a keyword that will make it tough\r\n\r\n return [result, updateUrlSearch];\r\n}\r\n\r\nexport function usePage(defaultPageSize) {\r\n const [page, setPage] = useState({ number: 0, size: defaultPageSize || 20 });\r\n\r\n function change(pageNum, pageSize) {\r\n if (pageNum === undefined && pageSize === undefined) return;\r\n const myNum = pageNum || 0; //if they've provided a new page size, reset to page 0\r\n const mySize = pageSize || page.size;\r\n setPage({ number: myNum, size: mySize });\r\n }\r\n\r\n return [page, change];\r\n}\r\n\r\nexport function updateUrlSearch(key, value) {\r\n const url = new URL(window.location.href);\r\n if (url.searchParams.has(key) && !value)\r\n url.searchParams.delete(key);\r\n else if (Boolean(value))\r\n url.searchParams.set(key, value);\r\n\r\n const relative = url.href.replace(window.location.origin, \"\"); //need to remove the origin for sake of the history\r\n return relative;\r\n}\r\n\r\nexport function useInterval(callback, delay) {\r\n const savedCallback = useRef();\r\n\r\n // Remember the latest function.\r\n useEffect(() => {\r\n savedCallback.current = callback;\r\n }, [callback]);\r\n\r\n // Set up the interval.\r\n useEffect(() => {\r\n function tick() {\r\n savedCallback.current();\r\n }\r\n if (delay !== null) {\r\n let id = setInterval(tick, delay);\r\n return () => clearInterval(id);\r\n }\r\n }, [delay]);\r\n}\r\n\r\nexport function useIsEmbeded(){\r\n const location = useLocation();\r\n const pathName = location.pathname.toLowerCase();\r\n const isEmbeded = pathName.indexOf(\"/player\") > -1 || pathName.indexOf(\"/_embed\") > -1;\r\n return isEmbeded;\r\n}\r\n\r\nexport const AnchorPositions = {\r\n bottomRight: {\r\n getContentAnchorEl: null,\r\n anchorOrigin: {\r\n vertical: \"bottom\",\r\n horizontal: \"right\",\r\n },\r\n transformOrigin: {\r\n vertical: \"top\",\r\n horizontal: \"right\",\r\n },\r\n },\r\n bottomLeft: {\r\n getContentAnchorEl: null,\r\n anchorOrigin: {\r\n vertical: \"bottom\",\r\n horizontal: \"left\",\r\n },\r\n transformOrigin: {\r\n vertical: \"top\",\r\n horizontal: \"left\",\r\n },\r\n },\r\n bottomCenter: {\r\n getContentAnchorEl: null,\r\n anchorOrigin: {\r\n vertical: \"bottom\",\r\n horizontal: \"center\",\r\n },\r\n transformOrigin: {\r\n vertical: \"top\",\r\n horizontal: \"center\",\r\n },\r\n },\r\n};\r\n\r\n//==================\r\n// Anchor Hook\r\n// export interface IAnchorHandler {\r\n// anchor : object,\r\n// isOpen : boolean,\r\n// onOpen : React.MouseEventHandler,\r\n// onClose : (any) => void,\r\n// positionProps : \"bottomRight\" | \"bottomLeft\" | \"bottomCenter\" | undefined,\r\n// }\r\n\r\nexport function useAnchor(position = \"bottomRight\")//: [\r\n // Element | null,\r\n // boolean,\r\n // React.MouseEventHandler,\r\n // (ignored?: any) => void,\r\n // any] \r\n {\r\n const [anchor, setAnchor] = React.useState(null);\r\n\r\n const onOpen = (e) => {\r\n setAnchor(e.currentTarget);\r\n };\r\n\r\n const onClose = () => {\r\n setAnchor(null);\r\n };\r\n const positionProps = AnchorPositions[position];\r\n\r\n return [anchor, Boolean(anchor), onOpen, onClose, positionProps];\r\n}","import React, { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { useHistory, useLocation, useParams } from \"react-router-dom\";\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Button, Grid, Menu, MenuItem, Tooltip, Typography } from '@material-ui/core';\r\nimport { useAuthWithActions } from './auth-provider';\r\nimport { useAnchor } from 'helpers/general-hooks';\r\nimport { fetchJsonFile } from 'helpers/api-helper';\r\nimport { useCustomizations } from \"@personicom/customizations\";\r\n\r\nconst defaultMenuItems = [\r\n { id: \"logout\", label: \"Logout\", isAuthenticated: true, actionPath: \"/logout\" },\r\n { id: \"reports\", label: \"Reports\", isAuthenticated: true, actionPath: \"/reports\" },\r\n // { id: \"sep\", isSeparator: true, isAuthenticated: true },\r\n];\r\nconst defaultAppMenuItem = { id: 30, label: \"Render Request\", isAuthenticated: true, actionPath: \"/app\" };\r\n\r\n//== Gets the appropriate path for an app \"application\" based on the appConfig and the fallback / defaults.\r\nconst getAppPath = (appConfig, subdomain) => {\r\n if (appConfig.isDefault) {\r\n return `${subdomain ? `/${subdomain}` : ''}/app`;\r\n }\r\n else {\r\n return `${subdomain ? `/${subdomain}` : ''}/app/${appConfig.urlSlug ?? appConfig.id}`;\r\n }\r\n}\r\n\r\nconst AuthContainer = ({ children }) => {\r\n const classes = buildStyles();\r\n const { blobUrl } = useCustomizations();\r\n const location = useLocation();\r\n const { subdomain } = useParams();\r\n const history = useHistory();\r\n const auth = useAuthWithActions();\r\n const [menuItems, setMenuItems] = useState([]);\r\n const [anchor, isOpen, onOpen, onClose, position] = useAnchor();\r\n const availableMenuItems = useMemo(() => menuItems.filter(itm => itm.isAuthenticated === auth.isAuthenticated), [menuItems, auth.isAuthenticated]);\r\n\r\n const menuClicked = useCallback((item) => async () => {\r\n if (item.actionPath === \"/logout\") {\r\n await auth.signOut();\r\n return;\r\n }\r\n else if (item.actionPath !== location.pathname) {\r\n history.push(item.actionPath);\r\n }\r\n onClose();\r\n }, [auth, location, history, onClose]);\r\n\r\n useEffect(() => {\r\n async function doEffect() {\r\n var menu = [];\r\n try {\r\n const appsUrl = blobUrl(\"applications.json\");\r\n const appsJson = await fetchJsonFile(appsUrl);\r\n if (appsJson?.applications) {\r\n console.log(\"applications:\", appsJson);\r\n menu = appsJson.applications.reduce((output, item) => {\r\n const menuItem = { id: item.id, label: item.label, isAuthenticated: true, actionPath: getAppPath(item, subdomain) };\r\n output.push(menuItem);\r\n return output;\r\n }, [...defaultMenuItems]);\r\n }\r\n else {\r\n console.log(\"no applications.json found, using defaults\");\r\n }\r\n }\r\n catch (ex) {\r\n console.error(\"failed to load applications.json, using default apps\", ex);\r\n }\r\n\r\n if (menu.length === 0) menu = [...defaultMenuItems, defaultAppMenuItem];\r\n setMenuItems(menu);\r\n }\r\n doEffect()\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n\r\n {auth.isAuthenticated &&\r\n \r\n \r\n \r\n \r\n \r\n }\r\n \r\n {availableMenuItems.map(item => {item.label})}\r\n \r\n\r\n \r\n
\r\n {children}\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default AuthContainer;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n authHeader: {\r\n padding: `${theme.spacing(0.5)}px ${theme.spacing(1)}px`, //`\r\n marginBottom: theme.spacing(1),\r\n },\r\n username: {\r\n marginLeft: theme.spacing(1),\r\n color: theme.schoolColors.color,\r\n },\r\n action: {\r\n paddingTop: 0,\r\n paddingBottom: 0,\r\n },\r\n headerButton: {\r\n border: \"none\",\r\n \"& i\": {\r\n color: theme.schoolColors.color,\r\n }\r\n }\r\n}));","import React from \"react\";\r\nimport ErrorCard from \"./error-card\";\r\n\r\nclass ErrorBoundary extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.state = { hasError: false, error: null };\r\n }\r\n\r\n static getDerivedStateFromError(error) {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error, errorInfo) {\r\n console.log(error, errorInfo);\r\n }\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return \r\n }\r\n\r\n return this.props.children; \r\n }\r\n}\r\n\r\nexport default ErrorBoundary;\r\n","import React, { useState, useEffect } from \"react\";\r\nimport ErrorCard from \"helpers/error-card\";\r\nimport { useAuth } from \"auth/auth-provider\";\r\nimport { getEnvironment, getStaticWebAppUrl } from \"helpers/api-helper\";\r\nimport { Grid, makeStyles } from \"@material-ui/core\";\r\nimport AdminSignIn from \"auth/admin-signin\";\r\nimport AuthContainer from \"auth/auth-container\";\r\nimport ErrorBoundary from \"helpers/error-boundary\";\r\nimport { useParams } from \"react-router\";\r\nimport { useCustomizations } from \"@personicom/customizations\";\r\n\r\nconst VodFrame = () => {\r\n const { isAuthenticated, user } = useAuth();\r\n const { application } = useParams();\r\n const [appUrl, setAppUrl] = useState(null);\r\n const [error, setError] = useState(null);\r\n const [lastApp, setLastApp] = useState(null);\r\n const classes = buildStyles();\r\n const { subdomain } = useCustomizations();\r\n\r\n\r\n //--\r\n // Effect to load the url for the iframe based on the environment we're running in.\r\n useEffect(() => {\r\n async function doEffect(){\r\n try{\r\n const env = getEnvironment(true).toLowerCase();\r\n let url = await getStaticWebAppUrl(env, \"app\");\r\n\r\n if (!url) {\r\n setError([\"Unfortunately, the on-demand video module could not be loaded. Technical support has been notified.\", \"Could not get app url. Either environments.json is missing or invalid, or it does not contain key for environment: \" + env]);\r\n return;\r\n }\r\n\r\n const appPath = application ? `/${application}` : \"\"; //for any secondary apps that will be at /[app-slug]\r\n setLastApp(application); //track this so we know to refresh when it changes\r\n\r\n //Sample: http://app.universitymsg.com.localhost:3002/pittcomingsoon/app\r\n url = `${url}/${subdomain}${appPath}/?cl=universitymsg.com&en=${env}&token=${encodeURIComponent(user.token)}&parentWindow=${encodeURIComponent(window.location.href)}`\r\n \r\n setAppUrl(url);\r\n }\r\n catch(ex){\r\n console.error(\"attempting to build the video on demand static web app url\", ex);\r\n setError([\"Unfortunately, the video on demand module could not be loaded. Technical support has been notified.\", ex.toString()]);\r\n }\r\n }\r\n \r\n if(user && user.token && (!appUrl || lastApp !== application)){\r\n // console.log(\"vod-frame is re-rendering, application: \", application);\r\n doEffect();\r\n }\r\n }, [appUrl, user, application, lastApp]);\r\n\r\n // console.log(\"user (from vod frame)\", user);\r\n return (\r\n \r\n {!isAuthenticated &&\r\n \r\n }\r\n {isAuthenticated &&\r\n \r\n \r\n {error && \r\n \r\n }\r\n {!error && appUrl && \r\n
\r\n \r\n
\r\n }\r\n
\r\n
\r\n }\r\n
\r\n );\r\n};\r\n\r\nexport default VodFrame;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n appBody: {\r\n flexWrap: \"nowrap\",\r\n textAlign: \"center\",\r\n padding: 5,\r\n borderBottom: `5px solid ${theme.schoolColors.borderColor}` //`\r\n },\r\n iframeContainer: {\r\n padding: theme.spacing(2),\r\n },\r\n iframe: {\r\n height: \"calc(100vh - 210px)\",\r\n border: \"none\",\r\n }\r\n \r\n}));","import React from 'react';\r\nimport AppHeader from '../app-header';\r\nimport { AuthProvider } from '../auth/auth-provider';\r\nimport VodFrame from './vod-frame';\r\n\r\n\r\nfunction VodContainer () {\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default VodContainer;","import React, { useEffect, useState } from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Grid } from '@material-ui/core';\r\nimport { useAuth } from 'auth/auth-provider';\r\nimport AdminSignIn from 'auth/admin-signin';\r\nimport AuthContainer from 'auth/auth-container';\r\nimport ErrorBoundary from 'helpers/error-boundary';\r\nimport { getEnvironment, getStaticWebAppUrl, getSearchParam } from 'helpers/api-helper';\r\nimport ErrorCard from 'helpers/error-card';\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useCustomizations } from \"@personicom/customizations\";\r\n\r\n\r\nconst ReportsFrame = () => {\r\n const { isAuthenticated, user } = useAuth();\r\n const classes = buildStyles();\r\n const [reportAppUrl, setReportAppUrl] = useState(null);\r\n const [error, setError] = useState(null);\r\n const location = useLocation();\r\n const { subdomain } = useCustomizations();\r\n\r\n\r\n //--\r\n // Effect to load the url for the iframe based on the environment we're running in.\r\n useEffect(() => {\r\n async function doEffect(){\r\n try{\r\n const env = getEnvironment(true).toLowerCase();\r\n let url = await getStaticWebAppUrl(env, \"reporting\"); \r\n\r\n if(!url){\r\n setError([\"Unfortunately, the reporting module could not be loaded. Technical support has been notified.\", \"Could not get reporting app url. Either environments.json is missing or invalid, or it does not contain key for environment: \" + env]);\r\n return;\r\n }\r\n\r\n const rowId = getSearchParam(\"rowid\", true);\r\n const rowPart = rowId ? `&rowid=${rowId}` : \"\";\r\n console.log(\"found row id: \", rowId);\r\n\r\n //Sample: http://reporting.universitymsg.com.localhost:3003/pittcomingsoon/\r\n url = `${url}/${subdomain}/?en=${env}&cl=universitymsg.com&${rowPart}&token=${encodeURIComponent(user.token)}&parentWindow=${encodeURIComponent(window.location.href)}`\r\n \r\n if(rowId) console.log(\"final url with row id: \", url);\r\n\r\n setReportAppUrl(url);\r\n }\r\n catch(ex){\r\n console.error(\"attempting to build the report static web app url\", ex);\r\n setError([\"Unfortunately, the reporting module could not be loaded. Technical support has been notified.\", ex.toString()]);\r\n }\r\n }\r\n \r\n if(!reportAppUrl && user && user.token){\r\n doEffect()\r\n }\r\n }, [reportAppUrl, user]);\r\n\r\n console.log(\"user\", user);\r\n return (\r\n \r\n {!isAuthenticated &&\r\n \r\n }\r\n {isAuthenticated &&\r\n \r\n \r\n {error && \r\n \r\n }\r\n {!error && reportAppUrl && \r\n
\r\n \r\n
\r\n }\r\n
\r\n
\r\n }\r\n
\r\n );\r\n}\r\n\r\nexport default ReportsFrame;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n appBody: {\r\n flexWrap: \"nowrap\",\r\n textAlign: \"center\",\r\n padding: 5,\r\n borderBottom: `5px solid ${theme.schoolColors.borderColor}` //`\r\n },\r\n iframeContainer: {\r\n padding: theme.spacing(2),\r\n },\r\n iframe: {\r\n height: \"calc(100vh - 210px)\",\r\n border: \"none\",\r\n }\r\n \r\n}));","import React from 'react';\r\nimport AppHeader from '../../app-header';\r\n// import ReportsBody from './reports-body';\r\n// import TelemetryProvider from '../../helpers/telemetry-provider';\r\nimport { AuthProvider } from '../../auth/auth-provider';\r\nimport Grid from \"@material-ui/core/Grid\";\r\nimport ErrorCard from \"../../helpers/error-card\";\r\nimport ReportsFrame from './reports-frame';\r\n\r\nfunction ReportsContainer(props) {\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default ReportsContainer;","import React, { useEffect, useState } from 'react';\r\nimport { useParams } from 'react-router-dom';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport ErrorBoundary from 'helpers/error-boundary';\r\nimport { getEnvironment, getStaticWebAppUrl } from 'helpers/api-helper';\r\nimport { getPlayerParamsFromUrl } from 'helpers/general-helpers';\r\nimport ErrorCard from 'helpers/error-card';\r\nimport { useIsEmbeded } from 'helpers/general-hooks';\r\nimport { useCustomizations } from \"@personicom/customizations\";\r\n\r\nconst PlayerFrameEmbeded = () => {\r\n const [playerAppUrl, setPlayerAppUrl] = useState(null);\r\n const [error, setError] = useState(null);\r\n const isEmbeded = useIsEmbeded();\r\n let { campaignId, sid } = useParams();\r\n const classes = buildStyles();\r\n const { subdomain } = useCustomizations();\r\n \r\n const { sidQueryParam, campaignQueryParam, isDebugFlagParam} = getPlayerParamsFromUrl();\r\n \r\n //--\r\n // Effect to load the url for the iframe based on the environment we're running in.\r\n useEffect(() => {\r\n async function doEffect(){\r\n try{\r\n \r\n const env = getEnvironment(true).toLowerCase();\r\n let swaUrl = await getStaticWebAppUrl(env, \"player\");\r\n\r\n if (!swaUrl){\r\n setError([\"Unfortunately, the player module could not be loaded. Technical support has been notified.\", \"Could not get player app url. Either environments.json is missing or invalid, or it does not contain key for environment: \" + env]);\r\n return;\r\n }\r\n\r\n const mySid = sid ?? sidQueryParam;\r\n const myCampaignId = campaignId ?? campaignQueryParam;\r\n /*\r\n * The SWA Player expect the url using path for subdomain, campaign, and video id:\r\n * https://player.client.com/{subdomain}/{campaignId}/{videoid}\r\n * \r\n * The player also takes an optiona /_embed/ path to force embed mode. This should be after the subdomain\r\n * https://player.client.com/{subdomain}/_embed/{campaignId}/{videoid}\r\n * \r\n * If not using a custom client CNAME, you must pass in the client via the cl param:\r\n * https://purple-pond-0d2672c10.azurestaticapps.net/seeyouatpitt/38E8A828-D684-45CE-A627-80326E636AC3/test07082021a?cl=universitymsg.com\r\n * \r\n * Environment info should be passed down always as well, using &en=${[qa,dev,production]}\r\n * \r\n * parentWindow should capture how they landed here, and used by SWA player to allow links back to here.\r\n */\r\n\r\n const embedOrNot = isEmbeded ? \"/_embed\" : \"\";\r\n\r\n var params = {\r\n cl: \"universitymsg.com\",\r\n en: env,\r\n parentWindow: encodeURIComponent(window.location.href), //We need to pass this, because the iframe child can't see our href. TODO: Policy change on our iframe to allow them to see our href?\r\n ...(document.referrer && {parentReferrer: encodeURIComponent(document.referrer)}) //if exists.\r\n };\r\n console.log(params);\r\n const urlSerchParams = new URLSearchParams(params);\r\n const url = new URL(swaUrl);\r\n url.search = urlSerchParams.toString();\r\n url.pathname = `${subdomain}${embedOrNot}/${myCampaignId ? `${myCampaignId}/` : \"\"}${mySid}`;\r\n console.log(`iframe url:\\r\\n ${url.toString()}`);\r\n\r\n setPlayerAppUrl(url.toString());\r\n \r\n }\r\n catch(ex){\r\n console.error(\"attempting to build the player static web app url\", ex);\r\n setError([\"Unfortunately, the player module could not be loaded. Technical support has been notified.\", ex.toString()]);\r\n }\r\n }\r\n \r\n if(!playerAppUrl){\r\n doEffect()\r\n }\r\n }, [playerAppUrl, subdomain, campaignId, sid, campaignQueryParam, sidQueryParam]);\r\n\r\n return (\r\n
\r\n \r\n {error && }\r\n {!error && playerAppUrl && \r\n
\r\n \r\n
\r\n }\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default PlayerFrameEmbeded;\r\n\r\nconst buildStyles = makeStyles(theme => ({\r\n iframeContainerEmbeded: { \r\n position: \"relative\", \r\n paddingBottom: \"56.25%\", \r\n height: 0, \r\n overflow: \"hidden\", \r\n maxWidth: \"100%\" \r\n },\r\n iframeContainer: {\r\n // padding: theme.spacing(2),\r\n height: \"100vh\",\r\n width: \"100%\",\r\n position: \"relative\",\r\n },\r\n iframeEmbeded : {\r\n border: \"none\",\r\n position: \"absolute\", \r\n top: 0, \r\n left: 0, \r\n width: \"100%\", \r\n height: \"100%\" \r\n }, \r\n iframe:{\r\n // height: \"53vh\",\r\n // minHeight: 500,\r\n height: \"100vh\",\r\n border: \"none\",\r\n [theme.breakpoints.down(\"sm\")]: {\r\n minHeight: 350\r\n },\r\n [theme.breakpoints.down(\"xs\")]: {\r\n minHeight: 30\r\n }\r\n } \r\n}));","import React from 'react';\r\nimport { BrowserRouter as Router, Switch, Route } from 'react-router-dom';\r\nimport VodContainer from './vod/vod-container.js';\r\nimport ReportsContainer from './components/reports/reports-container';\r\nimport PlayerFrameEmbeded from 'player/player-frame-embeded.js';\r\n\r\nfunction AppRouting() {\r\n\r\n return (\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 {/* //This is our default player route, for Landing mode.*/}\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default AppRouting;\r\n\r\n/*\r\n * Sample URLS:\r\n * Embeded : \r\n * https://pittgrad.universitymsg.com/player/?sid=4061609\r\n * https://pittgrad.universitymsg.com/_embed/?sid=4061609\r\n * Default : \r\n * https://welcometopitt.universitymsg.com/?sid=209178 * \r\n */","import React from 'react';\r\nimport AppRouting from \"./appRouting\";\r\nimport { Grid } from \"@material-ui/core\";\r\nimport { useEffect, useState } from \"react\";\r\nimport CustomizationsProvider, { CustomizationHelmet } from \"@personicom/customizations\";\r\nimport { getBaseUrl, getClientFromUrl, getEnvironmentFromUrl, getSubdomainFromUrl, ErrorCard, LoadingIndicator } from \"@personicom/customizations\";\r\n\r\n\r\n//TODO: do we still need to use GA at all?\r\nconst GA_TRACKER = \"UA-102377011-8\";\r\nconst GA_TRACKER_SECONDARY = \"UA-157273197-1\";\r\n\r\nconst App = () => {\r\n const [isReady, setReady] = useState(false);\r\n const [error, setError] = useState(null);\r\n const [path, setPath] = useState(\"\");\r\n useEffect(() => {\r\n async function initialize() {\r\n try {\r\n var client = await getClientFromUrl();\r\n var env = await getEnvironmentFromUrl();\r\n var sd = getSubdomainFromUrl();\r\n console.log(`Client: ${client}\\r\\nSD: ${sd}\\r\\nEnv: ${env}`);\r\n const basePath = await getBaseUrl();\r\n setPath(basePath);\r\n setReady(true);\r\n }\r\n catch (ex) {\r\n setError(ex);\r\n }\r\n }\r\n\r\n initialize();\r\n }, []);\r\n\r\n if (error) {\r\n return (\r\n \r\n \r\n \r\n );\r\n }\r\n else if (!isReady) {\r\n return ;\r\n }\r\n else {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n }\r\n}\r\n\r\nexport default App;","import { getReportData, getReportDownload, getReportFilters } from '../../helpers/api-helper';\r\n\r\n//===============\r\n// The Action Types\r\n\r\nconst LOADING = \"RPT_LOADING\", LOADED = \"RPT_LOADED\", FAILED = \"RPT_FAILED\";\r\nconst FILTERS_LOADING = \"RPT_FILTERS_LOADING\", FILTERS_LOADED = \"RPT_FILTERS_LOADED\", FILTERS_FAILED = \"RPT_FILTERS_FAILED\";\r\nconst DOWNLOADING = \"RPT_DOWNLOADING\", DOWNLOADED = \"RPT_DOWNLOADED\", DOWNLOAD_FAILED = \"RPT_DOWNLOAD_FAILED\";\r\n\r\nexport const RPT_ACTIONS = {\r\n LOADING, LOADED, FAILED,\r\n FILTERS_LOADING, FILTERS_LOADED, FILTERS_FAILED,\r\n DOWNLOADING, DOWNLOADED, DOWNLOAD_FAILED,\r\n};\r\n\r\n//-----------\r\n// Gets the report results that match the current page and filter\r\nexport const loadReports = (subdomain, user, pageNum, pageSize, sort, filter) => async(dispatch, getState) => {\r\n\r\n console.log(\"loadReports called with parameters\", pageNum, pageSize, sort, filter);\r\n \r\n dispatch({type: LOADING});\r\n\r\n const result = await getReportData(subdomain, user, pageNum, pageSize, sort, filter);\r\n if(result.isError){\r\n //TODO: test out the error case\r\n dispatch({type: FAILED, error: result.error});\r\n }\r\n else{ \r\n dispatch({type: LOADED, data: result.items, pagination: result.options, timestamp: result.timestamp});\r\n }\r\n}\r\n\r\n//-----------\r\n// Downloads the report data as a csv\r\nexport const downloadReport = (subdomain, user, sort, filter) => async(dispatch, getState) => {\r\n\r\n console.log(\"downloadReport called with parameters\", sort, filter);\r\n \r\n dispatch({type: DOWNLOADING});\r\n\r\n const result = await getReportDownload(subdomain, user, sort, filter);\r\n if(result.isError){\r\n //TODO: test out the error case\r\n dispatch({type: DOWNLOAD_FAILED, error: result.error});\r\n }\r\n else{ \r\n dispatch({type: DOWNLOADED, data: result});\r\n }\r\n}\r\n\r\n//-----------\r\n// Gets the filter options for the reports list\r\nexport const loadReportFilterOptions = (subdomain, user ) => async(dispatch, getState) => {\r\n\r\n dispatch({type: FILTERS_LOADING});\r\n\r\n const result = await getReportFilters(subdomain, user);\r\n if(result.isError){\r\n //TODO: test out the error case\r\n dispatch({type: FILTERS_FAILED, error: result.error});\r\n }\r\n else{ \r\n dispatch({type: FILTERS_LOADED, data: result});\r\n }\r\n}","import { RPT_ACTIONS } from '../actions/report-actions';\r\nimport { createReducer } from './reducer-helpers';\r\n\r\n//========================\r\n// Reducer Default State\r\nconst INITIAL_STATE = {\r\n status : {\r\n isInitialized : false,\r\n isWorking : false,\r\n isDownloading : false,\r\n optsWorking : false, \r\n error : null,\r\n pagination : null,\r\n loadedAt : null,\r\n },\r\n reportItems : null, \r\n filterOptions : null,\r\n};\r\n\r\n//========================\r\n// Reducer functions\r\n\r\n//#region Loading Report Filters\r\nfunction filtersLoading(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n optsWorking : true,\r\n error : null,\r\n },\r\n filterOptions : null,\r\n }\r\n}\r\n\r\nfunction filtersLoaded(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n optsWorking : false,\r\n error : null,\r\n },\r\n filterOptions : action.data,\r\n };\r\n}\r\n\r\nfunction filtersFailed(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n optsWorking : false,\r\n error : action.error,\r\n },\r\n filterOptions : null,\r\n };\r\n}\r\n//#endregion\r\n\r\n//#region Loading Report Items\r\nfunction itemsLoading(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isWorking : true,\r\n error : null,\r\n loadedAt : null,\r\n },\r\n reportItems : null, //TODO: should the items disappear while loading?\r\n }\r\n}\r\n\r\nfunction itemsLoaded(state, action){\r\n //DataGrid requires an id field, so make one with the data\r\n const items = action.data ? action.data.map(i => { return {id: i.renderId, ...i}; }) : action.data;\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isInitialized : true,\r\n isWorking : false,\r\n error : null,\r\n pagination : action.pagination,\r\n loadedAt : action.timestamp,\r\n },\r\n reportItems : items, //action.data,\r\n };\r\n}\r\n\r\nfunction itemsFailed(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isInitialized : true,\r\n isWorking : false,\r\n error : action.error,\r\n pagination : null,\r\n loadedAt : null,\r\n },\r\n reportItems : null,\r\n };\r\n}\r\n//#endregion\r\n\r\n//#region Downloading Report\r\nfunction downloading(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isDownloading : true,\r\n error : null,\r\n },\r\n }\r\n}\r\n\r\nfunction downloaded(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isDownloading : false,\r\n error : null,\r\n },\r\n };\r\n}\r\n\r\nfunction downloadFailed(state, action){\r\n return {\r\n ...state,\r\n status : {\r\n ...state.status,\r\n isDownloading : false,\r\n error : action.error,\r\n },\r\n };\r\n}\r\n//#endregion\r\n\r\n//-----------------\r\n// Action map that will be used to build the reducer\r\nconst reducerMap = {\r\n [RPT_ACTIONS.LOADING] : itemsLoading,\r\n [RPT_ACTIONS.LOADED] : itemsLoaded,\r\n [RPT_ACTIONS.FAILED] : itemsFailed, \r\n \r\n [RPT_ACTIONS.FILTERS_LOADING] : filtersLoading,\r\n [RPT_ACTIONS.FILTERS_LOADED] : filtersLoaded,\r\n [RPT_ACTIONS.FILTERS_FAILED] : filtersFailed, \r\n\r\n [RPT_ACTIONS.DOWNLOADING] : downloading,\r\n [RPT_ACTIONS.DOWNLOADED] : downloaded,\r\n [RPT_ACTIONS.DOWNLOAD_FAILED] : downloadFailed, \r\n \r\n};\r\n\r\n//The actually reducer\r\nexport default createReducer(INITIAL_STATE, reducerMap);","//--------------\r\n// Creates a reducer on the fly out of an object map\r\nexport function createReducer(initialState, handlers) {\r\n \r\n return function reducer(state = initialState, action) {\r\n if (handlers.hasOwnProperty(action.type)) {\r\n return handlers[action.type](state, action)\r\n } \r\n else {\r\n return state\r\n }\r\n }\r\n \r\n}","import { ApplicationInsights } from '@microsoft/applicationinsights-web';\r\nimport { ReactPlugin } from '@microsoft/applicationinsights-react-js';\r\nimport { getEnvironment } from './api-helper';\r\nlet reactPlugin = null;\r\nlet appInsights = null;\r\n\r\n/**\r\n * Create the App Insights Telemetry Service\r\n * @return {{reactPlugin: ReactPlugin, appInsights: Object, initialize: Function}} - Object\r\n */\r\nconst createTelemetryService = () => {\r\n\r\n /**\r\n * Initialize the Application Insights class\r\n * @param {string} instrumentationKey - Application Insights Instrumentation Key\r\n * @param {Object} browserHistory - client's browser history, supplied by the withRouter HOC\r\n * @return {void}\r\n */\r\n const initialize = (instrumentationKey, browserHistory) => {\r\n if (!browserHistory) {\r\n throw new Error('Could not initialize Telemetry Service');\r\n }\r\n if (!instrumentationKey) {\r\n throw new Error('Instrumentation key not provided in ./src/telemetry-provider.jsx')\r\n }\r\n\r\n reactPlugin = new ReactPlugin();\r\n\r\n appInsights = new ApplicationInsights({\r\n config: {\r\n instrumentationKey: instrumentationKey,\r\n maxBatchInterval: 0,\r\n disableFetchTracking: false,\r\n autoTrackPageVisitTime: true,\r\n extensions: [reactPlugin],\r\n extensionConfig: {\r\n [reactPlugin.identifier]: {\r\n history: browserHistory\r\n }\r\n }\r\n }\r\n });\r\n\r\n appInsights.loadAppInsights();\r\n\r\n var telemetryInitializer = (envelope) => {\r\n envelope.data.EnvironmentName = getEnvironment();\r\n };\r\n\r\n appInsights.addTelemetryInitializer(telemetryInitializer);\r\n\r\n appInsights.trackPageView();\r\n };\r\n\r\n return { reactPlugin, appInsights, initialize };\r\n};\r\n\r\nexport const ai = createTelemetryService();\r\nexport const getAppInsights = () => appInsights;\r\n","import React, { Component, Fragment } from 'react';\r\nimport { withAITracking } from '@microsoft/applicationinsights-react-js';\r\nimport { ai } from './TelemetryService';\r\nimport { withRouter } from 'react-router-dom';\r\n\r\n/**\r\n * This Component provides telemetry with Azure App Insights\r\n *\r\n * NOTE: the package '@microsoft/applicationinsights-react-js' has a HOC withAITracking that requires this to be a Class Component rather than a Functional Component\r\n */\r\nclass TelemetryProvider extends Component {\r\n state = {\r\n initialized: false\r\n };\r\n\r\n componentDidMount() {\r\n const { history } = this.props;\r\n const { initialized } = this.state;\r\n const AppInsightsInstrumentationKey = this.props.instrumentationKey; \r\n if (!Boolean(initialized) && Boolean(AppInsightsInstrumentationKey) && Boolean(history)) {\r\n ai.initialize(AppInsightsInstrumentationKey, history);\r\n this.setState({ initialized: true });\r\n }\r\n\r\n if (this.props.after)\r\n this.props.after();\r\n }\r\n\r\n render() {\r\n const { children } = this.props;\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default withRouter(withAITracking(ai.reactPlugin, TelemetryProvider));\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport _ from 'lodash';\r\nimport App from './app';\r\nimport { Provider } from 'react-redux';\r\nimport configureStore from './store/configure-store';\r\nimport { BrowserRouter } from 'react-router-dom';\r\nimport TelemetryProvider from 'helpers/telemetry-provider';\r\n\r\n\r\nconst rootElement = document.getElementById('root');\r\nconst store = configureStore();\r\n\r\nconst render = () => {\r\n ReactDOM.render(\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n , rootElement);\r\n};\r\n\r\n\r\n//Render the app the first time through\r\nrender();\r\n\r\n//Try to accept any HMR changes, and not re-render the whole app...\r\nif (module.hot) {\r\n module.hot.accept('./app', () => {\r\n render();\r\n });\r\n}\r\n","import { applyMiddleware, createStore } from 'redux';\r\nimport { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';\r\nimport thunk from 'redux-thunk';\r\nimport configureReducers from './reducers/root-reducer';\r\n// import { routerMiddleware } from 'react-router-redux';\r\nimport { createLogger } from 'redux-logger';\r\n\r\nconst configureMiddleware = () => {\r\n const logger = createLogger({collapsed : true});\r\n\r\n const middleware = [\r\n thunk,\r\n // routerMiddleware(history),\r\n logger\r\n ];\r\n\r\n // In development, use the browser's Redux dev tools extension if installed\r\n const enhancers = [];\r\n // const isDevelopment = process.env.NODE_ENV === 'development';\r\n // if (isDevelopment && typeof window !== 'undefined' && window.devToolsExtension) {\r\n // enhancers.push(window.devToolsExtension());\r\n // }\r\n const middlewares = composeWithDevTools(applyMiddleware(...middleware), ...enhancers);\r\n return middlewares;\r\n}\r\n\r\nexport default function configureStore() {\r\n\r\n const initialState = window.initialReduxState;\r\n const rootReducer = configureReducers();\r\n const middlewares = configureMiddleware();\r\n\r\n const store = createStore(\r\n rootReducer,\r\n initialState,\r\n middlewares,\r\n );\r\n\r\n //For HMR, try to hot-replace the reducer, if possible (doesn't always work)\r\n if(process.env.NODE_ENV === \"development\"){\r\n \r\n console.log(\"attempting to hot replace reducer\");\r\n\r\n if(module.hot){\r\n module.hot.accept(\"./reducers/root-reducer.js\", () => {\r\n const newRoot = require(\"./reducers/root-reducer\").default;\r\n store.replaceReducer(newRoot);\r\n });\r\n }\r\n }\r\n\r\n return store;\r\n}\r\n\r\n\r\n","import { combineReducers } from 'redux';\r\n// import { connectRouter } from 'connected-react-router';\r\n// import { routerReducer } from 'react-router-redux';\r\n// import appReducer from './app-reducer';\r\nimport rptReducer from './reports-reducer';\r\n\r\nexport default function configureReducers(history){\r\n\r\n const reducers = {\r\n // router : connectRouter(history),\r\n //app : appReducer,\r\n reports : rptReducer,\r\n };\r\n\r\n const rootReducer = combineReducers({\r\n ...reducers,\r\n // routing: routerReducer\r\n });\r\n\r\n return rootReducer;\r\n}"],"sourceRoot":""}