{"version":3,"sources":["features/alert/alertSlice.ts","features/session/sessionSlice.ts","features/sharedData/sharedDataSlice.ts","features/newAppl/newApplSlice.ts","features/myAppl/myApplSlice.ts","features/account/userRegisterSlice.ts","features/password/passwordResetSlice.ts","store/index.ts","../../src/utils/validate.ts","../../src/VseApplForm/VseApplFormPersonalParticulars.tsx","../../src/VseApplForm/VseApplFormCourseSelection.tsx","../../src/VseApplForm/VseApplFormClassSelection.tsx","../../src/VseApplForm/VseApplFormDocumentUpload.tsx","../../src/VseApplForm/VseApplFormDocumentSelection.tsx","../../src/VseApplForm/VseNewApplForm.tsx","../../src/VseApplForm/VseApplFormApplClass.tsx","../../src/VseApplForm/VseApplForm.tsx","../../src/VseCourse/VseCourseNewButtons.tsx","../../src/VseHtml/VseHtmlInput.tsx","../../src/VseHtml/VseHtmlField.tsx","../../src/VseCourse/VseCourseEditGrid.tsx","../../src/VseCourse/VseCourseHeaderGrid.tsx","../../src/VseCourse/VseClassComponentEditTable.tsx","../../src/VseCourse/VseClassEditGrid.tsx","../../src/VseCourse/VseClassEditList.tsx","../../src/VseCourse/VseCourseEditForm.tsx","../../src/VseDisclaimer/VseDisclaimer.tsx","components/layout/Footer.tsx","components/login/LoginControl.tsx","components/layout/Header.tsx","components/layout/Layout.tsx","components/Home.tsx","components/login/LoginGrid.tsx","components/alert/VseAlertComponent.tsx","components/alert/VseAlertContainer.tsx","components/login/LoginPage.tsx","components/login/LogoutPage.tsx","components/password/ForgotPasswordGrid.tsx","components/password/ForgotPasswordPage.tsx","components/password/ResetPasswordGrid.tsx","components/password/ResetPasswordPage.tsx","components/register/RegisterGrid.tsx","components/register/RegisterPage.tsx","components/register/ConfirmEmailPage.tsx","components/appl/NewApplPage.tsx","components/appl/MyApplList.tsx","components/appl/MyApplPage.tsx","components/Disclaimer.tsx","components/Timeout.tsx","App.tsx","../../src/VseTheme/VseTheme.tsx","registerServiceWorker.ts","index.tsx","store/configureStore.ts"],"names":["initialState","successMessages","validationProblemMessages","serverErrorMessages","tryHandleTimeout","thunkApi","error","response","state","getState","status","session","token","isAuthenticated","dispatch","VseSession","handleThunkError","msg404","alertSlice","actions","alertValidationProblem","data","alertNotFound","alertServerError","createSlice","name","reducers","reset","Object","assign","alertSucceeded","action","push","payload","dismissSucceeded","filter","s","p","errors","forEach","alertValidationProblemMessages","dismissValidationProblem","indexOf","dismissServerError","useVseAlertState","useTypedSelector","alert","initalToken","username","isAdmin","allowHandleIncoming","allowHandleOutoging","loading","challenge","createAsyncThunk","_","a","axios","get","rejectWithValue","login","userName","password","URLSearchParams","append","post","VseAlert","logout","loginSlice","timeout","extraReducers","builder","addCase","pending","fulfilled","rejected","useVseSessionState","applStatusLoading","applStatusOptions","classComponentTypeLoading","classComponentTypeOptions","languageLoading","languageOptions","majorLoading","majorOptions","seasonLoading","seasonOptions","studyLevelLoading","studyLevelOptions","studyYearLoading","studyYearOptions","teachingModeLoading","teachingModeOptions","timeZoneLoading","timeZoneOptions","universityLoading","universityOptions","siteMessageLoading","siteMessageOptions","loadApplStatuses","loadClassComponentTypes","loadLanguages","loadMajors","loadStudyLevels","loadStudyYears","loadTeachingModes","loadTimeZones","loadUniversities","loadSiteMessages","sharedDataSlice","useVseSharedDataState","sharedData","filteredCourses","courseFilterParam","documentStates","handle","config","documentType","title","required","accept","initialNewAppl","applicationID","seasonID","referenceNumber","emailAddress","homeUniversityID","homeUniversityStudentNumber","familyName","firstName","middleName","studyLevel","major","studyYear","submissionDate","classes","documents","transformResponse","JSON","parse","key","value","Date","sources","prepare","loadCourses","loadClasses","course","universityID","encodeURIComponent","termCode","trimRight","courseCode","uploadDocument","file","formData","FormData","source","CancelToken","signal","addEventListener","cancel","requestId","headers","cancelToken","submitNewAppl","newAppl","newApplSlice","addDocumentChanged","docState","find","fileName","uploaded","uploading","removeDocument","undefined","fileID","contentType","i","findIndex","e","application","classesOfCourseSelected","meta","arg","type","splice","seasonsOpening","myAppl","seasons","courses","universityTerms","load","myApplSlice","emailConfirmation","register","f","confirmPassword","confirmEmail","encodedId","encodedCode","userRegisterSlice","useUserRegisterState","userRegister","forgotPassword","verify","id","toString","resetPassword","query","passwordResetSlice","dismissBadRequestError","validationProblemDetails","usePasswordResetState","passwordReset","useSelector","alertReducer","loginReducer","sharedDataReducer","newApplReducer","myApplReducer","userRegisterReducer","passwordResetReducer","createValidationProblemDetails","isValid","valProblems","returnIfInvalid","appendErrorTo","msg","validateRequired","label","validateMaxLength","maxLength","isNaN","allowUnderscoreAndHyphen","format","VseApplFormPersonalParticulars","props","homeUniv","universityName","className","container","item","xs","md","InputProps","readOnly","helperText","onChange","ev","select","option","code","VseApplFormCourseSelection","React","init","setInit","isSelected","c","univ","lang","termStart","Intl","termEnd","termPerid","component","scope","padding","checked","onClick","minimumFractionDigits","renderCourse","renderCourses","useStyles","makeStyles","classColumn","verticalAlign","compColumn","renderClass","aClass","firstComp","otherComps","firstCompSchedules","classCompType","teachingMode","getTeachingMode","classID","componentID","rowSpan","length","onClickedHandler","timeZone","getTimeZone","scheduleID","compSchedules","schedules","comp","renderOtherComponents","VseApplFormClassSelection","selected","setSelected","handler","hidden","display","VseApplFormDocumentUpload","color","setFile","disableTypography","filesize","renderFile","clsx","files","VseValidation","handleChange","variant","handleCancel","VseApplFormDocumentSelection","uploads","index","onDocumentCancel","onDocumentUpload","onValidationProblem","backButton","marginRight","theme","buttonsBottom","marginTop","form","paper","margin","overflow","progressBar","backgroundColor","borderBottom","root","height","stepCaption","fontSize","stepInstructions","VseNewApplForm","dangerouslySetInnerHTML","__html","content","validatePersonalParticulars","applState","d","setActiveStep","prevActiveStep","useTheme","setApplState","courseSelected","setCourseSelected","steps","activeStep","btnNextOrSubmit","handleNextStepClick","current","position","elevation","step","getSeasonMessageEntity","getInstruction","alignItems","top","left","bottom","right","justifyContent","onCourseFiltering","onCourseSelected","getUniversity","getLanguageEntity","onSelected","handles","documentHandles","disabled","prev","tableTitle","marginLeft","buttonsTop","paddingTop","paddingBottom","paddingLeft","paddingRight","disabledBackground","approvalSection","infoSection","classSection","secondaryBar","sectionTitle","uphead","textTransform","marginBottom","headingContainer","buttonSection","white","input","minHeight","editButton","numberItem","textAlign","row","cellComponentType","width","cellTeachingMode","cellSchedule","cellTimeZone","card","appBar","toolbar","selectedTab","VseDisclaimer","style","fontWeight","href","footer","spacing","separator","Footer","Typography","align","getFullYear","Link","RouterLink","to","LoginControl","sessionState","useDispatch","isInLoginPage","useLocation","pathname","loggedIn","loginButton","Button","logoutButton","logo","Header","baseUrl","document","getElementsByTagName","getAttribute","AppBar","Toolbar","Grid","src","alt","_theme","maxWidth","app","flexDirection","page","flexGrow","Layout","CssBaseline","children","Home","LoginGrid","setUserName","setPassword","TextField","target","preventDefault","onSubmit","VseAlertComponent","messages","Alert","severity","onClose","onDismiss","AlertTitle","map","VseAlertContainer","history","useHistory","alertState","locAlertState","location","vseAlerts","msgs","LoginPage","url","search","Paper","LogoutPage","Backdrop","open","CircularProgress","ForgotPasswordGrid","ForgotPasswordPage","succeeded","passwordResetState","PasswordReset","ResetPasswordGrid","setHomeUniversityID","setConfirmPassword","MenuItem","ResetPasswordPage","sharedDataState","SharedData","params","useParams","RegisterGrid","RegisterPage","Session","userRegisterState","UserRegister","regForm","ConfirmEmailPage","back","NewApplPage","newApplState","subHeaderRef","parseInt","match","NewAppl","ref","season","seasonMessages","_file","appl","dtl","onNextStep","renderContent","MyApplList","Table","TableHead","TableRow","TableCell","TableBody","cls","getClass","getSeason","seasonDescr","shortDescription","univName","univTerm","getUniversityTerm","univTermDescr","getCourse","courseTitle","applStatus","getApplStatus","IconButton","description","DateTimeFormat","day","month","year","hour","hour12","minute","second","replace","main","flex","applyButton","toolBarContainer","sectionRow","MyApplPage","myApplState","setSeasonID","MyAppl","handleApplyClick","Disclaimer","Timeout","loginLink","vsePalette","background","default","primary","secondary","text","hint","vseTypography","h1","h2","h3","h4","h5","h6","subtitle1","subtitle2","createTheme","palette","typography","MuiGrid","MuiPaper","MuiTable","size","MuiToolbar","overrides","MuiFormControl","MuiTabs","indicator","borderTopLeftRadius","borderTopRightRadius","MuiTab","minWidth","captionSide","fontWeightBold","MuiTableCell","head","createVseTheme","App","secured","link","ThemeProvider","exact","path","isLocalhost","Boolean","window","hostname","registerValidSW","swUrl","navigator","serviceWorker","then","registration","onupdatefound","installingWorker","installing","onstatechange","controller","console","log","catch","createBrowserHistory","basename","store","middleware","thunk","routerMiddleware","rootReducer","combineReducers","router","connectRouter","enhancers","windowIfDefined","__REDUX_DEVTOOLS_EXTENSION__","createStore","compose","applyMiddleware","configureStore","ReactDOM","getElementById","URL","process","origin","fetch","ready","unregister","reload","checkValidServiceWorker","registerServiceWorker"],"mappings":"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","file":"static/js/main.8a47fffe.chunk.js","sourcesContent":["import {\r\n createSlice,\r\n PayloadAction,\r\n} from '@reduxjs/toolkit';\r\nimport {\r\n Dispatch,\r\n} from 'redux';\r\nimport { AxiosError } from 'axios';\r\nimport {\r\n VseAlertState,\r\n} from './alertTypes';\r\nimport {\r\n DotNetValidationProblemDetails,\r\n} from 'vse-material-ui';\r\nimport { ApplicationState, useTypedSelector } from '../../store';\r\nimport * as VseSession from '../session';\r\n\r\n// Private type from redux toolkit (not exported)\r\n// Copied from https://github.com/reduxjs/redux-toolkit/blob/master/src/createAsyncThunk.ts\r\n// Note: getState instead of state, because of the fact that it is getState and no state\r\ntype AsyncThunkConfig = {\r\n getState: () => unknown,\r\n dispatch: Dispatch,\r\n extra?: unknown,\r\n rejectValue?: unknown,\r\n serializedErrorType?: unknown,\r\n};\r\n\r\nconst initialState = {\r\n successMessages: [],\r\n validationProblemMessages: [],\r\n serverErrorMessages: [],\r\n} as VseAlertState;\r\n\r\nexport function tryHandleTimeout(thunkApi: AsyncThunkConfig, error: AxiosError) {\r\n if (error.response) {\r\n const state = thunkApi.getState() as ApplicationState;\r\n switch (error.response.status) {\r\n case 401:\r\n if (state.session.token.isAuthenticated) {\r\n thunkApi.dispatch(VseSession.timeout());\r\n }\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nexport function handleThunkError(thunkApi: AsyncThunkConfig, error: AxiosError, msg404: string = 'Not found or access denied') {\r\n if (error.response) {\r\n switch (error.response.status) {\r\n case 400:\r\n thunkApi.dispatch(alertSlice.actions.alertValidationProblem(error.response.data));\r\n break;\r\n\r\n case 401:\r\n // Should be handled by tryHandleTimeout\r\n break;\r\n\r\n case 403:\r\n case 404:\r\n thunkApi.dispatch(alertSlice.actions.alertNotFound(msg404));\r\n break;\r\n\r\n default:\r\n thunkApi.dispatch(alertSlice.actions.alertServerError(error));\r\n break;\r\n }\r\n }\r\n}\r\n\r\nexport const alertSlice = createSlice({\r\n name: 'alert',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state = Object.assign(state, initialState);\r\n },\r\n alertSucceeded: (state, action: PayloadAction) => {\r\n state.successMessages.push(action.payload);\r\n },\r\n dismissSucceeded: (state, action: PayloadAction) => {\r\n state.successMessages = state.successMessages.filter(s => s !== action.payload);\r\n },\r\n alertNotFound: (state, action: PayloadAction) => {\r\n //TODO: not use validation problem messages\r\n state.validationProblemMessages = [action.payload];\r\n },\r\n alertValidationProblem: (state, action: PayloadAction) => {\r\n state.validationProblemMessages = [];\r\n for (const p in action.payload.errors) {\r\n action.payload.errors[p]!.forEach(s => {\r\n state.validationProblemMessages.push(s);\r\n });\r\n }\r\n },\r\n alertValidationProblemMessages: (state, action: PayloadAction) => {\r\n state.validationProblemMessages = [];\r\n action.payload.forEach(s => {\r\n state.validationProblemMessages.push(s);\r\n });\r\n },\r\n dismissValidationProblem: (state, action: PayloadAction) => {\r\n if (action.payload) {\r\n const payload = action.payload;\r\n state.validationProblemMessages = state.validationProblemMessages.filter(s => payload.indexOf(s) === -1);\r\n } else {\r\n state.validationProblemMessages = [];\r\n }\r\n },\r\n alertServerError: (state, action: PayloadAction) => {\r\n if (action.payload.response) {\r\n state.serverErrorMessages.push(action.payload.response.data);\r\n } else {\r\n state.serverErrorMessages.push(\"Unknown server error\");\r\n }\r\n },\r\n dismissServerError: (state, action: PayloadAction) => {\r\n state.serverErrorMessages = state.serverErrorMessages.filter(s => s !== action.payload);\r\n },\r\n },\r\n});\r\n\r\nexport const {\r\n reset,\r\n alertSucceeded, dismissSucceeded,\r\n alertValidationProblem, dismissValidationProblem, alertValidationProblemMessages,\r\n alertServerError, dismissServerError,\r\n} = alertSlice.actions;\r\n\r\nexport default alertSlice.reducer;\r\n\r\nexport const useVseAlertState = (): VseAlertState => useTypedSelector(state => state.alert);\r\n","import {\r\n createSlice,\r\n createAsyncThunk,\r\n} from '@reduxjs/toolkit';\r\nimport axios from 'axios';\r\nimport {\r\n AxiosError,\r\n} from 'axios';\r\nimport {\r\n VseSessionState,\r\n VseSessionToken,\r\n} from './sessionTypes';\r\nimport { \r\n useTypedSelector,\r\n} from '../../store';\r\nimport * as VseAlert from '../alert';\r\n\r\nconst initalToken = {\r\n username: '',\r\n isAuthenticated: false,\r\n isAdmin: false,\r\n allowHandleIncoming: false,\r\n allowHandleOutoging: false,\r\n} as VseSessionToken;\r\n\r\nconst initialState = {\r\n loading: 'idle',\r\n token: initalToken,\r\n} as VseSessionState;\r\n\r\nexport const challenge = createAsyncThunk('session/challenge', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/identity/challenge');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n //Not required to handle error\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const login = createAsyncThunk('session/login', async ({ userName, password }: { userName: string, password: string }, thunkApi) => {\r\n let data = new URLSearchParams();\r\n data.append('userName', userName);\r\n data.append('password', password);\r\n try {\r\n const response = await axios.post('api/identity/login', data);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error);\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const logout = createAsyncThunk('session/logout', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/identity/logout');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n //Not required to handle error\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loginSlice = createSlice({\r\n name: 'session',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state = Object.assign(state, initialState);\r\n },\r\n timeout: (state) => {\r\n state.loading = 'timeout';\r\n },\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(login.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(login.fulfilled, (state, action) => {\r\n state.loading = 'succeeded';\r\n state.token = action.payload.data;\r\n });\r\n builder.addCase(login.rejected, (state) => {\r\n state.loading = 'failed';\r\n state.token = initalToken;\r\n });\r\n builder.addCase(challenge.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(challenge.fulfilled, (state, action) => {\r\n if (action.payload.data.isAuthenticated) {\r\n state.loading = 'succeeded';\r\n state.token = action.payload.data;\r\n } else {\r\n state.loading = 'pending';\r\n state.token = initalToken;\r\n }\r\n });\r\n builder.addCase(challenge.rejected, (state) => {\r\n state.loading = 'pending';\r\n state.token = initalToken;\r\n });\r\n builder.addCase(logout.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(logout.fulfilled, (state) => {\r\n state.loading = 'loggedOut';\r\n });\r\n builder.addCase(logout.rejected, (state) => {\r\n state.loading = 'loggedOut';\r\n });\r\n },\r\n});\r\n\r\nexport const { reset, timeout } = loginSlice.actions;\r\n\r\nexport default loginSlice.reducer;\r\n\r\nexport const useVseSessionState = (): VseSessionState => useTypedSelector(state => state.session);\r\n","import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';\r\nimport axios, { AxiosError } from 'axios';\r\nimport {\r\n ApplStatusEntity,\r\n ClassComponentTypeEntity,\r\n LanguageEntity,\r\n MajorEntity,\r\n StudyLevelEntity,\r\n StudyYearEntity,\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n UniversityEntity,\r\n SiteMessageEntity,\r\n} from 'vse-material-ui';\r\nimport { VseSharedDataState } from './sharedDataTypes';\r\nimport { useTypedSelector } from '../../store';\r\nimport * as VseSession from '../session';\r\nimport * as VseAlert from '../alert';\r\n\r\nconst initialState = {\r\n applStatusLoading: 'idle',\r\n applStatusOptions: [],\r\n classComponentTypeLoading: 'idle',\r\n classComponentTypeOptions: [],\r\n languageLoading: 'idle',\r\n languageOptions: [],\r\n majorLoading: 'idle',\r\n majorOptions: [],\r\n seasonLoading: 'idle',\r\n seasonOptions: [],\r\n studyLevelLoading: 'idle',\r\n studyLevelOptions: [],\r\n studyYearLoading: 'idle',\r\n studyYearOptions: [],\r\n teachingModeLoading: 'idle',\r\n teachingModeOptions: [],\r\n timeZoneLoading: 'idle',\r\n timeZoneOptions: [],\r\n universityLoading: 'idle',\r\n universityOptions: [],\r\n siteMessageLoading: 'idle',\r\n siteMessageOptions: [],\r\n} as VseSharedDataState;\r\n\r\nexport const loadApplStatuses = createAsyncThunk('sharedData/loadApplStatuses', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/applstatuses');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadClassComponentTypes = createAsyncThunk('sharedData/loadClassComponentTypes', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/classcomponentTypes');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadLanguages = createAsyncThunk('sharedData/loadLanguages', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/languages');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadMajors = createAsyncThunk('sharedData/loadMajors', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/majors');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadStudyLevels = createAsyncThunk('sharedData/loadStudyLevels', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/studylevels');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadStudyYears = createAsyncThunk('sharedData/loadStudyYears', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/studyyears');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadTeachingModes = createAsyncThunk('sharedData/loadTeachingModes', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/teachingmodes');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadTimeZones = createAsyncThunk('sharedData/loadTimeZones', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/timezones');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadUniversities = createAsyncThunk('sharedData/loadUniversities', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/universities');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadSiteMessages = createAsyncThunk('sharedData/loadSiteMessages', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get('api/shared/sitemessages');\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const sharedDataSlice = createSlice({\r\n name: 'sharedData',\r\n initialState,\r\n reducers: {\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(VseSession.reset, (state) => {\r\n state = Object.assign(state, initialState);\r\n });\r\n builder.addCase(loadApplStatuses.pending, (state) => {\r\n state.applStatusLoading = 'pending';\r\n });\r\n builder.addCase(loadApplStatuses.fulfilled, (state, action) => {\r\n state.applStatusLoading = 'succeeded';\r\n state.applStatusOptions = action.payload.data;\r\n });\r\n builder.addCase(loadApplStatuses.rejected, (state) => {\r\n state.applStatusLoading = 'failed';\r\n state.applStatusOptions = initialState.applStatusOptions;\r\n });\r\n builder.addCase(loadClassComponentTypes.pending, (state) => {\r\n state.classComponentTypeLoading = 'pending';\r\n });\r\n builder.addCase(loadClassComponentTypes.fulfilled, (state, action) => {\r\n state.classComponentTypeLoading = 'succeeded';\r\n state.classComponentTypeOptions = action.payload.data;\r\n });\r\n builder.addCase(loadClassComponentTypes.rejected, (state) => {\r\n state.classComponentTypeLoading = 'failed';\r\n state.classComponentTypeOptions = initialState.classComponentTypeOptions;\r\n });\r\n builder.addCase(loadLanguages.pending, (state) => {\r\n state.languageLoading = 'pending';\r\n });\r\n builder.addCase(loadLanguages.fulfilled, (state, action) => {\r\n state.languageLoading = 'succeeded';\r\n state.languageOptions = action.payload.data;\r\n });\r\n builder.addCase(loadLanguages.rejected, (state) => {\r\n state.languageLoading = 'failed';\r\n state.languageOptions = initialState.languageOptions;\r\n });\r\n builder.addCase(loadMajors.pending, (state) => {\r\n state.majorLoading = 'pending';\r\n });\r\n builder.addCase(loadMajors.fulfilled, (state, action) => {\r\n state.majorLoading = 'succeeded';\r\n state.majorOptions = action.payload.data;\r\n });\r\n builder.addCase(loadMajors.rejected, (state) => {\r\n state.majorLoading = 'failed';\r\n state.majorOptions = initialState.majorOptions;\r\n });\r\n builder.addCase(loadTeachingModes.pending, (state) => {\r\n state.teachingModeLoading = 'pending';\r\n });\r\n builder.addCase(loadTeachingModes.fulfilled, (state, action) => {\r\n state.teachingModeLoading = 'succeeded';\r\n state.teachingModeOptions = action.payload.data;\r\n });\r\n builder.addCase(loadTeachingModes.rejected, (state) => {\r\n state.teachingModeLoading = 'failed';\r\n state.teachingModeOptions = initialState.teachingModeOptions;\r\n });\r\n builder.addCase(loadTimeZones.pending, (state) => {\r\n state.timeZoneLoading = 'pending';\r\n });\r\n builder.addCase(loadTimeZones.fulfilled, (state, action) => {\r\n state.timeZoneLoading = 'succeeded';\r\n state.timeZoneOptions = action.payload.data;\r\n });\r\n builder.addCase(loadTimeZones.rejected, (state) => {\r\n state.timeZoneLoading = 'failed';\r\n state.timeZoneOptions = initialState.timeZoneOptions;\r\n });\r\n builder.addCase(loadStudyLevels.pending, (state) => {\r\n state.studyLevelLoading = 'pending';\r\n });\r\n builder.addCase(loadStudyLevels.fulfilled, (state, action) => {\r\n state.studyLevelLoading = 'succeeded';\r\n state.studyLevelOptions = action.payload.data;\r\n });\r\n builder.addCase(loadStudyLevels.rejected, (state) => {\r\n state.studyLevelLoading = 'failed';\r\n state.studyLevelOptions = initialState.studyLevelOptions;\r\n });\r\n builder.addCase(loadStudyYears.pending, (state) => {\r\n state.studyYearLoading = 'pending';\r\n });\r\n builder.addCase(loadStudyYears.fulfilled, (state, action) => {\r\n state.studyYearLoading = 'succeeded';\r\n state.studyYearOptions = action.payload.data;\r\n });\r\n builder.addCase(loadStudyYears.rejected, (state) => {\r\n state.studyYearLoading = 'failed';\r\n state.studyYearOptions = initialState.studyYearOptions;\r\n });\r\n builder.addCase(loadUniversities.pending, (state) => {\r\n state.universityLoading = 'pending';\r\n });\r\n builder.addCase(loadUniversities.fulfilled, (state, action) => {\r\n state.universityLoading = 'succeeded';\r\n state.universityOptions = action.payload.data;\r\n });\r\n builder.addCase(loadUniversities.rejected, (state) => {\r\n state.universityLoading = 'failed';\r\n state.universityOptions = initialState.universityOptions;\r\n });\r\n builder.addCase(loadSiteMessages.pending, (state) => {\r\n state.siteMessageLoading = 'pending';\r\n });\r\n builder.addCase(loadSiteMessages.fulfilled, (state, action) => {\r\n state.siteMessageLoading = 'succeeded';\r\n state.siteMessageOptions = action.payload.data;\r\n });\r\n builder.addCase(loadSiteMessages.rejected, (state) => {\r\n state.siteMessageLoading = 'failed';\r\n state.siteMessageOptions = initialState.siteMessageOptions;\r\n });\r\n }\r\n});\r\n\r\nexport default sharedDataSlice.reducer;\r\n\r\nexport const useVseSharedDataState = (): VseSharedDataState => useTypedSelector(state => state.sharedData);\r\n","import {\r\n createSlice,\r\n createAsyncThunk,\r\n PayloadAction,\r\n} from '@reduxjs/toolkit';\r\nimport axios, { AxiosRequestConfig, CancelTokenSource } from 'axios';\r\nimport {\r\n AxiosError,\r\n} from 'axios';\r\nimport {\r\n CourseEntity,\r\n ClassEntity,\r\n VseApplicationEntity,\r\n VseApplFormDocumentUploadHandle,\r\n VseApplFormDocumentUploadConfig,\r\n} from 'vse-material-ui';\r\nimport {\r\n NewVseApplicationToken,\r\n NewVseApplDocumentState,\r\n NewVseApplicationState,\r\n} from './newApplTypes';\r\nimport { useTypedSelector } from '../../store';\r\nimport * as VseAlert from '../alert';\r\nimport * as VseSession from '../session';\r\n\r\nconst initialState = {\r\n loading: 'idle',\r\n filteredCourses: [],\r\n courseFilterParam: {},\r\n documentStates: [ //TODO: Config dynamically\r\n {\r\n loading: 'idle',\r\n handle: {\r\n config: {\r\n documentType: 'HOMETSCPT',\r\n title: \"Home University Transcript\",\r\n required: true,\r\n accept: [\"image/jpeg\", \"image/png\", \"application/pdf\"],\r\n } as VseApplFormDocumentUploadConfig,\r\n } as VseApplFormDocumentUploadHandle,\r\n } as NewVseApplDocumentState,\r\n {\r\n loading: 'idle',\r\n handle: {\r\n config: {\r\n documentType: 'LANGPROF',\r\n title: \"Proof of Language Proficiency\",\r\n required: false,\r\n accept: [\"image/jpeg\", \"image/png\", \"application/pdf\"],\r\n } as VseApplFormDocumentUploadConfig,\r\n } as VseApplFormDocumentUploadHandle,\r\n } as NewVseApplDocumentState,\r\n ],\r\n} as NewVseApplicationState;\r\n\r\nconst initialNewAppl = {\r\n applicationID: 0,\r\n seasonID: 0,\r\n referenceNumber: '',\r\n userName: '',\r\n emailAddress: '',\r\n homeUniversityID: 0,\r\n homeUniversityStudentNumber: '',\r\n familyName: '',\r\n firstName: '',\r\n middleName: '',\r\n studyLevel: '',\r\n major: '',\r\n studyYear: '',\r\n submissionDate: '',\r\n status: '',\r\n classes: [],\r\n documents: [],\r\n} as VseApplicationEntity;\r\n\r\nfunction transformResponse(data: any) {\r\n try {\r\n let j = JSON.parse(data, (key, value) => {\r\n switch (key) {\r\n case 'startDate':\r\n case 'endDate':\r\n case 'outgoingApplicationStartDate':\r\n case 'outgoingApplicationDeadline':\r\n return new Date(value);\r\n default:\r\n return value;\r\n }\r\n });\r\n return j;\r\n } catch {\r\n // Not json\r\n return data;\r\n }\r\n}\r\n\r\nlet sources: Array<{ requestId: string, source: CancelTokenSource }> = [];\r\n\r\nexport const prepare = createAsyncThunk('newAppl/prepare', async (seasonID: number, thunkApi) => {\r\n try {\r\n const response = await axios.get(`api/apply/seasons/${seasonID}`, {\r\n transformResponse: transformResponse\r\n });\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadCourses = createAsyncThunk('newAppl/loadCourses', async (seasonID: number, thunkApi) => {\r\n //TODO: filtering\r\n try {\r\n const response = await axios.get(`api/apply/seasons/${seasonID}/courses`, {\r\n transformResponse: transformResponse\r\n });\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const loadClasses = createAsyncThunk('newAppl/loadClasses', async (course: CourseEntity, thunkApi) => {\r\n try {\r\n const response = await axios.get(`api/seasons/${course.seasonID}/universities/${course.universityID}/terms/${encodeURIComponent(course.termCode.trimRight())}/courses/${encodeURIComponent(course.courseCode.trimRight())}/classes`);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const uploadDocument = createAsyncThunk('newAppl/uploadDocument', async ({\r\n file,\r\n}: {\r\n handle: VseApplFormDocumentUploadHandle,\r\n file: File,\r\n}, thunkApi) => {\r\n try {\r\n let formData = new FormData();\r\n formData.append(\"file\", file);\r\n const source = axios.CancelToken.source();\r\n thunkApi.signal.addEventListener('abort', () => {\r\n source.cancel();\r\n });\r\n\r\n sources.push({ requestId: thunkApi.requestId, source: source });\r\n\r\n let config: AxiosRequestConfig = {\r\n headers: {\r\n \"Content-Type\": \"multipart/form-data\",\r\n },\r\n cancelToken: source.token,\r\n }\r\n const response = await axios.post<{ fileID: string }>(`api/file/upload`, formData, config);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const submitNewAppl = createAsyncThunk('newAppl/submitNewAppl', async (newAppl: VseApplicationEntity, thunkApi) => {\r\n try {\r\n const response = await axios.post(`api/apply/seasons/${newAppl.seasonID}`, newAppl);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const newApplSlice = createSlice({\r\n name: 'newAppl',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state = Object.assign(state, initialState);\r\n },\r\n addDocumentChanged: (state, action: PayloadAction<{\r\n documentType: string,\r\n file: File,\r\n }>) => {\r\n let docState = state.documentStates.find((s) => s.handle.config.documentType === action.payload.documentType);\r\n if (docState) {\r\n docState.handle.file = action.payload.file;\r\n docState.handle.fileName = action.payload.file.name;\r\n docState.handle.uploaded = false;\r\n docState.handle.uploading = false;\r\n }\r\n },\r\n removeDocument: (state, action: PayloadAction<{\r\n documentType: string,\r\n requestId?: string,\r\n }>) => {\r\n let docState = state.documentStates.find((s) => s.handle.config.documentType === action.payload.documentType);\r\n if (docState) {\r\n docState.loading = 'idle';\r\n docState.handle.file = undefined;\r\n docState.handle.requestId = undefined;\r\n docState.handle.fileID = undefined;\r\n docState.handle.fileName = undefined;\r\n docState.handle.contentType = undefined;\r\n docState.handle.uploaded = false;\r\n docState.handle.uploading = false;\r\n }\r\n const i = sources.findIndex((e) => e.requestId === action.payload.requestId);\r\n if (i >= 0) {\r\n sources[i].source.cancel();\r\n }\r\n },\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(VseSession.reset, (state) => {\r\n state = Object.assign(state, initialState);\r\n });\r\n builder.addCase(prepare.pending, (state) => {\r\n state.loading = 'pending';\r\n });\r\n builder.addCase(prepare.fulfilled, (state, action) => {\r\n state.loading = 'ready';\r\n state.token = action.payload.data;\r\n state.token.application = { ...initialNewAppl, ...action.payload.data.application };\r\n });\r\n builder.addCase(prepare.rejected, (state) => {\r\n state.loading = 'failed';\r\n state.token = undefined;\r\n });\r\n builder.addCase(loadCourses.fulfilled, (state, action) => {\r\n state.filteredCourses = action.payload.data;\r\n });\r\n builder.addCase(loadClasses.fulfilled, (state, action) => {\r\n state.classesOfCourseSelected = action.payload.data;\r\n });\r\n builder.addCase(loadClasses.rejected, (state) => {\r\n state.classesOfCourseSelected = undefined;\r\n });\r\n builder.addCase(uploadDocument.pending, (state, action) => {\r\n let docState = state.documentStates.find((docState) => docState.handle.config.documentType === action.meta.arg.handle.config.documentType);\r\n if (docState) {\r\n docState.loading = 'pending';\r\n docState.handle.fileName = action.meta.arg.file.name;\r\n docState.handle.contentType = action.meta.arg.file.type;\r\n docState.handle.requestId = action.meta.requestId;\r\n docState.handle.uploading = true;\r\n docState.handle.uploaded = false;\r\n }\r\n });\r\n builder.addCase(uploadDocument.fulfilled, (state, action) => {\r\n let docState = state.documentStates.find((docState) => docState.handle.config.documentType === action.meta.arg.handle.config.documentType);\r\n if (docState) {\r\n docState.loading = 'succeeded';\r\n docState.handle.fileID = action.payload.data.fileID;\r\n docState.handle.uploading = false;\r\n docState.handle.uploaded = true;\r\n //TODO: to add to appl.vseappldocument\r\n }\r\n const i = sources.findIndex((e) => e.requestId === action.meta.requestId);\r\n if (i >= 0) {\r\n sources.splice(i, 1);\r\n }\r\n });\r\n builder.addCase(uploadDocument.rejected, (state, action) => {\r\n let docState = state.documentStates.find((docState) => docState.handle.config.documentType === action.meta.arg.handle.config.documentType);\r\n if (docState) {\r\n docState.loading = 'failed';\r\n docState.handle.fileID = undefined;\r\n docState.handle.fileName = undefined;\r\n docState.handle.requestId = undefined;\r\n docState.handle.uploading = false;\r\n docState.handle.uploaded = false;\r\n }\r\n const i = sources.findIndex((e) => e.requestId === action.meta.requestId);\r\n if (i >= 0) {\r\n sources.splice(i, 1);\r\n }\r\n });\r\n builder.addCase(submitNewAppl.pending, (state) => {\r\n state.loading = 'pending';\r\n });\r\n builder.addCase(submitNewAppl.fulfilled, (state) => {\r\n state.loading = 'succeeded';\r\n });\r\n builder.addCase(submitNewAppl.rejected, (state, action) => {\r\n state.loading = 'ready';\r\n state.token!.application = action.meta.arg;\r\n });\r\n },\r\n});\r\n\r\nexport const {\r\n removeDocument,\r\n reset,\r\n} = newApplSlice.actions;\r\n\r\nexport default newApplSlice.reducer;\r\n\r\nexport const useNewVseApplicationState = (): NewVseApplicationState => useTypedSelector(state => state.newAppl);\r\n","import {\r\n createSlice,\r\n createAsyncThunk,\r\n} from '@reduxjs/toolkit';\r\nimport axios, { AxiosError } from 'axios';\r\nimport {\r\n ClassEntity,\r\n CourseEntity,\r\n SeasonEntity,\r\n UniversityTermEntity,\r\n VseApplicationEntity\r\n} from 'vse-material-ui';\r\nimport {\r\n MyApplState\r\n} from './myApplTypes';\r\nimport {\r\n useTypedSelector\r\n} from '../../store';\r\nimport * as VseSession from '../session';\r\nimport * as VseAlert from '../alert';\r\n\r\nconst initialState = {\r\n loading: 'idle',\r\n seasonsOpening: [],\r\n myAppl: [],\r\n seasons: [],\r\n classes: [],\r\n courses: [],\r\n universityTerms: [],\r\n} as MyApplState;\r\n\r\nexport const load = createAsyncThunk('myAppl/load', async (_, thunkApi) => {\r\n try {\r\n const response = await axios.get<{\r\n seasonsOpening: SeasonEntity[],\r\n myAppl: VseApplicationEntity[],\r\n seasons: SeasonEntity[],\r\n classes: ClassEntity[],\r\n courses: CourseEntity[],\r\n universityTerms: UniversityTermEntity[],\r\n }>(`api/myAppl`);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n if (!VseAlert.tryHandleTimeout(thunkApi, error)) {\r\n VseAlert.handleThunkError(thunkApi, error);\r\n }\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const myApplSlice = createSlice({\r\n name: 'myAppl',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state.loading = initialState.loading;\r\n state.seasonsOpening = initialState.seasonsOpening;\r\n state.myAppl = initialState.myAppl;\r\n state.seasons = initialState.seasons;\r\n state.classes = initialState.classes;\r\n state.courses = initialState.courses;\r\n state.universityTerms = initialState.universityTerms;\r\n },\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(VseSession.reset, (state) => {\r\n state = Object.assign(state, initialState);\r\n });\r\n builder.addCase(load.pending, (state) => {\r\n state.loading = 'pending';\r\n });\r\n builder.addCase(load.fulfilled, (state, action) => {\r\n state.loading = 'succeeded';\r\n state.seasonsOpening = action.payload.data.seasonsOpening;\r\n state.myAppl = action.payload.data.myAppl;\r\n state.seasons = action.payload.data.seasons;\r\n state.classes = action.payload.data.classes;\r\n state.courses = action.payload.data.courses;\r\n state.universityTerms = action.payload.data.universityTerms;\r\n });\r\n builder.addCase(load.rejected, (state) => {\r\n state.loading = 'failed';\r\n state.seasonsOpening = [];\r\n state.myAppl = [];\r\n state.seasons = [];\r\n state.classes = [];\r\n state.courses = [];\r\n state.universityTerms = [];\r\n });\r\n },\r\n});\r\n\r\nexport const { reset } = myApplSlice.actions;\r\n\r\nexport default myApplSlice.reducer;\r\n\r\nexport const useMyApplState = (): MyApplState => useTypedSelector(state => state.myAppl);\r\n","import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';\r\nimport axios from 'axios';\r\nimport { AxiosError } from 'axios';\r\nimport { UserRegistrationForm, UserRegisterState } from './userRegisterTypes';\r\nimport { useTypedSelector } from '../../store';\r\nimport * as VseAlert from '../alert';\r\n\r\nconst msg404Activate = 'The account activation link is invalid or has been expired';\r\n\r\nconst initialState = {\r\n loading: 'idle',\r\n emailConfirmation: 'idle',\r\n} as UserRegisterState;\r\n\r\nexport const register = createAsyncThunk('userRegister/register', async (f: UserRegistrationForm, thunkApi) => {\r\n const data = {\r\n userName: f.userName,\r\n homeUniversityID: f.homeUniversityID,\r\n password: f.password,\r\n confirmPassword: f.confirmPassword,\r\n };\r\n try {\r\n const response = await axios.post('api/identity/register', data);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error);\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const confirmEmail = createAsyncThunk('userRegister/confirmEmail', async ({ encodedId, encodedCode }: { encodedId: string, encodedCode: string }, thunkApi) => {\r\n let data = new FormData();\r\n data.append('id', encodedId);\r\n data.append('token', encodedCode);\r\n try {\r\n const response = await axios.post('api/identity/confirmEmail', data);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error, msg404Activate);\r\n return thunkApi.rejectWithValue(error);\r\n }\r\n});\r\n\r\nexport const userRegisterSlice = createSlice({\r\n name: 'userRegister',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state = Object.assign(state, initialState);\r\n },\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(register.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(register.fulfilled, (state) => {\r\n state.loading = 'succeeded';\r\n });\r\n builder.addCase(register.rejected, (state) => {\r\n state.loading = 'pending';\r\n });\r\n builder.addCase(confirmEmail.pending, (state) => {\r\n state.emailConfirmation = 'pending';\r\n });\r\n builder.addCase(confirmEmail.fulfilled, (state) => {\r\n state.emailConfirmation = 'succeeded';\r\n });\r\n builder.addCase(confirmEmail.rejected, (state) => {\r\n state.emailConfirmation = 'failed';\r\n });\r\n },\r\n});\r\n\r\nexport const { reset } = userRegisterSlice.actions;\r\n\r\nexport default userRegisterSlice.reducer;\r\n\r\nexport const useUserRegisterState = (): UserRegisterState => useTypedSelector(state => state.userRegister);\r\n","import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';\r\nimport axios from 'axios';\r\nimport { AxiosError } from 'axios';\r\nimport { PasswordResetState } from './passwordResetTypes';\r\nimport * as VseAlert from '../../features/alert';\r\nimport { useTypedSelector } from '../../store';\r\n\r\nconst msg404 = 'The password reset link is invalid or has been expired';\r\n\r\nconst initialState = {\r\n loading: 'idle',\r\n} as PasswordResetState;\r\n\r\nexport const forgotPassword = createAsyncThunk('password/forgotPassword', async (userName: string, thunkApi) => {\r\n let data = new FormData();\r\n data.append('userName', userName);\r\n try {\r\n const response = await axios.post('api/identity/forgotPassword', data);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error, msg404);\r\n return thunkApi.rejectWithValue(null);\r\n }\r\n});\r\n\r\nexport const verify = createAsyncThunk('password/verify', async ({ id, token }: {\r\n id: string,\r\n token: string,\r\n}, thunkApi) => {\r\n let data = new URLSearchParams();\r\n data.append('id', id);\r\n data.append('token', token);\r\n try {\r\n const response = await axios.get(`api/identity/resetPassword?${data.toString()}`);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error, msg404);\r\n return thunkApi.rejectWithValue(null);\r\n }\r\n});\r\n\r\nexport const resetPassword = createAsyncThunk('password/resetPassword', async ({ id, token, homeUniversityID, password, confirmPassword }: {\r\n id: string,\r\n token: string,\r\n homeUniversityID: number,\r\n password: string,\r\n confirmPassword: string,\r\n}, thunkApi) => {\r\n\r\n let query = new URLSearchParams();\r\n query.append('id', id);\r\n query.append('token', token);\r\n\r\n let data: {\r\n homeUniversityID?: number,\r\n password?: string,\r\n confirmPassword?: string,\r\n } = {};\r\n\r\n if (homeUniversityID) data.homeUniversityID = homeUniversityID;\r\n if (password) data.password = password;\r\n if (confirmPassword) data.confirmPassword = confirmPassword;\r\n\r\n try {\r\n const response = await axios.post(`api/identity/resetPassword?${query.toString()}`, data);\r\n return response;\r\n } catch (err) {\r\n const error: AxiosError = err;\r\n VseAlert.handleThunkError(thunkApi, error);\r\n return thunkApi.rejectWithValue(null);\r\n }\r\n});\r\n\r\nexport const passwordResetSlice = createSlice({\r\n name: 'passwordReset',\r\n initialState,\r\n reducers: {\r\n reset: (state) => {\r\n state = Object.assign(state, initialState);\r\n },\r\n dismissBadRequestError: (state) => {\r\n state.validationProblemDetails = undefined;\r\n },\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(forgotPassword.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(forgotPassword.fulfilled, (state) => {\r\n state.loading = 'succeeded';\r\n });\r\n builder.addCase(forgotPassword.rejected, (state) => {\r\n state.loading = 'failed';\r\n });\r\n builder.addCase(verify.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(verify.fulfilled, (state) => {\r\n state.loading = 'pending';\r\n });\r\n builder.addCase(verify.rejected, (state) => {\r\n state.loading = 'failed';\r\n });\r\n builder.addCase(resetPassword.pending, (state) => {\r\n state.loading = 'loading';\r\n });\r\n builder.addCase(resetPassword.fulfilled, (state) => {\r\n state.loading = 'succeeded';\r\n });\r\n builder.addCase(resetPassword.rejected, (state) => {\r\n state.loading = 'pending';\r\n });\r\n },\r\n});\r\n\r\nexport const {\r\n reset,\r\n} = passwordResetSlice.actions;\r\n\r\nexport default passwordResetSlice.reducer;\r\n\r\nexport const usePasswordResetState = (): PasswordResetState => useTypedSelector(state => state.passwordReset);\r\n\r\n","import { useSelector, TypedUseSelectorHook } from 'react-redux'\r\nimport { VseSessionState } from '../features/session/sessionTypes';\r\nimport { default as loginReducer } from '../features/session/sessionSlice';\r\nimport { VseSharedDataState } from '../features/sharedData/sharedDataTypes';\r\nimport { default as sharedDataReducer } from '../features/sharedData/sharedDataSlice';\r\nimport { NewVseApplicationState } from '../features/newAppl/newApplTypes';\r\nimport { default as newApplReducer } from '../features/newAppl/newApplSlice';\r\nimport { MyApplState } from '../features/myAppl/myApplTypes';\r\nimport { default as myApplReducer } from '../features/myAppl/myApplSlice';\r\nimport { UserRegisterState } from '../features/account/userRegisterTypes';\r\nimport { default as userRegisterReducer } from '../features/account/userRegisterSlice';\r\nimport { PasswordResetState } from '../features/password/passwordResetTypes';\r\nimport { default as passwordResetReducer } from '../features/password/passwordResetSlice';\r\nimport { VseAlertState } from '../features/alert/alertTypes';\r\nimport { default as alertReducer } from '../features/alert/alertSlice';\r\n\r\n// The top-level state object\r\nexport interface ApplicationState {\r\n alert: VseAlertState,\r\n session: VseSessionState,\r\n sharedData: VseSharedDataState,\r\n newAppl: NewVseApplicationState,\r\n myAppl: MyApplState,\r\n userRegister: UserRegisterState,\r\n passwordReset: PasswordResetState,\r\n}\r\n\r\nexport const useTypedSelector: TypedUseSelectorHook = useSelector;\r\n\r\n// Whenever an action is dispatched, Redux will update each top-level application state property using\r\n// the reducer with the matching name. It's important that the names match exactly, and that the reducer\r\n// acts on the corresponding ApplicationState property type.\r\nexport const reducers = {\r\n alert: alertReducer,\r\n session: loginReducer,\r\n sharedData: sharedDataReducer,\r\n newAppl: newApplReducer,\r\n myAppl: myApplReducer,\r\n userRegister: userRegisterReducer,\r\n passwordReset: passwordResetReducer,\r\n};\r\n\r\n","import { DotNetValidationProblemDetails } from \"../types\";\r\n\r\nexport function createValidationProblemDetails() {\r\n return {\r\n errors: {}\r\n }\r\n}\r\n\r\nexport function isValid(valProblems: DotNetValidationProblemDetails) {\r\n if (valProblems.errors) {\r\n for (let key in valProblems.errors) {\r\n if (valProblems.errors[key]!.length > 0) {\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport function returnIfInvalid(valProblems: DotNetValidationProblemDetails) {\r\n return isValid(valProblems) ? undefined : valProblems;\r\n}\r\n\r\nexport function appendErrorTo(valProblems: DotNetValidationProblemDetails, key: string, msg: string) {\r\n if (valProblems.errors[key]) {\r\n valProblems.errors[key]?.push(msg);\r\n } else {\r\n valProblems.errors[key] = [msg];\r\n }\r\n}\r\n\r\nexport function validateRequired(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n value?: string,\r\n): boolean {\r\n if (!value || value.trimEnd().length === 0) {\r\n appendErrorTo(valProblems, key, `The ${label} field is required.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateSelectionRequired(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n value?: number,\r\n): boolean {\r\n if (!value || value <= 0) {\r\n appendErrorTo(valProblems, key, `The ${label} field is required.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateNumberRequired(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n value?: number,\r\n): boolean {\r\n if (value === undefined || value === null || isNaN(value)) {\r\n appendErrorTo(valProblems, key, `The ${label} field is required.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateMaxLength(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n maxLength: number,\r\n value?: string,\r\n): boolean {\r\n if (value && value.trimEnd().length > maxLength) {\r\n appendErrorTo(valProblems, key, `The field ${label} must be a string with a maximum length of ${maxLength}.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateMaxLengthWitoutTrimEnd(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n maxLength: number,\r\n value?: string,\r\n): boolean {\r\n if (value && value.length > maxLength) {\r\n appendErrorTo(valProblems, key, `The field ${label} must be a string with a maximum length of ${maxLength}.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateNoSpace(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n value?: string,\r\n): boolean {\r\n if (value && value.trimEnd().indexOf(' ') >= 0) {\r\n appendErrorTo(valProblems, key, `The field ${label} must be a string without space.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nexport function validateNoSpecialCharacters(\r\n valProblems: DotNetValidationProblemDetails,\r\n key: string,\r\n label: string,\r\n value?: string,\r\n allowUnderscoreAndHyphen?: boolean\r\n): boolean {\r\n if (allowUnderscoreAndHyphen) {\r\n var format = /[`~!@#$%^&*()+=\\[\\]{};':\"\\\\|,.<>\\/?]+/;\r\n var msg = `The ${label} field cannot contain special characters, except hyphen \"-\" and underscore \"_\".`;\r\n } else {\r\n var format = /[`~!@#$%^&*_\\-()+=\\[\\]{};':\"\\\\|,.<>\\/?]+/;\r\n var msg = `The ${label} field cannot contain special characters.`;\r\n }\r\n if (value && format.test(value.trimEnd())) {\r\n appendErrorTo(valProblems, key, msg);\r\n return false;\r\n }\r\n return true;\r\n}\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport {\r\n DotNetValidationProblemDetailsTyped,\r\n MajorEntity,\r\n StudyLevelEntity,\r\n StudyYearEntity,\r\n UniversityEntity,\r\n VseApplicationEntity,\r\n} from '../types';\r\nimport * as VseValidation from '../utils/validate';\r\n\r\nexport interface VseApplFormPersonalParticularsProps extends Pick, 'className'> {\r\n data: VseApplicationEntity,\r\n majorOptions: MajorEntity[],\r\n studyLevelOptions: StudyLevelEntity[],\r\n studyYearOptions: StudyYearEntity[],\r\n universityOptions: UniversityEntity[]\r\n onChange: (\r\n changes: Pick,\r\n 'familyName' |\r\n 'firstName' |\r\n 'middleName' |\r\n 'homeUniversityID' |\r\n 'homeUniversityStudentNumber' |\r\n 'studyLevel' |\r\n 'major' |\r\n 'studyYear'>\r\n ) => void,\r\n};\r\n\r\nexport function validatePersonalParticulars(valProblems: DotNetValidationProblemDetailsTyped, data: VseApplicationEntity): DotNetValidationProblemDetailsTyped | undefined {\r\n VseValidation.validateRequired(valProblems, 'familyName', 'Family Name', data.familyName);\r\n VseValidation.validateMaxLength(valProblems, 'familyName', 'Family Name', 50, data.familyName);\r\n\r\n VseValidation.validateRequired(valProblems, 'firstName', 'Given Name', data.firstName);\r\n VseValidation.validateMaxLength(valProblems, 'firstName', 'Given Name', 50, data.firstName);\r\n\r\n VseValidation.validateMaxLength(valProblems, 'middleName', 'Middle Name', 50, data.middleName);\r\n\r\n VseValidation.validateRequired(valProblems, 'homeUniversityStudentNumber', 'Home U Student ID Number', data.homeUniversityStudentNumber);\r\n VseValidation.validateMaxLength(valProblems, 'homeUniversityStudentNumber', 'Home U Student ID Number', 20, data.homeUniversityStudentNumber);\r\n\r\n VseValidation.validateRequired(valProblems, 'studyLevel', 'Current Study Level', data.studyLevel);\r\n VseValidation.validateRequired(valProblems, 'major', 'Major', data.major);\r\n VseValidation.validateRequired(valProblems, 'studyYear', 'Current Study Year', data.studyYear);\r\n\r\n return VseValidation.returnIfInvalid(valProblems);\r\n}\r\n\r\nexport function VseApplFormPersonalParticulars(props: VseApplFormPersonalParticularsProps) {\r\n const { familyName, firstName, middleName, emailAddress, homeUniversityStudentNumber, studyYear } = props.data;\r\n const studyLevel = props.studyLevelOptions.length > 0 ? props.data.studyLevel : '';\r\n const homeUniversityID = props.universityOptions.length > 0 ? props.data.homeUniversityID : '';\r\n const major = props.majorOptions.length > 0 ? props.data.major : '';\r\n const homeUniv = props.universityOptions.find((value) => value.universityID === homeUniversityID);\r\n const universityName = homeUniv ? homeUniv.universityName : '';\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 props.onChange({ familyName: ev.target.value })\r\n }\r\n />\r\n \r\n \r\n props.onChange({ firstName: ev.target.value })\r\n }\r\n />\r\n \r\n \r\n props.onChange({ middleName: ev.target.value })\r\n }\r\n />\r\n \r\n \r\n props.onChange({ homeUniversityStudentNumber: ev.target.value })\r\n }\r\n />\r\n \r\n \r\n \r\n \r\n props.onChange({ studyLevel: ev.target.value })\r\n }\r\n >\r\n {props.studyLevelOptions.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n props.onChange({ major: ev.target.value })\r\n }\r\n >\r\n {props.majorOptions.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n props.onChange({ studyYear: ev.target.value })\r\n }\r\n >\r\n {props.studyYearOptions.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport Checkbox from '@material-ui/core/Checkbox';\r\nimport Table from '@material-ui/core/Table';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport { CourseEntity, LanguageEntity, UniversityEntity } from '../types';\r\n\r\nexport interface VseApplFormCourseSelectionProps extends Pick, 'className'> {\r\n data: CourseEntity[],\r\n selected?: CourseEntity,\r\n onCourseFiltering: () => void,\r\n onCourseSelected: (selected: CourseEntity) => void,\r\n getUniversity: (id: number) => UniversityEntity | undefined,\r\n getLanguageEntity: (code: string) => LanguageEntity | undefined,\r\n}\r\n\r\nexport function VseApplFormCourseSelection(props: VseApplFormCourseSelectionProps) {\r\n\r\n function renderCourse(c: CourseEntity, i: number) {\r\n const isSelected = props.selected ?\r\n c.universityID === props.selected.universityID &&\r\n c.seasonID === props.selected.seasonID &&\r\n c.termCode === props.selected.termCode &&\r\n c.courseCode === props.selected.courseCode\r\n : false;\r\n const univ = props.getUniversity(c.universityID);\r\n const lang = props.getLanguageEntity(c.language);\r\n const termStart = c.universityTerm ? (new Intl.DateTimeFormat('en-GB')).format(c.universityTerm.startDate) : undefined;\r\n const termEnd = c.universityTerm ? (new Intl.DateTimeFormat('en-GB')).format(c.universityTerm.endDate) : undefined;\r\n const termPerid = c.universityTerm ? `${termStart} to ${termEnd}` : undefined;\r\n return (\r\n \r\n \r\n props.onCourseSelected(c)\r\n } />\r\n \r\n {univ?.universityName}\r\n {c.courseCode}\r\n {c.courseTitle}\r\n {new Intl.NumberFormat('en-GB', { minimumFractionDigits: 1 }).format(c.units)}\r\n {lang?.description}\r\n {termPerid}\r\n \r\n );\r\n }\r\n\r\n function renderCourses() {\r\n if (props.data && props.data.length > 0) {\r\n return props.data.map((c, i) => {\r\n return renderCourse(c, i);\r\n });\r\n }\r\n return undefined;\r\n }\r\n\r\n const [init, setInit] = React.useState(false);\r\n\r\n React.useEffect(() => {\r\n if (!init) {\r\n props.onCourseFiltering();\r\n setInit(true);\r\n }\r\n })\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n Select\r\n Course Offering University\r\n Course Code\r\n Course Title\r\n No. of Credits\r\n Language of Instruction\r\n Study Period\r\n \r\n \r\n \r\n {renderCourses()}\r\n \r\n
\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport Box from '@material-ui/core/Box';\r\nimport Checkbox from '@material-ui/core/Checkbox';\r\nimport Table from '@material-ui/core/Table';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport {\r\n ClassEntity,\r\n ClassComponentEntity,\r\n ClassComponentScheduleEntity,\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n} from '../types';\r\n\r\n// TODO: has runtime warning: Warning: Each child in a list should have a unique \"key\" prop.\r\n\r\nconst useStyles = makeStyles({\r\n classColumn: {\r\n verticalAlign: 'text-top',\r\n },\r\n compColumn: {\r\n verticalAlign: 'text-top',\r\n },\r\n});\r\n\r\ntype ClassSelectedHandler = (selected: ClassEntity) => void;\r\n\r\ntype TeachingModeDecoder = (code: string) => TeachingModeEntity | undefined;\r\n\r\ntype TimeZoneDecoder = (code: string) => TimeZoneEntity | undefined;\r\n\r\nexport interface VseApplFormClassSelectionProps extends Pick, 'className'> {\r\n data?: ClassEntity[],\r\n getTeachingMode: TeachingModeDecoder,\r\n getTimeZone: TimeZoneDecoder,\r\n onSelected: ClassSelectedHandler,\r\n}\r\n\r\nfunction renderOtherComponents(\r\n classes: ReturnType,\r\n getTeachingMode: TeachingModeDecoder,\r\n getTimeZone: TimeZoneDecoder,\r\n comp: ClassComponentEntity,\r\n schedules?: ClassComponentScheduleEntity[]) {\r\n\r\n const compSchedules = schedules?.filter((s => {\r\n return s.classID === comp.classID && s.componentID === comp.componentID;\r\n }));\r\n const classCompType = comp.componentType;\r\n const teachingMode = getTeachingMode(comp.teachingMode);\r\n\r\n return (\r\n \r\n {classCompType ? classCompType : undefined}\r\n {teachingMode ? teachingMode.description : undefined}\r\n \r\n {compSchedules?.map((s: ClassComponentScheduleEntity) => {\r\n const timeZone = getTimeZone(s.timeZoneCode);\r\n return ({s.description} {timeZone ? `(${timeZone.description})` : undefined});\r\n })}\r\n \r\n \r\n );\r\n}\r\n\r\nfunction renderClass(\r\n classes: ReturnType,\r\n getTeachingMode: TeachingModeDecoder,\r\n getTimeZone: TimeZoneDecoder,\r\n onClickedHandler: ClassSelectedHandler,\r\n aClass: ClassEntity,\r\n checked: boolean) {\r\n const [firstComp, ...otherComps] = aClass.classComponents ? aClass.classComponents : [];\r\n const firstCompSchedules = aClass.classComponentSchedules?.filter((s => {\r\n return s.classID === firstComp.classID && s.componentID === firstComp.componentID;\r\n }));\r\n const classCompType = firstComp ? firstComp.componentType : undefined;\r\n const teachingMode = firstComp ? getTeachingMode(firstComp.teachingMode) : undefined;\r\n return (\r\n \r\n \r\n \r\n {\r\n onClickedHandler(aClass);\r\n }} />\r\n \r\n {aClass.className}\r\n {classCompType}\r\n {teachingMode ? teachingMode.description : undefined}\r\n \r\n {firstCompSchedules?.map((s: ClassComponentScheduleEntity) => {\r\n const timeZone = getTimeZone(s.timeZoneCode);\r\n return ({s.description} {timeZone ? `(${timeZone.description})` : undefined});\r\n })}\r\n \r\n \r\n {otherComps.map((comp) => (\r\n renderOtherComponents(classes, getTeachingMode, getTimeZone, comp, aClass.classComponentSchedules)\r\n ))}\r\n \r\n );\r\n}\r\n\r\nexport function VseApplFormClassSelection(props: VseApplFormClassSelectionProps) {\r\n const classes = useStyles();\r\n const [selected, setSelected] = React.useState();\r\n\r\n const handler: ClassSelectedHandler = (c) => {\r\n setSelected(c);\r\n props.onSelected(c);\r\n }\r\n return (\r\n
\r\n \r\n \r\n \r\n Select\r\n Class\r\n Component\r\n Mode of Teaching\r\n Schedule\r\n \r\n \r\n {props.data?.map((aClass) => {\r\n const checked = (aClass.classID === selected?.classID);\r\n return renderClass(classes, props.getTeachingMode, props.getTimeZone, handler, aClass, checked);\r\n })}\r\n
\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport Button from '@material-ui/core/Button';\r\nimport Card from '@material-ui/core/Card';\r\nimport CardActions from '@material-ui/core/CardActions';\r\nimport CardContent from '@material-ui/core/CardContent';\r\nimport CardHeader from '@material-ui/core/CardHeader';\r\nimport FormLabel from '@material-ui/core/FormLabel';\r\nimport LinearProgress from '@material-ui/core/LinearProgress';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport clsx from 'clsx';\r\nimport filesize from 'filesize';\r\nimport {\r\n DotNetValidationProblemDetailsTyped,\r\n VseApplicationEntity,\r\n} from '../types';\r\nimport * as VseValidation from '../utils/validate';\r\n\r\nexport type VseApplFormDocumentEventHandler = (documentType: string, file: File, requestId?: string, fileID?: string) => void;\r\n\r\nexport interface VseApplFormDocumentUploadProps extends React.HTMLAttributes {\r\n requestId?: string,\r\n fileID?: string,\r\n documentType: string,\r\n title: string,\r\n required: boolean,\r\n uploading: boolean,\r\n uploaded: boolean,\r\n accept: Array,\r\n onDocumentCancel: VseApplFormDocumentEventHandler,\r\n onDocumentUpload: VseApplFormDocumentEventHandler,\r\n onValidationProblem: (valProblems: DotNetValidationProblemDetailsTyped) => void,\r\n}\r\n\r\nconst useStyles = makeStyles({\r\n hidden: {\r\n display: 'none',\r\n },\r\n});\r\n\r\nexport function VseApplFormDocumentUpload(props: VseApplFormDocumentUploadProps) {\r\n function handleChange(ev: React.ChangeEvent, setFile: React.Dispatch>) {\r\n let valProblems: DotNetValidationProblemDetailsTyped | undefined = VseValidation.createValidationProblemDetails();\r\n const files: FileList | null = ev.target.files;\r\n\r\n if (files && files.length === 1) {\r\n const file: File = files[0];\r\n if (!props.accept.find((type) => type === file.type)) {\r\n VseValidation.appendErrorTo(valProblems, `document[${props.title}]`, 'Invalid document type');\r\n }\r\n // Max size: 2MB\r\n if (file.size > (2 * 1024 * 1024)) {\r\n VseValidation.appendErrorTo(valProblems, `document[${props.title}]`, 'Document size is larger than 2Mb');\r\n }\r\n\r\n if (VseValidation.isValid(valProblems)) {\r\n setFile(file);\r\n props.onDocumentUpload(props.documentType, file);\r\n } else {\r\n props.onValidationProblem(valProblems);\r\n }\r\n }\r\n }\r\n\r\n function handleCancel(file: File | undefined, setFile: React.Dispatch>) {\r\n if (file) {\r\n props.onDocumentCancel(props.documentType, file, props.requestId);\r\n setFile(undefined);\r\n }\r\n }\r\n\r\n function renderFile(file: File | undefined) {\r\n return file ? (\r\n \r\n {file.name}\r\n {filesize(file.size)}\r\n \r\n ) : ;\r\n }\r\n\r\n const classes = useStyles();\r\n const title = (\r\n {props.title}\r\n );\r\n const [file, setFile] = React.useState();\r\n\r\n return (\r\n \r\n \r\n \r\n {renderFile(file)}\r\n {props.uploading ? (\r\n \r\n ): undefined}\r\n \r\n \r\n \r\n handleChange(ev, setFile)\r\n }\r\n hidden\r\n />\r\n Choose file\r\n \r\n handleCancel(file, setFile)}\r\n >Cancel\r\n \r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport Grid, { GridProps } from '@material-ui/core/Grid';\r\nimport { VseApplFormDocumentUpload, VseApplFormDocumentEventHandler } from './VseApplFormDocumentUpload';\r\nimport { VseApplFormDocumentUploadHandle } from '../types/VseApplFormDocumentUploadHandle';\r\nimport {\r\n DotNetValidationProblemDetailsTyped,\r\n VseApplicationEntity,\r\n VseApplFormDocumentUploadConfig,\r\n} from '../types';\r\n\r\nexport interface VseApplFormDocumentChangeEvent {\r\n event: React.ChangeEvent,\r\n config: VseApplFormDocumentUploadConfig,\r\n}\r\n\r\nexport type VseApplFormDocumentChangeEventHandler = (event: VseApplFormDocumentChangeEvent) => void;\r\n\r\nexport interface VseApplFormDocumentCancelEvent {\r\n event: React.MouseEvent,\r\n config: VseApplFormDocumentUploadConfig,\r\n}\r\n\r\nexport type VseApplFormDocumentCancelEventHandler = (event: VseApplFormDocumentCancelEvent) => void;\r\n\r\nexport interface VseApplFormDocumentSelectionProps extends GridProps {\r\n handles: Array,\r\n onDocumentUpload: VseApplFormDocumentEventHandler,\r\n onDocumentCancel: VseApplFormDocumentEventHandler,\r\n onValidationProblem: (valProblems: DotNetValidationProblemDetailsTyped) => void,\r\n}\r\n\r\nexport function VseApplFormDocumentSelection(props: VseApplFormDocumentSelectionProps) {\r\n\r\n const uploads = props.handles.map((handle, index) => {\r\n return (\r\n \r\n \r\n \r\n );\r\n });\r\n return (\r\n \r\n {uploads}\r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Box from '@material-ui/core/Box';\r\nimport Button from '@material-ui/core/Button';\r\nimport CheckCircleRoundedIcon from '@material-ui/icons/CheckCircleRounded';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Portal from '@material-ui/core/Portal';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport {\r\n DotNetValidationProblemDetailsTyped,\r\n CourseEntity,\r\n ClassEntity,\r\n LanguageEntity,\r\n MajorEntity,\r\n StudyLevelEntity,\r\n StudyYearEntity,\r\n UniversityEntity,\r\n UniversityOpeningForOutogingEntity,\r\n VseApplicationEntity,\r\n VseApplicationClassEntity,\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n SeasonMessageEntity,\r\n} from '../types';\r\nimport * as VseValidation from '../utils/validate';\r\nimport { VseApplFormPersonalParticulars, validatePersonalParticulars } from './VseApplFormPersonalParticulars';\r\nimport { VseApplFormCourseSelection } from './VseApplFormCourseSelection';\r\nimport { VseApplFormClassSelection } from './VseApplFormClassSelection';\r\nimport {\r\n VseApplFormDocumentSelection,\r\n} from './VseApplFormDocumentSelection';\r\nimport {\r\n VseApplFormDocumentEventHandler\r\n} from './VseApplFormDocumentUpload'\r\nimport { VseApplFormDocumentUploadHandle } from '../types/VseApplFormDocumentUploadHandle';\r\nimport { VseApplicationDocumentEntity } from '../types/VseApplicationDocumentEntity';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n backButton: {\r\n marginRight: theme.spacing(1),\r\n },\r\n buttonsBottom: {\r\n marginTop: theme.spacing(1),\r\n },\r\n form: {\r\n padding: theme.spacing(2),\r\n },\r\n paper: {\r\n padding: theme.spacing(1),\r\n margin: 'auto',\r\n overflow: 'hidden',\r\n },\r\n progressBar: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: theme.palette.primary.contrastText,\r\n borderBottom: '1px solid rgba(0, 0, 0, 0.12)',\r\n },\r\n root: {\r\n height: '100%',\r\n },\r\n stepCaption: {\r\n fontSize: '0.7rem',\r\n },\r\n stepInstructions: {\r\n margin: theme.spacing(1),\r\n },\r\n hidden: {\r\n display: 'none',\r\n }\r\n}));\r\n\r\nexport interface VseNewApplFormProps {\r\n subHeaderRef: React.RefObject,\r\n season: UniversityOpeningForOutogingEntity,\r\n seasonMessages: SeasonMessageEntity[],\r\n application: VseApplicationEntity,\r\n filteredCourses: CourseEntity[],\r\n classesOfCourseSelected?: ClassEntity[],\r\n languageOptions: LanguageEntity[],\r\n majorOptions: MajorEntity[],\r\n studyLevelOptions: StudyLevelEntity[],\r\n studyYearOptions: StudyYearEntity[],\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n universityOptions: UniversityEntity[],\r\n onSubmit: (appl: VseApplicationEntity) => void,\r\n onCourseFiltering: () => void,\r\n onCourseSelected: (selected: CourseEntity) => void,\r\n documentHandles: Array,\r\n onDocumentUpload: VseApplFormDocumentEventHandler,\r\n onDocumentCancel: VseApplFormDocumentEventHandler,\r\n onValidationProblem: (valProblems: DotNetValidationProblemDetailsTyped) => void,\r\n onNextStep: () => void,\r\n};\r\n\r\nexport function VseNewApplForm(props: VseNewApplFormProps) {\r\n function getLanguageEntity(code: string): LanguageEntity | undefined {\r\n return props.languageOptions.find((e) => e.code === code);\r\n }\r\n\r\n function getTeachingMode(code: string): TeachingModeEntity | undefined {\r\n return props.teachingModeOptions.find((e) => e.code === code);\r\n }\r\n\r\n function getTimeZone(code: string): TimeZoneEntity | undefined {\r\n return props.timeZoneOptions.find((e) => e.code === code);\r\n }\r\n\r\n function getUniversityEntity(id: number): UniversityEntity | undefined {\r\n return props.universityOptions.find((e) => e.universityID === id);\r\n }\r\n\r\n function getSeasonMessageEntity(code: string) {\r\n const msg = props.seasonMessages.find(e => {\r\n return e.sectionCode.trimEnd() === 'APPL'\r\n && e.messageCode.trimEnd() === code;\r\n });\r\n return msg ? (\r\n
\r\n ) : undefined;\r\n }\r\n\r\n function handleNextStepClick() {\r\n let valProblems: DotNetValidationProblemDetailsTyped = VseValidation.createValidationProblemDetails();\r\n switch (activeStep) {\r\n case 0:\r\n validatePersonalParticulars(valProblems, applState);\r\n break;\r\n case 1:\r\n if (!courseSelected) {\r\n VseValidation.appendErrorTo(valProblems, \"courseSelected\", \"Please select 1 course\");\r\n }\r\n break;\r\n case 2:\r\n if (applState.classes.length === 0) {\r\n VseValidation.appendErrorTo(valProblems, \"classes\", \"Please select 1 class\");\r\n }\r\n break;\r\n case 3:\r\n const documents = props.documentHandles.filter(d => d.uploading || (d.config.required && !d.uploaded));\r\n documents.forEach(d => {\r\n if (d.uploading) {\r\n VseValidation.appendErrorTo(valProblems, \"documents\", `${d.config.title} is being uploaded, please wait`);\r\n } else if (d.config.required && !d.uploaded) {\r\n VseValidation.appendErrorTo(valProblems, \"documents\", `Please upload ${d.config.title}`);\r\n }\r\n })\r\n break;\r\n }\r\n\r\n if (VseValidation.isValid(valProblems)) {\r\n props.onNextStep();\r\n setActiveStep((prevActiveStep) => prevActiveStep + 1);\r\n } else {\r\n props.onValidationProblem(valProblems);\r\n }\r\n }\r\n\r\n function getInstruction(step: number) {\r\n const code = 'STEP.' + (step + 1).toString();\r\n return (step !== 4) ? getSeasonMessageEntity(code) : undefined;\r\n }\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const [applState, setApplState] = React.useState(props.application);\r\n const [courseSelected, setCourseSelected] = React.useState();\r\n\r\n const steps = [\r\n 'Personal Particulars',\r\n 'Course Selection',\r\n 'Class Selection',\r\n 'Document(s) Upload',\r\n 'Confirmation'\r\n ];\r\n\r\n const [activeStep, setActiveStep] = React.useState(0);\r\n\r\n const btnNextOrSubmit = (activeStep === steps.length - 1 ? (\r\n \r\n ) : (\r\n {\r\n handleNextStepClick();\r\n }}\r\n >Next\r\n )\r\n );\r\n\r\n // TODO: Move progress bar to new element\r\n return (\r\n
\r\n \r\n \r\n \r\n New Application for {props.season.description}\r\n \r\n \r\n \r\n
\r\n Instruction(s)\r\n {getInstruction(activeStep)}\r\n
\r\n \r\n \r\n \r\n \r\n \r\n {activeStep === steps.length ? : (\r\n \r\n \r\n \r\n \r\n {`${activeStep + 1} of ${steps.length}`}\r\n \r\n \r\n \r\n )}\r\n \r\n \r\n \r\n {`${steps[activeStep] ? steps[activeStep] : 'Success'}`}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n setApplState((prev) => {\r\n return { ...prev, ...changes };\r\n })}\r\n />\r\n {\r\n setCourseSelected(c);\r\n props.onCourseSelected(c);\r\n }}\r\n getUniversity={getUniversityEntity}\r\n getLanguageEntity={getLanguageEntity}\r\n />\r\n setApplState((prev) => {\r\n const vseApplClass: VseApplicationClassEntity = {\r\n applicationID: applState.applicationID,\r\n classID: c.classID,\r\n };\r\n return { ...prev, classes: [vseApplClass] };\r\n })}\r\n />\r\n \r\n
\r\n {getSeasonMessageEntity('STEP.5')}\r\n
\r\n
\r\n All steps completed\r\n
\r\n \r\n
\r\n
\r\n {\r\n setActiveStep((prev) => prev - 1);\r\n }}\r\n >Back\r\n {activeStep < steps.length ? btnNextOrSubmit : undefined}\r\n
\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme } from '@material-ui/core/styles';\r\nimport clsx from 'clsx';\r\nimport Box from '@material-ui/core/Box';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport TextField from '@material-ui/core/TextField';\r\n//import Checkbox from '@material-ui/core/Checkbox';\r\nimport Table from '@material-ui/core/Table';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport {\r\n ClassEntity,\r\n ClassComponentEntity,\r\n ClassComponentScheduleEntity,\r\n CourseEntity, UniversityEntity,\r\n TeachingModeEntity,\r\n TimeZoneEntity\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n classColumn: {\r\n verticalAlign: 'text-top',\r\n },\r\n compColumn: {\r\n verticalAlign: 'text-top',\r\n },\r\n tableTitle: {\r\n marginLeft: theme.spacing(-1),\r\n },\r\n}));\r\n\r\n//type ClassSelectedHandler = (selected: ClassEntity) => void;\r\n\r\nexport interface VseApplFormApplClassProps extends Pick, 'className'> {\r\n data?: ClassEntity[],\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n //getCourse: (seasonID: number, univID: number, termcode: string, code: string) => CourseEntity | undefined,\r\n getCourse: (code: string) => CourseEntity | undefined,\r\n getUniversity: (id: number) => UniversityEntity | undefined,\r\n applscourse?: CourseEntity[];\r\n //onSelected: ClassSelectedHandler,\r\n}\r\n\r\nfunction getTeachingMode(code: string, props: VseApplFormApplClassProps): string {\r\n const tm = props.teachingModeOptions.find((e) => e.code === code);\r\n const tmDescr = (tm === undefined ? code : tm.description);\r\n return tmDescr;\r\n}\r\n\r\nfunction getTimeZone(code: string, props: VseApplFormApplClassProps): string {\r\n const tz = props.timeZoneOptions.find((e) => e.code === code);\r\n const tzDescr = (tz === undefined ? code : tz.description);\r\n return tzDescr;\r\n}\r\n\r\nfunction renderOtherComponents(props: VseApplFormApplClassProps, classes: ReturnType, comp: ClassComponentEntity, schedules?: ClassComponentScheduleEntity[]) {\r\n const compSchedules = schedules?.filter((s => {\r\n return s.classID === comp.classID && s.componentID === comp.componentID;\r\n }));\r\n return (\r\n \r\n {comp.componentType}\r\n {getTeachingMode(comp.teachingMode, props)} \r\n \r\n {compSchedules?.map((s: ClassComponentScheduleEntity) => (\r\n \r\n {(s.description === null || s.timeZoneCode === null || s.description.trim().length === 0 || s.description.trim() === 'TBC' || s.description.trim() === 'TBA') ?\r\n (s.description) :\r\n (clsx(`${s.description}`, `(${getTimeZone(s.timeZoneCode, props)})`))\r\n }\r\n \r\n ))}\r\n \r\n \r\n );\r\n}\r\n\r\nfunction renderClass(props: VseApplFormApplClassProps, classes: ReturnType, aClass: ClassEntity) {\r\n const [firstComp, ...otherComps] = aClass.classComponents ? aClass.classComponents : [];\r\n const firstCompSchedules = aClass.classComponentSchedules?.filter((s => {\r\n return s.classID === firstComp.classID && s.componentID === firstComp.componentID;\r\n }));\r\n return (\r\n \r\n \r\n {firstComp.componentType}\r\n {getTeachingMode(firstComp.teachingMode, props)} \r\n \r\n {firstCompSchedules?.map((s: ClassComponentScheduleEntity) => (\r\n \r\n {(s.description === null || s.timeZoneCode === null || s.description.trim().length === 0 || s.description.trim() === 'TBC' || s.description.trim() === 'TBA') ?\r\n (s.description) :\r\n (clsx(`${s.description}`, `(${getTimeZone(s.timeZoneCode, props)})`))\r\n }\r\n \r\n ))}\r\n \r\n \r\n {otherComps.map((comp) => (\r\n renderOtherComponents(props, classes, comp, aClass.classComponentSchedules)\r\n ))}\r\n \r\n );\r\n}\r\n\r\nfunction renderClassInfo(aClass: ClassEntity, props: VseApplFormApplClassProps) {\r\n const univ = props.getUniversity(aClass.universityID);\r\n //const course = props.getCourse(aClass.seasonID, aClass.universityID, aClass.termCode, aClass.courseCode );\r\n const course = props.getCourse(aClass.courseCode);\r\n const courseTitle = course ? course.courseTitle : '';\r\n const offerUniversityTerm = course?.universityTerm ? course.universityTerm.description : '';\r\n const offerUniversity = univ ? univ.universityName : '';\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 \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport function VseApplFormApplClass(props: VseApplFormApplClassProps) {\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n {props.data?.map((aClass) => {\r\n return renderClassInfo(aClass, props);\r\n })}\r\n
\r\n Class Detail\r\n
\r\n \r\n \r\n \r\n Component\r\n Mode of Teaching\r\n Schedule\r\n \r\n \r\n {props.data?.map((aClass) => {\r\n return renderClass(props, classes, aClass);\r\n })}\r\n
\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport { VseApplicationEntity, MajorEntity, StudyLevelEntity, StudyYearEntity, UniversityEntity, ApplStatusEntity, ClassEntity, CourseEntity, TeachingModeEntity, SeasonEntity, TimeZoneEntity } from '../types';\r\nimport { VseApplFormPersonalParticularsReadyOnly } from './VseApplFormPersonalParticularsReadyOnly';\r\nimport { VseApplFormApplicationStatus } from './VseApplFormApplicationStatus';\r\nimport { VseApplFormApplClass } from './VseApplFormApplClass';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n backButton: {\r\n marginRight: theme.spacing(1),\r\n },\r\n buttonsTop: {\r\n backgroundColor: 'inherit',\r\n },\r\n form: {\r\n paddingTop: theme.spacing(1.5),\r\n paddingBottom: theme.spacing(1),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(2),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n overflow: 'hidden',\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n approvalSection: {\r\n backgroundColor: theme.palette.common.white,\r\n paddingTop: theme.spacing(0),\r\n paddingBottom: theme.spacing(0),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(1.5),\r\n height: '100%',\r\n },\r\n infoSection: {\r\n paddingTop: theme.spacing(2.5),\r\n paddingBottom: theme.spacing(0),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(1.5),\r\n height: '100%',\r\n },\r\n classSection: {\r\n paddingTop: theme.spacing(0),\r\n paddingBottom: theme.spacing(0),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(1.5),\r\n height: '100%',\r\n },\r\n secondaryBar: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: theme.palette.primary.contrastText,\r\n borderBottom: '1px solid rgba(0, 0, 0, 0.12)',\r\n },\r\n sectionTitle: {\r\n marginLeft: theme.spacing(-1),\r\n paddingBottom: theme.spacing(1.5),\r\n },\r\n uphead: {\r\n textTransform: \"uppercase\",\r\n },\r\n root: {\r\n height: '100%',\r\n },\r\n stepCaption: {\r\n fontSize: '0.7rem',\r\n },\r\n stepInstructions: {\r\n marginTop: theme.spacing(1),\r\n marginBottom: theme.spacing(1),\r\n },\r\n hidden: {\r\n display: 'none',\r\n },\r\n headingContainer: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n marginBottom: theme.spacing(1),\r\n paddingLeft: theme.spacing(3),\r\n paddingRight: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport interface VseApplFormProps {\r\n application: VseApplicationEntity,\r\n classesOfApplicationSelected?: ClassEntity[],\r\n coursesOfApplicationSelected?: CourseEntity[],\r\n majorOptions: MajorEntity[],\r\n studyLevelOptions: StudyLevelEntity[],\r\n studyYearOptions: StudyYearEntity[],\r\n universityOptions: UniversityEntity[],\r\n seasonOptions: SeasonEntity[],\r\n applStatusOptions: ApplStatusEntity[],\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n onChange: (changes: Pick,\r\n 'submissionDate' |\r\n 'endorsedDate' |\r\n 'approvalDate' |\r\n 'withdrawalDate' |\r\n 'adminRemark' |\r\n 'status'>) => void,\r\n};\r\n\r\nexport function VseApplForm(props: VseApplFormProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n function getUniversityEntity(id: number): UniversityEntity | undefined {\r\n return props.universityOptions.find((e) => e.universityID === id);\r\n }\r\n\r\n function getCourse(code: string): CourseEntity | undefined {\r\n return props.coursesOfApplicationSelected?.find((e) => e.courseCode === code);\r\n }\r\n\r\n const displayContent = () => {\r\n return \r\n }\r\n\r\n return (\r\n
\r\n \r\n
\r\n
\r\n
\r\n Application Status\r\n
\r\n {\r\n props.onChange(changes);\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n Personal Particulars\r\n
\r\n {displayContent()}\r\n
\r\n
\r\n
\r\n Class Selection\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n","import { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport React from 'react';\r\nimport Box from '@material-ui/core/Box';\r\nimport clsx from 'clsx';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Button from '@material-ui/core/Button';\r\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n backButton: {\r\n marginRight: theme.spacing(1),\r\n },\r\n buttonsTop: {\r\n backgroundColor: 'inherit',\r\n },\r\n buttonSection: {\r\n margin: 'auto',\r\n paddingTop: theme.spacing(1.5),\r\n paddingBottom: theme.spacing(1.5),\r\n overflow: 'hidden',\r\n backgroundColor: theme.palette.common.white,\r\n },\r\n root: {\r\n height: '100%',\r\n },\r\n hidden: {\r\n display: 'none',\r\n },\r\n}));\r\n\r\nexport interface VseCourseNewButtonsProps {\r\n viewOnly: boolean,\r\n onBackClick: () => void,\r\n onSaveClick: () => void,\r\n};\r\n\r\nexport function VseCourseNewButtons(props: VseCourseNewButtonsProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const showSaveButton = (props.viewOnly || (props.viewOnly === undefined)) ? false : true;\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 );\r\n}\r\n","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { makeStyles, Theme } from '@material-ui/core/styles';\r\nimport { InputProps as StandardInputProps } from '@material-ui/core/Input';\r\n\r\ninterface VseHtmlInputProps extends StandardInputProps {\r\n}\r\n\r\nconst useStyles = makeStyles(() => ({\r\n input: {\r\n display: 'none',\r\n },\r\n content: {\r\n height: 'auto',\r\n minHeight: (props) => `${(props.rows * 1.1875)}em`,\r\n '& > p:first-child ': {\r\n marginTop: 'auto',\r\n },\r\n '& > p:last-child ': {\r\n marginBottom: 'auto',\r\n },\r\n }\r\n}));\r\n\r\nexport function VseHtmlInput(props: VseHtmlInputProps) {\r\n const {\r\n value = \"\",\r\n rows = 1,\r\n onChange,\r\n } = props;\r\n const classes = useStyles({ rows: rows as number });\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport Input from '@material-ui/core/Input';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport { TextFieldProps, IconButtonProps } from '@material-ui/core';\r\nimport { VseHtmlInput } from './VseHtmlInput';\r\nimport { VseTinymceEditorDialogArgs } from './VseTinymceEditorDialog';\r\n\r\nconst useStyles = makeStyles(() => ({\r\n editButton: {\r\n position: 'absolute',\r\n top: 0,\r\n right: 0,\r\n }\r\n}));\r\n\r\ninterface VseHtmlFieldProps {\r\n mode: VseTinymceEditorDialogArgs['mode'],\r\n iconColor?: IconButtonProps['color'],\r\n iconSize?: IconButtonProps['size'],\r\n instruction?: VseTinymceEditorDialogArgs['instruction'],\r\n onEditorDialogReqested?: (args: VseTinymceEditorDialogArgs) => void,\r\n onUpdated: (content?: string) => void,\r\n}\r\n\r\n// reference: https://github.com/mui/material-ui/blob/v4.12.4/packages/material-ui/src/TextField/TextField.js\r\nexport function VseHtmlField(props: TextFieldProps & VseHtmlFieldProps) {\r\n const classes = useStyles();\r\n const {\r\n autoComplete,\r\n autoFocus = false,\r\n children,\r\n className,\r\n color = 'primary',\r\n defaultValue,\r\n disabled = false,\r\n error = false,\r\n FormHelperTextProps,\r\n fullWidth = false,\r\n helperText,\r\n hiddenLabel,\r\n iconColor = 'secondary',\r\n iconSize = 'small',\r\n id,\r\n InputLabelProps,\r\n inputProps,\r\n InputProps,\r\n inputRef,\r\n label,\r\n multiline = false,\r\n name,\r\n onBlur,\r\n onChange,\r\n onFocus,\r\n placeholder,\r\n ref,\r\n required = false,\r\n rows = 1,\r\n rowsMax,\r\n maxRows,\r\n minRows,\r\n select = false,\r\n SelectProps,\r\n type,\r\n value,\r\n variant = 'standard',\r\n ...other\r\n } = props;\r\n const {\r\n instruction = `Please input ${label}`,\r\n onEditorDialogReqested = () => void 0,\r\n onUpdated = () => void 0,\r\n } = props;\r\n const helperTextId = helperText && id ? `${id}-helper-text` : undefined;\r\n const inputLabelId = label && id ? `${id}-label` : undefined;\r\n\r\n return (\r\n \r\n \r\n {label}\r\n \r\n \r\n {helperText && (\r\n \r\n {helperText}\r\n \r\n )}\r\n {\r\n onEditorDialogReqested({\r\n open: true,\r\n mode: props.mode,\r\n title: label,\r\n instruction: instruction,\r\n value: value as string,\r\n onUpdate: (content) => onUpdated(content),\r\n });\r\n }}>\r\n \r\n );\r\n};\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport { VseHtmlField } from '../VseHtml/VseHtmlField';\r\nimport { VseTinymceEditorDialog, VseTinymceEditorDialogProps } from '../VseHtml/VseTinymceEditorDialog';\r\nimport { VseCourseEditTemplate } from '../types/VseCourseEditTemplate';\r\nimport {\r\n CourseStatusEntity,\r\n LanguageEntity,\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(1),\r\n },\r\n numberItem: {\r\n textAlign: 'right',\r\n },\r\n}));\r\n\r\nexport type CourseErrorKeyResolver = (key: keyof VseCourseEditTemplate) => string;\r\n\r\nexport interface VseCourseEditGridProps {\r\n data: VseCourseEditTemplate,\r\n decodeSeason: (id: number) => string | undefined,\r\n decodeUniversity: (id: number) => string | undefined,\r\n decodeUniversityTerm: (seasonID: number, universityID: number, termCode: string) => string | undefined,\r\n courseStatusOptions: CourseStatusEntity[],\r\n languageOptions: LanguageEntity[],\r\n onChange: (changes: Partial) => void,\r\n resolveCourseErrorKey: CourseErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n}\r\n\r\nexport function VseCourseEditGrid(props: VseCourseEditGridProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dateTimeFormatOptions = {\r\n year: 'numeric', month: '2-digit', day: '2-digit'\r\n };\r\n const firstDayOfClass = props.data.firstDayOfClass ? (new Intl.DateTimeFormat('en-CA', dateTimeFormatOptions)).format(new Date(props.data.firstDayOfClass)).replace(',', '') : null;\r\n const lastDayOfClass = props.data.lastDayOfClass ? (new Intl.DateTimeFormat('en-CA', dateTimeFormatOptions)).format(new Date(props.data.lastDayOfClass)).replace(',', '') : null;\r\n const units = parseFloat(props.data.units).toFixed(2);\r\n const teachHrsPerUnit = parseFloat(props.data.teachHrsPerUnit).toFixed(2);\r\n const coursePlaces = parseInt(props.data.coursePlaces).toString();\r\n\r\n const [editorProps, setEditorProps] = React.useState({\r\n open: false,\r\n });\r\n\r\n function hasError(key: keyof VseCourseEditTemplate): boolean {\r\n if (props.valProblemKeys) {\r\n const searchElement = props.resolveCourseErrorKey(key);\r\n return props.valProblemKeys.includes(searchElement);\r\n }\r\n return false;\r\n }\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 \r\n \r\n \r\n props.onChange({ courseCode: e.target.value })}\r\n error={hasError('courseCode')}\r\n />\r\n \r\n \r\n props.onChange({ courseTitle: e.target.value })}\r\n error={hasError('courseTitle')}\r\n />\r\n \r\n \r\n props.onChange({ statusCode: e.target.value })}\r\n error={hasError('statusCode')}\r\n >\r\n {props.courseStatusOptions.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n \r\n \r\n props.onChange({ offerUnit: e.target.value })}\r\n error={hasError('offerUnit')}\r\n />\r\n \r\n \r\n props.onChange({ courseTeacher: e.target.value })}\r\n error={hasError('courseTeacher')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ teacherProfile: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('teacherProfile')}\r\n />\r\n \r\n \r\n \r\n \r\n props.onChange({ units: e.target.value })}\r\n error={hasError('units')}\r\n />\r\n \r\n \r\n props.onChange({ teachHrsPerUnit: e.target.value })}\r\n error={hasError('teachHrsPerUnit')}\r\n />\r\n \r\n \r\n props.onChange({ coursePlaces: e.target.value })}\r\n error={hasError('coursePlaces')}\r\n />\r\n \r\n \r\n props.onChange({ language: e.target.value })}\r\n error={hasError('language')}\r\n >\r\n {props.languageOptions.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n props.onChange({ firstDayOfClass: e.target.value })}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={hasError('firstDayOfClass')}\r\n />\r\n \r\n \r\n props.onChange({ lastDayOfClass: e.target.value })}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={hasError('lastDayOfClass')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ courseLink: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('courseLink')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ courseDescription: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('courseDescription')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ courseRestriction: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('courseRestriction')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ pointNotes: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('pointNotes')}\r\n />\r\n \r\n \r\n \r\n \r\n {\r\n props.onChange({ feeByStudents: content });\r\n setEditorProps({ open: false });\r\n }}\r\n onEditorDialogReqested={(args) => {\r\n setEditorProps({\r\n open: args.open,\r\n onOpen: (openArgs) => Object.assign(openArgs, args),\r\n });\r\n }}\r\n error={hasError('feeByStudents')}\r\n />\r\n \r\n \r\n \r\n setEditorProps({ open: false })} />\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport { VseCourseEditTemplate } from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(1),\r\n },\r\n}));\r\n\r\nexport interface VseCourseHeaderGridProps {\r\n data: VseCourseEditTemplate,\r\n decodeSeason: (id: number) => string | undefined,\r\n decodeUniversity: (id: number) => string | undefined,\r\n decodeUniversityTerm: (seasonID: number, universityID: number, termCode: string) => string | undefined,\r\n decodeCourseStatus: (code: string) => string | undefined,\r\n}\r\n\r\nexport function VseCourseHeaderGrid(props: VseCourseHeaderGridProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const courseCode = props.data.courseCode ? props.data.courseCode : '';\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 \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
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport clsx from 'clsx';\r\nimport AddIcon from '@material-ui/icons/AddCircleOutline';\r\nimport DeleteIcon from '@material-ui/icons/RemoveCircleOutline';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport Table from '@material-ui/core/Table';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport { VseClassComponentEditTemplate, VseClassComponentScheduleEditTemplate } from \"../types/VseClassEditTemplate\";\r\nimport {\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles(() => ({\r\n row: {\r\n verticalAlign: 'text-top',\r\n },\r\n cellComponentType: {\r\n width: '30%',\r\n },\r\n cellTeachingMode: {\r\n width: '16%',\r\n },\r\n cellSchedule: {\r\n width: '30%',\r\n },\r\n cellTimeZone: {\r\n width: '15%',\r\n },\r\n hidden: {\r\n display: 'none',\r\n },\r\n}));\r\n\r\nexport type ComponentErrorKeyResolver = (index: number, key: keyof VseClassComponentEditTemplate) => string;\r\n\r\nexport type ComponentScheduleErrorKeyResolver = (index: number, scheduleIndex: number, key: keyof VseClassComponentScheduleEditTemplate) => string;\r\n\r\nlet teachingModes: TeachingModeEntity[] = [];\r\nlet tzCodes: TimeZoneEntity[] = [];\r\n\r\nexport interface VseClassComponentEditTableProps {\r\n list: Array,\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n onChange: (compIndex: number, changes: Partial) => void\r\n onAdd: () => void,\r\n onDelete: (compIndex: number) => void,\r\n onScheduleChange: (compIndex: number, schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: (compIndex: number) => void,\r\n onScheduleDelete: (compIndex: number, schdIndex: number) => void,\r\n resolveComponentErrorKey: ComponentErrorKeyResolver,\r\n resolveComponentScheduleErrorKey: ComponentScheduleErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n}\r\n\r\nfunction renderScheduleCells(\r\n classes: ReturnType,\r\n schedule: VseClassComponentScheduleEditTemplate,\r\n onChange: (changes: Partial) => void,\r\n onAdd: () => void,\r\n onDelete: () => void,\r\n index: number,\r\n last: boolean,\r\n resolveScheduleErrorKey: (index: number, key: keyof VseClassComponentScheduleEditTemplate) => string,\r\n valProblemKeys?: Array,\r\n) {\r\n function hasError(key: keyof VseClassComponentScheduleEditTemplate): boolean {\r\n if(valProblemKeys){\r\n const searchElement: string = resolveScheduleErrorKey(index, key);\r\n return valProblemKeys.includes(searchElement);\r\n }\r\n return false;\r\n }\r\n return (\r\n \r\n \r\n onAdd()}\r\n >\r\n \r\n \r\n onDelete()}\r\n >\r\n \r\n \r\n \r\n \r\n onChange({ description: e.target.value })}\r\n error={hasError('description')}\r\n />\r\n \r\n \r\n onChange({ tzCode: e.target.value })}\r\n error={hasError('tzCode')}\r\n >\r\n {tzCodes.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nfunction renderComponent(\r\n classes: ReturnType,\r\n component: VseClassComponentEditTemplate,\r\n onChange: (changes: Partial) => void,\r\n onAdd: () => void,\r\n onDelete: () => void,\r\n onScheduledChange: (schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: () => void,\r\n onScheduleDelete: (schdIndex: number) => void,\r\n index: number,\r\n last: boolean,\r\n resolveComponentErrorKey: ComponentErrorKeyResolver,\r\n resolveComponentScheduleErrorKey: ComponentScheduleErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n\r\n) {\r\n function hasError(key: keyof VseClassComponentEditTemplate): boolean {\r\n if (valProblemKeys) {\r\n const searchElement: string = resolveComponentErrorKey(index, key);\r\n return valProblemKeys.includes(searchElement);\r\n }\r\n return false;\r\n }\r\n const [firstSchd, ...otherSchd] = component.schedule;\r\n return (\r\n \r\n \r\n \r\n onAdd()}\r\n >\r\n \r\n \r\n onDelete()}\r\n >\r\n \r\n \r\n \r\n \r\n onChange({ componentType: e.target.value })}\r\n error={hasError('componentType')}\r\n />\r\n \r\n \r\n onChange({ teachingMode: e.target.value })}\r\n error={hasError('teachingMode')}\r\n >\r\n {teachingModes.map((option) => (\r\n \r\n {option.description}\r\n \r\n ))}\r\n \r\n \r\n {renderScheduleCells(classes, firstSchd, (changes) => onScheduledChange(0, changes), onScheduleAdd, () => onScheduleDelete(0), 0, otherSchd.length === 0, (scheduleIndex, key) => resolveComponentScheduleErrorKey(index, scheduleIndex, key), valProblemKeys)}\r\n \r\n {otherSchd.map((value, j) =>\r\n \r\n {renderScheduleCells(classes, value, (changes) => onScheduledChange(j + 1, changes), onScheduleAdd, () => onScheduleDelete(j + 1), (j + 1), otherSchd.length === (j + 1), (scheduleIndex, key) => resolveComponentScheduleErrorKey(index, scheduleIndex, key), valProblemKeys)}\r\n \r\n )}\r\n \r\n );\r\n}\r\n\r\nfunction renderComponents(\r\n classes: ReturnType,\r\n components: Array,\r\n onComponentChange: (compIndex: number, changes: Partial) => void,\r\n onComponentAdd: () => void,\r\n onComponentDelete: (compIndex: number) => void,\r\n onScheduleChange: (compIndex: number, schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: (compIndex: number) => void,\r\n onScheduleDelete: (compIndex: number, schdIndex: number) => void,\r\n resolveComponentErrorKey: ComponentErrorKeyResolver,\r\n resolveComponentScheduleErrorKey: ComponentScheduleErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n) {\r\n return components.map((value, index) => renderComponent(\r\n classes,\r\n value,\r\n (changes) => onComponentChange(index, changes),\r\n onComponentAdd,\r\n () => onComponentDelete(index),\r\n (schdIndex, changes) => onScheduleChange(index, schdIndex, changes),\r\n () => onScheduleAdd(index),\r\n (schdIndex) => onScheduleDelete(index, schdIndex),\r\n index,\r\n components.length === (index + 1),\r\n resolveComponentErrorKey,\r\n resolveComponentScheduleErrorKey,\r\n valProblemKeys,\r\n ));\r\n}\r\n\r\nexport function VseClassComponentEditTable(props: VseClassComponentEditTableProps) {\r\n const classes = useStyles();\r\n teachingModes = props.teachingModeOptions;\r\n tzCodes = props.timeZoneOptions;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n Component\r\n \r\n \r\n Mode of Teaching\r\n \r\n \r\n \r\n Schedule Description\r\n \r\n \r\n Time Zone\r\n \r\n \r\n \r\n {renderComponents(\r\n classes,\r\n props.list,\r\n props.onChange,\r\n props.onAdd,\r\n props.onDelete,\r\n props.onScheduleChange,\r\n props.onScheduleAdd,\r\n props.onScheduleDelete,\r\n props.resolveComponentErrorKey,\r\n props.resolveComponentScheduleErrorKey,\r\n props.valProblemKeys,\r\n )}\r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport AddIcon from '@material-ui/icons/AddCircleOutline';\r\nimport DeleteIcon from '@material-ui/icons/RemoveCircleOutline';\r\nimport clsx from 'clsx';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport {\r\n VseClassComponentEditTable,\r\n ComponentErrorKeyResolver,\r\n ComponentScheduleErrorKeyResolver,\r\n} from './VseClassComponentEditTable';\r\nimport { VseClassEditTemplate, VseClassComponentEditTemplate, VseClassComponentScheduleEditTemplate } from '../types/VseClassEditTemplate';\r\nimport {\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n hidden: {\r\n display: 'none',\r\n },\r\n}));\r\n\r\nexport type ClassErrorKeyResolver = (key: keyof VseClassEditTemplate) => string\r\n\r\nexport interface VseClassEditGridProps {\r\n data: VseClassEditTemplate,\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n onChange: (changes: Partial) => void,\r\n onAdd: () => void,\r\n onDelete: () => void,\r\n onComponentChange: (compIndex: number, changes: Partial) => void\r\n onComponentAdd: () => void,\r\n onComponentDelete: (compIndex: number) => void,\r\n onScheduleChange: (compIndex: number, schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: (compIndex: number) => void,\r\n onScheduleDelete: (compIndex: number, schdIndex: number) => void,\r\n last: boolean,\r\n resolveClassErrorKey: ClassErrorKeyResolver,\r\n resolveComponentErrorKey: ComponentErrorKeyResolver,\r\n resolveComponentScheduleErrorKey: ComponentScheduleErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n}\r\n\r\nexport function VseClassEditGrid(props: VseClassEditGridProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n function hasError(key: keyof VseClassEditTemplate): boolean {\r\n if (props.valProblemKeys) {\r\n const searchElement: string = props.resolveClassErrorKey(key);\r\n return props.valProblemKeys.includes(searchElement);\r\n }\r\n return false;\r\n }\r\n return (\r\n
\r\n \r\n \r\n \r\n props.onChange({ className: e.target.value })}\r\n error={hasError('className')}\r\n />\r\n \r\n \r\n \r\n props.onAdd()}\r\n >\r\n \r\n \r\n props.onDelete()}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Card from '@material-ui/core/Card';\r\nimport { VseClassEditGrid } from './VseClassEditGrid';\r\nimport { VseClassEditTemplate, VseClassComponentEditTemplate, VseClassComponentScheduleEditTemplate } from '../types/VseClassEditTemplate';\r\nimport {\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n card: {\r\n marginBottom: theme.spacing(1),\r\n },\r\n}));\r\n\r\nexport type ClassErrorKeyResolver = (index: number, key: keyof VseClassEditTemplate) => string;\r\n\r\nexport type ClassComponentErrorKeyResolver = (index: number, componentIndex: number, key: keyof VseClassComponentEditTemplate) => string;\r\n\r\nexport type ClassComponentScheduleErrorKeyResolver = (index: number, componentIndex: number, scheduleIndex: number, key: keyof VseClassComponentScheduleEditTemplate) => string;\r\n\r\nexport interface VseClassEditListProps {\r\n list: Array,\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n onChange: (index: number, changes: Partial) => void,\r\n onAdd: () => void,\r\n onDelete: (index: number) => void,\r\n onComponentChange: (classIndex: number, compIndex: number, changes: Partial) => void,\r\n onComponentAdd: (classIndex: number) => void,\r\n onComponentDelete: (classIndex: number, compIndex: number) => void,\r\n onScheduleChange: (classIndex: number, compIndex: number, schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: (classIndex: number, compIndex: number) => void,\r\n onScheduleDelete: (classIndex: number, compIndex: number, schdIndex: number) => void,\r\n resolveClassErrorKey: ClassErrorKeyResolver,\r\n resolveClassComponentErrorKey: ClassComponentErrorKeyResolver,\r\n resolveClassComponentScheduleErrorKey: ClassComponentScheduleErrorKeyResolver,\r\n valProblemKeys?: Array,\r\n}\r\n\r\nexport function VseClassEditList(props: VseClassEditListProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n return (\r\n \r\n {props.list.map((value, index) =>\r\n \r\n props.onChange(index, changes)}\r\n onAdd={() => props.onAdd()}\r\n onDelete={() => props.onDelete(index)}\r\n onComponentChange={(compIndex, changes) => props.onComponentChange(index, compIndex, changes)}\r\n onComponentAdd={() => props.onComponentAdd(index)}\r\n onComponentDelete={(compIndex) => props.onComponentDelete(index, compIndex)}\r\n onScheduleChange={(compIndex, schdIndex, changes) => props.onScheduleChange(index, compIndex, schdIndex, changes)}\r\n onScheduleAdd={(compIndex) => props.onScheduleAdd(index, compIndex)}\r\n onScheduleDelete={(compIndex, schdIndex) => props.onScheduleDelete(index, compIndex, schdIndex)}\r\n last={props.list.length === (index + 1)}\r\n resolveClassErrorKey={(key) => props.resolveClassErrorKey(index, key)}\r\n resolveComponentErrorKey={(componentIndex, key) => props.resolveClassComponentErrorKey(index, componentIndex, key)}\r\n resolveComponentScheduleErrorKey={(componentIndex, scheduleIndex, key) => props.resolveClassComponentScheduleErrorKey(index, componentIndex, scheduleIndex, key)}\r\n valProblemKeys={props.valProblemKeys}\r\n />\r\n \r\n )}\r\n \r\n );\r\n}\r\n","import React from 'react';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Button from '@material-ui/core/Button';\r\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Tab from '@material-ui/core/Tab';\r\nimport Tabs from '@material-ui/core/Tabs';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport {\r\n VseCourseEditGrid,\r\n CourseErrorKeyResolver,\r\n} from './VseCourseEditGrid';\r\nimport { VseCourseHeaderGrid } from './VseCourseHeaderGrid';\r\nimport {\r\n VseClassEditList,\r\n ClassErrorKeyResolver,\r\n ClassComponentErrorKeyResolver,\r\n ClassComponentScheduleErrorKeyResolver,\r\n} from './VseClassEditList';\r\nimport { VseCourseEditTemplate } from '../types/VseCourseEditTemplate';\r\nimport { VseClassEditTemplate, VseClassComponentEditTemplate, VseClassComponentScheduleEditTemplate } from '../types/VseClassEditTemplate';\r\nimport {\r\n SeasonEntity,\r\n UniversityEntity,\r\n CourseStatusEntity,\r\n LanguageEntity,\r\n UniversityTermEntity,\r\n TeachingModeEntity,\r\n TimeZoneEntity,\r\n DotNetValidationProblemDetails,\r\n} from '../types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n appBar: {\r\n marginBottom: theme.spacing(2),\r\n },\r\n toolbar: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n },\r\n form: {\r\n paddingTop: theme.spacing(1),\r\n paddingBottom: theme.spacing(1),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(2),\r\n },\r\n selectedTab: {\r\n color: theme.palette.common.white,\r\n },\r\n}));\r\n\r\nexport interface VseCourseEditFormProps {\r\n courseData: VseCourseEditTemplate,\r\n seasonOptions: SeasonEntity[],\r\n universityOptions: UniversityEntity[],\r\n universityTermOptions: UniversityTermEntity[],\r\n courseStatusOptions: CourseStatusEntity[],\r\n languageOptions: LanguageEntity[],\r\n teachingModeOptions: TeachingModeEntity[],\r\n timeZoneOptions: TimeZoneEntity[],\r\n onSave: () => void,\r\n onBack: () => void,\r\n onCourseChange: (changes: Partial) => void,\r\n onClassChange: (index: number, changes: Partial) => void,\r\n onClassAdd: () => void,\r\n onClassDelete: (index: number) => void,\r\n onComponentChange: (index: number, compIndex: number, changes: Partial) => void,\r\n onComponentAdd: (index: number) => void,\r\n onComponentDelete: (index: number, compIndex: number) => void,\r\n onScheduleChange: (index: number, compIndex: number, schdIndex: number, changes: Partial) => void,\r\n onScheduleAdd: (index: number, compIndex: number) => void,\r\n onScheduleDelete: (index: number, compIndex: number, schdIndex: number) => void,\r\n resolveCourseErrorKey: CourseErrorKeyResolver,\r\n resolveClassErrorKey: ClassErrorKeyResolver,\r\n resolveClassComponentErrorKey: ClassComponentErrorKeyResolver,\r\n resolveClassComponentScheduleErrorKey: ClassComponentScheduleErrorKeyResolver,\r\n valProblems?: DotNetValidationProblemDetails,\r\n}\r\n\r\nexport function VseCourseEditForm(props: VseCourseEditFormProps) {\r\n function decodeSeason(seasonID: number) {\r\n const data = props.seasonOptions.filter((e) => e.seasonID === seasonID);\r\n if (data && data.length > 0) return data[0].shortDescription;\r\n return undefined;\r\n }\r\n function decodeUniversity(univID: number) {\r\n const data = props.universityOptions.filter((e) => e.universityID === univID);\r\n if (data && data.length > 0) return data[0].universityName;\r\n return undefined;\r\n }\r\n function decodeUniversityTerm(seasonID: number, universityID: number, termCode: string) {\r\n const data = props.universityTermOptions.filter((e) => e.seasonID === seasonID && e.universityID === universityID && e.termCode === termCode);\r\n if (data && data.length > 0) return data[0].description;\r\n return undefined;\r\n }\r\n function decodeCourseStatus(code: string) {\r\n const data = props.courseStatusOptions.filter((e) => e.code === code);\r\n if (data && data.length > 0) return data[0].description;\r\n return undefined;\r\n }\r\n\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const [tab, setTab] = React.useState<'course' | 'class'>('course');\r\n const valProblemKeys = props.valProblems ? Object.keys(props.valProblems.errors) : undefined;\r\n\r\n React.useLayoutEffect(() => {\r\n if (props.valProblems) {\r\n const keys = Object.keys(props.valProblems.errors);\r\n let courseError = false;\r\n let classError = false;\r\n keys.forEach((value) => {\r\n if (value.startsWith('course')) {\r\n courseError = true;\r\n } else if (value.startsWith('classes')) {\r\n classError = true;\r\n }\r\n });\r\n if (courseError) {\r\n setTab('course');\r\n } else if (classError) {\r\n setTab('class');\r\n }\r\n }\r\n }, [props.valProblems]);\r\n return (\r\n \r\n \r\n \r\n \r\n props.onSave()}\r\n >\r\n Save\r\n \r\n props.onBack()}\r\n >\r\n Back\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setTab(newValue)}\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
\r\n );\r\n}\r\n","import React from 'react';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\nexport function VseDisclaimer() {\r\n return (\r\n \r\n Disclaimer\r\n Copyright © 2021. All Rights Reserved. The Chinese University of Hong Kong.\r\n Unless otherwise indicated, The Chinese University of Hong Kong (hereinafter referred to as \"CUHK\") owns the copyright in the pages, in the screens displaying the pages, in the information and materials therein, and in their arrangement.\r\n Security Enforcement\r\n We recommend you to enforce the following:\r\n
    \r\n
  1. Do NOT disclose your password to any third party.
  2. \r\n
  3. Change your password on a regular basis.
  4. \r\n
  5. Do NOT open other internet browser sessions or access other sites when accessing the VSE online application form (hereinafter referred to as \"the online application form\").
  6. \r\n
\r\n Browsing\r\n The online application form will not collect any personal information from your computer. This means that, unless you voluntarily and knowingly provide us with personal information, we will not know your name, your e-mail address, or any other identifiable information relating to you.\r\n Internet Protocol (IP) Address\r\n An IP address is a number that is automatically assigned to your computer every time you browse the Internet. When users request a page from this site, this server logs the user's current IP address. We use IP addresses to help diagnose system problems. We do not link IP addresses to any personal information about you.\r\n Securing the Transmission and Storage of Information\r\n Information displayed in this website is transferred over a Secured Sockets Layer (SSL) line provided you are using a SSL enabled browser. This ensures that your information is encrypted as it travels over the Internet. This secure mode is enabled before any such information is transmitted from your computer. After information reaches CUHK it is stored on a secure server that resides behind a firewall that is designed to block access from outside the Campus.\r\n Although the information in this website is presented in good faith and believed to be correct, CUHK makes no warranties as to the completeness or accuracy of such information. Information is supplied on the condition that the persons receiving it will determine for themselves its suitability for their purposes prior to use. In no event and under no circumstances will the University be liable for damages of any nature whatsoever resulting from the use of or reliance upon information herein referred.\r\n THIS INFORMATION IS PROVIDED \"AS IS\" AND NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, OF MERCHANTABILITY OR MARKETABILITY, FITNESS FOR A PARTICULAR PURPOSE OR OF ANY OTHER NATURE, ARE MADE WITH RESPECT TO THIS INFORMATION.\r\n Links to Other Sites\r\n The online application form contains links to other sites. The online application form does not share your personal information with those websites. If you choose to leave this site via links to other sites, CUHK is not responsible for the privacy policies or contents of those sites, nor is CUHK responsible for the cookies those sites may deposit on your computer.\r\n Contact Us\r\n If you have any questions about this privacy statement or privacy concern, please e-mail us at apru.vse@cuhk.edu.hk.\r\n
\r\n );\r\n}\r\n","import { Link as RouterLink } from 'react-router-dom';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport Link from '@material-ui/core/Link';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n footer: {\r\n padding: theme.spacing(2),\r\n },\r\n separator: {\r\n paddingLeft: theme.spacing(0.5),\r\n paddingRight: theme.spacing(0.5),\r\n },\r\n}));\r\n\r\nexport function Footer() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n return (\r\n
\r\n \r\n Copyright © {new Date().getFullYear()}. All Rights Reserved. APRU VSE\r\n
\r\n Copyright © {new Date().getFullYear()}. All Rights Reserved. The Chinese University of Hong Kong\r\n |\r\n Disclaimer\r\n
\r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Link, useLocation } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport Button from '@material-ui/core/Button';\r\nimport * as VseSession from '../../features/session';\r\n\r\nexport function LoginControl() {\r\n const sessionState = VseSession.useVseSessionState();\r\n const dispatch = useDispatch();\r\n const location = useLocation();\r\n const isInLoginPage = location.pathname === \"/login\";\r\n const loggedIn = sessionState.token.isAuthenticated && sessionState.loading !== 'timeout';\r\n const loginButton = ;\r\n const logoutButton = ;\r\n\r\n React.useEffect(() => {\r\n if (sessionState.loading === 'idle') {\r\n dispatch(VseSession.challenge());\r\n }\r\n }, [dispatch, sessionState.loading]);\r\n\r\n return (\r\n loggedIn ? logoutButton : isInLoginPage ?
: loginButton\r\n );\r\n}\r\n","import { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport { LoginControl } from '../login/LoginControl';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n appBar: {\r\n paddingTop: theme.spacing(2),\r\n },\r\n logo: {\r\n height: '60px'\r\n },\r\n}));\r\n\r\nexport function Header() {\r\n const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href') as string;\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n return (\r\n \r\n \r\n \r\n \r\n APRU VSE logo\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport CssBaseline from '@material-ui/core/CssBaseline';\r\nimport { Footer } from './Footer';\r\nimport { Header } from './Header';\r\n\r\nconst useStyles = makeStyles((_theme: Theme) => ({\r\n root: {\r\n display: 'flex',\r\n minHeight: '100vh',\r\n maxWidth: '1536px',\r\n margin: 'auto',\r\n },\r\n app: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n width: '100%',\r\n maxWidth: '1280px',\r\n marginLeft: 'auto',\r\n marginRight: 'auto',\r\n },\r\n page: {\r\n flexGrow: 1,\r\n },\r\n}));\r\n\r\ninterface LayoutProps {\r\n children: React.ReactNode | React.ReactNodeArray\r\n}\r\n\r\nexport function Layout(props: LayoutProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n return (\r\n
\r\n \r\n
\r\n
\r\n
\r\n {props.children}\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n","import {\r\n Redirect\r\n} from 'react-router-dom';\r\n\r\nexport function Home() {\r\n return (\r\n \r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Link } from 'react-router-dom';\r\nimport Button from '@material-ui/core/Button';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\nexport declare type LoginGridSubmitEventHandler = (userName: string, password: string) => void;\r\n\r\nexport interface LoginGridProps {\r\n onSubmit: LoginGridSubmitEventHandler,\r\n}\r\nexport function LoginGrid(props: LoginGridProps) {\r\n const [userName, setUserName] = React.useState('');\r\n const [password, setPassword] = React.useState('');\r\n\r\n return (\r\n \r\n Applicant Login\r\n \r\n \r\n \r\n \r\n setUserName(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n setPassword(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n {\r\n ev.preventDefault();\r\n props.onSubmit(userName, password);\r\n setPassword('');\r\n }\r\n }\r\n >Login\r\n \r\n \r\n Reset Password\r\n \r\n \r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Theme, makeStyles } from '@material-ui/core/styles';\r\nimport Alert from '@material-ui/lab/Alert';\r\nimport AlertTitle from '@material-ui/lab/AlertTitle';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n marginBottom: theme.spacing(2),\r\n },\r\n action: {\r\n alignItems: 'flex-start',\r\n },\r\n}));\r\n\r\nexport interface VseAlertComponentProps extends Pick, 'className'> {\r\n theme: Theme,\r\n severity: 'error' | 'info' | 'success' | 'warning', // copied from material-ui Alert API\r\n title?: string,\r\n messages: string[],\r\n onDismiss: (messagesToDismiss: string[]) => void,\r\n}\r\n\r\nexport function VseAlertComponent(props: VseAlertComponentProps) {\r\n const classes = useStyles(props.theme);\r\n\r\n return (\r\n props.messages.length === 0 ? null : (\r\n props.onDismiss ? props.onDismiss(props.messages) : null\r\n }\r\n >\r\n {props.title ? (\r\n {props.title}\r\n ) : undefined}\r\n {props.messages.length === 1 ?
: (\r\n
    \r\n {props.messages.map((s, i) =>
  • )}\r\n
\r\n )}\r\n \r\n )\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { useTheme } from '@material-ui/core';\r\nimport { useHistory } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { VseAlertComponent } from './VseAlertComponent';\r\nimport * as VseAlert from '../../features/alert';\r\n\r\nexport interface VseAlertContainerProps extends Pick, 'className'> {\r\n\r\n}\r\n\r\nexport function VseAlertContainer(props: VseAlertContainerProps) {\r\n const theme = useTheme();\r\n const history = useHistory<{\r\n vseAlerts: VseAlert.VseAlertState\r\n }>();\r\n const alertState = VseAlert.useVseAlertState();\r\n const locAlertState: VseAlert.VseAlertState | undefined = history.location.state && history.location.state.vseAlerts ? history.location.state.vseAlerts : undefined;\r\n const dispatch = useDispatch();\r\n\r\n React.useEffect(() => {\r\n if (locAlertState && locAlertState.validationProblemMessages) {\r\n dispatch(VseAlert.alertValidationProblemMessages(locAlertState.validationProblemMessages));\r\n }\r\n }, [dispatch, locAlertState]);\r\n\r\n return (\r\n \r\n {alertState.successMessages.length === 0 ? undefined : alertState.successMessages.map((s, i) => {\r\n return (\r\n msgs.forEach((msg) => dispatch(VseAlert.dismissSucceeded(msg)))}\r\n />\r\n );\r\n })}\r\n {alertState.validationProblemMessages.length === 0 ? undefined : (\r\n dispatch(VseAlert.dismissValidationProblem(msgs))}\r\n />\r\n )}\r\n {alertState.serverErrorMessages.length === 0 ? undefined : alertState.serverErrorMessages.map((s, i) => {\r\n return (\r\n msgs.forEach((msg) => dispatch(VseAlert.dismissServerError(msg)))}\r\n />\r\n );\r\n })}\r\n \r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Redirect, useLocation } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport { LoginGrid } from './LoginGrid';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as VseAlert from '../../features/alert';\r\nimport * as VseSession from '../../features/session';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n alert: {\r\n padding: theme.spacing(1),\r\n margin: theme.spacing(1),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function LoginPage() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const location = useLocation();\r\n const sessionState = VseSession.useVseSessionState();\r\n\r\n React.useEffect(function handleLoading() {\r\n return function cleanup() {\r\n dispatch(VseAlert.dismissValidationProblem());\r\n };\r\n }, [dispatch]);\r\n\r\n if (sessionState.token.isAuthenticated) {\r\n const params = new URLSearchParams(location.search);\r\n const url = params.get(\"redirect\");\r\n if (url) {\r\n return ;\r\n } else {\r\n return ;\r\n }\r\n }\r\n\r\n return (\r\n
\r\n \r\n \r\n dispatch(VseSession.login({ userName, password }))\r\n } />\r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Redirect } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport Backdrop from '@material-ui/core/Backdrop';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport * as VseSession from '../../features/session';\r\n\r\nexport function LogoutPage() {\r\n const sessionState = VseSession.useVseSessionState();\r\n const dispatch = useDispatch();\r\n\r\n React.useEffect(() => {\r\n dispatch(VseSession.logout());\r\n }, [dispatch]);\r\n\r\n React.useEffect(() => {\r\n if (sessionState.loading === 'loggedOut') {\r\n dispatch(VseSession.reset());\r\n }\r\n }, [dispatch, sessionState.loading]);\r\n\r\n switch (sessionState.loading) {\r\n case 'idle': // after reset\r\n return ();\r\n default:\r\n return (\r\n \r\n \r\n \r\n );\r\n }\r\n}\r\n","import * as React from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\nexport interface ForgotPasswordGridProps {\r\n onSubmit: (userName: string) => void,\r\n}\r\n\r\nexport function ForgotPasswordGrid(props: ForgotPasswordGridProps) {\r\n const [userName, setUserName] = React.useState('');\r\n\r\n return (\r\n \r\n \r\n Reset password\r\n \r\n \r\n Please enter your registered email address below. An email will be sent to you with a link to reset your password.\r\n \r\n \r\n setUserName(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n props.onSubmit(userName)\r\n }\r\n >Submit\r\n \r\n \r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { useDispatch } from 'react-redux';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { ForgotPasswordGrid } from './ForgotPasswordGrid';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as PasswordReset from '../../features/password';\r\nimport * as VseAlert from '../../features/alert';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function ForgotPasswordPage() {\r\n\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const succeeded = (\r\n
\r\n Reset Password\r\n \r\n An email has been sent to your email address. Click on the link in the email and follow instructions to reset your password.\r\n \r\n
\r\n );\r\n const passwordResetState = PasswordReset.usePasswordResetState();\r\n const dispatch = useDispatch();\r\n\r\n React.useEffect(function init() {\r\n return function reset() {\r\n dispatch(PasswordReset.reset())\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch]);\r\n\r\n React.useEffect(() => {\r\n if (passwordResetState.loading === 'succeeded') {\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch, passwordResetState.loading]);\r\n\r\n return (\r\n
\r\n \r\n \r\n {passwordResetState.loading === 'succeeded' ? (\r\n succeeded\r\n ) : (\r\n dispatch(PasswordReset.forgotPassword(userName))} />\r\n )}\r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport {\r\n UniversityEntity,\r\n} from 'vse-material-ui';\r\n\r\nexport interface ResetPasswordGridProps {\r\n universityOptions: UniversityEntity[],\r\n onSubmit: (homeUniversityID: string | number, password: string, confirmPassword: string) => void,\r\n}\r\nexport function ResetPasswordGrid(props: ResetPasswordGridProps) {\r\n const [homeUniversityID, setHomeUniversityID] = React.useState('');\r\n const [password, setPassword] = React.useState('');\r\n const [confirmPassword, setConfirmPassword] = React.useState('');\r\n\r\n return (\r\n \r\n Reset Password\r\n Please enter the following information to reset your APRU VSE application account password\r\n \r\n setHomeUniversityID(ev.target.value)\r\n }\r\n >\r\n {props.universityOptions.map((option) => (\r\n \r\n {option.universityName}\r\n \r\n ))}\r\n \r\n \r\n \r\n setPassword(ev.target.value)\r\n } />\r\n \r\n \r\n setConfirmPassword(ev.target.value)\r\n } />\r\n \r\n \r\n Note\r\n Your password must be at least 8 characters and contain at least:\r\n
    \r\n
  • one uppercase letter;
  • \r\n
  • one lowercase letter;
  • \r\n
  • one numeric; and
  • \r\n
  • one non-alphanumeric character
  • \r\n
\r\n
\r\n \r\n props.onSubmit(homeUniversityID, password, confirmPassword)\r\n }\r\n >Submit\r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Link, useParams, useLocation } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Backdrop from '@material-ui/core/Backdrop';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { ResetPasswordGrid } from './ResetPasswordGrid';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as SharedData from '../../features/sharedData';\r\nimport * as PasswordReset from '../../features/password';\r\nimport * as VseAlert from '../../features/alert';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function ResetPasswordPage() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const sharedDataState = SharedData.useVseSharedDataState();\r\n const passwordResetState = PasswordReset.usePasswordResetState();\r\n const params = useParams<{ id: string }>();\r\n const location = useLocation();\r\n const search = new URLSearchParams(location.search);\r\n const token = search.get(\"c\");\r\n\r\n React.useEffect(function init() {\r\n dispatch(PasswordReset.verify({\r\n id: params.id,\r\n token: token ? token : ''\r\n }));\r\n\r\n return function reset() {\r\n dispatch(PasswordReset.reset())\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch, params.id, token]);\r\n\r\n React.useEffect(() => {\r\n if (passwordResetState.loading === 'succeeded') {\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch, passwordResetState.loading]);\r\n\r\n React.useEffect(function loadUniversities() {\r\n if (sharedDataState.universityLoading === 'idle') {\r\n dispatch(SharedData.loadUniversities());\r\n }\r\n }, [dispatch, sharedDataState.universityLoading]);\r\n\r\n return (\r\n
\r\n \r\n {passwordResetState.loading === 'failed' ? (\r\n
\r\n ) : (\r\n \r\n {passwordResetState.loading === 'pending' ? (\r\n dispatch(PasswordReset.resetPassword({\r\n id: params.id,\r\n token: token ? token : '',\r\n homeUniversityID: homeUniversityID as number,\r\n password,\r\n confirmPassword\r\n }))\r\n }\r\n />\r\n ) : (passwordResetState.loading === 'succeeded' ? (\r\n
\r\n Reset Password\r\n Your APRU VSE application account password has been reset. Login to your account\r\n
\r\n ) : (\r\n \r\n \r\n \r\n ))}\r\n
\r\n )}\r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport {\r\n UniversityEntity,\r\n} from 'vse-material-ui';\r\nimport {\r\n UserRegistrationForm,\r\n} from '../../features/account/userRegisterTypes';\r\n\r\nexport interface RegisterGridProps {\r\n universityOptions: UniversityEntity[],\r\n onSubmit: (regForm: UserRegistrationForm) => void,\r\n}\r\n\r\nexport function RegisterGrid(props: RegisterGridProps) {\r\n const [userName, setUserName] = React.useState('');\r\n const [homeUniversityID, setHomeUniversityID] = React.useState('');\r\n const [password, setPassword] = React.useState('');\r\n const [confirmPassword, setConfirmPassword] = React.useState('');\r\n\r\n return (\r\n \r\n Create your APRU VSE Application Account\r\n \r\n setUserName(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n setHomeUniversityID(ev.target.value)\r\n }\r\n >\r\n {props.universityOptions.map((option) => (\r\n \r\n {option.universityName}\r\n \r\n ))}\r\n \r\n \r\n \r\n setPassword(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n setConfirmPassword(ev.target.value)\r\n }\r\n />\r\n \r\n \r\n Note\r\n Your password must be at least 8 characters and contain at least:\r\n
    \r\n
  • one uppercase letter;
  • \r\n
  • one lowercase letter;
  • \r\n
  • one numeric; and
  • \r\n
  • one non-alphanumeric character
  • \r\n
\r\n
\r\n \r\n {\r\n ev.preventDefault();\r\n props.onSubmit({ userName, homeUniversityID, password, confirmPassword });\r\n setPassword('');\r\n setConfirmPassword('');\r\n }}\r\n >Submit\r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Redirect } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport {\r\n RegisterGrid,\r\n} from './RegisterGrid';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as VseAlert from '../../features/alert';\r\nimport * as Session from '../../features/session';\r\nimport * as SharedData from '../../features/sharedData';\r\nimport * as UserRegister from '../../features/account';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function RegisterPage() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const sessionState = Session.useVseSessionState();\r\n const sharedDataState = SharedData.useVseSharedDataState();\r\n const userRegisterState = UserRegister.useUserRegisterState();\r\n\r\n React.useEffect(() => {\r\n return () => {\r\n dispatch(UserRegister.reset());\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch]);\r\n\r\n React.useEffect(() => {\r\n if (userRegisterState.loading === 'succeeded') {\r\n dispatch(VseAlert.dismissValidationProblem());\r\n }\r\n }, [dispatch, userRegisterState.loading]);\r\n\r\n React.useEffect(() => {\r\n if (sharedDataState.universityLoading === 'idle') {\r\n dispatch(SharedData.loadUniversities());\r\n }\r\n }, [dispatch, sharedDataState.universityLoading]);\r\n\r\n return (\r\n sessionState.token.isAuthenticated ? : (\r\n
\r\n \r\n \r\n {userRegisterState.loading === 'succeeded' ? (\r\n
\r\n Account Creation Successful\r\n \r\n A verification email has been sent to your email address. Click on the link in the email to activate your account.\r\n \r\n
\r\n ) : (\r\n dispatch(UserRegister.register(regForm))\r\n }\r\n />\r\n )\r\n }\r\n
\r\n
\r\n )\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { Link, useLocation } from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { Theme, makeStyles, useTheme } from '@material-ui/core/styles';\r\nimport Backdrop from '@material-ui/core/Backdrop';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as UserRegister from '../../features/account';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function ConfirmEmailPage() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const userRegisterState = UserRegister.useUserRegisterState();\r\n const location = useLocation();\r\n const dispatch = useDispatch();\r\n\r\n React.useEffect(() => {\r\n const params = new URLSearchParams(location.search);\r\n const i = params.get('i');\r\n const c = params.get('c');\r\n dispatch(UserRegister.confirmEmail({ encodedId: i ? i : '', encodedCode: c ? c : '' }));\r\n\r\n return function cleanup() {\r\n dispatch(UserRegister.reset());\r\n }\r\n }, [dispatch, location.search]);\r\n\r\n\r\n switch (userRegisterState.emailConfirmation) {\r\n case 'failed':\r\n return (\r\n
\r\n \r\n
\r\n );\r\n\r\n case 'succeeded':\r\n return (\r\n
\r\n \r\n Account Activated\r\n Your account has been activated. Login to your account.\r\n \r\n
\r\n );\r\n\r\n default:\r\n return (\r\n \r\n \r\n \r\n );\r\n }\r\n}\r\n","import * as React from 'react';\r\nimport {\r\n Redirect,\r\n RouteComponentProps,\r\n} from 'react-router-dom';\r\nimport { useDispatch } from 'react-redux';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Backdrop from '@material-ui/core/Backdrop';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport { VseNewApplForm } from 'vse-material-ui';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as SharedData from '../../features/sharedData';\r\nimport * as NewAppl from '../../features/newAppl';\r\nimport * as VseAlert from '../../features/alert';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n alert: {\r\n padding: theme.spacing(1),\r\n margin: theme.spacing(1),\r\n },\r\n back: {\r\n padding: theme.spacing(1),\r\n margin: theme.spacing(1),\r\n },\r\n}));\r\n\r\ninterface NewApplParams {\r\n seasonID: string,\r\n}\r\n\r\ninterface NewApplPageProps extends RouteComponentProps {\r\n\r\n}\r\n\r\nexport function NewApplPage(props: NewApplPageProps) {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const sharedDataState = SharedData.useVseSharedDataState();\r\n const newApplState = NewAppl.useNewVseApplicationState();\r\n const alertState = VseAlert.useVseAlertState();\r\n const subHeaderRef = React.useRef(null);\r\n\r\n React.useEffect(function init() {\r\n const seasonID: number = parseInt(props.match.params.seasonID);\r\n if (!isNaN(seasonID)) {\r\n dispatch(NewAppl.prepare(seasonID));\r\n }\r\n\r\n return function cleanup() {\r\n dispatch(VseAlert.dismissValidationProblem());\r\n dispatch(NewAppl.reset());\r\n };\r\n }, [dispatch, props.match.params.seasonID]);\r\n\r\n React.useEffect(function handleLoading() {\r\n switch (newApplState.loading) {\r\n case 'succeeded':\r\n const msg = 'Application submitted successfully. Your application, if endorsed by your home university, will be forwarded to the corresponding course offering university after the application deadline. The time for course offering universities to review and approve your application varies, but you will be informed by the VSE Central Office of your application result (successful/not successful) before the first day of class of your selected course. For enquiries, please email to apru.vse@cuhk.edu.hk.';\r\n dispatch(VseAlert.alertSucceeded(msg));\r\n break;\r\n }\r\n }, [dispatch, newApplState.loading]);\r\n\r\n React.useEffect(function loadLanguages() {\r\n if (sharedDataState.languageLoading === 'idle') {\r\n dispatch(SharedData.loadLanguages());\r\n }\r\n }, [dispatch, sharedDataState.languageLoading]);\r\n\r\n React.useEffect(function loadMajors() {\r\n if (sharedDataState.majorLoading === 'idle') {\r\n dispatch(SharedData.loadMajors());\r\n }\r\n }, [dispatch, sharedDataState.majorLoading]);\r\n\r\n React.useEffect(function loadStudyLevels() {\r\n if (sharedDataState.studyLevelLoading === 'idle') {\r\n dispatch(SharedData.loadStudyLevels());\r\n }\r\n }, [dispatch, sharedDataState.studyLevelLoading]);\r\n\r\n React.useEffect(function loadStudyYears() {\r\n if (sharedDataState.studyYearLoading === 'idle') {\r\n dispatch(SharedData.loadStudyYears());\r\n }\r\n }, [dispatch, sharedDataState.studyYearLoading]);\r\n\r\n React.useEffect(function loadTeachingModes() {\r\n if (sharedDataState.teachingModeLoading === 'idle') {\r\n dispatch(SharedData.loadTeachingModes());\r\n }\r\n }, [dispatch, sharedDataState.teachingModeLoading]);\r\n\r\n React.useEffect(function loadTeachingModes() {\r\n if (sharedDataState.timeZoneLoading === 'idle') {\r\n dispatch(SharedData.loadTimeZones());\r\n }\r\n }, [dispatch, sharedDataState.timeZoneLoading]);\r\n\r\n React.useEffect(function loadUniversities() {\r\n if (sharedDataState.universityLoading === 'idle') {\r\n dispatch(SharedData.loadUniversities());\r\n }\r\n }, [dispatch, sharedDataState.universityLoading]);\r\n\r\n function renderContent() {\r\n let content = (\r\n \r\n \r\n \r\n );\r\n switch (newApplState.loading) {\r\n case 'succeeded':\r\n content = (\r\n \r\n );\r\n break;\r\n\r\n case 'failed':\r\n content = (\r\n \r\n );\r\n break;\r\n\r\n case 'ready':\r\n if (newApplState.token) {\r\n content = (\r\n state.handle)}\r\n onDocumentCancel={\r\n (documentType: string, _file: File, requestId?: string) => {\r\n dispatch(NewAppl.removeDocument({\r\n documentType,\r\n requestId,\r\n }))\r\n }\r\n }\r\n onDocumentUpload={\r\n (documentType, file) => {\r\n const docState = newApplState.documentStates.find((docState) => docState.handle.config.documentType === documentType);\r\n if (docState) dispatch(NewAppl.uploadDocument({ handle: docState.handle, file }));\r\n }\r\n }\r\n onSubmit={(appl) => {\r\n dispatch(NewAppl.submitNewAppl(appl));\r\n }}\r\n onCourseFiltering={() => {\r\n if (newApplState.token) {\r\n dispatch(NewAppl.loadCourses(newApplState.token.season.seasonID));\r\n }\r\n }}\r\n onCourseSelected={(course) => {\r\n if (newApplState.token) {\r\n dispatch(NewAppl.loadClasses(course));\r\n }\r\n }}\r\n onValidationProblem={(dtl) => {\r\n dispatch(VseAlert.alertValidationProblem(dtl));\r\n }}\r\n onNextStep={() => { dispatch(VseAlert.dismissValidationProblem()) }}\r\n />\r\n );\r\n }\r\n break;\r\n\r\n }\r\n return content;\r\n }\r\n\r\n return (\r\n \r\n
\r\n \r\n {renderContent()}\r\n \r\n );\r\n}\r\n","import IconButton from '@material-ui/core/IconButton';\r\nimport LaunchIcon from '@material-ui/icons/Launch';\r\nimport Table from '@material-ui/core/Table';\r\nimport TableBody from '@material-ui/core/TableBody';\r\nimport TableCell from '@material-ui/core/TableCell';\r\nimport TableHead from '@material-ui/core/TableHead';\r\nimport TableRow from '@material-ui/core/TableRow';\r\nimport {\r\n ApplStatusEntity,\r\n ClassEntity,\r\n CourseEntity,\r\n SeasonEntity,\r\n UniversityEntity,\r\n UniversityTermEntity,\r\n VseApplicationEntity\r\n} from 'vse-material-ui';\r\n\r\nexport interface MyApplListProps {\r\n data: VseApplicationEntity[],\r\n getApplStatus: (applStatus: string) => ApplStatusEntity | undefined,\r\n getSeason: (seasonID: number) => SeasonEntity | undefined,\r\n getUniversity: (universityID: number) => UniversityEntity | undefined,\r\n getUniversityTerm: (universityID: number, seasonID: number, termCode: string) => UniversityTermEntity | undefined,\r\n getClass: (classID: number) => ClassEntity | undefined,\r\n getCourse: (universityID: number, seasonID: number, termCode: string, courseCode: string) => CourseEntity | undefined,\r\n}\r\n\r\nexport function MyApplList(props: MyApplListProps) {\r\n return (\r\n \r\n \r\n \r\n \r\n Application No.\r\n VSE Season\r\n Course Offering University\r\n Course Offering Term\r\n Course Code\r\n Course Title\r\n Class\r\n Status\r\n Submission Date\r\n \r\n \r\n \r\n {props.data.map(e => {\r\n const cls = props.getClass(e.classes[0].classID); // Only the first\r\n const season = props.getSeason(e.seasonID);\r\n const seasonDescr = season ? season.shortDescription : null;\r\n const univ = cls ? props.getUniversity(cls.universityID) : null;\r\n const univName = univ ? univ.universityName : null;\r\n const univTerm = cls ? props.getUniversityTerm(cls.universityID, cls.seasonID, cls.termCode) : null;\r\n const univTermDescr = univTerm ? univTerm.shortDescription : null;\r\n const course = cls ? props.getCourse(cls.universityID, cls.seasonID, cls.termCode, cls.courseCode) : null;\r\n const courseTitle = course ? course.courseTitle : null;\r\n const applStatus = props.getApplStatus(e.status);\r\n return (\r\n \r\n \r\n {e.referenceNumber}\r\n {seasonDescr}\r\n {univName}\r\n {univTermDescr}\r\n {cls ? cls.courseCode : null}\r\n {courseTitle}\r\n {cls ? cls.className : null}\r\n {applStatus ? applStatus.description : null}\r\n {/* TODO: Date format */}\r\n {e.submissionDate ? new Intl.DateTimeFormat('en-CA', { day: \"numeric\", month: \"short\", year: \"numeric\", hour: \"2-digit\", hour12: false, minute: \"2-digit\", second: undefined }).format(new Date(e.submissionDate)).replace(',', '') : undefined}\r\n \r\n );\r\n })}\r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { useDispatch } from 'react-redux';\r\nimport { useHistory } from 'react-router-dom';\r\nimport clsx from 'clsx';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Button from '@material-ui/core/Button';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport Backdrop from '@material-ui/core/Backdrop';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { MyApplList } from './MyApplList';\r\nimport { VseAlertContainer } from '../alert/VseAlertContainer';\r\nimport * as SharedData from '../../features/sharedData';\r\nimport * as MyAppl from '../../features/myAppl';\r\nimport * as VseAlert from '../../features/alert';\r\nimport { VseApplicationEntity, DotNetValidationProblemDetailsTyped, VseValidation } from 'vse-material-ui';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n main: {\r\n flex: 1,\r\n padding: theme.spacing(1, 1),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n overflow: 'hidden',\r\n },\r\n appBar: {\r\n borderBottom: '1px solid rgba(0, 0, 0, 0.12)',\r\n },\r\n applyButton: {\r\n marginRight: theme.spacing(1),\r\n },\r\n alert: {\r\n padding: theme.spacing(1),\r\n margin: theme.spacing(1),\r\n },\r\n toolBarContainer: {\r\n display: 'flex',\r\n alignItems: 'flex-end',\r\n //paddingLeft: theme.spacing(2),\r\n },\r\n sectionTitle: {\r\n paddingLeft: theme.spacing(2),\r\n paddingTop: theme.spacing(2),\r\n },\r\n sectionRow: {\r\n paddingLeft: theme.spacing(2),\r\n },\r\n hidden: {\r\n display: 'none',\r\n },\r\n}));\r\n\r\nexport function MyApplPage() {\r\n function getApplStatus(applStatus: string) {\r\n if (sharedDataState.applStatusLoading === 'succeeded') {\r\n return sharedDataState.applStatusOptions.find(e => e.code === applStatus);\r\n }\r\n return undefined;\r\n }\r\n\r\n function getClass(classID: number) {\r\n if (myApplState.loading === 'succeeded') {\r\n return myApplState.classes.find(e => e.classID === classID);\r\n }\r\n return undefined;\r\n }\r\n\r\n function getCourse(universityID: number, seasonID: number, termCode: string, courseCode: string) {\r\n if (myApplState.loading === 'succeeded') {\r\n return myApplState.courses.find(e => {\r\n return e.universityID === universityID &&\r\n e.seasonID === seasonID &&\r\n e.termCode === termCode &&\r\n e.courseCode === courseCode;\r\n });\r\n }\r\n return undefined;\r\n }\r\n\r\n function getSeason(seasonID: number) {\r\n if (myApplState.loading === 'succeeded') {\r\n return myApplState.seasons.find(e => e.seasonID === seasonID);\r\n }\r\n return undefined;\r\n }\r\n\r\n function getUniversity(universityID: number) {\r\n if (sharedDataState.universityLoading === 'succeeded') {\r\n return sharedDataState.universityOptions.find(e => e.universityID === universityID);\r\n }\r\n return undefined;\r\n }\r\n\r\n function getUniversityTerm(universityID: number, seasonID: number, termCode: string) {\r\n if (myApplState.loading === 'succeeded') {\r\n return myApplState.universityTerms.find(e => {\r\n return e.universityID === universityID &&\r\n e.seasonID === seasonID &&\r\n e.termCode === termCode;\r\n });\r\n }\r\n return undefined;\r\n }\r\n\r\n function handleApplyClick() {\r\n let valProblems: DotNetValidationProblemDetailsTyped = VseValidation.createValidationProblemDetails();\r\n if (seasonID === '' || seasonID === undefined) {\r\n VseValidation.appendErrorTo(valProblems, \"seasonSelect\", \"Please select a season for application\");\r\n dispatch(VseAlert.alertValidationProblem(valProblems));\r\n } else {\r\n history.push(`/apply/${seasonID}`);\r\n }\r\n };\r\n\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n let history = useHistory();\r\n const dispatch = useDispatch();\r\n const sharedDataState = SharedData.useVseSharedDataState();\r\n const myApplState = MyAppl.useMyApplState();\r\n //const seasonID = myApplState.seasonsOpening.length > 0 ? myApplState.seasonsOpening[0].seasonID : undefined;\r\n const [seasonID, setSeasonID] = React.useState('');\r\n\r\n React.useEffect(() => {\r\n dispatch(MyAppl.load());\r\n return () => {\r\n dispatch(VseAlert.reset());\r\n dispatch(MyAppl.reset());\r\n };\r\n }, [dispatch]);\r\n\r\n React.useEffect(() => {\r\n if (sharedDataState.applStatusLoading === 'idle') {\r\n dispatch(SharedData.loadApplStatuses());\r\n }\r\n }, [dispatch, sharedDataState.applStatusLoading]);\r\n\r\n React.useEffect(() => {\r\n if (sharedDataState.universityLoading === 'idle') {\r\n dispatch(SharedData.loadUniversities());\r\n }\r\n }, [dispatch, sharedDataState.universityLoading]);\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n {(myApplState.loading !== 'succeeded' && myApplState.loading !== 'failed') ? (\r\n \r\n \r\n \r\n ) : (\r\n \r\n \r\n \r\n \r\n 0 && classes.hidden)} >\r\n No VSE Season is currently open for application.\r\n \r\n \r\n {\r\n setSeasonID(ev.target.value);\r\n //console.log(ev.target.value, 'select');\r\n }}\r\n >\r\n {myApplState.seasonsOpening.map((option) => (\r\n \r\n {option.shortDescription}\r\n \r\n ))}\r\n \r\n \r\n \r\n { handleApplyClick(); }}\r\n >\r\n Apply\r\n \r\n \r\n \r\n \r\n \r\n
\r\n My Applications\r\n
\r\n {myApplState.myAppl.length > 0 ? (\r\n \r\n ) : (\r\n
\r\n No application found.\r\n
\r\n )\r\n }\r\n
\r\n )\r\n }\r\n
\r\n
\r\n
\r\n );\r\n}\r\n","import { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport { VseDisclaimer } from 'vse-material-ui';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n main: {\r\n flex: 1,\r\n padding: theme.spacing(1, 1),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n overflow: 'hidden',\r\n '& p': {\r\n marginBottom: theme.spacing(2),\r\n },\r\n '& p + h6': {\r\n marginTop: theme.spacing(1),\r\n },\r\n },\r\n}));\r\n\r\nexport function Disclaimer() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { useDispatch } from 'react-redux';\r\nimport {\r\n Link,\r\n useLocation,\r\n} from 'react-router-dom';\r\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport * as VseSession from '../features/session';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => ({\r\n main: {\r\n flex: 1,\r\n padding: theme.spacing(1, 1),\r\n },\r\n paper: {\r\n margin: 'auto',\r\n padding: theme.spacing(2),\r\n },\r\n}));\r\n\r\nexport function Timeout() {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const location = useLocation();\r\n const params = new URLSearchParams(location.search);\r\n const url = params.get(\"redirect\");\r\n let loginLink = '/login';\r\n if (url) {\r\n loginLink += `?redirect=${url}`;\r\n }\r\n\r\n React.useEffect(() => {\r\n return () => {\r\n dispatch(VseSession.reset());\r\n }\r\n }, [dispatch]);\r\n\r\n return (\r\n
\r\n \r\n Timeout\r\n Your login session has been timeout, please login and try again.\r\n \r\n
\r\n );\r\n}\r\n","import { Switch, Redirect, Route, useLocation } from 'react-router';\r\nimport { ThemeProvider } from '@material-ui/core/styles';\r\nimport { createVseTheme } from 'vse-material-ui';\r\nimport { Layout } from './components/layout/Layout';\r\nimport { Home } from './components/Home';\r\nimport { LoginPage } from './components/login/LoginPage';\r\nimport { LogoutPage } from './components/login/LogoutPage';\r\nimport { ForgotPasswordPage } from './components/password/ForgotPasswordPage';\r\nimport { ResetPasswordPage } from './components/password/ResetPasswordPage';\r\nimport { RegisterPage } from './components/register/RegisterPage'; // VSE0004\r\nimport { ConfirmEmailPage } from './components/register/ConfirmEmailPage'; // VSE0004\r\nimport { NewApplPage } from './components/appl/NewApplPage';\r\nimport { MyApplPage } from './components/appl/MyApplPage';\r\nimport { Disclaimer } from './components/Disclaimer';\r\nimport { Timeout } from './components/Timeout';\r\nimport * as VseSession from './features/session';\r\n\r\nlet theme = createVseTheme();\r\n\r\nexport default function App() {\r\n const sessionState = VseSession.useVseSessionState();\r\n const location = useLocation();\r\n\r\n function secured(e: JSX.Element) {\r\n const link: string = `${location.pathname}${location.search}`;\r\n if (sessionState.token) {\r\n if (sessionState.token.isAuthenticated) {\r\n if (sessionState.loading === 'timeout') {\r\n return ;\r\n }\r\n else {\r\n return e;\r\n }\r\n }\r\n }\r\n return ;\r\n }\r\n\r\n const SecuredMyApplPage = () => (secured());\r\n\r\n const SecuredNewApplPage = (props: any) => (secured());\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 \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n","import { createTheme } from '@material-ui/core/styles';\r\n\r\nexport function createVseTheme() {\r\n const vsePalette = {\r\n background: {\r\n paper: \"rgba(255, 255, 255, 1)\",\r\n default: \"rgba(255, 255, 255, 1)\",\r\n },\r\n action: {\r\n disabledBackground: \"rgba(163, 163, 163, 0.12)\",\r\n },\r\n primary: {\r\n // light: will be calculated from main,\r\n main: \"rgba(102, 45, 145, 1)\",\r\n // dark: will be calculated from main,\r\n // contrastText: will be calculated to contrast with main\r\n },\r\n secondary: {\r\n // light: will be calculated from main,\r\n main: \"rgba(27, 176, 178, 0.87)\",\r\n // dark: will be calculated from main,\r\n // contrastText: will be calculated to contrast with main\r\n },\r\n text: {\r\n primary: \"rgba(0, 0, 0, 0.87)\",\r\n secondary: \"#1bafb2\",\r\n disabled: \"rgba(0, 0, 0, 0.38)\",\r\n hint: \"rgba(0, 0, 0, 0.38)\",\r\n },\r\n };\r\n\r\n const vseTypography = {\r\n h1: {\r\n color: vsePalette.primary.main,\r\n },\r\n h2: {\r\n color: vsePalette.primary.main,\r\n },\r\n h3: {\r\n color: vsePalette.primary.main,\r\n },\r\n h4: {\r\n color: vsePalette.primary.main,\r\n },\r\n h5: {\r\n color: vsePalette.primary.main,\r\n },\r\n h6: {\r\n color: vsePalette.primary.main,\r\n },\r\n subtitle1: {\r\n color: vsePalette.secondary.main,\r\n },\r\n subtitle2: {\r\n color: vsePalette.secondary.main,\r\n },\r\n }\r\n\r\n let theme = createTheme({\r\n palette: vsePalette,\r\n typography: vseTypography,\r\n });\r\n\r\n return {\r\n ...theme,\r\n props: {\r\n MuiGrid: {\r\n spacing: 2,\r\n },\r\n MuiPaper: {\r\n elevation: 3,\r\n },\r\n MuiTable: {\r\n size: 'small',\r\n },\r\n MuiToolbar: {\r\n variant: 'dense',\r\n },\r\n },\r\n overrides: {\r\n MuiFormControl: {\r\n root: {\r\n width: '100%',\r\n }\r\n },\r\n MuiGrid: {\r\n container: {\r\n paddingBottom: theme.spacing(2),\r\n },\r\n },\r\n MuiTabs: {\r\n root: {\r\n marginLeft: theme.spacing(1),\r\n },\r\n indicator: {\r\n height: 3,\r\n borderTopLeftRadius: 3,\r\n borderTopRightRadius: 3,\r\n backgroundColor: theme.palette.common.white,\r\n },\r\n },\r\n MuiTab: {\r\n root: {\r\n margin: '0 16px',\r\n minWidth: 0,\r\n padding: 0,\r\n [theme.breakpoints.up('md')]: {\r\n padding: 0,\r\n minWidth: 0,\r\n },\r\n },\r\n },\r\n MuiTable: {\r\n root: {\r\n '& caption': {\r\n captionSide: 'top',\r\n padding: theme.spacing(0, 2, 0, 2),\r\n fontWeight: theme.typography.fontWeightBold,\r\n },\r\n },\r\n },\r\n MuiTableCell: {\r\n head: {\r\n color: vsePalette.secondary.main,\r\n },\r\n },\r\n },\r\n };\r\n}\r\n","// In production, we register a service worker to serve assets from local cache.\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 the \"N+1\" visit to a page, since previously\r\n// cached resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\r\n// This link also includes instructions on opting out of this behavior.\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\nexport default function register() {\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 url = process.env.PUBLIC_URL as string;\r\n const publicUrl = new URL(url, window.location.toString());\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/facebookincubator/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. Lets check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl);\r\n } else {\r\n // Is not local host. Just register service worker\r\n registerValidSW(swUrl);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: string) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing as ServiceWorker;\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the old content will have been purged and\r\n // the fresh content will have been added to the cache.\r\n // It's the perfect time to display a \"New content is\r\n // available; please refresh.\" message in your web app.\r\n console.log('New content is available; please refresh.');\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 }\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) {\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 (response.status === 404 || (contentType && contentType.indexOf('javascript') === -1)) {\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);\r\n }\r\n })\r\n .catch(() => {\r\n console.log('No internet connection found. App is running in offline mode.');\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 * as ReactDOM from 'react-dom';\r\nimport { Provider } from 'react-redux';\r\nimport { ConnectedRouter } from 'connected-react-router';\r\nimport { createBrowserHistory } from 'history';\r\nimport configureStore from './store/configureStore';\r\nimport App from './App';\r\nimport registerServiceWorker from './registerServiceWorker';\r\n\r\n// Create browser history to use in the Redux store\r\nconst baseUrl = document.getElementsByTagName('base')[0].getAttribute('href') as string;\r\nconst history = createBrowserHistory({ basename: baseUrl });\r\n\r\n// Get the application-wide store instance, prepopulating with state from the server where available.\r\nconst store = configureStore(history);\r\n\r\nReactDOM.render(\r\n \r\n \r\n \r\n \r\n ,\r\n document.getElementById('root'));\r\n\r\nregisterServiceWorker();\r\n","import { applyMiddleware, combineReducers, compose, createStore } from 'redux';\r\nimport thunk from 'redux-thunk';\r\nimport { connectRouter, routerMiddleware } from 'connected-react-router';\r\nimport { History } from 'history';\r\nimport { ApplicationState, reducers } from './';\r\n\r\nexport default function configureStore(history: History, initialState?: ApplicationState) {\r\n const middleware = [\r\n thunk,\r\n routerMiddleware(history)\r\n ];\r\n\r\n const rootReducer = combineReducers({\r\n ...reducers,\r\n router: connectRouter(history)\r\n });\r\n\r\n const enhancers = [];\r\n const windowIfDefined = typeof window === 'undefined' ? null : window as any; // eslint-disable-line @typescript-eslint/no-explicit-any\r\n if (windowIfDefined && windowIfDefined.__REDUX_DEVTOOLS_EXTENSION__) {\r\n enhancers.push(windowIfDefined.__REDUX_DEVTOOLS_EXTENSION__());\r\n }\r\n\r\n return createStore(\r\n rootReducer,\r\n initialState,\r\n compose(applyMiddleware(...middleware), ...enhancers)\r\n );\r\n}\r\n"],"sourceRoot":""}