Skip to content

Commit

Permalink
Merge pull request #157 from software-students-fall2021/michelle-cats…
Browse files Browse the repository at this point in the history
…-del

delete user-created categories
  • Loading branch information
tangym27 authored Dec 5, 2021
2 parents a8caf80 + 49c2fd1 commit e27e07e
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 16 deletions.
16 changes: 13 additions & 3 deletions back-end/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const setTransactionNotesInDatabase = require("./functions/setTransactionNotesIn
const setTransactionCategoryInDatabase = require("./functions/setTransactionCategoryInDatabase");
const postCategory = require("./functions/postCategory");
const editCategory = require("./functions/editCategory");
const deleteCategory = require("./functions/deleteCategory");

const PLAID_CLIENT_ID = process.env.PLAID_CLIENT_ID;
const PLAID_SECRET = process.env.PLAID_SECRET;
Expand Down Expand Up @@ -183,11 +184,8 @@ app.post("/api/register", async (req, res) => {
// function to get categories from Plaid
app.get("/api/categories", async (req, resp) => {
try {
// resp.json({});
const userId = req.query._id;
const categories = await getCategories(userId);
// resp.json({});

categories.categories.sort((a, b) => a.name.localeCompare(b.name));
resp.json(categories.categories);
} catch (error) {
Expand Down Expand Up @@ -223,6 +221,18 @@ app.post("/api/changeCategories", async (req, resp) => {
resp.json(result);
});

app.post("/api/deleteCategories", async (req, resp) => {
const userId = req.body.id;
const result = await deleteCategory(
{
name: req.body.name,
icon: req.body.icon,
},
userId
);
resp.json(result);
});

// Create a link token with configs which we can then use to initialize Plaid Link client-side.
// See https://plaid.com/docs/#create-link-token
app.post("/api/create_link_token", async (request, response) => {
Expand Down
29 changes: 29 additions & 0 deletions back-end/functions/deleteCategory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const AccessTokenModel = require("../model/accessToken");
const UserModel = require("../model/user");

// Mongoose quickstart: https://mongoosejs.com/docs/index.html
const deleteCategory = async (category, userId) => {
const found = await UserModel.exists({
_id: userId,
"categories.name": category.name,
"categories.icon": category.icon,
});
UserModel.updateOne(
{
_id: userId,
"categories.name": category.name,
"categories.icon": category.icon,
},
{ $pull: { categories: { name: category.name } } },
function (err) {
if (err) {
console.log(err);
} else {
console.log("Successfully deleted category name", category.name);
}
}
);
return found;
};

module.exports = deleteCategory;
49 changes: 47 additions & 2 deletions back-end/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ describe("testing routes", () => {
chai
.request(app)
.post("/api/categories")
.send({ category: "testing", _id: 0 })
.send({ category: "testing", id: undefined })
.end(function (err, res) {
expect(res).to.have.status(200);
cb();
Expand All @@ -322,7 +322,7 @@ describe("testing routes", () => {
.request(app)
.post("/api/changeCategories")
.send({
_id: 0,
id: undefined,
name: "tName",
icon: "tIcon",
oldName: "oName",
Expand All @@ -333,7 +333,52 @@ describe("testing routes", () => {
cb();
});
});
it("returns successful check for found category", function (cb) {
chai
.request(app)
.post("/api/deleteCategories")
.send({
id: undefined,
name: "tName",
icon: "tIcon",
})
.end(function (err, res) {
expect(res);
cb();
});
});
});
describe("testing post route /api/deleteCategories", () => {
it("returns a 200 status with valid category info", function (cb) {
chai
.request(app)
.post("/api/deleteCategories")
.send({
id: undefined,
name: "tName",
icon: "tIcon",
})
.end(function (err, res) {
expect(res).to.have.status(200);
cb();
});
});
it("returns no duplicate category found", function (cb) {
chai
.request(app)
.post("/api/deleteCategories")
.send({
id: undefined,
name: "tName",
icon: "tIcon",
})
.end(function (err, res) {
expect(res);
cb();
});
});
});

describe("testing post route /api/create_link_token", () => {
it("returns a 200 status", function (cb) {
chai
Expand Down
17 changes: 17 additions & 0 deletions front-end/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ async function editCategory(name, icon, oldName, oldIcon) {
}
}

async function deleteCategory(name, icon) {
try {
const id = sessionStorage.getItem("user")
? JSON.parse(sessionStorage.getItem("user"))._id
: null;
const result = await axios.post("/api/deleteCategories", {
id,
name,
icon,
});
return result.data;
} catch (err) {
console.error(err);
}
}

async function setTransactionCategory(id, newCategory) {
try {
await axios.post("/api/setTransactionCategory", {
Expand Down Expand Up @@ -152,6 +168,7 @@ async function getAccountInfo() {
const api = {
postNewCategory,
editCategory,
deleteCategory,
getCategoryList,
getAllTransactions,
getRecentTransactions,
Expand Down
36 changes: 26 additions & 10 deletions front-end/src/pages/Categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ const CategoryOverlay = ({ category, closeOverlay }) => {
return null;
}

const defaultCategories = [
"Bank Fees",
"Community",
"Food and Drink",
"Healthcare",
"Payment",
"Recreation",
"Service",
"Shops",
"Tax",
"Transfer",
"Travel",
];

const Icon = iconNameToComponent[category.icon];
// const [name, setName] = useState(category?.name);
return (
Expand All @@ -51,16 +65,18 @@ const CategoryOverlay = ({ category, closeOverlay }) => {
<h2>Category: {category.name}</h2>
<Icon className="category-icon" />
<br />
<Button
type="submit"
variant="contained"
onClick={handleSubmit}
component={Link}
to="/homepage"
>
{" "}
Edit{" "}
</Button>
{!defaultCategories.includes(category.name) ? (
<Button
type="submit"
variant="contained"
onClick={handleSubmit}
component={Link}
to="/homepage"
>
{" "}
Edit{" "}
</Button>
) : null}
<h4>Transactions</h4>
<div className="overlay-transactions-wrapper">
<div className={cx("overlay-transactions")}>
Expand Down
43 changes: 42 additions & 1 deletion front-end/src/pages/EditCategory.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const EditCategory = (props) => {
const [name, setName] = React.useState(oldName);

const [exists, setExists] = React.useState(true);
const [emptyTransactions, setEmptyTransactions] = React.useState(true);

const history = useHistory();

const onSubmit = React.useCallback(
Expand All @@ -65,10 +67,29 @@ const EditCategory = (props) => {
setName(e.target.value);
};

const handleDelete = React.useCallback(
async (e) => {
e.preventDefault();
if (transactions === undefined) {
setExists(false);
} else {
setExists(true);
if (transactions.length === 0) {
setEmptyTransactions(true);
const result = await api.deleteCategory(oldName, oldIcon);
history.push("/categories");
} else {
setEmptyTransactions(false);
}
}
},
[history, oldName, oldIcon, transactions?.length]
);

return (
<div>
<h1>Edit Category</h1>
{!exists ? <h2> Category does not exist!</h2> : null}
{!exists ? <h2 id="warning"> Category does not exist!</h2> : null}
<form onSubmit={onSubmit} className="container">
<label htmlFor="name" className={styles.marginBottom}>
<b>Category Name:</b>
Expand All @@ -87,6 +108,26 @@ const EditCategory = (props) => {
Update
</button>
</form>
<br /> <br />
<div className="container">
<b>Note: You can only delete empty categories.</b>

<hr />
{!emptyTransactions ? (
<p id="warning">
<b>
There are still transactions in this category. Please reassign
them first!
</b>
</p>
) : null}

<br />
<button className={styles.muiButton} onClick={handleDelete} id="del">
Delete
</button>
</div>
<br /> <br />
</div>
);
};
Expand Down
8 changes: 8 additions & 0 deletions front-end/src/pages/css/IconGrid.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@
.selected-icon {
border: solid black 4px;
}

#del {
background-color: red;
}

#warning {
color: red;
}

0 comments on commit e27e07e

Please sign in to comment.