Added subject selection for irregular students

This commit is contained in:
Keannu Bernasol 2023-07-25 16:52:35 +08:00
parent 473291646c
commit eb08e02a16
6 changed files with 126 additions and 39 deletions

10
package-lock.json generated
View file

@ -23,6 +23,7 @@
"moti": "^0.25.3", "moti": "^0.25.3",
"react": "18.2.0", "react": "18.2.0",
"react-native": "0.71.8", "react-native": "0.71.8",
"react-native-bouncy-checkbox": "^3.0.7",
"react-native-dropdown-picker": "^5.4.6", "react-native-dropdown-picker": "^5.4.6",
"react-native-gesture-handler": "~2.9.0", "react-native-gesture-handler": "~2.9.0",
"react-native-image-picker": "^5.6.0", "react-native-image-picker": "^5.6.0",
@ -12275,6 +12276,15 @@
"prop-types": "^15.7.2" "prop-types": "^15.7.2"
} }
}, },
"node_modules/react-native-bouncy-checkbox": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/react-native-bouncy-checkbox/-/react-native-bouncy-checkbox-3.0.7.tgz",
"integrity": "sha512-776TgMGt9wTpOQA1TcvFjL5VUn6o945wFYf3Ztqva62/vT2o3JAezLiP7hYh2Svd+PewfWBYSPMs4jeaSoS8Sg==",
"peerDependencies": {
"react": ">= 16.x.x",
"react-native": ">= 0.55.x"
}
},
"node_modules/react-native-codegen": { "node_modules/react-native-codegen": {
"version": "0.71.5", "version": "0.71.5",
"resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.71.5.tgz", "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.71.5.tgz",

View file

@ -24,6 +24,7 @@
"moti": "^0.25.3", "moti": "^0.25.3",
"react": "18.2.0", "react": "18.2.0",
"react-native": "0.71.8", "react-native": "0.71.8",
"react-native-bouncy-checkbox": "^3.0.7",
"react-native-dropdown-picker": "^5.4.6", "react-native-dropdown-picker": "^5.4.6",
"react-native-gesture-handler": "~2.9.0", "react-native-gesture-handler": "~2.9.0",
"react-native-image-picker": "^5.6.0", "react-native-image-picker": "^5.6.0",

View file

@ -9,12 +9,15 @@ import {
StudentData, StudentData,
} from "../../interfaces/Interfaces"; } from "../../interfaces/Interfaces";
let debug = true;
export let backendURL = ""; export let backendURL = "";
if (debug) { export let backendURLWebsocket = "";
let use_production = true;
if (__DEV__ || !use_production) {
backendURL = "http://10.0.10.8:8000"; backendURL = "http://10.0.10.8:8000";
backendURLWebsocket = "ws://10.0.10.8:8000";
} else { } else {
backendURL = "https://keannu125.pythonanywhere.com"; backendURL = "https://stude.keannu1.duckdns.org";
backendURLWebsocket = "ws://stude.keannu1.duckdns.org";
} }
const instance = axios.create({ const instance = axios.create({
@ -220,26 +223,46 @@ export async function GetYearLevels() {
} }
export async function GetSubjects( export async function GetSubjects(
byCourseOnly: boolean,
course: string, course: string,
year_level: string, year_level?: string,
semester: string semester?: string
) { ) {
const config = await GetConfig(); const config = await GetConfig();
return instance console.log("by course only?", byCourseOnly);
.get( // If year level and semester specified,
"/api/v1/subjects/" + course + "/" + year_level + "/" + semester, if (!byCourseOnly && year_level && semester) {
config return instance
) .get(
.then((response) => { "/api/v1/subjects/" + course + "/" + year_level + "/" + semester,
// console.log(JSON.stringify(response.data)); config
return [true, response.data]; )
}) .then((response) => {
.catch((error) => { // console.log(JSON.stringify(response.data));
let error_message = ""; return [true, response.data];
if (error.response) error_message = error.response.data; })
else error_message = "Unable to reach servers"; .catch((error) => {
return [false, error_message]; let error_message = "";
}); if (error.response) error_message = error.response.data;
else error_message = "Unable to reach servers";
return [false, error_message];
});
}
// If only course is specified
else {
return instance
.get("/api/v1/subjects/" + course, config)
.then((response) => {
// console.log(JSON.stringify(response.data));
return [true, response.data];
})
.catch((error) => {
let error_message = "";
if (error.response) error_message = error.response.data;
else error_message = "Unable to reach servers";
return [false, error_message];
});
}
} }
export async function OnboardingUpdateStudentInfo(info: OnboardingParams) { export async function OnboardingUpdateStudentInfo(info: OnboardingParams) {

View file

@ -17,6 +17,7 @@ import LogoutIcon from "../../icons/LogoutIcon/LogoutIcon";
import { logout } from "../../features/redux/slices/StatusSlice/StatusSlice"; import { logout } from "../../features/redux/slices/StatusSlice/StatusSlice";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import UserIcon from "../../icons/UserIcon/UserIcon"; import UserIcon from "../../icons/UserIcon/UserIcon";
import SubjectIcon from "../../icons/SubjectIcon/SubjectIcon";
export default function CustomDrawerContent(props: {}) { export default function CustomDrawerContent(props: {}) {
const navigation = useNavigation<RootDrawerParamList>(); const navigation = useNavigation<RootDrawerParamList>();
@ -80,7 +81,7 @@ export default function CustomDrawerContent(props: {}) {
navigation.navigate("Subjects"); navigation.navigate("Subjects");
}} }}
> >
<UserIcon size={32} /> <SubjectIcon size={32} />
<Text style={styles.text_white_medium}>Subjects</Text> <Text style={styles.text_white_medium}>Subjects</Text>
</DrawerButton> </DrawerButton>
<DrawerButton <DrawerButton

View file

@ -0,0 +1,27 @@
import * as React from "react";
import { IconProps } from "../../interfaces/Interfaces";
import { Svg, Path } from "react-native-svg";
import { colors } from "../../styles";
export default function SubjectIcon(props: IconProps) {
return (
<>
<Svg
width={props.size}
height={props.size}
viewBox="0 0 24 24"
strokeWidth="2"
stroke={colors.icon_color}
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<Path stroke="none" d="M0 0h24v24H0z" fill="none"></Path>
<Path d="M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z"></Path>
<Path d="M19 16h-12a2 2 0 0 0 -2 2"></Path>
<Path d="M9 8h6"></Path>
</Svg>
</>
);
}

View file

@ -7,7 +7,7 @@ import {
NativeSyntheticEvent, NativeSyntheticEvent,
TextInputChangeEventData, TextInputChangeEventData,
} from "react-native"; } from "react-native";
import { useState } from "react"; import { useEffect, useState } from "react";
import { import {
SemesterParams, SemesterParams,
UserInfoParams, UserInfoParams,
@ -32,8 +32,8 @@ import {
} from "../../components/Api/Api"; } from "../../components/Api/Api";
import { colors } from "../../styles"; import { colors } from "../../styles";
import DropDownPicker from "react-native-dropdown-picker"; import DropDownPicker from "react-native-dropdown-picker";
import { ValueType } from "react-native-dropdown-picker";
import AnimatedContainerNoScroll from "../../components/AnimatedContainer/AnimatedContainerNoScroll"; import AnimatedContainerNoScroll from "../../components/AnimatedContainer/AnimatedContainerNoScroll";
import BouncyCheckbox from "react-native-bouncy-checkbox";
export default function SubjectsPage() { export default function SubjectsPage() {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -82,11 +82,20 @@ export default function SubjectsPage() {
mutationFn: PatchUserInfo, mutationFn: PatchUserInfo,
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user"] }); queryClient.invalidateQueries({ queryKey: ["user"] });
queryClient.invalidateQueries({ queryKey: ["subjects"] }); queryClient.invalidateQueries({ queryKey: ["subjects", viewAll] });
setSelectedSubjects([]); setSelectedSubjects([]);
}, },
}); });
// View all Subjects or only view those under current course, year level, and semester
// This is for irregular students
const [viewAll, setViewAll] = useState(false);
// If viewing all subjects, refresh the choices
useEffect(() => {
queryClient.invalidateQueries({ queryKey: ["subjects", viewAll] });
}, [viewAll]);
// Subjects // Subjects
const [selected_subjects, setSelectedSubjects] = useState<any>([]); const [selected_subjects, setSelectedSubjects] = useState<any>([]);
@ -95,21 +104,22 @@ export default function SubjectsPage() {
const Subjects = useQuery({ const Subjects = useQuery({
enabled: StudentInfo.isFetched, enabled: StudentInfo.isFetched,
queryKey: ["subjects"], queryKey: ["subjects", viewAll],
queryFn: async () => { queryFn: async () => {
let data; let data;
if (StudentInfo.data) { if (
if ( StudentInfo.data &&
StudentInfo.data[1].course_shortname && StudentInfo.data[1].course_shortname &&
StudentInfo.data[1].yearlevel_shortname && StudentInfo.data[1].yearlevel_shortname &&
StudentInfo.data[1].semester_shortname
) {
data = await GetSubjects(
viewAll,
StudentInfo.data[1].course_shortname,
StudentInfo.data[1].yearlevel_shortname,
StudentInfo.data[1].semester_shortname StudentInfo.data[1].semester_shortname
) { );
data = await GetSubjects( console.log(JSON.stringify(data));
StudentInfo.data[1].course_shortname,
StudentInfo.data[1].yearlevel_shortname,
StudentInfo.data[1].semester_shortname
);
}
} }
if (data) { if (data) {
if (!data[0]) { if (!data[0]) {
@ -189,17 +199,30 @@ export default function SubjectsPage() {
...styles.text_white_tiny_bold, ...styles.text_white_tiny_bold,
...{ textAlign: "left" }, ...{ textAlign: "left" },
}} }}
dropDownContainerStyle={{ modalContentContainerStyle={{
backgroundColor: colors.primary_2, backgroundColor: colors.primary_2,
borderWidth: 0, borderWidth: 0,
zIndex: 1000, zIndex: 1000,
maxHeight: 512,
}} }}
dropDownDirection="TOP" autoScroll
dropDownDirection="BOTTOM"
listMode="MODAL"
/> />
</View> </View>
</View> </View>
<View style={{ zIndex: -1 }}> <View style={{ zIndex: -1 }}>
<View style={styles.padding} />
<View style={styles.flex_row}>
<BouncyCheckbox
onPress={() => {
setViewAll(!viewAll);
setSubjectsOpen(false);
}}
fillColor={colors.secondary_3}
/>
<Text style={styles.text_white_small}>Irregular </Text>
</View>
<View style={styles.padding} />
<Button <Button
onPress={() => { onPress={() => {
if (subjectsOpen) { if (subjectsOpen) {
@ -208,6 +231,8 @@ export default function SubjectsPage() {
mutation.mutate({ mutation.mutate({
subjects: selected_subjects, subjects: selected_subjects,
}); });
} else {
setSubjectsOpen(true);
} }
}} }}
> >