Skip to content

Commit

Permalink
feat: add searchbar
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgengaldal committed Oct 3, 2024
1 parent ce92ec4 commit f6d00b2
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 57 deletions.
4 changes: 3 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import tailwind from '@astrojs/tailwind';

import vercel from '@astrojs/vercel/serverless';

import react from '@astrojs/react';

// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
integrations: [tailwind(), react()],
output: 'hybrid',
adapter: vercel()
});
157 changes: 154 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
"dependencies": {
"": "file:",
"@astrojs/check": "^0.9.3",
"@astrojs/react": "^3.6.2",
"@astrojs/tailwind": "^5.1.1",
"@astrojs/vercel": "^7.8.1",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"astro": "^4.15.9",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwindcss": "^3.4.13",
"typescript": "^5.6.2"
}
Expand Down
86 changes: 86 additions & 0 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useEffect, useState } from "react";
import { fetchClasses } from "../utils/hkdirApi";
import type { Class } from "../types";
import { getUniqueObjectByPredicate } from "../utils/object";

const LIST_LENGTH = 10

export const SearchBar = () => {
const [classes, setClasses] = useState<Class[]>([]);
const [shownClasses, setShownClasses] = useState<Class[]>([]);
const [showList, setShowList] = useState(false);

useEffect(() => {
fetchClasses().then((classes) => {
const allClasses = getUniqueObjectByPredicate(
classes,
(classs) => classs.classCode
);

setClasses(allClasses);
setShownClasses(allClasses.slice(0, LIST_LENGTH));
});
}, []);

const handleTyping = (e: any) => {
const searchWord = e.target.value;
setShownClasses(
classes.filter((classs) => {
return (
classs.classCode.toLowerCase().startsWith(searchWord.toLowerCase()) ||
classs.className.toLowerCase().startsWith(searchWord.toLowerCase())
);
})
.slice(0, LIST_LENGTH)
);
};

return (
<div className="flex flex-col justify-center divide-y gap-1 divide-accent">

<div className="relative w-full">
<input
className="w-full bg-dark outline-none pl-10 p-2 rounded-full focus:rounded-none focus:rounded-t-xl"
type="text"
onChange={handleTyping}

placeholder="Søk etter et fag"
onBlur={(e) => {
// Sets timeout to ensure the link is clicked before it disappears
setTimeout(() => setShowList(false), 100)
}}
onFocus={(e) => {
setShowList(true);
}}
/>
<div className="absolute inset-y-3 left-2">
{/* Search icon */}
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
</svg>
</div>

</div>

{showList &&
<div className="relative w-full h-0">
<div className="w-full absolute z-10 bg-dark flex flex-col divide-y shadow-lg shadow-black p-2 ">
{shownClasses.length ?

shownClasses.map((object, index) => {
return (
<a
className="block"
key={index}
href={"/" + object.classCode.slice(0, -2)}
>
{object.className} ({object.classCode.slice(0, -2)})
</a>
);
})
: <p><i>Ingen fag stemmer med søket</i></p>}
</div>
</div>}
</div>
);
};
10 changes: 8 additions & 2 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
import { SearchBar } from '../components/SearchBar';
interface Props {
title: string;
}
Expand All @@ -17,7 +19,11 @@ const { title } = Astro.props;
<title>{title}</title>
</head>
<body>
<slot />
<main>
<a href="/"><h1>Studie<span class="text-gradient">løpet</span></h1></a>
<SearchBar client:load/>
<slot />
</main>
</body>
</html>
<style is:global>
Expand All @@ -34,7 +40,7 @@ const { title } = Astro.props;
}
html {
font-family: system-ui, sans-serif;
background: #13151a;
background: #222;
}

code {
Expand Down
3 changes: 0 additions & 3 deletions src/pages/[classCode].astro
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ const semester = filteredGradeEntries[0].semester
---

<Layout title={`Studieløpet | ${classCode}`}>
<main>
<h1>Studie<span class="text-gradient">løpet</span></h1>
<div class="bg-gray-800 p-5 flex flex-col ">
<h2 class="">{filtering.classCode.slice(0, -2)}</h2>
<h3 class="italic text-sm mb-2">{semester} {filtering.year}</h3>
Expand All @@ -48,5 +46,4 @@ const semester = filteredGradeEntries[0].semester
color: getColorByStudyProgrammeCode(code),
}))}
/>
</main>
</Layout>
Loading

0 comments on commit f6d00b2

Please sign in to comment.