Skip to content

Commit

Permalink
Merge pull request #76 from sfbrigade/expired-features
Browse files Browse the repository at this point in the history
Expired features
  • Loading branch information
dave-hay authored Jul 9, 2022
2 parents a5473f1 + fa9666f commit e2cb784
Show file tree
Hide file tree
Showing 10 changed files with 8,100 additions and 8,302 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "7.2.1",
"@types/jest": "^24.0.0",
"@types/lodash": "^4.14.159",
"@types/lodash": "^4.14.182",
"@types/node": "^12.0.0",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.13",
"@types/react-test-renderer": "^17.0.1",
"axios": "^0.19.2",
"jest-location-mock": "^1.0.9",
"lodash": "^4.17.21",
"moment": "^2.27.0",
"prettier": "^2.3.2",
"react": "^17.0.2",
Expand Down
10 changes: 6 additions & 4 deletions src/api/getResults.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import {getResults} from "./getResults";
import {ReliefType, Result, ResultResponse, SupportType} from "../types";
import { ReliefType, Result, ResultResponse, SortOptionType, SupportType } from "../types";
import {standardizeFormat} from "./responseFormatter";
import sortListBy from "../components/results/sort/sortListBy";

const data = require("../assets/data/results.json");

describe("getResults", () => {
it("fetches data successfully from the API", async () => {
const sortedResults = sortListBy(data.results, SortOptionType.DueDateNewToOld);
const expectedResults = [
{
name: data.results[0].name,
supportType: data.results[0].supportType,
interestRate: data.results[0].interestRate,
name: sortedResults[0].name,
supportType: sortedResults[0].supportType,
interestRate: sortedResults[0].interestRate,
},
];

Expand Down
9 changes: 7 additions & 2 deletions src/api/getResults.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import {Result, ResultResponse} from "../types";
import {Result, ResultResponse, SortOptionType} from "../types";
import {standardizeFormat} from "./responseFormatter";
import data from "../assets/data/results.json";
import sortListBy from "../components/results/sort/sortListBy";

export const getResults = async (): Promise<Result[]> => {
try {
// @ts-ignore
return data.results.map((result: ResultResponse) => standardizeFormat(result) );
const results = data.results.map((result: ResultResponse) =>
standardizeFormat(result)
);
// @ts-ignore
return sortListBy(results, SortOptionType.DueDateNewToOld);
} catch (error) {
console.error("Error", error);
return [] as Result[];
Expand Down
4 changes: 2 additions & 2 deletions src/assets/data/results.json
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@
"sectorType":"Public",
"supportedEntity":"Government",
"entityName":"U.S. Small Business Association (SBA)",
"deadlineApplicable":"Yes",
"deadlineApplicable":"No",
"deadline":null,
"websiteUrl":"https://www.sba.gov/federal-contracting/contracting-assistance-programs/8a-business-development-program",
"description":"",
Expand Down Expand Up @@ -2248,7 +2248,7 @@
"sectorType":"Private",
"supportedEntity":"Private",
"entityName":"Zellerbach Family Foundation",
"deadlineApplicable":"",
"deadlineApplicable":"Yes",
"deadline":"2021-12-20T00:00:00.000Z",
"websiteUrl":"https://zff.org/ca-covid-response-grants/",
"description":"",
Expand Down
8 changes: 8 additions & 0 deletions src/components/results/ResultCard.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,11 @@ export const Tag = styled(Typography).attrs({variant: 'body2' })`
padding-right: 12px;
color: ${colors.text};
`;

export const ExpiredTag = styled(Typography).attrs({variant: 'body2' })`
background: ${colors.primaryRed};
border-radius: 16px;
padding-left: 12px;
padding-right: 12px;
color: ${colors.white};
`;
30 changes: 16 additions & 14 deletions src/components/results/ResultCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from "react";
import Moment from "moment";

import {Result} from "../../types";
import {
formatAwardAmount,
Expand All @@ -14,7 +16,7 @@ import {
StyledName,
StyledReliefType,
SupportTypeContainer,
SupportTypeItem, Tag, Tags
SupportTypeItem, Tag, Tags, ExpiredTag
} from "./ResultCard.styles";

const onApply = (url: string) => {
Expand All @@ -33,19 +35,18 @@ const ResultCard: React.FC<Result> = ({
lgbtq,
websiteUrl,
}) => {
const deadlineString = (): string => {
let deadlineLabelText = "";
if (deadlineApplicable === "Yes" || deadlineApplicable === "Unknown") {
if (!deadline) {
deadlineLabelText = "Unknown";
} else {
deadlineLabelText = formatDate(deadline);
}
} else if (deadlineApplicable === "No") {
deadlineLabelText = "Ongoing";
let isExpired = false;
let deadlineLabelText = "";
if (deadlineApplicable === "Yes" || deadlineApplicable === "Unknown") {
if (!deadline) {
deadlineLabelText = "Unknown";
} else {
deadlineLabelText = formatDate(deadline);
isExpired = Moment().isAfter(Moment(deadline));
}
return deadlineLabelText;
};
} else if (deadlineApplicable === "No") {
deadlineLabelText = "Ongoing";
}

return (
<StyledCard>
Expand All @@ -54,7 +55,7 @@ const ResultCard: React.FC<Result> = ({
<span data-testid='support-type-header'>{`${supportType}${formatInterestRate(
interestRate,
supportType
)}${deadlineString()}`}</span>
)}${deadlineLabelText}`}</span>
</SupportTypeItem>
</SupportTypeContainer>
<StyledAwardAmount>{formatAwardAmount(maxAwardAmount)}</StyledAwardAmount>
Expand All @@ -70,6 +71,7 @@ const ResultCard: React.FC<Result> = ({
<Tags>
{blackOwned && <Tag>Black-owned</Tag>}
{lgbtq && <Tag>LGBTQ</Tag>}
{isExpired && <ExpiredTag>Possibly Closed</ExpiredTag>}
</Tags>
</CardBottom>
</StyledCard>
Expand Down
53 changes: 27 additions & 26 deletions src/components/results/sort/sortListBy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ describe("sortListBy", () => {
dateAdded: "Fri, 05 Jun 2020 00:00:00 GMT",
maxAwardAmount: 10000000,
reliefType: ReliefType.COVID,
deadline: "Fri, 20 Sep 2019 00:00:00 GMT",
deadlineApplicable: "Yes",
deadline: "Fri, 20 Sep 2019 00:00:00 GMT", //09/20/19
});
const result2 = makeResult({
id: 2,
name: "result 2",
supportType: SupportType.Grant,
interestRate: null,
dateAdded: "Wed, 10 Jun 2020 00:00:00 GMT",
maxAwardAmount: null,
maxAwardAmount: 0,
reliefType: ReliefType.ProtestDamage,
deadline: "Thu, 16 Apr 2020 00:00:00 GMT",
deadlineApplicable: "Yes",
deadline: "Thu, 16 Apr 2020 00:00:00 GMT", //04/16/20
});
const result3 = makeResult({
id: 3,
Expand All @@ -31,7 +33,8 @@ describe("sortListBy", () => {
dateAdded: "Wed, 10 Jun 2020 00:00:00 GMT",
maxAwardAmount: 500,
reliefType: ReliefType.Both,
deadline: "Mon, 15 Jun 2020 00:00:00 GMT",
deadlineApplicable: "Yes",
deadline: "Mon, 15 Jun 2020 00:00:00 GMT", //06/15/20
});
const result4 = makeResult({
id: 4,
Expand Down Expand Up @@ -59,7 +62,7 @@ describe("sortListBy", () => {
supportType: SupportType.Loan,
interestRate: null,
dateAdded: "Fri, 02 Jun 2020 00:00:00 GMT",
maxAwardAmount: null,
maxAwardAmount: 0,
reliefType: ReliefType.COVID,
deadline: null,
});
Expand All @@ -72,28 +75,27 @@ describe("sortListBy", () => {
});

describe("Sorting by award amount", () => {
it("places results with null award amount at the end", () => {
const results: Result[] = [result5, result1];
it("places results with null or 0 award amount at the end", () => {
const input: Result[] = [result5, result1];
const answer: Result[] = [result1, result5];
expect(sortListBy(results, SortOptionType.AwardAmountHighToLow)).toEqual(
answer
);
expect(sortListBy(results, SortOptionType.AwardAmountLowToHigh)).toEqual(
expect(sortListBy(input, SortOptionType.AwardAmountHighToLow)).toEqual(
answer
);
});
it("sorts results from high to low award amounts when sort option is AwardAmountHighToLow", () => {
const answer: Result[] = [result1, result4, result3, result2, result5];
const input: Result[] = [result3, result1, result4];
const answer: Result[] = [result1, result4, result3];
const highToLow = sortListBy(
results,
input,
SortOptionType.AwardAmountHighToLow
);
expect(highToLow).toEqual(answer);
});
it("sorts results from low to high award amounts when sort option is AwardAmountLowToHigh", () => {
const answer: Result[] = [result3, result4, result1, result2, result5];
const input: Result[] = [result1, result4, result3, result2];
const answer: Result[] = [result2, result3, result4, result1];
const lowToHigh = sortListBy(
results,
input,
SortOptionType.AwardAmountLowToHigh
);
expect(lowToHigh).toEqual(answer);
Expand Down Expand Up @@ -139,27 +141,26 @@ describe("sortListBy", () => {
});

describe("Sorting by due date", () => {
it("places results with a null deadline value at the end", () => {
const results: Result[] = [result6, result1];
const answer: Result[] = [result1, result6];
expect(sortListBy(results, SortOptionType.DueDateOldToNew)).toEqual(
answer
);
expect(sortListBy(results, SortOptionType.DueDateNewToOld)).toEqual(
it("places results with a null deadline value at the beginning", () => {
const input: Result[] = [result1, result6];
const answer: Result[] = [result6, result1];
expect(sortListBy(input, SortOptionType.DueDateNewToOld)).toEqual(
answer
);
});

it("sorts results from oldest deadline to newest deadline when sort option is DueDateOldToNew", () => {
const answer: Result[] = [result1, result2, result3, result4, result5];
expect(sortListBy(results, SortOptionType.DueDateOldToNew)).toEqual(
const input: Result[] = [result3, result2, result1];
const answer: Result[] = [result1, result2, result3];
expect(sortListBy(input, SortOptionType.DueDateOldToNew)).toEqual(
answer
);
});

it("sorts results from newest deadline to oldest deadline when sort option is DueDateNewToOld", () => {
const answer: Result[] = [result3, result2, result1, result4, result5];
expect(sortListBy(results, SortOptionType.DueDateNewToOld)).toEqual(
const answer: Result[] = [result3, result2, result1];
const input: Result[] = [result1, result2, result3];
expect(sortListBy(input, SortOptionType.DueDateNewToOld)).toEqual(
answer
);
});
Expand Down
63 changes: 21 additions & 42 deletions src/components/results/sort/sortListBy.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,31 @@
import {SortOptionType, Result, SupportType} from "../../../types";
import Moment from "moment";
import _ from "lodash";

/**
* TODO use lodash
* TODO use lodash interest rate sorting
* Sorts a copy of the given list with the given option and returns the copy.
* @param {Result[]} list - filteredResults from ../Results.tsx
* @param {SortOptionType} option - Sort order
*/
export default (list: Result[], option: SortOptionType): Result[] => {
const sortedList = [...list];
let sortedList = [...list];
switch (+option) {
case SortOptionType.AwardAmountHighToLow:
sortedList.sort((a, b) => {
if (a.maxAwardAmount !== null && b.maxAwardAmount !== null) {
return b.maxAwardAmount - a.maxAwardAmount;
} else if (a.maxAwardAmount !== null && b.maxAwardAmount === null) {
return -1;
} else if (a.maxAwardAmount === null && b.maxAwardAmount !== null) {
return 1;
} else {
sortedList = _.orderBy(sortedList, [(element) => {
if (element.maxAwardAmount === null) {
return 0;
}
});
return element.maxAwardAmount;
}], ['desc']);
break;
case SortOptionType.AwardAmountLowToHigh:
sortedList.sort((a, b) => {
if (a.maxAwardAmount !== null && b.maxAwardAmount !== null) {
return a.maxAwardAmount - b.maxAwardAmount;
} else if (a.maxAwardAmount !== null && b.maxAwardAmount === null) {
return -1;
} else if (a.maxAwardAmount === null && b.maxAwardAmount !== null) {
return 1;
} else {
sortedList = _.orderBy(sortedList, [(element) => {
if (element.maxAwardAmount === null) {
return 0;
}
});
return element.maxAwardAmount;
}], ['asc']);
break;
case SortOptionType.InterestLowToHigh:
sortedList.sort((a, b) => {
Expand Down Expand Up @@ -97,32 +88,20 @@ export default (list: Result[], option: SortOptionType): Result[] => {
});
break;
case SortOptionType.DueDateOldToNew:
sortedList.sort((a, b) => {
if (a.deadline === null && b.deadline !== null) {
return 1;
sortedList = _.orderBy(sortedList, [(element) => {
if (!element.deadline) {
return Moment().toDate();
}
if (a.deadline !== null && b.deadline === null) {
return -1;
}
if (a.deadline === null && b.deadline === null) {
return 0;
}
return Moment(a.deadline).diff(Moment(b.deadline));
});
return Moment(element.deadline).toDate();
}], ['asc']);
break;
case SortOptionType.DueDateNewToOld:
sortedList.sort((a, b) => {
if (a.deadline === null && b.deadline !== null) {
return 1;
}
if (a.deadline !== null && b.deadline === null) {
return -1;
sortedList = _.orderBy(sortedList, [(element) => {
if (!element.deadline) {
return Moment().toDate();
}
if (a.deadline === null && b.deadline === null) {
return 0;
}
return Moment(b.deadline).diff(Moment(a.deadline));
});
return Moment(element.deadline).toDate();
}], ['desc']);
break;
case SortOptionType.None:
default:
Expand Down
3 changes: 2 additions & 1 deletion src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import "./assets/fonts/bree-serif.css";
import "./assets/fonts/source-sans-pro.css";
import {createTheme} from "@mui/material/styles";
import {red} from "@mui/material/colors";
import { grey, red } from "@mui/material/colors";

const defaultTheme = createTheme();

export const colors = {
primaryRed: red[400],
text: defaultTheme.palette.text.primary,
white: grey[50],
};

export const theme = createTheme({
Expand Down
Loading

0 comments on commit e2cb784

Please sign in to comment.