Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add search functionality #14

Merged
merged 25 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3d472fe
Begin algolia search setup
aaronmbos Oct 7, 2022
70019ac
Adding algolia import
aaronmbos Oct 10, 2022
c24efec
Merge remote-tracking branch 'origin/main' into feat/search
aaronmbos Oct 12, 2022
bce90ed
Finish algolia import
aaronmbos Oct 12, 2022
57c41ee
Search updates
aaronmbos Oct 13, 2022
69b93f8
Begin search ui without algolia components
aaronmbos Oct 14, 2022
962e4ed
Implement search bar with no search
aaronmbos Oct 15, 2022
5913e28
Add search page
aaronmbos Oct 16, 2022
85b562d
Implement rudimentary search function to algolia
aaronmbos Oct 17, 2022
a21841a
Working through some input state issues
aaronmbos Oct 18, 2022
7c6d5e7
Formatting
aaronmbos Oct 18, 2022
098f92b
Updates for search
aaronmbos Oct 21, 2022
686855b
Merge remote-tracking branch 'origin/main' into feat/search
aaronmbos Oct 22, 2022
639408a
Finish up url param based search
aaronmbos Oct 22, 2022
79a31c9
Merge remote-tracking branch 'origin/main' into feat/search
aaronmbos Nov 9, 2022
de737eb
More search updates
aaronmbos Nov 9, 2022
490c085
Implement result component and clean up
aaronmbos Nov 10, 2022
ffd770b
Merge remote-tracking branch 'origin/main' into feat/search
aaronmbos Nov 12, 2022
233c030
Update algolia import script
aaronmbos Nov 12, 2022
392a795
Add api files for search
aaronmbos Nov 12, 2022
80e8c6d
Move algolia search to API route
aaronmbos Nov 14, 2022
53e380f
Doing a bit of clean up of search components and api
aaronmbos Nov 17, 2022
161c4c6
Fix the nav mobile menu breakpoint
aaronmbos Nov 17, 2022
9d780c6
Update api request handler to exclude content
aaronmbos Nov 17, 2022
f53c778
Clean up some component imports
aaronmbos Nov 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions components/button-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@ interface Props {
fill: string;
id?: string;
classList?: string[];
dimensions: [height: number, width: number];
}

