From 160ffc5763b4780cc452c2a3a8a96a3bda52293e Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Tue, 18 Jul 2023 00:33:02 +0800 Subject: [PATCH] Overhauled dropdown menu designs for onboarding and userinfo page --- src/components/Api/Api.tsx | 2 +- src/interfaces/Interfaces.tsx | 36 ++- src/routes/Onboarding/Onboarding.tsx | 30 ++- src/routes/UserInfoPage/UserInfoPage.tsx | 283 ++++++++++++++++++----- src/styles.tsx | 7 +- 5 files changed, 273 insertions(+), 85 deletions(-) diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index 3187178..c7b98c4 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -207,7 +207,7 @@ export async function GetYearLevels() { return instance .get("/api/v1/year_levels/", config) .then((response) => { - // console.log(JSON.stringify(response.data)); + console.log(JSON.stringify(response.data)); return [true, response.data]; }) .catch((error) => { diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index 05d1c70..7013b6b 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -47,6 +47,7 @@ export interface ActivationParams { token: string; } +// Semester export interface Semester { id: string; name: string; @@ -57,21 +58,37 @@ export type Semesters = Array; export type SemesterParams = [boolean, Semesters]; +// Year Level export interface YearLevel { id: string; name: string; shortname: string; } -export type YearLevelParams = [boolean, YearLevel]; +export type YearLevels = Array; +export type YearLevelParams = [boolean, YearLevels]; + +// Course export interface Course { id: string; name: string; shortname: string; } +export type Courses = Array; +export type CourseParams = [boolean, Courses]; -export type CourseParams = [boolean, Course]; +// Subject +export interface Subject { + id: string; + name: string; + code: string; + // courses: any[]; // To-do + // year_levels: any[]; // To-do + // semesters: any[]; // To-do +} +export type Subjects = Array; +export type SubjectParams = [boolean, Subjects]; export interface OnboardingParams { year_level: string; @@ -89,17 +106,20 @@ export interface PatchStudentData { } export interface StudentData { - avatar: string; - course: string; - email: string; first_name: string; - is_banned: boolean; last_name: string; - semester: string; + email: string; + avatar: string; student_id_number: string; + is_banned: boolean; + semester: string; + semester_shortname: string; + course: string; + course_shortname: string; + year_level: string; + yearlevel_shortname: string; subjects: any[]; // To-do username: string; - year_level: string; } export type UserInfoParams = [boolean, StudentData]; diff --git a/src/routes/Onboarding/Onboarding.tsx b/src/routes/Onboarding/Onboarding.tsx index 56a875d..fc9ab48 100644 --- a/src/routes/Onboarding/Onboarding.tsx +++ b/src/routes/Onboarding/Onboarding.tsx @@ -145,13 +145,15 @@ export default function Onboarding() { setSemesterOpen(false); setYearLevelOpen(false); }} + style={styles.input} setValue={setSelectedCourse} placeholder="Choose your course" - containerStyle={{ - ...styles.input, - ...{ zIndex: 3000 }, + containerStyle={{ zIndex: 3000 }} + textStyle={{ + ...styles.text_white_small_bold, + ...{ textAlign: "center" }, }} - dropDownContainerStyle={{ backgroundColor: "white" }} + dropDownContainerStyle={{ backgroundColor: colors.primary_2 }} /> {error} diff --git a/src/routes/UserInfoPage/UserInfoPage.tsx b/src/routes/UserInfoPage/UserInfoPage.tsx index 767084e..fe16baa 100644 --- a/src/routes/UserInfoPage/UserInfoPage.tsx +++ b/src/routes/UserInfoPage/UserInfoPage.tsx @@ -7,20 +7,26 @@ import { NativeSyntheticEvent, TextInputChangeEventData, } from "react-native"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useNavigation } from "@react-navigation/native"; import { RootDrawerParamList, SemesterParams, UserInfoParams, Semester, + SubjectParams, + Subject, + YearLevel, + Course, } from "../../interfaces/Interfaces"; import Button from "../../components/Button/Button"; import { TouchableOpacity, Image } from "react-native"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { + GetCourses, GetSemesters, GetSubjects, + GetYearLevels, PatchUserInfo, UserInfo, } from "../../components/Api/Api"; @@ -30,6 +36,7 @@ import AnimatedContainerNoScroll from "../../components/AnimatedContainer/Animat export default function UserInfoPage() { const queryClient = useQueryClient(); + // User Info const [user, setUser] = useState({ first_name: "", last_name: "", @@ -67,6 +74,10 @@ export default function UserInfoPage() { queryClient.invalidateQueries({ queryKey: ["user"] }); }, }); + + // Semester + const [selected_semester, setSelectedSemester] = useState(""); + const [semesterOpen, setSemesterOpen] = useState(false); const [semesters, setSemesters] = useState([ { label: "", value: "", shortname: "" }, ]); @@ -74,19 +85,106 @@ export default function UserInfoPage() { queryKey: ["semesters"], queryFn: GetSemesters, onSuccess: (data: SemesterParams) => { + console.log("Semesters", data[1]); let semestersData = data[1].map((semester: Semester) => ({ label: semester.name, value: semester.id, shortname: semester.shortname, })); - // Update the 'semesters' state setSemesters(semestersData); + console.log(semesters); }, }); - const [isEditable, setIsEditable] = useState(false); - const subjectOptions = ["", "", "", ""]; + // Subjects + const [selected_subjects, setSelectedSubjects] = useState([]); + const [subjectsOpen, setSubjectsOpen] = useState(false); + const [subjects, setSubjects] = useState([ + { id: 0, label: "", value: "", shortname: "" }, + ]); + + const Subjects = useQuery({ + enabled: StudentInfo.isFetched, + queryKey: ["subjects"], + queryFn: async () => { + let data; + if (StudentInfo.data) { + if ( + 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 + ); + } + } + if (data) { + if (!data[0]) { + throw new Error("Error with query" + data[1]); + } + if (!data[1]) { + throw new Error("User has no course, year level, or semester!"); + } + } + + return data; + }, + onSuccess: (data: SubjectParams) => { + let subjectsData = data[1].map((subject: Subject) => ({ + id: Number(subject.id), + label: subject.name, + value: subject.id, + shortname: subject.code, + })); + + // Update the 'subjects' state + setSubjects(subjectsData); + }, + }); + + // Year Level + const [selected_yearlevel, setSelectedYearLevel] = useState(""); + const [yearLevelOpen, setYearLevelOpen] = useState(false); + const [year_levels, setYearLevels] = useState([{ label: "", value: "" }]); + const yearlevel_query = useQuery({ + queryKey: ["year_levels"], + queryFn: GetYearLevels, + onSuccess: (data) => { + let year_levels = data[1].map((yearlevel: YearLevel) => ({ + label: yearlevel.name, + value: yearlevel.name, + })); + setYearLevels(year_levels); + }, + }); + + // Course + const [selected_course, setSelectedCourse] = useState(""); + const [courseOpen, setCourseOpen] = useState(false); + const [courses, setCourses] = useState([ + { + label: "", + value: "", + }, + ]); + const course_query = useQuery({ + queryKey: ["courses"], + queryFn: GetCourses, + onSuccess: (data) => { + let courses = data[1].map((course: Course) => ({ + label: course.name, + value: course.name, + })); + setCourses(courses); + }, + }); + // Toggle editing of profile + const [isEditable, setIsEditable] = useState(false); + // Profile photo function Avatar() { if (user.avatar) { return ; @@ -99,20 +197,19 @@ export default function UserInfoPage() { ); } } - const [selected_subjects, setSelectedSubjects] = useState([]); - const [subjectsOpen, setSubjectsOpen] = useState(false); - const [subjects, setSubjects] = useState([{ label: "", value: "" }]); + return ( - - {(displayName.first_name || "Undefined") + - " " + - (displayName.last_name || "User")} - - + + + {(displayName.first_name || "Undefined") + + " " + + (displayName.last_name || "User")} + + @@ -154,15 +251,31 @@ export default function UserInfoPage() { Year Level - - ): void => { - setUser({ ...user, year_level: e.nativeEvent.text }); + { + setYearLevelOpen(open); + setSemesterOpen(false); + setCourseOpen(false); + setSubjectsOpen(false); }} - value={user.year_level} + setValue={setSelectedYearLevel} + placeholder={user.year_level} + placeholderStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + style={styles.input} + textStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + containerStyle={{ zIndex: 4000 }} + dropDownContainerStyle={{ backgroundColor: colors.primary_2 }} /> @@ -171,15 +284,31 @@ export default function UserInfoPage() { Semester - - ): void => { - setUser({ ...user, semester: e.nativeEvent.text }); + { + setYearLevelOpen(false); + setSemesterOpen(open); + setCourseOpen(false); + setSubjectsOpen(false); }} - value={user.semester} + setValue={setSelectedSemester} + placeholder={user.semester} + placeholderStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + style={styles.input} + textStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + containerStyle={{ zIndex: 3000 }} + dropDownContainerStyle={{ backgroundColor: colors.primary_2 }} /> @@ -188,15 +317,31 @@ export default function UserInfoPage() { Course - - ): void => { - setUser({ ...user, course: e.nativeEvent.text }); + { + setYearLevelOpen(false); + setSemesterOpen(false); + setCourseOpen(open); + setSubjectsOpen(false); }} - value={user.course} + setValue={setSelectedCourse} + placeholder={user.course} + placeholderStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + style={styles.input} + textStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + containerStyle={{ zIndex: 2000 }} + dropDownContainerStyle={{ backgroundColor: colors.primary_2 }} /> @@ -207,41 +352,57 @@ export default function UserInfoPage() { setSubjectsOpen(open)} + setOpen={(open) => { + setYearLevelOpen(false); + setSemesterOpen(false); + setCourseOpen(false); + setSubjectsOpen(open); + }} setValue={setSelectedSubjects} placeholder="Subjects" - placeholderStyle={styles.text_white_tiny} + placeholderStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} style={styles.input} - textStyle={styles.text_white_small_bold} - dropDownContainerStyle={{ backgroundColor: "white" }} + textStyle={{ + ...styles.text_white_tiny_bold, + ...{ textAlign: "left" }, + }} + containerStyle={{ zIndex: 12000 }} + dropDownContainerStyle={{ backgroundColor: colors.primary_2 }} /> - + + + ); diff --git a/src/styles.tsx b/src/styles.tsx index 3d97764..3618d22 100644 --- a/src/styles.tsx +++ b/src/styles.tsx @@ -141,15 +141,16 @@ const styles = StyleSheet.create({ alignSelf: "center", }, profile: { - height: 96, - width: 96, + height: 64, + width: 64, alignSelf: "center", borderRadius: 150 / 2, overflow: "hidden", + padding: 0, }, input: { paddingHorizontal: 8, - marginVertical: 12, + marginVertical: 2, borderWidth: 1, color: colors.text_default, backgroundColor: colors.primary_2,