Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,20 @@
with:
deno-version: v1.x

- name: Update Algolia Index
if: github.ref == 'refs/heads/main'
run: deno run -A scripts/update_algolia_index.ts
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
ALGOLIA_INDEX_NAME: ${{ secrets.ALGOLIA_INDEX_NAME }}

- name: Build step
run: "deno task build"

- name: Upload to Deno Deploy
if: github.ref == 'refs/heads/main'
uses: denoland/deployctl@v1

Check warning on line 39 in .github/workflows/deploy.yml

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (deployctl)
with:
project: "9renpoto"
entrypoint: "main.ts"
Expand Down
22 changes: 21 additions & 1 deletion components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import IconActivity from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/activity.tsx";
import Campfire from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/campfire.tsx";
import IconRss from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/rss.tsx";
import Search from "@/islands/Search.tsx";

export function Header({ title }: { title: string }) {
interface HeaderProps {
title: string;
algolia?: {
appId: string;
searchKey: string;
indexName: string;
};
}

export function Header(props: HeaderProps) {
const { title, algolia } = props;
const menus = [
{ name: <IconRss />, href: "/rss.xml" },
{ name: <IconActivity />, href: "https://9renpoto.github.io/upptime" },
Expand All @@ -27,6 +38,15 @@ export function Header({ title }: { title: string }) {
</a>
</li>
))}
{algolia && (
<li>
<Search
appId={algolia.appId}
searchKey={algolia.searchKey}
indexName={algolia.indexName}
/>
</li>
)}
</ul>
</header>
);
Expand Down
3 changes: 2 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"@std/testing": "jsr:@std/testing@^0.225.3",
"preact": "https://esm.sh/preact@10.22.0",
"preact/": "https://esm.sh/preact@10.22.0/",
"tailwindcss": "npm:tailwindcss@^3.4.6"
"tailwindcss": "npm:tailwindcss@^3.4.6",
"algoliasearch": "https://esm.sh/algoliasearch@4.20.0"

Check warning on line 31 in deno.json

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)
},
"lint": {
"rules": {
Expand Down
59 changes: 59 additions & 0 deletions islands/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useState, useEffect, useRef } from "preact/hooks";
import algoliasearch from "algoliasearch/lite";

Check warning on line 2 in islands/Search.tsx

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)

Check warning on line 2 in islands/Search.tsx

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)

interface SearchProps {
appId: string;
searchKey: string;
indexName: string;
}

interface Hit {
objectID: string;
title: string;
snippet: string;
}

export default function Search(props: SearchProps) {
const { appId, searchKey, indexName } = props;
const [query, setQuery] = useState("");
const [hits, setHits] = useState<Hit[]>([]);
const searchInput = useRef<HTMLInputElement>(null);

const searchClient = algoliasearch(appId, searchKey);

Check warning on line 22 in islands/Search.tsx

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)
const index = searchClient.initIndex(indexName);

useEffect(() => {
if (query.length > 0) {
index.search<Hit>(query).then(({ hits }) => {
setHits(hits);
});
} else {
setHits([]);
}
}, [query]);

return (
<div class="relative">
<input
ref={searchInput}
type="text"
value={query}
onInput={(e) => setQuery(e.currentTarget.value)}
placeholder="Search..."
class="border rounded-lg px-2 py-1"
/>
{hits.length > 0 && (
<ul class="absolute top-full left-0 w-full bg-white border rounded-lg mt-1 shadow-lg z-10">
{hits.map((hit) => (
<li key={hit.objectID} class="border-b">
<a href={`/entry/${hit.objectID}`} class="block p-2 hover:bg-gray-100">
<div class="font-bold">{hit.title}</div>
<p class="text-sm text-gray-600">{hit.snippet}</p>
</a>
</li>
))}
</ul>
)}
</div>
);
}
35 changes: 35 additions & 0 deletions scripts/update_algolia_index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import "https://deno.land/std@0.192.0/dotenv/load.ts";
import algoliasearch from "algoliasearch";

Check warning on line 2 in scripts/update_algolia_index.ts

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)

Check warning on line 2 in scripts/update_algolia_index.ts

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)
import { getPosts } from "@/utils/posts.ts";

const appId = Deno.env.get("ALGOLIA_APP_ID");
const adminKey = Deno.env.get("ALGOLIA_ADMIN_KEY");
const indexName = Deno.env.get("ALGOLIA_INDEX_NAME");

if (!appId || !adminKey || !indexName) {
console.error(
"ALGOLIA_APP_ID, ALGOLIA_ADMIN_KEY, and ALGOLIA_INDEX_NAME must be set",
);
Deno.exit(1);
}

const client = algoliasearch(appId, adminKey);

Check warning on line 16 in scripts/update_algolia_index.ts

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (algoliasearch)
const index = client.initIndex(indexName);

const posts = await getPosts();

const records = posts.map((post) => ({
objectID: post.slug,
title: post.title,
snippet: post.snippet,
content: post.content,
publishedAt: post.publishedAt.toISOString(),
}));

try {
await index.saveObjects(records);
console.log("Algolia index updated successfully!");
} catch (error) {
console.error("Failed to update Algolia index:", error);
Deno.exit(1);
}
Loading