11"use client" ;
22
33import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
4- import { addToUsersFavorites , deleteFromUsersFavorites } from "@/lib/actions" ;
4+ import { addToUsersFavorites , deleteFromUsersFavorites , getListing } from "@/lib/actions" ;
5+ import { queryKeys } from "@/lib/queryKeys" ;
56import { Heart , Share } from "lucide-react" ;
67import { Item , Sublet } from "@/lib/types" ;
78import { ListingActions } from "@/components/listings/detail/ListingActions" ;
@@ -12,42 +13,40 @@ import { BackButton } from "@/components/listings/detail/BackButton";
1213import { SubletMap } from "@/components/listings/detail/SubletMap" ;
1314
1415interface Props {
15- listing : Item | Sublet ;
16- initialIsFavorited : boolean ;
16+ listingId : number ;
1717}
1818
19- export const ListingDetail = ( { listing, initialIsFavorited } : Props ) => {
20- const listingType = listing . listing_type ;
21- const priceLabel = listingType === "sublet" ? "/mo" : undefined ;
22- const listingOwnerLabel = listingType === "item" ? "Seller" : "Owner" ;
19+ export const ListingDetail = ( { listingId } : Props ) => {
2320 const queryClient = useQueryClient ( ) ;
24- const favoritesQuery = useQuery ( {
25- queryKey : [ "favorite" , listing . id ] ,
26- queryFn : async ( ) => initialIsFavorited ,
27- initialData : initialIsFavorited ,
28- staleTime : Infinity ,
21+ const queryKey = queryKeys . listing ( listingId ) ;
22+
23+ const { data : listing } = useQuery ( {
24+ queryKey ,
25+ queryFn : ( ) => getListing ( String ( listingId ) ) ,
2926 } ) ;
3027
31- const isFavorited = favoritesQuery . data ?? false ;
28+ const isFavorited = listing ?. is_favorited ?? false ;
3229
3330 const toggleFavoriteMutation = useMutation ( {
3431 meta : { suppressErrorToast : true } , // since it's noisy to show error toast on top of optimistic update
3532 mutationFn : async ( shouldFavorite : boolean ) => {
3633 if ( shouldFavorite ) {
37- await addToUsersFavorites ( listing . id ) ;
34+ await addToUsersFavorites ( listingId ) ;
3835 } else {
39- await deleteFromUsersFavorites ( listing . id ) ;
36+ await deleteFromUsersFavorites ( listingId ) ;
4037 }
4138 } ,
4239 onMutate : async ( shouldFavorite : boolean ) => {
43- await queryClient . cancelQueries ( { queryKey : [ "favorite" , listing . id ] } ) ;
44- const previous = queryClient . getQueryData < boolean > ( [ "favorite" , listing . id ] ) ;
45- queryClient . setQueryData ( [ "favorite" , listing . id ] , shouldFavorite ) ;
40+ await queryClient . cancelQueries ( { queryKey } ) ;
41+ const previous = queryClient . getQueryData < Item | Sublet > ( queryKey ) ;
42+ if ( previous ) {
43+ queryClient . setQueryData ( queryKey , { ...previous , is_favorited : shouldFavorite } ) ;
44+ }
4645 return { previous } ;
4746 } ,
4847 onError : ( _error , _shouldFavorite , context ) => {
49- if ( context ?. previous !== undefined ) {
50- queryClient . setQueryData ( [ "favorite" , listing . id ] , context . previous ) ;
48+ if ( context ?. previous ) {
49+ queryClient . setQueryData ( queryKey , context . previous ) ;
5150 }
5251 } ,
5352 } ) ;
@@ -56,10 +55,14 @@ export const ListingDetail = ({ listing, initialIsFavorited }: Props) => {
5655 toggleFavoriteMutation . mutate ( ! isFavorited ) ;
5756 } ;
5857
59- const subletCoords =
60- listingType === "sublet" ? listing . additional_data : null ;
61- const hasLocation =
62- subletCoords ?. latitude != null && subletCoords ?. longitude != null ;
58+ if ( ! listing ) return null ;
59+
60+ const listingType = listing . listing_type ;
61+ const priceLabel = listingType === "sublet" ? "/mo" : undefined ;
62+ const listingOwnerLabel = listingType === "item" ? "Seller" : "Owner" ;
63+
64+ const subletCoords = listingType === "sublet" ? listing . additional_data : null ;
65+ const hasLocation = subletCoords ?. latitude != null && subletCoords ?. longitude != null ;
6366
6467 return (
6568 < div className = "mx-auto flex w-full max-w-[96rem] flex-col p-8 px-4 sm:px-12" >
@@ -94,13 +97,11 @@ export const ListingDetail = ({ listing, initialIsFavorited }: Props) => {
9497 < div >
9598 < h2 className = "text-lg font-semibold" > { "Where you'll be living" } </ h2 >
9699 < p className = "text-sm text-gray-500" >
97- Approximate location shown. The exact location will be shared once you connect with the owner.
100+ Approximate location shown. The exact location will be shared once you connect
101+ with the owner.
98102 </ p >
99- </ div >
100- < SubletMap
101- latitude = { subletCoords . latitude ! }
102- longitude = { subletCoords . longitude ! }
103- />
103+ </ div >
104+ < SubletMap latitude = { subletCoords . latitude ! } longitude = { subletCoords . longitude ! } />
104105 </ div >
105106 ) }
106107 < ListingActions
0 commit comments