Staff Início posts to /campanha/home-search with scoped word-start matches, shared readout component, and simplify hardening (messages, fetch busy, malformed response guard).
31 lines
1,016 B
TypeScript
31 lines
1,016 B
TypeScript
import { normalizeSearchPhrase } from '@/lib/wordStartFilter'
|
|
|
|
/** Lower tier = stronger name match (word-start at label start beats mid-label). */
|
|
export const homeSearchNameRelevanceTier = (
|
|
normalizedLabel: string,
|
|
normalizedQuery: string,
|
|
): number => {
|
|
if (!normalizedQuery) return 0
|
|
if (normalizedLabel.startsWith(normalizedQuery)) return 0
|
|
if (normalizedLabel.includes(` ${normalizedQuery}`)) return 1
|
|
return 2
|
|
}
|
|
|
|
export type HomeSearchNameSortable = {
|
|
normalizedName: string
|
|
votes2022: number
|
|
}
|
|
|
|
export const compareHomeSearchNameRelevance = (
|
|
left: HomeSearchNameSortable,
|
|
right: HomeSearchNameSortable,
|
|
normalizedQuery: string,
|
|
): number => {
|
|
const tierDelta =
|
|
homeSearchNameRelevanceTier(left.normalizedName, normalizedQuery) -
|
|
homeSearchNameRelevanceTier(right.normalizedName, normalizedQuery)
|
|
if (tierDelta !== 0) return tierDelta
|
|
return right.votes2022 - left.votes2022
|
|
}
|
|
|
|
export const normalizeHomeSearchName = (name: string): string => normalizeSearchPhrase(name)
|