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",
"react": "18.2.0",
"react-native": "0.71.8",
"react-native-bouncy-checkbox": "^3.0.7",
"react-native-dropdown-picker": "^5.4.6",
"react-native-gesture-handler": "~2.9.0",
"react-native-image-picker": "^5.6.0",
@ -12275,6 +12276,15 @@
"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": {
"version": "0.71.5",
"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",
"react": "18.2.0",
"react-native": "0.71.8",
"react-native-bouncy-checkbox": "^3.0.7",
"react-native-dropdown-picker": "^5.4.6",
"react-native-gesture-handler": "~2.9.0",
"react-native-image-picker": "^5.6.0",

View file

@ -9,12 +9,15 @@ import {
StudentData,
} from "../../interfaces/Interfaces";
let debug = true;
export let backendURL = "";
if (debug) {
export let backendURLWebsocket = "";
let use_production = true;
if (__DEV__ || !use_production) {
backendURL = "http://10.0.10.8:8000";
backendURLWebsocket = "ws://10.0.10.8:8000";
} else {
backendURL = "https://keannu125.pythonanywhere.com";
backendURL = "https://stude.keannu1.duckdns.org";
backendURLWebsocket = "ws://stude.keannu1.duckdns.org";
}
const instance = axios.create({
@ -220,26 +223,46 @@ export async function GetYearLevels() {
}
export async function GetSubjects(
byCourseOnly: boolean,
course: string,
year_level: string,
semester: string
year_level?: string,
semester?: string
) {
const config = await GetConfig();
return instance
.get(
"/api/v1/subjects/" + course + "/" + year_level + "/" + semester,
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];
});
console.log("by course only?", byCourseOnly);
// If year level and semester specified,
if (!byCourseOnly && year_level && semester) {
return instance
.get(
"/api/v1/subjects/" + course + "/" + year_level + "/" + semester,
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];
});
}
// 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) {

View file

@ -17,6 +17,7 @@ import LogoutIcon from "../../icons/LogoutIcon/LogoutIcon";
import { logout } from "../../features/redux/slices/StatusSlice/StatusSlice";
import AsyncStorage from "@react-native-async-storage/async-storage";
import UserIcon from "../../icons/UserIcon/UserIcon";
import SubjectIcon from "../../icons/SubjectIcon/SubjectIcon";
export default function CustomDrawerContent(props: {}) {
const navigation = useNavigation<RootDrawerParamList>();
@ -80,7 +81,7 @@ export default function CustomDrawerContent(props: {}) {
navigation.navigate("Subjects");
}}
>
<UserIcon size={32} />
<SubjectIcon size={32} />
<Text style={styles.text_white_medium}>Subjects</Text>
</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,
TextInputChangeEventData,
} from "react-native";
import { useState } from "react";
import { useEffect, useState } from "react";
import {
SemesterParams,
UserInfoParams,
@ -32,8 +32,8 @@ import {
} from "../../components/Api/Api";
import { colors } from "../../styles";
import DropDownPicker from "react-native-dropdown-picker";
import { ValueType } from "react-native-dropdown-picker";
import AnimatedContainerNoScroll from "../../components/AnimatedContainer/AnimatedContainerNoScroll";
import BouncyCheckbox from "react-native-bouncy-checkbox";
export default function SubjectsPage() {
const queryClient = useQueryClient();
@ -82,11 +82,20 @@ export default function SubjectsPage() {
mutationFn: PatchUserInfo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user"] });
queryClient.invalidateQueries({ queryKey: ["subjects"] });
queryClient.invalidateQueries({ queryKey: ["subjects", viewAll] });
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
const [selected_subjects, setSelectedSubjects] = useState<any>([]);
@ -95,21 +104,22 @@ export default function SubjectsPage() {
const Subjects = useQuery({
enabled: StudentInfo.isFetched,
queryKey: ["subjects"],
queryKey: ["subjects", viewAll],
queryFn: async () => {
let data;
if (StudentInfo.data) {
if (
StudentInfo.data[1].course_shortname &&
StudentInfo.data[1].yearlevel_shortname &&
if (
StudentInfo.data &&
StudentInfo.data[1].course_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
) {
data = await GetSubjects(
StudentInfo.data[1].course_shortname,
StudentInfo.data[1].yearlevel_shortname,
StudentInfo.data[1].semester_shortname
);
}
);
console.log(JSON.stringify(data));
}
if (data) {
if (!data[0]) {
@ -189,17 +199,30 @@ export default function SubjectsPage() {
...styles.text_white_tiny_bold,
...{ textAlign: "left" },
}}
dropDownContainerStyle={{
modalContentContainerStyle={{
backgroundColor: colors.primary_2,
borderWidth: 0,
zIndex: 1000,
maxHeight: 512,
}}
dropDownDirection="TOP"
autoScroll
dropDownDirection="BOTTOM"
listMode="MODAL"
/>
</View>
</View>
<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
onPress={() => {
if (subjectsOpen) {
@ -208,6 +231,8 @@ export default function SubjectsPage() {
mutation.mutate({
subjects: selected_subjects,
});
} else {
setSubjectsOpen(true);
}
}}
>