From 058b120ce95726dcb8d8f38cbb550d151774642d Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Wed, 6 Sep 2023 18:13:43 +0800 Subject: [PATCH] Addded initial heatmap rendering --- src/components/Api/Api.tsx | 29 ++++++++- src/interfaces/Interfaces.tsx | 17 ++++- src/routes/Home/Home.tsx | 119 +++++++++++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index 3f70195..f518496 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -17,7 +17,7 @@ if (__DEV__) { } // Switch this on if you wanna run production URLs while in development -let use_production = true; +let use_production = false; if (__DEV__ && use_production) { backendURL = "https://stude.keannu1.duckdns.org"; backendURLWebsocket = "ws://stude.keannu1.duckdns.org"; @@ -269,3 +269,30 @@ export async function GetStudentStatusList() { return [false, error_message]; }); } + +export async function GetStudentStatusListFiltered() { + const config = await GetConfig(); + return instance + .get("/api/v1/student_status/filter/near_student_status", config) + .then((response) => { + return [true, response.data]; + }) + .catch((error) => { + let error_message = ParseError(error); + return [false, error_message]; + }); +} + +// To-do +export async function GetStudentStatusListFilteredCurrentLocation() { + const config = await GetConfig(); + return instance + .get("/api/v1/student_status/list/", config) + .then((response) => { + return [true, response.data]; + }) + .catch((error) => { + let error_message = ParseError(error); + return [false, error_message]; + }); +} diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index ffd85d9..a21360e 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -1,5 +1,6 @@ import * as Location from "expo-location"; import { GetStudentStatus } from "../components/Api/Api"; +import { Float } from "react-native/Libraries/Types/CodegenTypes"; export interface IconProps { size: number; @@ -124,8 +125,8 @@ export interface PatchUserInfoType { } interface Location { - latitude: number; - longitude: number; + latitude: Float; + longitude: Float; } export interface StudentStatusType { @@ -136,9 +137,19 @@ export interface StudentStatusType { active?: boolean; } +export interface StudentStatusFilterType { + active: boolean; + distance: number; + landmark: string | null; + location: Location; + study_group?: string; + subject: string; + user: string; +} + export type StudentStatusReturnType = [boolean, StudentStatusType]; -export type StudentStatusListType = Array; +export type StudentStatusListType = Array; export type StudentStatusListReturnType = [boolean, StudentStatusListType]; export type LocationType = Location.LocationObject; diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index 2b910e2..951045e 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -2,7 +2,15 @@ import styles, { Viewport, colors } from "../../styles"; import { View, Text } from "react-native"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; import { useState, useEffect } from "react"; -import MapView, { Callout, Marker, UrlTile } from "react-native-maps"; +import MapView, { + Callout, + Heatmap, + Circle, + Marker, + UrlTile, + Overlay, + Polygon, +} from "react-native-maps"; import * as Location from "expo-location"; import GetDistance from "../../components/GetDistance/GetDistance"; import Button from "../../components/Button/Button"; @@ -12,11 +20,13 @@ import { LocationType, StudentStatusType, StudentStatusListReturnType, + StudentStatusListType, } from "../../interfaces/Interfaces"; import { useNavigation } from "@react-navigation/native"; import { GetStudentStatus, GetStudentStatusList, + GetStudentStatusListFiltered, PatchStudentStatus, urlProvider, } from "../../components/Api/Api"; @@ -166,18 +176,60 @@ export default function Home() { }, }); + const [student_statuses, setStudentStatuses] = useState([]); // Student Status List const StudentStatusList = useQuery({ + enabled: studying, queryKey: ["user_status_list"], queryFn: async () => { - const data = await GetStudentStatusList(); + const data = await GetStudentStatusListFiltered(); if (data[0] == false) { return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, onSuccess: (data: StudentStatusListReturnType) => { - console.log("List of students:", data[1]); + if (data[1]) { + // We first flatten the data to remove nested entries + let flattened_data = data[1].map((item) => ({ + active: item.active, + distance: item.distance, + landmark: item.landmark, + latitude: item.location.latitude, + longitude: item.location.longitude, + study_group: "", + subject: item.subject, + user: item.user, + })); + flattened_data.push({ + active: true, + distance: 50, + landmark: "", + latitude: 9.498298904115586, + longitude: 125.59552381187677, + study_group: "", + subject: "Introduction to Computing", + user: "Keannu", + }); + // We get each unique subject + let unique_subjects = [ + ...new Set(flattened_data.map((item) => item.subject)), + ]; + console.log("Unique Subjects:", unique_subjects); + let result: any[] = []; + // Then append all entries belonging to that subject to its own array + unique_subjects.forEach((subject) => { + let filteredData = flattened_data.filter( + (item) => item.subject === subject && item.study_group === "" + ); + // We then concatenate this into the final array + result = result.concat([filteredData]); + }); + + console.log("Final Result:", result); + + setStudentStatuses(result); + } }, onError: (error: Error) => { toast.show(String(error), { @@ -222,6 +274,66 @@ export default function Home() { }} loadingBackgroundColor={colors.secondary_2} > + {student_statuses.map((student_status: any, index: number) => { + console.log("TEST INDEX", index, student_status); + return ( + { + const users = student_statuses.map((item: any) => ({ + user: item.user, + })); + toast.hideAll(); + toast.show( + + + Subject: {student_status[0].subject} + + + Students Studying: {student_status.length} + + + , + { + type: "normal", + placement: "top", + duration: 2000, + animationType: "slide-in", + style: { + backgroundColor: colors.secondary_2, + borderWidth: 1, + borderColor: colors.primary_1, + }, + } + ); + }} + /> + ); + })} +