Skip to content

Commit 7651c98

Browse files
chore(www): improve search in partners directory (supabase#46390)
In the partner integrations directory, search and find results even while inputting sub-strings. For example find Stripe even if you just typed out "str". Current behaviour is that you need to type full words to match findings. ## Before https://github.com/user-attachments/assets/d8b0fd2e-ba50-4530-a800-dbecc49e9bc6 ## After https://github.com/user-attachments/assets/cc48a89a-5800-4e97-a29b-e020b1b29476
1 parent 498d051 commit 7651c98

2 files changed

Lines changed: 43 additions & 21 deletions

File tree

apps/www/lib/marketplaceDb.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,24 @@ export async function listPartnerSlugs(): Promise<string[]> {
101101
}
102102

103103
async function searchMarketplaceListings(search: string): Promise<Partner[] | null> {
104+
const searchTerm = search.trim()
104105
let query = marketplaceClient.from('listings').select('*').is('publish_marketplace', true)
105106

106-
if (search.trim()) {
107-
query = query.textSearch('listing_tsv', `${search.trim()}`, {
108-
type: 'websearch',
109-
config: 'english',
110-
})
107+
if (searchTerm) {
108+
const searchPattern = `%${searchTerm}%`
109+
query = query.or(
110+
`title.ilike.${searchPattern},description.ilike.${searchPattern},partner_name.ilike.${searchPattern}`
111+
)
111112
}
112113

113-
const { data } = await query
114+
const { data, error } = await query
114115

115-
return data?.map(toPartner) ?? null
116+
if (error) {
117+
console.error('Marketplace search error:', error)
118+
return null
119+
}
120+
121+
return data?.map(toPartner) ?? []
116122
}
117123

118124
/**
@@ -122,23 +128,27 @@ export async function searchPartners(search: string): Promise<Partner[] | null>
122128
if (isUseMarketplaceDb) {
123129
return searchMarketplaceListings(search)
124130
} else {
131+
const searchTerm = search.trim()
125132
let query = supabase
126133
.from('partners')
127134
.select('*')
128135
.eq('approved', true)
129136
.order('category')
130137
.order('title')
131138

132-
if (search.trim()) {
133-
query = query.textSearch('tsv', `${search.trim()}`, {
134-
type: 'websearch',
135-
config: 'english',
136-
})
139+
if (searchTerm) {
140+
const searchPattern = `%${searchTerm}%`
141+
query = query.or(`title.ilike.${searchPattern},description.ilike.${searchPattern}`)
137142
}
138143

139-
const { data: partners } = await query
144+
const { data: partners, error } = await query
145+
146+
if (error) {
147+
console.error('Partners search error:', error)
148+
return null
149+
}
140150

141-
return partners?.map(miscDbToPartner) ?? null
151+
return partners?.map(miscDbToPartner) ?? []
142152
}
143153
}
144154

apps/www/pages/partners/integrations/index.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { type Category, type Partner } from '~/types/partners'
77
import { Loader, Search } from 'lucide-react'
88
import { NextSeo } from 'next-seo'
99
import { useRouter } from 'next/router'
10-
import { useEffect, useState } from 'react'
10+
import { useEffect, useRef, useState } from 'react'
1111
import { InputGroup, InputGroupAddon, InputGroupInput } from 'ui'
1212
import { useDebounce } from 'use-debounce'
1313

@@ -51,6 +51,7 @@ function IntegrationPartnersPage(props: Props) {
5151
const [search, setSearch] = useState('')
5252
const [debouncedSearchTerm] = useDebounce(search, 300)
5353
const [isSearching, setIsSearching] = useState(false)
54+
const searchIdRef = useRef(0)
5455

5556
useEffect(() => {
5657
if (debouncedSearchTerm.trim() === '') {
@@ -60,13 +61,24 @@ function IntegrationPartnersPage(props: Props) {
6061
}
6162

6263
setIsSearching(true)
63-
searchPartners(debouncedSearchTerm).then((partners) => {
64-
if (partners) {
65-
setPartners(partners)
66-
}
64+
const currentSearchId = ++searchIdRef.current
6765

68-
setIsSearching(false)
69-
})
66+
searchPartners(debouncedSearchTerm)
67+
.then((results) => {
68+
if (currentSearchId === searchIdRef.current) {
69+
setPartners(results ?? [])
70+
}
71+
})
72+
.catch(() => {
73+
if (currentSearchId === searchIdRef.current) {
74+
setPartners([])
75+
}
76+
})
77+
.finally(() => {
78+
if (currentSearchId === searchIdRef.current) {
79+
setIsSearching(false)
80+
}
81+
})
7082
}, [debouncedSearchTerm, initialPartners])
7183

7284
return (

0 commit comments

Comments
 (0)