Skip to content

Commit

Permalink
add the frontend chapter dashboard (#19)
Browse files Browse the repository at this point in the history
* adding front end

* updated front end routes still not working

* fixing front end

* adding image, changing spacing, changing font, adding box

* little errors but starting to do routes

* added card popup for view button

* everything donegit add .git add .

* to dos for the future

* toggle (#16)

* checkbox (#17)

* toggle

* toggling

* checkbox

* refactor entire page

* merge and add filter

* fix id issues

* removing isAdmin for chapter dashboard routes

* fixing toggle requests route

* fix deleterequest route admin

---------

Co-authored-by: logbrass <[email protected]>
Co-authored-by: aditighoshh <[email protected]>
Co-authored-by: zoegoldman <[email protected]>
Co-authored-by: Caroline Chen <[email protected]>
Co-authored-by: kygchng <[email protected]>
  • Loading branch information
6 people authored Jan 28, 2025
1 parent 60385d9 commit 4483af3
Show file tree
Hide file tree
Showing 36 changed files with 39,488 additions and 132 deletions.
2 changes: 1 addition & 1 deletion client/src/AdminDashboard/DeleteUserButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import Button from '@mui/material/Button';
import { deleteUser } from './api.tsx';
import { deleteUser } from './api.ts';
import LoadingButton from '../components/buttons/LoadingButton.tsx';
import ConfirmationModal from '../components/ConfirmationModal.tsx';
import AlertType from '../util/types/alert.ts';
Expand Down
2 changes: 1 addition & 1 deletion client/src/AdminDashboard/PromoteUserButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import Button from '@mui/material/Button';
import { upgradePrivilege } from './api.tsx';
import { upgradePrivilege } from './api.ts';
import LoadingButton from '../components/buttons/LoadingButton.tsx';
import ConfirmationModal from '../components/ConfirmationModal.tsx';

Expand Down
2 changes: 1 addition & 1 deletion client/src/AdminDashboard/UserTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LocationCity } from '@material-ui/icons';
import { PaginationTable, TColumn } from '../components/PaginationTable.tsx';
import DeleteUserButton from './DeleteUserButton.tsx';
import PromoteUserButton from './PromoteUserButton.tsx';
import { useData } from '../util/api.tsx';
import { useData } from '../util/api.ts';
import { useAppSelector } from '../util/redux/hooks.ts';
import { selectUser } from '../util/redux/userSlice.ts';
import IUser from '../util/types/user.ts';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* A file containing all the api calls for the admin dashboard.
*/
import { deleteData, putData } from '../util/api.tsx';
import { deleteData, putData } from '../util/api.ts';

/**
* Sends a request to the server to delete a user
Expand Down
6 changes: 6 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import AlertPopup from './components/AlertPopup.tsx';
import InviteRegisterPage from './Authentication/InviteRegisterPage.tsx';
import Landing from './Landing/Landing.tsx';
import TempAdminDashboardPage from './AdminDashboard/TempAdminDashboardPage.tsx';
import ChapterDashboardPage from './Chapters/ChapterDashboardPage.tsx';

function App() {
return (
Expand Down Expand Up @@ -68,6 +69,11 @@ function App() {
<Route path="/admin" element={<TempAdminDashboardPage />} />
</Route>

<Route
path="/chapterDash/:chapterId"
element={<ChapterDashboardPage />}
/>

{/* Route which redirects to a different page depending on if the user is an authenticated or not by utilizing the DynamicRedirect component */}
<Route
path="/"
Expand Down
2 changes: 1 addition & 1 deletion client/src/Authentication/InviteRegisterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import PrimaryButton from '../components/buttons/PrimaryButton.tsx';
import ScreenGrid from '../components/ScreenGrid.tsx';
import FormRow from '../components/form/FormRow.tsx';
import FormGrid from '../components/form/FormGrid.tsx';
import { useData } from '../util/api.tsx';
import { useData } from '../util/api.ts';

/**
* A page users visit to be able to register for a new account by inputting
Expand Down
15 changes: 12 additions & 3 deletions client/src/Authentication/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,13 @@ function LoginPage() {

const dispatch = useAppDispatch();
function dispatchUser(
id: string,
userEmail: string,
city: string,
state: string,
admin: boolean,
) {
dispatch(loginRedux({ email: userEmail, city, state, admin }));
dispatch(loginRedux({ id, email: userEmail, city, state, admin }));
}

const clearErrorMessages = () => {
Expand Down Expand Up @@ -197,8 +198,16 @@ function LoginPage() {
loginUser(values.email, values.password)
.then((user) => {
console.log('navigating to home!');
dispatchUser(user.email!, user.city!, user.state!, user.admin!);
navigate('/home');
dispatchUser(
// eslint-disable-next-line no-underscore-dangle
user._id!,
user.email!,
user.city!,
user.state!,
user.admin!,
);
// eslint-disable-next-line no-underscore-dangle
navigate(`/chapterDash/${user._id!}`, { replace: true });
})
.catch((e) => {
console.log('failed to login...');
Expand Down
2 changes: 1 addition & 1 deletion client/src/Authentication/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* A file for defining functions used to interact with the backend server
* for authentication purposes.
*/
import { postData } from '../util/api.tsx';
import { postData } from '../util/api.ts';

/**
* Sends a request to the server to log in a user
Expand Down
41 changes: 41 additions & 0 deletions client/src/Chapters/AcceptingRequestsToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FormControlLabel, Switch, Typography } from '@mui/material';
import { Box } from '@mui/system';
import React from 'react';
import IUser from '../util/types/user.ts';
import { putData } from '../util/api.ts';

interface IAcceptingRequestsToggleProps {
chapter: IUser;
}

function AcceptingRequestsToggle({ chapter }: IAcceptingRequestsToggleProps) {
const [checked, setChecked] = React.useState(chapter.isAcceptingRequests);
const [error, setError] = React.useState<string | null>(null);

const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
const response = await putData(`user/toggleRequests/${chapter.id}`, {});

if (response.error) {
setError(response.error.message || 'An error occurred');
}
};

return (
<Box>
<FormControlLabel
control={
<Switch checked={checked} onChange={handleChange} color="primary" />
}
label={
checked
? 'Currently accepting requests'
: 'Not curently accepting requests'
}
/>
{error && <Typography sx={{ color: 'red' }}>Error: {error}</Typography>}
</Box>
);
}

export default AcceptingRequestsToggle;
157 changes: 157 additions & 0 deletions client/src/Chapters/ActiveRequestsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import {
Box,
Button,
Checkbox,
FormControl,
InputLabel,
Menu,
MenuItem,
Select,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Typography,
} from '@mui/material';
import React, { useEffect, useState } from 'react';
import { formatDate } from '../util/date.ts';
import IBirthdayRequest from '../util/types/birthdayRequest.ts';
import RequestDetailDialog from './RequestDetailDialog.tsx';

interface IActiveRequestsTableProps {
activeRequests: IBirthdayRequest[];
fulfillRequest: (request: IBirthdayRequest) => void;
}

function ActiveRequestsTable({
activeRequests,
fulfillRequest,
}: IActiveRequestsTableProps) {
const [open, setOpen] = useState(false);
const [selectedRequest, setSelectedRequest] = useState<IBirthdayRequest>(
{} as IBirthdayRequest,
);

const [filterMonthOptions, setFilterMonthOptions] = useState<number[][]>([]);
const [filterMonth, setFilterMonth] = useState<number[] | null | undefined>(
undefined,
);

const viewRequest = (request: IBirthdayRequest) => {
setSelectedRequest(request);
setOpen(true);
};

useEffect(() => {
const months = activeRequests
.map((request) => {
const date = new Date(request.childBirthday);
return [date.getMonth() + 1, date.getFullYear()];
})
.filter(
(value, index, self) =>
index ===
self.findIndex((t) => JSON.stringify(t) === JSON.stringify(value)),
);

console.log(months);

setFilterMonthOptions(months);
}, [activeRequests]);

const filteredRequests = activeRequests.filter((request) => {
if (!filterMonth) {
return true;
}

const date = new Date(request.childBirthday);
return (
date.getMonth() + 1 === filterMonth[0] &&
date.getFullYear() === filterMonth[1]
);
});

return (
<>
<Box>
<Typography variant="h5" fontWeight="bold" mb={1}>
Active Requests
</Typography>
<FormControl sx={{ m: 1, minWidth: 150, color: 'black' }}>
<InputLabel>Filter by month</InputLabel>
<Select
label="Filter by month"
value={
// eslint-disable-next-line no-nested-ternary
filterMonth === undefined
? undefined
: filterMonth
? `${filterMonth[0]}/${filterMonth[1]}`
: 'None'
}
onChange={(event) => {
if (event.target.value === 'None') {
setFilterMonth(null);
return;
}

const value = (event.target.value as string).split('/');
setFilterMonth([parseInt(value[0], 10), parseInt(value[1], 10)]);
}}
>
<MenuItem value="None">
<em>None</em>
</MenuItem>
{filterMonthOptions.map((month) => (
<MenuItem
value={`${month[0]}/${month[1]}`}
key={`${month[0]}/${month[1]}`}
>
{month[0]}/{month[1]}
</MenuItem>
))}
</Select>
</FormControl>
<Table>
<TableHead>
<TableRow>
<TableCell>Child Name</TableCell>
<TableCell>Child Birthday</TableCell>
<TableCell>Agency Name</TableCell>
<TableCell>Mark Completed</TableCell>
<TableCell>{}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredRequests.map((request) => (
<TableRow key={request.id}>
<TableCell>{request.childName}</TableCell>
<TableCell>{formatDate(request.childBirthday)}</TableCell>
<TableCell>{request.agencyOrganization}</TableCell>
<TableCell>
<Checkbox onClick={() => fulfillRequest(request)} />
</TableCell>
<TableCell>
<Button
variant="contained"
onClick={() => viewRequest(request)}
>
View
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
<RequestDetailDialog
request={selectedRequest}
open={open}
onClose={() => setOpen(false)}
/>
</>
);
}

export default ActiveRequestsTable;
21 changes: 21 additions & 0 deletions client/src/Chapters/ChapterDashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Box, Typography } from '@mui/material';
import React from 'react';
import Logo from './Logo.tsx';
import IUser from '../util/types/chapter.ts';

interface IChapterDashboardHeaderProps {
chapter: IUser;
}

function ChapterDashboardHeader({ chapter }: IChapterDashboardHeaderProps) {
return (
<Box sx={{ textAlign: 'left' }}>
<Logo />
<Typography variant="h4" fontWeight="bold" mb={1}>
Welcome {chapter.city}, {chapter.state}!
</Typography>
</Box>
);
}

export default ChapterDashboardHeader;
Loading

0 comments on commit 4483af3

Please sign in to comment.