export default function ButtonIcon({ path, fill, id, classList }: Props) {
export default function ButtonIcon({
path,
fill,
id,
classList,
dimensions,
}: Props) {
return (
<svg
id={id}
xmlns="http://www.w3.org/2000/svg"
width="17"
height="17"
width={dimensions[1]}
height={dimensions[0]}
viewBox={`0 0 ${dimensions[1]} ${dimensions[0]}`}
fill={fill}
className={`inline ${classList?.join(" ")}`}
>
Expand Down
19 changes: 0 additions & 19 deletions components/icon.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function Layout({ children }: Props) {
description="Blogging about software and technology from a software engineer's perspective."
image={`${process.env.NEXT_PUBLIC_ORIGIN}/static/card-logo.png`}
/>
<div className="flex flex-col bg-gray-50 dark:bg-stone-800 dark:text-white">
<div className="flex flex-col w-screen h-screen overflow-auto bg-gray-50 dark:bg-stone-800 dark:text-white">
<Nav />
<main className="w-full pt-8 max-w-screen-lg mx-auto px-10 md:px-28 grow dark:bg-stone-800 dark:text-white">
{children}
Expand Down
8 changes: 6 additions & 2 deletions components/nav-body.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NavigationLink } from "./nav"
import { NavigationLink } from "./nav";
import NavLink from "./nav-link";
import ThemeIcon from "./theme-icon";
import NavSearch from "./nav-search";

interface Props {
navLinks: NavigationLink[];
Expand All @@ -9,7 +10,7 @@ interface Props {
export default function NavBody({ navLinks }: Props) {
return (
<>
<div className="flex-1 justify-between hidden sm:flex sm:ml-10">
<div className="shrink-1 justify-between hidden md:flex sm:ml-10">
<div className="flex flex-none space-x-4">
{navLinks.map((link: NavigationLink) => {
return (
Expand All @@ -18,6 +19,9 @@ export default function NavBody({ navLinks }: Props) {
})}
</div>
</div>
<div className="flex-1 grow md:flex hidden md:justify-end px-4">
<NavSearch />
</div>
<div className="mt-1 mr-5 flex flex-0">
<ThemeIcon />
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/nav-hamburger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ interface Props {

export default function NavHamburger({ isMenuOpen, handleClick }: Props) {
return (
<div className="flex items-center sm:hidden">
<div className="flex items-center md:hidden">
<button
onClick={handleClick}
className="inline-flex items-center justify-center p-2 rounded-md focus:outline-none focus:ring-2 focus:ring-inset dark:focus:ring-stone-800 focus:ring-white"
className="inline-flex items-center justify-center p-2 rounded-md focus:outline-none hover:ring-2 hover:ring-stone-400 transition-all"
aria-expanded="false"
>
<span className="sr-only">Open main menu</span>
Expand Down
2 changes: 1 addition & 1 deletion components/nav-logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Link from "next/link";

export default function NavLogo() {
return (
<div className="shrink-0 hidden sm:flex sm:items-center">
<div className="shrink-0 md:flex md:items-center">
<Link href="/">
<a className="dark:text-blue-300 dark:hover:text-blue-100 hover:text-blue-700 text-blue-500 cursor-pointer text-2xl font-mono font-bold flex items-center flex-none px-2">
&lt;Aaron Bos&#47;&gt;
Expand Down
26 changes: 25 additions & 1 deletion components/nav-mobile-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import NavMobileLink from "./nav-mobile-link";
import { NavigationLink } from "./nav";
import { MaxSearchLength } from "../constants";
import { useRouter } from "next/router";

interface Props {
isMenuOpen: boolean;
navLinks: NavigationLink[];
}

export default function NavMobileMenu({ isMenuOpen, navLinks }: Props) {
const router = useRouter();

return (
<div
id="mobileMenu"
className={`${isMenuOpen ? "block" : "hidden"} sm:hidden`}
className={`${isMenuOpen ? "block" : "hidden"} md:hidden`}
>
<div className="px-2 pt-2 pb-3 space-y-1">
{navLinks.map((link) => {
Expand All @@ -22,6 +26,26 @@ export default function NavMobileMenu({ isMenuOpen, navLinks }: Props) {
/>
);
})}
<input
maxLength={MaxSearchLength}
className="block mx-auto w-full dark:bg-stone-800 dark:text-white rounded-md dark:focus:ring-stone-400 dark:focus:ring-2 dark:focus:border-0"
type="search"
placeholder="Search posts"
onKeyUp={(e) => {
if (e.key === "Enter") {
const query = (e.target as HTMLInputElement).value;

router.push({
pathname: "/search",
query: {
q: encodeURIComponent(
query.substring(0, MaxSearchLength - 1)
),
},
});
}
}}
/>
</div>
</div>
);
Expand Down
29 changes: 29 additions & 0 deletions components/nav-search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useRouter } from "next/router";
import { MaxSearchLength } from "../constants";

export default function NavSearch() {
const router = useRouter();

return (
<input
maxLength={MaxSearchLength}
className="lg:w-1/2 md:w-3/4 dark:bg-stone-800 dark:text-white rounded-md dark:focus:ring-stone-400 dark:focus:ring-2 dark:focus:border-0"
type="search"
placeholder="Search posts"
onKeyUp={(e) => {
if (e.key === "Enter") {
const query = (e.target as HTMLInputElement).value;

router.push({
pathname: "/search",
query: {
q: encodeURIComponent(
query.trim().substring(0, MaxSearchLength - 1)
),
},
});
}
}}
/>
);
}
6 changes: 4 additions & 2 deletions components/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ export default function Nav() {

return (
<nav className="border-b border-b-gray-200 dark:border-b-zinc-700">
<div className="max-w-6xl mx-auto px-2 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto px-2 sm:px-6 md:px-8">
<div className="relative flex items-center justify-between h-16">
<NavHamburger
isMenuOpen={menuState}
handleClick={() => setMenuState(!menuState)}
/>
<div className="flex-1 flex justify-end sm:items-stretch sm:justify-start">
<div className="flex md:justify-center md:items-stretch">
<NavLogo />
</div>
<div className="md:flex-1 flex justify-end md:justify-start">
<NavBody navLinks={navLinks} />
</div>
</div>
Expand Down
14 changes: 12 additions & 2 deletions components/reaction-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,19 @@ export default function ReactionRow({ postSlug, url }: Props) {
<AnchorButton
href={`https://twitter.com/intent/tweet?url=${encodeURI(url)}`}
>
<ButtonIcon fill="rgb(29,155,240)" path={icons.twitter} />
<ButtonIcon
fill="rgb(29,155,240)"
path={icons.twitter}
dimensions={[17, 17]}
/>
<span className="text-sm ml-2">Share</span>
</AnchorButton>
<AnchorButton href="https://aaronbos.dev/feed.xml">
<ButtonIcon fill="currentColor" path={icons.bell} />
<ButtonIcon
fill="currentColor"
path={icons.bell}
dimensions={[17, 17]}
/>
<span className="text-sm ml-2">Subscribe</span>
</AnchorButton>
<button
Expand All @@ -114,12 +122,14 @@ export default function ReactionRow({ postSlug, url }: Props) {
id="clip"
fill="currentColor"
path={icons.emptyClipboard}
dimensions={[17, 17]}
/>
<ButtonIcon
id="clipped"
fill="currentColor"
path={icons.copiedClipboard}
classList={["hidden"]}
dimensions={[17, 17]}
/>{" "}
<span id="clip-text" className="text-sm ml-1">
Copy link
Expand Down
7 changes: 5 additions & 2 deletions components/recent-posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import PostPreview from "./post-preview";
import { BlogPost } from "../lib/posts";

interface Props {
recentPosts: Pick<BlogPost, "id" | "slug" | "description" | "date" | "metadata" | "title">[];
recentPosts: Pick<
BlogPost,
"id" | "slug" | "description" | "date" | "metadata" | "title"
>[];
}

export default function RecentPosts({ recentPosts }: Props) {
return (
<div className="my-3">
<div className="dark:bg-stone-800 bg-gray-50 my-3">
<h3 className="pt-6 text-xl font-semibold pb-3">Recent Posts</h3>
<hr />
{recentPosts.map((post) => {
Expand Down
2 changes: 2 additions & 0 deletions constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const BlogIndex: string = "aaronbos_blog_index";
export const MaxSearchLength: number = 128;
30 changes: 30 additions & 0 deletions lib/request-handlers/search-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import algoliasearch from "algoliasearch";
import { BlogIndex } from "../../constants";
import { ApiResponse, SearchHit } from "../../types/api/types";

export async function handleGet(
query: string
): Promise<ApiResponse<SearchHit[]>> {
const client = algoliasearch(
process.env.ALGOLIA_APP_ID!,
process.env.ALGOLIA_SEARCH_API_KEY!
);

const index = client.initIndex(BlogIndex);
const rawResults = (await index.search<SearchHit>(query)).hits;
return {
// Unfortunately need to map here to make sure the entire content isn't sent in the response
data: rawResults.map((h) => {
return {
objectID: h.objectID,
title: h.title,
description: h.description,
date: h.date,
metadata: h.metadata,
slug: h.slug,
};
}),
isSuccess: true,
message: "",
};
}
Loading