Skip to content

Commit

Permalink
Merge branch 'release-1.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
entrotech committed May 22, 2020
2 parents b57dc2b + 2357aa9 commit c441796
Show file tree
Hide file tree
Showing 17 changed files with 319 additions and 27 deletions.
31 changes: 26 additions & 5 deletions app/controllers/stakeholder-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ const stakeholderService = require("../services/stakeholder-service");

const search = (req, res) => {
let categoryIds = req.query.categoryIds;
// if (!categoryIds) {
// categoryIds = ["1", "2", "3", "4", "5", "6"];
// } else if (typeof categoryIds == "string") {
// categoryIds = [categoryIds];
// }
if (!categoryIds) {
// If no filter, just use active categories.
categoryIds = ["1", "3", "8", "9", "10", "11"];
} else if (typeof categoryIds == "string") {
categoryIds = [categoryIds];
}
const params = { ...req.query, categoryIds };
stakeholderService
.search(params)
Expand All @@ -18,6 +19,25 @@ const search = (req, res) => {
});
};

const searchDashboard = (req, res) => {
let categoryIds = req.query.categoryIds;
if (!categoryIds) {
// If no filter, just use active categories.
categoryIds = ["1", "3", "8", "9", "10", "11"];
} else if (typeof categoryIds == "string") {
categoryIds = [categoryIds];
}
const params = { ...req.query, categoryIds };
stakeholderService
.searchDashboard(params)
.then((resp) => {
res.send(resp);
})
.catch((err) => {
res.status("404").json({ error: err.toString() });
});
};

