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

Logic to Receive Data from API #60

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@headlessui/react": "^1.7.3",
"@heroicons/react": "^2.0.12",
"@tanstack/react-query": "^5.25.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
Expand All @@ -14,15 +15,16 @@
"@types/react-dom": "^18.0.0",
"@types/react-lottie": "^1.2.6",
"@types/react-router-dom": "^5.3.3",
"axios": "^1.6.7",
"headlessui": "^0.0.0",
"heroicons": "^2.0.11",
"localforage": "^1.10.0",
"match-sorter": "^6.3.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.10.0",
"react-lottie": "^1.2.3",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"sort-by": "^1.2.0",
"tw-elements": "^1.0.0-beta1",
Expand Down Expand Up @@ -63,4 +65,4 @@
"tailwindcss": "^3.1.8",
"ts-jest": "^29.0.3"
}
}
}
81 changes: 45 additions & 36 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React, { createContext, useState } from "react";
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import "./App.css";
import Footer from "./components/Footer";
import Menu from "./components/Menu";
Expand All @@ -9,7 +10,9 @@ import Error404 from "./pages/Error404";
import EventDetailsPage from "./pages/EventDetailsPage";
import Homepage from "./pages/Homepage";
import LoginPage from "./pages/LoginPage";
import { PastVotesComponent } from "./pages/PastVotes";
import UserPreference from "./pages/UserPreference";
import { VotingPage } from "./pages/VotingPage";

export type UserID = string | null;

Expand All @@ -23,48 +26,54 @@ export const LoginContext = createContext<UserContext>({
setUserID: () => {},
});

export const queryClient = new QueryClient();

