diff --git a/src/components/AdminDashboard/BusinessTable/BusinessTable.tsx b/src/components/AdminDashboard/BusinessTable/BusinessTable.tsx
index 0ffa0d3..ba1d95f 100644
--- a/src/components/AdminDashboard/BusinessTable/BusinessTable.tsx
+++ b/src/components/AdminDashboard/BusinessTable/BusinessTable.tsx
@@ -29,7 +29,7 @@ import { BiCheck, BiEnvelope, BiPlus, BiTimeFive, BiX } from 'react-icons/bi';
import { useNavigate } from 'react-router-dom';
import { useBackend } from '../../../contexts/BackendContext';
-import DownloadCSV from '../../../utils/downloadCSV';
+import downloadCSV from '../../../utils/downloadCSV';
import BusinessTableModal from './BusinessTableModal';
const TABLE_HEADERS = ['Business Name', 'Location', 'Email', 'Form Status', 'Last Submitted'];
@@ -149,8 +149,7 @@ export const BusinessTable = () => {
};
const handleSendReminders = async () => {
- for (const businessId of selectedBusinessIds) {
- // ! FIX ME
+ selectedBusinessIds.forEach(async (businessId) => {
try {
const requestData = {
businessId: businessId,
@@ -164,7 +163,8 @@ export const BusinessTable = () => {
} catch (error) {
console.error('Error sending reminders:', error);
}
- }
+ });
+
const message = `To ${selectedBusinessIds.size} ${
selectedBusinessIds.size > 1 ? `businesses` : ` business`
}.`;
@@ -184,7 +184,7 @@ export const BusinessTable = () => {
headers.push(TABLE_HEADERS[i].toLowerCase().replace(' ', '_'));
}
try {
- DownloadCSV(ids);
+ downloadCSV(ids);
const message = `For ${ids.length} ${ids.length > 1 ? `businesses` : ` business`}.`;
toast({
title: 'Downloaded CSV',
@@ -246,10 +246,7 @@ export const BusinessTable = () => {
console.log(businessResponse);
- if (
- true ||
- (currentTab === 'All' && search === '' && businessCountResponse.data[0]['count'] === 0)
- ) {
+ if (currentTab === 'All' && search === '' && businessCountResponse.data[0]['count'] === 0) {
onOpen();
}
diff --git a/src/components/BusinessTablePending/BusinessTablePending.jsx b/src/components/BusinessTablePending/BusinessTablePending.jsx
index df08898..967023d 100644
--- a/src/components/BusinessTablePending/BusinessTablePending.jsx
+++ b/src/components/BusinessTablePending/BusinessTablePending.jsx
@@ -18,7 +18,7 @@ import { FaPlus } from 'react-icons/fa6';
import { useNavigate } from 'react-router-dom';
import { useBackend } from '../../contexts/BackendContext';
-import DownloadCSV from '../../utils/downloadCSV';
+import downloadCSV from '../../utils/downloadCSV';
import { BusinessForm } from '../BusinessForm/BusinessForm.1';
import ViewBusiness from '../ViewBusiness/ViewBusiness';
@@ -120,7 +120,7 @@ const BusinessTablePending = (businessData) => {
for (var i = 0; i < TABLE_HEADERS.length; i++) {
headers.push(TABLE_HEADERS[i].toLowerCase().replace(' ', '_'));
}
- DownloadCSV(headers, ids, 'business');
+ downloadCSV(headers, ids, 'business');
};
const handleSendReminders = async () => {
diff --git a/src/components/DonationTrackingTable/DonationSite.jsx b/src/components/DonationTrackingTable/DonationSite.jsx
deleted file mode 100644
index 70883d5..0000000
--- a/src/components/DonationTrackingTable/DonationSite.jsx
+++ /dev/null
@@ -1,90 +0,0 @@
-/* eslint react/prop-types: 0 */
-import { useEffect, useState } from 'react';
-import { Checkbox, Td, Tr } from '@chakra-ui/react';
-import { useNavigate } from 'react-router-dom';
-
-import { useBackend } from '../../contexts/BackendContext';
-
-const DonationSite = ({ donation_site, checkSet, setCheck, topCheckBox }) => {
- const [individualCheckBox, setIndividualCheckBox] = useState(topCheckBox);
- const [donationSiteName, setDonationSiteName] = useState('');
- const navigate = useNavigate();
- const { backend } = useBackend();
-
- useEffect(() => {
- setIndividualCheckBox(topCheckBox);
- }, [topCheckBox]);
-
- useEffect(() => {
- const getDonationSiteName = async () => {
- try {
- const businessResponse = await backend.get(`business/${donation_site.business_id}`);
- setDonationSiteName(businessResponse.data[0].name);
- } catch (error) {
- console.log(error);
- }
- };
-
- getDonationSiteName();
- }, []);
-
- const headers = [
- donationSiteName,
- donation_site?.donation_id,
- donation_site?.food_bank_donation,
- donation_site?.reporter,
- donation_site?.email,
- donation_site?.date ? new Date(donation_site.date).toLocaleDateString() : null,
- donation_site?.canned_dog_food_quantity !== null
- ? `${donation_site.canned_dog_food_quantity} lb`
- : '0 lb',
- donation_site?.dry_dog_food_quantity !== null
- ? `${donation_site.dry_dog_food_quantity} lb`
- : '0 lb',
- donation_site?.canned_cat_food_quantity !== null
- ? `${donation_site.canned_cat_food_quantity} lb`
- : '0 lb',
- donation_site?.dry_cat_food_quantity !== null
- ? `${donation_site.dry_cat_food_quantity} lb`
- : '0 lb',
- donation_site?.misc_items,
- donation_site?.volunteer_hours !== null ? `${donation_site.volunteer_hours} hrs` : '0 hrs',
- ];
-
- const handleClick = () => {
- const newCheckedState = !individualCheckBox;
- setIndividualCheckBox(newCheckedState);
- if (checkSet.has(donation_site.donation_id)) {
- setCheck((prevState) => {
- prevState.delete(donation_site.donation_id);
- return prevState;
- });
- } else {
- setCheck((prevState) => {
- prevState.add(donation_site.donation_id);
- return prevState;
- });
- }
- };
-
- const handleRowClick = async (id) => {
- navigate(`/ViewDonation/${id}`);
- };
-
- return (
-
-
- {headers.map((header, index) => (
- handleRowClick(donation_site.donation_id)}>
- {header}
- |
- ))}
-
- );
-};
-
-export default DonationSite;
diff --git a/src/components/DonationTrackingTable/DonationSite.tsx b/src/components/DonationTrackingTable/DonationSite.tsx
new file mode 100644
index 0000000..a0348f1
--- /dev/null
+++ b/src/components/DonationTrackingTable/DonationSite.tsx
@@ -0,0 +1,92 @@
+import { useEffect, useState } from 'react';
+import { Checkbox, Td, Tr } from '@chakra-ui/react';
+import { useNavigate } from 'react-router-dom';
+
+import { useBackend } from '../../contexts/BackendContext';
+import { Donation } from '../../types/donation';
+
+interface DonationSiteProps {
+ donation: Donation;
+ checkedSet: Set;
+ allChecked: boolean;
+ setCheckedSet: (set: Set) => unknown;
+}
+
+export const DonationSite = ({
+ donation,
+ checkedSet,
+ allChecked,
+ setCheckedSet,
+}: DonationSiteProps) => {
+ const navigate = useNavigate();
+ const { backend } = useBackend();
+
+ const [isChecked, setIsChecked] = useState(allChecked || checkedSet.has(donation.business_id));
+ const [donationSiteName, setDonationSiteName] = useState('');
+
+ useEffect(() => {
+ setIsChecked(allChecked);
+ }, [allChecked]);
+
+ useEffect(() => {
+ const getDonationSiteName = async () => {
+ try {
+ const businessResponse = await backend.get(`business/${donation.business_id}`);
+ setDonationSiteName(businessResponse.data[0].name);
+ } catch (error) {
+ console.log(error);
+ }
+ };
+
+ getDonationSiteName();
+ }, []);
+
+ const cells = [
+ donationSiteName,
+ donation?.donation_id,
+ donation?.food_bank_donation,
+ donation?.reporter,
+ donation?.email,
+ donation?.date ? new Date(donation.date).toLocaleDateString() : null,
+ donation?.canned_dog_food_quantity !== null
+ ? `${donation.canned_dog_food_quantity} lb`
+ : '0 lb',
+ donation?.dry_dog_food_quantity !== null ? `${donation.dry_dog_food_quantity} lb` : '0 lb',
+ donation?.canned_cat_food_quantity !== null
+ ? `${donation.canned_cat_food_quantity} lb`
+ : '0 lb',
+ donation?.dry_cat_food_quantity !== null ? `${donation.dry_cat_food_quantity} lb` : '0 lb',
+ donation?.misc_items,
+ donation?.volunteer_hours !== null ? `${donation.volunteer_hours} hrs` : '0 hrs',
+ ];
+
+ const handleClick = () => {
+ const newCheckedState = !isChecked;
+ setIsChecked(newCheckedState);
+
+ const newSet = new Set(checkedSet);
+ checkedSet.has(donation.donation_id)
+ ? newSet.delete(donation.donation_id)
+ : newSet.add(donation.donation_id);
+
+ setCheckedSet(newSet);
+ };
+
+ const handleRowClick = async (id: number) => {
+ navigate(`/ViewDonation/${id}`);
+ };
+
+ return (
+
+
+
+ |
+
+ {cells.map((cell, index) => (
+ handleRowClick(donation.donation_id)}>
+ {cell}
+ |
+ ))}
+
+ );
+};
diff --git a/src/components/DonationTrackingTable/DonationTrackingTable.module.css b/src/components/DonationTrackingTable/DonationTrackingTable.module.css
deleted file mode 100644
index 9839770..0000000
--- a/src/components/DonationTrackingTable/DonationTrackingTable.module.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.roundedTable {
- padding: var(--chakra-space-3);
- border-width: 1px;
- border-radius: 12px;
- overflow-x: auto;
- background: var(--white, #fff);
-}
-
-.resultNavigation {
- display: flex;
- flex-direction: row;
- justify-content: right;
- align-items: center;
-}
-
-.checkBoxHeader {
- display: flex;
- flex-direction: row;
- align-items: center;
- padding: 0 10px;
- margin-top: 15px;
-}
diff --git a/src/components/DonationTrackingTable/DonationTrackingTable.tsx b/src/components/DonationTrackingTable/DonationTrackingTable.tsx
index 10ba9fb..1081c2b 100644
--- a/src/components/DonationTrackingTable/DonationTrackingTable.tsx
+++ b/src/components/DonationTrackingTable/DonationTrackingTable.tsx
@@ -1,10 +1,5 @@
-import { useEffect, useState } from 'react';
-import {
- ArrowDownIcon,
- ChevronDownIcon,
- ChevronLeftIcon,
- ChevronRightIcon,
-} from '@chakra-ui/icons';
+import { ChangeEvent, useEffect, useState } from 'react';
+import { ArrowDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
import {
Box,
Button,
@@ -12,6 +7,7 @@ import {
Flex,
Heading,
HStack,
+ Icon,
IconButton,
Input,
Tab,
@@ -26,82 +22,61 @@ import {
Tr,
useToast,
} from '@chakra-ui/react';
-
-import { useBackend } from '../../contexts/BackendContext';
-import DonationSite from './DonationSite';
-
-import './DonationTrackingTable.module.css';
-
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
+import { useBackend } from '../../contexts/BackendContext';
import { pageStyle, pageTitleStyle } from '../../styles/sharedStyles';
-import DownloadCSV from '../../utils/downloadCSV';
+import { Donation } from '../../types/donation';
+import downloadCSV from '../../utils/downloadCSV';
import NotificationsDrawer from '../NotificationsDrawer/NotificationsDrawer';
-import classes from './DonationTrackingTable.module.css';
+import { DonationSite } from './DonationSite';
+
+const TABLE_HEADERS = [
+ 'Donation Site',
+ 'Donation ID',
+ 'Food Bank',
+ 'Person Reporting',
+ 'Email',
+ 'Date',
+ 'Canned Dog Food',
+ 'Dry Dog Food',
+ 'Canned Cat Food',
+ 'Dry Cat Food',
+ 'Misc Items',
+ 'Volunteer Hours',
+];
+
+const TAB_HEADERS = ['month', 'quarter', 'year', 'all'];
export const DonationTrackingTable = () => {
- const navigate = useNavigate();
const { backend } = useBackend();
const { isAdmin } = useAuth();
const toast = useToast();
+ const navigate = useNavigate();
- const [donationTrackingTableData, setDonationTrackingTableData] = useState([]);
- const [checkedSet, setCheckedSet] = useState(new Set());
- const [topCheckBox, setTopCheckBox] = useState(false);
- const headers = [
- 'Donation Site',
- 'Donation ID',
- 'Food Bank',
- 'Person Reporting',
- 'Email',
- 'Date',
- 'Canned Dog Food',
- 'Dry Dog Food',
- 'Canned Cat Food',
- 'Dry Cat Food',
- 'Misc Items',
- 'Volunteer Hours',
- ];
+ const [donationTrackingTableData, setDonationTrackingTableData] = useState([]);
+ const [checkedSet, setCheckedSet] = useState>(new Set());
+ const [allChecked, setAllChecked] = useState(false);
- const tabHeaders = ['month', 'quarter', 'year', 'all'];
- const [currentTab, setCurrentTab] = useState('month'); //change to all once all page is implemented
+ const [currentTab, setCurrentTab] = useState('all');
const [currentPageNum, setCurrentPageNum] = useState(1);
const [currentDonationsNum, setCurrentDonationsNum] = useState(0);
const [pageLimit, setPageLimit] = useState(1);
const [searchTerm, setSearchTerm] = useState('');
- const [isAdminUser, setIsAdminUser] = useState(false);
const [notifications, setNotifications] = useState([]);
- const loadInfo = async () => {
- changePage();
- const donationNumResponse = await backend.get(
- `/donation/totalDonations/${currentTab}/?searchTerm=${searchTerm}`,
- );
- setCurrentDonationsNum(donationNumResponse.data[0]['count']);
- setPageLimit(Math.ceil(donationNumResponse.data[0]['count'] / 10));
- };
-
- const changeTab = async (tab) => {
+ const changeTab = async (tab: string) => {
setCurrentTab(tab);
setCurrentPageNum(1);
setCheckedSet(new Set());
- setTopCheckBox(false);
- };
-
- const changePage = async () => {
- const donationResponse = await backend.get(
- `/donation/filter/${currentTab}/?pageNum=${currentPageNum}&searchTerm=${searchTerm}`,
- );
- setDonationTrackingTableData(donationResponse.data);
+ setAllChecked(false);
};
useEffect(() => {
- const getData = async () => {
- try {
- loadInfo();
- } catch (error) {
- console.error('Error fetching data:', error);
+ const checkIsAdmin = async () => {
+ if (!(await isAdmin())) {
+ navigate('/BusinessDashboard');
}
};
@@ -114,70 +89,77 @@ export const DonationTrackingTable = () => {
}
};
- const checkIsAdmin = async () => {
- if (!(await isAdmin())) {
- navigate('/BusinessDashboard');
- } else {
- setIsAdminUser(true);
+ checkIsAdmin();
+
+ try {
+ getNotifications();
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ }
+ }, []);
+
+ useEffect(() => {
+ const getData = async () => {
+ try {
+ const donationResponse = await backend.get(
+ `/donation/filter/${currentTab}/?pageNum=${currentPageNum}&searchTerm=${searchTerm}`,
+ );
+ setDonationTrackingTableData(donationResponse.data);
+
+ const donationNumResponse = await backend.get(
+ `/donation/totalDonations/${currentTab}/?searchTerm=${searchTerm}`,
+ );
+ setCurrentDonationsNum(donationNumResponse.data[0]['count']);
+ setPageLimit(Math.ceil(donationNumResponse.data[0]['count'] / 10));
+ } catch (error) {
+ console.error('Error fetching data:', error);
}
};
- checkIsAdmin();
getData();
- if (notifications.length == 0) {
- getNotifications();
- }
}, [currentTab, currentPageNum, searchTerm]);
- const renderDonationTrackingTableData = () => {
- return donationTrackingTableData.map((element, index) => {
- return (
-
- );
- });
- };
-
const handleCheckBoxes = () => {
- const newCheckboxValue = !topCheckBox;
- setTopCheckBox(newCheckboxValue);
+ const newCheckboxValue = !allChecked;
+ setAllChecked(newCheckboxValue);
if (newCheckboxValue) {
const newCheckedSet = new Set(
donationTrackingTableData.map((element) => element.donation_id),
);
+
setCheckedSet(newCheckedSet);
} else {
- const newCheckedSet = new Set();
+ const newCheckedSet = new Set();
setCheckedSet(newCheckedSet);
}
};
- const handleDownloadCSV = () => {
+ const handleDownloadCSV = async () => {
const ids = Array.from(checkedSet);
+
try {
if (ids.length === 0) {
- toast({
- title: 'Downloaded CSV',
+ return toast({
+ title: 'No Businesses Selected',
description: 'Select a business first',
status: 'error',
duration: 3000,
isClosable: true,
});
- } else {
- DownloadCSV(ids, true);
- const message = `For ${ids.length} ${ids.length > 1 ? `businesses` : ` business`}.`;
+ }
+
+ const ok = await downloadCSV(ids, true, backend);
+
+ if (ok) {
toast({
title: 'Downloaded CSV',
- description: message,
+ description: `For ${ids.length} ${ids.length > 1 ? `businesses` : ` business`}.`,
status: 'success',
duration: 3000,
isClosable: true,
});
+ } else {
+ throw Error;
}
} catch (error) {
toast({
@@ -190,82 +172,88 @@ export const DonationTrackingTable = () => {
}
};
- const handleSearch = (event) => {
- setSearchTerm(event.target.value.split(' ').join('+'));
+ const handleSearch = (event: ChangeEvent) => {
+ setSearchTerm(event.currentTarget.value.split(' ').join('+'));
setCurrentPageNum(1);
};
return (
- <>
- {isAdminUser && (
-
-
- Donation Tracking
-
-
+
+
+ Donation Tracking
+
+
-
-
- {tabHeaders.map((header) => (
- changeTab(header)} key={header} sx={{ whiteSpace: 'nowrap' }}>
- This
- {header}
-
- ))}
+
+
+ {TAB_HEADERS.map((header) => (
+ changeTab(header)} key={header} sx={{ whiteSpace: 'nowrap' }}>
+ {header}
+
+ ))}
+
+
- changeTab('all')}>All
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
- {headers.map((header, index) => {
- return {header} | ;
- })}
-
-
- {renderDonationTrackingTableData()}
-
-
+
+
+
+
+
+
+ |
+ {TABLE_HEADERS.map((header, index) => {
+ return {header} | ;
+ })}
+
+
+
+ {donationTrackingTableData.map((donation) => (
+
+ ))}
+
+
+
-
-
- {currentDonationsNum > 0 ? (currentPageNum - 1) * 10 + 1 : 0} to{' '}
- {Math.min(currentPageNum * 10, currentDonationsNum)} of {currentDonationsNum}
-
- }
- onClick={() => setCurrentPageNum(currentPageNum - 1)}
- />
- = pageLimit}
- icon={}
- onClick={() => setCurrentPageNum(currentPageNum + 1)}
- />
-
-
- )}
- >
+
+
+ {currentDonationsNum > 0 ? (currentPageNum - 1) * 10 + 1 : 0} to{' '}
+ {Math.min(currentPageNum * 10, currentDonationsNum)} of {currentDonationsNum}
+
+
+ }
+ onClick={() => setCurrentPageNum(currentPageNum - 1)}
+ />
+ = pageLimit}
+ icon={}
+ onClick={() => setCurrentPageNum(currentPageNum + 1)}
+ />
+
+
);
};
diff --git a/src/components/NotificationsDrawer/NotificationsDrawer.jsx b/src/components/NotificationsDrawer/NotificationsDrawer.jsx
index 7a4c063..ad6e078 100644
--- a/src/components/NotificationsDrawer/NotificationsDrawer.jsx
+++ b/src/components/NotificationsDrawer/NotificationsDrawer.jsx
@@ -26,7 +26,7 @@ import {
import PropTypes from 'prop-types';
import { useNavigate } from 'react-router-dom';
-import DownloadCSV from '../../utils/downloadCSV';
+import downloadCSV from '../../utils/downloadCSV';
import 'boxicons';
@@ -60,7 +60,7 @@ const NotificationsDrawer = ({ notificationsData }) => {
};
const handleDownloadCSV = (ids) => {
- DownloadCSV(ids);
+ downloadCSV(ids);
};
const handleSendReminder = async (businessId, businessName) => {
diff --git a/src/components/ViewDonation/ViewDonation.jsx b/src/components/ViewDonation/ViewDonation.jsx
index 4a0f555..67c66fe 100644
--- a/src/components/ViewDonation/ViewDonation.jsx
+++ b/src/components/ViewDonation/ViewDonation.jsx
@@ -19,7 +19,7 @@ import PropTypes from 'prop-types';
import { useNavigate, useParams } from 'react-router-dom';
import { useBackend } from '../../contexts/BackendContext';
-import DownloadCSV from '../../utils/downloadCSV';
+import downloadCSV from '../../utils/downloadCSV';
import NotificationsDrawer from '../NotificationsDrawer/NotificationsDrawer';
import classes from './ViewDonation.module.css';
@@ -34,7 +34,7 @@ const ViewDonation = () => {
const handleDownloadCSV = () => {
try {
- DownloadCSV([id], true);
+ downloadCSV([id], true);
toast({
title: 'Downloaded CSV',
description: `for ${businessName}`,
diff --git a/src/utils/downloadCSV.js b/src/utils/downloadCSV.js
index 42525e3..bf7b087 100644
--- a/src/utils/downloadCSV.js
+++ b/src/utils/downloadCSV.js
@@ -1,6 +1,6 @@
-// DownloadCSV.js
+// downloadCSV.js
-async function DownloadCSV(ids, isDonation = false) {
+async function downloadCSV(ids, isDonation = false, backend) {
const headers = {
'Business Name': 'name',
'Business Phone': 'primary_phone',
@@ -15,26 +15,21 @@ async function DownloadCSV(ids, isDonation = false) {
'Miscellaneous Items': 'miscellaneous_items',
'Volunteer Hours': 'volunteer_hours',
};
+
try {
let response;
if (isDonation) {
- response = await fetch(
- `http://localhost:3001/donation/selectByIdsDonation?ids=${ids.join(',')}`,
- {
- method: 'GET',
- },
- );
+ response = await backend.get(`/donation/donation_tracking/selectByIds?ids=${ids.join(',')}`);
+ console.log('RESPONSE:', response);
} else {
- response = await fetch(`http://localhost:3001/donation/selectByIds?ids=${ids.join(',')}`, {
- method: 'GET',
- });
+ response = await backend.get(`/donation/selectByIds?ids=${ids.join(',')}`);
}
- if (!response.ok) {
+ if (!response.statusText === 'OK') {
throw new Error('Failed to fetch data from the server');
}
- const data = await response.json();
+ const data = await response.data;
// Create CSV string
const csvRows = [];
@@ -62,9 +57,11 @@ async function DownloadCSV(ids, isDonation = false) {
document.body.appendChild(link); // Required for Firefox
link.click();
document.body.removeChild(link); // Clean up
+
+ return true; // TODO: fix me )= (error handling etc)
} catch (error) {
- console.error('Error downloading CSV:', error);
+ console.error(error);
}
}
-export default DownloadCSV;
+export default downloadCSV;