From 643ecb76db824b2ad09b4e19368cface377019a5 Mon Sep 17 00:00:00 2001 From: Aaron Po Date: Thu, 27 Aug 2026 00:23:27 -0400 Subject: [PATCH] Move full brewery list to /breweries/directory, add nearby resource route --- .../breweries/routes/breweries-nearby.tsx | 21 +++++++++++++++++++ .../{breweries.tsx => brewery-directory.tsx} | 19 ++++++++++++----- web/frontend/app/routes.ts | 2 ++ 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 web/frontend/app/features/breweries/routes/breweries-nearby.tsx rename web/frontend/app/features/breweries/routes/{breweries.tsx => brewery-directory.tsx} (86%) diff --git a/web/frontend/app/features/breweries/routes/breweries-nearby.tsx b/web/frontend/app/features/breweries/routes/breweries-nearby.tsx new file mode 100644 index 00000000..ba5abcae --- /dev/null +++ b/web/frontend/app/features/breweries/routes/breweries-nearby.tsx @@ -0,0 +1,21 @@ +import { data } from 'react-router'; +import { getBreweryLocationsNearby } from '../breweries.server'; +import type { Route } from './+types/breweries-nearby'; + +export const loader = async ({ request }: Route.LoaderArgs) => { + const url = new URL(request.url); + const latitude = Number(url.searchParams.get('latitude')); + const longitude = Number(url.searchParams.get('longitude')); + const rangeInMetres = Number(url.searchParams.get('rangeInMetres')); + + if ( + !Number.isFinite(latitude) || + !Number.isFinite(longitude) || + !Number.isFinite(rangeInMetres) + ) { + throw data('latitude, longitude, and rangeInMetres are required.', { status: 400 }); + } + + const breweries = await getBreweryLocationsNearby(latitude, longitude, rangeInMetres); + return { breweries }; +}; diff --git a/web/frontend/app/features/breweries/routes/breweries.tsx b/web/frontend/app/features/breweries/routes/brewery-directory.tsx similarity index 86% rename from web/frontend/app/features/breweries/routes/breweries.tsx rename to web/frontend/app/features/breweries/routes/brewery-directory.tsx index 77c4c44a..09ce94e2 100644 --- a/web/frontend/app/features/breweries/routes/breweries.tsx +++ b/web/frontend/app/features/breweries/routes/brewery-directory.tsx @@ -1,8 +1,9 @@ +import { Link } from 'react-router'; import RouteErrorState from '../../../components/ui/error/RouteErrorState'; import ClientOnly from '../../../components/ClientOnly'; import BreweryCard from '../components/BreweryCard'; import { getBreweries, getBreweryLocations, type SimplifiedBrewery } from '../breweries.server'; -import type { Route } from './+types/breweries'; +import type { Route } from './+types/brewery-directory'; import { lazy, Suspense, useEffect, useRef, useState } from 'react'; import { useFetcher } from 'react-router'; import type { BreweryMapPin } from '../components/BreweryMap'; @@ -11,7 +12,7 @@ const PAGE_SIZE = 12; const MAP_PLACEHOLDER_CLASS = 'h-[28rem] md:h-[34rem] w-full rounded-box bg-base-300'; export const meta = ({}: Route.MetaArgs) => { - return [{ title: 'Breweries | The Biergarten App' }]; + return [{ title: 'Brewery Directory | The Biergarten App' }]; }; export const loader = async ({ request }: Route.LoaderArgs) => { @@ -59,7 +60,7 @@ const Breweries = ({ loaderData }: Route.ComponentProps) => { const observer = new IntersectionObserver((entries) => { if (entries[0]?.isIntersecting && fetcher.state === 'idle') { - fetcher.load(`/breweries?limit=${PAGE_SIZE}&offset=${offset}`); + fetcher.load(`/breweries/directory?limit=${PAGE_SIZE}&offset=${offset}`); } }); @@ -72,8 +73,16 @@ const Breweries = ({ loaderData }: Route.ComponentProps) => { return (
-

Breweries

-

Discover our partner breweries.

+ + ← Back to Breweries + +

Full brewery directory

+

+ All of our partner breweries, newest first. +

}> {() => ( diff --git a/web/frontend/app/routes.ts b/web/frontend/app/routes.ts index 2c67c679..8465e019 100644 --- a/web/frontend/app/routes.ts +++ b/web/frontend/app/routes.ts @@ -11,6 +11,8 @@ export default [ route('confirm', 'features/auth/routes/confirm.tsx'), route('beers', 'features/catalog/routes/beers.tsx'), route('breweries', 'features/breweries/routes/breweries.tsx'), + route('breweries/directory', 'features/breweries/routes/brewery-directory.tsx'), + route('breweries/nearby', 'features/breweries/routes/breweries-nearby.tsx'), route('breweries/:id', 'features/breweries/routes/brewery-detail.tsx'), route('beer-styles', 'features/catalog/routes/beer-styles.tsx'), ] satisfies RouteConfig;