Skip to content

Commit 3a2e58e

Browse files
authored
✨ sort by open (#472)
* write basic sorting function * refactor and get subcategory working * move sorting to front end * move sortByOpen to utils
1 parent 0fe95ad commit 3a2e58e

File tree

5 files changed

+45
-25
lines changed

5 files changed

+45
-25
lines changed

packages/common/src/ResourceSchedule.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { RRule, RRuleSet } from "rrule";
22
import {
3+
TResource,
34
TResourceScheduleData,
45
TScheduleItemOpenClose,
56
TTimezoneName,
@@ -199,6 +200,27 @@ export default class ResourceSchedule {
199200
);
200201
}
201202

203+
/**
204+
* Returns bool to indicate if a resource is currently open.
205+
* @param at The date to compare against. Defaults to `new Date()`.
206+
*/
207+
isOpen(at: Date = new Date()): boolean | null {
208+
if (this.alwaysOpen) {
209+
return true;
210+
}
211+
212+
const nextScheduleItemPeriod = this.getNextScheduleItemPeriod(at);
213+
if (!nextScheduleItemPeriod) {
214+
return null;
215+
}
216+
217+
if (at.getTime() > nextScheduleItemPeriod.open.getTime()) {
218+
return true;
219+
}
220+
221+
return false;
222+
}
223+
202224
/**
203225
* Converts data in the form of `TResourceScheduleData` (the format a resource schedule is sent over
204226
* the wire and stored in the database) into a full-fledged `ResourceSchedule` instance.

packages/server/src/routes/api/category/[stub].ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ export async function get(req, res, _next) {
66
const categoryDocument = await Category.getByStub(stub);
77

88
if (categoryDocument) {
9-
res
10-
.status(200)
11-
.json({ category: await categoryDocumentToCategory(categoryDocument) });
9+
res.status(200).json({
10+
category: await categoryDocumentToCategory(categoryDocument),
11+
});
1212
} else {
1313
res.status(404).json({ message: `Category ${stub} not found` });
1414
}

packages/web/src/components/CategoryResults.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React from "react";
55
import ResourceList from "./ResourceList";
66
import SubCategories from "./SubCategories";
77
import Typography from "@material-ui/core/Typography";
8+
import { sortByOpen } from "../utils/schedule";
89
import { useParams } from "react-router-dom";
910
import useResourcesByCategory from "./useResourcesByCategory";
1011
import useResourcesBySubcategory from "./useResourcesBySubcategory";
@@ -44,7 +45,9 @@ const CategoryResults = ({
4445
const status = subcategoryStub
4546
? subcategoryResourcesStatus
4647
: categoryResourcesStatus;
47-
const resources = subcategoryStub ? subcategoryResources : categoryResources;
48+
const resources = sortByOpen(
49+
subcategoryStub ? subcategoryResources : categoryResources
50+
);
4851

4952
return (
5053
<>

packages/web/src/components/ResourceCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { getIsOpen, getNextOpenText } from "../utils/schedule";
2-
31
import Card from "@material-ui/core/Card";
42
import CardActionArea from "@material-ui/core/CardActionArea";
53
import CardActions from "@material-ui/core/CardActions";
@@ -13,6 +11,8 @@ import ScheduleIcon from "@material-ui/icons/Schedule";
1311
import { TResource } from "@upswyng/types";
1412
import { Theme } from "@material-ui/core/styles/createMuiTheme";
1513
import Typography from "@material-ui/core/Typography";
14+
import { getNextOpenText } from "../utils/schedule";
15+
1616
import makeStyles from "@material-ui/styles/makeStyles";
1717
import { useHistory } from "react-router-dom";
1818

@@ -63,7 +63,7 @@ const ResourceCard = ({ index = 1, placeholder, resource }: Props) => {
6363
const { name, resourceId, schedule, streetViewImage } = resource;
6464

6565
const parsedSchedule = ResourceSchedule.parse(schedule);
66-
const isOpen = getIsOpen(parsedSchedule);
66+
const isOpen = parsedSchedule.isOpen();
6767
const scheduleText = getNextOpenText(parsedSchedule);
6868
const classes = useStyles({
6969
index,

packages/web/src/utils/schedule.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
TDay,
3+
TResource,
34
TSchedule,
45
TScheduleItemOpenClose,
56
TSchedulePeriod,
@@ -88,24 +89,6 @@ const getOpensAtText = ({ open }: TScheduleItemOpenClose) =>
8889
sameElse: "MMM Do",
8990
});
9091

91-
export const getIsOpen = (schedule: ResourceSchedule): boolean | null => {
92-
if (schedule.alwaysOpen) {
93-
return true;
94-
}
95-
96-
const currentDt = new Date();
97-
const nextScheduleItemPeriod = schedule.getNextScheduleItemPeriod(currentDt);
98-
if (!nextScheduleItemPeriod) {
99-
return null;
100-
}
101-
102-
if (currentDt.getTime() > nextScheduleItemPeriod.open.getTime()) {
103-
return true;
104-
}
105-
106-
return false;
107-
};
108-
10992
export const getNextOpenText = (schedule: ResourceSchedule): string => {
11093
if (schedule.alwaysOpen) {
11194
return "Open 24/7";
@@ -123,3 +106,15 @@ export const getNextOpenText = (schedule: ResourceSchedule): string => {
123106

124107
return `open ${getOpensAtText(nextScheduleItemPeriod)}`;
125108
};
109+
110+
export const sortByOpen = (resources: TResource[] | undefined) => {
111+
return resources
112+
? resources.sort((resourceA, resourceB) => {
113+
const A = ResourceSchedule.parse(resourceA.schedule).isOpen();
114+
const B = ResourceSchedule.parse(resourceB.schedule).isOpen();
115+
if (A && !B) return -1;
116+
if (B && !A) return 1;
117+
return 0;
118+
})
119+
: [];
120+
};

0 commit comments

Comments
 (0)