diff --git a/App.tsx b/App.tsx index 80e3d00..66975af 100644 --- a/App.tsx +++ b/App.tsx @@ -18,6 +18,7 @@ import Revalidation from "./src/routes/Revalidation/Revalidation"; import Activation from "./src/routes/Activation/Activation"; import UserInfo from "./src/routes/UserInfo/UserInfo"; import { useState, useEffect } from "react"; +import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; const Drawer = createDrawerNavigator(); @@ -36,6 +37,8 @@ const linking = { }, }; +const queryClient = new QueryClient(); + export default function App() { const [initialRoute, setInitialRoute] = useState(null); useEffect(() => { @@ -51,21 +54,23 @@ export default function App() { }, [initialRoute]); return ( - - - - - - - - + + + + + + + + + - - + + + ); } diff --git a/app.json b/app.json index ca641e0..4802c78 100644 --- a/app.json +++ b/app.json @@ -26,6 +26,14 @@ }, "web": { "favicon": "./assets/favicon.png" - } + }, + "plugins": [ + [ + "expo-location", + { + "locationAlwaysAndWhenInUsePermission": "Allow Stud-E to use your location." + } + ] + ] } } diff --git a/package-lock.json b/package-lock.json index e9f3093..6ea9366 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,9 +13,12 @@ "@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-intent-launcher": "~10.5.2", "expo-linking": "~4.0.1", + "expo-location": "~15.1.1", "expo-status-bar": "~1.4.4", "moti": "^0.25.3", "react": "18.2.0", @@ -24,6 +27,7 @@ "react-native-gesture-handler": "~2.9.0", "react-native-image-picker": "^5.6.0", "react-native-modal": "^13.0.1", + "react-native-maps": "1.3.2", "react-native-reanimated": "~2.14.4", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", @@ -5206,6 +5210,46 @@ "@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/geojson": { + "version": "7946.0.10", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" + }, "node_modules/@types/hammerjs": { "version": "2.0.41", "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", @@ -7413,6 +7457,14 @@ "expo": "*" } }, + "node_modules/expo-intent-launcher": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/expo-intent-launcher/-/expo-intent-launcher-10.5.2.tgz", + "integrity": "sha512-qFIanCkLlTvqYTtJQJocZuZesi6b8lAdY9xF3oLFsdaTXKIMrfQfWI67zwBJvaNqgiV9MbbYnBHsFoOAzhBTKA==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-keep-awake": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-12.0.1.tgz", @@ -7433,6 +7485,14 @@ "url-parse": "^1.5.9" } }, + "node_modules/expo-location": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/expo-location/-/expo-location-15.1.1.tgz", + "integrity": "sha512-hoKRlmi6Ya+NeZ72Zt385SDcSsIDpJI60TCBVO+Hc9xfKA9Hyminyyo5WiwI8J03igmPTCl8Y37MxBNKY9AWkg==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.2.0.tgz", @@ -12289,6 +12349,22 @@ "peerDependencies": { "react": "*", "react-native": ">=0.65.0" + "node_modules/react-native-maps": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-1.3.2.tgz", + "integrity": "sha512-NB7HGRZOgxxXCWzrhIVucx/bsrEWANvk3DLci1ov4P9MQnEVQYQCCkTxsnaEvO191GeBOCRDyYn6jckqbfMtmg==", + "dependencies": { + "@types/geojson": "^7946.0.8" + }, + "peerDependencies": { + "react": ">= 17.0.1", + "react-native": ">= 0.64.3", + "react-native-web": ">= 0.11" + }, + "peerDependenciesMeta": { + "react-native-web": { + "optional": true + } } }, "node_modules/react-native-reanimated": { diff --git a/package.json b/package.json index 9349b40..bf7ee0c 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,12 @@ "@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", + "expo-intent-launcher": "~10.5.2", + "expo-location": "~15.1.1", "expo-status-bar": "~1.4.4", "moti": "^0.25.3", "react": "18.2.0", @@ -32,7 +35,8 @@ "react-native-svg": "13.4.0", "react-query": "^3.39.3", "react-redux": "^8.1.1", - "redux": "^4.2.1" + "redux": "^4.2.1", + "react-native-maps": "1.3.2" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/src/components/AnimatedContainer/AnimatedContainer.tsx b/src/components/AnimatedContainer/AnimatedContainer.tsx index 838a688..8f5960d 100644 --- a/src/components/AnimatedContainer/AnimatedContainer.tsx +++ b/src/components/AnimatedContainer/AnimatedContainer.tsx @@ -1,21 +1,35 @@ import * as React from "react"; -import { View, Text } from "react-native"; +import { View, Text, ScrollView } from "react-native"; import styles from "../../styles"; import { colors } from "../../styles"; -import { MotiView } from "moti"; +import { MotiView, MotiScrollView } from "moti"; export interface props { children: React.ReactNode; } export default function AnimatedContainer(props: props) { return ( - {props.children} - + ); } diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index 47d5bf7..5a5ddcb 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -3,6 +3,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import { ActivationParams, LoginParams, + OnboardingParams, RegistrationParams, } from "../../interfaces/Interfaces"; @@ -51,7 +52,10 @@ export function UserRegister(register: RegistrationParams) { return [true, response.status]; }) .catch((error) => { - return [false, error.response.status, error.response.data]; + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + return [false, error_message]; }); } @@ -70,8 +74,10 @@ export function UserLogin(user: LoginParams) { return [true]; }) .catch((error) => { - console.log("Login Failed:" + JSON.stringify(error.response.data)); - return [false, error.response.data]; + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + return [false, error_message]; }); } @@ -88,11 +94,14 @@ export async function TokenRefresh() { "Token refresh success! New Access Token", response.data.access );*/ - return [true]; + return true; }) .catch((error) => { - console.log("Refresh Failed: " + JSON.stringify(error.response.data)); - return [false, error.response.data]; + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + console.log("Token Refresh error:", error_message); + return false; }); } export async function UserInfo() { @@ -105,11 +114,13 @@ export async function UserInfo() { }) .then((response) => { // console.log(JSON.stringify(response.data)); - return response.data; + return [true, response.data]; }) .catch((error) => { - console.log("User Info Error", error.response.data); - return [false, error.response.data]; + let error_message = ""; + if (error.response) error_message = error.response.data; + else error_message = "Unable to reach servers"; + return [false, error_message]; }); } @@ -125,3 +136,86 @@ 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; + }); +} + +export async function OnboardingUpdateStudentInfo(info: OnboardingParams) { + const accessToken = await getAccessToken(); + const headers = { + Authorization: `Bearer ${accessToken}`, + }; + return instance + .patch("/api/v1/accounts/users/me/", info, { headers }) + .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 updating onboarding info", error_message); + return [false, error_message]; + }); +} diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 6a843c7..43aaf84 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -6,15 +6,24 @@ export interface props { children: React.ReactNode; onPress: (event: GestureResponderEvent) => void; color: string; + disabled?: boolean; } -export default function Button(props: props) { +export default function Button({ disabled = false, ...props }: props) { + const rgb = props.color.match(/\d+/g); return ( {props.children} diff --git a/src/components/DrawerSettings/CustomDrawerContent.tsx b/src/components/DrawerSettings/CustomDrawerContent.tsx index 3382abc..845d732 100644 --- a/src/components/DrawerSettings/CustomDrawerContent.tsx +++ b/src/components/DrawerSettings/CustomDrawerContent.tsx @@ -14,17 +14,41 @@ import DrawerButton from "../Button/DrawerButton"; import { useDispatch, useSelector } from "react-redux"; import { RootState } from "../../features/redux/Store/Store"; import LogoutIcon from "../../icons/LogoutIcon/LogoutIcon"; -import { clear } from "../../features/redux/slices/AuthSlice/AuthSlice"; +import { logout } from "../../features/redux/slices/StatusSlice/StatusSlice"; import AsyncStorage from "@react-native-async-storage/async-storage"; import UserIcon from "../../icons/UserIcon/UserIcon"; export default function CustomDrawerContent(props: {}) { const navigation = useNavigation(); - const logged_in = useSelector( - (state: RootState) => state.auth.creds.logged_in - ); + const status = useSelector((state: RootState) => state.status); const dispatch = useDispatch(); - if (logged_in) { + if (status.logged_in && status.onboarding) { + return ( + + + + Stud-E + + + { + dispatch(logout()); + await AsyncStorage.clear(); + navigation.navigate("Login"); + }} + > + + Logout + + + ); + } else if (status.logged_in) { return ( { - dispatch(await clear()); + dispatch(logout()); await AsyncStorage.clear(); navigation.navigate("Login"); }} @@ -79,15 +103,6 @@ export default function CustomDrawerContent(props: {}) { Stud-E - { - navigation.navigate("Home"); - }} - > - - Home - { @@ -100,7 +115,6 @@ export default function CustomDrawerContent(props: {}) { { - dispatch(clear()); navigation.navigate("Register"); }} > diff --git a/src/components/GetDistance/GetDistance.tsx b/src/components/GetDistance/GetDistance.tsx new file mode 100644 index 0000000..d3af390 --- /dev/null +++ b/src/components/GetDistance/GetDistance.tsx @@ -0,0 +1,23 @@ +export default function GetDistance( + lat1: number, + lon1: number, + lat2: number, + lon2: number +) { + var R = 6371; // km + var dLat = toRad(lat2 - lat1); + var dLon = toRad(lon2 - lon1); + var lat1 = toRad(lat1); + var lat2 = toRad(lat2); + + var a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + var distance = R * c; + return distance; +} + +export function toRad(value: number) { + return (value * Math.PI) / 180; +} diff --git a/src/components/IsStringEmpty/IsStringEmpty.tsx b/src/components/IsStringEmpty/IsStringEmpty.tsx new file mode 100644 index 0000000..b1cd9d1 --- /dev/null +++ b/src/components/IsStringEmpty/IsStringEmpty.tsx @@ -0,0 +1,3 @@ +export default function isStringEmpty(str: string) { + return str === "" || str === null || str === undefined; +} diff --git a/src/features/redux/Store/Store.tsx b/src/features/redux/Store/Store.tsx index 55a6590..9fd7cd1 100644 --- a/src/features/redux/Store/Store.tsx +++ b/src/features/redux/Store/Store.tsx @@ -1,9 +1,11 @@ import { configureStore } from "@reduxjs/toolkit"; -import AuthReducer from "../slices/AuthSlice/AuthSlice"; +import StatusReducer from "../slices/StatusSlice/StatusSlice"; +import UserReducer from "../slices/UserSlice/UserSlice"; const store = configureStore({ reducer: { - auth: AuthReducer, + status: StatusReducer, + user: UserReducer, }, }); diff --git a/src/features/redux/slices/AuthSlice/AuthSlice.tsx b/src/features/redux/slices/AuthSlice/AuthSlice.tsx deleted file mode 100644 index b575579..0000000 --- a/src/features/redux/slices/AuthSlice/AuthSlice.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit"; - -export const AuthSlice = createSlice({ - name: "Auth", - initialState: { - creds: { - email: "", - uid: "", - username: "", - full_name: "", - logged_in: false, - }, - }, - reducers: { - login: (state) => { - state.creds.logged_in = true; - }, - setUser: (state, action) => { - state.creds = { - email: action.payload.email, - uid: action.payload.uid, - username: action.payload.username, - full_name: action.payload.full_name, - logged_in: true, - }; - }, - clear: (state) => { - state.creds = { - email: "", - uid: "", - username: "", - full_name: "", - logged_in: false, - }; - }, - }, -}); - -// Action creators are generated for each case reducer function -export const { login, setUser, clear } = AuthSlice.actions; - -export default AuthSlice.reducer; diff --git a/src/features/redux/slices/StatusSlice/StatusSlice.tsx b/src/features/redux/slices/StatusSlice/StatusSlice.tsx new file mode 100644 index 0000000..2baa661 --- /dev/null +++ b/src/features/redux/slices/StatusSlice/StatusSlice.tsx @@ -0,0 +1,29 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const StatusSlice = createSlice({ + name: "Status", + initialState: { + logged_in: false, + onboarding: false, + }, + reducers: { + login: (state) => { + state.logged_in = true; + }, + logout: (state) => { + state.logged_in = false; + }, + setOnboarding: (state) => { + state.onboarding = true; + }, + unsetOnboarding: (state) => { + state.onboarding = false; + }, + }, +}); + +// Action creators are generated for each case reducer function +export const { login, logout, setOnboarding, unsetOnboarding } = + StatusSlice.actions; + +export default StatusSlice.reducer; diff --git a/src/features/redux/slices/UserSlice/UserSlice.tsx b/src/features/redux/slices/UserSlice/UserSlice.tsx new file mode 100644 index 0000000..3927136 --- /dev/null +++ b/src/features/redux/slices/UserSlice/UserSlice.tsx @@ -0,0 +1,51 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const UserSlice = createSlice({ + name: "User", + initialState: { + user: { + email: "", + uid: "", + username: "", + first_name: "", + last_name: "", + full_name: "", + year_level: "", + semester: " ", + course: "", + }, + }, + reducers: { + setUser: (state, action) => { + state.user = { + email: action.payload.email, + uid: action.payload.uid, + username: action.payload.username, + first_name: action.payload.first_name, + last_name: action.payload.last_name, + full_name: action.payload.first_name + " " + action.payload.last_name, + year_level: action.payload.year_level, + semester: action.payload.semester, + course: action.payload.course, + }; + }, + clear: (state) => { + state.user = { + email: "", + uid: "", + username: "", + first_name: "", + last_name: "", + full_name: "", + year_level: "", + semester: " ", + course: "", + }; + }, + }, +}); + +// Action creators are generated for each case reducer function +export const { setUser, clear } = UserSlice.actions; + +export default UserSlice.reducer; diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index 6c6be0e..d9671ec 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -46,3 +46,27 @@ 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; +} + +export interface OnboardingParams { + year_level: string; + course: string; + semester: string; +} diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index bb9c886..5805287 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -1,17 +1,112 @@ -import * as React from "react"; import styles from "../../styles"; import { View, Text } from "react-native"; import { useSelector } from "react-redux"; import { RootState } from "../../features/redux/Store/Store"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; +import { useState, useEffect } from "react"; +import MapView, { Marker, UrlTile } from "react-native-maps"; +import * as Location from "expo-location"; +import GetDistance from "../../components/GetDistance/GetDistance"; +import Button from "../../components/Button/Button"; +import { colors } from "../../styles"; +import { startActivityAsync, ActivityAction } from "expo-intent-launcher"; +type LocationType = Location.LocationObject; export default function Home() { - const creds = useSelector((state: RootState) => state.auth.creds); + const [location, setLocation] = useState(null); + const [dist, setDist] = useState(null); + const [feedback, setFeedback] = useState( + "To continue, please allow Stud-E permission to location services" + ); + + async function requestLocation() { + let { status } = await Location.requestForegroundPermissionsAsync(); + if (status === "granted") { + getLocation(); + return; + } else if (status === "denied") { + setFeedback("Stud-E requires location services to function"); + setTimeout(() => { + startActivityAsync(ActivityAction.LOCATION_SOURCE_SETTINGS); + }, 3000); + console.log("Location Permission denied"); + } + } + + async function getLocation() { + let location = await Location.getCurrentPositionAsync({}); + setLocation(location); + let dist = GetDistance( + location.coords.latitude, + location.coords.longitude, + 8.4857, + 124.6565 + ); + setDist(Math.round(dist)); + } + useEffect(() => { + requestLocation(); + }, []); + + const ustpCoords = { + latitude: 8.4857, + longitude: 124.6565, + latitudeDelta: 0.000235, + longitudeDelta: 0.000067, + }; + function CustomMap() { + if (dist !== null && location !== null) { + if (dist <= 1.5) { + // Just switch this condition for map debugging + return ; + } else { + return ( + + + You are too far from USTP {"\n"} + Get closer to use Stud-E + + + + {dist}km away from USTP {"\n"} + + + ); + } + } else { + return ( + + {feedback} + + + ); + } + } + const creds = useSelector((state: RootState) => state.user.user); return ( - Template Homepage - {JSON.stringify(creds)} + ); diff --git a/src/routes/Login/Login.tsx b/src/routes/Login/Login.tsx index c18617d..a4283cd 100644 --- a/src/routes/Login/Login.tsx +++ b/src/routes/Login/Login.tsx @@ -17,12 +17,17 @@ import { RootDrawerParamList } from "../../interfaces/Interfaces"; import { UserInfo, UserLogin } from "../../components/Api/Api"; import { ParseLoginError } from "../../components/ParseError/ParseError"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; -import { setUser as setStateUser } from "../../features/redux/slices/AuthSlice/AuthSlice"; +import { setUser } from "../../features/redux/slices/UserSlice/UserSlice"; +import { + login, + setOnboarding, + unsetOnboarding, +} from "../../features/redux/slices/StatusSlice/StatusSlice"; export default function Login() { const navigation = useNavigation(); const dispatch = useDispatch(); - const [user, setUser] = useState({ + const [creds, setCreds] = useState({ username: "", password: "", error: "", @@ -49,11 +54,11 @@ export default function Login() { placeholder="Username" placeholderTextColor="white" autoCapitalize="none" - value={user.username} + value={creds.username} onChange={( e: NativeSyntheticEvent ): void => { - setUser({ ...user, username: e.nativeEvent.text }); + setCreds({ ...creds, username: e.nativeEvent.text }); }} /> @@ -62,42 +67,43 @@ export default function Login() { placeholder="Password" placeholderTextColor="white" secureTextEntry={true} - value={user.password} + value={creds.password} onChange={( e: NativeSyntheticEvent ): void => { - setUser({ ...user, password: e.nativeEvent.text }); + setCreds({ ...creds, password: e.nativeEvent.text }); }} /> - {user.error} + {creds.error} diff --git a/src/routes/Register/Register.tsx b/src/routes/Register/Register.tsx index 5b224ca..97c1b8c 100644 --- a/src/routes/Register/Register.tsx +++ b/src/routes/Register/Register.tsx @@ -160,7 +160,7 @@ export default function Register() { } else { setUser({ ...user, - feedback: ParseError(JSON.stringify(result[2])), + feedback: ParseError(JSON.stringify(result[1])), }); } }); diff --git a/src/routes/Revalidation/Revalidation.tsx b/src/routes/Revalidation/Revalidation.tsx index bee1ca4..e2f099e 100644 --- a/src/routes/Revalidation/Revalidation.tsx +++ b/src/routes/Revalidation/Revalidation.tsx @@ -7,8 +7,14 @@ import { colors } from "../../styles"; import { useEffect, useState } from "react"; import { useNavigation } from "@react-navigation/native"; import { RootDrawerParamList } from "../../interfaces/Interfaces"; -import { setUser } from "../../features/redux/slices/AuthSlice/AuthSlice"; +import { + login, + unsetOnboarding, +} from "../../features/redux/slices/StatusSlice/StatusSlice"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; +import { setUser } from "../../features/redux/slices/UserSlice/UserSlice"; +import { setOnboarding } from "../../features/redux/slices/StatusSlice/StatusSlice"; +import AsyncStorage from "@react-native-async-storage/async-storage"; export default function Revalidation() { const dispatch = useDispatch(); @@ -17,14 +23,23 @@ export default function Revalidation() { useEffect(() => { setState("Previous session found"); TokenRefresh().then(async (response) => { - if (response[0]) { - let user_info = await UserInfo(); - await dispatch(setUser(user_info)); - if (!(user_info.year_level || user_info.course || user_info.semester)) { + let user_info = await UserInfo(); + if (response && user_info[0]) { + dispatch(login()); + dispatch(setUser(user_info[1])); + if ( + !( + user_info[1].year_level || + user_info[1].course || + user_info[1].semester + ) + ) { + dispatch(setOnboarding()); await setTimeout(() => { navigation.navigate("Onboarding"); }, 700); } else { + dispatch(unsetOnboarding()); await setTimeout(() => { navigation.navigate("Home"); }, 700); @@ -32,6 +47,7 @@ export default function Revalidation() { } else { await setState("Session expired"); await setTimeout(() => { + AsyncStorage.clear(); navigation.navigate("Login"); }, 700); } diff --git a/src/styles.tsx b/src/styles.tsx index 67877a5..3bf00a7 100644 --- a/src/styles.tsx +++ b/src/styles.tsx @@ -1,5 +1,10 @@ -import { createErrorHandler } from "expo/build/errors/ExpoErrorManager"; -import { StyleSheet } from "react-native"; +import { StyleSheet, Dimensions } from "react-native"; + +const width = Dimensions.get("window").width; +const height = Dimensions.get("window").height; + +const containerWidth = width - width * 0.08; +const containerHeight = height - height * 0.01; export const colors = { orange_1: "#FFDEAD", @@ -15,6 +20,7 @@ export const colors = { login_color: "#0047AB", reg_color: "#0096FF", head: "white" + blue_disabled: "#C07624", }; export const font_sizes = { @@ -32,17 +38,13 @@ const styles = StyleSheet.create({ width: "100%", }, container: { - marginTop: "5%", - width: "92%", - borderRadius: 15, - backgroundColor: colors.blue_2, alignItems: "center", alignSelf: "center", - paddingTop: 32, - paddingBottom: 32, - justifyContent: "flex-start", + justifyContent: "center", display: "flex", flexDirection: "column", + flex: 1, + paddingHorizontal: 4, }, flex_row: { display: "flex", @@ -53,6 +55,7 @@ const styles = StyleSheet.create({ display: "flex", flexDirection: "column", alignItems: "center", + justifyContent: "center", }, text_white_tiny: { color: colors.text_default, @@ -88,19 +91,32 @@ const styles = StyleSheet.create({ justifyContent: "center", alignSelf: "center", alignItems: "center", + textAlign: "center", display: "flex", flexDirection: "row", marginVertical: 4, marginHorizontal: 8, padding: 8, borderRadius: 16, + width: width * 0.4, }, text_input: { color: colors.text_default, backgroundColor: colors.blue_1, - width: "50%", padding: 10, borderRadius: 8, + width: width * 0.5, + }, + dropdown_template: { + borderRadius: 16, + width: "70%", + marginVertical: 6, + }, + map: { + flex: 1, + height: containerHeight, + width: containerWidth, + alignSelf: "center", }, profile: { height: 80, @@ -140,7 +156,5 @@ const styles = StyleSheet.create({ inactiveText: { color: 'white', }, - }); - export default styles;