Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements and UI Updates #65

Merged
merged 6 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@types/file-saver": "^2.0.7",
"@types/jest": "^29.2.0",
"@types/node": "^18.15.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react-lottie": "^1.2.6",
"@types/react-router-dom": "^5.3.3",
"axios": "^1.7.7",
"file-saver": "^2.0.5",
"headlessui": "^0.0.0",
"heroicons": "^2.0.11",
"jwt-decode": "^4.0.0",
Expand Down
34 changes: 17 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { jwtDecode } from "jwt-decode";
import React, { createContext, useContext, useEffect } from "react";
import { useContext, useEffect } from "react";
import { useCookies } from "react-cookie";
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import "./App.css";
import MemberClient from "./client/MemberClient";
import Footer from "./components/Footer";
import Menu from "./components/Menu";
import RequireAuth from "./components/RequireAuth";
import { AuthContext } from "./hooks/useAuth";
import { AuthContext, useAuth } from "./hooks/useAuth";
import AttendanceRecordPage from "./pages/AttendanceRecordPage";
import Error404 from "./pages/Error404";
import EventDetailsPage from "./pages/EventDetailsPage";
Expand All @@ -16,20 +16,10 @@ import LoginPage from "./pages/LoginPage";
import UserPreference from "./pages/UserPreference";
import { JWTAuthToken } from "./util/Types";

export type UserID = string | null;

type UserContext = {
userID: UserID;
setUserID: React.Dispatch<React.SetStateAction<UserID>>;
};

export const LoginContext = createContext<UserContext>({
userID: null,
setUserID: () => {},
});

function App() {
const { member, loading, setMember, setLoading } = useContext(AuthContext);
const { member, loading, setMember, setLoading, setCheckedCookie } =
useContext(AuthContext);
const { logout } = useAuth();
const [cookies] = useCookies(["token"]);

useEffect(() => {
Expand All @@ -44,13 +34,23 @@ function App() {
if (memberResponse.data) {
setMember(memberResponse.data);
} else {
console.log("Error fetching member: ", memberResponse.error);
console.log("Unable to verify member: ", memberResponse.error);
logout();
}
}
setCheckedCookie(true);
setLoading(false);
};
checkLoggedIn();
}, [cookies.token, setMember, loading, setLoading, member]);
}, [
cookies.token,
setMember,
loading,
setLoading,
member,
setCheckedCookie,
logout,
]);

