Skip to content

Commit

Permalink
componentize header and fix existing reservation page styles (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgravois authored Jun 9, 2024
1 parent 5a63962 commit a86eb18
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 230 deletions.
5 changes: 3 additions & 2 deletions app/models/reservation.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
});
}
Expand Down Expand Up @@ -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')
}

Expand All @@ -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)
Expand Down
64 changes: 64 additions & 0 deletions app/routes/Header.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<header className="header">
<div className="header_content">
<div className="header_left">
<Link to="/" className="h1">
Court dibs
</Link>
<h2 className="h2">Call dibs on one of our sportsball courts</h2>
<div className="header_illustration">
<div className="header_icon header_icon___pickleball">
<img
alt="pball"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/pickleball-solid.svg?v=1714837585684"
/>
</div>
<div className="header_icon header_icon___tennis">
<img
alt="tennis racquet"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/tennis-ball-solid.svg?v=1714837585529"
/>
</div>
<div className="header_icon header_icon___basketball">
<img
alt="bball"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/basketball-solid.svg?v=1714837585367"
/>
</div>
</div>
</div>
<div className="header_right">
{hideLoginLinks ? null : user ? (
<>
<p className="header_user">{user.email}</p>
<Form action="/logout" method="post">
<button
type="submit"
className="header_link header_link___button"
>
Sign out
</button>
</Form>
</>
) : (
<Link to="/start" className="header_link header_link___button">
Sign up or sign in
</Link>
)}
</div>
</div>
</header>
);
}
30 changes: 0 additions & 30 deletions app/routes/HeaderLeft.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion app/routes/ReservationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
29 changes: 3 additions & 26 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -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" }];
Expand All @@ -30,30 +30,7 @@ export default function Index() {

return (
<>
<header className="header">
<div className="header_content">
<HeaderLeft />
<div className="header_right">
{user ? (
<>
<p className="header_user">{user.email}</p>
<Form action="/logout" method="post">
<button
type="submit"
className="header_link header_link___button"
>
Sign out
</button>
</Form>
</>
) : (
<Link to="/start" className="header_link header_link___button">
Sign up or sign in
</Link>
)}
</div>
</div>
</header>
<Header />
<div className="wrapper">
<ReservationList
reservations={data.reservations as Rez[]}
Expand Down
9 changes: 2 additions & 7 deletions app/routes/magic.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import type { MetaFunction } from "@remix-run/node";

import { HeaderLeft } from "./HeaderLeft";
import { Header } from "./Header";

export const meta: MetaFunction = () => [{ title: "Magic" }];

export default function Magic() {
return (
<>
<header className="header">
<div className="header_content">
<HeaderLeft />
<div className="header_right"></div>
</div>
</header>
<Header hideLoginLinks />
<main className="magicLink">
<p className="magicLink_message">Check your inbox for a magic link.</p>
</main>
Expand Down
78 changes: 53 additions & 25 deletions app/routes/reservations.$reservationId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -37,38 +39,64 @@ export const action = async ({ params, request }: ActionFunctionArgs) => {
return redirect("/");
};

const courtIcon = (val: string) =>
val === "pb" ? (
<div className="existingRes_courtIcon">
<img
alt="pball"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/pickleball-solid.svg?v=1714837585684"
/>
</div>
) : val === "10s" ? (
<div className="existingRes_courtIcon">
<img
alt="tennis racquet"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/tennis-ball-solid.svg?v=1714837585529"
/>
</div>
) : (
<div className="existingRes_courtIcon">
<img
alt="bball"
src="https://cdn.glitch.global/5f00a93b-ae9c-4d9a-b9cf-472487408ff8/basketball-solid.svg?v=1714837585367"
/>
</div>
);

export default function ReservationDetailsPage() {
const data = useLoaderData<typeof loader>();
const currUser = useUser();

const { start, end, user } = data.reservation;
const { start, end, user, court, openPlay } = data.reservation;
const canDelete = currUser.id === user.id;

return (
<div>
<h3 className="text-2xl font-bold">{format(start, "iiii, MMMM dd")}</h3>
<p className="py-6">
{user.email}
<br />
{format(start, "h:mm bbb")}
&nbsp;-&nbsp;
{format(end, "h:mm bbb")}
</p>

{canDelete ? (
<>
<hr className="my-4" />
<Form method="post">
<button
type="submit"
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
>
Delete
</button>
</Form>
</>
) : null}
</div>
<>
<Header />
<div className="existingRes">
<div className="existingRes_stack">
<p className="existingRes_label">{format(start, "iiii, MMMM dd")}</p>
<p>{user.email}</p>
<p>
{format(start, "h:mm bbb")}
&nbsp;-&nbsp;
{format(end, "h:mm bbb")}
</p>
<p>{openPlay ? "Open play" : null}</p>
<p>{courtIcon(court)}</p>
{canDelete ? (
<>
<hr className="my-4" />
<Form method="post">
<button type="submit" className="newRes_button">
Delete
</button>
</Form>
</>
) : null}
</div>
</div>
</>
);
}

Expand Down
Loading

0 comments on commit a86eb18

Please sign in to comment.