function App() {
const [userID, setUserID] = useState<UserID>(localStorage.getItem("user"));

return (
<LoginContext.Provider value={{ userID, setUserID }}>
<div className="flex flex-col min-h-screen justify-between">
<Router>
<div className={`${userID && " lg:flex lg:min-h-fit "}`}>
{userID ? (
<>
<Menu />
<div className="hidden lg:block lg:min-w-[19vw]"></div>
</>
) : null}
<QueryClientProvider client={queryClient}>
<div className="flex flex-col min-h-screen justify-between">
<Router>
<div className={`${userID && " lg:flex lg:min-h-fit "}`}>
{userID ? (
<>
<Menu />
<div className="hidden lg:block lg:min-w-[19vw]"></div>
</>
) : null}

<Routes>
<Route
path="/"
element={<LoginPage />}
errorElement={<Error404 />}
/>
<Route element={<RequireAuth />}>
<Route path="/events" element={<Homepage />} />
<Route path="/events/:id" element={<EventDetailsPage />} />
<Route path="/user/" element={<UserPreference />} />
<Route path="/record" element={<AttendanceRecordPage />} />
</Route>
<Routes>
<Route
path="/"
element={<LoginPage />}
errorElement={<Error404 />}
/>
<Route element={<RequireAuth />}>
<Route path="/events" element={<Homepage />} />
<Route path="/events/:id" element={<EventDetailsPage />} />
<Route path="/user/" element={<UserPreference />} />
<Route path="/record" element={<AttendanceRecordPage />} />
<Route path="/voting" element={<VotingPage />} />
<Route path="/voting/past" element={<PastVotesComponent />} />
</Route>

<Route path="*" element={<Error404 />} />
</Routes>
</div>
</Router>
{userID ? (
<div className="lg:flex">
{/* Used to take into account the always-visible side bar */}
<div className="hidden lg:block lg:min-w-[19vw]"></div>
<Footer hideInfo={false} />
</div>
) : (
<Footer hideInfo={true} />
)}
</div>
<Route path="*" element={<Error404 />} />
</Routes>
</div>
</Router>
{userID ? (
<div className="lg:flex">
{/* Used to take into account the always-visible side bar */}
<div className="hidden lg:block lg:min-w-[19vw]"></div>
<Footer hideInfo={false} />
</div>
) : (
<Footer hideInfo={true} />
)}
</div>
</QueryClientProvider>
</LoginContext.Provider>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/assets/SearchBarIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/client/attendanceChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createdAttendanceChange } from "../util/Types";
import { api } from "./login";

export const getAllAttendanceChangesForMember = async (uuid: string) => {
const attendance = await api.get("/attendance/getAllAttendanceChanges", {
params: {
memberID: uuid,
},
});
return attendance.data;
};

export const createAttendanceChangeRequest = async (
attendanceChange: createdAttendanceChange
) => {
console.log(attendanceChange);
const attendance = await api.post(
"/attendance/postAttendanceChange",
attendanceChange
);

return attendance.data;
};
21 changes: 21 additions & 0 deletions src/client/attendanceRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { api } from "./login";

export const getAttendanceRecord = async (memberID: string) => {
const response = await api.get("/record/getAttendanceRecord", {
params: {
id: memberID,
},
});

return response.data.record;
};

export const getAttendanceEventsFromRecord = async (memberID: string) => {
const response = await api.get("/record/getAttendanceEvents", {
params: {
id: memberID,
},
});

return response.data.events;
};
70 changes: 15 additions & 55 deletions src/client/client.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,23 @@
import { mockAttendanceChange } from "../data/attendanceChange";
import { mockAttendanceRecord } from "../data/attendanceRecord";
import { mockEvents } from "../data/events";
import UserJSON from "../data/users.json";
import {
AttendanceChange,
AttendanceRecord,
ChangeStatus,
Event,
Member,
RequestType,
} from "../util/Types";
import { Event, Member } from "../util/Types";

// TODO: move these to a test file along with the mock data

/**
* Gets an event with the given id
* @param id The id of the event being fetched
* @returns The event if it can be found, or an error
*/
export function fetchEvent(id: number): Promise<Event> {
export function fetchEvent(id: string): Promise<Event> {
return new Promise((resolve, reject) => {
setTimeout(() => {
const event = mockEvents.find((e) => e.id === id);
const event = mockEvents.find((e) => e.uuid === id);
event ? resolve(event) : reject("404 Not found");
}, 1000);
});
}

/**
* Gets all the events
* @returns An array of events if they can be found, or an error
*/
export function fetchAllEvents(): Promise<Event[]> {
return new Promise((resolve, reject) => {
setTimeout(() => {
mockEvents ? resolve(mockEvents) : reject("404 Not found");
}, 1000);
});
}

/**
* Gets the member with the associated nuid
* @param nuid The nuid of the member
Expand All @@ -53,15 +34,16 @@ export function fetchMember(nuid: string): Promise<Member | undefined> {
});
}

/*
//sample function to fetch all attendance change requests
export const findAttendanceChangeRequests = (
memberID: string,
eventID: Number
eventID: string
) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const attendanceChange = mockAttendanceChange.find(
(ac) => ac.memberID === parseInt(memberID) && ac.eventID === eventID
(ac) => ac.memberID === memberID && ac.eventID === eventID
);
attendanceChange
? resolve(attendanceChange)
Expand All @@ -76,7 +58,7 @@ export const findAttendanceChangeRequestForMember = (
return new Promise((resolve, reject) => {
setTimeout(() => {
const attendanceChange = mockAttendanceChange.filter(
(ac) => ac.memberID !== parseInt(memberID)
(ac) => ac.memberID !== memberID
);
attendanceChange
? resolve(attendanceChange)
Expand All @@ -87,16 +69,16 @@ export const findAttendanceChangeRequestForMember = (

export const createAttendanceChange = (
memberID: string,
eventID: Number
eventID: string
): Promise<AttendanceChange | undefined> => {
return new Promise((resolve, reject) => {
setTimeout(() => {
//Sample Attendance Change being added
const newAttendance: AttendanceChange = {
id: mockAttendanceChange.length + 1,
memberID: parseInt(memberID),
uuid: mockAttendanceChange.length.toString(),
memberID: memberID,
eventID: eventID,
request_type: RequestType.ABSENT,
type: RequestType.ABSENT,
reason: "idk",
submit_time: new Date("2001-01-01 12:00:00"),
change_status: ChangeStatus.EXCUSED,
Expand All @@ -113,34 +95,12 @@ export const getAttendanceRecordForMember = (
return new Promise((resolve, reject) => {
setTimeout(() => {
const attendanceRecordForMember = mockAttendanceRecord.filter(
(attendanceRecord) => attendanceRecord.memberID !== parseInt(memberId)
(attendanceRecord) => attendanceRecord.member_id !== memberId
);
attendanceRecordForMember
? resolve(attendanceRecordForMember)
: reject("No attendanceRecordForMember");
}, 1000);
});
};

export const getAttendanceEventsForMember = (
memberId: string
): Promise<Event[]> => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const attendanceRecordForMember = mockAttendanceRecord.filter(
(attendanceRecord) => attendanceRecord.memberID !== parseInt(memberId)
);
const attendanceEventsForMember = attendanceRecordForMember.map(
({ eventID, memberID, attendance_status }) => eventID
);
const events = [];
for (const attendanceEventId of attendanceEventsForMember) {
for (const actualEvent of mockEvents) {
if (actualEvent.id === attendanceEventId) {
events.push(actualEvent);
}
}
}
}, 1000);
});
};
*/
16 changes: 16 additions & 0 deletions src/client/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { api } from "./login";

export const getAllEvents = async () => {
const response = await api.get("/event/getAllEvents");
return response.data;
};

export const getEvent = async (event_id: string) => {
const response = await api.get("/event/getEvent", {
params: {
id: event_id,
},
});

return response.data;
};
21 changes: 21 additions & 0 deletions src/client/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import axios from "axios";

// NOTE: our local backend blocks put/post requests, which is annoying for creating real
// attendance changes, as a quick work-around I used a url of the most recently depoyed
// backend (I know not ideal)
export const api = axios.create({
baseURL: `https://sgatooling-7y9kdz96i-sandboxneu.vercel.app/api`,
headers: {
"Content-Type": "application/json",
},
});

export const loginMember = async (nuid: string, last_name: string) => {
const response = await api.get("/auth", {
params: {
id: nuid,
password: last_name,
},
});
return response.data;
};
31 changes: 31 additions & 0 deletions src/client/member.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { api } from "./login";

export const getMember = async (uuid: string) => {
const response = await api.get("/member/getMember", {
params: {
id: uuid,
},
});

return response.data.member;
};

export const getMemberTags = async (uuid: string) => {
const reponse = await api.get("/member/getMemberTags", {
params: {
id: uuid,
},
});

return reponse.data.memberTags;
};

export const updateMemberPreferences = async (uuid: string) => {
const response = await api.get("/member/updateMemberPreferences", {
params: {
id: uuid,
},
});

return response.data;
};
Loading
Loading