search: added filter button
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
ec1b131c3c
commit
306585ad98
@ -0,0 +1,56 @@
|
|||||||
|
import { SearchType } from "@/client/typings/search/options";
|
||||||
|
import { Component } from "@/typings/component";
|
||||||
|
|
||||||
|
import { FiFilter as FilterIcon } from "react-icons/fi";
|
||||||
|
|
||||||
|
import { Button } from "@nextui-org/button";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dropdown,
|
||||||
|
DropdownTrigger,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownItem
|
||||||
|
} from "@nextui-org/dropdown";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
|
export const Filter: Component<{
|
||||||
|
filter: SearchType;
|
||||||
|
setFilter: (filter: SearchType) => void;
|
||||||
|
}> = ({ setFilter, filter }) => {
|
||||||
|
const filterMenuItems: { key: SearchType; label: string }[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{ key: "all", label: "All" },
|
||||||
|
{ key: "video", label: "Videos" },
|
||||||
|
{ key: "channel", label: "Channels" },
|
||||||
|
{ key: "playlist", label: "Playlists" }
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown>
|
||||||
|
<DropdownTrigger>
|
||||||
|
<Button className="h-full" variant="bordered" isIconOnly>
|
||||||
|
<FilterIcon className="text-xl" />
|
||||||
|
</Button>
|
||||||
|
</DropdownTrigger>
|
||||||
|
<DropdownMenu
|
||||||
|
aria-label="Static Actions"
|
||||||
|
items={filterMenuItems}
|
||||||
|
selectionMode="single"
|
||||||
|
selectedKeys={[filter]}
|
||||||
|
onSelectionChange={(keys) => {
|
||||||
|
const selectedKeys = keys as Set<SearchType>;
|
||||||
|
|
||||||
|
const selectedKey = Array.from(selectedKeys)[0];
|
||||||
|
|
||||||
|
if (!selectedKey) return;
|
||||||
|
|
||||||
|
setFilter(selectedKey);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(item) => <DropdownItem key={item.key}>{item.label}</DropdownItem>}
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,12 @@
|
|||||||
|
import z from "zod";
|
||||||
|
|
||||||
export interface SearchOptions {
|
export interface SearchOptions {
|
||||||
pageParam?: string;
|
pageParam?: string;
|
||||||
type?: SearchType;
|
type?: SearchType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchType = "video" | "playlist" | "channel" | "all";
|
export const searchTypes = ["video", "playlist", "channel", "all"] as const;
|
||||||
|
|
||||||
|
export const SearchTypeModel = z.enum(searchTypes);
|
||||||
|
|
||||||
|
export type SearchType = z.infer<typeof SearchTypeModel>;
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import { SearchType } from "@/client/typings/search/options";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
const searchPathname = "/results";
|
||||||
|
|
||||||
|
export const useSearch = (): ((query: string, filter?: SearchType) => void) => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (query, filter = "all") => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
|
params.set("search_query", query);
|
||||||
|
params.set("filter", filter);
|
||||||
|
|
||||||
|
router.push(searchPathname + "?" + params.toString());
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,26 @@
|
|||||||
|
const billion = 1.0e9;
|
||||||
|
const million = 1.0e6;
|
||||||
|
const thousand = 1.0e3;
|
||||||
|
|
||||||
|
const formatBigNumber = (num: number): string => {
|
||||||
|
const abs = Math.abs(num);
|
||||||
|
|
||||||
|
// Nine Zeroes for Billions
|
||||||
|
if (abs >= billion) return (abs / billion).toPrecision(3) + "B";
|
||||||
|
|
||||||
|
if (abs >= million) {
|
||||||
|
if (abs >= million * 10) return (abs / million).toPrecision(3) + "M";
|
||||||
|
|
||||||
|
return (abs / million).toPrecision(2) + "M";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs >= thousand) {
|
||||||
|
if (abs >= thousand * 10) return (abs / thousand).toPrecision(3) + "K";
|
||||||
|
|
||||||
|
return (abs / thousand).toPrecision(2) + "K";
|
||||||
|
}
|
||||||
|
|
||||||
|
return abs.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default formatBigNumber;
|
@ -1,14 +0,0 @@
|
|||||||
const formatViewCount = (num: number): string => {
|
|
||||||
// Nine Zeroes for Billions
|
|
||||||
return Math.abs(num) >= 1.0e9
|
|
||||||
? (Math.abs(num) / 1.0e9).toPrecision(3) + "B"
|
|
||||||
: // Six Zeroes for Millions
|
|
||||||
Math.abs(num) >= 1.0e6
|
|
||||||
? (Math.abs(num) / 1.0e6).toPrecision(3) + "M"
|
|
||||||
: // Three Zeroes for Thousands
|
|
||||||
Math.abs(num) >= 1.0e3
|
|
||||||
? (Math.abs(num) / 1.0e3).toPrecision(3) + "K"
|
|
||||||
: Math.abs(num).toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
export default formatViewCount;
|
|
Loading…
Reference in new issue