Created
August 24, 2022 20:26
-
-
Save chamellion/a5e28469b3dea88eb6eee61a4fd0b9b3 to your computer and use it in GitHub Desktop.
The curriculum content
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useCallback, useEffect, useMemo, useRef, useState} from "react"; | |
import SafeAreaContainer from "../../components/SafeAreaContainer"; | |
import { | |
Alert, | |
Dimensions, | |
Linking, | |
ScrollView, | |
StyleSheet, | |
Text, | |
ToastAndroid, | |
TouchableOpacity, | |
View | |
} from "react-native"; | |
import DefaultPreferences from "react-native-default-preference"; | |
import Utils from "../Utils"; | |
import CustomSpinner from "../../components/CustomSpinner"; | |
import CurriculumDetail from "../../components/CurriculumDetail"; | |
import {Dropdown} from "react-native-element-dropdown/index"; | |
import Entypo from "react-native-vector-icons/Entypo"; | |
import BottomSheet, { | |
BottomSheetFlatList, BottomSheetModal, | |
BottomSheetModalProvider, | |
BottomSheetTextInput, | |
useBottomSheet | |
} from "@gorhom/bottom-sheet"; | |
import {useNavigation} from "@react-navigation/native"; | |
const chatIcon = <Entypo name={'chat'} color={'white'} size={24}/> | |
const globalStyle = require('../GlobalStyleSheet') | |
const CurriculumContent = ({route}) => { | |
const param = route.params | |
const volumeId = param.volumeId | |
const classChosen = param.classChosen | |
const subjectId = param.subjectId | |
const term = param.term | |
const week = param.week | |
const [weekState, setWeekState] = useState(Number.parseInt(week)) | |
const [content, setContent] = useState({}) | |
const [isLoading, setLoading] = useState(true) | |
const [dataExist, setDataExist] = useState(false) | |
const BASE_URL = Utils.baseUrl | |
const weekDataArray = [ | |
{ | |
label: "Week 1", | |
value: '1' | |
}, | |
{ | |
label: 'Week 2', | |
value: 2 | |
}, | |
{ | |
label: 'Week 3', | |
value: 3 | |
}, | |
{ | |
label: 'Week 4', | |
value: 4 | |
}, | |
{ | |
label: 'Week 5', | |
value: 5 | |
}, | |
{ | |
label: 'Week 6', | |
value: 6 | |
}, | |
{ | |
label: 'Week 7', | |
value: 7 | |
}, | |
{ | |
label: 'Week 8', | |
value: 8 | |
}, | |
{ | |
label: 'Week 9', | |
value: 9 | |
}, | |
{ | |
label: 'Week 10', | |
value: 10 | |
}, | |
{ | |
label: 'Week 11', | |
value: 11 | |
}, | |
{ | |
label: 'Week 12', | |
value: 12 | |
}, | |
{ | |
label: 'Week 13', | |
value: 13 | |
} | |
] | |
const [weekData] = useState(weekDataArray) | |
const [chosenWeek, setChosenWeek] = useState(null) | |
const getCurriculumContent = async (passedWeek) => { | |
try { | |
setLoading(true) | |
let token = await DefaultPreferences.get('TOKEN_PREF') | |
let URL = `${BASE_URL}curriculum-contents/volume/${volumeId}/class/${classChosen}/subject/${subjectId}/term/${term}/week/${passedWeek}` | |
console.log(URL) | |
let response = | |
await fetch(URL, { | |
method: 'GET', | |
headers: { | |
"Authorization": token | |
} | |
}) | |
let responseJson = await response.json(); | |
console.log(responseJson) | |
if (response.status === 200) { | |
let content = responseJson.data['curriculum content'] | |
if (content.length === 0) { | |
setDataExist(false) | |
} else { | |
setDataExist(true) | |
setContent(content[0]) | |
let chat = content.chat | |
setChatResource(chat) | |
} | |
} else if (response.status === 401 && responseJson.messages[0] === 'Expired access token error') { | |
console.log("This loop was breached") | |
const refreshToken = await DefaultPreferences.get('REFRESH_TOKEN'); | |
const sessionId = await DefaultPreferences.get('SESSION_ID') | |
const token = await DefaultPreferences.get('TOKEN_PREF') | |
const mUrl = BASE_URL + 'sessions/' + sessionId | |
console.log("Refresh token url is " + mUrl) | |
let refreshResponse = await fetch(mUrl, { | |
method: 'PATCH', | |
headers: { | |
"Authorization": token | |
}, | |
body: JSON.stringify({ | |
"refreshToken": refreshToken | |
}) | |
}); | |
let refreshResponseJson = await refreshResponse.json(); | |
if (refreshResponse.status === 200) { | |
let refreshToken = refreshResponseJson.data.refreshToken | |
let nAccessToken = refreshResponseJson.data.accessToken | |
await DefaultPreferences.set("REFRESH_TOKEN", refreshToken) | |
await DefaultPreferences.set("REFRESH_TOKEN", nAccessToken) | |
await getCurriculumContent() | |
} else { | |
Alert.alert("Error", refreshResponseJson.messages[0]) | |
} | |
} else { | |
Alert.alert("Error", responseJson.messages[0]) | |
} | |
} catch (e) { | |
console.log("error is " + e); | |
} finally { | |
setLoading(false) | |
} | |
} | |
const refHook = useRef(true) | |
useEffect(() => { | |
getCurriculumContent(weekState).catch(error => console.log(error)) | |
}, []) | |
const [isNonTeachingWeek] = useState(weekState === 7 || weekState === 11 || weekState === 12 || weekState === 13) | |
useEffect(() => { | |
if (refHook.current) { | |
refHook.current = false | |
return | |
} | |
getCurriculumContent(weekState).catch(e => console.log(e)) | |
}, [weekState]) | |
// useEffect(() => { | |
// if (refHook.current) { | |
// refHook.current = false | |
// return | |
// } | |
// | |
// }, [openModal]) | |
const bottomRef = useRef(null) | |
const [openModal, setModalOpen] = useState(true) | |
const snapPoint = useMemo(() => ['80%'], []) | |
const [chatResource, setChatResource] = useState([]) | |
const [userComment, setUserComment] = useState("") | |
const getAllBookChats = async (resourceId) => { | |
try { | |
setLoading(true) | |
let token = await DefaultPreferences.get("TOKEN_PREF") | |
let BASE_URL = Utils.baseUrl | |
let bookList = "curriculum" | |
let response = await fetch(`${BASE_URL}/chat/resource/${bookList}/resourceId/${resourceId}`, { | |
method: 'GET', | |
headers: { | |
"Authorization": token | |
} | |
}) | |
let responseJson = await response.json() | |
if (response.status === 200) { | |
let chatData = responseJson.data.Chats | |
setChatResource(chatData) | |
} else { | |
Alert.alert("Error", responseJson.messages[0]) | |
} | |
} catch (e) { | |
console.log(e); | |
Alert.alert("Error", "One or more error has occurred") | |
} finally { | |
setLoading(false) | |
} | |
} | |
const saveAComment = async (resourceId) => { | |
try { | |
setLoading(true) | |
if (userComment.length <= 0) { | |
Alert.alert("Error", "Empty text, enter a valid message to continue") | |
} else { | |
let profileId = await DefaultPreferences.get("PROFILE_PREF") | |
let token = await DefaultPreferences.get("TOKEN_PREF") | |
const data = JSON.stringify({ | |
"profileId": profileId, | |
"resource": "curriculum", | |
"resourceId": resourceId, | |
"discussion": userComment, | |
"reply": null, | |
"attachment": null | |
}) | |
let BASE_URL = Utils.baseUrl | |
let response = await fetch(BASE_URL + "chat", { | |
method: 'POST', | |
headers: { | |
"Authorization": token, | |
'Content-type': 'application/json', | |
}, | |
body: data | |
}) | |
let responseJson = await response.json(); | |
console.log(responseJson) | |
if (response.status === 201) { | |
ToastAndroid.show("Post successful", ToastAndroid.LONG) | |
await getAllBookChats(resourceId) | |
} | |
} | |
} catch (e) { | |
console.log(e); | |
} finally { | |
setLoading(false) | |
} | |
} | |
// callbacks | |
const handlePresentModalPress = useCallback(() => { | |
if (openModal){ | |
bottomRef.current?.present(); | |
setModalOpen(!openModal) | |
}else { | |
bottomRef.current?.dismiss(); | |
setModalOpen(!openModal) | |
} | |
}, [openModal]); | |
const handleSheetChanges = useCallback((index: number) => { | |
console.log('handleSheetChanges', index); | |
}, []); | |
return ( | |
<SafeAreaContainer> | |
<BottomSheetModalProvider> | |
{ | |
!isLoading && <ScrollView showsVerticalScrollIndicator={false} | |
contentContainerStyle={{minHeight: '100%'}}> | |
<View> | |
<CustomSpinner setVisibility={isLoading} spinnerStyle={Style.loadingIndicators}/> | |
{ | |
dataExist ? <View style={Style.topicContainer}> | |
<Text style={Style.topicText}>{JSON.parse(content.topic)?.heading?.content}</Text> | |
</View> : | |
<Text style={Style.topicText}>No Content Available</Text> | |
} | |
<View style={{marginEnd: 32}}> | |
<View style={{flexDirection: "row"}}> | |
<CurriculumDetail | |
heading={"Class"} | |
detail={`${(content?.levelName)?.charAt(0)}${(content?.name)?.charAt(0)}${content.class}`} | |
backgroundStyle={{marginStart: 16, marginTop: 16, marginEnd: 50}}/> | |
<CurriculumDetail | |
heading={"Subject"} | |
detail={`${content.subjectName}`} | |
backgroundStyle={{marginStart: 16, marginTop: 16}}/> | |
</View> | |
<View style={{flexDirection: "row"}}> | |
<CurriculumDetail | |
heading={"Term"} | |
detail={getTermInWords(content.term)} | |
backgroundStyle={{ | |
marginTop: 8, | |
marginStart: 16, | |
marginBottom: 16, | |
marginEnd: 24 | |
}}/> | |
<CurriculumDetail | |
heading={"Week"} | |
detail={`${content.week_no}`} | |
detailStyle={{textAlign: 'center'}} | |
backgroundStyle={{marginTop: 8, marginStart: 16, marginBottom: 16}}/> | |
</View> | |
</View> | |
<View style={[globalStyle.androidCardView, {backgroundColor: "#D9D9D9"}]}> | |
{ | |
dataExist && ( | |
<View style={Style.subTopicContainer}> | |
<Text style={Style.subTopic}>Topic</Text> | |
<Text | |
style={Style.subTopicContent}>{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.topic).heading.content}</Text> | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.topic)?.body?.type === 'ul' ? JSON.parse(content.topic)?.body?.content?.map((element) => ( | |
<Text | |
style={{color: 'black'}}>{element.value.length === 0 ? "" : `\t \u2022 ${element?.value}`}</Text>)) : | |
<Text>{""}</Text>} | |
</View> | |
) | |
} | |
</View> | |
<View style={[globalStyle.androidCardView, {backgroundColor: "#D9D9D9"}]}> | |
{ | |
dataExist && ( | |
<View style={Style.subTopicContainer}> | |
<Text style={Style.subTopic}>Learning Objective</Text> | |
{ | |
((JSON.parse(content?.learning_objective)?.heading?.content).length > 0) && | |
<Text | |
style={Style.subTopicContent}>{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : | |
<Text>{`${JSON.parse(content?.learning_objective)?.heading?.content}`}</Text>}</Text> | |
} | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : (JSON.parse(content.learning_objective)?.body.type === 'ul' ? JSON.parse(content.learning_objective)?.body?.content?.map((element) => ( | |
<Text | |
style={{color: 'black'}}>{`\t\u2022 ${element?.value}`}</Text>)) : | |
<Text>{""}</Text>)} | |
</View> | |
) | |
} | |
</View> | |
<View style={[globalStyle.androidCardView, {backgroundColor: "#D9D9D9"}]}> | |
{ | |
dataExist && ( | |
<View style={Style.subTopicContainer}> | |
<Text style={Style.subTopic}>Learning Activity</Text> | |
{ | |
((JSON.parse(content.learning_activity)?.heading?.content).length > 0) && | |
<Text | |
style={Style.subTopicContent}>{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.learning_activity)?.heading?.content}</Text> | |
} | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.learning_activity)?.body?.type === 'ul' ? JSON.parse(content.learning_activity)?.body?.content?.map((element) => ( | |
<Text | |
style={{color: 'black'}}>{element.value.length === 0 ? "" : `\t \u2022 ${element?.value}`}</Text>)) : JSON.parse(content.learning_activity)?.body?.content.map((element) => ( | |
<Text style={{color: 'black'}}>{element.value}</Text>))} | |
</View> | |
) | |
} | |
</View> | |
<View style={[globalStyle.androidCardView, {backgroundColor: "#D9D9D9"}]}> | |
{ | |
dataExist && ( | |
<View style={Style.subTopicContainer}> | |
<Text style={Style.subTopic}>Embedded Core Skills</Text> | |
{ | |
((JSON.parse(content?.embedded_core_skill)?.heading?.content).length > 0) && | |
<Text | |
style={Style.subTopicContent}>{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content?.embedded_core_skill)?.heading?.content}</Text> | |
} | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.embedded_core_skill)?.body?.type === 'ul' ? JSON.parse(content?.embedded_core_skill)?.body?.content?.map((element) => ( | |
<Text>{`\t\u2022 ${element.value}`}</Text>)) : JSON.parse(content.embedded_core_skill)?.body?.content?.map((element) => ( | |
<Text style={{color: 'black'}}>{element?.value}</Text>))} | |
</View> | |
) | |
} | |
</View> | |
<View style={[globalStyle.androidCardView, {backgroundColor: "#D9D9D9"}]}> | |
{ | |
dataExist && ( | |
<View style={Style.subTopicContainer}> | |
<Text style={Style.subTopic}>Learning Resources</Text> | |
{ | |
((JSON.parse(content.learning_resource)?.heading?.content).length > 0) && | |
<Text style={Style.subTopicContent}> | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.learning_resource)?.heading?.content} | |
</Text> | |
} | |
{(content.week_no === 7 || content.week_no === 11 || content.week_no === 12 || content.week_no === 13) ? | |
<Text>{""}</Text> : JSON.parse(content.learning_resource).body.content.map((element) => ( | |
processLink(element) | |
))} | |
</View> | |
) | |
} | |
</View> | |
<View style={{flexDirection: "row", justifyContent: "space-around", marginBottom: 32}}> | |
<TouchableOpacity style={Style.smallButtons} onPress={() => { | |
if (weekState < 2) { | |
Alert.alert("Error", "All Curriculum begins at week one") | |
} else { | |
let newWeek = weekState - 1 | |
setWeekState(newWeek) | |
} | |
}}> | |
<Text style={Style.smallButtonText}>prev</Text> | |
</TouchableOpacity> | |
<Dropdown | |
style={Style.dropdown} | |
data={weekData} | |
value={chosenWeek} | |
labelField={"label"} | |
valueField={"value"} | |
maxHeight={300} | |
onChange={item => { | |
setChosenWeek(item.value) | |
setWeekState(item.value) | |
}}/> | |
<TouchableOpacity style={Style.smallButtons} onPress={() => { | |
/*Week at 12 is being checked because update is later done in the else block | |
when weekState is 12, it's being updated already to 13 in else block | |
*/ | |
if (weekState > 12) { | |
Alert.alert("Error", "You have reached the end of the week for a term") | |
} else { | |
let newWeekState = weekState + 1 | |
setWeekState(newWeekState) | |
} | |
}}> | |
<Text style={Style.smallButtonText}>Next</Text> | |
</TouchableOpacity> | |
</View> | |
</View> | |
</ScrollView> | |
} | |
<TouchableOpacity style={Style.sendButtonContainer} | |
activeOpacity={0.4} | |
onPress={() => handlePresentModalPress()}> | |
<View style={{flexDirection: 'row', alignItems: 'center'}}> | |
<Text style={{marginEnd: 6}}>{chatIcon}</Text> | |
<Text style={Style.sendButtonText}>{openModal ? "Show Comment" : "Close Comment"}</Text> | |
</View> | |
</TouchableOpacity> | |
<BottomSheetModal snapPoints={snapPoint} | |
ref={bottomRef} | |
enablePanDownToClose={true} | |
enableDismissOnClose={true}> | |
<CustomSpinner setVisibility={isLoading} spinnerStyle={Style.loadingIndicators}/> | |
<BottomSheetFlatList | |
data={chatResource} | |
showsVerticalScrollIndicator={false} | |
ListHeaderComponent={ | |
<View> | |
{/*<TouchableOpacity style={Style.sendChatContainer}>*/} | |
{/* <Text style={Style.sendChatText}>Close</Text>*/} | |
{/*</TouchableOpacity>*/} | |
<BottomSheetTextInput | |
style={[globalStyle.textInputStyle, {alignSelf: "center", marginTop: 12}]} | |
placeholder={"Type your comment"} | |
autoCorrect={false} | |
multiline={true} | |
onChangeText={setUserComment} | |
value={userComment} | |
/> | |
<TouchableOpacity style={Style.sendChatContainer} onPress={async () => { | |
if (userComment.length <= 0) { | |
Alert.alert("Error", "Empty text, enter a valid message to continue") | |
} else { | |
await saveAComment(content.id) | |
setUserComment("") | |
} | |
}}> | |
<Text style={Style.sendChatText}>Send</Text> | |
</TouchableOpacity> | |
</View> | |
} | |
renderItem={({item}) => { | |
const data = item.cleanData ? item.cleanData : item; | |
let discussion = data.discussion | |
let fullName = data.profile_info.surname + " " + data.profile_info.firstname | |
return ( | |
<View style={Style.chatContainer}> | |
<Text style={Style.chatName}>{fullName}</Text> | |
<Text style={Style.chatMessage}>{discussion}</Text> | |
</View> | |
) | |
}} | |
/> | |
</BottomSheetModal> | |
</BottomSheetModalProvider> | |
</SafeAreaContainer> | |
) | |
} | |
const Style = StyleSheet.create({ | |
topicText: { | |
textAlign: "center", | |
marginTop: 16, | |
fontSize: 24, | |
fontFamily: 'NunitoSans-ExtraBold', | |
color: 'black' | |
}, | |
topicContainer: { | |
alignContent: "center", | |
marginTop: 8, | |
marginHorizontal: 16, | |
justifyContent: "center", | |
}, | |
subTopic: { | |
fontSize: 20, | |
fontFamily: 'NunitoSans-SemiBold', | |
color: 'black' | |
}, | |
subTopicContainer: { | |
marginHorizontal: 16, | |
marginTop: 12, | |
}, | |
subTopicContent: { | |
fontFamily: 'NunitoSans-Regular', | |
color: 'black' | |
}, | |
scrollViewStyle: { | |
flexGrow: 1 | |
}, | |
loadingIndicators: { | |
position: "absolute", | |
top: Dimensions.get("screen").height / 3, | |
zIndex: 3, | |
elevation: 3, | |
alignSelf: "center" | |
}, | |
subHeading: { | |
marginStart: 16, | |
marginTop: 16, | |
marginBottom: 16 | |
}, | |
dropdown: { | |
borderWidth: 1, | |
borderRadius: 8, | |
paddingHorizontal: 12, | |
width: 150, | |
borderColor: '#E0E2EB', | |
backgroundColor: '#d9d9d9', | |
}, | |
smallButtons: { | |
backgroundColor: '#005EB4', | |
paddingVertical: 4, | |
paddingHorizontal: 24, | |
alignItems: 'center', | |
justifyContent: 'center', | |
borderRadius: 6 | |
}, | |
smallButtonText: { | |
fontWeight: 'bold', | |
textAlign: 'center', | |
color: '#ffffff', | |
textTransform: 'uppercase', | |
fontFamily: 'Roboto-Regular', | |
lineHeight: 16 | |
}, | |
sendButtonContainer: { | |
paddingHorizontal: 16, | |
alignSelf: 'baseline', | |
backgroundColor: | |
Utils.buttonColor, | |
borderRadius: 5, | |
paddingVertical: 6, | |
marginBottom: 8, | |
position: 'absolute', | |
zIndex: 2, | |
elevation: 2, | |
alignItems: 'center', | |
justifyContent: 'center', | |
right: 32, | |
bottom: 70, | |
}, | |
sendButtonText: { | |
textTransform: 'uppercase', | |
color: 'white', | |
fontFamily: 'NunitoSans-ExtraBold' | |
}, | |
chatName: { | |
fontFamily: 'NunitoSans-ExtraBold', | |
color: 'black' | |
}, | |
chatMessage: { | |
fontFamily: 'NunitoSans-SemiBoldItalic', | |
}, | |
chatContainer: { | |
backgroundColor: '#F2F3F7', | |
padding: 12, | |
marginTop: 16, | |
marginStart: 24, | |
borderRadius: 12, | |
}, | |
sendChatContainer:{ | |
paddingHorizontal: 16, | |
alignSelf: 'flex-end', | |
backgroundColor: | |
Utils.buttonColor, | |
borderRadius: 5, | |
paddingVertical: 6, | |
marginEnd: 24, | |
marginTop: 4, | |
marginBottom: 8, | |
justifyContent: 'flex-end' | |
}, | |
sendChatText: { | |
textTransform: 'uppercase', | |
color: 'white', | |
fontFamily: 'NunitoSans-ExtraBold' | |
} | |
}) | |
function processLink(element) { | |
if (element.type === "a") { | |
return ( | |
<TouchableOpacity onPress={() => handleLinkClicked(element)}> | |
<Text style={{color: 'black', textDecorationLine: 'underline'}}>{`\t\u2022 ${element.value}`}</Text> | |
</TouchableOpacity> | |
) | |
} else { | |
return <Text style={{color: 'black'}}>{`\t\u2022 ${element.value}`}</Text> | |
} | |
} | |
async function handleLinkClicked(element) { | |
try { | |
let canOpenLink = Linking.canOpenURL(element.value) | |
if (canOpenLink) { | |
let value = Linking.openURL(element.value) | |
console.log("Value is " + value) | |
} | |
} catch (e) { | |
console.log(e); | |
} | |
} | |
function getTermInWords(termNumber) { | |
switch (termNumber) { | |
case 1: | |
return "First Term" | |
case 2: | |
return "Second Term" | |
case 3: | |
return "Third Term" | |
} | |
} | |
export default CurriculumContent |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment