Skip to content

Commit 159ddd0

Browse files
authored
feat: implement dictionary browse page (#60)
This Pull Request implement the Dictionary browse page; a page intended to link to all dictionary word. It implements the "Alphabetical" word browsing logic (to start with, maybe we can categorize some more 🤔). It also implemented the alphabetic route that holds a list of words starting with the requested alphabet and pagination for this list of words. ### Changes Made - Added a new `ALPHABETS` value to `constants` which obviously carries a list of all alphabets a-z - Implemented the paginated dynamics route `[alpha]/[page]` which builds to a pagination-enabled routes for words filtered by their initial letter - Implemented the `/browse` page, which integrates the `ALPHABETS` constant to create a button that links to individual route specific to words starting with each alphabets - temporarily implemented a `browse words` link that links to the `/browse` page as fallback when no recent searches is found in localhost - I still haven't exactly figured which position to place this link to the browse page immediately yet 🤕 - Added some few new todos: - Extract the `$addToRecentSearches` logic from the `search` island to the `word.astro` layout to enable addition of words to recent searches when a word is viewed - the current set-up only allows adding words to recent searches when a word is opened through the search bar search results - Compute a means to get previous page url (maybe with `referer`) so as to integrate in Navbar return nav to allow easy return to previous page, this is particularly useful for returning user to the `/browse` page from word layout if user opened word from their - the current setup only returns a user to the homepage ### Screencast/Screenshot [screencast-bpconcjcammlapcogcnnelfmaeghhagj-2024.04.24-12_41_08.webm](https://github.com/babblebey/jargons.dev/assets/25631971/5379dad9-20e3-4e0b-a3b3-9a39a5d4d8cb) _**Alphabets with no words**_ ![image](https://github.com/babblebey/jargons.dev/assets/25631971/594a7b6e-5809-48cf-93da-6c491e64e160) 📖
2 parents 9f41a9e + 943038a commit 159ddd0

9 files changed

Lines changed: 197 additions & 5 deletions

File tree

constants.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,12 @@ export const SITE_META_KEYWORDS = [
2020
"dev dictionary",
2121
"developer dictionary",
2222
"software development dictionary",
23+
];
24+
25+
export const ALPHABETS = [
26+
"a", "b", "c", "d", "e", "f",
27+
"g", "h", "i", "j", "k", "l",
28+
"m", "n", "o", "p", "q", "r",
29+
"s", "t", "u", "v", "w", "x",
30+
"y", "z"
2331
];

src/components/islands/recent-searches.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { $recentSearches } from "../../lib/stores/search.js";
55
/**
66
* Recent Searches Component - An Island that displays a user's last 5 searches
77
*
8-
* @todo implement a default list instead of `null` when no `$recentSearch` is found
8+
* @todo implement a default list instead of `null` (now browse-word link) when no `$recentSearch` is found
99
* @todo implement loading component to avoid flickering UI
1010
*/
1111
export default function RecentSearches() {
@@ -28,5 +28,11 @@ export default function RecentSearches() {
2828
))}
2929
</ol>
3030
</div>
31-
) : null;
31+
) : (
32+
<div className="ml-2 mt-4 md:mt-6">
33+
<a href="/browse">
34+
Browse Words
35+
</a>
36+
</div>
37+
);
3238
}

