mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 10:04:44 +00:00
Move full brewery list to /breweries/directory, add nearby resource route
This commit is contained in:
@@ -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 };
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import { Link } from 'react-router';
|
||||||
import RouteErrorState from '../../../components/ui/error/RouteErrorState';
|
import RouteErrorState from '../../../components/ui/error/RouteErrorState';
|
||||||
import ClientOnly from '../../../components/ClientOnly';
|
import ClientOnly from '../../../components/ClientOnly';
|
||||||
import BreweryCard from '../components/BreweryCard';
|
import BreweryCard from '../components/BreweryCard';
|
||||||
import { getBreweries, getBreweryLocations, type SimplifiedBrewery } from '../breweries.server';
|
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 { lazy, Suspense, useEffect, useRef, useState } from 'react';
|
||||||
import { useFetcher } from 'react-router';
|
import { useFetcher } from 'react-router';
|
||||||
import type { BreweryMapPin } from '../components/BreweryMap';
|
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';
|
const MAP_PLACEHOLDER_CLASS = 'h-[28rem] md:h-[34rem] w-full rounded-box bg-base-300';
|
||||||
|
|
||||||
export const meta = ({}: Route.MetaArgs) => {
|
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) => {
|
export const loader = async ({ request }: Route.LoaderArgs) => {
|
||||||
@@ -59,7 +60,7 @@ const Breweries = ({ loaderData }: Route.ComponentProps) => {
|
|||||||
|
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
if (entries[0]?.isIntersecting && fetcher.state === 'idle') {
|
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 (
|
return (
|
||||||
<div className="min-h-screen bg-base-200">
|
<div className="min-h-screen bg-base-200">
|
||||||
<div className="container mx-auto p-14">
|
<div className="container mx-auto p-14">
|
||||||
<h1 className="text-4xl font-bold mb-4">Breweries</h1>
|
<Link
|
||||||
<p className="text-base-content/70 mb-6">Discover our partner breweries.</p>
|
to="/breweries"
|
||||||
|
className="link link-hover text-sm text-base-content/60 mb-4 inline-block"
|
||||||
|
>
|
||||||
|
← Back to Breweries
|
||||||
|
</Link>
|
||||||
|
<h1 className="text-4xl font-bold mb-4">Full brewery directory</h1>
|
||||||
|
<p className="text-base-content/70 mb-6">
|
||||||
|
All of our partner breweries, newest first.
|
||||||
|
</p>
|
||||||
|
|
||||||
<ClientOnly fallback={<div className={MAP_PLACEHOLDER_CLASS} />}>
|
<ClientOnly fallback={<div className={MAP_PLACEHOLDER_CLASS} />}>
|
||||||
{() => (
|
{() => (
|
||||||
@@ -11,6 +11,8 @@ export default [
|
|||||||
route('confirm', 'features/auth/routes/confirm.tsx'),
|
route('confirm', 'features/auth/routes/confirm.tsx'),
|
||||||
route('beers', 'features/catalog/routes/beers.tsx'),
|
route('beers', 'features/catalog/routes/beers.tsx'),
|
||||||
route('breweries', 'features/breweries/routes/breweries.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('breweries/:id', 'features/breweries/routes/brewery-detail.tsx'),
|
||||||
route('beer-styles', 'features/catalog/routes/beer-styles.tsx'),
|
route('beer-styles', 'features/catalog/routes/beer-styles.tsx'),
|
||||||
] satisfies RouteConfig;
|
] satisfies RouteConfig;
|
||||||
|
|||||||
Reference in New Issue
Block a user