Skip to content

Commit

Permalink
Fix search in examples and guides
Browse files Browse the repository at this point in the history
  • Loading branch information
yashovardhan committed Dec 11, 2024
1 parent 0816771 commit 9fe4516
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 126 deletions.
95 changes: 41 additions & 54 deletions src/components/Examples/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ export default function Examples(props: {
const [productFilter, setProductFilter] = useState<string[]>([]);
const [platformFilter, setPlatformFilter] = useState<string[]>([]);
const [blockchainFilter, setBlockchainFilter] = useState<string[]>([]);
const [tagFilteredExampleMap, setTagFilteredExampleMap] =
useState<ExamplesInterface[]>(sortedExamples);
const [searchFilteredExampleMap, setSearchFilteredExampleMap] =
useState<ExamplesInterface[]>(tagFilteredExampleMap);
const [filteredExamples, setFilteredExamples] = useState<ExamplesInterface[]>(sortedExamples);

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

// Apply tag filters first
useEffect(() => {
function filterByTags() {
let examples;
examples = sortedExamples;
examples = examples.filter((item) => {
let filtered = sortedExamples;

if (productFilter.length > 0 || platformFilter.length > 0 || blockchainFilter.length > 0) {
filtered = sortedExamples.filter((item) => {
const prodFil =
productFilter.length === 0 || productFilter.some((tag) => item.tags.includes(tag));
const platFil =
platformFilter.length === 0 || platformFilter.some((tag) => item.tags.includes(tag));
const blockFil =
blockchainFilter.length === 0 || blockchainFilter.some((tag) => item.tags.includes(tag));

return [prodFil, platFil, blockFil].some((result) => result === true);
return prodFil && platFil && blockFil;
});
setTagFilteredExampleMap(examples);
}
filterByTags();
}, [productFilter, platformFilter, blockchainFilter, searchFilteredExampleMap]);

// Reset search when filters change
setSearchInput("");
setFilteredExamples(filtered);
}, [productFilter, platformFilter, blockchainFilter]);

const onChangeProduct = (e) => {
const filterValue = e.map((item) => item.value);
Expand All @@ -83,55 +83,42 @@ export default function Examples(props: {
const onChangeBlockchain = (e) => {
const filterValue = e.map((item) => item.value);
setBlockchainFilter(filterValue);
setTags([...productFilter, ...filterValue, ...platformFilter]);
setTags([...productFilter, ...platformFilter, ...filterValue]);
};

function highlightSearchText(text) {
if (searchInput === "") {
if (!searchInput.trim()) {
return text;
}
let inputKeywords = searchInput.split(" ");
inputKeywords = inputKeywords.filter((keyword) => keyword !== "");
const keywords = inputKeywords
.map((keyword) => {
return `(${keyword})`;
})
.join("|");
const regex = new RegExp(keywords, "gi");
const matches = text.match(regex);
const searchTerms = searchInput.trim().split(/\s+/);
const regex = new RegExp(`(${searchTerms.join("|")})`, "gi");
const parts = text.split(regex);
if (matches) {
return (
<span>
{parts.filter(String).map((part, i) => {
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
})}
</span>
);
}
return text;

return (
<span>
{parts.map((part, i) => {
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
})}
</span>
);
}

function onChangeSearch(input) {
setSearchInput(input);
}

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

function searchFilter(item) {
return (
inputKeywords.some((key) => item.title.toLowerCase().includes(key.toLowerCase())) ||
inputKeywords.some((key) => item.description.toLowerCase().includes(key.toLowerCase())) ||
inputKeywords.some((key) =>
item.tags.map((tag) => tag.toLowerCase().includes(key.toLowerCase())),
)
);
}
let examples = tagFilteredExampleMap;
if (input !== "") {
examples = tagFilteredExampleMap.filter((item) => searchFilter(item));
}
setSearchFilteredExampleMap(examples);
}
const searchTerms = searchInput.toLowerCase().trim().split(/\s+/);
return searchTerms.every(
(term) =>
item.title.toLowerCase().includes(term) ||
item.description.toLowerCase().includes(term) ||
item.tags.some((tag) => tag.toLowerCase().includes(term)),
);
});

function renderArticle(article) {
return (
Expand Down Expand Up @@ -165,7 +152,7 @@ export default function Examples(props: {
<div className={styles.tagContainer}>
{article.tags &&
article.tags.map((tag) => {
if (tags.includes(tag) || searchInput.split(" ").includes(tag)) {
if (tags.includes(tag) || searchInput.split(/\s+/).includes(tag)) {
return (
<div key={tag} className={styles.tagActive}>
{tag}
Expand All @@ -177,7 +164,7 @@ export default function Examples(props: {

{article.tags &&
article.tags.map((tag) => {
if (!(tags.includes(tag) || searchInput.split(" ").includes(tag))) {
if (!(tags.includes(tag) || searchInput.split(/\s+/).includes(tag))) {
return (
<div key={tag} className={styles.tag}>
{tag}
Expand Down Expand Up @@ -212,7 +199,7 @@ export default function Examples(props: {
</svg>
</div>
<input
placeholder="Quick search for anything"
placeholder="Search within filtered results"
value={searchInput}
onChange={(event) => onChangeSearch(event.target.value)}
type="text"
Expand Down Expand Up @@ -271,8 +258,8 @@ export default function Examples(props: {
)}
</div>
<div className={styles.container}>
{tagFilteredExampleMap.map((item) => renderArticle(item))}
{tagFilteredExampleMap.length === 0 && (
{displayedExamples.map((item) => renderArticle(item))}
{displayedExamples.length === 0 && (
<div className={styles.noResults}>
<p>No Results Found</p>
</div>
Expand Down
21 changes: 6 additions & 15 deletions src/components/ProductCards/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,12 @@ export default function QuickNavigation() {
<span className={styles.pill}>Demo{chevron}</span>
</a>
<a
href={`${baseUrl}quick-start?product=PNP&sdk=PNP_MODAL&framework=REACT&stepIndex=0`}
href={`${baseUrl}quick-start?product=PNP&sdk=PNP_MODAL`}
className={styles.pillContainer}
>
<span className={styles.pill}>Quick Start{chevron}</span>
</a>
<a
href={`${baseUrl}examples?product=Plug+and+Play&sdk=Plug+and+Play+Web+Modal+SDK`}
className={styles.pillContainer}
>
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
<span className={styles.pill}>Examples{chevron}</span>
</a>
</div>
Expand Down Expand Up @@ -445,15 +442,12 @@ export default function QuickNavigation() {
<span className={styles.pill}>Demo{chevron}</span>
</a>
<a
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=SFA_WEB&framework=REACT&stepIndex=0`}
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=SFA_WEB`}
className={styles.pillContainer}
>
<span className={styles.pill}>Quick Start{chevron}</span>
</a>
<a
href={`${baseUrl}examples?product=Core+Kit&sdk=Single+Factor+Auth+JS+SDK`}
className={styles.pillContainer}
>
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
<span className={styles.pill}>Examples{chevron}</span>
</a>
<a href={`https://t.me/w3a_tg_mini_app_bot/`} className={styles.pillContainer}>
Expand Down Expand Up @@ -498,15 +492,12 @@ export default function QuickNavigation() {
{mpcIcons}
<div className={styles.links}>
<a
href={`${baseUrl}quick-start?product=CORE_KIT&sdk=MPC_CORE_KIT&framework=REACT&stepIndex=0`}
href={`${baseUrl}quick-start?product=MPC_CORE_KIT&sdk=MPC_CORE_KIT_WEB`}
className={styles.pillContainer}
>
<span className={styles.pill}>Quick Start{chevron}</span>
</a>
<a
href={`${baseUrl}examples?product=Core+Kit&sdk=Single+Factor+Auth+JS+SDK`}
className={styles.pillContainer}
>
<a href={`${baseUrl}examples`} className={styles.pillContainer}>
<span className={styles.pill}>Examples{chevron}</span>
</a>
</div>
Expand Down
95 changes: 38 additions & 57 deletions src/pages/guides/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Layout from "@theme/Layout";
import { GuidesInterface, platformMap, productMap } from "../../common/maps";

import Select, { StylesConfig } from "react-select";
// import { request } from "graphql-request";
import { useState, useEffect } from "react";
import SEO from "../../components/SEO";
import styles from "./styles.module.css";
Expand All @@ -21,45 +20,40 @@ export default function Guides({ content }: GuidesInterface) {
return {};
})
.sort((a: any, b: any) => {
//if pinned == 1, the is the first
if (a.pinned && !b.pinned) return -1;
if (!a.pinned && b.pinned) return 1;
// Convert date strings to Date objects for comparison
const aDate = new Date(a.date);
const bDate = new Date(b.date);

// If dates are equal, or as a fallback, sort by 'order' if needed
return +bDate - +aDate;
});

const [searchInput, setSearchInput] = useState<string>("");
const [tags, setTags] = useState<string[]>([]);
const [productFilter, setProductFilter] = useState<string[]>([]);
const [platformFilter, setPlatformFilter] = useState<string[]>([]);
const [tagFilteredGuides, setTagFilteredGuides] = useState(completeGuides);
const [searchFilteredGuides, setSearchFilteredGuides] = useState(tagFilteredGuides);
const [filteredGuides, setFilteredGuides] = useState(completeGuides);
const { siteConfig } = useDocusaurusContext();
const { baseUrl } = siteConfig;

// Apply tag filters first
useEffect(() => {
function filterByTags() {
let guides;
guides = completeGuides;
console.log("productFilter", productFilter);
console.log("platformFilter", platformFilter);
console.log("tags", tags);
guides = guides.filter((item) => {
let filtered = completeGuides;

if (productFilter.length > 0 || platformFilter.length > 0) {
filtered = completeGuides.filter((item) => {
const prodFil =
productFilter.length === 0 || productFilter.some((tag) => item.tags.includes(tag));
const platFil =
platformFilter.length === 0 || platformFilter.some((tag) => item.tags.includes(tag));

return [prodFil, platFil].some((result) => result === true);
return prodFil && platFil;
});

setTagFilteredGuides(guides.sort((a: any, b: any) => a.order - b.order));
}
filterByTags();
}, [productFilter, platformFilter, searchFilteredGuides]);

// Reset search when filters change
setSearchInput("");
setFilteredGuides(filtered);
}, [productFilter, platformFilter]);

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

function highlightSearchText(text) {
if (searchInput === "") {
if (!searchInput.trim()) {
return text;
}
let inputKeywords = searchInput.split(" ");
inputKeywords = inputKeywords.filter((keyword) => keyword !== "");
const keywords = inputKeywords
.map((keyword) => {
return `(${keyword})`;
})
.join("|");
const regex = new RegExp(keywords, "gi");
const matches = text.match(regex);
const searchTerms = searchInput.trim().split(/\s+/);
const regex = new RegExp(`(${searchTerms.join("|")})`, "gi");
const parts = text.split(regex);
if (matches) {
return (
<span>
{parts.filter(String).map((part, i) => {
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
})}
</span>
);
}
return text;

return (
<span>
{parts.map((part, i) => {
return regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>;
})}
</span>
);
}

function onChangeSearch(input) {
setSearchInput(input);
}

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

function searchFilter(item) {
return (
inputKeywords.some((key) => item.title.toLowerCase().includes(key.toLowerCase())) ||
inputKeywords.some((key) => item.description.toLowerCase().includes(key.toLowerCase())) ||
inputKeywords.some((key) =>
item.tags.some((tag) => tag.toLowerCase().includes(key.toLowerCase())),
)
);
}
let guides = tagFilteredGuides;
if (input !== "") {
guides = tagFilteredGuides.filter((item) => searchFilter(item));
}
setSearchFilteredGuides(guides);
}
const searchTerms = searchInput.toLowerCase().trim().split(/\s+/);
return searchTerms.every(
(term) =>
item.title.toLowerCase().includes(term) ||
item.description.toLowerCase().includes(term) ||
item.tags.some((tag) => tag.toLowerCase().includes(term)),
);
});

function renderArticle(article) {
return (
Expand Down Expand Up @@ -247,8 +228,8 @@ export default function Guides({ content }: GuidesInterface) {
</header>

<div className={styles.container}>
{tagFilteredGuides.map((item) => renderArticle(item))}
{tagFilteredGuides.length === 0 && (
{displayedGuides.map((item) => renderArticle(item))}
{displayedGuides.length === 0 && (
<div className={styles.noResults}>
<p>No result</p>
</div>
Expand Down

0 comments on commit 9fe4516

Please sign in to comment.