{"version":3,"sources":["components/loading/loading.tsx","components/loading/index.ts","components/user/user-context.tsx","components/user/index.ts","utils/api-client.tsx","components/app/app.tsx","serviceWorker.ts","utils/theme.tsx","index.tsx","components/app/app-provider.tsx","components/user/user-service.ts","components/auth/auth-service.ts","components/auth/auth-context.tsx","components/auth/index.ts"],"names":["Root","styled","div","vertical","horizontal","padding","theme","spacing","Loading","children","rest","CircularProgress","size","color","UserContext","createContext","undefined","UserProvider","value","user","useAuth","data","Provider","useUser","context","useContext","Error","api","endpoint","a","async","Promise","resolve","reject","token","window","localStorage","getItem","process","headers","Authorization","config","fetch","then","response","ok","json","catch","Response","status","message","String","body","object","error_description","get","method","post","JSON","stringify","loadAuthenticatedApp","module","default","AuthenticatedApp","React","lazy","UnauthenticatedApp","isLocalhost","Boolean","location","hostname","match","registerValidSW","swUrl","navigator","serviceWorker","register","registration","onupdatefound","installingWorker","installing","onstatechange","state","controller","console","log","onUpdate","onSuccess","error","defaults","palette","primary","main","secondary","typography","fontFamily","join","overrides","MuiFormControlLabel","label","width","MuiLinearProgress","colorPrimary","backgroundColor","GlobalStyle","createGlobalStyle","ReactDOM","render","StrictMode","CssBaseline","createMuiTheme","StylesProvider","injectFirst","useEffect","Suspense","fallback","document","getElementById","URL","href","origin","addEventListener","contentType","indexOf","ready","unregister","reload","checkValidServiceWorker","getUserKey","setUser","setItem","name","requestSaveUser","requestUser","username","getTokenKey","key","setToken","access_token","userRequestUser","requestLogout","removeItem","AuthContext","bootstrapAppData","AuthProvider","useState","loading","setLoading","firstAttemptFinished","setFirstAttemptFinished","useAsync","promiseFn","isPending","isSettled","setError","useLayoutEffect","handleLogin","password","requestLogin","finally","login","logout"],"mappings":"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","file":"static/js/main.e3d46821.chunk.js","sourcesContent":["import { CircularProgress } from '@material-ui/core';\r\nimport { CircularProgressProps } from '@material-ui/core/CircularProgress';\r\nimport { ContentPosition } from 'csstype';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface ILoadingProps extends CircularProgressProps {\r\n vertical?: ContentPosition;\r\n horizontal?: ContentPosition;\r\n padding?: number;\r\n}\r\n\r\nconst Root = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n\r\n ${({ vertical, horizontal }) =>\r\n (vertical || horizontal) &&\r\n `\r\n justify-content: ${vertical};\r\n align-items: ${horizontal};\r\n `}\r\n\r\n ${({ padding, theme }) => padding && `padding: ${theme.spacing(padding)}px`}\r\n`;\r\n\r\nexport const Loading: React.FC = ({\r\n children,\r\n vertical,\r\n horizontal,\r\n padding,\r\n ...rest\r\n}) => (\r\n \r\n \r\n {children}\r\n \r\n);\r\n","export { Loading } from './loading';\r\n","import { useAuth } from '@components/auth';\r\nimport React, { createContext, useContext } from 'react';\r\nimport { IUser } from './IUser';\r\n\r\nexport interface IUserContextProps {\r\n user: IUser | undefined;\r\n}\r\n\r\nconst UserContext = createContext(undefined);\r\n\r\nconst UserProvider: React.FC<{ value?: Partial }> = ({\r\n value,\r\n ...rest\r\n}) => {\r\n const { data: user } = useAuth();\r\n return ;\r\n};\r\n\r\nfunction useUser() {\r\n const context = useContext(UserContext);\r\n if (context === undefined) {\r\n throw new Error(`useUser must be used within a UserProvider`);\r\n }\r\n return context;\r\n}\r\n\r\nexport { UserProvider, useUser };\r\n","export { UserProvider, useUser } from './user-context';\r\n","interface IResponseError {\r\n error: string;\r\n error_description: string;\r\n}\r\n\r\nfunction instanceOfResponseError(object: any): object is IResponseError {\r\n return 'error' in object && 'error_description' in object;\r\n}\r\n\r\nconst api = async (endpoint: string, { ...rest }) =>\r\n new Promise((resolve, reject) => {\r\n const token =\r\n process.env.REACT_APP_TOKEN &&\r\n window.localStorage.getItem(process.env.REACT_APP_TOKEN);\r\n const headers: { [key: string]: string } = {\r\n 'content-type': 'application/json'\r\n };\r\n\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n\r\n const config: { [key: string]: string } = {\r\n ...rest,\r\n headers: {\r\n ...headers,\r\n ...rest.headers\r\n }\r\n };\r\n\r\n fetch(`${process.env.REACT_APP_API_URL}/${endpoint}`, config)\r\n .then(async response => {\r\n if (!response.ok) throw response;\r\n return resolve(await response.json());\r\n })\r\n .catch(async (response: Error | Response | string) => {\r\n if (response instanceof Error) return reject(response);\r\n if (!(response instanceof Response)) return reject(new Error(response));\r\n\r\n // Special handling if Unauthorized\r\n if (response.status === 401) {\r\n return reject({ message: String(response.status) } as Error);\r\n }\r\n\r\n const body: Response | IResponseError = await response.json();\r\n if (instanceOfResponseError(body)) {\r\n return reject(new Error(body.error_description));\r\n }\r\n\r\n return reject(body);\r\n });\r\n });\r\n\r\nexport async function get(endpoint: string, { ...rest }): Promise {\r\n const config: { [key: string]: string } = { method: 'GET', ...rest };\r\n return api(endpoint, config);\r\n}\r\n\r\nexport async function post(\r\n endpoint: string,\r\n { ...rest }\r\n): Promise {\r\n const config: { [key: string]: string } = { method: 'POST', ...rest };\r\n\r\n if (config.body && typeof config.body !== 'string') {\r\n config.body = JSON.stringify(config.body);\r\n }\r\n\r\n return api(endpoint, config);\r\n}\r\n","import { Loading } from '@components/loading';\r\nimport { useUser } from '@components/user';\r\nimport React from 'react';\r\n\r\nconst loadAuthenticatedApp = () =>\r\n import('./authenticated-app').then(module => ({\r\n default: module.AuthenticatedApp\r\n }));\r\nconst AuthenticatedApp = React.lazy(loadAuthenticatedApp);\r\n\r\nconst UnauthenticatedApp = React.lazy(() =>\r\n import('./unauthenticated-app').then(module => ({\r\n default: module.UnauthenticatedApp\r\n }))\r\n);\r\n\r\nexport function App() {\r\n const { user } = useUser();\r\n // pre-load the authenticated side in the background while the user's\r\n // filling out the login form.\r\n React.useEffect(() => {\r\n loadAuthenticatedApp();\r\n }, []);\r\n return (\r\n }\r\n >\r\n {user ? : }\r\n \r\n );\r\n}\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\ntype Config = {\r\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\r\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\r\n};\r\n\r\nexport function register(config?: Config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(\r\n (process as { env: { [key: string]: string } }).env.PUBLIC_URL,\r\n window.location.href\r\n );\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: string, config?: Config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import { createMuiTheme } from '@material-ui/core/styles';\r\nimport {\r\n Theme as MuiTheme,\r\n ThemeOptions\r\n} from '@material-ui/core/styles/createMuiTheme';\r\nimport {\r\n StylesProvider,\r\n ThemeProvider as MuiThemeProvider\r\n} from '@material-ui/styles';\r\nimport React from 'react';\r\nimport { ThemeProvider as StyledComponentsThemeProvider } from 'styled-components';\r\n\r\nconst defaults: ThemeOptions = {\r\n palette: {\r\n primary: {\r\n main: '#0076bf'\r\n },\r\n secondary: {\r\n main: '#004a88'\r\n }\r\n },\r\n typography: {\r\n fontFamily: [\r\n '-apple-system',\r\n 'BlinkMacSystemFont',\r\n '\"Segoe UI\"',\r\n 'Roboto',\r\n '\"Helvetica Neue\"',\r\n 'Arial',\r\n 'sans-serif',\r\n '\"Apple Color Emoji\"',\r\n '\"Segoe UI Emoji\"',\r\n '\"Segoe UI Symbol\"'\r\n ].join(',')\r\n },\r\n overrides: {\r\n MuiFormControlLabel: {\r\n label: { width: '100%' }\r\n },\r\n MuiLinearProgress: {\r\n colorPrimary: { backgroundColor: 'rgba(158, 202, 230, 0.3)' } // TODO: Get value from theme?\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Use custom Material UI theme in both Styled components and Material UI.\r\n */\r\nexport const Theme: React.FC = ({ children, ...rest }) => {\r\n const theme = createMuiTheme({ ...defaults, ...rest });\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n \r\n );\r\n};\r\n\r\n/**\r\n * Enables Material UI theme intellisense.\r\n */\r\ndeclare module 'styled-components' {\r\n export interface DefaultTheme extends MuiTheme {}\r\n}\r\n","import 'react-app-polyfill/ie11';\r\nimport 'react-app-polyfill/stable';\r\nimport { App, AppProviders } from '@components/app';\r\nimport { CssBaseline } from '@material-ui/core';\r\nimport React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport { createGlobalStyle } from 'styled-components';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport { Theme } from './utils/theme';\r\n\r\nconst GlobalStyle = createGlobalStyle`\r\n #root { height: 100vh; }\r\n`;\r\n\r\nReactDOM.render(\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.register();\r\n","import { AuthProvider } from '@components/auth';\r\nimport { UserProvider } from '@components/user';\r\nimport React from 'react';\r\n\r\nexport const AppProviders: React.FC = ({ children }) => {\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n","import { IUser } from '@components/user/IUser';\r\n\r\nfunction getUserKey() {\r\n try {\r\n const key = process.env.REACT_APP_USER_KEY;\r\n if (!key) throw Error(`Must set user key variable in .env`);\r\n return key;\r\n } catch (error) {\r\n console.error(error);\r\n }\r\n return '';\r\n}\r\n\r\nfunction setUser(user: IUser) {\r\n window.localStorage.setItem(getUserKey(), user.name);\r\n}\r\n\r\nfunction getUser() {\r\n return window.localStorage.getItem(getUserKey());\r\n}\r\n\r\nexport async function requestSaveUser(user: IUser) {\r\n try {\r\n setUser(user);\r\n return Promise.resolve();\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n}\r\n\r\nexport async function requestUser(): Promise {\r\n try {\r\n const username = getUser();\r\n if (!username) throw new Error();\r\n return Promise.resolve({ name: username });\r\n } catch (error) {\r\n return Promise.reject();\r\n }\r\n}\r\n\r\nexport async function requestLogout() {\r\n window.localStorage.removeItem(getUserKey());\r\n return Promise.resolve();\r\n}\r\n","import { IUser } from '@components/user/IUser';\r\nimport {\r\n requestLogout as userRequestLogout,\r\n requestSaveUser,\r\n requestUser as userRequestUser\r\n} from '@components/user/user-service';\r\nimport { post } from '@utils/api-client';\r\n\r\nexport interface ILoginRequest {\r\n username: string;\r\n password: string;\r\n}\r\n\r\nexport interface ILoginResponse {\r\n access_token: string;\r\n expires_in: number;\r\n token_type: string;\r\n}\r\n\r\nfunction getTokenKey() {\r\n try {\r\n const key = process.env.REACT_APP_TOKEN;\r\n if (!key) throw Error(`Must set token variable in .env`);\r\n return key;\r\n } catch (error) {\r\n console.error(error);\r\n }\r\n return '';\r\n}\r\n\r\nfunction getToken() {\r\n return window.localStorage.getItem(getTokenKey());\r\n}\r\n\r\nfunction setToken({ access_token }: ILoginResponse) {\r\n window.localStorage.setItem(getTokenKey(), access_token);\r\n}\r\n\r\nexport async function requestUser(): Promise {\r\n const token = getToken();\r\n if (!token) {\r\n return Promise.resolve(undefined);\r\n }\r\n try {\r\n const user = userRequestUser();\r\n return Promise.resolve(user);\r\n } catch (error) {\r\n requestLogout();\r\n return Promise.reject(error);\r\n }\r\n}\r\n\r\nexport async function requestLogin({ username, password }: ILoginRequest) {\r\n const config = {\r\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\r\n };\r\n const body = `grant_type=password&username=${username}&password=${password}`;\r\n\r\n await post('token', { body, ...config }).then(response =>\r\n setToken(response)\r\n );\r\n requestSaveUser({ name: username });\r\n}\r\n\r\nexport function requestLogout() {\r\n window.localStorage.removeItem(getTokenKey());\r\n userRequestLogout();\r\n return Promise.resolve();\r\n}\r\n","import { Loading } from '@components/loading';\r\nimport { IUser } from '@components/user/IUser';\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useLayoutEffect,\r\n useState\r\n} from 'react';\r\nimport { useAsync } from 'react-async';\r\nimport {\r\n ILoginRequest,\r\n requestLogin,\r\n requestLogout,\r\n requestUser\r\n} from './auth-service';\r\n\r\nexport interface IAuthContextProps {\r\n data: IUser | undefined;\r\n loading: boolean;\r\n error: Error | undefined;\r\n login: (data: ILoginRequest) => void;\r\n logout: () => Promise;\r\n}\r\n\r\nconst AuthContext = createContext(undefined);\r\n\r\nasync function bootstrapAppData() {\r\n const user = await requestUser();\r\n return user;\r\n}\r\n\r\nconst AuthProvider: React.FC<{ value?: Partial }> = ({\r\n value,\r\n ...rest\r\n}) => {\r\n const [loading, setLoading] = useState(false);\r\n const [firstAttemptFinished, setFirstAttemptFinished] = useState(false);\r\n\r\n const { data, isPending, isSettled, error, setError, reload } = useAsync({\r\n promiseFn: bootstrapAppData\r\n });\r\n\r\n useLayoutEffect(() => {\r\n if (isSettled) {\r\n setFirstAttemptFinished(true);\r\n }\r\n }, [isSettled]);\r\n\r\n if (!firstAttemptFinished) {\r\n if (isPending) {\r\n return ;\r\n }\r\n }\r\n\r\n function handleLogin(data: ILoginRequest) {\r\n setLoading(true);\r\n requestLogin(data)\r\n .then(reload)\r\n .catch((response: Error) => setError(response))\r\n .finally(() => setLoading(false));\r\n }\r\n\r\n const login = (data: ILoginRequest) => handleLogin(data);\r\n const logout = () => requestLogout().then(reload);\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nfunction useAuth() {\r\n const context = useContext(AuthContext);\r\n if (context === undefined) {\r\n throw new Error(`useAuth must be used within a AuthProvider`);\r\n }\r\n return context;\r\n}\r\n\r\nexport { AuthProvider, useAuth };\r\n","export { AuthProvider, useAuth } from './auth-context';\r\n"],"sourceRoot":""}