const getById = (req, res) => {
const { id } = req.params;
stakeholderService
Expand Down Expand Up @@ -99,6 +119,7 @@ const claim = (req, res) => {

module.exports = {
search,
searchDashboard,
getById,
post,
put,
Expand Down
1 change: 1 addition & 0 deletions app/routes/stakeholder-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const router = require("express").Router();
const stakeholderController = require("../controllers/stakeholder-controller");

router.get("/", stakeholderController.search);
router.get("/dashboard", stakeholderController.searchDashboard);
router.get("/:id", stakeholderController.getById);
router.post("/", stakeholderController.post);
router.put("/:id", stakeholderController.put);
Expand Down
19 changes: 14 additions & 5 deletions app/services/account-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const SALT_ROUNDS = 10;
const selectAll = () => {
let sql = `
select w.id, w.first_name, w.last_name, w.email, w.date_created,
w.email_confirmed, w.is_admin, w.is_security_admin, w.is_data_entry
w.email_confirmed, w.is_admin, w.is_coordinator, w.is_security_admin, w.is_data_entry
from login w
order by w.last_name, w.first_name, w.date_created
`;
Expand All @@ -27,6 +27,7 @@ const selectAll = () => {
dateCreated: row.date_created,
emailConfirmed: row.email_confirmed,
isAdmin: row.is_admin,
isCoordinator: row.is_coordinator,
isSecurityAdmin: row.is_security_admin,
isDataEntry: row.is_data_entry,
}));
Expand All @@ -35,7 +36,7 @@ const selectAll = () => {

const selectById = (id) => {
const sql = `select w.id, w.first_name, w.last_name, w.email,
w.date_created, w.email_confirmed, w.is_admin, w.is_security_admin, w.is_data_entry
w.date_created, w.email_confirmed, w.is_admin, w.is_coordinator, w.is_security_admin, w.is_data_entry
from login w where w.id = ${id}`;
return pool.query(sql).then((res) => {
const row = res.rows[0];
Expand All @@ -47,6 +48,7 @@ const selectById = (id) => {
dateCreated: row.date_created,
emailConfirmed: row.email_confirmed,
isAdmin: row.is_admin,
isCoordinator: row.is_coordinator,
isSecurityAdmin: row.is_security_admin,
isDataEntry: row.is_data_entry,
};
Expand All @@ -55,7 +57,7 @@ const selectById = (id) => {

const selectByEmail = (email) => {
const sql = `select id, first_name, last_name, email, password_hash,
email_confirmed, date_created, is_admin, is_security_admin, is_data_entry
email_confirmed, date_created, is_admin, is_coordinator, is_security_admin, is_data_entry
from login where email ilike '${email}'`;
return pool.query(sql).then((res) => {
const row = res.rows[0];
Expand All @@ -69,6 +71,7 @@ const selectByEmail = (email) => {
dateCreated: row.date_created,
emailConfirmed: row.email_confirmed,
isAdmin: row.is_admin,
isCoordinator: row.is_coordinator,
isSecurityAdmin: row.is_security_admin,
isDataEntry: row.is_data_entry,
};
Expand Down Expand Up @@ -319,6 +322,7 @@ const authenticate = async (email, password) => {
lastName: user.lastName,
email: user.email,
isAdmin: user.isAdmin,
isCoordinator: user.isCoordinator,
isSecurityAdmin: user.isSecurityAdmin,
isDataEntry: user.isDataEntry,
emailConfirmed: user.emailConfirmed,
Expand Down Expand Up @@ -369,8 +373,13 @@ const setPermissions = async (userId, permissionName, value) => {
};
}
// Don't expose any columns besides the currently allowed ones:
// is_admin, is_security_admin, is_data_entry
var allowedPermissions = ["is_admin", "is_security_admin", "is_data_entry"];
// is_admin, is_coordinator, is_security_admin, is_data_entry
var allowedPermissions = [
"is_admin",
"is_coordinator",
"is_security_admin",
"is_data_entry",
];
if (!allowedPermissions.includes(permissionName)) {
return {
success: false,
Expand Down
168 changes: 168 additions & 0 deletions app/services/stakeholder-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,173 @@ const search = async ({
return stakeholders;
};

const searchDashboard = async ({
name,
categoryIds,
isInactive,
isAssigned,
isSubmitted,
isApproved,
isRejected,
isClaimed,
assignedLoginId,
claimedLoginId,
verificationStatusId,
latitude,
longitude,
distance,
}) => {
const categoryClause = categoryIds
? `(select sc.stakeholder_id
from stakeholder_category sc
where sc.category_id in (${categoryIds.join(",")}))`
: "";
const nameClause = "'%" + name.replace(/'/g, "''") + "%'";
const sql = `
select s.id, s.name, s.address_1, s.address_2, s.city, s.state, s.zip,
s.phone, s.latitude, s.longitude, s.website,
(select array(select row_to_json(category_row)
from (
select c.id, c.name
from category c
join stakeholder_category sc on c.id = sc.category_id
where sc.stakeholder_id = s.id
) category_row
)) as categories,
to_char(s.created_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as created_date, s.created_login_id,
to_char(s.modified_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as modified_date, s.modified_login_id,
to_char(s.submitted_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as submitted_date, s.submitted_login_id,
to_char(s.approved_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as approved_date,
to_char(s.rejected_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as rejected_date, s.reviewed_login_id,
to_char(s.assigned_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as assigned_date, s.assigned_login_id,
to_char(s.created_date at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS')
as claimed_date, s.claimed_login_id,
s.requirements, s.admin_notes, s.inactive,
L1.first_name || ' ' || L1.last_name as created_user,
L2.first_name || ' ' || L2.last_name as modified_user,
L3.first_name || ' ' || L3.last_name as submitted_user,
L4.first_name || ' ' || L4.last_name as reviewed_user,
L5.first_name || ' ' || L5.last_name as assigned_user,
L6.first_name || ' ' || L6.last_name as claimed_user,
s.email,
s.covid_notes,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
s.v_hours, s.verification_status_id, s.inactive_temporary
from stakeholder s
left join login L1 on s.created_login_id = L1.id
left join login L2 on s.modified_login_id = L2.id
left join login L3 on s.submitted_login_id = L3.id
left join login L4 on s.reviewed_login_id = L4.id
left join login L5 on s.assigned_login_id = L5.id
left join login L6 on s.claimed_login_id = L6.id
where s.name ilike ${nameClause}
${
categoryIds && categoryIds.length > 0
? ` and s.id in ${categoryClause} `
: ""
}
${trueFalseEitherClause("s.assigned_date", isAssigned)}
${trueFalseEitherClause("s.submitted_date", isSubmitted)}
${trueFalseEitherClause("s.approved_date", isApproved)}
${trueFalseEitherClause("s.rejected_date", isRejected)}
${trueFalseEitherClause("s.claimed_date", isClaimed)}
${booleanEitherClause("s.inactive", isInactive)}
${assignedLoginId ? ` and s.assigned_login_id = ${assignedLoginId} ` : ""}
${claimedLoginId ? ` and s.claimed_login_id = ${claimedLoginId} ` : ""}
${
Number(verificationStatusId) > 0
? ` and s.verification_status_id = ${verificationStatusId} `
: ""
}
order by s.name
`;
//console.log(sql);
const stakeholderResult = await pool.query(sql);
let stakeholders = [];
stakeholderResult.rows.forEach((row) => {
stakeholders.push({
id: row.id,
name: row.name || "",
address1: row.address_1 || "",
address2: row.address_2 || "",
city: row.city || "",
state: row.state || "",
zip: row.zip || "",
phone: row.phone || "",
latitude: row.latitude ? Number(row.latitude) : null,
longitude: row.longitude ? Number(row.longitude) : null,
website: row.website || "",
createdDate: row.created_date,
createdLoginId: row.created_login_id,
modifiedDate: row.modified_date,
modifiedLoginId: row.modified_login_id,
submittedDate: row.submitted_date,
submittedLoginId: row.submitted_login_id,
assignedDate: row.assigned_date,
assignedLoginId: row.assigned_login_id,
approvedDate: row.approved_date,
rejectedDate: row.rejected_date,
reviewedLoginId: row.reviewed_login_id,
claimedDate: row.claimed_date,
claimedLoginId: row.claimed_login_id,
requirements: row.requirements || "",
adminNotes: row.admin_notes || "",
inactive: row.inactive,
createdUser: row.created_user || "",
modifiedUser: row.modified_user || "",
submittedUser: row.submitted_user || "",
reviewedUser: row.reviewed_user || "",
assignedUser: row.assigned_user || "",
claimedUser: row.claimed_user || "",
categories: row.categories,
email: row.email || "",
covidNotes: row.covid_notes || "",
confirmedName: row.v_name,
confirmedCategories: row.v_categories,
confirmedAddress: row.v_address,
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
});
});

if (latitude && longitude && distance) {
// Should move distance calc into stored proc
stakeholders.forEach((stakeholder) => {
if (stakeholder.latitude && stakeholder.longitude) {
stakeholder.distance =
Math.sqrt(
(Math.abs(stakeholder.longitude - longitude) *
Math.cos((latitude / 360) * 2 * Math.PI)) **
2 +
Math.abs(stakeholder.latitude - latitude) ** 2
) * 69.097;
} else {
stakeholder.distance = 999;
}
});
// Should move sorting into stored proc
stakeholders.sort((a, b) => a.distance - b.distance);
// Should move distance filter into stored proc
if (distance > 0) {
stakeholders = stakeholders.filter(
(stakeholder) => stakeholder.distance <= distance
);
}
}

return stakeholders;
};

const selectById = async (id) => {
const sql = `select
s.id, s.name, s.address_1, s.address_2, s.city, s.state, s.zip,
Expand Down Expand Up @@ -741,6 +908,7 @@ const remove = (id) => {

module.exports = {
search,
searchDashboard,
selectById,
insert,
update,
Expand Down
5 changes: 4 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"name": "food-oasis-client",
"version": "0.1.0",
"description": "React Client for Food Oasis",
"version": "1.0.1",
"author": "Hack for LA",
"license": "MIT",
"private": true,
"proxy": "http://localhost:5000",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Faq.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const Faq = () => {
<UserContext.Consumer>
{(user) =>
user &&
user.isAdmin && (
(user.isAdmin || user.isCoordinator) && (
<div className={classes.buttonsContainer}>
<Link className={classes.link} to="/faqs/add">
<AddButton label="Add New Faq" />
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/FaqItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const FaqItem = ({ faq, reorder, reorderFaqs, faqLength }) => {
<UserContext.Consumer>
{(user) =>
user &&
user.isAdmin && (
(user.isAdmin || user.isCoordinator) && (
<div className={classes.editBar}>
<Typography className={classes.identifier} variant="h6">
{identifier}
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const LoginForm = (props) => {
setToast({
message: "Login successful.",
});
if (response.user.isAdmin) {
if (response.user.isAdmin || response.user.isCoordinator) {
history.push("/verificationAdmin");
} else if (response.user.isSecurityAdmin) {
history.push("/securityadmindashboard");
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default function Menu(props) {
<UserContext.Consumer>
{(user) => (
<>
{user && user.isAdmin ? (
{user && (user.isAdmin || user.isCoordinator) ? (
<>
<MenuItemLink
key="organizationedit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ const SecurityAdminDashboard = () => {
if (account) {
if (permission === "is_admin") {
account["isAdmin"] = value;
} else if (permission === "is_coordinator") {
account["isCoordinator"] = value;
} else if (permission === "is_security_admin") {
account["isSecurityAdmin"] = value;
} else if (permission === "is_data_entry") {
Expand Down
Loading

0 comments on commit c441796

Please sign in to comment.