From 8de8e67070d2cae7dda89846b03f3748b0858e4a Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Mon, 17 Jul 2023 18:45:25 +0800 Subject: [PATCH] Allow editing of user info --- src/components/Api/Api.tsx | 52 +++++++++++++++++++++----------- src/interfaces/Interfaces.tsx | 18 +++++------ src/routes/UserInfo/UserInfo.tsx | 42 ++++++++++++++++++++++---- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index c63d096..33427f6 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -4,7 +4,9 @@ import { ActivationParams, LoginParams, OnboardingParams, + PatchStudentData, RegistrationParams, + StudentData, } from "../../interfaces/Interfaces"; let debug = true; @@ -43,6 +45,16 @@ export async function setRefreshToken(refresh: string) { return true; } +// Header Config Template for REST +export async function GetConfig() { + const accessToken = await getAccessToken(); + return { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }; +} + // User APIs export function UserRegister(register: RegistrationParams) { console.log(JSON.stringify(register)); @@ -105,13 +117,9 @@ export async function TokenRefresh() { }); } export async function UserInfo() { - const accessToken = await getAccessToken(); + const config = await GetConfig(); return instance - .get("/api/v1/accounts/users/me/", { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - }) + .get("/api/v1/accounts/users/me/", config) .then((response) => { // console.log(JSON.stringify(response.data)); return [true, response.data]; @@ -124,6 +132,23 @@ export async function UserInfo() { }); } +export async function PatchUserInfo(info: PatchStudentData) { + const config = await GetConfig(); + return instance + .patch("/api/v1/accounts/users/me/", info, 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"; + console.log(error_message); + return [false, error_message]; + }); +} + export function UserActivate(activation: ActivationParams) { return instance .post("/api/v1/accounts/users/activation/", activation) @@ -178,13 +203,9 @@ export async function GetSemesters() { } export async function GetYearLevels() { - const accessToken = await getAccessToken(); + const config = await GetConfig(); return instance - .get("/api/v1/year_levels/", { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - }) + .get("/api/v1/year_levels/", config) .then((response) => { // console.log(JSON.stringify(response.data)); return [true, response.data]; @@ -198,12 +219,9 @@ export async function GetYearLevels() { } export async function OnboardingUpdateStudentInfo(info: OnboardingParams) { - const accessToken = await getAccessToken(); - const headers = { - Authorization: `Bearer ${accessToken}`, - }; + const config = await GetConfig(); return instance - .patch("/api/v1/accounts/users/me/", info, { headers }) + .patch("/api/v1/accounts/users/me/", info, config) .then((response) => { console.log(JSON.stringify(response.data)); return [true, response.data]; diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index ed57230..0a0fd9b 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -77,6 +77,15 @@ export interface OnboardingParams { semester: string; } +export interface PatchStudentData { + course?: string | null; + first_name?: string | null; + last_name?: string | null; + semester?: string | null; + subjects?: any[] | null; // To-do, replace 'any' with your actual type + year_level?: string | null; +} + export interface StudentData { avatar: string; course: string; @@ -87,15 +96,6 @@ export interface StudentData { semester: string; student_id_number: string; subjects: any[]; // To-do - user_status: { - active: boolean; - landmark: string; - location: any; // To-do - study_group: any[]; // To-do - subject: string; - timestamp: string; - user: string; - }; username: string; year_level: string; } diff --git a/src/routes/UserInfo/UserInfo.tsx b/src/routes/UserInfo/UserInfo.tsx index db33407..c690a43 100644 --- a/src/routes/UserInfo/UserInfo.tsx +++ b/src/routes/UserInfo/UserInfo.tsx @@ -18,11 +18,15 @@ import { TouchableOpacity, Image } from "react-native"; import { ScrollView } from "react-native-gesture-handler"; import SelectDropdown from "react-native-select-dropdown"; import DropdownIcon from "../../icons/DropdownIcon/DropdownIcon"; -import { useQuery } from "react-query"; -import { UserInfo as GetUserInfo } from "../../components/Api/Api"; +import { useMutation, useQuery, useQueryClient } from "react-query"; +import { + UserInfo as GetUserInfo, + PatchUserInfo, +} from "../../components/Api/Api"; import { colors } from "../../styles"; export default function UserInfo() { + const queryClient = useQueryClient(); const UserInfo = useQuery("user", GetUserInfo, { onSuccess: (data: UserInfoParams) => { setUser({ @@ -34,10 +38,18 @@ export default function UserInfo() { course: data[1].course, avatar: data[1].avatar, }); + setDisplayName({ + first_name: data[1].first_name, + last_name: data[1].last_name, + }); + }, + }); + const mutation = useMutation({ + mutationFn: PatchUserInfo, + onSuccess: () => { + queryClient.invalidateQueries("user"); }, }); - - const navigation = useNavigation(); const [isEditable, setIsEditable] = useState(false); const subjectOptions = ["", "", "", ""]; const [user, setUser] = useState({ @@ -48,6 +60,10 @@ export default function UserInfo() { course: "", avatar: "", }); + const [displayName, setDisplayName] = useState({ + first_name: "", + last_name: "", + }); function Avatar() { if (user.avatar) { return ; @@ -64,7 +80,9 @@ export default function UserInfo() { - {(user.first_name || "Undefined") + " " + (user.last_name || "User")} + {(displayName.first_name || "Undefined") + + " " + + (displayName.last_name || "User")} @@ -185,7 +203,19 @@ export default function UserInfo() { setIsEditable(!isEditable)} + onPress={() => { + if (isEditable) { + mutation.mutate({ + first_name: user.first_name, + last_name: user.last_name, + course: user.course, + semester: user.semester, + subjects: [], + year_level: user.year_level, + }); + } + setIsEditable(!isEditable); + }} > {isEditable && UserInfo.isSuccess ? "Save" : "Edit Profile"}