Skip to content

Commit 9fe4516

Browse files
committed
Fix search in examples and guides
1 parent 0816771 commit 9fe4516

File tree

3 files changed

+85
-126
lines changed

3 files changed

+85
-126
lines changed

src/components/Examples/index.tsx

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ export default function Examples(props: {
3232
const [productFilter, setProductFilter] = useState<string[]>([]);
3333
const [platformFilter, setPlatformFilter] = useState<string[]>([]);
3434
const [blockchainFilter, setBlockchainFilter] = useState<string[]>([]);
35-
const [tagFilteredExampleMap, setTagFilteredExampleMap] =
36-
useState<ExamplesInterface[]>(sortedExamples);
37-
const [searchFilteredExampleMap, setSearchFilteredExampleMap] =
38-
useState<ExamplesInterface[]>(tagFilteredExampleMap);
35+
const [filteredExamples, setFilteredExamples] = useState<ExamplesInterface[]>(sortedExamples);
3936

4037
const chevron = (
4138
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -49,24 +46,27 @@ export default function Examples(props: {
4946
</svg>
5047
);
5148

49+
// Apply tag filters first
5250
useEffect(() => {
53-
function filterByTags() {
54-
let examples;
55-
examples = sortedExamples;
56-
examples = examples.filter((item) => {
51+
let filtered = sortedExamples;
52+
53+
if (productFilter.length > 0 || platformFilter.length > 0 || blockchainFilter.length > 0) {
54+
filtered = sortedExamples.filter((item) => {
5755
const prodFil =
5856
productFilter.length === 0 || productFilter.some((tag) => item.tags.includes(tag));
5957
const platFil =
6058
platformFilter.length === 0 || platformFilter.some((tag) => item.tags.includes(tag));
6159
const blockFil =
6260
blockchainFilter.length === 0 || blockchainFilter.some((tag) => item.tags.includes(tag));
6361

64-
return [prodFil, platFil, blockFil].some((result) => result === true);
62+
return prodFil && platFil && blockFil;
6563
});
66-
setTagFilteredExampleMap(examples);
6764
}
68-
filterByTags();
69-
}, [productFilter, platformFilter, blockchainFilter, searchFilteredExampleMap]);
65+
66+
// Reset search when filters change
67+
setSearchInput("");
68+
setFilteredExamples(filtered);
69+
}, [productFilter, platformFilter, blockchainFilter]);
7070

7171
const onChangeProduct = (e) => {
7272
const filterValue = e.map((item) => item.value);
@@ -83,55 +83,42 @@ export default function Examples(props: {
8383
const onChangeBlockchain = (e) => {
8484
const filterValue = e.map((item) => item.value);
8585
setBlockchainFilter(filterValue);
86-
setTags([...productFilter, ...filterValue, ...platformFilter]);
86+
setTags([...productFilter, ...platformFilter, ...filterValue]);
8787
};
8888

8989
function highlightSearchText(text) {
90-
if (searchInput === "") {
90+
if (!searchInput.trim()) {
9191
return text;
9292
}
93-
let inputKeywords = searchInput.split(" ");
94-
inputKeywords = inputKeywords.filter((keyword) => keyword !== "");
95-
const keywords = inputKeywords
96-
.map((keyword) => {
97-
return `(${keyword})`;
98-
})
99-
.join("|");
100-
const regex = new RegExp(keywords, "gi");
101-
const matches = text.match(regex);
93+
const searchTerms = searchInput.trim().split(/\s+/);
94+
const regex = new RegExp(`(${searchTerms.join("|")})`, "gi");
10295
const parts = text.split(regex);
103-
if (matches) {
104-
return (
105-
<span>
106-
{parts.filter(String).map((part, i) => {
107-
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
108-
})}
109-
</span>
110-
);
111-
}
112-
return text;
96+
97+
return (
98+
<span>
99+
{parts.map((part, i) => {
100+
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
101+
})}
102+
</span>
103+
);
113104
}
114105

115106
function onChangeSearch(input) {
116107
setSearchInput(input);
108+
}
117109

118-
const inputKeywords = input.trim().split(" ").filter(Boolean);
110+
// Filter the already filtered examples based on search
111+
const displayedExamples = filteredExamples.filter((item) => {
112+
if (!searchInput.trim()) return true;
119113

120-
function searchFilter(item) {
121-
return (
122-
inputKeywords.some((key) => item.title.toLowerCase().includes(key.toLowerCase())) ||
123-
inputKeywords.some((key) => item.description.toLowerCase().includes(key.toLowerCase())) ||
124-
inputKeywords.some((key) =>
125-
item.tags.map((tag) => tag.toLowerCase().includes(key.toLowerCase())),
126-
)
127-
);
128-
}
129-
let examples = tagFilteredExampleMap;
130-
if (input !== "") {
131-
examples = tagFilteredExampleMap.filter((item) => searchFilter(item));
132-
}
133-
setSearchFilteredExampleMap(examples);
134-
}
114+
const searchTerms = searchInput.toLowerCase().trim().split(/\s+/);
115+
return searchTerms.every(
116+
(term) =>
117+
item.title.toLowerCase().includes(term) ||
118+
item.description.toLowerCase().includes(term) ||
119+
item.tags.some((tag) => tag.toLowerCase().includes(term)),
120+
);
121+
});
135122

136123
function renderArticle(article) {
137124
return (
@@ -165,7 +152,7 @@ export default function Examples(props: {
165152
<div className={styles.tagContainer}>
166153
{article.tags &&
167154
article.tags.map((tag) => {
168-
if (tags.includes(tag) || searchInput.split(" ").includes(tag)) {
155+
if (tags.includes(tag) || searchInput.split(/\s+/).includes(tag)) {
169156
return (
170157
<div key={tag} className={styles.tagActive}>
171158
{tag}
@@ -177,7 +164,7 @@ export default function Examples(props: {
177164

178165
{article.tags &&
179166
article.tags.map((tag) => {
180-
if (!(tags.includes(tag) || searchInput.split(" ").includes(tag))) {
167+
if (!(tags.includes(tag) || searchInput.split(/\s+/).includes(tag))) {
181168
return (
182169
<div key={tag} className={styles.tag}>
183170
{tag}
@@ -212,7 +199,7 @@ export default function Examples(props: {
212199
</svg>
213200
</div>
214201
<input
215-
placeholder="Quick search for anything"
202+
placeholder="Search within filtered results"
216203
value={searchInput}
217204
onChange={(event) => onChangeSearch(event.target.value)}
218205
type="text"
@@ -271,8 +258,8 @@ export default function Examples(props: {
271258
)}
272259
</div>
273260
<div className={styles.container}>
274-
{tagFilteredExampleMap.map((item) => renderArticle(item))}
275-
{tagFilteredExampleMap.length === 0 && (
261+
{displayedExamples.map((item) => renderArticle(item))}
262+
{displayedExamples.length === 0 && (
276263
<div className={styles.noResults}>
277264
<p>No Results Found</p>
278265
</div>

src/components/ProductCards/index.tsx

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -383,15 +383,12 @@ export default function QuickNavigation() {
383383
<span className={styles.pill}>Demo{chevron}</span>
384384
</a>
385385
<a
386-
href={`${baseUrl}quick-start?product=PNP&sdk=PNP_MODAL&framework=REACT&stepIndex=0`}
386+
href={`${baseUrl}quick-start?product=PNP&sdk=PNP_MODAL`}
387387
className={styles.pillContainer}
388388
>
389389
<span className={styles.pill}>Quick Start{chevron}</span>
390390
</a>
391-
<a
392-
href={`${baseUrl}examples?product=Plug+and+Play&sdk=Plug+and+Play+Web+Modal+SDK`}
393-
className={styles.pillContainer}
394-
>
391+
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
395392
<span className={styles.pill}>Examples{chevron}</span>
396393
</a>
397394
</div>
@@ -445,15 +442,12 @@ export default function QuickNavigation() {
445442
<span className={styles.pill}>Demo{chevron}</span>
446443
</a>
447444
<a
448-
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=SFA_WEB&framework=REACT&stepIndex=0`}
445+
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=SFA_WEB`}
449446
className={styles.pillContainer}
450447
>
451448
<span className={styles.pill}>Quick Start{chevron}</span>
452449
</a>
453-
<a
454-
href={`${baseUrl}examples?product=Core+Kit&sdk=Single+Factor+Auth+JS+SDK`}
455-
className={styles.pillContainer}
456-
>
450+
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
457451
<span className={styles.pill}>Examples{chevron}</span>
458452
</a>
459453
<a href={`https://t.me/w3a_tg_mini_app_bot/`} className={styles.pillContainer}>
@@ -498,15 +492,12 @@ export default function QuickNavigation() {
498492
{mpcIcons}
499493
<div className={styles.links}>
500494
<a
501-
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=MPC_CORE_KIT&framework=REACT&stepIndex=0`}
495+
href={`${baseUrl}quick-start?product=MPC_CORE_KIT&sdk=MPC_CORE_KIT_WEB`}
502496
className={styles.pillContainer}
503497
>
504498
<span className={styles.pill}>Quick Start{chevron}</span>
505499
</a>
506-
<a
507-
href={`${baseUrl}examples?product=Core+Kit&sdk=Single+Factor+Auth+JS+SDK`}
508-
className={styles.pillContainer}
509-
>
500+
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
510501
<span className={styles.pill}>Examples{chevron}</span>
511502
</a>
512503
</div>

src/pages/guides/index.tsx

Lines changed: 38 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import Layout from "@theme/Layout";
99
import { GuidesInterface, platformMap, productMap } from "../../common/maps";
1010

1111
import Select, { StylesConfig } from "react-select";
12-
// import { request } from "graphql-request";
1312
import { useState, useEffect } from "react";
1413
import SEO from "../../components/SEO";
1514
import styles from "./styles.module.css";
@@ -21,45 +20,40 @@ export default function Guides({ content }: GuidesInterface) {
2120
return {};
2221
})
2322
.sort((a: any, b: any) => {
24-
//if pinned == 1, the is the first
2523
if (a.pinned && !b.pinned) return -1;
2624
if (!a.pinned && b.pinned) return 1;
27-
// Convert date strings to Date objects for comparison
2825
const aDate = new Date(a.date);
2926
const bDate = new Date(b.date);
30-
31-
// If dates are equal, or as a fallback, sort by 'order' if needed
3227
return +bDate - +aDate;
3328
});
29+
3430
const [searchInput, setSearchInput] = useState<string>("");
3531
const [tags, setTags] = useState<string[]>([]);
3632
const [productFilter, setProductFilter] = useState<string[]>([]);
3733
const [platformFilter, setPlatformFilter] = useState<string[]>([]);
38-
const [tagFilteredGuides, setTagFilteredGuides] = useState(completeGuides);
39-
const [searchFilteredGuides, setSearchFilteredGuides] = useState(tagFilteredGuides);
34+
const [filteredGuides, setFilteredGuides] = useState(completeGuides);
4035
const { siteConfig } = useDocusaurusContext();
4136
const { baseUrl } = siteConfig;
4237

38+
// Apply tag filters first
4339
useEffect(() => {
44-
function filterByTags() {
45-
let guides;
46-
guides = completeGuides;
47-
console.log("productFilter", productFilter);
48-
console.log("platformFilter", platformFilter);
49-
console.log("tags", tags);
50-
guides = guides.filter((item) => {
40+
let filtered = completeGuides;
41+
42+
if (productFilter.length > 0 || platformFilter.length > 0) {
43+
filtered = completeGuides.filter((item) => {
5144
const prodFil =
5245
productFilter.length === 0 || productFilter.some((tag) => item.tags.includes(tag));
5346
const platFil =
5447
platformFilter.length === 0 || platformFilter.some((tag) => item.tags.includes(tag));
5548

56-
return [prodFil, platFil].some((result) => result === true);
49+
return prodFil && platFil;
5750
});
58-
59-
setTagFilteredGuides(guides.sort((a: any, b: any) => a.order - b.order));
6051
}
61-
filterByTags();
62-
}, [productFilter, platformFilter, searchFilteredGuides]);
52+
53+
// Reset search when filters change
54+
setSearchInput("");
55+
setFilteredGuides(filtered);
56+
}, [productFilter, platformFilter]);
6357

6458
const onChangeProduct = (e) => {
6559
const filterValue = e.map((item) => item.value);
@@ -74,51 +68,38 @@ export default function Guides({ content }: GuidesInterface) {
7468
};
7569

7670
function highlightSearchText(text) {
77-
if (searchInput === "") {
71+
if (!searchInput.trim()) {
7872
return text;
7973
}
80-
let inputKeywords = searchInput.split(" ");
81-
inputKeywords = inputKeywords.filter((keyword) => keyword !== "");
82-
const keywords = inputKeywords
83-
.map((keyword) => {
84-
return `(${keyword})`;
85-
})
86-
.join("|");
87-
const regex = new RegExp(keywords, "gi");
88-
const matches = text.match(regex);
74+
const searchTerms = searchInput.trim().split(/\s+/);
75+
const regex = new RegExp(`(${searchTerms.join("|")})`, "gi");
8976
const parts = text.split(regex);
90-
if (matches) {
91-
return (
92-
<span>
93-
{parts.filter(String).map((part, i) => {
94-
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
95-
})}
96-
</span>
97-
);
98-
}
99-
return text;
77+
78+
return (
79+
<span>
80+
{parts.map((part, i) => {
81+
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
82+
})}
83+
</span>
84+
);
10085
}
10186

10287
function onChangeSearch(input) {
10388
setSearchInput(input);
89+
}
10490

105-
const inputKeywords = input.trim().split(" ").filter(Boolean);
91+
// Filter the already filtered guides based on search
92+
const displayedGuides = filteredGuides.filter((item) => {
93+
if (!searchInput.trim()) return true;
10694

107-
function searchFilter(item) {
108-
return (
109-
inputKeywords.some((key) => item.title.toLowerCase().includes(key.toLowerCase())) ||
110-
inputKeywords.some((key) => item.description.toLowerCase().includes(key.toLowerCase())) ||
111-
inputKeywords.some((key) =>
112-
item.tags.some((tag) => tag.toLowerCase().includes(key.toLowerCase())),
113-
)
114-
);
115-
}
116-
let guides = tagFilteredGuides;
117-
if (input !== "") {
118-
guides = tagFilteredGuides.filter((item) => searchFilter(item));
119-
}
120-
setSearchFilteredGuides(guides);
121-
}
95+
const searchTerms = searchInput.toLowerCase().trim().split(/\s+/);
96+
return searchTerms.every(
97+
(term) =>
98+
item.title.toLowerCase().includes(term) ||
99+
item.description.toLowerCase().includes(term) ||
100+
item.tags.some((tag) => tag.toLowerCase().includes(term)),
101+
);
102+
});
122103

123104
function renderArticle(article) {
124105
return (
@@ -247,8 +228,8 @@ export default function Guides({ content }: GuidesInterface) {
247228
</header>
248229

249230
<div className={styles.container}>
250-
{tagFilteredGuides.map((item) => renderArticle(item))}
251-
{tagFilteredGuides.length === 0 && (
231+
{displayedGuides.map((item) => renderArticle(item))}
232+
{displayedGuides.length === 0 && (
252233
<div className={styles.noResults}>
253234
<p>No result</p>
254235
</div>

0 commit comments

Comments
 (0)