From bccc8081505c3cba5858ae08cdc4159dc04c2430 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Thu, 6 Jul 2023 17:19:19 +0800 Subject: [PATCH] Improved revalidation and added drop down menus to onboarding --- App.tsx | 33 +++++---- package-lock.json | 36 ++++++++++ package.json | 1 + src/components/Api/Api.tsx | 63 +++++++++++++++++ src/interfaces/Interfaces.tsx | 18 +++++ src/routes/Onboarding/Onboarding.tsx | 88 +++++++++++++++++++++--- src/routes/Revalidation/Revalidation.tsx | 5 +- 7 files changed, 218 insertions(+), 26 deletions(-) diff --git a/App.tsx b/App.tsx index 8ab50a5..d1d9e46 100644 --- a/App.tsx +++ b/App.tsx @@ -17,6 +17,7 @@ import Onboarding from "./src/routes/Onboarding/Onboarding"; import Revalidation from "./src/routes/Revalidation/Revalidation"; import Activation from "./src/routes/Activation/Activation"; import { useState, useEffect } from "react"; +import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; const Drawer = createDrawerNavigator(); @@ -35,6 +36,8 @@ const linking = { }, }; +const queryClient = new QueryClient(); + export default function App() { const [initialRoute, setInitialRoute] = useState(null); useEffect(() => { @@ -50,20 +53,22 @@ export default function App() { }, [initialRoute]); return ( - - - - - - - - - - + + + + + + + + + + + + ); } diff --git a/package-lock.json b/package-lock.json index 85b5680..02e3d1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", "@reduxjs/toolkit": "^1.9.5", + "@tanstack/react-query": "^4.29.19", "axios": "^1.4.0", "expo": "~48.0.18", "expo-linking": "~4.0.1", @@ -5202,6 +5203,41 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tanstack/query-core": { + "version": "4.29.19", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.19.tgz", + "integrity": "sha512-uPe1DukeIpIHpQi6UzIgBcXsjjsDaLnc7hF+zLBKnaUlh7jFE/A+P8t4cU4VzKPMFB/C970n/9SxtpO5hmIRgw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.19", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.19.tgz", + "integrity": "sha512-XiTIOHHQ5Cw1WUlHaD4fmVUMhoWjuNJlAeJGq7eM4BraI5z7y8WkZO+NR8PSuRnQGblpuVdjClQbDFtwxTtTUw==", + "dependencies": { + "@tanstack/query-core": "4.29.19", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@types/hammerjs": { "version": "2.0.41", "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", diff --git a/package.json b/package.json index d6d1135..3caa37d 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", "@reduxjs/toolkit": "^1.9.5", + "@tanstack/react-query": "^4.29.19", "axios": "^1.4.0", "expo": "~48.0.18", "expo-linking": "~4.0.1", diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index 75300cf..cae13ae 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -135,3 +135,66 @@ export function UserActivate(activation: ActivationParams) { } // App APIs + +export async function GetCourses() { + const accessToken = await getAccessToken(); + return instance + .get("/api/v1/courses/", { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }) + .then((response) => { + // console.log(JSON.stringify(response.data)); + return response.data; + }) + .catch((error) => { + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + console.log("Error getting courses", error_message); + return false; + }); +} + +export async function GetSemesters() { + const accessToken = await getAccessToken(); + return instance + .get("/api/v1/semesters/", { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }) + .then((response) => { + // console.log(JSON.stringify(response.data)); + return response.data; + }) + .catch((error) => { + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + console.log("Error getting semesters", error_message); + return false; + }); +} + +export async function GetYearLevels() { + const accessToken = await getAccessToken(); + return instance + .get("/api/v1/year_levels/", { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }) + .then((response) => { + // console.log(JSON.stringify(response.data)); + return response.data; + }) + .catch((error) => { + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + console.log("Error getting year levels", error_message); + return false; + }); +} diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index 6c6be0e..eae85db 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -46,3 +46,21 @@ export interface ActivationParams { uid: string; token: string; } + +export interface SemesterParams { + id: string; + name: string; + shortname: string; +} + +export interface YearLevelParams { + id: string; + name: string; + shortname: string; +} + +export interface CourseParams { + id: string; + name: string; + shortname: string; +} diff --git a/src/routes/Onboarding/Onboarding.tsx b/src/routes/Onboarding/Onboarding.tsx index 2a68a37..a763653 100644 --- a/src/routes/Onboarding/Onboarding.tsx +++ b/src/routes/Onboarding/Onboarding.tsx @@ -2,42 +2,100 @@ import * as React from "react"; import styles from "../../styles"; import { View, Text } from "react-native"; import { useNavigation } from "@react-navigation/native"; -import { RootDrawerParamList } from "../../interfaces/Interfaces"; +import { + CourseParams, + RootDrawerParamList, + SemesterParams, + YearLevelParams, +} from "../../interfaces/Interfaces"; import { colors } from "../../styles"; import { AnimatePresence, MotiView } from "moti"; import { useEffect, useState } from "react"; import Button from "../../components/Button/Button"; import DropDownPicker from "react-native-dropdown-picker"; import isStringEmpty from "../../components/IsStringEmpty/IsStringEmpty"; - +import { useQuery } from "@tanstack/react-query"; +import { + GetCourses, + GetSemesters, + GetYearLevels, +} from "../../components/Api/Api"; export default function Onboarding() { const navigation = useNavigation(); // const dispatch = useDispatch(); // const creds = useSelector((state: RootState) => state.auth.creds); - + const [error, setError] = useState(false); // Semesters const [semester, setSemester] = useState(""); const [semesterOpen, setSemesterOpen] = useState(false); const [semesters, setSemesters] = useState([ - { label: "1st Semester", value: "1st Sem" }, - { label: "2nd Semester", value: "2nd Sem" }, + { label: "1st Semester", value: "1st Sem", id: "" }, + { label: "2nd Semester", value: "2nd Sem", id: "" }, ]); + const semester_query = useQuery({ + queryKey: ["semesters"], + queryFn: GetSemesters, + onSuccess: (data) => { + let semesters = data.map((item: SemesterParams) => ({ + label: item.name, + value: item.shortname, + id: item.id, + })); + setSemesters(semesters); + }, + onError: () => { + setError(true); + }, + }); // Year Level const [year_level, setYearLevel] = useState(""); const [yearLevelOpen, setYearLevelOpen] = useState(false); const [year_levels, setYearLevels] = useState([ - { label: "1st Year", value: "1st Year" }, - { label: "2nd Year", value: "2nd Year" }, + { label: "1st Year", value: "1st Year", id: "" }, + { label: "2nd Year", value: "2nd Year", id: "" }, ]); + const yearlevel_query = useQuery({ + queryKey: ["year_levels"], + queryFn: GetYearLevels, + onSuccess: (data) => { + let year_levels = data.map((item: YearLevelParams) => ({ + label: item.name, + value: item.shortname, + id: item.id, + })); + setYearLevels(year_levels); + }, + onError: () => { + setError(true); + }, + }); // Course const [course, setCourse] = useState(""); const [courseOpen, setCourseOpen] = useState(false); const [courses, setCourses] = useState([ - { label: "Bachelor of Science in Information Technology", value: "BSIT" }, - { label: "Bachelor of Science in Computer Science", value: "BSCS" }, + { + label: "Bachelor of Science in Information Technology", + value: "BSIT", + id: "", + }, + { label: "Bachelor of Science in Computer Science", value: "BSCS", id: "" }, ]); const [complete, setComplete] = useState(false); - + const course_query = useQuery({ + queryKey: ["courses"], + queryFn: GetCourses, + onSuccess: (data) => { + let courses = data.map((item: CourseParams) => ({ + label: item.name, + value: item.shortname, + id: item.id, + })); + setCourses(courses); + }, + onError: () => { + setError(true); + }, + }); useEffect(() => { setComplete( !isStringEmpty(year_level) && @@ -45,7 +103,15 @@ export default function Onboarding() { !isStringEmpty(semester) ); }, [year_level, course, semester, complete]); - + if (error) { + return ( + + + Error loading details + + + ); + } return ( diff --git a/src/routes/Revalidation/Revalidation.tsx b/src/routes/Revalidation/Revalidation.tsx index df677e5..ad8ff05 100644 --- a/src/routes/Revalidation/Revalidation.tsx +++ b/src/routes/Revalidation/Revalidation.tsx @@ -20,7 +20,10 @@ export default function Revalidation() { if (response) { let user_info = await UserInfo(); await dispatch(setUser(user_info)); - if (!(user_info.year_level || user_info.course || user_info.semester)) { + if ( + !(user_info.year_level || user_info.course || user_info.semester) && + (await UserInfo()) + ) { await setTimeout(() => { navigation.navigate("Onboarding"); }, 700);