src/components/islands/search.jsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ function SearchDialog() {
156156
e.preventDefault();
157157
if (document.querySelector("._cursor")) {
158158
const word = document.querySelector("._cursor");
159+
/**
160+
* @todo extract this `$addToRecentSearchesFn` operation to `word` layout..
161+
* ..so words are added to recent searches when viewed (not only when searched)
162+
*/
159163
$addToRecentSearchesFn({
160164
word: word.textContent,
161165
url: word.href
@@ -242,9 +246,13 @@ function SearchResult({ result = [], cursor, searchTerm }) {
242246
/**
243247
* @todo find better ways - don't hardcode `browse` string to the word slug
244248
*/
245-
href={`browse/${doc.slug}`}
249+
href={`/browse/${doc.slug}`}
246250
onClick={(e) => {
247251
e.preventDefault();
252+
/**
253+
* @todo extract this `$addToRecentSearchesFn` operation to `word` layout..
254+
* ..so words are added to recent searches when viewed (not only when searched)
255+
*/
248256
$addToRecentSearchesFn({
249257
word: e.currentTarget.textContent,
250258
url: e.currentTarget.href

src/layouts/word.astro

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
---
2+
/**
3+
* @todo Get URL of previous page (maybe from `referer`) and return there on Navigation back; good for browse page
4+
*/
25
import BaseLayout from "./base.astro";
36
import { getCollection } from "astro:content";
47
import Navbar from "../components/navbar.astro";
@@ -51,5 +54,26 @@ const editUrl = `/editor/edit/${frontmatter.url.split("/")[3].split(".")[0]}`;
5154
<article class="w-full max-w-screen-lg prose">
5255
<slot />
5356
</article>
57+
58+
<!-- Scripts
59+
TODO [THOUGHTS]: I didn't want to implement anything using the `script` tag at all, but this looked to be..
60+
..the only means of adding current word to recent searches when word is opened on client-side, will be..
61+
..nice if we can find another means ;)
62+
-->
63+
<script>
64+
/**
65+
* This (Commented out for now) should rightfully add current word to recentSearches on view; which should..
66+
* ..extract the functionality from the `search` island `onClick` search result..
67+
* ..but see @todo below
68+
*
69+
* @todo it's exhibiting similar behaviour reported in issue @link below
70+
* @link https://github.com/babblebey/jargons.dev/issues/10
71+
*/
72+
// import { $addToRecentSearchesFn } from "../lib/stores/search.js";
73+
// $addToRecentSearchesFn({
74+
// word: document.querySelector("h1").textContent.trim(),
75+
// url: document.location.href
76+
// });
77+
</script>
5478
</main>
5579
</BaseLayout>

src/lib/utils/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function getRepoParts(repoFullname) {
2929
* @returns {string}
3030
*/
3131
export function normalizeAsUrl(string) {
32-
return string.toLowerCase().replace(/\s+/g, "-");
32+
return string.trim().toLowerCase().replace(/\s+/g, "-");
3333
}
3434

3535
/**
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
import { getCollection } from "astro:content";
3+
import { ALPHABETS } from "../../../../constants.js";
4+
import BaseLayout from "../../../layouts/base.astro";
5+
import Navbar from "../../../components/navbar.astro";
6+
import Search from "../../../components/islands/search";
7+
8+
const { page } = Astro.props;
9+
const params = Astro.params;
10+
11+
const dictionary = await getCollection("dictionary");
12+
13+
export const prerender = true;
14+
15+
export async function getStaticPaths({ paginate }) {
16+
const dictionary = await getCollection("dictionary");
17+
return ALPHABETS.flatMap(alpha => {
18+
const filteredWords = dictionary.filter(word => word.slug[0] === alpha);
19+
return paginate(filteredWords, {
20+
params: { alpha },
21+
pageSize: 1
22+
});
23+
});
24+
}
25+
---
26+
27+
<BaseLayout
28+
pageTitle={`Browse jargons.dev`}
29+
subtitle={`Words Starting With "${params.alpha.toUpperCase()}" (Page ${page.currentPage})`}
30+
class="min-h-screen flex flex-col"
31+
>
32+
<Navbar>
33+
<Search triggerSize="sm" dictionary={dictionary} client:load />
34+
</Navbar>
35+
36+
<main class="w-full max-w-screen-lg grow flex flex-col p-5 md:mt-10 mx-auto space-y-6">
37+
<!-- Page Title -->
38+
<h1 class="text-3xl md:text-5xl font-black">
39+
Browse: Letter { params.alpha.toUpperCase() }
40+
</h1>
41+
42+
<!-- Words List -->
43+
<div>
44+
{page.data.length ? page.data.map(word => (
45+
<a href={`/browse/${word.slug}`}
46+
class="flex items-center md:text-lg justify-between no-underline w-full p-4 even:bg-gray-100 hover:bg-gray-100/50"
47+
>
48+
<span>{ word.data.title }</span>
49+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
50+
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5"></path>
51+
</svg>
52+
</a>
53+
)) : (
54+
<div class="mt-10 space-y-6">
55+
<p>
56+
Looks like this alphabet is feeling a bit lonely! 🤔 Why not be the first to add a word and give it some company?
57+
</p>
58+
<section class="rounded-lg border shadow-sm">
59+
<div class="space-y-1.5 p-3 md:p-6 flex flex-col lg:flex-row lg:items-center justify-between gap-4">
60+
<div class="space-y-1">
61+
<h3 class="font-semibold tracking-tight text-2xl">Contribute Words</h3>
62+
<p class="text-sm">
63+
You can contribute new words to the jargons.dev dictionary.
64+
</p>
65+
</div>
66+
<a
67+
class="flex items-center w-fit justify-center no-underline px-4 py-2 rounded-md border border-gray-200 bg-white hover:bg-gray-100 text-sm shadow-sm hover:shadow transition-colors"
68+
href="/editor/new"
69+
>
70+
<span>Start Now</span>
71+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width={1.5} stroke="currentColor" class="w-4 h-4">
72+
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 19.5 15-15m0 0H8.25m11.25 0v11.25" />
73+
</svg>
74+
</a>
75+
</div>
76+
</section>
77+
</div>
78+
)}
79+
</div>
80+
81+
<!-- Pagination -->
82+
{(page.url.next || page.url.prev) ? (
83+
<div class="w-full flex !mt-auto">
84+
<div class="mx-auto flex items-center space-x-4">
85+
{page.url.prev ? (
86+
<a href={page.url.prev} class="bg-black text-white no-underline rounded py-1 px-2">Previous</a>
87+
) : (
88+
<span class="bg-gray-100 text-gray-400 cursor-not-allowed no-underline rounded py-1 px-2">Previous</span>
89+
)}
90+
91+
<span>
92+
Page { page.currentPage }
93+
</span>
94+
95+
{page.url.next ? (
96+
<a href={page.url.next} class="bg-black text-white no-underline rounded py-1 px-2">Next</a>
97+
) : (
98+
<span class="bg-gray-100 text-gray-400 cursor-not-allowed no-underline rounded py-1 px-2">Next</span>
99+
)}
100+
</div>
101+
</div>
102+
) : null}
103+
</main>
104+
</BaseLayout>

src/pages/browse/index.astro

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
import { getCollection } from "astro:content";
3+
import { ALPHABETS } from "../../../constants.js";
4+
import BaseLayout from "../../layouts/base.astro";
5+
import Navbar from "../../components/navbar.astro";
6+
import Search from "../../components/islands/search.jsx";
7+
8+
const dictionary = await getCollection("dictionary");
9+
---
10+
11+
<BaseLayout
12+
pageTitle="Browse Words"
13+
class="min-h-screen"
14+
>
15+
<Navbar>
16+
<Search triggerSize="sm" dictionary={dictionary} client:load />
17+
</Navbar>
18+
19+
<main class="max-w-screen-lg p-5 md:mt-10 mx-auto space-y-6">
20+
<h2 class="text-3xl md:text-5xl font-black">
21+
Browse Alphabetically
22+
</h2>
23+
<div class="flex flex-wrap gap-3">
24+
{ALPHABETS.map(alpha => (
25+
<a
26+
href={`/browse/${alpha}/1`}
27+
class="no-underline flex h-16 w-16 md:h-20 md:w-20 bg-gray-100 hover:bg-black hover:text-white rounded md:text-lg transition-colors ease-in-out"
28+
>
29+
<span class="m-auto">{ alpha.toUpperCase() }</span>
30+
</a>
31+
))}
32+
</div>
33+
</main>
34+
</BaseLayout>

src/pages/editor/new/index.astro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ const action = resolveEditorActionFromPathname(pathname);
1919
>
2020
<Navbar
2121
returnNav={{
22+
/**
23+
* @todo now this looks weirds the commit link below - the `editor/new` route can now be reached from places..
24+
* ..other than the jargons editor page.
25+
* @link https://github.com/babblebey/jargons.dev/pull/60/commits/6e1ccf74f31c6b8da4b42bc1ffdc0efbf16b19ac
26+
*/
2227
label: "Back to Jargons Editor",
2328
location: "javascript: history.back()"
2429
}}

src/pages/index.astro

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import RecentSearches from "../components/islands/recent-searches.jsx";
77
const dictionary = await getCollection("dictionary");
88
---
99

10-
<BaseLayout pageTitle="Dictionary">
10+
<BaseLayout
11+
pageTitle="Jargons.dev"
12+
subtitle="Simplified Meaning & Definition to Technical Terms"
13+
>
1114
<main class="flex flex-col max-w-screen-lg p-5 justify-center mx-auto min-h-screen">
1215
<!-- Title -->
1316
<div class="mb-4 md:mb-6">

0 commit comments

Comments
 (0)