Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@
"searchPlaceholder": "Suchen",
"searchError": "Etwas ist schiefgelaufen. Erneut versuchen?",
"searchNoResults": "Keine Ergebnisse. Tippe weiter oder verfeinere deine Suche",
"returnToListing": "Zurück zum Eintrag",
"loadingPins": "Wird geladen…",
"didYouKnow": "Wusstest du schon?",
"steps": {
"find": {
Expand Down
2 changes: 2 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@
"searchPlaceholder": "Search",
"searchError": "Something went wrong. Try again?",
"searchNoResults": "No results. Keep typing or refine your search",
"returnToListing": "Return to listing",
"loadingPins": "Loading…",
"didYouKnow": "Did you know?",
"steps": {
"find": {
Expand Down
2 changes: 2 additions & 0 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@
"searchPlaceholder": "Buscar",
"searchError": "Algo salió mal. ¿Intentarlo de nuevo?",
"searchNoResults": "Sin resultados. Sigue escribiendo o ajusta tu búsqueda",
"returnToListing": "Volver al anuncio",
"loadingPins": "Cargando…",
"didYouKnow": "¿Sabías que?",
"steps": {
"find": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { cache } from "react";
import type { Metadata } from "next/types";

import { createClient } from "@/utils/supabase/server";
import { siteConfig } from "@/config/site";
import { generateListingMetadata } from "@/utils/listingUtils";
import MapPageClient from "@/components/MapPageClient";
import { cache } from "react";
import MapPageClient from "@/features/map";
import type { Listing } from "@/types/listing";

type MapPageSearchParams = {
listing?: string;
};

type MapPageProps = {
searchParams: Promise<MapPageSearchParams>;
};

// Fetch data only once and use across metadata and page
const getInitialData = cache(async (listingSlug) => {
const getInitialData = cache(async (listingSlug: string | undefined) => {
const supabase = await createClient();

// Get user first
const {
data: { user },
} = await supabase.auth.getUser();

// Then get listing data if slug exists
const listingResponse = listingSlug
? await supabase
.from(user ? "listings_private_data" : "listings_public_data")
Expand All @@ -24,11 +32,13 @@ const getInitialData = cache(async (listingSlug) => {

return {
user,
listing: listingResponse?.data,
listing: (listingResponse?.data ?? null) as Listing | null,
};
});

export async function generateMetadata({ searchParams }) {
export async function generateMetadata({
searchParams,
}: MapPageProps): Promise<Metadata> {
const listingSlug = (await searchParams)?.listing;

if (!listingSlug) {
Expand All @@ -42,18 +52,17 @@ export async function generateMetadata({ searchParams }) {

const { user, listing } = await getInitialData(listingSlug);

// Use shared utility to generate metadata
return generateListingMetadata(listing, user);
}

export default async function Page({ searchParams }) {
export default async function Page({ searchParams }: MapPageProps) {
const listingSlug = (await searchParams)?.listing;
const { user, listing } = await getInitialData(listingSlug);

return (
<MapPageClient
user={user}
initialListingSlug={listingSlug}
initialListingSlug={listingSlug ?? null}
initialListing={listing}
/>
);
Expand Down
1 change: 0 additions & 1 deletion src/app/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ export async function fetchListingsInView(
return [];
}

console.log(`Successfully fetched ${data?.length || 0} listings`);
return data || [];
} catch (error) {
console.error("Fatal error in fetchListingsInView:", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"use client";
import type { ReactNode } from "react";
import type { User } from "@supabase/supabase-js";
import { useDeviceContext } from "@/hooks/useDeviceContext";
import { Drawer } from "vaul";
import Button from "@/components/Button";
import ChatWindow from "@/components/ChatWindow";
import ListingCta from "@/components/ListingCta";
import { styled } from "@pigment-css/react";

import type { Listing } from "@/types/listing";

const sidebarWidth = "clamp(20rem, 30vw, 30rem)";

const StyledDrawerOverlay = styled(Drawer.Overlay)({
Expand All @@ -15,7 +19,7 @@ const StyledDrawerOverlay = styled(Drawer.Overlay)({
});

const ListingCtaContainer = styled("div")({
padding: "0 1rem", // Match padding from other parts of ListingRead
padding: "0 1rem",

"& > *": {
width: "100%",
Expand All @@ -24,17 +28,16 @@ const ListingCtaContainer = styled("div")({

const StyledDrawerContent = styled(Drawer.Content)(({ theme }) => ({
background: theme.colors.background.top,
borderRadius: `${theme.corners.base} ${theme.corners.base} 0 0`, // Match over drawer content
borderRadius: `${theme.corners.base} ${theme.corners.base} 0 0`,

overflowX: "hidden",

"&::after": {
display: "none", // Otherwise seems to include side scroll, even when overflowX hidden
display: "none",
},

marginTop: "24px",
// maxHeight: "95%",
height: "95%", // Take up full height even if the message contents aren't overflowing yet
height: "95%",
position: "fixed",
bottom: "0",
left: "0",
Expand All @@ -43,7 +46,7 @@ const StyledDrawerContent = styled(Drawer.Content)(({ theme }) => ({
flexDirection: "column",

"@media (min-width: 768px)": {
borderRadius: theme.corners.base, // Match over drawer content
borderRadius: theme.corners.base,
height: "unset",
marginTop: "unset",
top: "24px",
Expand All @@ -52,53 +55,53 @@ const StyledDrawerContent = styled(Drawer.Content)(({ theme }) => ({
left: "unset",
outline: "none",
width: sidebarWidth,
// height: "100%",
},
}));

// We need to define two different drawer components, because depending on the 'modal' prop, a different number of hooks will be rendered
// React doesn't like when we conditionally change the number of hooks. It's better to just render a separate component for each case
// Shared drawer props to reduce repetition
const getDrawerProps = ({
isNested,
isChatDrawerOpen,
setIsChatDrawerOpen,
isDesktop,
...rest
}) => ({
isNested,
direction: isDesktop ? "right" : undefined,
open: isChatDrawerOpen,
onOpenChange: setIsChatDrawerOpen,
...rest,
});

const ModalDrawer = (props) => {
const DrawerComponent = props.isNested ? Drawer.NestedRoot : Drawer.Root;
return <DrawerComponent modal={true} {...getDrawerProps(props)} />;
type ListingChatDrawerProps = {
isNested?: boolean;
user: User | null;
listing: Listing;
isChatDrawerOpen: boolean;
setIsChatDrawerOpen: (open: boolean) => void;
existingThread: unknown;
};

const NonModalDrawer = (props) => {
const DrawerComponent = props.isNested ? Drawer.NestedRoot : Drawer.Root;
return <DrawerComponent modal={false} {...getDrawerProps(props)} />;
type SharedDrawerProps = {
isNested?: boolean;
open: boolean;
onOpenChange: (open: boolean) => void;
direction?: "right";
children?: ReactNode;
};

// We need two drawer variants because `modal` changes which hooks vaul renders.
function ModalDrawer({ isNested, ...rest }: SharedDrawerProps) {
const DrawerComponent = isNested ? Drawer.NestedRoot : Drawer.Root;
return <DrawerComponent modal={true} {...rest} />;
}

function NonModalDrawer({ isNested, ...rest }: SharedDrawerProps) {
const DrawerComponent = isNested ? Drawer.NestedRoot : Drawer.Root;
return <DrawerComponent modal={false} {...rest} />;
}

export default function ListingChatDrawer({
isNested,
user,
listing,
isChatDrawerOpen,
setIsChatDrawerOpen,
existingThread,
listingDisplayName,
...props
}) {
}: ListingChatDrawerProps) {
const { isDesktop, hasTouch } = useDeviceContext();

// We can infer modal behavior based on presentation
// If it's a mobile breakpoint, always use a model
// If it's a desktop breakpoint, only use a modal if it's NOT a nested drawer
const shouldUseModal = !isDesktop || isNested === false;
// Mobile: always modal. Desktop: modal only if NOT a nested drawer.
// (`!isNested` treats an omitted prop the same as `false`.)
const shouldUseModal = !isDesktop || !isNested;

const visibility = listing.visibility ?? undefined;
const isStub = listing.is_stub ?? undefined;

const drawerContent = (
<>
Expand All @@ -108,14 +111,14 @@ export default function ListingChatDrawer({
<ListingCta
viewer="owner"
slug={listing.slug}
visibility={listing.visibility}
isStub={listing.is_stub}
visibility={visibility}
isStub={isStub}
/>
) : listing.is_stub ? (
<ListingCta
viewer="guest"
slug={listing.slug}
visibility={listing.visibility}
visibility={visibility}
isStub={true}
/>
) : (
Expand All @@ -129,8 +132,8 @@ export default function ListingChatDrawer({
<ListingCta
viewer="guest"
slug={listing.slug}
visibility={listing.visibility}
isStub={listing.is_stub}
visibility={visibility}
isStub={isStub}
/>
)}
</ListingCtaContainer>
Expand All @@ -154,10 +157,9 @@ export default function ListingChatDrawer({
return (
<DrawerComponent
isNested={isNested}
isChatDrawerOpen={isChatDrawerOpen}
setIsChatDrawerOpen={setIsChatDrawerOpen}
isDesktop={isDesktop}
{...props}
open={isChatDrawerOpen}
onOpenChange={setIsChatDrawerOpen}
direction={isDesktop ? "right" : undefined}
>
{drawerContent}
</DrawerComponent>
Expand Down
Loading
Loading