Skip to content

Commit

Permalink
Volunteer monitor logs page (#139)
Browse files Browse the repository at this point in the history
* Create PR for #137

* Your Monitor Logs table

* Export buton (no functionality)

* stuff

* Multiple partners

* Fix checkbox + some cleanup

* Move descriptions out

* Mobile table

* YourLogs -> VolunteerLogs + cleanup

* Fix file names

* Rounded header

* Resolve console warnings

Co-authored-by: janehvo <[email protected]>
Co-authored-by: Jane Vo <[email protected]>
  • Loading branch information
3 people authored May 31, 2022
1 parent f2a3009 commit 9f4a73a
Show file tree
Hide file tree
Showing 13 changed files with 634 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Navbar from './components/Navbar/Navbar';
import PeoplePage from './pages/PeoplePage';
import Species from './pages/Species';
import Numbers from './pages/EmergencyNumbers';
import VolunteerLogs from './pages/VolunteerLogsPage';
import NotFoundPage from './pages/NotFoundPage';

import AdminInviteModal from './components/Authentication/AdminInviteModal';
Expand Down Expand Up @@ -132,6 +133,17 @@ function App() {
path="/edit-log-template"
element={<ProtectedRoute Component={MonitorLogEditPage} roles={[ADMIN_ROLE]} />}
/>
<Route
exact
path="/your-logs"
element={
<ProtectedRoute
Component={VolunteerLogs}
path="/logout"
roles={[ADMIN_ROLE, VOLUNTEER_ROLE]}
/>
}
/>
<Route
exact
path="/numbers"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ const Pagination = ({
</pre> */}
<Flex
bg="#4E4E4E"
alignItems="center"
alignItems={{ md: 'center', base: 'flex-end' }}
pl="24px"
pt="8px"
pb="8px"
pr="24px"
borderBottomRadius={10}
direction={{ md: 'row', base: 'column' }}
>
<Flex alignItems="center">
<Flex pr="8px">
Expand Down
2 changes: 1 addition & 1 deletion src/components/AdminPageTable/AdminPageTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { useTable, usePagination, useSortBy } from 'react-table';
import { Table, Tr, Td, Tbody, Spinner } from '@chakra-ui/react';
import AdminPageHeader from './AdminPageHeader';
import Pagination from './Pagination';
import Pagination from '../../common/TablePagination';
import CellStructure from './AdminPageStructure';

/* eslint-enable react/destructuring-assignment, react/prop-types */
Expand Down
21 changes: 16 additions & 5 deletions src/components/AdminPageTable/ExportLogsModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useToast,
useDisclosure,
} from '@chakra-ui/react';
import { BiExport } from 'react-icons/bi';
import { CgSoftwareUpload } from 'react-icons/cg';

// modal for the export selected logs button
const ExportLogsModal = ({ count }) => {
Expand All @@ -22,13 +22,13 @@ const ExportLogsModal = ({ count }) => {
const exportLogs = () => {
onExportClose();

// Make backend call
// TO DO: Make backend call
// eslint-disable-next-line no-console
console.log(`Exporting ${count} logs`);

toast({
title: 'Export Successful!',
description: `You've exported ${count} logs.`,
description: `You've exported ${count} log(s).`,
status: 'success',
duration: 5000,
isClosable: true,
Expand All @@ -37,7 +37,12 @@ const ExportLogsModal = ({ count }) => {

return (
<>
<Button onClick={onExportOpen} variant="solidNoHover" bg="ochBlue" rightIcon={<BiExport />}>
<Button
onClick={onExportOpen}
variant="solidNoHover"
bg="ochBlue"
rightIcon={<CgSoftwareUpload />}
>
Export Selected Logs
</Button>

Expand All @@ -46,7 +51,11 @@ const ExportLogsModal = ({ count }) => {
<ModalContent>
<ModalHeader>Export Selected Logs</ModalHeader>
<ModalBody>
<Text>You are about to export {count} log(s) as csv files.</Text>
{count === 0 ? (
<Text>You have not selected any logs to export.</Text>
) : (
<Text>You are about to export {count} log(s) as csv files.</Text>
)}
</ModalBody>

<ModalFooter>
Expand All @@ -58,6 +67,8 @@ const ExportLogsModal = ({ count }) => {
color="white"
variant="solidNoHover"
onClick={() => exportLogs()}
isDisabled={count === 0}
_hover={{ _disabled: { opacity: 0.4 } }}
>
Yes, Export
</Button>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navbar/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Navbar = ({ onAdminPortal, setOnAdminPortal, changesMade }) => {
];

const volunteer = [
{ text: 'Monitor Logs', path: '/logs' },
{ text: 'Monitor Logs', path: '/your-logs' },
{ text: 'Species Catalog', path: '/species' },
{ text: 'Sections & Segments', path: '/sections' },
{ text: 'Emergency Numbers', path: '/numbers' },
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navbar/NavbarMobile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const NavbarMobile = ({ isAdmin, onAdminPortal, setOnAdminPortal }) => {
];

const volunteer = [
{ text: 'Monitor Logs', path: '/logs' },
{ text: 'Monitor Logs', path: '/your-logs' },
{ text: 'Species Catalog', path: '/species' },
{ text: 'Sections & Segments', path: '/sections' },
{ text: 'Emergency Numbers', path: '/numbers' },
Expand Down
6 changes: 6 additions & 0 deletions src/components/VolunteerLogs/VolunteerLogs.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.table-head th:first-child {
border-radius: 10px 0 0 0px;
}
.table-head th:last-child {
border-radius: 0 10px 0 0;
}
144 changes: 144 additions & 0 deletions src/components/VolunteerLogs/VolunteerLogsRows.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { React } from 'react';
import PropTypes from 'prop-types';
import { Button, Checkbox, Badge, Text, Icon } from '@chakra-ui/react';
import { FiEdit3 } from 'react-icons/fi';

const DateFormat = ({ date }) => {
return new Date(date).toLocaleDateString();
};

const Check = ({ checked, setChecked, id }) => {
return (
<Checkbox
bg="white"
isChecked={checked.get(id)}
onChange={event => {
if (event.target.checked) {
const remainingChecks = new Map(checked);
remainingChecks.set(id, true);
setChecked(remainingChecks);
} else {
const remainingChecks = new Map(checked);
remainingChecks.set(id, false);
setChecked(remainingChecks);
}
}}
/>
);
};

const AllCheck = ({ checked, setChecked, allChecked, setAllChecked }) => {
const handleAllChecked = () => {
const newCheckedData = new Map(checked);
if (allChecked) {
newCheckedData.forEach((value, keys) => {
newCheckedData.set(keys, false);
});
} else {
newCheckedData.forEach((value, keys) => {
newCheckedData.set(keys, true);
});
}
setAllChecked(!allChecked);
setChecked(newCheckedData);
};

return <Checkbox bg="white" isChecked={allChecked} onChange={handleAllChecked} />;
};

const ApplyBadge = ({ approval }) => {
if (approval === 'UNDER_REVIEW') {
return (
<Badge variant="solid" colorScheme="blue">
UNDER REVIEW
</Badge>
);
}

if (approval === 'UNSUBMITTED') {
return (
<Badge variant="solid" colorScheme="gray">
DRAFT
</Badge>
);
}

if (approval === 'RESUBMITTED') {
return (
<Badge variant="solid" colorScheme="purple">
RESUBMITTED
</Badge>
);
}

if (approval === 'EDITS_REQUESTED') {
return (
<Badge variant="solid" colorScheme="red">
EDITS REQUESTED
</Badge>
);
}

if (approval === 'APPROVED') {
return (
<Badge variant="solid" colorScheme="green">
APPROVED
</Badge>
);
}

return <Text fontSize="xs">{approval}</Text>;
};

const Partners = ({ sessionPartners }) => {
if (sessionPartners.length === 0) {
return '';
}
const names = sessionPartners.map(
partner => `${partner.firstName.charAt(0)}. ${partner.lastName}`,
);
return <p>{names.join(', ')}</p>;
};

const EditButton = ({ logId, approval }) => {
// console.log(logId);
if (approval === 'APPROVED') {
return '';
}

return (
<Button bgColor="transparent" minW={2} h={6} px={2}>
<Icon h={{ md: 5, base: 4 }} w={{ md: 5, base: 4 }} as={FiEdit3} />
</Button>
);
};

Check.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
checked: PropTypes.object.isRequired,
setChecked: PropTypes.func.isRequired,
id: PropTypes.string.isRequired,
};

AllCheck.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
checked: PropTypes.object.isRequired,
setChecked: PropTypes.func.isRequired,
allChecked: PropTypes.bool.isRequired,
setAllChecked: PropTypes.func.isRequired,
};

ApplyBadge.propTypes = {
approval: PropTypes.string.isRequired,
};

Partners.propTypes = {
sessionPartners: PropTypes.arrayOf(Object).isRequired,
};

EditButton.propTypes = {
logId: PropTypes.string.isRequired,
approval: PropTypes.string.isRequired,
};

export { DateFormat, Check, AllCheck, ApplyBadge, Partners, EditButton };
89 changes: 89 additions & 0 deletions src/components/VolunteerLogs/VolunteerLogsStructure.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Flex } from '@chakra-ui/react';
import { ApplyBadge, DateFormat, Check, AllCheck, Partners, EditButton } from './VolunteerLogsRows';

const CellStructure = (checked, setChecked, allChecked, setAllChecked) => {
/* eslint-disable react/destructuring-assignment, react/prop-types */
const cellStructure = [
{
id: 'checkbox',
Header: (
<AllCheck
checked={checked}
setChecked={setChecked}
allChecked={allChecked}
setAllChecked={setAllChecked}
/>
),
accessor: '_id',
disableSortBy: true,
Cell: ({ value }) => <Check checked={checked} setChecked={setChecked} id={value} />,
},
{
id: 'segment',
Header: 'Segment',
accessor: 'segment.segmentId',
Cell: props => <p>{props.value}</p>,
},
{
id: 'segmentName',
Header: 'Segment Name',
accessor: 'segment.name',
Cell: props => <p>{props.value}</p>,
},
{
id: 'submittedAt',
Header: 'Date',
accessor: 'submittedAt',
Cell: ({ value }) => <DateFormat date={value} />,
},
{
id: 'status',
Header: 'Approval Status',
accessor: 'status',
minWidth: 100,
Cell: ({ value }) => <ApplyBadge approval={value} />,
},
{
id: 'partners',
Header: 'Monitor Partners',
accessor: 'sessionPartners',
disableSortBy: true,
Cell: props => (props.value ? <Partners sessionPartners={props.value} /> : ''),
},
{
id: 'edit',
Header: '',
accessor: '_id',
disableSortBy: true,
Cell: props => (
<EditButton logId={props.row.original._id} approval={props.row.original.status} />
),
},
{
// combined approval status and edit for mobile table
id: 'statusAndEdit',
Header: 'Approval Status',
accessor: 'status',
disableSortBy: true,
Cell: props => (
<Flex direction="row" justify="space-between" align="center">
<ApplyBadge approval={props.row.original.status} />
<EditButton logId={props.row.original._id} approval={props.row.original.status} />
</Flex>
),
},
];
return cellStructure;
};

CellStructure.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
checked: PropTypes.object.isRequired,
setChecked: PropTypes.func.isRequired,
allChecked: PropTypes.bool.isRequired,
setAllChecked: PropTypes.func.isRequired,
};

export default CellStructure;
Loading

0 comments on commit 9f4a73a

Please sign in to comment.