Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions packages/common/src/ResourceSchedule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RRule, RRuleSet } from "rrule";
import {
TResource,
TResourceScheduleData,
TScheduleItemOpenClose,
TTimezoneName,
Expand Down Expand Up @@ -199,6 +200,27 @@ export default class ResourceSchedule {
);
}

/**
* Returns bool to indicate if a resource is currently open.
* @param at The date to compare against. Defaults to `new Date()`.
*/
isOpen(at: Date = new Date()): boolean | null {
if (this.alwaysOpen) {
return true;
}

const nextScheduleItemPeriod = this.getNextScheduleItemPeriod(at);
if (!nextScheduleItemPeriod) {
return null;
}

if (at.getTime() > nextScheduleItemPeriod.open.getTime()) {
return true;
}

return false;
}

/**
* Converts data in the form of `TResourceScheduleData` (the format a resource schedule is sent over
* the wire and stored in the database) into a full-fledged `ResourceSchedule` instance.
Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/routes/api/category/[stub].ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ export async function get(req, res, _next) {
const categoryDocument = await Category.getByStub(stub);

if (categoryDocument) {
res
.status(200)
.json({ category: await categoryDocumentToCategory(categoryDocument) });
res.status(200).json({
category: await categoryDocumentToCategory(categoryDocument),
});
} else {
res.status(404).json({ message: `Category ${stub} not found` });
}
Expand Down
5 changes: 4 additions & 1 deletion packages/web/src/components/CategoryResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from "react";
import ResourceList from "./ResourceList";
import SubCategories from "./SubCategories";
import Typography from "@material-ui/core/Typography";
import { sortByOpen } from "../utils/schedule";
import { useParams } from "react-router-dom";
import useResourcesByCategory from "./useResourcesByCategory";
import useResourcesBySubcategory from "./useResourcesBySubcategory";
Expand Down Expand Up @@ -44,7 +45,9 @@ const CategoryResults = ({
const status = subcategoryStub
? subcategoryResourcesStatus
: categoryResourcesStatus;
const resources = subcategoryStub ? subcategoryResources : categoryResources;
const resources = sortByOpen(
subcategoryStub ? subcategoryResources : categoryResources
);

return (
<>
Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/components/ResourceCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { getIsOpen, getNextOpenText } from "../utils/schedule";

import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardActions from "@material-ui/core/CardActions";
Expand All @@ -13,6 +11,8 @@ import ScheduleIcon from "@material-ui/icons/Schedule";
import { TResource } from "@upswyng/types";
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import Typography from "@material-ui/core/Typography";
import { getNextOpenText } from "../utils/schedule";

import makeStyles from "@material-ui/styles/makeStyles";
import { useHistory } from "react-router-dom";

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

const parsedSchedule = ResourceSchedule.parse(schedule);
const isOpen = getIsOpen(parsedSchedule);
const isOpen = parsedSchedule.isOpen();
const scheduleText = getNextOpenText(parsedSchedule);
const classes = useStyles({
index,
Expand Down
31 changes: 13 additions & 18 deletions packages/web/src/utils/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
TDay,
TResource,
TSchedule,
TScheduleItemOpenClose,
TSchedulePeriod,
Expand Down Expand Up @@ -88,24 +89,6 @@ const getOpensAtText = ({ open }: TScheduleItemOpenClose) =>
sameElse: "MMM Do",
});

export const getIsOpen = (schedule: ResourceSchedule): boolean | null => {
if (schedule.alwaysOpen) {
return true;
}

const currentDt = new Date();
const nextScheduleItemPeriod = schedule.getNextScheduleItemPeriod(currentDt);
if (!nextScheduleItemPeriod) {
return null;
}

if (currentDt.getTime() > nextScheduleItemPeriod.open.getTime()) {
return true;
}

return false;
};

export const getNextOpenText = (schedule: ResourceSchedule): string => {
if (schedule.alwaysOpen) {
return "Open 24/7";
Expand All @@ -123,3 +106,15 @@ export const getNextOpenText = (schedule: ResourceSchedule): string => {

return `open ${getOpensAtText(nextScheduleItemPeriod)}`;
};

export const sortByOpen = (resources: TResource[] | undefined) => {
return resources
? resources.sort((resourceA, resourceB) => {
const A = ResourceSchedule.parse(resourceA.schedule).isOpen();
const B = ResourceSchedule.parse(resourceB.schedule).isOpen();
if (A && !B) return -1;
if (B && !A) return 1;
return 0;
})
: [];
};