Skip to content

Commit

Permalink
donations
Browse files Browse the repository at this point in the history
  • Loading branch information
karenl03 committed Apr 6, 2024
1 parent 696d5f2 commit 46251df
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 40 deletions.
2 changes: 1 addition & 1 deletion client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function App() {
path="/invite/:token"
element={<InviteRegisterPage />}
/>
<Route path="/donor-profile" element={<DonorProfilePage />} />
<Route path="/donor-profile" element={<DonorProfilePage donorID='65daa67d6c34e8adb9f2d2c4' />} />
<Route path="/home" element={<HomeDashboardPage />} />
{/* Routes accessed only if user is authenticated */}
<Route element={<ProtectedRoutesWrapper />}>
Expand Down
20 changes: 20 additions & 0 deletions client/src/HomeDashboard/HomeDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useAppDispatch } from '../util/redux/hooks';
import DonationsSponsorshipsTable from '../components/tables/DonationsSponsorshipsTable';
import GrantTable from '../components/tables/GrantTable';

interface BasicTableProps {
alignment: string;
Expand Down Expand Up @@ -148,6 +150,24 @@ function HomeDashboard() {
{alignment.charAt(0).toUpperCase() + alignment.slice(1)}s
</Typography>
</Box>

<Box
display="flex"
flexDirection="row"
alignItems="center"
marginBottom={2}
marginLeft={2}
sx={{
width: '100%',
justifyContent: 'flex-start',
}}
>
{alignment === 'donation' || alignment === 'sponsorship' ? (
<DonationsSponsorshipsTable />
) : (
<GrantTable />
)}
</Box>
</Box>
);
}
Expand Down
31 changes: 31 additions & 0 deletions client/src/components/tables/CommunicationsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import FilteringTable from './FilteringTable';

function CommunicationsTable() {
// Define the columns
// <Date>, <# of Recipients>, <Recipient List>, <Added Groups>
const columns = [
{ id: 'date_created', label: 'Date' },
{ id: 'donor_ids', label: '# of Recipients' },
{ id: 'donor_ids', label: 'Recipient List' },
{ id: 'group_name', label: 'Added Groups' },
// Add more columns as needed
];

// Generate the rows
const rows = [];
const startDate = new Date('2023-01-01');
const endDate = new Date('2024-12-31');
for (let d = startDate; d <= endDate; d.setDate(d.getDate() + 1)) {
rows.push({
id: rows.length + 1,
name: `Name ${rows.length + 1}`,
date: d.toISOString().split('T')[0], // Format the date as 'yyyy-mm-dd'
// Add more data as needed
});
}

return <FilteringTable columns={columns} rows={rows} />;
}

export default CommunicationsTable;
43 changes: 43 additions & 0 deletions client/src/components/tables/DonationsSponsorshipsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { useState, useEffect } from 'react';
import FilteringTable from './FilteringTable';

function DonationsSponsorshipsTable() {
const [rows, setRows] = useState([]); // State to store the fetched rows

useEffect(() => {
const fetchData = async () => {
try {
// Fetch data from the backend route using the native fetch API
const response = await fetch('/all'); // Assuming your backend route is /api/donors/type/sponsor
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const data = await response.json();
setRows(data); // Update the state with the fetched data
} catch (error) {
console.error('Error fetching data:', error);
}
};

fetchData(); // Call the fetchData function when the component mounts

// Clean up function to cancel any ongoing requests
return () => {
// You can cancel any ongoing requests here if needed
};
}, []); // Empty dependency array ensures that this effect runs only once

// Define the columns
const columns = [
{ id: 'date', label: 'Date' },
{ id: 'amount', label: 'Amount' },
{ id: 'donor_id', label: 'Donor' },
{ id: 'payment_type', label: 'Payment Type' },
{ id: 'purpose_id', label: 'Purpose' },
// Add more columns as needed
];

return <FilteringTable columns={columns} rows={rows} />;
}

export default DonationsSponsorshipsTable;
32 changes: 32 additions & 0 deletions client/src/components/tables/DonorsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import FilteringTable from './FilteringTable';

function DonorsTable() {
// Define the columns
// <Name>, <Donor Group>, <Recent Donation>, <Last Communication>
const columns = [
{ id: 'contact_name', label: 'Name' },
{ id: 'donor_group', label: 'Donor Group' },
{ id: 'last_donation_date', label: 'Recent Donation' },
{ id: 'last_communication_date', label: 'Last Communication' },
// Add more columns as needed
];

// Generate the rows
const rows = [];
const startDate = new Date('2023-01-01');
const endDate = new Date('2024-12-31');
for (let d = startDate; d <= endDate; d.setDate(d.getDate() + 1)) {
rows.push({
id: rows.length + 1,
name: `Name ${rows.length + 1}`,
date: d.toISOString().split('T')[0], // Format the date as 'yyyy-mm-dd'
// Add more data as needed
});

}

return <FilteringTable columns={columns} rows={rows} />;
}

