{"version":3,"sources":["features/localStorage/constants.ts","features/auth/AuthContext.tsx","features/localStorage/useLocalStorage.ts","app/PublicRoute.tsx","app/AppRouter.tsx","app/App.tsx","serviceWorker.ts","index.tsx","constants/routes.ts"],"names":["LOCAL_STORAGE_EVENT","AuthContext","createContext","undefined","AuthProvider","children","auth","useProvideAuth","Provider","value","key","initialValue","readValue","useCallback","window","item","localStorage","getItem","JSON","parse","error","useState","storedValue","setStoredValue","useEffect","handleStorageChange","addEventListener","removeEventListener","newValue","Function","setItem","stringify","removeItem","dispatchEvent","Event","useLocalStorage","isAuthenticated","PublicRoute","strict","rest","context","useContext","Error","useAuth","state","useLocation","render","location","to","pathname","from","ROOT_ROUTE","LandingPage","lazy","CreatorLandingPage","AppRouter","fallback","path","CREATOR_ROUTE","queryClient","QueryClient","App","client","Boolean","hostname","match","ReactDOM","StrictMode","document","getElementById","navigator","serviceWorker","ready","then","registration","unregister","catch","console","message"],"mappings":"kLAaaA,EAAsB,gB,OCL7BC,EAAcC,6BAA4CC,GAMnDC,EAAmB,SAAC,GAAkB,IAAhBC,EAAe,EAAfA,SAC3BC,EAAOC,IAEb,OAAO,cAACN,EAAYO,SAAb,CAAsBC,MAAOH,EAA7B,SAAoCD,KAevCE,EAAiB,WACrB,MC5B6B,SAC7BG,EACAC,GAIA,IAAMC,EAAYC,uBAAY,WAE5B,GAAsB,qBAAXC,OACT,OAAOH,EAET,IACE,IAAMI,EAAOD,OAAOE,aAAaC,QAAQP,GACzC,OAAOK,EAAOG,KAAKC,MAAMJ,GAAQJ,EACjC,MAAOS,GACP,OAAOT,KAER,CAACA,EAAcD,IAGlB,EAAsCW,mBAAST,GAA/C,mBAAOU,EAAP,KAAoBC,EAApB,KAuCA,OAhBAC,qBAAU,WACRD,EAAeX,OACd,CAACA,IACJY,qBAAU,WACR,IAAMC,EAAsB,WAC1BF,EAAeX,MAMjB,OAHAE,OAAOY,iBAAiB,UAAWD,GAEnCX,OAAOY,iBAAiB1B,EAAqByB,GACtC,WACLX,OAAOa,oBAAoB,UAAWF,GACtCX,OAAOa,oBAAoB3B,EAAqByB,MAEjD,CAACb,IACG,CAACU,EApCS,SAACb,GAChB,IAEE,IAAMmB,EAAWnB,aAAiBoB,SAAWpB,EAAMa,GAAeb,EAE7DA,EAIHK,OAAOE,aAAac,QAAQpB,EAAKQ,KAAKa,UAAUH,IAHhDd,OAAOE,aAAagB,WAAWtB,GAMjCa,EAAeK,GAEfd,OAAOmB,cAAc,IAAIC,MAAMlC,IAE/B,aDXsBmC,CD1BC,gBC6B3B,MAAO,CACLC,gBAJF,sB,yDEjBWC,EAAc,SAAC,GAIU,IAHpChC,EAGmC,EAHnCA,SAGmC,IAFnCiC,cAEmC,SADhCC,EACgC,iBAC3BH,EFEa,WACrB,IAAMI,EAAUC,qBAAWxC,GAC3B,IAAKuC,EACH,MAAM,IAAIE,MAAJ,wDAER,OAAOF,EEPqBG,GAApBP,gBAEAQ,EAAUC,cAAVD,MAER,OACE,cAAC,IAAD,2BACML,GADN,IAEEO,OAAQ,oBAAGC,EAAH,EAAGA,SAAH,OACJX,GAAmBE,EACnB,cAAC,IAAD,CACEU,GAAI,CACFC,SAAQ,iBAAEL,QAAF,IAAEA,GAAF,UAAEA,EAAOM,YAAT,aAAE,EAAaD,gBAAf,QAA2BE,IACnCP,MAAO,CAAEM,KAAMH,MAInB1C,OC9BJ+C,EAAcC,gBAAK,kBAAM,kCACzBC,EAAqBD,gBAAK,kBAAM,8DAEzBE,EAAY,WACvB,OACE,cAAC,WAAD,CAAUC,SAAU,6CAApB,SACE,eAAC,IAAD,WACE,cAAC,EAAD,CAAaC,KAAMC,IAAepB,QAAQ,EAA1C,SACE,cAACgB,EAAD,MAEF,cAAC,EAAD,CAAaG,KAAMN,IAAYb,QAAQ,EAAvC,SACE,cAACc,EAAD,MAEF,cAAC,IAAD,CAAOK,KAAK,IAAZ,SACE,8CCbJE,EAAc,IAAIC,cAEXC,EAAM,kBACjB,cAAC,sBAAD,CAAqBC,OAAQH,EAA7B,SACE,cAAC,gBAAD,UACE,cAAC,IAAD,UACE,cAAC,EAAD,UACE,cAAC,EAAD,aCHUI,QACW,cAA7BjD,OAAOiC,SAASiB,UAEe,UAA7BlD,OAAOiC,SAASiB,UAEhBlD,OAAOiC,SAASiB,SAASC,MACvB,2DCZNC,IAASpB,OACP,cAAC,IAAMqB,WAAP,UACE,cAAC,EAAD,MAEFC,SAASC,eAAe,SD8HpB,kBAAmBC,WACrBA,UAAUC,cAAcC,MACrBC,MAAK,SAACC,GACLA,EAAaC,gBAEdC,OAAM,SAACxD,GACNyD,QAAQzD,MAAMA,EAAM0D,a,gCE9I5B,oEAAO,IAAM3B,EAAa,IAEbO,EAAgB,a","file":"static/js/main.4a262f2a.chunk.js","sourcesContent":["/**\n * Constants relating to localStorage.\n */\n\n/**\n * Key to store whether the admin is logged in in localStorage.\n */\nexport const LOGGED_IN_KEY = 'is-logged-in'\n\n/**\n * Event name to be used when emitting event to indicate that localStorage has\n * been modified.\n */\nexport const LOCAL_STORAGE_EVENT = 'local-storage'\n","import { createContext, FC, useContext } from 'react'\n\nimport { LOGGED_IN_KEY, useLocalStorage } from '~features/localStorage'\n\ntype AuthContextProps = {\n isAuthenticated?: boolean\n}\n\nconst AuthContext = createContext(undefined)\n\n/**\n * Provider component that wraps your app and makes auth object available to any\n * child component that calls `useAuth()`.\n */\nexport const AuthProvider: FC = ({ children }) => {\n const auth = useProvideAuth()\n\n return {children}\n}\n\n/**\n * Hook for components nested in ProvideAuth component to get the current auth object.\n */\nexport const useAuth = (): AuthContextProps => {\n const context = useContext(AuthContext)\n if (!context) {\n throw new Error(`useAuth must be used within a AuthProvider component`)\n }\n return context\n}\n\n// Provider hook that creates auth object and handles state\nconst useProvideAuth = () => {\n const [isAuthenticated] = useLocalStorage(LOGGED_IN_KEY)\n\n // Return the user object and auth methods\n return {\n isAuthenticated,\n }\n}\n","// Retrieved from https://usehooks-typescript.com/react-hook/use-local-storage\nimport { useCallback, useEffect, useState } from 'react'\n\nimport { LOCAL_STORAGE_EVENT } from './constants'\n\nexport const useLocalStorage = (\n key: string,\n initialValue?: T,\n): readonly [T | undefined, (value?: T) => void] => {\n // Get from local storage then\n // parse stored json or return initialValue\n const readValue = useCallback(() => {\n // Prevent build error \"window is undefined\" but keep keep working\n if (typeof window === 'undefined') {\n return initialValue\n }\n try {\n const item = window.localStorage.getItem(key)\n return item ? JSON.parse(item) : initialValue\n } catch (error) {\n return initialValue\n }\n }, [initialValue, key])\n // State to store our value\n // Pass initial state function to useState so logic is only executed once\n const [storedValue, setStoredValue] = useState(readValue)\n // Return a wrapped version of useState's setter function that ...\n // ... persists the new value to localStorage.\n const setValue = (value?: T) => {\n try {\n // Allow value to be a function so we have the same API as useState\n const newValue = value instanceof Function ? value(storedValue) : value\n\n if (!value) {\n window.localStorage.removeItem(key)\n } else {\n // Save to local storage\n window.localStorage.setItem(key, JSON.stringify(newValue))\n // Save state\n }\n setStoredValue(newValue)\n // We dispatch a custom event so every useLocalStorage hook are notified\n window.dispatchEvent(new Event(LOCAL_STORAGE_EVENT))\n // eslint-disable-next-line no-empty\n } catch {\n // TODO (#2640) Pass in some sort of logger here.\n }\n }\n useEffect(() => {\n setStoredValue(readValue())\n }, [readValue])\n useEffect(() => {\n const handleStorageChange = () => {\n setStoredValue(readValue())\n }\n // this only works for other documents, not the current one\n window.addEventListener('storage', handleStorageChange)\n // this is a custom event, triggered in writeValueToLocalStorage\n window.addEventListener(LOCAL_STORAGE_EVENT, handleStorageChange)\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n window.removeEventListener(LOCAL_STORAGE_EVENT, handleStorageChange)\n }\n }, [readValue])\n return [storedValue, setValue] as const\n}\n","import { Redirect, Route, RouteProps, useLocation } from 'react-router-dom'\nimport { Location } from 'history'\n\nimport { ROOT_ROUTE } from '~constants/routes'\n\nimport { useAuth } from '~features/auth'\n\nexport interface PublicRouteProps extends Omit {\n // If `strict` is true, only non-authed users can access the route.\n // i.e. signin page, where authed users accessing that page should be\n // redirected out.\n // If `strict` is false, then both authed and non-authed users can access\n // the route.\n strict?: boolean\n}\n\nexport const PublicRoute = ({\n children,\n strict = true,\n ...rest\n}: PublicRouteProps): JSX.Element => {\n const { isAuthenticated } = useAuth()\n\n const { state } = useLocation<{ from: Location | undefined }>()\n\n return (\n \n !!isAuthenticated && strict ? (\n \n ) : (\n children\n )\n }\n />\n )\n}\n","import { lazy, Suspense } from 'react'\nimport { Route, Switch } from 'react-router-dom'\n\nimport { CREATOR_ROUTE, ROOT_ROUTE } from '~constants/routes'\n\nimport { PublicRoute } from './PublicRoute'\n\nconst LandingPage = lazy(() => import('~pages/LandingPage'))\nconst CreatorLandingPage = lazy(() => import('~pages/CreatorLandingPage'))\n\nexport const AppRouter = (): JSX.Element => {\n return (\n Loading...}>\n \n \n \n \n \n \n \n \n
404
\n
\n
\n
\n )\n}\n","import { QueryClient, QueryClientProvider } from 'react-query'\nimport { BrowserRouter } from 'react-router-dom'\nimport { ThemeProvider } from '@opengovsg/design-system-react'\n\nimport { AuthProvider } from '~features/auth'\n\nimport { AppRouter } from './AppRouter'\n\nconst queryClient = new QueryClient()\n\nexport const App = (): JSX.Element => (\n \n \n \n \n \n \n \n \n \n)\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,\n ),\n)\n\ntype Config = {\n onSuccess?: (_registration: ServiceWorkerRegistration) => void\n onUpdate?: (_registration: ServiceWorkerRegistration) => void\n}\n\nexport function register(config?: Config): void {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config)\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA',\n )\n })\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config)\n }\n })\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then((registration) => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing\n if (installingWorker == null) {\n return\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.',\n )\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration)\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.')\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration)\n }\n }\n }\n }\n }\n })\n .catch((error) => {\n console.error('Error during service worker registration:', error)\n })\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then((response) => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type')\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then((registration) => {\n registration.unregister().then(() => {\n window.location.reload()\n })\n })\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config)\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.',\n )\n })\n}\n\nexport function unregister(): void {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then((registration) => {\n registration.unregister()\n })\n .catch((error) => {\n console.error(error.message)\n })\n }\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport App from './app'\nimport * as serviceWorker from './serviceWorker'\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root'),\n)\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister()\n","export const ROOT_ROUTE = '/'\nexport const LOGIN_ROUTE = '/login'\nexport const CREATOR_ROUTE = '/creator'\n"],"sourceRoot":""}