return (
<div className="flex flex-col min-h-screen justify-between">
Expand Down
32 changes: 22 additions & 10 deletions src/client/AuthClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from "axios";
import axios, { AxiosError } from "axios";
import { AuthResponse, Response } from "../util/Types";

class AuthClient {
Expand All @@ -7,15 +7,27 @@ class AuthClient {
lastName: string
): Promise<Response<AuthResponse>> {
// Call the login API
const response = await axios.post(`/api/auth`, {
nuid,
lastName,
});
return {
data: response.data.auth,
error: response.data.error,
status: response.status,
};
try {
const response = await axios.post(`/api/auth`, {
nuid,
lastName,
});
return {
data: response.data.auth,
error: response?.data.error,
status: response.status,
};
} catch (e) {
if (e instanceof AxiosError) {
let error: AxiosError<any, any> = e;
return {
data: undefined,
error: error.response?.data.error,
status: error.response?.status,
};
}
throw e;
}
}
}

Expand Down
33 changes: 0 additions & 33 deletions src/client/EventClient.ts

This file was deleted.

20 changes: 12 additions & 8 deletions src/client/MemberClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from "axios";
import axios, { AxiosError } from "axios";
import { Member, Response } from "../util/Types";

export default class MemberClient {
Expand All @@ -8,17 +8,21 @@ export default class MemberClient {
* @returns The Member with that nuid or undefined
*/
public static async fetchMember(id: string): Promise<Response<Member>> {
const response = await axios.get(`/api/member/getMember/?id=${id}`);
if (response.status === 200) {
try {
const response = await axios.get(`/api/member/getMember/?id=${id}`);
return {
data: response.data,
error: "",
};
} else {
return {
data: undefined,
error: response.data,
};
} catch (e) {
if (e instanceof AxiosError) {
let error: AxiosError<any, any> = e;
return {
data: undefined,
error: error.response?.data,
};
}
throw e;
}
}
}
6 changes: 5 additions & 1 deletion src/components/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PinSVG from ".././assets/Pin.svg";
import TextIconSVG from ".././assets/TextIcon.svg";
import ".././styles.css";
import TriangleError from "../assets/TriangleError.svg";
import { saveICSEvent } from "../util/saveICSEvent";
import {
AttendanceChange,
Event,
Expand Down Expand Up @@ -111,7 +112,10 @@ const EventCard = ({
<li className="hover:underline py-3 px-4">
Enable Notifications
</li>
<li className="hover:underline border-t border-gray-300 border-solid pb-3 pt-2 px-4">
<li
className="hover:underline border-t border-gray-300 border-solid pb-3 pt-2 px-4"
onClick={() => saveICSEvent(event)}
>
Add to Calendar
</li>
</ul>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const Menu = (): ReactElement => {
<div>
<Link to={`/events`}>
<img
src="https://images.squarespace-cdn.com/content/v1/5939fcd1db29d6ec60929205/1599605891670-HLWDP9UQBSK6XT6DLF3A/SGA+White+Text+Transparent.png%3Fformat=1500w"
src="https://images.squarespace-cdn.com/content/v1/5939fcd1db29d6ec60929205/7c34e45d-ee16-4883-8334-358495ef8e38/SGA+Logo+and+Seal.png?format=1500w"
alt="Student Government Association Logo"
className="w-32 cursor-pointer"
onClick={() => setShowSidebar(false)}
Expand All @@ -66,7 +66,7 @@ const Menu = (): ReactElement => {
<div className="flex flex-col items-start w-full h-full">
<Link to={`/events`} className="p-8">
<img
src="https://images.squarespace-cdn.com/content/v1/5939fcd1db29d6ec60929205/1599605891670-HLWDP9UQBSK6XT6DLF3A/SGA+White+Text+Transparent.png%3Fformat=1500w"
src="https://images.squarespace-cdn.com/content/v1/5939fcd1db29d6ec60929205/7c34e45d-ee16-4883-8334-358495ef8e38/SGA+Logo+and+Seal.png?format=1500w"
alt="Student Government Association Logo"
className="w-48 cursor-pointer"
onClick={() => setShowSidebar(false)}
Expand Down
6 changes: 3 additions & 3 deletions src/components/RequireAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import Loading from "./Loading";
// Navigation to the login menu if the user is not logged in.

const RequireAuth = () => {
const { member, loading } = useContext(AuthContext);
const { member, loading, checkedCookie } = useContext(AuthContext);

if (member) {
if (member && checkedCookie) {
return <Outlet />;
} else if (loading) {
} else if (loading || !checkedCookie) {
return <Loading />;
} else {
return <Navigate to="/" />;
Expand Down
12 changes: 3 additions & 9 deletions src/components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { ReactElement, useContext } from "react";
import { ReactElement } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { LoginContext } from "../App";
import { useAuth } from "../hooks/useAuth";

const Settings = (props: {
useState: React.Dispatch<React.SetStateAction<boolean>>;
}): ReactElement => {
const { setUserID } = useContext(LoginContext);
const { logout } = useAuth();
let navigate = useNavigate();

function logout() {
localStorage.removeItem("user");
setUserID(null);
navigate("/");
}

function Click(route: string) {
navigate(route);
props.useState(false);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ import { JWTAuthToken, Member } from "../util/Types";
type AuthContextType = {
member?: Member;
loading: boolean;
checkedCookie: boolean;
setMember: (member?: Member) => void;
setLoading: (loading: boolean) => void;
setCheckedCookie: (checkedCookie: boolean) => void;
};

export const AuthContext = createContext<AuthContextType>({
member: undefined,
loading: false,
checkedCookie: false,
setMember: () => {},
setLoading: () => {},
setCheckedCookie: () => {},
});

export const useAuth = (): {
Expand Down
12 changes: 11 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,20 @@ const root = ReactDOM.createRoot(
const Root = () => {
const [member, setMember] = React.useState<Member | undefined>(undefined);
const [loading, setLoading] = React.useState(false);
const [checkedCookie, setCheckedCookie] = React.useState(false);

return (
<QueryClientProvider client={queryClient}>
<AuthContext.Provider value={{ member, loading, setMember, setLoading }}>
<AuthContext.Provider
value={{
member,
loading,
checkedCookie,
setMember,
setLoading,
setCheckedCookie,
}}
>
<CookiesProvider>
<App />
</CookiesProvider>
Expand Down
6 changes: 5 additions & 1 deletion src/pages/EventDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import TextIconSVG from ".././assets/TextIcon.svg";
import Loading from "../components/Loading";
import useEvent from "../hooks/useEvent";
import { createDateString } from "../util/Date";
import { saveICSEvent } from "../util/saveICSEvent";

//if time is not defined make it all day
const EventDetailsPage = (): ReactElement => {
Expand Down Expand Up @@ -60,7 +61,10 @@ const EventDetailsPage = (): ReactElement => {
<li className="hover:underline py-3 px-4">
Enable Notifications
</li>
<li className="hover:underline border-t border-gray-300 border-solid pb-3 pt-2 px-4">
<li
className="hover:underline border-t border-gray-300 border-solid pb-3 pt-2 px-4"
onClick={() => saveICSEvent(event)}
>
Add to Calendar
</li>
</ul>
Expand Down
Loading
Loading