From ada8d0e2672fd2ba44f73f144ed9d011a8dc719b Mon Sep 17 00:00:00 2001 From: Akshaya Date: Tue, 6 Apr 2021 20:28:50 -0700 Subject: [PATCH 01/23] show student offerings --- src/api/offerings.js | 58 +++++++++++++++++++++++++-- src/containers/HomeContainers/Home.js | 4 +- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/api/offerings.js b/src/api/offerings.js index 95691df..3b6a4dc 100644 --- a/src/api/offerings.js +++ b/src/api/offerings.js @@ -1,4 +1,5 @@ import axios from 'axios' +import { result } from 'lodash' import { HTTP_STATUS_CODES, BASE_URL } from '.' import { format } from '../utils/string' import { getCurrentAuthenticatedUser, isUserAuthenticated } from './auth' @@ -28,12 +29,62 @@ export const getOfferingData = async (offeringId) => { return null } + +/////////////////// STUDENT OFFERING FUNCTIONS //////////////////// + + +/** + * Gets the data for an offering from the CT API if the student is authenticated + * @returns The offering data + */ + export const getOfferingsByStudent = async () => { + if (!isUserAuthenticated()) return null + + const url = format(ENDPOINTS.OFFERING, 'ByStudent') + + try { + const resp = await axios.get(url) + if (resp?.status !== HTTP_STATUS_CODES.OK) { + return null + } + return resp.data + } catch (error) { + console.error(error) + } + + return null +} + +/** + * Returns an array of all the offering data for the current user. + * If no user is signed in, null is returned. + * @returns Array of offerings data + */ + export const getOfferingsData = async () => { + const offerings = [] + + const studentOfferings = await getOfferingsByStudent() + if (studentOfferings == null) return null + + for (const entry of studentOfferings) { + const offeringData = await getOfferingData(entry.offering.id) + if (offeringData != null) offerings.push(offeringData) + } + + return offerings +} + + +/////////////////// STARRED OFFERING CALLS ////////////////////// + + + /** * Returns an array of all the starred offering data for the current user. * If no user is signed in, null is returned. * @returns Array of offerings data */ -export const getStarredOfferingsData = async () => { + export const getStarredOfferingsData = async () => { const offerings = [] const starredOfferings = getStarredOfferings() @@ -47,16 +98,17 @@ export const getStarredOfferingsData = async () => { return offerings } + /** * Gets the starred offering course IDs for the current user. * If no user is signed in, null is returned * @returns An object, where each key is the starred course ID and each value is 'starred'. */ -export const getStarredOfferings = () => { + export const getStarredOfferings = () => { if (!isUserAuthenticated()) return null const user = getCurrentAuthenticatedUser() if (user?.metadata?.starredOfferings == null) return null return JSON.parse(user.metadata.starredOfferings) -} +} \ No newline at end of file diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainers/Home.js index 7bf24bc..1067b64 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainers/Home.js @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react' import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' import PropTypes from 'prop-types' -import { getStarredOfferingsData } from '../../api/offerings' +import { getStarredOfferingsData, getOfferingsData } from '../../api/offerings' import CourseCard from '../../components/Cards/CourseCard' import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' @@ -16,7 +16,7 @@ const Home = ({ navigation }) => { useEffect(() => { const fetchCourseInfo = async () => { - const offerings = await getStarredOfferingsData() + const offerings = await getOfferingsData() setCourses(offerings) } fetchCourseInfo() From d9eb64752b472b6214b74399d1b111778b8a4d5b Mon Sep 17 00:00:00 2001 From: Akshaya Date: Tue, 6 Apr 2021 21:47:33 -0700 Subject: [PATCH 02/23] trying to add university dropdown to Home container --- src/containers/HomeContainers/Home.js | 38 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainers/Home.js index 1067b64..f83044d 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainers/Home.js @@ -1,19 +1,20 @@ import React, { useState, useEffect } from 'react' import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' +// import { Picker } from '@react-native-picker/picker'; import PropTypes from 'prop-types' import { getStarredOfferingsData, getOfferingsData } from '../../api/offerings' +// import { getCurrentAuthenticatedUser } from '../../api/auth' import CourseCard from '../../components/Cards/CourseCard' import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' import styles from './Home.style' /** - * Contains the home screen of the application. Lists starred courses and gives the user the ability + * Contains the home screen of the application. Lists courses and gives the user the ability * to search for courses. Clicking on a course shows the playlists for it. */ const Home = ({ navigation }) => { const [courses, setCourses] = useState([]) - useEffect(() => { const fetchCourseInfo = async () => { const offerings = await getOfferingsData() @@ -59,7 +60,37 @@ const Home = ({ navigation }) => { } /** - * Renders all of the users' starred courses into a FlatList + * Render user's login information + */ + // const [universities, setSelectedUniversity] = useState([]); + // useEffect(() => { + // const fetchUniversityInfo = async () => { + // const allUniversities = await getUniversities() + // setSelectedUniversity(allUniversities) + // } + // fetchUniversityInfo() + // }, [setSelectedUniversity]) + + // const renderUniversityDropDown = () => { + // const currentUser = getCurrentAuthenticatedUser() + // const universityId = currentUser.universityId + + // console.log("WERE HERE!!!!!!!!!!!!!!") + // console.log(universities) + // const universityItems = universities.map( (uni) => { + // return + // }) + // return ( setSelectedUniversity(university)} + // mode='dropdown'> + // { universityItems } + // ) + // // return { universityId } + // } + + /** + * Renders all of the users' courses into a FlatList */ const renderStarredCourses = () => { if (courses == null) return null @@ -84,6 +115,7 @@ const Home = ({ navigation }) => { return ( + {/* {renderUniversityDropDown()} */} {renderSwitch()} {renderStarredCourses()} From c1b3359bd96be5fb449ba3bae3449551e799a958 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 7 Apr 2021 01:41:57 -0500 Subject: [PATCH 03/23] Added a university picker and displays all courses available to the student --- package.json | 7 +- src/api/video.js | 54 +++++++++++++ src/containers/HomeContainers/Home.js | 78 ++++++++++++------- .../TranscriptContainer.js | 65 ++++++++++++++++ 4 files changed, 172 insertions(+), 32 deletions(-) create mode 100644 src/api/video.js create mode 100644 src/containers/TranscriptContainer/TranscriptContainer.js diff --git a/package.json b/package.json index 1a1c4b1..1ba74bd 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "dependencies": { "@expo/vector-icons": "^12.0.4", "@react-native-community/masked-view": "0.1.10", + "@react-native-community/picker": "^1.8.1", "@react-native-picker/picker": "1.9.2", "@react-navigation/bottom-tabs": "^5.11.8", "@react-navigation/native": "^5.9.3", @@ -32,15 +33,15 @@ "react-native-elements": "^3.3.2", "react-native-gesture-handler": "^1.10.3", "react-native-navigation": "^7.11.2", - "react-native-picker-select": "^8.0.4", + "react-native-paper": "^4.7.2", + "react-native-picker-select": "8.0.0", "react-native-reanimated": "~1.13.0", "react-native-safe-area-context": "3.1.9", "react-native-screens": "~2.15.2", "react-native-unimodules": "^0.13.0", + "react-native-vector-icons": "^8.1.0", "react-native-web": "^0.15.0", "react-test-renderer": "^17.0.1", - "react-native-paper": "^4.7.2", - "react-native-vector-icons": "^8.1.0", "rn-fetch-blob": "^0.12.0" }, "devDependencies": { diff --git a/src/api/video.js b/src/api/video.js new file mode 100644 index 0000000..55ef3a2 --- /dev/null +++ b/src/api/video.js @@ -0,0 +1,54 @@ +import axios from 'axios' +import { HTTP_STATUS_CODES, BASE_URL } from '.' +import { format } from '../utils/string' + +export const ENDPOINTS = { + TRANSCRIPT: `${BASE_URL}Captions/ByTranscription/{0}`, + MEDIA: `${BASE_URL}Media/{0}` +} + +// export const get = async (transcriptionId) => { +// const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) + +// try { +// const resp = await axios.get(url) +// if (resp?.status !== HTTP_STATUS_CODES.OK) return null +// return resp.data +// } catch (error) { +// console.error(error) +// } + +// return null +// } + +export const getVideoTranscription = async (transcriptionId) => { + const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) + + try { + const resp = await axios.get(url) + if (resp?.status !== HTTP_STATUS_CODES.OK) return null + return resp.data + } catch (error) { + console.error(error) + } + + return null +} + +export const getMedia = async (mediaId) => { + const url = format(ENDPOINTS.MEDIA, mediaId.mediaId) + console.log("URL") + console.log(mediaId) + console.log(url) + + + try { + const resp = await axios.get(url) + if (resp?.status !== HTTP_STATUS_CODES.OK) return null + return resp.data + } catch (error) { + console.error(error) + } + + return null +} \ No newline at end of file diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainers/Home.js index f83044d..bd3dc40 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainers/Home.js @@ -1,9 +1,10 @@ import React, { useState, useEffect } from 'react' import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' -// import { Picker } from '@react-native-picker/picker'; +import { Picker } from '@react-native-community/picker'; import PropTypes from 'prop-types' import { getStarredOfferingsData, getOfferingsData } from '../../api/offerings' -// import { getCurrentAuthenticatedUser } from '../../api/auth' +import { getUniversities } from '../../api/universities' +import { getCurrentAuthenticatedUser } from '../../api/auth' import CourseCard from '../../components/Cards/CourseCard' import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' @@ -62,32 +63,51 @@ const Home = ({ navigation }) => { /** * Render user's login information */ - // const [universities, setSelectedUniversity] = useState([]); - // useEffect(() => { - // const fetchUniversityInfo = async () => { - // const allUniversities = await getUniversities() - // setSelectedUniversity(allUniversities) - // } - // fetchUniversityInfo() - // }, [setSelectedUniversity]) - - // const renderUniversityDropDown = () => { - // const currentUser = getCurrentAuthenticatedUser() - // const universityId = currentUser.universityId - - // console.log("WERE HERE!!!!!!!!!!!!!!") - // console.log(universities) - // const universityItems = universities.map( (uni) => { - // return - // }) - // return ( setSelectedUniversity(university)} - // mode='dropdown'> - // { universityItems } - // ) - // // return { universityId } - // } + const renderUniversityDropDown = () => { + const currentUser = getCurrentAuthenticatedUser() + const universityId = currentUser.universityId + + // Don't need to use useState and useEffect, just need to get the async + const [universities, setAllUniversities] = useState([]) + useEffect(() => { + const fetchUniversities = async () => { + const allUnis = await getUniversities() + setAllUniversities(allUnis) + } + fetchUniversities() + }, [setAllUniversities]) + + + // var currUniversity = null + // for (var i = 0; i < universities.length; i++) { + // console.log(universities[i]) + // if (universities[i].id == universityId) { + // currUniversity = universities[i] //.id + // } + // } + // console.log("Current university") + // console.log(currUniversity) + + let universityItems = universities.map( (uni) => { + return + }); + + const [university, setUniversity] = useState(universityId) + + const onUniversitySelected = (universityId) => { + // Reload the page for the selected universityId + setUniversity(universityId) + console.log("GOT HERE") + console.log(universityId) + } + + return ( onUniversitySelected(universityId)}> + { universityItems } + ) + } /** * Renders all of the users' courses into a FlatList @@ -115,7 +135,7 @@ const Home = ({ navigation }) => { return ( - {/* {renderUniversityDropDown()} */} + {renderUniversityDropDown()} {renderSwitch()} {renderStarredCourses()} diff --git a/src/containers/TranscriptContainer/TranscriptContainer.js b/src/containers/TranscriptContainer/TranscriptContainer.js new file mode 100644 index 0000000..43483e0 --- /dev/null +++ b/src/containers/TranscriptContainer/TranscriptContainer.js @@ -0,0 +1,65 @@ +import React, { useState, useEffect } from 'react' +import { TouchableNativeFeedback, FlatList, View } from 'react-native' +import PropTypes from 'prop-types' +import { ListItem } from 'react-native-elements' +import { getVideoTranscription } from '../../api/universities' +import { STACK_SCREENS } from '../CTNavigationContainer/index' + +/** + * NEW CONTENT HERE!!! + * + * Contains the course screen of the application. Lists all courses + * that participate (i.e. instructor has registered the courses and + * uploads videos) in Class Transcribe. Clicking on a course shows the user's + * starred offerings for it. + */ +const TranscriptContainer = ({ navigation, transcriptId }) => { + const [transcript, setTranscript] = useState([]) + + useEffect(() => { + const fetchTranscriptInfo = async () => { + const videoTranscript = await getVideoTranscription(departmentId) + setTranscript(videoTranscript) + } + + fetchTranscriptInfo() + }, [setTranscript]) + + const onLineSelected = (transcriptLine) => { + // Allow user to edit the line and save/cancel it + // somewhat like how web is structured + + } + + /** + * Renders all of the users' starred courses into a FlatList + */ + const renderItem = ({ item }) => { + return ( + onLineSelected(item.text)}> + + + + {item.text} + + + + + ) + } + + return ( + + + + ) +} + +TranscriptContainer.propTypes = { + transcriptId: PropTypes.string.isRequired, + navigation: PropTypes.shape({ + push: PropTypes.func.isRequired, + }).isRequired, +} + +export default TranscriptContainer \ No newline at end of file From e2ac032649a07b2f074e82e48ad43302294ca08c Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 12:34:02 -0700 Subject: [PATCH 04/23] locking picker to 8.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce8e9a7..a11fec3 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react-native-gesture-handler": "^1.10.3", "react-native-navigation": "^7.11.2", "react-native-paper": "^4.7.2", - "react-native-picker-select": "^8.0.4", + "react-native-picker-select": "8.0.0", "react-native-reanimated": "~1.13.0", "react-native-safe-area-context": "3.1.9", "react-native-screens": "~2.15.2", From 1138515831e9c3ec9e2d8dcead297c190008351a Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 12:50:16 -0700 Subject: [PATCH 05/23] added new string test to check for null --- __tests__/utils/string-test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/__tests__/utils/string-test.js b/__tests__/utils/string-test.js index 8857dc9..046c4d4 100644 --- a/__tests__/utils/string-test.js +++ b/__tests__/utils/string-test.js @@ -31,6 +31,10 @@ describe('Check formatting', () => { }) describe('Check truncation', () => { + test('check null string', () => { + expect(truncateString(null, 10)).toBe('') + }) + test('already short enough', () => { expect(truncateString('hello', 10)).toBe('hello') }) From 65cf557d328f366fb45720b64c6dc578551897e1 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 13:58:10 -0700 Subject: [PATCH 06/23] fixing null string --- src/utils/string.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/string.js b/src/utils/string.js index d7784a8..5031898 100644 --- a/src/utils/string.js +++ b/src/utils/string.js @@ -27,6 +27,7 @@ const replaceAll = (string, search, replace) => { * @returns */ export const truncateString = (str, maxLength) => { + if (!str) return "" if (str.length <= maxLength) return str const truncated = `${str.substring(0, maxLength)}...` From ea91ba9748693d4ffb41e1e9e723564cd0992c18 Mon Sep 17 00:00:00 2001 From: mlw6 Date: Wed, 7 Apr 2021 15:58:57 -0500 Subject: [PATCH 07/23] Get userdata from CT Website --- src/containers/LoginContainer/LoginContainer.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/containers/LoginContainer/LoginContainer.js b/src/containers/LoginContainer/LoginContainer.js index 6c685b6..a6f5737 100644 --- a/src/containers/LoginContainer/LoginContainer.js +++ b/src/containers/LoginContainer/LoginContainer.js @@ -35,6 +35,7 @@ const LoginContainer = ({ onAuthLevelChange }) => { } window.ReactNativeWebView.postMessage(localStorage["authToken"]) + window.ReactNativeWebView.postMessage(userInfoString) } getToken(); @@ -48,9 +49,16 @@ const LoginContainer = ({ onAuthLevelChange }) => { const onBrowserMessage = async (event) => { if (!event?.nativeEvent?.data) return - setAuthToken(event.nativeEvent.data) - await getUserMetadata() - onAuthLevelChange(isUserAuthenticated()) + const data = event.nativeEvent.data + + try { + const userData = JSON.parse(data) + } catch (e) { + console.log("CALLED " + data) + setAuthToken(data) + await getUserMetadata() + onAuthLevelChange(isUserAuthenticated()) + } } return ( From b6b2b8ea0cf41555337e73758c90327b7b16fc8c Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 14:20:30 -0700 Subject: [PATCH 08/23] set user data when logging in and initialize university to start search with --- src/api/auth.js | 7 +++++++ src/containers/HomeContainers/Home.js | 12 ++---------- src/containers/LoginContainer/LoginContainer.js | 4 ++-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/api/auth.js b/src/api/auth.js index 191d639..c5dd02b 100644 --- a/src/api/auth.js +++ b/src/api/auth.js @@ -50,6 +50,13 @@ export const setAuthToken = (token) => { currentAuthenticatedUser.authToken = token } +export const setUserData= (userData) => { + if (!currentAuthenticatedUser) currentAuthenticatedUser = {} + currentAuthenticatedUser.userId = userData.userId + currentAuthenticatedUser.universityId = userData.universityId + currentAuthenticatedUser.emailId = userData.emailId +} + /** * Returns the signed in user's data or null if no one is signed in. * See @currentAuthenticatedUser for the attributes returned in the object diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainers/Home.js index 0f55301..9b8e14e 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainers/Home.js @@ -64,6 +64,7 @@ const Home = ({ navigation }) => { */ const renderUniversityDropDown = () => { const currentUser = getCurrentAuthenticatedUser() + console.log(currentUser) const universityId = currentUser.universityId // Don't need to use useState and useEffect, just need to get the async @@ -76,16 +77,7 @@ const Home = ({ navigation }) => { fetchUniversities() }, [setAllUniversities]) - - // var currUniversity = null - // for (var i = 0; i < universities.length; i++) { - // console.log(universities[i]) - // if (universities[i].id == universityId) { - // currUniversity = universities[i] //.id - // } - // } - // console.log("Current university") - // console.log(currUniversity) + let universityItems = universities.map( (uni) => { return diff --git a/src/containers/LoginContainer/LoginContainer.js b/src/containers/LoginContainer/LoginContainer.js index a6f5737..d722801 100644 --- a/src/containers/LoginContainer/LoginContainer.js +++ b/src/containers/LoginContainer/LoginContainer.js @@ -1,7 +1,7 @@ import React from 'react' import PropTypes from 'prop-types' import WebView from 'react-native-webview' -import { getUserMetadata, isUserAuthenticated, setAuthToken } from '../../api/auth' +import { getUserMetadata, isUserAuthenticated, setAuthToken, setUserData } from '../../api/auth' import { FILE_SERVER_BASE_URL } from '../../constants' /** @@ -53,8 +53,8 @@ const LoginContainer = ({ onAuthLevelChange }) => { try { const userData = JSON.parse(data) + setUserData(userData) } catch (e) { - console.log("CALLED " + data) setAuthToken(data) await getUserMetadata() onAuthLevelChange(isUserAuthenticated()) From 935d0aee3e979ef4891ce961163036ee0d2f04f6 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 14:21:28 -0700 Subject: [PATCH 09/23] changing naivgator to navigator --- __tests__/frontend/PlaylistContainer-test.js | 8 ++++---- .../CTNavigationContainer/CTNavigationContainer.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/__tests__/frontend/PlaylistContainer-test.js b/__tests__/frontend/PlaylistContainer-test.js index c8f176e..c35c8d2 100644 --- a/__tests__/frontend/PlaylistContainer-test.js +++ b/__tests__/frontend/PlaylistContainer-test.js @@ -77,7 +77,7 @@ describe('Check videos rendering', () => { describe('Check video navigation', () => { const playlistId = '51519746-aa6c-485c-9894-549959c457b5' - const mockNaivgator = { push: jest.fn() } + const mockNavigator = { push: jest.fn() } test('when clicking on first item', async () => { mock @@ -85,7 +85,7 @@ describe('Check video navigation', () => { .reply(HTTP_STATUS_CODES.OK, VIDEOS_BY_PLAYLIST_RESPONSE) const { queryAllByA11yRole } = render( - + ) const videos = await waitFor(() => queryAllByA11yRole('button')) expect(videos.length).not.toBe(0) @@ -94,7 +94,7 @@ describe('Check video navigation', () => { const firstVideo = VIDEOS_BY_PLAYLIST_RESPONSE.medias.find((v) => v.index === 0) const expectedVideoUrl = FILE_SERVER_BASE_URL + firstVideo.video.video1Path - expect(mockNaivgator.push).toHaveBeenCalled() - expect(mockNaivgator.push).toHaveBeenCalledWith(STACK_SCREENS.VIDEO, { url: expectedVideoUrl }) + expect(mockNavigator.push).toHaveBeenCalled() + expect(mockNavigator.push).toHaveBeenCalledWith(STACK_SCREENS.VIDEO, { url: expectedVideoUrl }) }) }) diff --git a/src/containers/CTNavigationContainer/CTNavigationContainer.js b/src/containers/CTNavigationContainer/CTNavigationContainer.js index cdebbe5..9dbfe11 100644 --- a/src/containers/CTNavigationContainer/CTNavigationContainer.js +++ b/src/containers/CTNavigationContainer/CTNavigationContainer.js @@ -19,7 +19,7 @@ const Stack = createStackNavigator() /** * The navigator of the home tab. Contains a stack navigator. */ -const HomeNaivgator = () => { +const HomeNavigator = () => { return ( @@ -124,7 +124,7 @@ const CTNavigationContainer = () => { /> ( From 7883901319c6882b21328bf8edfb5a1923d1111f Mon Sep 17 00:00:00 2001 From: Akshaya Date: Wed, 7 Apr 2021 14:39:20 -0700 Subject: [PATCH 10/23] removing university, dept, course from app navigator --- .../CTNavigationContainer/CTNavigationContainer.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/containers/CTNavigationContainer/CTNavigationContainer.js b/src/containers/CTNavigationContainer/CTNavigationContainer.js index 9dbfe11..c54874c 100644 --- a/src/containers/CTNavigationContainer/CTNavigationContainer.js +++ b/src/containers/CTNavigationContainer/CTNavigationContainer.js @@ -91,10 +91,7 @@ const VideoView = ({ route }) => { */ const CourseNavigator = () => { return ( - - - - + From 5a671ed0edf3dbe24be2d0120a4a357019358a8b Mon Sep 17 00:00:00 2001 From: Akshaya Date: Fri, 9 Apr 2021 18:17:07 -0700 Subject: [PATCH 11/23] more changes --- src/api/auth.js | 2 +- src/api/offerings.js | 20 +++--- src/api/video.js | 59 +++++++++-------- src/containers/HomeContainers/Home.js | 63 ++++++++++--------- .../LoginContainer/LoginContainer.js | 6 +- .../TranscriptContainer.js | 9 +-- src/utils/string.js | 2 +- 7 files changed, 76 insertions(+), 85 deletions(-) diff --git a/src/api/auth.js b/src/api/auth.js index c5dd02b..9e5cfd2 100644 --- a/src/api/auth.js +++ b/src/api/auth.js @@ -50,7 +50,7 @@ export const setAuthToken = (token) => { currentAuthenticatedUser.authToken = token } -export const setUserData= (userData) => { +export const setUserData = (userData) => { if (!currentAuthenticatedUser) currentAuthenticatedUser = {} currentAuthenticatedUser.userId = userData.userId currentAuthenticatedUser.universityId = userData.universityId diff --git a/src/api/offerings.js b/src/api/offerings.js index e5ab63f..cdb0344 100644 --- a/src/api/offerings.js +++ b/src/api/offerings.js @@ -29,15 +29,13 @@ export const getOfferingData = async (offeringId) => { return null } - -/////////////////// STUDENT OFFERING FUNCTIONS //////////////////// - +/// //////////////// STUDENT OFFERING FUNCTIONS //////////////////// /** * Gets the data for an offering from the CT API if the student is authenticated * @returns The offering data */ - export const getOfferingsByStudent = async () => { +export const getOfferingsByStudent = async () => { if (!isUserAuthenticated()) return null const url = format(ENDPOINTS.OFFERING, 'ByStudent') @@ -60,7 +58,7 @@ export const getOfferingData = async (offeringId) => { * If no user is signed in, null is returned. * @returns Array of offerings data */ - export const getOfferingsData = async () => { +export const getOfferingsData = async () => { const offerings = [] const studentOfferings = await getOfferingsByStudent() @@ -74,17 +72,14 @@ export const getOfferingData = async (offeringId) => { return offerings } - -/////////////////// STARRED OFFERING CALLS ////////////////////// - - +/// //////////////// STARRED OFFERING CALLS ////////////////////// /** * Returns an array of all the starred offering data for the current user. * If no user is signed in, null is returned. * @returns Array of offerings data */ - export const getStarredOfferingsData = async () => { +export const getStarredOfferingsData = async () => { const offerings = [] const starredOfferings = getStarredOfferings() @@ -98,17 +93,16 @@ export const getOfferingData = async (offeringId) => { return offerings } - /** * Gets the starred offering course IDs for the current user. * If no user is signed in, null is returned * @returns An object, where each key is the starred course ID and each value is 'starred'. */ - export const getStarredOfferings = () => { +export const getStarredOfferings = () => { if (!isUserAuthenticated()) return null const user = getCurrentAuthenticatedUser() if (user?.metadata?.starredOfferings == null) return null return JSON.parse(user.metadata.starredOfferings) -} \ No newline at end of file +} diff --git a/src/api/video.js b/src/api/video.js index 55ef3a2..7a3b7d6 100644 --- a/src/api/video.js +++ b/src/api/video.js @@ -4,12 +4,12 @@ import { format } from '../utils/string' export const ENDPOINTS = { TRANSCRIPT: `${BASE_URL}Captions/ByTranscription/{0}`, - MEDIA: `${BASE_URL}Media/{0}` + MEDIA: `${BASE_URL}Media/{0}`, } // export const get = async (transcriptionId) => { // const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) - + // try { // const resp = await axios.get(url) // if (resp?.status !== HTTP_STATUS_CODES.OK) return null @@ -17,38 +17,37 @@ export const ENDPOINTS = { // } catch (error) { // console.error(error) // } - + // return null // } export const getVideoTranscription = async (transcriptionId) => { - const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) - - try { - const resp = await axios.get(url) - if (resp?.status !== HTTP_STATUS_CODES.OK) return null - return resp.data - } catch (error) { - console.error(error) - } - - return null + const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) + + try { + const resp = await axios.get(url) + if (resp?.status !== HTTP_STATUS_CODES.OK) return null + return resp.data + } catch (error) { + console.error(error) + } + + return null } export const getMedia = async (mediaId) => { - const url = format(ENDPOINTS.MEDIA, mediaId.mediaId) - console.log("URL") - console.log(mediaId) - console.log(url) - - - try { - const resp = await axios.get(url) - if (resp?.status !== HTTP_STATUS_CODES.OK) return null - return resp.data - } catch (error) { - console.error(error) - } - - return null -} \ No newline at end of file + const url = format(ENDPOINTS.MEDIA, mediaId.mediaId) + console.log('URL') + console.log(mediaId) + console.log(url) + + try { + const resp = await axios.get(url) + if (resp?.status !== HTTP_STATUS_CODES.OK) return null + return resp.data + } catch (error) { + console.error(error) + } + + return null +} diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainers/Home.js index 9b8e14e..26556aa 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainers/Home.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react' import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' -import { Picker } from '@react-native-community/picker'; +import { Picker } from '@react-native-community/picker' import PropTypes from 'prop-types' import { getStarredOfferingsData, getOfferingsData } from '../../api/offerings' import { getUniversities } from '../../api/universities' @@ -63,41 +63,42 @@ const Home = ({ navigation }) => { * Render user's login information */ const renderUniversityDropDown = () => { - const currentUser = getCurrentAuthenticatedUser() - console.log(currentUser) - const universityId = currentUser.universityId - - // Don't need to use useState and useEffect, just need to get the async - const [universities, setAllUniversities] = useState([]) - useEffect(() => { - const fetchUniversities = async () => { - const allUnis = await getUniversities() - setAllUniversities(allUnis) - } - fetchUniversities() - }, [setAllUniversities]) - - + const currentUser = getCurrentAuthenticatedUser() + console.log(currentUser) + const universityId = currentUser.universityId + + // Don't need to use useState and useEffect, just need to get the async + const [universities, setAllUniversities] = useState([]) + useEffect(() => { + const fetchUniversities = async () => { + const allUnis = await getUniversities() + setAllUniversities(allUnis) + } + fetchUniversities() + }, [setAllUniversities]) - let universityItems = universities.map( (uni) => { - return - }); + const universityItems = universities.map((uni) => { + return + }) - const [university, setUniversity] = useState(universityId) + const [university, setUniversity] = useState(universityId) - const onUniversitySelected = (universityId) => { - // Reload the page for the selected universityId - setUniversity(universityId) - console.log("GOT HERE") - console.log(universityId) - } + const onUniversitySelected = (universityId) => { + // Reload the page for the selected universityId + setUniversity(universityId) + console.log('GOT HERE') + console.log(universityId) + } - return ( onUniversitySelected(universityId)}> - { universityItems } - ) + onValueChange={(universityId) => onUniversitySelected(universityId)} + > + {universityItems} + + ) } /** diff --git a/src/containers/LoginContainer/LoginContainer.js b/src/containers/LoginContainer/LoginContainer.js index d722801..e5b961f 100644 --- a/src/containers/LoginContainer/LoginContainer.js +++ b/src/containers/LoginContainer/LoginContainer.js @@ -55,9 +55,9 @@ const LoginContainer = ({ onAuthLevelChange }) => { const userData = JSON.parse(data) setUserData(userData) } catch (e) { - setAuthToken(data) - await getUserMetadata() - onAuthLevelChange(isUserAuthenticated()) + setAuthToken(data) + await getUserMetadata() + onAuthLevelChange(isUserAuthenticated()) } } diff --git a/src/containers/TranscriptContainer/TranscriptContainer.js b/src/containers/TranscriptContainer/TranscriptContainer.js index 43483e0..d5c0a06 100644 --- a/src/containers/TranscriptContainer/TranscriptContainer.js +++ b/src/containers/TranscriptContainer/TranscriptContainer.js @@ -7,7 +7,7 @@ import { STACK_SCREENS } from '../CTNavigationContainer/index' /** * NEW CONTENT HERE!!! - * + * * Contains the course screen of the application. Lists all courses * that participate (i.e. instructor has registered the courses and * uploads videos) in Class Transcribe. Clicking on a course shows the user's @@ -28,7 +28,6 @@ const TranscriptContainer = ({ navigation, transcriptId }) => { const onLineSelected = (transcriptLine) => { // Allow user to edit the line and save/cancel it // somewhat like how web is structured - } /** @@ -39,9 +38,7 @@ const TranscriptContainer = ({ navigation, transcriptId }) => { onLineSelected(item.text)}> - - {item.text} - + {item.text} @@ -62,4 +59,4 @@ TranscriptContainer.propTypes = { }).isRequired, } -export default TranscriptContainer \ No newline at end of file +export default TranscriptContainer diff --git a/src/utils/string.js b/src/utils/string.js index 5031898..9baf6b8 100644 --- a/src/utils/string.js +++ b/src/utils/string.js @@ -27,7 +27,7 @@ const replaceAll = (string, search, replace) => { * @returns */ export const truncateString = (str, maxLength) => { - if (!str) return "" + if (!str) return '' if (str.length <= maxLength) return str const truncated = `${str.substring(0, maxLength)}...` From e6556692ad890165220f1c00f6b8c20d325a0419 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Fri, 9 Apr 2021 22:49:18 -0700 Subject: [PATCH 12/23] filtering uni in dpicker functional --- .../CTNavigationContainer.js | 14 ++++--- .../{HomeContainers => HomeContainer}/Home.js | 42 +++++++++++++++---- .../Home.style.js | 0 .../PlaylistContainer/PlaylistContainer.js | 2 +- 4 files changed, 44 insertions(+), 14 deletions(-) rename src/containers/{HomeContainers => HomeContainer}/Home.js (79%) rename src/containers/{HomeContainers => HomeContainer}/Home.style.js (100%) diff --git a/src/containers/CTNavigationContainer/CTNavigationContainer.js b/src/containers/CTNavigationContainer/CTNavigationContainer.js index 19ddb60..dedd193 100644 --- a/src/containers/CTNavigationContainer/CTNavigationContainer.js +++ b/src/containers/CTNavigationContainer/CTNavigationContainer.js @@ -5,7 +5,7 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' import { createStackNavigator } from '@react-navigation/stack' import { MaterialCommunityIcons } from '@expo/vector-icons' import { STACK_SCREENS } from './index' -import Home from '../HomeContainers/Home' +import Home from '../HomeContainer/Home' import CoursePlaylistsContainer from '../CoursePlaylistsContainer/CoursePlaylistsContainer' import VideoContainer from '../VideoContainer/VideoContainer' import UniversityListContainer from '../UniversityListContainer/UniversityListContainer' @@ -21,8 +21,8 @@ const Stack = createStackNavigator() */ const HomeNavigator = () => { return ( - - + + @@ -30,6 +30,10 @@ const HomeNavigator = () => { ) } +const HomeView = ({ navigation }) => { + return +} + /** * Wraps the UniversityListContainer so that it can * receive the proper props @@ -91,8 +95,8 @@ const VideoView = ({ route }) => { */ const CourseNavigator = () => { return ( - - + + diff --git a/src/containers/HomeContainers/Home.js b/src/containers/HomeContainer/Home.js similarity index 79% rename from src/containers/HomeContainers/Home.js rename to src/containers/HomeContainer/Home.js index 26556aa..35e13e3 100644 --- a/src/containers/HomeContainers/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -15,11 +15,29 @@ import styles from './Home.style' * to search for courses. Clicking on a course shows the playlists for it. */ const Home = ({ navigation }) => { + const currentUser = getCurrentAuthenticatedUser() + var universityId = currentUser.universityId + + const filterCourses = (offerings, universityId) => { + var newOfferings = [] + for (const i in offerings) { + if (offerings[i].term.universityId == universityId) { + newOfferings.push(offerings[i]) + } + } + + return newOfferings + } + const [courses, setCourses] = useState([]) useEffect(() => { const fetchCourseInfo = async () => { const offerings = await getOfferingsData() - setCourses(offerings) + const studentCourses = filterCourses(offerings, universityId) + + console.log(studentCourses) + + setCourses(studentCourses) } fetchCourseInfo() }, [setCourses]) @@ -60,13 +78,9 @@ const Home = ({ navigation }) => { } /** - * Render user's login information + * Render universities */ const renderUniversityDropDown = () => { - const currentUser = getCurrentAuthenticatedUser() - console.log(currentUser) - const universityId = currentUser.universityId - // Don't need to use useState and useEffect, just need to get the async const [universities, setAllUniversities] = useState([]) useEffect(() => { @@ -78,16 +92,28 @@ const Home = ({ navigation }) => { }, [setAllUniversities]) const universityItems = universities.map((uni) => { - return + return }) const [university, setUniversity] = useState(universityId) - const onUniversitySelected = (universityId) => { + const onUniversitySelected = async (universityId) => { // Reload the page for the selected universityId setUniversity(universityId) console.log('GOT HERE') + // console.log(universityId) + const newUnicourses = await getOfferingsData() + const newCourses = filterCourses(newUnicourses, universityId) console.log(universityId) + // console.log(newCourses) + try { + setCourses(newCourses) + } catch (error) { + console.error(error) + } + + renderCourseItem() + // window.location.reload() } return ( diff --git a/src/containers/HomeContainers/Home.style.js b/src/containers/HomeContainer/Home.style.js similarity index 100% rename from src/containers/HomeContainers/Home.style.js rename to src/containers/HomeContainer/Home.style.js diff --git a/src/containers/PlaylistContainer/PlaylistContainer.js b/src/containers/PlaylistContainer/PlaylistContainer.js index d0bce75..0681bb1 100644 --- a/src/containers/PlaylistContainer/PlaylistContainer.js +++ b/src/containers/PlaylistContainer/PlaylistContainer.js @@ -14,7 +14,7 @@ const PlaylistContainer = ({ navigation, playlistId }) => { const response = await getVideosByPlaylist(playlistId) if (!response) return const sortedVideos = response.medias.sort((a, b) => a.index - b.index) - // Get rid of undefined indexs + // Get rid of undefined indices for (let i = 0; i < sortedVideos.length; i += 1) { sortedVideos[i].index = i } From 0957915f9fe855bc6dfc3906d495a95ed5a6b61b Mon Sep 17 00:00:00 2001 From: Akshaya Date: Fri, 9 Apr 2021 23:35:19 -0700 Subject: [PATCH 13/23] figuired out 401 errors and fixed virutalized list warning --- src/containers/HomeContainer/Home.js | 29 ++++++++++++---------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index 35e13e3..e5cd1c5 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -33,10 +33,7 @@ const Home = ({ navigation }) => { useEffect(() => { const fetchCourseInfo = async () => { const offerings = await getOfferingsData() - const studentCourses = filterCourses(offerings, universityId) - - console.log(studentCourses) - + const studentCourses = filterCourses(offerings, universityId) setCourses(studentCourses) } fetchCourseInfo() @@ -70,9 +67,9 @@ const Home = ({ navigation }) => { /> - - - + {/* + + */} ) } @@ -81,7 +78,6 @@ const Home = ({ navigation }) => { * Render universities */ const renderUniversityDropDown = () => { - // Don't need to use useState and useEffect, just need to get the async const [universities, setAllUniversities] = useState([]) useEffect(() => { const fetchUniversities = async () => { @@ -92,7 +88,10 @@ const Home = ({ navigation }) => { }, [setAllUniversities]) const universityItems = universities.map((uni) => { - return + return }) const [university, setUniversity] = useState(universityId) @@ -100,20 +99,14 @@ const Home = ({ navigation }) => { const onUniversitySelected = async (universityId) => { // Reload the page for the selected universityId setUniversity(universityId) - console.log('GOT HERE') - // console.log(universityId) const newUnicourses = await getOfferingsData() const newCourses = filterCourses(newUnicourses, universityId) - console.log(universityId) - // console.log(newCourses) try { setCourses(newCourses) + renderCourseItem() } catch (error) { console.error(error) } - - renderCourseItem() - // window.location.reload() } return ( @@ -133,7 +126,9 @@ const Home = ({ navigation }) => { const renderStarredCourses = () => { if (courses == null) return null - return + return index.toString()} + data={courses} + renderItem={renderCourseItem} /> } const [mode, setMode] = useState(false) From faf7a78fd6064f9a79a351641e3fcb7f80c61e10 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 00:00:32 -0700 Subject: [PATCH 14/23] linting issues --- src/api/video.js | 24 ++--------- .../CTNavigationContainer.js | 41 +++---------------- src/containers/HomeContainer/Home.js | 40 +++++++++--------- 3 files changed, 30 insertions(+), 75 deletions(-) diff --git a/src/api/video.js b/src/api/video.js index 7a3b7d6..c589f0b 100644 --- a/src/api/video.js +++ b/src/api/video.js @@ -1,26 +1,13 @@ import axios from 'axios' -import { HTTP_STATUS_CODES, BASE_URL } from '.' +import { HTTP_STATUS_CODES } from '.' +import { API_BASE_URL } from '../constants' import { format } from '../utils/string' export const ENDPOINTS = { - TRANSCRIPT: `${BASE_URL}Captions/ByTranscription/{0}`, - MEDIA: `${BASE_URL}Media/{0}`, + TRANSCRIPT: `${API_BASE_URL}Captions/ByTranscription/{0}`, + MEDIA: `${API_BASE_URL}Media/{0}`, } -// export const get = async (transcriptionId) => { -// const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) - -// try { -// const resp = await axios.get(url) -// if (resp?.status !== HTTP_STATUS_CODES.OK) return null -// return resp.data -// } catch (error) { -// console.error(error) -// } - -// return null -// } - export const getVideoTranscription = async (transcriptionId) => { const url = format(ENDPOINTS.TRANSCRIPT, transcriptionId) @@ -37,9 +24,6 @@ export const getVideoTranscription = async (transcriptionId) => { export const getMedia = async (mediaId) => { const url = format(ENDPOINTS.MEDIA, mediaId.mediaId) - console.log('URL') - console.log(mediaId) - console.log(url) try { const resp = await axios.get(url) diff --git a/src/containers/CTNavigationContainer/CTNavigationContainer.js b/src/containers/CTNavigationContainer/CTNavigationContainer.js index dedd193..03f57b9 100644 --- a/src/containers/CTNavigationContainer/CTNavigationContainer.js +++ b/src/containers/CTNavigationContainer/CTNavigationContainer.js @@ -8,10 +8,7 @@ import { STACK_SCREENS } from './index' import Home from '../HomeContainer/Home' import CoursePlaylistsContainer from '../CoursePlaylistsContainer/CoursePlaylistsContainer' import VideoContainer from '../VideoContainer/VideoContainer' -import UniversityListContainer from '../UniversityListContainer/UniversityListContainer' import PlaylistContainer from '../PlaylistContainer/PlaylistContainer' -import DepartmentListContainer from '../DepartmentListContainer/DepartmentListContainer' -import CourseListContainer from '../CourseListContainer/CourseListContainer' const Tab = createBottomTabNavigator() const Stack = createStackNavigator() @@ -21,7 +18,7 @@ const Stack = createStackNavigator() */ const HomeNavigator = () => { return ( - + @@ -30,40 +27,12 @@ const HomeNavigator = () => { ) } -const HomeView = ({ navigation }) => { - return -} - -/** - * Wraps the UniversityListContainer so that it can - * receive the proper props - */ -const UniversityListView = ({ navigation }) => { - return -} - -/** - * Wraps the DepartmentListContainer so that it can - * receive the proper props - */ -const DepartmentListView = ({ navigation, route }) => { - return ( - - ) -} - /** - * Wraps the CourseListContainer so that it can + * Wraps the Home container so that it can * receive the proper props */ -const CourseListView = ({ navigation, route }) => { - return ( - - ) +const HomeView = ({ navigation }) => { + return } /** @@ -95,7 +64,7 @@ const VideoView = ({ route }) => { */ const CourseNavigator = () => { return ( - + diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index e5cd1c5..6d5bb35 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -2,11 +2,11 @@ import React, { useState, useEffect } from 'react' import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' import { Picker } from '@react-native-community/picker' import PropTypes from 'prop-types' -import { getStarredOfferingsData, getOfferingsData } from '../../api/offerings' +import { getOfferingsData } from '../../api/offerings' import { getUniversities } from '../../api/universities' import { getCurrentAuthenticatedUser } from '../../api/auth' import CourseCard from '../../components/Cards/CourseCard' -import Recommend from '../../components/Recommend/Recommend' +// import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' import styles from './Home.style' @@ -16,16 +16,16 @@ import styles from './Home.style' */ const Home = ({ navigation }) => { const currentUser = getCurrentAuthenticatedUser() - var universityId = currentUser.universityId + const universityId = currentUser.universityId - const filterCourses = (offerings, universityId) => { - var newOfferings = [] + const filterCourses = (offerings) => { + const newOfferings = [] for (const i in offerings) { - if (offerings[i].term.universityId == universityId) { + if (offerings[i].term.universityId === universityId) { newOfferings.push(offerings[i]) } } - + return newOfferings } @@ -33,7 +33,7 @@ const Home = ({ navigation }) => { useEffect(() => { const fetchCourseInfo = async () => { const offerings = await getOfferingsData() - const studentCourses = filterCourses(offerings, universityId) + const studentCourses = filterCourses(offerings) setCourses(studentCourses) } fetchCourseInfo() @@ -88,19 +88,17 @@ const Home = ({ navigation }) => { }, [setAllUniversities]) const universityItems = universities.map((uni) => { - return + return }) const [university, setUniversity] = useState(universityId) - const onUniversitySelected = async (universityId) => { + const onUniversitySelected = async (newUniversityId) => { // Reload the page for the selected universityId - setUniversity(universityId) + setUniversity(newUniversityId) const newUnicourses = await getOfferingsData() - const newCourses = filterCourses(newUnicourses, universityId) + const newCourses = filterCourses(newUnicourses) + try { setCourses(newCourses) renderCourseItem() @@ -113,7 +111,7 @@ const Home = ({ navigation }) => { onUniversitySelected(universityId)} + onValueChange={(newUniversityId) => onUniversitySelected(newUniversityId)} > {universityItems} @@ -126,9 +124,13 @@ const Home = ({ navigation }) => { const renderStarredCourses = () => { if (courses == null) return null - return index.toString()} - data={courses} - renderItem={renderCourseItem} /> + return ( + index.toString()} + data={courses} + renderItem={renderCourseItem} + /> + ) } const [mode, setMode] = useState(false) From f0e41d382874607c693046638793a0866ce0cc08 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 10 Apr 2021 02:13:52 -0500 Subject: [PATCH 15/23] fixing linters --- __tests__/frontend/PlaylistContainer-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/frontend/PlaylistContainer-test.js b/__tests__/frontend/PlaylistContainer-test.js index 1bb8687..1f268f3 100644 --- a/__tests__/frontend/PlaylistContainer-test.js +++ b/__tests__/frontend/PlaylistContainer-test.js @@ -91,8 +91,8 @@ describe('Check video navigation', () => { fireEvent.press(videos[0]) - expect(mockNaivgator.push).toHaveBeenCalled() - expect(mockNaivgator.push).toHaveBeenCalledWith(STACK_SCREENS.VIDEO, { + expect(mockNavigator.push).toHaveBeenCalled() + expect(mockNavigator.push).toHaveBeenCalledWith(STACK_SCREENS.VIDEO, { videos: VIDEOS_BY_PLAYLIST_RESPONSE.medias, index: 0, }) From 2ece48cd8c2acbdd73c9b8f47f35417d85253255 Mon Sep 17 00:00:00 2001 From: Akshaya Jagannadharao Date: Sat, 10 Apr 2021 00:19:04 -0700 Subject: [PATCH 16/23] Delete src/containers/TranscriptContainer directory Transcript container will be a new branch for the next iteration --- .../TranscriptContainer.js | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 src/containers/TranscriptContainer/TranscriptContainer.js diff --git a/src/containers/TranscriptContainer/TranscriptContainer.js b/src/containers/TranscriptContainer/TranscriptContainer.js deleted file mode 100644 index d5c0a06..0000000 --- a/src/containers/TranscriptContainer/TranscriptContainer.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { TouchableNativeFeedback, FlatList, View } from 'react-native' -import PropTypes from 'prop-types' -import { ListItem } from 'react-native-elements' -import { getVideoTranscription } from '../../api/universities' -import { STACK_SCREENS } from '../CTNavigationContainer/index' - -/** - * NEW CONTENT HERE!!! - * - * Contains the course screen of the application. Lists all courses - * that participate (i.e. instructor has registered the courses and - * uploads videos) in Class Transcribe. Clicking on a course shows the user's - * starred offerings for it. - */ -const TranscriptContainer = ({ navigation, transcriptId }) => { - const [transcript, setTranscript] = useState([]) - - useEffect(() => { - const fetchTranscriptInfo = async () => { - const videoTranscript = await getVideoTranscription(departmentId) - setTranscript(videoTranscript) - } - - fetchTranscriptInfo() - }, [setTranscript]) - - const onLineSelected = (transcriptLine) => { - // Allow user to edit the line and save/cancel it - // somewhat like how web is structured - } - - /** - * Renders all of the users' starred courses into a FlatList - */ - const renderItem = ({ item }) => { - return ( - onLineSelected(item.text)}> - - - {item.text} - - - - ) - } - - return ( - - - - ) -} - -TranscriptContainer.propTypes = { - transcriptId: PropTypes.string.isRequired, - navigation: PropTypes.shape({ - push: PropTypes.func.isRequired, - }).isRequired, -} - -export default TranscriptContainer From 5bb18800cbedbba6147f6091612e044829e2f195 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 10 Apr 2021 02:28:51 -0500 Subject: [PATCH 17/23] added documentation to new functions --- package.json | 2 +- src/api/auth.js | 8 ++++++++ src/containers/HomeContainer/Home.js | 13 +++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 94aec77..0501910 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "build-ios": "expo build:ios", "ios": "expo start --ios", "web": "expo start --web", - "eject": "expo eject --non-interactive --eject-method bare", + "eject": "expo eject --non-interactive --ject-method bare", "lint": "eslint ." }, "private": true diff --git a/src/api/auth.js b/src/api/auth.js index 9e5cfd2..564879c 100644 --- a/src/api/auth.js +++ b/src/api/auth.js @@ -45,11 +45,19 @@ export const getUserMetadata = async () => { } } +/** + * Set the authorization token for the current authenticated user + * @param authToken Pass in the auth token so user can watch CT videos + */ export const setAuthToken = (token) => { if (!currentAuthenticatedUser) currentAuthenticatedUser = {} currentAuthenticatedUser.authToken = token } +/** + * Initialize user's data using the metadata that is passed in during authorization + * @param userData Pass in userData to obtain each user's information + */ export const setUserData = (userData) => { if (!currentAuthenticatedUser) currentAuthenticatedUser = {} currentAuthenticatedUser.userId = userData.userId diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index 6d5bb35..e305d39 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -6,7 +6,7 @@ import { getOfferingsData } from '../../api/offerings' import { getUniversities } from '../../api/universities' import { getCurrentAuthenticatedUser } from '../../api/auth' import CourseCard from '../../components/Cards/CourseCard' -// import Recommend from '../../components/Recommend/Recommend' +import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' import styles from './Home.style' @@ -18,6 +18,10 @@ const Home = ({ navigation }) => { const currentUser = getCurrentAuthenticatedUser() const universityId = currentUser.universityId + /** + * Helper function to filter courses by university id + * @param offerings Pass in all offerings that student is allowed to access only + */ const filterCourses = (offerings) => { const newOfferings = [] for (const i in offerings) { @@ -67,15 +71,15 @@ const Home = ({ navigation }) => { /> - {/* + - */} + ) } /** - * Render universities + * Render universities' course offerings in a dropdown picker based on university id. */ const renderUniversityDropDown = () => { const [universities, setAllUniversities] = useState([]) @@ -96,6 +100,7 @@ const Home = ({ navigation }) => { const onUniversitySelected = async (newUniversityId) => { // Reload the page for the selected universityId setUniversity(newUniversityId) + const newUnicourses = await getOfferingsData() const newCourses = filterCourses(newUnicourses) From a2a148e88d48b1e3e4c37d43234f4dbe0a65d181 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 13:23:03 -0700 Subject: [PATCH 18/23] removing recommendation and switch from home --- src/containers/HomeContainer/Home.js | 21 +-------------------- src/containers/HomeContainer/Home.style.js | 15 ++++----------- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index e305d39..089bbc9 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -60,7 +60,7 @@ const Home = ({ navigation }) => { const courseId = item.offering.id return ( - + onCourseSelected(courseId)}> { /> - - - ) } @@ -138,25 +135,9 @@ const Home = ({ navigation }) => { ) } - const [mode, setMode] = useState(false) - const renderSwitch = () => { - return ( - - Latest Video Mode: {mode.toString()} - setMode(!mode)} - value={mode} - /> - - ) - } - return ( {renderUniversityDropDown()} - {renderSwitch()} {renderStarredCourses()} ) diff --git a/src/containers/HomeContainer/Home.style.js b/src/containers/HomeContainer/Home.style.js index f4ad73d..dc3593c 100644 --- a/src/containers/HomeContainer/Home.style.js +++ b/src/containers/HomeContainer/Home.style.js @@ -1,19 +1,12 @@ import { StyleSheet } from 'react-native' const HomeStyle = StyleSheet.create({ - container: { + cardContainer: { display: 'flex', + justifyContent: 'center', + alignItems: 'center', flexDirection: 'row', - marginTop: 10, - marginBottom: 10, - flexWrap: 'wrap', - width: '100%', - }, - cardContainer: { - width: '50%', - }, - recContainer: { - width: '50%', + width: '98%', }, viewStyle: { From eaac18bc5b9d1a48c687fe00c1c438bed0e8765e Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 13:23:44 -0700 Subject: [PATCH 19/23] create new endpoints string for offeringsByStudent --- src/api/offerings.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/offerings.js b/src/api/offerings.js index cdb0344..abc80db 100644 --- a/src/api/offerings.js +++ b/src/api/offerings.js @@ -6,6 +6,7 @@ import { getCurrentAuthenticatedUser, isUserAuthenticated } from './auth' export const ENDPOINTS = { OFFERING: `${API_BASE_URL}Offerings/{0}`, + OFFERINGBYSTUDENT: `${API_BASE_URL}Offerings/ByStudent` } /** @@ -38,7 +39,7 @@ export const getOfferingData = async (offeringId) => { export const getOfferingsByStudent = async () => { if (!isUserAuthenticated()) return null - const url = format(ENDPOINTS.OFFERING, 'ByStudent') + const url = ENDPOINTS.OFFERINGBYSTUDENT try { const resp = await axios.get(url) From 1f23c9dd91bb42fd907c85a69f71144fa8a73d62 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 13:29:48 -0700 Subject: [PATCH 20/23] linter --- src/api/offerings.js | 4 ++-- src/containers/HomeContainer/Home.js | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/api/offerings.js b/src/api/offerings.js index abc80db..11f1317 100644 --- a/src/api/offerings.js +++ b/src/api/offerings.js @@ -6,7 +6,7 @@ import { getCurrentAuthenticatedUser, isUserAuthenticated } from './auth' export const ENDPOINTS = { OFFERING: `${API_BASE_URL}Offerings/{0}`, - OFFERINGBYSTUDENT: `${API_BASE_URL}Offerings/ByStudent` + OFFERINGSBYSTUDENT: `${API_BASE_URL}Offerings/ByStudent`, } /** @@ -39,7 +39,7 @@ export const getOfferingData = async (offeringId) => { export const getOfferingsByStudent = async () => { if (!isUserAuthenticated()) return null - const url = ENDPOINTS.OFFERINGBYSTUDENT + const url = ENDPOINTS.OFFERINGSBYSTUDENT try { const resp = await axios.get(url) diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index 089bbc9..c7e1adc 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -1,12 +1,11 @@ import React, { useState, useEffect } from 'react' -import { TouchableNativeFeedback, Switch, FlatList, View, Text } from 'react-native' +import { TouchableNativeFeedback, FlatList, View } from 'react-native' import { Picker } from '@react-native-community/picker' import PropTypes from 'prop-types' import { getOfferingsData } from '../../api/offerings' import { getUniversities } from '../../api/universities' import { getCurrentAuthenticatedUser } from '../../api/auth' import CourseCard from '../../components/Cards/CourseCard' -import Recommend from '../../components/Recommend/Recommend' import { STACK_SCREENS } from '../CTNavigationContainer/index' import styles from './Home.style' From 12ed4dd928570d05fcf5cc2d89d4b8897a7eeb0c Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 13:40:21 -0700 Subject: [PATCH 21/23] fixing undefined is not an object warning --- src/api/offerings.js | 4 ++-- src/containers/HomeContainer/Home.js | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/api/offerings.js b/src/api/offerings.js index 11f1317..c34d804 100644 --- a/src/api/offerings.js +++ b/src/api/offerings.js @@ -6,7 +6,7 @@ import { getCurrentAuthenticatedUser, isUserAuthenticated } from './auth' export const ENDPOINTS = { OFFERING: `${API_BASE_URL}Offerings/{0}`, - OFFERINGSBYSTUDENT: `${API_BASE_URL}Offerings/ByStudent`, + OFFERINGBYSTUDENT: `${API_BASE_URL}Offerings/ByStudent`, } /** @@ -39,7 +39,7 @@ export const getOfferingData = async (offeringId) => { export const getOfferingsByStudent = async () => { if (!isUserAuthenticated()) return null - const url = ENDPOINTS.OFFERINGSBYSTUDENT + const url = ENDPOINTS.OFFERINGBYSTUDENT try { const resp = await axios.get(url) diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index c7e1adc..826b401 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -15,7 +15,7 @@ import styles from './Home.style' */ const Home = ({ navigation }) => { const currentUser = getCurrentAuthenticatedUser() - const universityId = currentUser.universityId + var universityId = currentUser.universityId /** * Helper function to filter courses by university id @@ -92,17 +92,15 @@ const Home = ({ navigation }) => { }) const [university, setUniversity] = useState(universityId) - const onUniversitySelected = async (newUniversityId) => { - // Reload the page for the selected universityId setUniversity(newUniversityId) + universityId = newUniversityId const newUnicourses = await getOfferingsData() const newCourses = filterCourses(newUnicourses) try { setCourses(newCourses) - renderCourseItem() } catch (error) { console.error(error) } From 6ad9a08cb1fea00d70d748dad012a09b3a23b5a8 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 13:43:01 -0700 Subject: [PATCH 22/23] check data exists before setting user data --- src/api/auth.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/auth.js b/src/api/auth.js index 564879c..d0a8348 100644 --- a/src/api/auth.js +++ b/src/api/auth.js @@ -60,9 +60,9 @@ export const setAuthToken = (token) => { */ export const setUserData = (userData) => { if (!currentAuthenticatedUser) currentAuthenticatedUser = {} - currentAuthenticatedUser.userId = userData.userId - currentAuthenticatedUser.universityId = userData.universityId - currentAuthenticatedUser.emailId = userData.emailId + currentAuthenticatedUser.userId = userData?.userId + currentAuthenticatedUser.universityId = userData?.universityId + currentAuthenticatedUser.emailId = userData?.emailId } /** From d0ac3c63ac8cad0868d7388d3733a993e5afdd29 Mon Sep 17 00:00:00 2001 From: Akshaya Date: Sat, 10 Apr 2021 15:05:28 -0700 Subject: [PATCH 23/23] added one test --- __tests__/frontend/HomeContainer-test.js | 57 ++++++++++++++++++++++++ src/containers/HomeContainer/Home.js | 6 ++- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 __tests__/frontend/HomeContainer-test.js diff --git a/__tests__/frontend/HomeContainer-test.js b/__tests__/frontend/HomeContainer-test.js new file mode 100644 index 0000000..ca2f65e --- /dev/null +++ b/__tests__/frontend/HomeContainer-test.js @@ -0,0 +1,57 @@ +import axios from 'axios' +import React from 'react' +import MockAdapter from 'axios-mock-adapter' +import { render } from '@testing-library/react-native' +import { setUserData } from '../../src/api/auth' +import { ENDPOINTS as UNI_ENDPOINTS } from '../../src/api/universities' +import { ENDPOINTS as OFFER_ENDPOINTS } from '../../src/api/offerings' +import { format } from '../../src/utils/string' + +import { HTTP_STATUS_CODES } from '../../src/api' +import { UNIVERSITY_RESPONSE } from '../mock_responses/mock-university-response' +import Home from '../../src/containers/HomeContainer/Home' +import { OFFERINGS_RESPONSE_1 } from '../mock_responses/mock-offerings-response' + +// const assertNoButtonsRendered = async () => { +// const { queryAllByA11yRole } = render() +// const universityList = await waitFor(() => queryAllByA11yRole('button')) +// expect(universityList.length).toBe(0) +// } + +const mock = new MockAdapter(axios) +describe('Check universities rendering', () => { + const USER_DATA = { + authToken: 'A', + universityId: '1001', + userId: 'test user', + emaildId: 'testuser@email.com', + } + + const offeringId = 'ac5b1727-629c-443b-8c1a-cc1bd541af6a' + + afterEach(() => { + mock.reset() + }) + + test('Check that components render', async () => { + const mockNavigator = { push: jest.fn() } + + mock.onGet(`${UNI_ENDPOINTS.UNIVERSITIES}`).reply(HTTP_STATUS_CODES.OK, UNIVERSITY_RESPONSE) + mock + .onGet(`${OFFER_ENDPOINTS.OFFERINGBYSTUDENT}`) + .reply(HTTP_STATUS_CODES.OK, OFFERINGS_RESPONSE_1) + mock + .onGet(`${format(OFFER_ENDPOINTS.OFFERING, offeringId)}`) + .reply(HTTP_STATUS_CODES.OK, OFFERINGS_RESPONSE_1) + + setUserData(USER_DATA) + + const { getByTestId } = render() + + const picker = await getByTestId('picker') + expect(picker).not.toBe(null) + + const courseList = await getByTestId('courseList') + expect(courseList).not.toBe(null) + }) +}) diff --git a/src/containers/HomeContainer/Home.js b/src/containers/HomeContainer/Home.js index 826b401..d2eeb12 100644 --- a/src/containers/HomeContainer/Home.js +++ b/src/containers/HomeContainer/Home.js @@ -15,7 +15,7 @@ import styles from './Home.style' */ const Home = ({ navigation }) => { const currentUser = getCurrentAuthenticatedUser() - var universityId = currentUser.universityId + let universityId = currentUser.universityId /** * Helper function to filter courses by university id @@ -88,7 +88,7 @@ const Home = ({ navigation }) => { }, [setAllUniversities]) const universityItems = universities.map((uni) => { - return + return }) const [university, setUniversity] = useState(universityId) @@ -108,6 +108,7 @@ const Home = ({ navigation }) => { return ( onUniversitySelected(newUniversityId)} @@ -125,6 +126,7 @@ const Home = ({ navigation }) => { return ( index.toString()} data={courses} renderItem={renderCourseItem}