Skip to content

Commit

Permalink
feat(explorer): search page (#2258)
Browse files Browse the repository at this point in the history
  • Loading branch information
sstraatemans authored Jun 14, 2024
1 parent b75c405 commit 8ba3ec9
Show file tree
Hide file tree
Showing 17 changed files with 718 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { tableClass } from './styles.css';
const CompactTableDesktop: FC<ICompactTableProps> = ({
data,
fields,
label,
label = 'Table',
}) => {
return (
<Table aria-label={label} isStriped className={tableClass}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const getItem = (item: IProps['item'], key: ITableField['key']) => {
const value = keyArr.reduce((acc, val) => {
if (!acc) return;
const newItem = acc[val];
if (!newItem) return;
if (newItem === undefined || newItem === null) return;

return newItem;
}, item);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { SearchOptionEnum } from '@/hooks/search/utils/utils';
import { truncateValues } from '@/services/format';
import type { ApolloError } from '@apollo/client';
import { MonoSearch } from '@kadena/react-icons/system';
import { Badge, Box } from '@kadena/react-ui';
import { atoms } from '@kadena/react-ui/styles';
import React, { useState } from 'react';
import type { Dispatch, SetStateAction } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import {
searchBadgeBoxClass,
searchBoxClass,
Expand All @@ -18,29 +21,48 @@ export type SearchItemTitle =

export interface ISearchItem {
title: SearchItemTitle;
disabled?: boolean;
data?: any;
}
interface ISearchComponentProps {
placeholder: string;
searchItems: ISearchItem[];
export interface ISearchComponentProps {
searchData: ISearchItem[];
setSearchQuery?: Dispatch<SetStateAction<string>>;
searchQuery?: string;
searchOption: SearchOptionEnum | null;
setSearchOption: Dispatch<SetStateAction<SearchOptionEnum | null>>;
loading: boolean;
errors: ApolloError[];
}

const SearchComponent: React.FC<ISearchComponentProps> = ({
placeholder,
searchItems,
searchData,
setSearchQuery,
searchQuery,
searchOption,
setSearchOption,
}) => {
const [isEditing, setIsEditing] = useState(false);
const [searchOption, setSearchOption] = useState<number | null>(null);
const [searchValue, setSearchValue] = useState<string>('');
const [optionClicked, setOptionClicked] = useState(false);
const [escapePressed, setEscapePressed] = useState(false);
const ref = useRef<HTMLInputElement>(null);

const setOptionsDisabledExcept = (exceptIndex: number): void => {
searchItems.forEach((item, index) => {
if (index !== exceptIndex) {
item.disabled = true;
}
});
const handleSearchOption = (
inferedOption: SearchItemTitle | undefined,
): void => {
if (inferedOption === 'Account') {
setSearchOption(SearchOptionEnum.ACCOUNT);
}
if (inferedOption === 'Request Key') {
setSearchOption(SearchOptionEnum.REQUESTKEY);
}

if (inferedOption === 'Block Height') {
setSearchOption(SearchOptionEnum.BLOCKHEIGHT);
}

if (!inferedOption || inferedOption === undefined) {
setSearchOption(null);
}
};

const inferOption = (value: string): SearchItemTitle | undefined => {
Expand All @@ -60,14 +82,11 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
return undefined;
};

const enableAllOptions = (): void => {
searchItems.forEach((item) => {
item.disabled = false;
});
const handleSearch = (): void => {
const value = ref.current?.value ?? '';
if (setSearchQuery) setSearchQuery(value);
};

const handleSearch = (value: string, option: number | null): void => {};

const handleSearchValueChange = (
e: React.ChangeEvent<HTMLInputElement>,
): void => {
Expand All @@ -76,24 +95,7 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
if (escapePressed || optionClicked) return;

const inferedOption = inferOption(e.target.value);
if (inferedOption === 'Account') {
setSearchOption(0);
setOptionsDisabledExcept(0);
}
if (inferedOption === 'Request Key') {
setSearchOption(1);
setOptionsDisabledExcept(1);
}

if (inferedOption === 'Block Height') {
setSearchOption(2);
setOptionsDisabledExcept(2);
}

if (!inferedOption || inferedOption === undefined) {
setSearchOption(null);
enableAllOptions();
}
handleSearchOption(inferedOption);
};

const handleSearchValueKeyDown = (
Expand All @@ -102,7 +104,7 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
if (e.key === 'ArrowDown') {
e.preventDefault();
setSearchOption((prev) =>
prev === null ? 0 : Math.min(prev + 1, searchItems.length - 1),
prev === null ? 0 : Math.min(prev + 1, searchData.length - 1),
);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
Expand All @@ -112,15 +114,22 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
setIsEditing(false);
setEscapePressed(false);
setOptionClicked(false);
handleSearch(searchValue, searchOption);
handleSearch();
} else if (e.key === 'Escape') {
setOptionClicked(false);
setSearchOption(null);
setEscapePressed(true);
enableAllOptions();
setIsEditing(false);
} else {
setEscapePressed(false);
setOptionClicked(false);
}
};

useEffect(() => {
setSearchValue(searchQuery ?? '');
}, [searchQuery]);

return (
<>
<Box
Expand Down Expand Up @@ -149,11 +158,12 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
<MonoSearch />

<input
ref={ref}
type="text"
placeholder={placeholder}
placeholder="Search the Kadena Blockchain on"
value={searchValue}
onChange={(e) => handleSearchValueChange(e)}
onFocus={() => setIsEditing(true)}
onClick={() => setIsEditing((v) => !v)}
className={searchInputClass}
/>

Expand All @@ -163,7 +173,9 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
justifyContent={'flex-end'}
className={searchBadgeBoxClass}
>
<Badge size="lg">{searchItems[searchOption].title}</Badge>
{searchData[searchOption] && (
<Badge size="lg">{searchData[searchOption].title}</Badge>
)}
</Box>
)}
</Box>
Expand All @@ -179,15 +191,14 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
fontFamily: 'primaryFont',
})}
>
{searchItems.map((item, index) => (
{searchData?.map((item, index) => (
<Box
key={index}
onMouseDown={() => setOptionClicked(true)}
onClick={() => {
if (!item.disabled) {
setSearchOption(index);
setIsEditing(false);
}
handleSearch();
setSearchOption(index);
setIsEditing(false);
}}
style={{
gridTemplateColumns: '1fr 3fr',
Expand All @@ -197,7 +208,7 @@ const SearchComponent: React.FC<ISearchComponentProps> = ({
display: 'grid',
alignItems: 'flex-start',
paddingInlineStart: 'md',
cursor: item.disabled ? 'not-allowed' : 'pointer',
cursor: 'pointer',
backgroundColor:
index === searchOption ? 'base.@active' : 'base.default',
width: '100%',
Expand Down
Loading

0 comments on commit 8ba3ec9

Please sign in to comment.