Skip to content

Commit

Permalink
Projects now displayed in a table + removed balance chart labels + fi…
Browse files Browse the repository at this point in the history
…x tablePagination bug
  • Loading branch information
fmata97 committed Feb 12, 2024
1 parent 5e81ca8 commit 66c876a
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 146 deletions.
8 changes: 6 additions & 2 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,15 @@ tfoot.MuiTableFooter-root td.MuiTableCell-root {
border-color: var(--separator-color);
}

/* Table footer icons */
tfoot.MuiTableFooter-root svg {
/* Table pagination icons */
.MuiTablePagination-root svg {
color: white;
}

.MuiTablePagination-root button.Mui-disabled svg {
opacity: 0.3;
}

/* Scrollbar */

/* width */
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/components/BalanceTimeSeries.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,9 @@ function BalanceTimeSeries({ transactions, loading, disableRange, inDashboard, o
x: dates,
y: balanceVal,
type: "scatter",
mode: "lines+markers+text",
mode: "lines+markers",
line: { color: "6bba75", width: 1.5 },
marker: { color: "white", size: 6 },
text: balanceVal,
textposition: "top center",
hoverinfo: "x+y",
},
]}
Expand Down
63 changes: 0 additions & 63 deletions frontend/src/components/ProjList.jsx

This file was deleted.

