Skip to content

Commit

Permalink
Deliveries updates
Browse files Browse the repository at this point in the history
  • Loading branch information
mojowen committed Nov 8, 2023
1 parent 0dd167e commit 22e4a4a
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 108 deletions.
2 changes: 1 addition & 1 deletion src/api/PizzaApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class PizzaApi {
}

public async getOrder(id: OrderId, errorHandler?: (error: ApiError) => void): Promise<OrderDetails | null> {
return this.handleResponse(await baseFetch<OrderDetails>(`/order/${id}`), errorHandler);
return this.handleResponse(await baseFetch<OrderDetails>(`/orders/${id}`), errorHandler);
}

public async getOrders(page: number = 0, limit: number = 100, errorHandler?: (error: ApiError) => void): Promise<OrderQueryResults> {
Expand Down
2 changes: 2 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export namespace Components {
}
interface UiGeoMap {
"center"?: google.maps.LatLngLiteral;
"currentAddress"?: string;
"deliveries"?: { coords: google.maps.LatLngLiteral; id: LocationId }[];
"trucks"?: { coords: google.maps.LatLngLiteral; id: LocationId }[];
"zoom"?: number;
Expand Down Expand Up @@ -452,6 +453,7 @@ declare namespace LocalJSX {
}
interface UiGeoMap {
"center"?: google.maps.LatLngLiteral;
"currentAddress"?: string;
"deliveries"?: { coords: google.maps.LatLngLiteral; id: LocationId }[];
"onMarkerSelected"?: (event: CustomEvent<{
type: "pizza" | "truck";
Expand Down
2 changes: 1 addition & 1 deletion src/components/app-root/app-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class AppRoot {
<stencil-route url="/activity" component="page-activity" />
<stencil-route url="/covid" component="page-covid" />
<stencil-route url="/contact" component="page-contact" />
<stencil-route url={["/deliveries/:location", "/deliveries"]} component="page-deliveries" />
<stencil-route url={["/deliveries/:location/:order", "/deliveries/:location", "/deliveries"]} component="page-deliveries" />
<stencil-route url="/donate" component="page-donate" />
<stencil-route url="/gift" component="page-gift" />
<stencil-route url="/crustclub" component="page-crustclub" />
Expand Down
6 changes: 3 additions & 3 deletions src/components/page-activity/page-activity.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, h, Host, State } from "@stencil/core";

import { OrderDetails, PizzaApi } from "../../api";
import { scrollPageToTop } from "../../util";
import { locationURL, scrollPageToTop } from "../../util";

@Component({
tag: "page-activity",
Expand Down Expand Up @@ -41,11 +41,11 @@ export class PageActivity {
<div class="order-day">
<h3 class="date-header">{date}</h3>
<ui-pizza-list class="order-list">
{orders.map(({ id, createdAt, orderType, pizzas, location: { fullAddress }, reports }: OrderDetails) => (
{orders.map(({ id, createdAt, orderType, pizzas, location, reports }: OrderDetails) => (
<li id={"order-id-" + id} key={id}>
<b>
{pizzas} {orderType} ordered at {new Date(createdAt).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })} for{" "}
<stencil-route-link url={`/deliveries/${encodeURI(fullAddress)}`}>{fullAddress}</stencil-route-link>
<stencil-route-link url={locationURL(location)}>{location.fullAddress}</stencil-route-link>
</b>
<ul>
{reports.map(({ reportURL, createdAt: reportCreatedAt, waitTime }) => (
Expand Down
28 changes: 0 additions & 28 deletions src/components/page-deliveries/page-deliveries.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,6 @@ page-deliveries {
cursor: pointer;
}

hr.heavy {
width: 100%;
background-color: $red;
height: 8px;
margin: 0;
}

#deliveries-map-container {
background-color: $gray1;
width: 100%;
height: 300px;

@media ($tablet) {
height: 420px;
}

&.is-single-location {
height: 200px;
}
}

.now-feeding {
padding: 0.5em 0 0.5em 1.5em;
font-size: 0.8em;
font-weight: 600;
background-color: $white;
}

.food-choices {
font-size: 0.9em;
font-weight: 600;
Expand Down
70 changes: 21 additions & 49 deletions src/components/page-deliveries/page-deliveries.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Build, Component, Fragment, FunctionalComponent, h, Host, Listen, Prop, State, Watch } from "@stencil/core";
import { MatchResults, RouterHistory } from "@stencil/router";
// @ts-ignore
import {} from "googlemaps";

import { LocationInfo, LocationStatus, OrderDetails, OrderInfo, OrderTypes, PizzaApi, TruckDetails, TruckInfo } from "../../api";
import { scrollPageToTop } from "../../util";
import { formatDateTime, formatTime, scrollPageToTop } from "../../util";
import { UiGeoMap } from "../ui-geo-map/ui-geo-map";

enum FoodChoice {
Expand All @@ -15,10 +13,6 @@ enum FoodChoice {

type OrderOrTruckItem = { type: "pizza"; data: OrderDetails | null } | { type: "truck"; data: TruckDetails | null };

const formatTime = (date: Date) => date.toLocaleTimeString([], { hour: "numeric", minute: "2-digit", timeZoneName: "short" });

const formatDate = (date: Date) => date.toLocaleDateString([], { day: "2-digit", month: "2-digit" });

const ReportLink = () => <stencil-route-link url="/report">Make a report</stencil-route-link>;

const FoodChoices: FunctionalComponent<{
Expand Down Expand Up @@ -46,7 +40,7 @@ const OrderDetailDisplay: FunctionalComponent<{
<ui-dynamic-text value={order} format={x => x.location.fullAddress} />
</span>
<div>
<ui-dynamic-text value={order} format={x => `${x.quantity} ${x.orderType} at ${formatDate(x.createdAt)} ${formatTime(x.createdAt)}`} />
<ui-dynamic-text value={order} format={x => `${x.quantity} ${x.orderType} at ${formatDateTime(x.createdAt)}`} />
</div>
</li>
);
Expand All @@ -62,10 +56,7 @@ const OrderInfoDisplay: FunctionalComponent<{
<ui-dynamic-text value={order} format={x => `${x.quantity} ${x.orderType} en route`} />
</span>
<div>
<ui-dynamic-text
value={order}
format={x => `${formatDate(x.createdAt)} ${formatTime(x.createdAt)}${reportCount > 0 ? ` • ${reportCount} report${reportCount === 1 ? "" : "s"}` : ""}`}
/>
<ui-dynamic-text value={order} format={x => `${formatDateTime(x.createdAt)}${reportCount > 0 ? ` • ${reportCount} report${reportCount === 1 ? "" : "s"}` : ""}`} />
</div>
</li>
);
Expand All @@ -80,7 +71,7 @@ const TruckInfoDisplay: FunctionalComponent<{
<ui-dynamic-text value={truck} format={x => x.location.fullAddress} />
</span>
<div>
<ui-dynamic-text value={truck} format={x => `Food truck on location since ${formatDate(x.createdAt)} ${formatTime(x.createdAt)}`} />
<ui-dynamic-text value={truck} format={x => `Food truck on location since ${formatDateTime(x.createdAt)}`} />
</div>
</li>
);
Expand All @@ -104,9 +95,6 @@ const OrderAndTruckInfoList: FunctionalComponent<{
),
);

const DEFAULT_ZOOM = 4;
const SELECTED_LOCATION_ZOOM = 15;

@Component({
tag: "page-deliveries",
styleUrl: "page-deliveries.scss",
Expand All @@ -117,21 +105,20 @@ export class PageDeliveries {
@Prop() public match!: MatchResults;

@State() private selectedAddress?: string;
@State() private selectedLocation?: LocationStatus;
@State() private selectedOrder?: OrderInfo;
/**
* Watched and used to re-center the map
*/
// @ts-ignore
@State() private mapCenterPoint: { lat: number; lng: number };
@State() private selectedFood: FoodChoice;
@State() private selectedLocation?: LocationStatus;
@State() private selectedOrder?: OrderInfo;
@State() private recentOrders?: OrderDetails[];
@State() private recentTrucks?: TruckInfo[];
@State() private mapZoom: number;

constructor() {
this.selectedFood = FoodChoice.all;
this.mapZoom = DEFAULT_ZOOM;
this.mapZoom = UiGeoMap.DEFAULT_ZOOM;
this.mapCenterPoint = UiGeoMap.US_CENTER;
}

Expand Down Expand Up @@ -161,32 +148,19 @@ export class PageDeliveries {
}
}

/*
@Watch( "selectedFood" )
public selectedFoodChanged( filter: FoodChoice ) {
const val = filter === FoodChoice.all
? ""
: Object.keys( FoodChoice ).find( k => ( FoodChoice as any )[k] === filter ) + "";
if( window.location.hash !== val ) {
window.location.hash = val;
}
}
*/

/**
* Lookup location info when the selected address value changes
*/
@Watch("selectedAddress")
public selectedAddressChanged(newAddress?: string, oldAddress?: string) {
const ownPathFragment = this.history.location.pathname.split("/").filter(x => x !== "")[0];
if (newAddress == null && oldAddress != null) {
const path = `/${ownPathFragment}`;
if (newAddress === undefined && oldAddress != null) {
const path = `/deliveries`;
this.selectedLocation = undefined;
if (this.history.location.pathname !== path) {
this.history.push(path, {});
}
} else if (newAddress != null && newAddress !== oldAddress) {
const path = `/${ownPathFragment}/${newAddress}`;
const path = `/deliveries/${newAddress.replace(/\s/g, "+")}`;
if (this.history.location.pathname !== path) {
this.history.push(path, {});
}
Expand All @@ -213,9 +187,9 @@ export class PageDeliveries {
@Watch("mapCenterPoint")
public mapCenterPointChanged(coords?: { lat: number; lng: number }) {
if (coords?.lat === UiGeoMap.US_CENTER.lat) {
this.mapZoom = DEFAULT_ZOOM;
this.mapZoom = UiGeoMap.DEFAULT_ZOOM;
} else {
this.mapZoom = SELECTED_LOCATION_ZOOM;
this.mapZoom = UiGeoMap.SELECTED_LOCATION_ZOOM;
}
scrollPageToTop();
}
Expand Down Expand Up @@ -319,15 +293,14 @@ export class PageDeliveries {
</Fragment>
)}
<FoodChoices selected={selectedFood} onSelected={x => (this.selectedFood = x)} />
<hr class="heavy" />
<div class="now-feeding">Now feeding{nowFeeding || " American voters"}</div>
<div id="deliveries-map-container" class={{ "is-single-location": selectedAddress != null }}>
<ui-geo-map
center={mapCenterPoint}
zoom={mapZoom}
currentAddress={selectedAddress}
deliveries={
selectedFood === FoodChoice.all || selectedFood === FoodChoice.pizza
? this.recentOrders?.slice(0, 30).map(x => ({
? this.recentOrders?.slice(0, 100).map(x => ({
coords: {
lat: parseFloat(x.location.lat),
lng: parseFloat(x.location.lng),
Expand All @@ -338,7 +311,7 @@ export class PageDeliveries {
}
trucks={
selectedFood === FoodChoice.all || selectedFood === FoodChoice.trucks
? this.recentTrucks?.slice(0, 20).map(x => ({
? this.recentTrucks?.slice(0, 50).map(x => ({
coords: {
lat: parseFloat(x.location.lat),
lng: parseFloat(x.location.lng),
Expand All @@ -365,14 +338,14 @@ export class PageDeliveries {

<ui-card>
<div>
<h3>Current Deliveries</h3>
<h3>Recent Deliveries</h3>
{selectedLocation != null && selectedFood === FoodChoice.trucks && locationItems.length < 1 ? (
<p>
There are no food trucks currently at this location.
<br />
<ReportLink />
</p>
) : selectedLocation != null && ((selectedFood === FoodChoice.pizza && locationItems.length < 1) || selectedLocation.notFound === true) ? (
) : selectedLocation != null && (locationItems.length < 1 || selectedLocation.notFound === true) ? (
<p>
There are no reports of lines at this location.
<br />
Expand Down Expand Up @@ -433,9 +406,7 @@ export class PageDeliveries {
<div>
<h3>{selectedOrder!.pizzas} Pizzas</h3>
<p>
<strong>
{formatDate(selectedOrder!.createdAt)}, {formatTime(selectedOrder!.createdAt)}
</strong>
<strong>{formatDateTime(selectedOrder!.createdAt)}</strong>
</p>
<p>From {selectedOrder!.restaurant}</p>
<ul>
Expand Down Expand Up @@ -470,8 +441,9 @@ export class PageDeliveries {
};
}

private setAddressFromUrl(match: MatchResults) {
const location = match.params.location;
private async setAddressFromUrl(match: MatchResults) {
const location = match.params?.location?.replace(/\+/g, " ");

if (location !== this.selectedAddress) {
this.selectedAddress = location;
// TODO: Lookup address lat/lng from selectedAddress
Expand Down
28 changes: 13 additions & 15 deletions src/components/page-home/Deliveries.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import { h } from "@stencil/core";

import { OrderDetails } from "../../api";
import { locationURL } from "../../util";
import { formatDateTime } from "../../util";

const capitalize = (word: string): String => `${word.slice(0, 1).toUpperCase()}${word.slice(1, word.length)}`;

const formatDate = (date: Date): String => {
const day = date.getDate();
const month = date.getMonth() + 1;
const hours = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
const minutes = date.getMinutes();
const meridian = date.getHours() > 12 ? "pm" : "am";

return `${day}/${month} ${hours}:${minutes} ${meridian}`;
};

const Delivery = ({ order }: { order: OrderDetails }) => (
<div class="delivery">
<h5>
<h5 class="has-text-black">
{order.quantity} {capitalize(order.orderType)}
</h5>
<span class="time">{formatDate(order.createdAt)}</span>
<span class="time">{formatDateTime(order.createdAt)}</span>
<p>
{order.location.address} in
<br />
{order.location.city}, {order.location.state}
<stencil-route-link url={locationURL(order.location)}>
{order.location.address} in
<br />
{order.location.city}, {order.location.state}
</stencil-route-link>
</p>
</div>
);
Expand All @@ -36,6 +30,10 @@ const Deliveries = ({ orders }: { orders?: OrderDetails[] }) => (
<Delivery order={order} />
))}
</div>
<hr />
<stencil-route-link url="/activity" class="has-text-blue">
See more deliveries
</stencil-route-link>
</div>
);

Expand Down
7 changes: 5 additions & 2 deletions src/components/page-home/page-home.scss
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ page-home {

.deliveries-wrapper {
overflow-y: scroll;
height: 100%;
height: 93%;
}

@media ($under-tweet) {
Expand All @@ -250,7 +250,6 @@ page-home {
border-bottom: 1px solid $gray2;
margin: 10px 0;
padding: 4px 0;

h5 {
margin: 0;
line-height: 0.5rem;
Expand All @@ -263,6 +262,10 @@ page-home {
p {
color: $gray4;
font-size: 0.75rem;
font-weight: normal;
a {
color: $gray4;
}
}
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/components/page-home/page-home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Build, Component, h, Prop, State } from "@stencil/core";
import { Component, h, Prop, State } from "@stencil/core";
import { RouterHistory } from "@stencil/router";

import { OrderDetails, PizzaApi, PizzaTotals } from "../../api";
Expand All @@ -20,10 +20,8 @@ export class PageHome {
public async componentWillLoad() {
document.title = `Home | Pizza to the Polls`;

if (Build.isBrowser) {
PizzaApi.getTotals().then(totals => (this.totals = totals));
PizzaApi.getOrders(0, 20).then(({ results }) => (this.orders = results));
}
PizzaApi.getTotals().then(totals => (this.totals = totals));
PizzaApi.getOrders(0, 20).then(({ results }) => (this.orders = results));
}

public render() {
Expand Down
Loading

0 comments on commit 22e4a4a

Please sign in to comment.