export default DonorsTable;
188 changes: 188 additions & 0 deletions client/src/components/tables/FilteringTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import React, { useState } from 'react';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableFooter,
TableRow,
TablePagination,
TextField,
Select,
MenuItem,
Button,
IconButton,
Input,
SelectChangeEvent,
Link,
} from '@mui/material';
import FilterAltIcon from '@mui/icons-material/FilterAlt';
import { getData, useData } from '../../util/api';

interface Column {
id: string;
label: string;
}

interface Row {
[key: string]: number | string;
id: number;
name: string;
date: string;
}

interface FilteringTableProps {
columns: Column[];
rows: Row[];
}

function FilteringTable({
columns: initialColumns,
rows: initialRows,
}: FilteringTableProps) {
const [rows, setRows] = useState<Row[]>(initialRows);
const [columns, setColumns] = useState<Column[]>(initialColumns);
const [filterType, setFilterType] = useState('calendar');
const [filterYear, setFilterYear] = useState(new Date().getFullYear());
const [filterVisible, setFilterVisible] = useState(false);
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [searchTerm, setSearchTerm] = useState('');

const donations = useData('donation/all');
console.log(donations);

const handleFilterTypeChange = (event: SelectChangeEvent<string>) => {
setFilterType(event.target.value);
};

const handleFilterYearChange = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
setFilterYear(parseInt(event.target.value, 10));
};

const toggleFilterVisible = () => {
setFilterVisible(!filterVisible);
};

const handleChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value.toLowerCase());
setPage(0); // Reset to the first page when the search term changes
};

// Apply the search filter first
const searchedRows = rows.filter((row) => {
// Convert all row values to string and lowercase, then check if they include the search term
return Object.values(row).some((value) =>
value.toString().toLowerCase().includes(searchTerm),
);
});

// Then apply the year filter
const filteredRows = searchedRows.filter((row) => {
const date = new Date(row.date as string);
const year = date.getFullYear();
const month = date.getMonth();

if (filterType === 'calendar') {
return year === filterYear;
}
// fiscal year
return (
(month >= 6 && year === filterYear) ||
(month < 6 && year - 1 === filterYear)
);
});

return (
<>
{/* {filterVisible && (
<>
<Select value={filterType} onChange={handleFilterTypeChange}>
<MenuItem value="calendar">Calendar Year</MenuItem>
<MenuItem value="fiscal">Fiscal Year</MenuItem>
</Select>
<TextField
label="Year"
value={filterYear}
onChange={handleFilterYearChange}
/>
</>
)} */}

<TableContainer
style={{
borderRadius: '16px',
overflow: 'hidden',
boxShadow: '0px 0px 10px rgba(0,0,0,0.1)',
maxWidth: '80%',
margin: 'auto',
padding: '20px',
}}
>
<TextField
label="Search"
variant="outlined"
onChange={handleSearchChange}
style={{ margin: '10px', width: `calc(100% / 4` }}
/>
<IconButton onClick={toggleFilterVisible} style={{ margin: '20px' }}>
<FilterAltIcon />
</IconButton>
<Table>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
style={{ width: `calc(100% / ${columns.length})` }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{filteredRows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => (
<TableRow key={row.id}>
{columns.map((column) => (
<TableCell key={column.id}>{row[column.id]}</TableCell>
))}
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={filteredRows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</>
);
}

export default FilteringTable;
33 changes: 33 additions & 0 deletions client/src/components/tables/GrantTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import FilteringTable from './FilteringTable';

function GrantTable() {
// Define the columns
// <Date>, <Amount>, <Donor>, <Payment Type>, <Purpose>, <Year>
const columns = [
{ id: 'date', label: 'Date' },
{ id: 'amount', label: 'Amount' },
{ id: 'donor_id', label: 'Donor' },
{ id: 'payment_type', label: 'Payment Type' },
{ id: 'purpose_id', label: 'Purpose' },
{ id: 'date', label: 'Year' },
// Add more columns as needed
];

// Generate the rows
const rows = [];
const startDate = new Date('2023-01-01');
const endDate = new Date('2024-12-31');
for (let d = startDate; d <= endDate; d.setDate(d.getDate() + 1)) {
rows.push({
id: rows.length + 1,
name: `Name ${rows.length + 1}`,
date: d.toISOString().split('T')[0], // Format the date as 'yyyy-mm-dd'
// Add more data as needed
});
}

return <FilteringTable columns={columns} rows={rows} />;
}

export default GrantTable;
Loading

0 comments on commit 46251df

Please sign in to comment.