This repository was archived by the owner on Jun 19, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathtable-header.tsx
More file actions
121 lines (112 loc) · 3.89 KB
/
table-header.tsx
File metadata and controls
121 lines (112 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React from "react";
import { useRouter } from "next/router";
import { useDebounce } from "rooks";
import useSupabaseAuth from "lib/hooks/useSupabaseAuth";
import Search from "components/atoms/Search/search";
import Title from "components/atoms/Typography/title";
import LimitSelect, { LimitSelectMap } from "components/atoms/Select/limit-select";
import LayoutToggle, { ToggleValue } from "components/atoms/LayoutToggle/layout-toggle";
import { setQueryParams } from "lib/utils/query-params";
import ClientOnly from "components/atoms/ClientOnly/client-only";
import PaginationResult from "../PaginationResults/pagination-result";
interface TableHeaderProps {
title?: string;
metaInfo: Meta;
entity: string;
onSearch?: (search?: string) => void;
layout?: ToggleValue;
onLayoutToggle?: (value: ToggleValue) => void;
}
const TableHeader = ({ title, metaInfo, entity, onSearch, layout, onLayoutToggle }: TableHeaderProps): JSX.Element => {
const router = useRouter();
const [searchTerm, setSearchTerm] = React.useState<string>("");
const [suggestions, setSuggestions] = React.useState<string[]>([]);
const { providerToken } = useSupabaseAuth();
const { limit } = router.query;
const updateSuggestionsDebounced = useDebounce(async () => {
const req = await fetch(
`https://api.github.com/search/repositories?q=${encodeURIComponent(`${searchTerm} in:name`)}`,
{
...(providerToken
? {
headers: {
Authorization: `Bearer ${providerToken}`,
},
}
: {}),
}
);
if (req.ok) {
const res = await req.json();
const suggestions = res.items.map((item: any) => item.full_name);
setSuggestions(suggestions);
}
}, 250);
React.useEffect(() => {
setSuggestions([]);
if (!searchTerm) return;
updateSuggestionsDebounced();
}, [searchTerm]);
return (
<div className="flex flex-col flex-wrap w-full pl-4 md:pl-0 gap-y-2 md:flex-row md:justify-between md:items-center md:pb-4">
<div className="flex items-center justify-between gap-x-4 md:justify-start">
<Title className="!text-2xl !leading-none " level={1}>
{title}
</Title>
{layout ? (
<div className="md:hidden">
<LayoutToggle value={layout} onChange={onLayoutToggle} />
</div>
) : (
""
)}
<ClientOnly>
<PaginationResult
total={metaInfo.itemCount}
className="hidden !translate-y-[2px] md:inline-flex"
metaInfo={metaInfo}
entity={entity}
/>
</ClientOnly>
</div>
<div className="flex flex-col-reverse items-start gap-3 md:flex-row md:items-end ">
{layout ? (
<div className="hidden md:inline-flex">
<LayoutToggle value={layout} onChange={onLayoutToggle} />
</div>
) : (
""
)}
{onSearch ? (
<Search
placeholder={`Search ${title}`}
labelText={`Search ${title}`}
className="max-w-full text-sm py-1.5"
name={"query"}
onSearch={onSearch}
suggestions={suggestions}
onChange={(value) => setSearchTerm(value)}
/>
) : (
""
)}
<LimitSelect
placeholder="10 per page"
options={[
{ name: "10 per page", value: "10" },
{ name: "20 per page", value: "20" },
{ name: "30 per page", value: "30" },
{ name: "40 per page", value: "40" },
{ name: "50 per page", value: "50" },
]}
defaultValue={limit as LimitSelectMap}
className="hidden ml-auto min-w-max md:inline-block"
onChange={function (limit: string): void {
setQueryParams({ limit: `${limit}` });
}}
/>
</div>
</div>
);
};
export default TableHeader;