4 changes: 3 additions & 1 deletion frontend/src/components/ProjectsEditModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ function ProjectEditModal({ open, setOpen, project, refetch }) {
>
<div className="form-header">
<CloseIcon className="modal-close-btn" onClick={handleClose} />
<h1>Edit Project {project.name}</h1>
<h1>
Edit {project.symbolic ? "Symbolic " : ""}Project {project.name}
</h1>
</div>

<div className="form-body">
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/ProjectsFilterBtn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,12 @@ function ProjectsFilterBtn({ params, setParams, refetch }) {

<hr />
<div className="form-row last">
<button className="btn" id="projects-filter-clear-btn" onClick={clearFilters}>
<button
type="button"
className="btn"
id="projects-filter-clear-btn"
onClick={clearFilters}
>
Clear
</button>
<button type="submit" className="btn" id="projects-filter-save-btn">
Expand Down
186 changes: 186 additions & 0 deletions frontend/src/components/ProjectsTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import React, { useEffect, useState } from "react";
import MoreOptionsBtn from "./MoreOptionsBtn";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableHead from "@mui/material/TableHead";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableFooter from "@mui/material/TableFooter";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import IconButton from "@mui/material/IconButton";
import FirstPageIcon from "@mui/icons-material/FirstPage";
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import LastPageIcon from "@mui/icons-material/LastPage";
import CircularProgress from "@mui/material/CircularProgress";
import EditIcon from "@mui/icons-material/Edit";
import DeleteIcon from "@mui/icons-material/Delete";

function TablePaginationActions(props) {
const { count, page, rowsPerPage, onPageChange } = props;

const handleFirstPageButtonClick = event => {
onPageChange(event, 0);
};

const handleBackButtonClick = event => {
onPageChange(event, page - 1);
};

const handleNextButtonClick = event => {
onPageChange(event, page + 1);
};

const handleLastPageButtonClick = event => {
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};

return (
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
<IconButton
onClick={handleFirstPageButtonClick}
disabled={page === 0}
aria-label="first page"
>
<FirstPageIcon />
</IconButton>
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
<KeyboardArrowLeft />
</IconButton>
<IconButton
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
<KeyboardArrowRight />
</IconButton>
<IconButton
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
<LastPageIcon />
</IconButton>
</Box>
);
}

export default function ProjectsTable({ data, openEditModal, openDeleteModal, loading }) {
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(15);

// Avoid a layout jump when reaching the last page with empty rows.
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - data.length) : 0;

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

const handleChangeRowsPerPage = event => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

// Reset the page index when the data changes
useEffect(() => {
setPage(0);
}, [data]);

return (
<TableContainer className="projects-table">
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center" padding="none">
Name
</TableCell>
<TableCell align="center">Transactions</TableCell>
<TableCell align="center">Balance</TableCell>
<TableCell align="center">Active</TableCell>
<TableCell align="center" padding="none" width={24}></TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.length === 0 &&
!loading && ( // display message when there's no data to display
<TableRow>
<TableCell colSpan={5} align="center" sx={{ fontSize: 18 }}>
No projects found
</TableCell>
</TableRow>
)}

{loading && (
<TableRow>
<TableCell colSpan={5} align="center" sx={{ border: 0 }}>
<CircularProgress className="loading-circle large" sx={{ m: 5 }} />
</TableCell>
</TableRow>
)}

{!loading &&
(rowsPerPage > 0
? data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: data
).map(row => (
<TableRow key={row.name} hover>
<TableCell component="th" scope="row" align="center">
<span className={row.symbolic ? "symbolic-indicator" : ""}>{row.name}</span>
</TableCell>
<TableCell align="center">{row.transaction_count}</TableCell>
<TableCell align="center">{`${row.balance.toFixed(2)}€`}</TableCell>
<TableCell align="center">{`${row.active ? "Yes" : "No"}`}</TableCell>
<TableCell align="center">
<MoreOptionsBtn
options={[
{
icon: <EditIcon />,
name: "Edit",
callback: () => openEditModal(row),
},
{
icon: <DeleteIcon />,
name: "Delete",
callback: () => openDeleteModal(row),
},
]}
/>
</TableCell>
</TableRow>
))}
{emptyRows > 0 && (
<TableRow style={{ height: 62.18 * emptyRows }}>
<TableCell colSpan={5} />
</TableRow>
)}
</TableBody>
{!loading && (
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[15, 20, 25, { label: "All", value: -1 }]}
colSpan={5}
count={data.length}
rowsPerPage={rowsPerPage}
// If the data has been filtered and the current page doesn't exist anymore, pass 0
// to the TablePagination component while the page hasn't been reset to 0 by the useEffect hook
page={page < Math.ceil(data.length / rowsPerPage) ? page : 0}
SelectProps={{
inputProps: {
"aria-label": "rows per page",
},
native: false,
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
/>
</TableRow>
</TableFooter>
)}
</Table>
</TableContainer>
);
}
6 changes: 5 additions & 1 deletion frontend/src/components/TransactionsFilterBtn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,11 @@ function TransactionsFilterBtn({ params, setParams, refetch, projectsList }) {

<hr />
<div className="form-row last">
<button className="btn transactions-filter-clear-btn" onClick={clearFilters}>
<button
type="button"
className="btn transactions-filter-clear-btn"
onClick={clearFilters}
>
Clear
</button>
<button type="submit" className="btn" id="transactions-filter-save-btn">
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/TransactionsReportBtn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,11 @@ function TransactionsReportBtn({ params, projectsList, sortOptions }) {

<hr />
<div className="form-row last">
<button className="btn transactions-filter-clear-btn" onClick={clearFilters}>
<button
type="button"
className="btn transactions-filter-clear-btn"
onClick={clearFilters}
>
Clear filters
</button>
<button
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/components/TransactionsTable.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import axios_instance from "../Axios";
import { showErrorMsg } from "../Alerts";
import MoreOptionsBtn from "./MoreOptionsBtn";
Expand Down Expand Up @@ -149,6 +149,11 @@ export default function TransactionsTable({ data, openEditModal, openDeleteModal
return newStr;
}

// Reset the page index when the data changes
useEffect(() => {
setPage(0);
}, [data]);

return (
<TableContainer>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
Expand All @@ -169,7 +174,7 @@ export default function TransactionsTable({ data, openEditModal, openDeleteModal
<TableCell align="center" padding="none">
Receipt
</TableCell>
<TableCell align="center" padding="none"></TableCell>
<TableCell align="center" padding="none" width={24}></TableCell>
</TableRow>
</TableHead>
<TableBody>
Expand Down Expand Up @@ -243,7 +248,9 @@ export default function TransactionsTable({ data, openEditModal, openDeleteModal
colSpan={8}
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
// If the data has been filtered and the current page doesn't exist anymore, pass 0
// to the TablePagination component while the page hasn't been reset to 0 by the useEffect hook
page={page < Math.ceil(data.length / rowsPerPage) ? page : 0}
SelectProps={{
inputProps: {
"aria-label": "rows per page",
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,21 +247,21 @@ function DashboardPage() {
bolderMain
/>
<DashboardCard
headingText={activeProjectsCount ?? "?"}
headingText={`${activeProjectsCount ?? "?"}`}
mainText="Active"
subText="Projects"
icon={<HandymanIcon />}
/>
</div>
<div className="dashboard-card-row">
<DashboardCard
headingText={transactionsLastMonth?.length ?? "?"}
headingText={`${transactionsLastMonth?.length ?? "?"}`}
mainText="Transactions"
subText="in the past 30 days"
smallerMain
/>
<DashboardCard
headingText={authorizedUsersCount ?? "?"}
headingText={`${authorizedUsersCount ?? "?"}`}
mainText={authorizedUsersCount === 1 ? "Person" : "People"}
subText="in the system"
icon={<ManageAccountsIcon />}
Expand Down
Loading

0 comments on commit 66c876a

Please sign in to comment.