diff --git a/app/models/reservation.server.ts b/app/models/reservation.server.ts
index 0fd43ec..4585ea9 100644
--- a/app/models/reservation.server.ts
+++ b/app/models/reservation.server.ts
@@ -11,7 +11,7 @@ export function getReservation({
}) {
userId;
return prisma.reservation.findFirst({
- select: { id: true, start: true, end: true, court: true, user: true },
+ select: { id: true, start: true, end: true, court: true, user: true, openPlay: true },
where: { id },
});
}
@@ -61,7 +61,7 @@ export async function createReservation({
}
// bonus: warn if after dusk
- if (compareAsc(end, addHours(startOfToday(), 20)) === 1) {
+ if (compareAsc(end, addHours(startOfDay(start), 20)) === 1) {
throw new Error('Reservations must conclude by 20:00')
}
@@ -80,6 +80,7 @@ export async function createReservation({
const sameDay = await prisma.reservation.findFirst({
where: {
userId,
+ court,
start: {
gte: startOfDay(start),
lte: addDays(startOfDay(start), 1)
diff --git a/app/routes/Header.tsx b/app/routes/Header.tsx
new file mode 100644
index 0000000..42e5925
--- /dev/null
+++ b/app/routes/Header.tsx
@@ -0,0 +1,64 @@
+import type { User } from "@prisma/client";
+import { Form, Link } from "@remix-run/react";
+
+import { useOptionalUser } from "~/utils";
+
+export function Header({
+ hideLoginLinks = false,
+}: {
+ hideLoginLinks?: boolean;
+}) {
+ const user: User | undefined = useOptionalUser();
+
+ return (
+
+
+
+
+ Court dibs
+
+
Call dibs on one of our sportsball courts
+
+
+
+ {hideLoginLinks ? null : user ? (
+ <>
+
{user.email}
+
+ >
+ ) : (
+
+ Sign up or sign in
+
+ )}
+
+
+
+ );
+}
diff --git a/app/routes/HeaderLeft.tsx b/app/routes/HeaderLeft.tsx
deleted file mode 100644
index bc7c7d9..0000000
--- a/app/routes/HeaderLeft.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Link } from "@remix-run/react";
-
-export const HeaderLeft = () => (
-
-
- Court dibs
-
-
Call dibs on one of our sportsball courts
-
-
-);
diff --git a/app/routes/ReservationList.tsx b/app/routes/ReservationList.tsx
index 765d479..c99ee45 100644
--- a/app/routes/ReservationList.tsx
+++ b/app/routes/ReservationList.tsx
@@ -24,7 +24,7 @@ export interface Rez {
openPlay: boolean;
}
-const dateToHeader = (date: Date) => {
+export const dateToHeader = (date: Date) => {
const prefix = isToday(date)
? "Today - "
: isTomorrow(date)
diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx
index a402496..40481de 100644
--- a/app/routes/_index.tsx
+++ b/app/routes/_index.tsx
@@ -1,12 +1,12 @@
import type { User } from "@prisma/client";
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
-import { Form, Link, json, useLoaderData } from "@remix-run/react";
+import { json, useLoaderData } from "@remix-run/react";
import { getReservations } from "~/models/reservation.server";
import { getSession } from "~/session.server";
import { useOptionalUser } from "~/utils";
-import { HeaderLeft } from "./HeaderLeft";
+import { Header } from "./Header";
import { ReservationList, Rez } from "./ReservationList";
export const meta: MetaFunction = () => [{ title: "Court dibs" }];
@@ -30,30 +30,7 @@ export default function Index() {
return (
<>
-
-
-
-
- {user ? (
- <>
-
{user.email}
-
- >
- ) : (
-
- Sign up or sign in
-
- )}
-
-
-
+
[{ title: "Magic" }];
export default function Magic() {
return (
<>
-
+
Check your inbox for a magic link.
diff --git a/app/routes/reservations.$reservationId.tsx b/app/routes/reservations.$reservationId.tsx
index 0a1fc22..5d44b74 100644
--- a/app/routes/reservations.$reservationId.tsx
+++ b/app/routes/reservations.$reservationId.tsx
@@ -13,6 +13,8 @@ import { deleteReservation, getReservation } from "~/models/reservation.server";
import { requireUserId } from "~/session.server";
import { useUser } from "~/utils";
+import { Header } from "./Header";
+
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const userId = await requireUserId(request);
invariant(params.reservationId, "reservationId not found");
@@ -37,38 +39,64 @@ export const action = async ({ params, request }: ActionFunctionArgs) => {
return redirect("/");
};
+const courtIcon = (val: string) =>
+ val === "pb" ? (
+
+
+
+ ) : val === "10s" ? (
+
+
+
+ ) : (
+
+
+
+ );
+
export default function ReservationDetailsPage() {
const data = useLoaderData();
const currUser = useUser();
- const { start, end, user } = data.reservation;
+ const { start, end, user, court, openPlay } = data.reservation;
const canDelete = currUser.id === user.id;
return (
-
-
{format(start, "iiii, MMMM dd")}
-
- {user.email}
-
- {format(start, "h:mm bbb")}
- -
- {format(end, "h:mm bbb")}
-
-
- {canDelete ? (
- <>
-
-
- >
- ) : null}
-
+ <>
+
+
+
+
{format(start, "iiii, MMMM dd")}
+
{user.email}
+
+ {format(start, "h:mm bbb")}
+ -
+ {format(end, "h:mm bbb")}
+
+
{openPlay ? "Open play" : null}
+
{courtIcon(court)}
+ {canDelete ? (
+ <>
+
+
+ >
+ ) : null}
+
+
+ >
);
}
diff --git a/app/routes/reservations.new.tsx b/app/routes/reservations.new.tsx
index 6749ed6..723d42d 100644
--- a/app/routes/reservations.new.tsx
+++ b/app/routes/reservations.new.tsx
@@ -2,11 +2,14 @@ import type { ActionFunctionArgs } from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import { Form, Link, useActionData, useSearchParams } from "@remix-run/react";
import { addMinutes, startOfToday } from "date-fns";
-import { useEffect, useRef } from "react";
+import { useRef } from "react";
import { createReservation } from "~/models/reservation.server";
import { requireUserId } from "~/session.server";
+import { Header } from "./Header";
+import { dateToHeader } from "./ReservationList";
+
export const action = async ({ request }: ActionFunctionArgs) => {
const userId = await requireUserId(request);
const formData = await request.formData();
@@ -66,141 +69,146 @@ export default function NewReservationPage() {
const courtRef = useRef(null);
const durationRef = useRef(null);
- useEffect(() => {
- if (actionData?.errors?.start) {
- startTimeRef.current?.focus();
- }
- }, [actionData]);
-
return (
-