Implement search result component

Searching not yet added, sample results added for testing
This commit is contained in:
Andy Chan 2024-11-12 17:52:16 -05:00
parent b2ffd46a79
commit 7027d7f993
4 changed files with 106 additions and 2 deletions

View File

@ -2,6 +2,7 @@
import Callout from "@/components/resource/Callout";
import Card from "@/components/resource/Card";
import { LandingSearchBar } from "@/components/resource/LandingSearchBar";
import { SearchResult } from "@/components/resource/SearchResult";
import Image from "next/image";
import Link from "next/link";
@ -13,6 +14,7 @@ export default function Page() {
Good evening!
</h1>
</div>
<LandingSearchBar />
</div>
);

View File

@ -15,7 +15,10 @@ import React, {
useEffect,
} from "react";
import Image from "next/image";
import { FilterBox } from "../FilterBox";
import { SearchResult } from "./SearchResult";
// TODO: Actually implement search.
import sampleResults from "./sample_results.json";
export const LandingSearchBar: React.FC = () => {
const [searchTerm, setSearchTerm] = useState("");
@ -111,7 +114,12 @@ export const LandingSearchBar: React.FC = () => {
</div>
{/* search results, for now since it's empty this is the default screen */}
<div className="flex flex-col pt-16 space-y-2 justify-center items-center">
<div
className={
"flex flex-col pt-16 space-y-2 justify-center items-center" +
(searchTerm.length > 0 ? " hidden" : "")
}
>
<Image
alt="Landing illustration"
src="/landing_illustration.png"
@ -123,6 +131,22 @@ export const LandingSearchBar: React.FC = () => {
results.
</p>
</div>
<div
className={
"p-1 flex flex-col gap-1 mt-2" +
(searchTerm.length > 0 ? "" : " hidden")
}
>
{sampleResults.map((result, i) => (
<SearchResult
key={i}
type={result.type}
name={result.name}
description={result.description}
/>
))}
</div>
</div>
);
};
@ -147,6 +171,7 @@ const useFilterPillDropdown = (
}, [ref, setShowDropdown]);
};
// Props for the filter pill...
interface FilterPillProps {
icon: React.ForwardRefExoticComponent<
Omit<React.SVGProps<SVGSVGElement>, "ref">
@ -158,6 +183,7 @@ interface FilterPillProps {
setSelectedOptions: React.Dispatch<SetStateAction<boolean[]>>;
}
// The filter pill (visible when filter button active, contains dropdown)
const FilterPill: React.FC<FilterPillProps> = ({
icon,
name,

View File

@ -0,0 +1,44 @@
import React from "react";
import {
BookmarkIcon,
ClipboardIcon,
QuestionMarkCircleIcon,
ArrowUturnRightIcon,
} from "@heroicons/react/24/solid";
interface SearchResultProps {
type: "resource" | "service" | string;
name: string;
description: string;
}
export const SearchResult: React.FC<SearchResultProps> = ({
type,
name,
description,
}) => {
const Icon: React.ForwardRefExoticComponent<
Omit<React.SVGProps<SVGSVGElement>, "ref">
> =
type === "resource"
? BookmarkIcon
: type === "service"
? ClipboardIcon
: QuestionMarkCircleIcon; // Unknown type
return (
<div className="flex justify-between items-center w-full p-2 rounded-md hover:bg-purple-100 cursor-pointer group">
{/* Left side of the item */}
<div className="flex gap-2 items-center max-w-[95%]">
<Icon className="h-6 w-6 flex-shrink-0" />
<span className="font-medium flex-grow text-nowrap">
{name}
</span>
<span className="text-gray-400 text-nowrap overflow-hidden text-ellipsis flex-shrink">
{description}
</span>
</div>
<ArrowUturnRightIcon className="h-5 w-5 rotate-180 invisible group-hover:visible" />
</div>
);
};

View File

@ -0,0 +1,32 @@
[
{
"type": "resource",
"name": "example name",
"description": "example description"
},
{
"type": "service",
"name": "example name",
"description": "example description"
},
{
"type": "resource",
"name": "National Domestic Violence Hotline",
"description": "24/7 confidential support for victims of domestic violence"
},
{
"type": "resource",
"name": "Legal Aid Society",
"description": "Free legal assistance for low-income individuals"
},
{
"type": "service",
"name": "Crisis Hotline",
"description": "24/7 support for individuals in crisis"
},
{
"type": "unknown",
"name": "unknown thing with a really long name",
"description": "and let's also type out a really long description to see how it handles overflow and all that anyways"
}
]