diff --git a/bun.lockb b/bun.lockb index d558f09..4992cd4 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/src/routes/places/index.tsx b/src/routes/places/index.tsx index 0565be5..d78acbe 100644 --- a/src/routes/places/index.tsx +++ b/src/routes/places/index.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { FeaturedPlace, Place } from "@/types/places"; +import { Place } from "@/types/places"; import "mapbox-gl/dist/mapbox-gl.css"; import Map, { MapRef, PointLike, Source } from "react-map-gl"; import Layer from "react-map-gl/dist/esm/components/layer"; @@ -27,7 +27,7 @@ export async function loader({ request }: LoaderFunctionArgs) { const [responsePlaces, responseTopDestinations] = await Promise.all([ api<responsePlaces>(`places?search=${keyword ?? ""}`), - api<{ data: Array<FeaturedPlace> }>("/places/featured"), + api<responsePlaces>("/places/featured"), ]); return { @@ -38,7 +38,7 @@ export async function loader({ request }: LoaderFunctionArgs) { } export function PlacesIndexRoute() { - const { places, keyword } = useLoaderData() as Awaited< + const { places, keyword, topDestinations } = useLoaderData() as Awaited< ReturnType<typeof loader> >; @@ -150,7 +150,11 @@ export function PlacesIndexRoute() { <aside className="w-[720px] h-screen flex flex-col"> <PlacesSidebarHeader /> <div className="p-6 h-[85%]"> - <PlaceDetailPlaceholder places={places} keyword={keyword} /> + <PlaceDetailPlaceholder + places={places} + keyword={keyword} + topDestinations={topDestinations} + /> </div> </aside> @@ -214,46 +218,60 @@ function PlacesSidebarHeader() { function PlaceDetailPlaceholder({ places, keyword, + topDestinations, }: { places: Place[]; keyword: string; + topDestinations: Place[]; }) { + const placeList = keyword !== "" ? places : topDestinations; + return ( <div className="h-[100%]"> - <p className="font-medium text-xl mb-6">Show result of "{keyword}"</p> + <p className="font-medium text-xl mb-6"> + {keyword !== "" ? `Show result of "${keyword}"` : "Top destinations:"} + </p> <ScrollArea className="h-[100%]"> - {places.map((place, index) => ( + {placeList.map((place, index) => ( <div className="flex flex-row gap-4 mb-4 min-h-[145px] w-full" key={index} > - <img - className="object-cover rounded-lg w-[198px] h-[145px]" - src={place.imageUrl} - alt={place.title} - /> + <Link to={`/places/${place.slug}`}> + <img + className="object-cover rounded-lg w-[198px] h-[145px]" + src={place.imageUrl} + alt={place.title} + /> + </Link> <div className="flex flex-col gap-2 flex-1 overflow-hidden"> - <p className="text-xl font-bold">{place.title}</p> + <Link + to={`/places/${place.slug}`} + className="text-xl font-bold hover:underline" + > + {place.title} + </Link> <div className="flex flex-row gap-4 "> {place.categories.map((category, index) => ( - <div + <Link + to={`/places?q=${category.name}`} key={index} - className="px-[10px] py-[5px] bg-blue-200 rounded-3xl" + className="px-[10px] py-[5px] bg-blue-200 rounded-3xl hover:bg-blue-300" > <p className="font-bold text-xs text-blue-600"> {category.name} </p> - </div> + </Link> ))} </div> - <p className="text-sm font-medium text-gray-500 truncate text-ellipsis"> + <p className="text-sm font-medium text-gray-500 truncate text-ellipsis max-w-[390px]"> {place.description} </p> - <p className="text-sm font-medium text-gray-500 truncate text-ellipsis"> + <p className="text-sm font-medium text-gray-500 truncate text-ellipsis max-w-[390px]"> {place.address} </p> </div>