feat : add fuzzy matching for searching
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { searchItems } from "@/lib/search";
|
||||
import { SearchNotice } from "@/components/search-notice";
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { SearchIcon, UsersIcon } from "lucide-react";
|
||||
@@ -39,10 +42,10 @@ type GuideCard = {
|
||||
export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
|
||||
const [query, setQuery] = useState("");
|
||||
const presence = useVisitorPresence(null);
|
||||
const normalized = query.trim().toLowerCase();
|
||||
const filtered = guides.filter((guide) =>
|
||||
`${guide.name} ${guide.overview} ${guide.aliases.join(" ")}`.toLowerCase().includes(normalized),
|
||||
);
|
||||
const search = searchItems(guides, query,
|
||||
(guide) => `${guide.name} ${guide.overview} ${guide.aliases.join(" ")}`,
|
||||
(guide) => [guide.name, ...guide.aliases]);
|
||||
const filtered = search.items;
|
||||
return (
|
||||
<div className="flex flex-col gap-8">
|
||||
<InputGroup className="h-11 max-w-2xl">
|
||||
@@ -56,6 +59,7 @@ export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
|
||||
aria-label="ค้นหาไกด์"
|
||||
/>
|
||||
</InputGroup>
|
||||
<SearchNotice fuzzy={search.fuzzy} />
|
||||
{filtered.length ? (
|
||||
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{filtered.map((guide, index) => (
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { SearchNotice } from "@/components/search-notice";
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { ArrowUpRightIcon, SearchIcon, XIcon } from "lucide-react";
|
||||
@@ -19,7 +21,7 @@ import { rarityGradientClass } from "@/lib/catalog/rarity";
|
||||
import { isCustomTravelerKey } from "@/lib/catalog/travelers";
|
||||
import type { PublicGuide } from "@/lib/guides/queries";
|
||||
import {
|
||||
matchesTeamSearch,
|
||||
searchTeams,
|
||||
sortTeamsByDps,
|
||||
type DpsOrder,
|
||||
type TeamSearchTarget,
|
||||
@@ -379,18 +381,21 @@ export function TeamSearch({ groups }: { groups: PublicGuide["teamGroups"] }) {
|
||||
const [query, setQuery] = useState("");
|
||||
const [searchTarget, setSearchTarget] = useState<TeamSearchTarget>("all");
|
||||
const [dpsOrder, setDpsOrder] = useState<DpsOrder>(null);
|
||||
const filteredTeams = useMemo(
|
||||
() => sortTeamsByDps(teams.filter((team) => matchesTeamSearch({
|
||||
const search = useMemo(
|
||||
() => searchTeams(teams, (team) => ({
|
||||
team: [team.title],
|
||||
character: team.members.flatMap((member) => [member.character.name, ...member.character.aliases]),
|
||||
weapon: team.members.flatMap((member) => member.weapon ? [member.weapon.name, ...member.weapon.aliases] : []),
|
||||
artifact: team.members.flatMap((member) => [member.artifact, member.secondArtifact].flatMap((artifact) => artifact ? [artifact.name, ...artifact.aliases] : [])),
|
||||
}, query, searchTarget)), dpsOrder),
|
||||
[dpsOrder, query, searchTarget, teams],
|
||||
}), query, searchTarget),
|
||||
[query, searchTarget, teams],
|
||||
);
|
||||
|
||||
const filteredTeams = sortTeamsByDps(search.items, dpsOrder);
|
||||
|
||||
return (
|
||||
<div className="flex min-w-0 flex-col gap-4">
|
||||
<SearchNotice fuzzy={search.fuzzy} />
|
||||
{groups.length > 1 ? (
|
||||
<ScrollableNav ariaLabel="เลือกเงื่อนไขทีม" className="w-full min-w-0">
|
||||
<ToggleGroup aria-label="เลือกเงื่อนไขทีม" variant="outline" value={[activeCondition]} onValueChange={(values) => {
|
||||
|
||||
Reference in New Issue
Block a user