Skip to content

Commit 03a9632

Browse files
committed
rework the search feature so that an All Snippets category is used. this is the default category for any langauge and will show all the snippets for that language.
1 parent 6193c90 commit 03a9632

File tree

8 files changed

+45
-38
lines changed

8 files changed

+45
-38
lines changed

src/components/CategoryList.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useNavigate, useSearchParams } from "react-router-dom";
33

44
import { useAppContext } from "@contexts/AppContext";
55
import { useCategories } from "@hooks/useCategories";
6+
import { defaultCategoryName } from "@utils/consts";
67
import { slugify } from "@utils/slugify";
78

89
interface CategoryListItemProps {
@@ -13,10 +14,9 @@ const CategoryListItem: FC<CategoryListItemProps> = ({ name }) => {
1314
const navigate = useNavigate();
1415
const [searchParams] = useSearchParams();
1516

16-
const { language, category, setCategory } = useAppContext();
17+
const { language, category } = useAppContext();
1718

1819
const handleSelect = () => {
19-
setCategory(name);
2020
navigate({
2121
pathname: `/${slugify(language.name)}/${slugify(name)}`,
2222
search: searchParams.toString(),
@@ -50,6 +50,7 @@ const CategoryList = () => {
5050

5151
return (
5252
<ul role="list" className="categories">
53+
<CategoryListItem name={defaultCategoryName} />
5354
{fetchedCategories.map((name, idx) => (
5455
<CategoryListItem key={idx} name={name} />
5556
))}

src/components/LanguageSelector.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { slugify } from "@utils/slugify";
1515
const LanguageSelector = () => {
1616
const navigate = useNavigate();
1717

18-
const { language, setLanguage, setCategory, setSearchText } = useAppContext();
18+
const { language, setSearchText } = useAppContext();
1919
const { fetchedLanguages, loading, error } = useLanguages();
2020

2121
const dropdownRef = useRef<HTMLDivElement>(null);
@@ -33,8 +33,6 @@ const LanguageSelector = () => {
3333
});
3434

3535
setSearchText("");
36-
setLanguage(newLanguage);
37-
setCategory(newCategory);
3836
navigate(`/${slugify(newLanguage.name)}/${slugify(newCategory)}`);
3937
setIsOpen(false);
4038
};

src/components/SnippetList.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const SnippetList = () => {
6464
<>
6565
<motion.ul role="list" className="snippets">
6666
<AnimatePresence mode="popLayout">
67-
{fetchedSnippets.map((snippet, idx) => {
67+
{fetchedSnippets.map((snippet, _idx) => {
6868
const uniqueId = `${language.name}-${snippet.title}`;
6969
return (
7070
<motion.li
@@ -75,15 +75,15 @@ const SnippetList = () => {
7575
opacity: 1,
7676
y: 0,
7777
transition: {
78-
delay: shouldReduceMotion ? 0 : 0.09 + idx * 0.05,
78+
// delay: shouldReduceMotion ? 0 : 0.09 + idx * 0.05,
7979
duration: shouldReduceMotion ? 0 : 0.2,
8080
},
8181
}}
8282
exit={{
8383
opacity: 0,
8484
y: -20,
8585
transition: {
86-
delay: idx * 0.01,
86+
// delay: idx * 0.01,
8787
duration: shouldReduceMotion ? 0 : 0.09,
8888
},
8989
}}

src/contexts/AppContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const AppProvider: FC<{ children: React.ReactNode }> = ({
3535
useEffect(() => {
3636
configure();
3737
// eslint-disable-next-line react-hooks/exhaustive-deps
38-
}, [fetchedLanguages]);
38+
}, [fetchedLanguages, languageName, categoryName]);
3939

4040
/**
4141
* Set the default language if the language is not found in the URL.

src/hooks/useSnippets.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useSearchParams } from "react-router-dom";
33

44
import { useAppContext } from "@contexts/AppContext";
55
import { CategoryType } from "@types";
6+
import { defaultCategoryName } from "@utils/consts";
67
import { QueryParams } from "@utils/enums";
78
import { slugify } from "@utils/slugify";
89

@@ -21,21 +22,26 @@ export const useSnippets = () => {
2122
return [];
2223
}
2324

24-
if (searchParams.has(QueryParams.SEARCH)) {
25-
return data
26-
.find((item) => item.name === category)
27-
?.snippets.filter((item) => {
28-
const searchTerm = (
29-
searchParams.get(QueryParams.SEARCH) || ""
30-
).toLowerCase();
31-
return (
32-
item.title.toLowerCase().includes(searchTerm) ||
33-
item.description.toLowerCase().includes(searchTerm) ||
34-
item.tags.some((tag) => tag.toLowerCase().includes(searchTerm))
35-
);
36-
});
25+
// If the category is the default category, return all snippets for the given language.
26+
const snippets =
27+
slugify(category) === slugify(defaultCategoryName)
28+
? data.flatMap((item) => item.snippets)
29+
: (data.find((item) => item.name === category)?.snippets ?? []);
30+
31+
if (!searchParams.has(QueryParams.SEARCH)) {
32+
return snippets;
3733
}
38-
return data.find((item) => item.name === category)?.snippets;
34+
35+
return snippets.filter((item) => {
36+
const searchTerm = (
37+
searchParams.get(QueryParams.SEARCH) || ""
38+
).toLowerCase();
39+
return (
40+
item.title.toLowerCase().includes(searchTerm) ||
41+
item.description.toLowerCase().includes(searchTerm) ||
42+
item.tags.some((tag) => tag.toLowerCase().includes(searchTerm))
43+
);
44+
});
3945
}, [category, data, searchParams]);
4046

4147
return { fetchedSnippets, loading, error };

src/utils/configureUserSelection.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CategoryType, LanguageType } from "@types";
22

3-
import { defaultCategory, defaultLanguage } from "./consts";
3+
import { defaultCategoryName, defaultLanguage } from "./consts";
44
import { slugify } from "./slugify";
55

66
export async function configureUserSelection({
@@ -34,14 +34,19 @@ export async function configureUserSelection({
3434
category = fetchedCategories.find(
3535
(item) => slugify(item.name) === slugifiedCategoryName
3636
);
37-
if (category === undefined && fetchedCategories.length > 0) {
38-
category = fetchedCategories[0];
39-
}
37+
4038
if (category === undefined) {
41-
category = defaultCategory;
39+
category = {
40+
name: defaultCategoryName,
41+
snippets: fetchedCategories.flatMap((item) => item.snippets),
42+
};
4243
}
4344
} catch (_error) {
44-
category = defaultCategory;
45+
// This state should not be reached in the normal flow.
46+
category = {
47+
name: defaultCategoryName,
48+
snippets: [],
49+
};
4550
}
4651

4752
return { language, category: category.name };

src/utils/consts.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ export const defaultLanguage: LanguageType = {
66
subIndexes: [],
77
};
88

9-
export const defaultCategory: CategoryType = {
10-
name: "",
11-
snippets: [],
12-
};
9+
export const defaultCategoryName: CategoryType["name"] = "All Snippets";
1310

1411
// TODO: add custom loading and error handling
1512
export const defaultState: AppState = {
1613
language: defaultLanguage,
1714
setLanguage: () => {},
18-
category: defaultCategory.name,
15+
category: defaultCategoryName,
1916
setCategory: () => {},
2017
snippet: null,
2118
setSnippet: () => {},

tests/configureUserSelection.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
22

33
import { CategoryType, LanguageType } from "../src/types";
44
import { configureUserSelection } from "../src/utils/configureUserSelection";
5-
import { defaultCategory, defaultLanguage } from "../src/utils/consts";
5+
import { defaultCategoryName, defaultLanguage } from "../src/utils/consts";
66
import { slugify } from "../src/utils/slugify";
77

88
vi.mock("../src/utils/slugify");
@@ -36,7 +36,7 @@ describe("configureUserSelection", () => {
3636

3737
expect(result).toEqual({
3838
language: defaultLanguage,
39-
category: defaultCategory.name,
39+
category: defaultCategoryName,
4040
});
4141

4242
expect(fetch).toHaveBeenCalledWith("/consolidated/_index.json");
@@ -80,7 +80,7 @@ describe("configureUserSelection", () => {
8080

8181
expect(result).toEqual({
8282
language: mockLanguages[0],
83-
category: mockCategories[0].name,
83+
category: defaultCategoryName,
8484
});
8585

8686
expect(slugify).toHaveBeenCalledWith("JavaScript");
@@ -163,7 +163,7 @@ describe("configureUserSelection", () => {
163163

164164
expect(result).toEqual({
165165
language: mockLanguages[0],
166-
category: defaultCategory.name,
166+
category: defaultCategoryName,
167167
});
168168

169169
expect(slugify).toHaveBeenCalledWith("JavaScript");

0 commit comments

Comments
 (0)