{"version":3,"sources":["constants/taxonomy.ts","hooks/usePrevious.ts","constants/resultsPerPage.ts","utils/searchParamsToObject.ts","atoms/searchResultState.ts","components/GlobalStyles.tsx","constants/index.ts","hooks/useDFPSlot.ts","components/StyledLoader.tsx","App.tsx","constants/text.ts","atoms/userState.ts","reportWebVitals.ts","index.tsx"],"names":["SUBJECT_CATEGORIES","QUAL_GROUP","PG_ATTENDANCE","FIELD_TITLES","QUALIFICATION","ATTENDANCE","SUBJECTS","NO_COURSES_FOUND","usePrevious","value","ref","useRef","useEffect","current","RESULTS_PER_PAGE","searchParamsToObject","params","JSON","parse","replace","key","decodeURIComponent","searchResultState","atom","default","totalNumberOfResults","GlobalStyles","_ref","styles","_jsx","Global","css","_templateObject","_taggedTemplateLiteral","MPU_ID_PREFIX","useDfpSlot","keyword","keyValues","_useState","useState","_useState2","_slicedToArray","stateKeyword","setStateKeyword","_useState3","_useState4","stateKeyValues","setStateKeyValues","useLayoutEffect","googletag","window","cmd","slots","push","pubads","getTargeting","length","clearTargeting","collapseEmptyDivs","_loop","i","slot","getSlots","find","adSlot","getSlotElementId","concat","defineSlot","setCollapseEmptyDiv","setTargeting","addService","enableSingleRequest","enableServices","display","R","refresh","StyledLoader","styled","Loader","Form","lazy","Results","queryClient","QueryClient","API_BASE_URL","qualificationEndPoint","attendanceEndPoint","selectedFiltersEndPoint","toggleSavedEndPoint","profileEndPoint","getTopLevelSubjectTnrsEndpoint","selectedCourseSessionStorageKey","getPagingSize","pageNo","arguments","undefined","shapeData","data","controls","checked","name","camelcase","id","label","_toConsumableArray","map","text","tnr","kebabCase","toLowerCase","toUpperCase","slice","renameKeysWith","createTitle","shapeDataObject","attendanceModes","_ref2","_asyncToGenerator","_regeneratorRuntime","mark","_callee","wrap","_context","prev","next","fetch","sent","json","abrupt","stop","apply","qualifications","_ref3","_callee2","_context2","fetchCheckboxFiltersData","_ref4","_callee3","rawData","mergedData","_context3","Promise","all","forEach","item","Object","keys","values","fetchRelatedItems","_ref5","_callee4","combinedFilterTnrs","setRelatedItems","results","_context4","then","res","_x","_x2","SelectedFiltersStatus","CourseSearchEvents","App","useQueryClient","bus","useBus","queryParam","useLocation","search","useParams","_useAsyncResource","useAsyncResource","filtersReader","setCombinedFilterTnrs","subjectTnr","setSubjectTnr","_useState5","_useState6","topLevelSubjectTnrs","setTopLevelSubjectTnrs","_useState7","attendance","qualification","location","institution","subject","featuredCourses","size","_useState8","selectedFilters","setSelectedFilters","_useState9","IDLE","_useState10","selectedFiltersStatus","setSelectedFiltersStatus","_useState11","_useState12","selectedSubjectText","setSelectedSubjectText","setSearch","useCallback","isSearch","hasFilters","_useState13","_useState14","subjectParam","setSubjectParam","setUserLoggedInState","useSetRecoilState","userLoggedInState","_useState15","_useState16","title","setTitle","_useState17","_useState18","relatedItems","_useState19","_useState20","showResults","setShowResults","_useState21","page","searchParams","_useState22","searchParamData","setSearchParamData","useRecoilValue","resetSearchResultState","useResetRecoilState","isFirstRun","refetchRelatedItems","allSearch","prevCombinedFilterTnrs","prevSelectedSubjectTnr","prevSelectedFilters","prevSearch","prevSubjectParam","selectedFiltersFeaturedCourses","split","no","parseInt","doSearch","useListener","SEARCH_SUBMITTED","sessionStorage","getItem","scrollTo","fetchUserLoggedInState","_ref6","_callee5","response","_context5","axios","get","withCredentials","status","error","Error","useDeepCompareEffect","query","substring","queryParams","extraParam","paramsValues","fetchSelectedFilters","_ref7","_callee6","_yield$axios$get","pageFromUrl","_context6","LOADING","includes","join","SUCCESS","_objectSpread","toString","t0","ERROR","console","clear","emit","SEARCH_CLEARED","_selectedFilters$qual","_selectedFilters$atte","_selectedFilters$loca","_selectedFilters$inst","_selectedFilters$subj","tnrProp","qualificationTnrs","attendanceModeTnrs","locationTnrs","institutionTnrs","filter","Boolean","fetchTopLevelSubjectTnrs","_ref8","_callee7","_context7","_x3","prevFilterTnrsEqCurrent","prevSelectedFiltersEqCurrent","noFilters","tempTitle","subjectUsed","getTitle","_jsxs","_Fragment","children","Helmet","content","Well","ErrorBoundary","fallback","Suspense","loading","searchParam","filters","searchData","RelatedItems","ReactQueryDevtools","initialIsOpen","AppConnected","ThemeProvider","theme","HelmetProvider","RecoilRoot","QueryClientProvider","client","BusProvider","Route","path","exact","reportWebVitals","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","React","StrictMode","Router","document","getElementById"],"mappings":"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","file":"static/js/main.c2fa7f56.chunk.js","sourcesContent":["export const SUBJECT_CATEGORIES = {\n QUAL_GROUP: 'QUAL_GROUP',\n PG_ATTENDANCE: 'PG_ATTENDANCE',\n};\n\nexport type SUBJECT_CATEGORIES_TYPE = keyof typeof SUBJECT_CATEGORIES;\nexport const FIELD_TITLES = {\n QUALIFICATION: 'Qualification',\n ATTENDANCE: 'Attendance',\n SUBJECTS: 'Subjects',\n} as const;\n\nexport const NO_COURSES_FOUND = 'No courses found';\n","import { useRef, useEffect } from 'react';\n\nexport const usePrevious = (value: T): T | undefined => {\n const ref = useRef();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n};\n","export const RESULTS_PER_PAGE: number = 20;\n","export const searchParamsToObject = (\n params: string\n): Record => {\n if (!params) {\n return {};\n }\n return JSON.parse(\n '{\"' + params.replace(/&/g, '\",\"').replace(/=/g, '\":\"') + '\"}',\n function(key, value) {\n return key === '' ? value : decodeURIComponent(value);\n }\n );\n};\n","import { atom } from 'recoil';\n\nexport interface SearchResultState {\n totalNumberOfResults: null | number;\n}\n\nexport const searchResultState = atom({\n key: 'searchResultState',\n default: {\n totalNumberOfResults: null,\n },\n});\n","import React from 'react';\nimport { Global, css } from '@emotion/react';\n\nexport interface GlobalStylesProps {\n styles?: string;\n}\n\nconst GlobalStyles: React.FC = ({ styles }) => (\n \n);\n\nexport default GlobalStyles;\n","export const MPU_ID_PREFIX = 'advert-course-search';\n","import {useLayoutEffect, useState} from 'react';\nimport * as R from 'ramda';\nimport { MPU_ID_PREFIX } from '../constants';\n\nconst useDfpSlot = (keyword: string, keyValues: number[]) => {\n // creating these state variables to keep track of previous keyword and keyvalues\n const [stateKeyword, setStateKeyword] = useState(keyword);\n const [stateKeyValues, setStateKeyValues] = useState(keyValues);\n\n useLayoutEffect(() => {\n const googletag = window.googletag || { cmd: [] };\n let slots: Array = [];\n const adsToAdd = 2;\n googletag.cmd.push(() => {\n if (googletag.pubads().getTargeting('Keyword').length) {\n googletag.pubads().clearTargeting('Keyword');\n }\n if (googletag.pubads().getTargeting('KeyValues').length) {\n googletag.pubads().clearTargeting('KeyValues');\n }\n\n googletag.pubads().collapseEmptyDivs();\n for (let i = 1; i <= adsToAdd; i++) {\n /* check if the slot is already present and assign it to the slot variable instead of defining slots everytime\n Defining slots everytime was causing this error https://developers.google.com/publisher-tag/guides/publisher-console-messages?utm_source=devconsole&utm_medium=console&utm_campaign=details#28\n and it was preventing the code from setting targets for the slot like we expect.\n */\n let slot = googletag.pubads().getSlots().find((adSlot: any) => adSlot.getSlotElementId() === `${MPU_ID_PREFIX}-` + i);\n if(!slot) {\n slot = googletag.defineSlot(\n '/141389100/MPUContent',\n [300, 250],\n `${MPU_ID_PREFIX}-` + i\n );\n }\n if (slot) {\n slot.setCollapseEmptyDiv(true);\n slots.push(slot);\n if (keyword)\n slot.setTargeting('Keyword', keyword);\n if (keyValues.length)\n slot.setTargeting('KeyValues', keyValues);\n slot.addService(googletag.pubads());\n\n }\n }\n googletag.pubads().enableSingleRequest();\n googletag.enableServices();\n\n for (let i = 1; i <= adsToAdd; i++) {\n googletag.display(`${MPU_ID_PREFIX}-` + i);\n }\n /*\n refresh() method is necessary to populate the slots with new ad content\n https://developers.google.com/publisher-tag/guides/control-ad-loading#refresh\n And also adding the condition to check when the keyword or keyvalue actually changes, to make sure we do not refresh the ad slots frequently\n */\n if(stateKeyword != keyword || !R.equals(stateKeyValues,keyValues)) {\n googletag.pubads().refresh();\n setStateKeyword(keyword);\n setStateKeyValues(keyValues);\n }\n });\n }, [keyword, keyValues]);\n};\n\nexport default useDfpSlot;\n","import styled from '@emotion/styled';\nimport { Loader } from '@prospects/cl-core';\n\nconst StyledLoader = styled(Loader)`\n padding-top: 36px;\n`;\n\nexport default StyledLoader;\n","//@ts-nocheck\nimport React, {FC, lazy, Suspense, useCallback, useEffect, useRef, useState} from 'react';\nimport { Route } from 'react-router-dom';\nimport { RecoilRoot, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil';\nimport { Provider as BusProvider, useBus, useListener } from 'react-bus';\nimport { RelatedItems, Well } from '@prospects/cl-prospects';\nimport { theme, ThemeProvider } from '@prospects/cl-core';\nimport axios from 'axios';\nimport camelcase from 'camelcase';\nimport { useLocation, useParams } from 'react-router';\nimport kebabCase from '@queso/kebab-case';\nimport * as R from 'ramda';\nimport { renameKeysWith } from 'ramda-adjunct';\nimport useDeepCompareEffect from 'use-deep-compare-effect';\nimport { FilterGroupProps, FilterGroupTitles, SelectedFilters } from '@prospects/cl-prospects/lib/hooks/useCourseSearchForm';\nimport { FIELD_TITLES, SUBJECT_CATEGORIES, SUBJECT_CATEGORIES_TYPE } from './constants/taxonomy';\nimport GlobalStyles from './components/GlobalStyles';\nimport { usePrevious } from './hooks/usePrevious';\nimport { searchParamsToObject } from './utils/searchParamsToObject';\nimport { userLoggedInState } from './atoms/userState';\nimport { WELL_TITLE } from './constants/text';\nimport useDfpSlot from './hooks/useDFPSlot';\nimport { useAsyncResource } from 'use-async-resource';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport StyledLoader from './components/StyledLoader';\nimport { RESULTS_PER_PAGE } from './constants/resultsPerPage';\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\nimport { QueryClient, QueryClientProvider, useQueryClient } from 'react-query';\n\nimport { ReactQueryDevtools } from 'react-query/devtools';\nimport { searchResultState } from './atoms/searchResultState';\n\ndeclare global {\n interface Window {\n dataLayer: any;\n __page: string;\n googletag: any;\n }\n}\n\nconst Form = lazy(() => import('./components/Form'));\nconst Results = lazy(() => import('./components/Results'));\n\nconst queryClient = new QueryClient();\n\ninterface DataShape {\n text: string;\n tnr: number;\n count: number;\n}\n\nexport const API_BASE_URL =\n process.env.NODE_ENV === 'development' ? process.env.REACT_APP_API_URL : '';\n\nconst qualificationEndPoint = `${API_BASE_URL}/api/taxonomy/categories?subject_categories=${SUBJECT_CATEGORIES.QUAL_GROUP}&subject_categories_groups=`;\nconst attendanceEndPoint = `${API_BASE_URL}/api/taxonomy/categories?subject_categories=${SUBJECT_CATEGORIES.PG_ATTENDANCE}&subject_categories_groups=`;\nconst selectedFiltersEndPoint = `${API_BASE_URL}/api/selected-filters`;\nexport const toggleSavedEndPoint = `${API_BASE_URL}/api/toggleSaved/course?itemId=`;\nexport const profileEndPoint = `${API_BASE_URL}/api/profile`;\n\nexport const getTopLevelSubjectTnrsEndpoint = `${API_BASE_URL}/api/taxonomy/get_toplevel_subject_tnrs/`;\nexport const selectedCourseSessionStorageKey = 'selectedCourse';\n\nexport const getPagingSize = (pageNo: number = 0): number => {\n if (pageNo === 0) {\n return RESULTS_PER_PAGE;\n }\n\n return pageNo * RESULTS_PER_PAGE;\n};\n\nconst createTitle = (\n key: SUBJECT_CATEGORIES_TYPE,\n): FilterGroupTitles | 'Subjects' => {\n if (key === `${SUBJECT_CATEGORIES.PG_ATTENDANCE}`) {\n return FIELD_TITLES.ATTENDANCE;\n } else if (key === `${SUBJECT_CATEGORIES.QUAL_GROUP}`) {\n return FIELD_TITLES.QUALIFICATION;\n }\n return FIELD_TITLES.SUBJECTS;\n};\n\nconst shapeData = (data: Record): FilterGroupProps => {\n const transformKeys = (key: string) =>\n createTitle(key as SUBJECT_CATEGORIES_TYPE);\n const transformValues = (\n controls: DataShape[],\n key: SUBJECT_CATEGORIES_TYPE,\n ) => [\n {\n value: 'all',\n checked: true,\n name: `${camelcase(key)}[]`,\n id: `${camelcase(key)}All`,\n label: 'All',\n },\n ...controls.map(({ text, tnr }) => ({\n value: text ? kebabCase(text.toLowerCase()) : '',\n checked: false,\n name: `${camelcase(key)}[]`,\n id: `${tnr}`,\n label: text[0].toUpperCase() + text.slice(1),\n })),\n ];\n\n const shapeDataObject = R.compose(\n R.mapObjIndexed(transformValues),\n // @ts-ignore\n renameKeysWith(transformKeys),\n );\n // @ts-ignore\n return shapeDataObject(data);\n};\n\nexport interface TaxonomyTerm {\n tnr: number;\n text: string;\n}\n\ntype ProfileImage = {\n url: string;\n width: number;\n height: number;\n};\n\ninterface Profile {\n displayName: string;\n logo: ProfileImage;\n masthead: ProfileImage;\n slug: string;\n tnrName: string;\n tnrNumber: number;\n}\n\nexport interface Course {\n id: number;\n courseUID: number;\n courseName: string;\n institutionName: TaxonomyTerm;\n departmentName: TaxonomyTerm;\n qualifications: [];\n saved: boolean;\n isFeatured: boolean;\n isNewFunding: boolean;\n institutionSlug: string;\n institutionProfile: null | Profile;\n departmentSlug: string;\n departmentProfile: null | Profile;\n courseSlug: string;\n startsJanuary: boolean;\n online: boolean;\n}\n\nexport interface SearchResult {\n lastPage: boolean;\n totalNumberOfResults: number | null;\n courses: Array;\n featuredCourses: Array;\n nextPage: number;\n}\n\nconst attendanceModes = async () =>\n await (await fetch(attendanceEndPoint)).json();\nconst qualifications = async () =>\n await (await fetch(qualificationEndPoint)).json();\n\nconst fetchCheckboxFiltersData = async () => {\n const rawData = await Promise.all([qualifications(), attendanceModes()]);\n const mergedData: Record = {};\n\n rawData.forEach(\n item => (mergedData[`${Object.keys(item)[0]}`] = Object.values(item)[0]),\n );\n return shapeData(mergedData);\n};\n\nconst fetchRelatedItems = async (\n combinedFilterTnrs: number[],\n setRelatedItems: React.Dispatch>,\n) => {\n const results = await fetch(\n `${API_BASE_URL}/api/relatedItems?relatedItemTypes=COURSE&tnrs=${combinedFilterTnrs}&maxItems=4`,\n ).then(res => res.json());\n setRelatedItems(results);\n};\n\nenum SelectedFiltersStatus {\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n SUCCESS = 'SUCCESS',\n ERROR = 'ERROR',\n}\n\nexport enum CourseSearchEvents {\n SEARCH_CLEARED = 'search:cleared',\n SEARCH_SUBMITTED = 'search:submitted',\n}\n\nexport interface URLParams {\n one: string;\n two: string;\n three: string;\n four: string;\n}\n\nconst App: FC = () => {\n const queryClient = useQueryClient();\n const bus = useBus();\n const { search: queryParam } = useLocation();\n const params = useParams();\n const [filtersReader] = useAsyncResource(fetchCheckboxFiltersData, []);\n const [combinedFilterTnrs, setCombinedFilterTnrs] = useState([]);\n const [subjectTnr, setSubjectTnr] = useState();\n const [topLevelSubjectTnrs, setTopLevelSubjectTnrs] = useState([]);\n const selectedFiltersDefaults = {\n attendance: [],\n qualification: [],\n location: [],\n institution: [],\n subject: [],\n keyword: '',\n featuredCourses: '',\n size: '20',\n all: null,\n };\n const [selectedFilters, setSelectedFilters] = useState<\n SelectedFilters & {\n featuredCourses: string;\n size: string;\n all: boolean | null;\n }\n >(selectedFiltersDefaults);\n const [selectedFiltersStatus, setSelectedFiltersStatus] = useState(\n SelectedFiltersStatus.IDLE,\n );\n const [selectedSubjectText, setSelectedSubjectText] = useState('');\n const search = useRef(false);\n const setSearch = useCallback(\n (isSearch: boolean) => (search.current = isSearch),\n [],\n );\n const hasFilters = useRef(false);\n const setHasFilters = (filters: boolean) => (hasFilters.current = filters);\n const [subjectParam, setSubjectParam] = useState('');\n const setUserLoggedInState = useSetRecoilState(userLoggedInState);\n const [title, setTitle] = useState('');\n const [relatedItems, setRelatedItems] = useState([]);\n const [showResults, setShowResults] = useState(false);\n const [searchParamData, setSearchParamData] = useState<{\n featuredCourses: number[] | null;\n selectedSubjectText: string;\n subjectParam: string;\n page: number;\n size: number;\n searchParams: number[] | null;\n }>({\n page: 0,\n size: 20,\n searchParams: null,\n featuredCourses: null,\n selectedSubjectText: '',\n subjectParam: '',\n });\n const { totalNumberOfResults } = useRecoilValue(searchResultState);\n const resetSearchResultState = useResetRecoilState(searchResultState);\n const isFirstRun = useRef(true);\n const refetchRelatedItems= useRef(true);\n const allSearch = useRef(false);\n const prevCombinedFilterTnrs = usePrevious(combinedFilterTnrs);\n const prevSelectedSubjectTnr = usePrevious(selectedSubjectText);\n const prevSelectedFilters = usePrevious(selectedFilters);\n const prevSearch = usePrevious(search);\n const prevSubjectParam = usePrevious(subjectParam);\n\n const selectedFiltersFeaturedCourses = selectedFilters.featuredCourses\n ? selectedFilters.featuredCourses.split(',').map(no => parseInt(no, 10))\n : null;\n const doSearch = useCallback(\n (\n searchParams: number[],\n page: number = 0,\n isNewSearch: boolean = true,\n featured: boolean = true,\n size: number = RESULTS_PER_PAGE,\n ) => {\n fetchRelatedItems([...combinedFilterTnrs, ...topLevelSubjectTnrs], setRelatedItems);\n setShowResults(true);\n setSearchParamData({\n page,\n size,\n searchParams,\n featuredCourses: selectedFiltersFeaturedCourses,\n selectedSubjectText,\n subjectParam: subjectParam || '',\n });\n },\n [\n selectedSubjectText,\n subjectParam,\n selectedFiltersFeaturedCourses,\n combinedFilterTnrs,\n topLevelSubjectTnrs,\n ],\n );\n\n const handleIsSearch = (searchParam: any) => {\n setSearch(searchParam);\n };\n\n const handleSubjectParam = (subjectParam: any) => {\n setSubjectParam(subjectParam);\n };\n\n const handleSearchSubmitted = () => {\n // setShowResults(false);\n };\n\n useListener(CourseSearchEvents.SEARCH_SUBMITTED, handleSearchSubmitted);\n\n useEffect(() => {\n if (sessionStorage.getItem(selectedCourseSessionStorageKey)) {\n window.scrollTo(0, 0);\n }\n const fetchUserLoggedInState = async () => {\n const response = await axios.get(profileEndPoint, {\n withCredentials: true,\n });\n\n if (response.status === 200 && response.data) {\n setUserLoggedInState(true);\n }\n };\n\n try {\n fetchUserLoggedInState();\n } catch (error) {\n // @ts-ignore\n throw new Error(error);\n }\n }, [setUserLoggedInState]);\n\n useDeepCompareEffect(() => {\n const query = searchParamsToObject(queryParam.substring(1));\n const queryParams = query['extra-criteria'];\n const extraParam = queryParams ? `?extra-criteria=${queryParams}` : '';\n const keyword = searchParamsToObject(queryParam.substring(1)).keyword;\n const paramsValues: string[] = R.values(params);\n\n const fetchSelectedFilters = async () => {\n try {\n setSelectedFiltersStatus(SelectedFiltersStatus.LOADING);\n const { data } = await axios.get<{\n selectedFilters: SelectedFilters;\n }>(\n `${selectedFiltersEndPoint}${\n paramsValues.includes('all')\n ? ''\n : '/' + paramsValues.join('/')\n }${\n extraParam\n ? keyword\n ? `?keyword=${keyword}&extra-criteria=${queryParams}`\n : extraParam\n : keyword\n ? `?keyword=${keyword}`\n : ''\n }`,\n );\n setSelectedFiltersStatus(SelectedFiltersStatus.SUCCESS);\n const pageFromUrl = query.page || '0';\n\n setSelectedFilters({\n ...data.selectedFilters,\n keyword: data.selectedFilters.keyword[0] || '',\n featuredCourses: query.featuredCourses || '',\n size: getPagingSize(parseInt(pageFromUrl) + 1).toString(),\n all: paramsValues.includes('all') || null,\n });\n } catch (error) {\n setSelectedFiltersStatus(SelectedFiltersStatus.ERROR);\n console.error(`fetching selected filters: ${error}`);\n }\n };\n if (R.isEmpty(params) && !queryParam && showResults) {\n // reset search to default state\n queryClient.clear();\n bus.emit(CourseSearchEvents.SEARCH_CLEARED);\n resetSearchResultState();\n setSelectedFilters({\n attendance: [],\n qualification: [],\n location: [],\n institution: [],\n subject: [],\n keyword: '',\n featuredCourses: '',\n size: '20',\n all: null,\n });\n setShowResults(false);\n\n return;\n }\n fetchSelectedFilters();\n }, [params, queryParam]);\n\n useDeepCompareEffect(() => {\n if (selectedFiltersStatus !== SelectedFiltersStatus.SUCCESS) {\n return;\n }\n\n const tnrProp = R.prop('tnr');\n const qualificationTnrs = selectedFilters.qualification?.map(tnrProp);\n const attendanceModeTnrs = selectedFilters.attendance?.map(tnrProp);\n const locationTnrs = selectedFilters.location?.map(tnrProp);\n const institutionTnrs = selectedFilters.institution?.map(tnrProp);\n const keyword =\n selectedFilters.keyword || selectedFilters.subject[0]?.text || '';\n if(selectedFilters.subject[0]) {\n setSubjectTnr(selectedFilters.subject[0].tnr);\n }\n else {\n setTopLevelSubjectTnrs([]);\n }\n\n setCombinedFilterTnrs(\n qualificationTnrs\n .concat(attendanceModeTnrs, locationTnrs, institutionTnrs)\n .filter(Boolean),\n );\n\n setSelectedSubjectText(keyword);\n }, [selectedFilters, selectedFiltersStatus]);\n\n useEffect(() =>{\n const fetchTopLevelSubjectTnrs = async (tnr: number) => {\n const response = await axios.get(getTopLevelSubjectTnrsEndpoint+tnr, {\n withCredentials: true,\n });\n\n if (response.status === 200 && response.data) {\n refetchRelatedItems.current=true;\n setTopLevelSubjectTnrs([...response.data, tnr]);\n }\n };\n if(subjectTnr) {\n fetchTopLevelSubjectTnrs(subjectTnr);\n }\n\n\n },[subjectTnr]);\n\n\n\n\n useEffect(() => {\n\n const paramsValues: string[] = R.values(params);\n if (\n (!paramsValues.length &&\n !paramsValues.includes('all') &&\n !queryParam &&\n isFirstRun.current) ||\n refetchRelatedItems.current\n ) {\n isFirstRun.current = false;\n refetchRelatedItems.current = false;\n fetchRelatedItems([...combinedFilterTnrs, ...topLevelSubjectTnrs], setRelatedItems);\n }\n }, [params, combinedFilterTnrs, topLevelSubjectTnrs, queryParam]);\n\n // Searching done here\n useDeepCompareEffect(() => {\n const prevFilterTnrsEqCurrent = R.equals(\n prevCombinedFilterTnrs,\n combinedFilterTnrs,\n );\n const prevSelectedFiltersEqCurrent = R.equals(\n selectedFilters,\n prevSelectedFilters,\n );\n const size = parseInt(selectedFilters.size, 10);\n\n if (selectedFiltersStatus !== SelectedFiltersStatus.SUCCESS) {\n return;\n }\n if (!search.current && combinedFilterTnrs.length) {\n hasFilters.current = true;\n }\n if (!search.current && !combinedFilterTnrs.length) {\n hasFilters.current = false;\n }\n // This condition is a form search with no filters or params set\n // when submitting the form after it has already been used with\n // filters\n if (\n search.current &&\n !hasFilters.current &&\n !combinedFilterTnrs.length &&\n !selectedSubjectText &&\n !subjectParam &&\n (!prevFilterTnrsEqCurrent ||\n prevSelectedSubjectTnr !== selectedSubjectText) &&\n selectedFilters.all\n ) {\n allSearch.current = true;\n return doSearch([], undefined, undefined, false);\n }\n\n // This condition is a form search with no filters or params set\n // This should only work on initial route when pressing submit\n if (\n search.current &&\n !hasFilters.current &&\n !combinedFilterTnrs.length &&\n !selectedSubjectText &&\n prevFilterTnrsEqCurrent &&\n prevSelectedFiltersEqCurrent &&\n prevSelectedSubjectTnr === selectedSubjectText &&\n !subjectParam &&\n !totalNumberOfResults &&\n !selectedFilters.all\n ) {\n allSearch.current = true;\n return doSearch([], undefined, undefined, false);\n }\n\n // This is a form search with filters\n if (\n search.current &&\n hasFilters.current &&\n (combinedFilterTnrs.length || selectedSubjectText) &&\n (!prevFilterTnrsEqCurrent ||\n prevSelectedSubjectTnr !== selectedSubjectText) &&\n !selectedFilters.all\n ) {\n allSearch.current = false;\n return doSearch(combinedFilterTnrs, undefined, undefined, false);\n }\n\n if (\n prevFilterTnrsEqCurrent &&\n prevSelectedFiltersEqCurrent &&\n search.current === prevSearch?.current &&\n prevSelectedSubjectTnr === selectedSubjectText &&\n prevSubjectParam === subjectParam\n ) {\n return;\n }\n\n // This condition is a search triggered by navigation changes with no form submit\n // that has criteria\n if (\n !search.current &&\n (combinedFilterTnrs.length || selectedSubjectText) &&\n (!prevFilterTnrsEqCurrent ||\n prevSelectedSubjectTnr !== selectedSubjectText)\n ) {\n allSearch.current = false;\n return doSearch(\n combinedFilterTnrs,\n undefined,\n undefined,\n undefined,\n size,\n );\n }\n // This condition is for navigation to a search that has no filters\n if (\n !search.current &&\n !hasFilters.current &&\n !combinedFilterTnrs.length &&\n !selectedSubjectText &&\n selectedFilters.all\n ) {\n if (allSearch.current) {\n return;\n }\n allSearch.current = true;\n return doSearch([], undefined, undefined, undefined, size);\n }\n }, [\n selectedFilters,\n prevSelectedFilters,\n prevSearch,\n combinedFilterTnrs,\n prevCombinedFilterTnrs,\n doSearch,\n prevSelectedSubjectTnr,\n selectedSubjectText,\n subjectParam,\n prevSubjectParam,\n totalNumberOfResults,\n selectedFiltersStatus,\n ]);\n\n // useDeepCompareEffect - construct title dynamically\n useDeepCompareEffect(() => {\n const getTitle = (): string => {\n const noFilters =\n !selectedFilters.attendance.length &&\n !selectedFilters.institution.length &&\n !selectedFilters.location.length &&\n !selectedFilters.qualification.length &&\n !selectedFilters.subject.length;\n let tempTitle: string = '';\n let subjectUsed: boolean = false;\n\n // attendance filter with none or one qualification selected\n if (selectedFilters.attendance.length === 1) {\n if (selectedFilters.qualification.length === 0) {\n tempTitle = `${selectedFilters.attendance[0].text} courses`;\n if (selectedFilters.subject.length === 1) {\n subjectUsed = true;\n tempTitle = `${selectedFilters.attendance[0].text} ${selectedFilters.subject[0].text} courses`;\n }\n } else if (selectedFilters.qualification.length === 1) {\n tempTitle = tempTitle.concat(\n `${selectedFilters.attendance[0].text},`,\n );\n } else {\n tempTitle = '';\n }\n }\n\n // qualification filter with none or one attendance selected\n if (selectedFilters.qualification.length === 1) {\n if (\n selectedFilters.attendance.length === 1 ||\n selectedFilters.attendance.length === 0\n ) {\n tempTitle = tempTitle.concat(\n ` ${selectedFilters.qualification[0].text}`,\n );\n } else {\n tempTitle = '';\n }\n }\n\n // more than one qualification or attendance selected\n if (\n selectedFilters.qualification.length > 1 ||\n selectedFilters.attendance.length > 1\n ) {\n tempTitle = '';\n }\n\n // both qualification and attendance not selected\n if (\n selectedFilters.qualification.length === 0 &&\n selectedFilters.attendance.length === 0\n ) {\n tempTitle = 'postgraduate courses';\n }\n\n // subject and keyword if not used before\n if (\n selectedFilters.subject.length !== 0 &&\n tempTitle !== '' &&\n !subjectUsed\n ) {\n tempTitle = tempTitle.concat(\n ` in ${selectedFilters.subject[0].text}`,\n );\n }\n if (\n selectedFilters.subject.length !== 0 &&\n selectedFilters.keyword !== '' &&\n selectedFilters.keyword !== selectedFilters.subject[0].text\n ) {\n tempTitle = '';\n }\n if (\n selectedFilters.keyword &&\n selectedFilters.subject.length === 0\n ) {\n tempTitle = '';\n }\n\n // location and institution\n if (selectedFilters.location.length !== 0 && tempTitle !== '') {\n tempTitle = tempTitle.concat(\n ` in ${selectedFilters.location[0].text}`,\n );\n }\n if (selectedFilters.institution.length !== 0 && tempTitle !== '') {\n tempTitle = tempTitle.concat(\n ` at ${selectedFilters.institution[0].text}`,\n );\n }\n\n // All the courses, no filters\n if (noFilters && selectedFilters.keyword === '') {\n tempTitle = '';\n }\n if (tempTitle !== '') {\n tempTitle = tempTitle[0]\n .toUpperCase()\n .concat(tempTitle.slice(1));\n }\n return tempTitle;\n };\n\n if (selectedFiltersStatus !== SelectedFiltersStatus.SUCCESS) {\n return;\n }\n\n setTitle(getTitle());\n }, [\n selectedFilters.attendance,\n selectedFilters.institution,\n selectedFilters.keyword,\n selectedFilters.location,\n selectedFilters.qualification,\n selectedFilters.subject,\n selectedFiltersStatus,\n ]);\n\n useDfpSlot(selectedFilters.keyword, [...combinedFilterTnrs, ...topLevelSubjectTnrs]);\n\n return (\n <>\n \n \n \n \n There has been an error}>\n }>\n \n \n \n \n {showResults && (\n There has been an error}>\n }>\n \n \n \n )}\n \n \n \n );\n};\n\nconst AppConnected = () => (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n);\n\nexport default AppConnected;\n","export const WELL_TITLE = 'Search postgraduate courses';\n","import { atom } from 'recoil';\n\nexport const userLoggedInState = atom({\n key: 'userLoggedInState',\n default: false,\n});\n","import { ReportHandler } from 'web-vitals';\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(\n ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n }\n );\n }\n};\n\nexport default reportWebVitals;\n","import 'react-app-polyfill/ie11';\nimport 'react-app-polyfill/stable';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { BrowserRouter as Router } from 'react-router-dom';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n \n \n \n \n ,\n document.getElementById('courseSearch')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}