react-icons/bs#BsSearch JavaScript Examples

The following examples show how to use react-icons/bs#BsSearch. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.jsx    From roomie-frontend with MIT License 6 votes vote down vote up
Search = ({ onChange }) => {
  return (
    <>
      <SearchContainer>
        <SearchItem onChange={onChange} type='search' placeholder='Find your next roomie' />
        <SearchIconItem>
          <BsSearch />
        </SearchIconItem>
      </SearchContainer>
      <Title>The best places in MedellĂ­n <br/> to live unique moments</Title>
    </>
  );
}
Example #2
Source File: SearchTokenInput.js    From plenty-interface with GNU General Public License v3.0 6 votes vote down vote up
SearchTokenInput = ({ value, onChange, inputRef }) => {
  return (
    <div className="mt-1 flex flex-row w-100">
      <InputGroup>
        <InputGroup.Prepend>
          <InputGroup.Text className="search-icon border-right-0">
            <BsSearch />
          </InputGroup.Text>
        </InputGroup.Prepend>
        <FormControl
          ref={inputRef}
          placeholder="Search"
          className={'shadow-none border-left-0 search-box'}
          value={value}
          onChange={onChange}
        />
      </InputGroup>
    </div>
  );
}
Example #3
Source File: styles.js    From VisGeo-ETL with MIT License 5 votes vote down vote up
SearchIcon = styled(BsSearch)`
  font-size: 80px;
  color: rgba(67, 219, 178, 0.25);

  transition: ease-in-out 0.2s;
`
Example #4
Source File: Farms.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
Farms = (props) => {
  const [sortValue, setSortValue] = useState(FARM_SORT_OPTIONS.APR);
  const [floaterValue, setFloaterValue] = useState({});
  const [searchValue, setSearchValue] = useState('');
  const [tabChange, setTabChange] = useState(FARM_TAB.ALL);
  const [isSelected, setIsSelected] = useState(false);
  const [isOpen, setIsOpen] = useState(false);
  const [showConfirmTransaction, setShowConfirmTransaction] = useState(false);

  function toggleHidden() {
    setIsOpen(!isOpen);
  }
  function setSelectTitle(e) {
    setSortValue(e.target.value);
    toggleHidden();
  }

  // * Initial Call
  useEffect(() => {
    if (props.activeFarms.length === 0 || props.inactiveFarms.length === 0) {
      const farmsWithoutData = populateFarmsWithoutData();
      props.populateEmptyFarmsData(farmsWithoutData);
    }
  }, []);

  const handleClose = () => {
    setShowConfirmTransaction(false);
  };

  useEffect(() => {
    const fetchData = () => {
      props.getFarmsData(props.isActiveOpen);
      props.getUserStakes(props.userAddress, 'FARMS', props.isActiveOpen);
      props.getHarvestValues(props.userAddress, 'FARMS', props.isActiveOpen);
      props.fetchUserBalances(props.userAddress);
    };

    fetchData();
    const backgroundRefresh = setInterval(() => {
      fetchData();
    }, 60 * 1000);

    return () => clearInterval(backgroundRefresh);
  }, [props.isActiveOpen, props.userAddress, props.rpcNode]);

  const sortFarmsFunc = useCallback(
    (a, b) => {
      if (sortValue === FARM_SORT_OPTIONS.APR) {
        return Number(a.values?.APR) < Number(b.values?.APR) ? 1 : -1;
      }

      if (sortValue === FARM_SORT_OPTIONS.TVL) {
        return Number(a.values?.totalLiquidty) < Number(b.values?.totalLiquidty) ? 1 : -1;
      }

      if (sortValue === FARM_SORT_OPTIONS.REWARDS) {
        const a1 = Number(a.values?.rewardRate * 2880);
        const b1 = Number(b.values?.rewardRate * 2880);
        return a1 < b1 ? 1 : -1;
      }

      return 0;
    },
    [sortValue],
  );

  const filterBySearch = useCallback(
    (farm) => farm.farmData.CARD_TYPE.toLowerCase().includes(searchValue.toLowerCase()),
    [searchValue],
  );

  const filterByTab = useCallback(
    (farm) => {
      if (tabChange === FARM_TAB.CTEZ) {
        return farm.farmData.CARD_TYPE.toLowerCase().includes('ctez');
      }
      if (tabChange === FARM_TAB.NEW) {
        return farm.farmData.bannerType?.includes('info');
      }
      if (tabChange === FARM_TAB.STABLE) {
        return (
          farm.farmData.farmType?.includes('veStableAMM') || farm.farmData.farmType?.includes('xtz')
        );
      }
      if (tabChange === FARM_TAB.YOU) {
        return props.userStakes[farm.farmData.CONTRACT]?.stakedAmount > 0;
      }

      return true;
    },
    [tabChange, props.userStakes],
  );

  const filterByStaked = useCallback(
    (farm) => {
      if (!props.isStakedOnlyOpen) return true;

      return props.userStakes[farm.farmData.CONTRACT]?.stakedAmount > 0;
    },
    [props.isStakedOnlyOpen, props.userStakes],
  );

  const farmsToRender = useMemo(() => {
    const farmsInView = props.isActiveOpen
      ? props.activeFarms.slice()
      : props.inactiveFarms.slice();

    return farmsInView
      .filter(filterBySearch)
      .filter(filterByTab)
      .filter(filterByStaked)
      .sort(sortFarmsFunc);
  }, [
    filterBySearch,
    filterByTab,
    filterByStaked,
    sortFarmsFunc,
    props.activeFarms,
    props.inactiveFarms,
    props.isActiveOpen,
  ]);

  return (
    <>
      <div>
        <div>
          <div className={styles.header}>
            <Tabs
              className={`swap-container-tab ${styles.farmstab}`}
              mountOnEnter={true}
              unmountOnExit={true}
              onSelect={(e) => setTabChange(e)}
            >
              <Tab eventKey={FARM_TAB.ALL} title={FARM_TAB.ALL} />
              <Tab eventKey={FARM_TAB.NEW} title={FARM_TAB.NEW} />
              <Tab
                eventKey={FARM_TAB.STABLE}
                title={
                  <span>
                    <span className="mr-2">{FARM_TAB.STABLE}</span>
                    {tabChange === FARM_TAB.STABLE ? <StableswapImg /> : <StableswapGrey />}
                  </span>
                }
              />
              <Tab eventKey={FARM_TAB.YOU} title={FARM_TAB.YOU} />
            </Tabs>

            <div className={styles.selectForm}>
              <div className={styles.selectgroup}>
                <label htmlFor="button"> Sort by:</label>
                <button
                  id="button"
                  onClick={(ev) => toggleHidden(ev)}
                  className={`button ${styles.sortLabel}
                `}
                >
                  <span id="select-label">{sortValue}</span>
                  <span className={`material-icons ${styles.arrow} `}>keyboard_arrow_down</span>
                </button>

                <div
                  className={clsx(styles.dropdown, isOpen ? styles.show : styles.hidden)}
                  id="dropdown"
                >
                  <label className={` ${styles.sortby} ${styles.sortby} `}>SORT BY:</label>
                  <div className={styles.selectOption}>
                    <label className={styles.selectItem} htmlFor="select-apr">
                      {FARM_SORT_OPTIONS.APR}
                    </label>
                    <input
                      className={`option ${styles.option}`}
                      id="select-apr"
                      type="radio"
                      name="where"
                      value={FARM_SORT_OPTIONS.APR}
                      onClick={(ev) => setSelectTitle(ev)}
                    />
                  </div>
                  <div className={styles.selectOption}>
                    <label className={styles.selectItem} htmlFor="select-tvl">
                      {FARM_SORT_OPTIONS.TVL}
                    </label>
                    <input
                      className={`option ${styles.option}`}
                      id="select-tvl"
                      type="radio"
                      name="where"
                      value={FARM_SORT_OPTIONS.TVL}
                      onClick={(ev) => setSelectTitle(ev)}
                    />
                  </div>
                  <div className={styles.selectOption}>
                    <label className={styles.selectItem} htmlFor="select-rewards">
                      {FARM_SORT_OPTIONS.REWARDS}
                    </label>
                    <input
                      className={`option ${styles.option}`}
                      name="where"
                      id="select-rewards"
                      type="radio"
                      value={FARM_SORT_OPTIONS.REWARDS}
                      onClick={(ev) => setSelectTitle(ev)}
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div className={` mt-4 justify-between  ${styles.header2}`}>
            <div className={styles.leftDiv}>
              <InputGroup className={styles1.searchBar}>
                <InputGroup.Prepend>
                  <InputGroup.Text className="search-icon border-right-0">
                    <BsSearch />
                  </InputGroup.Text>
                </InputGroup.Prepend>
                <FormControl
                  placeholder="Search"
                  className={`shadow-none border-left-0 ${styles1.searchBox}`}
                  value={searchValue}
                  onChange={(ev) => setSearchValue(ev.target.value)}
                />
              </InputGroup>
            </div>
            <div className={styles.selectForm1}>
              <span className={styles.sortButton} onClick={() => setIsSelected(!isSelected)}>
                Sort
                <span className={clsx('material-icons', styles.arrow, isSelected && styles.rotate)}>
                  keyboard_arrow_up
                </span>
              </span>
            </div>
            <div>
              <div className={styles.rightDiv}>
                <div>
                  <Switch
                    value={props.isActiveOpen}
                    onChange={() => props.toggleFarmsType(!props.isActiveOpen)}
                    trueLabel={'Active'}
                    falseLabel={'Inactive'}
                    inverted={true}
                  />
                </div>
              </div>
            </div>
          </div>
          {isSelected && (
            <div className={`justify-between flex ${styles.mobileSort}`}>
              <div
                onClick={() => setSortValue(FARM_SORT_OPTIONS.APR)}
                className={clsx(
                  styles.sortButton,
                  sortValue === FARM_SORT_OPTIONS.APR ? styles.addbg : styles.removebg,
                )}
              >
                {FARM_SORT_OPTIONS.APR}
              </div>
              <div
                onClick={() => setSortValue(FARM_SORT_OPTIONS.TVL)}
                className={clsx(
                  styles.sortButton,
                  sortValue === FARM_SORT_OPTIONS.TVL ? styles.addbg : styles.removebg,
                )}
              >
                {FARM_SORT_OPTIONS.TVL}
              </div>
              <div
                onClick={() => setSortValue(FARM_SORT_OPTIONS.REWARDS)}
                className={clsx(
                  styles.sortButton,
                  sortValue === FARM_SORT_OPTIONS.REWARDS ? styles.addbg : styles.removebg,
                )}
              >
                {FARM_SORT_OPTIONS.REWARDS}
              </div>
            </div>
          )}
          <div className={styles.cardsContainer}>
            {farmsToRender?.map((farm) => {
              return (
                <FarmCard
                  key={`${farm.identifier}${props.isActiveOpen ? ' active' : ''}`}
                  harvestOnFarm={props.harvestOnFarm}
                  stakeOnFarm={props.stakeOnFarm}
                  openFarmsStakeModal={props.openFarmsStakeModal}
                  openFarmsUnstakeModal={props.openFarmsUnstakeModal}
                  connectWallet={props.connectWallet}
                  unstakeOnFarm={props.unstakeOnFarm}
                  isActiveOpen={props.isActiveOpen}
                  farmCardData={farm}
                  userStakes={props.userStakes}
                  harvestValueOnFarms={props.harvestValueOnFarms}
                  userAddress={props.userAddress}
                  currentBlock={props.currentBlock}
                  harvestOperation={props.harvestOperation}
                  theme={props.theme}
                  setShowConfirmTransaction={setShowConfirmTransaction}
                  setFloaterValue={setFloaterValue}
                  setLoader={props.setLoader}
                />
              );
            })}
          </div>
        </div>
      </div>
      <StakeModal
        walletBalances={props.walletBalances}
        isActiveOpen={props.isActiveOpen}
        modalData={props.stakeModal}
        open={props.stakeModal.open}
        onClose={() => props.closeFarmsStakeModal()}
        stakeOnFarm={props.stakeOnFarm}
        stakeOperation={props.stakeOperation}
        setShowConfirmTransaction={setShowConfirmTransaction}
        setFloaterValue={setFloaterValue}
        setLoader={props.setLoader}
      />
      <UnstakeModal
        modalData={props.unstakeModal}
        currentBlock={props.currentBlock}
        open={props.unstakeModal.open}
        onClose={() => {
          props.closeFarmsUnstakeModal();
        }}
        userStakes={props.userStakes}
        isActiveOpen={props.isActiveOpen}
        unstakeOnFarm={props.unstakeOnFarm}
        unstakeOperation={props.unstakeOperation}
        setShowConfirmTransaction={setShowConfirmTransaction}
        setFloaterValue={setFloaterValue}
        setLoader={props.setLoader}
      />
      <ConfirmTransaction
        show={showConfirmTransaction}
        theme={props.theme}
        content={
          floaterValue.type === 'Harvest'
            ? `${floaterValue.type} ${floaterValue.value} ${floaterValue.pair}  `
            : `${floaterValue.type} ${Number(floaterValue.value).toFixed(6)} ${
                floaterValue.pair
              } LP `
        }
        onHide={handleClose}
      />
      <FarmModals
        setLoader={props.setLoader}
        type={floaterValue.type}
        pair={floaterValue.pair}
        value={floaterValue.value}
        theme={props.theme}
        content={
          floaterValue.type === 'Harvest'
            ? `${floaterValue.type} ${floaterValue.value} ${floaterValue.pair}  `
            : `${floaterValue.type} ${Number(floaterValue.value).toFixed(6)} ${
                floaterValue.pair
              } LP `
        }
      />
    </>
  );
}
Example #5
Source File: index.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
LiquidityPage = () => {
  const {
    data = {
      summary: [],
      liquidity: [],
    },
    isLoading,
    error,
  } = useGetLiquidityQuery({ pollingInterval: 3_000 });

  const { imgPaths } = useLazyImages({ data: data.liquidity, page: 'liquidity' });

  const { isOnlyFavTokens, setIsOnlyFavTokens, favoriteTokens, editFavoriteTokenList } =
    useFavoriteToken('liquidity');

  const { valueFormat, stringSort, numberSort } = useTableNumberUtils();

  // ? Move to React Table filter later
  const finalData = useMemo(() => {
    if (isOnlyFavTokens) {
      return data.liquidity?.filter((datum) => favoriteTokens.includes(datum.pool_contract)) ?? [];
    }

    return data.liquidity;
  }, [favoriteTokens, isOnlyFavTokens, data]);

  const columns = useMemo(
    () => [
      {
        Header: (
          <TokensSymbolHeader
            className={styles.favoriteIcon}
            isOnlyFavTokens={isOnlyFavTokens}
            setIsOnlyFavTokens={setIsOnlyFavTokens}
          />
        ),
        id: 'favorite',
        accessor: 'pool_contract',
        disableSortBy: true,
        Cell: (row) => {
          return (
            <TokensSymbol
              tokenSymbol={row.value}
              className={styles.favoriteIcon}
              favoriteTokens={favoriteTokens}
              editFavoriteTokenList={editFavoriteTokenList}
            />
          );
        },
        width: 200,
      },
      {
        Header: <span className="ml-2">Name</span>,
        id: 'token',
        accessor: 'token1',
        sortType: stringSort,
        Cell: (row) => {
          const { token1, token2 } = row.row.original;
          return (
            <div className="d-flex pl-2 align-items-center">
              <TokenAvatar imgPath1={imgPaths[token1]} imgPath2={imgPaths[token2]} />
              <span className="ml-2 mr-4">
                {token1 === 'tez' ? 'TEZ' : token1 === 'ctez' ? 'CTEZ' : token1} /{' '}
                {token2 === 'tez' ? 'TEZ' : token2 === 'ctez' ? 'CTEZ' : token2}
              </span>
            </div>
          );
        },
        width: 120,
      },
      {
        Header: (
          <span className="flex align-center">
            Liquidity&nbsp;
            <Tooltip id={'liquidity-header'} message={'The value of tokens staked in the pool.'} />
          </span>
        ),
        id: 'liquidity',
        accessor: 'total_liquidity',
        sortType: numberSort,
        Cell: (row) => <span title={row.value}>{valueFormat(row.value)}</span>,
      },
      {
        Header: 'Daily Volume',
        accessor: '24h_volume',
        sortType: numberSort,
        Cell: (row) => <span>{valueFormat(row.value)}</span>,
      },
      {
        Header: 'Weekly Fees',
        accessor: '24h_fee',
        sortType: numberSort,
        Cell: (row) => <span>{valueFormat(row.value)}</span>,
      },
      {
        Header: (
          <span className="flex align-center">
            LP APR&nbsp;
            <Tooltip id={'lp-apr-header'} message={'Based on the annualized trading fees.'} />
          </span>
        ),
        accessor: 'lp_apr',
        sortType: numberSort,
        Cell: (row) => <span>{valueFormat(row.value ?? 0, { percentChange: true })}%</span>,
      },
      {
        Header: (
          <span className="flex align-center">
            Farm&nbsp;
            <Tooltip
              id={'farm-header'}
              message={'Active indicates a farm for the LP tokens of the liquidity pool.'}
            />
          </span>
        ),
        accessor: 'pool_contract',
        sortType: numberSort,
        Cell: (row) => (isActiveFarm(row.value) ? <span>Active</span> : null),
      },
      {
        disableSortBy: true,
        Header: '',
        id: 'trade',
        accessor: (x) => (
          <div className="d-flex">
            <Link
              style={{ textDecoration: 'none' }}
              to={{
                pathname: '/liquidity',
                search: `?${createSearchParams({
                  tokenA: x.token1,
                  tokenB: x.token2,
                })}`,
              }}
            >
              <Button color="primary" isIconBtn startIcon="add" iconBtnType="square" size="large" />
            </Link>

            <Link
              className="ml-2"
              style={{ textDecoration: 'none' }}
              to={{
                pathname: '/swap',
                search: `?${createSearchParams({
                  from: x.token1,
                  to: x.token2,
                })}`,
              }}
            >
              <Button
                color="default"
                isIconBtn
                startIcon="swap_vert"
                iconBtnType="square"
                size="large"
              />
            </Link>
          </div>
        ),
        width: 120,
      },
    ],
    [
      isOnlyFavTokens,
      setIsOnlyFavTokens,
      stringSort,
      numberSort,
      favoriteTokens,
      editFavoriteTokenList,
      imgPaths,
    ],
  );

  const [searchQuery, setSearchQuery] = useState('');

  return (
    <>
      <LiquiditySummary data={data.summary} />

      <Container fluid className={clsx(styles.tokens, styles.liquidityTable)}>
        <div className="w-100 d-flex justify-content-between px-5 align-items-center">
          <h5 className="font-weight-bolder">Liquidity Pools</h5>
          <InputGroup className={styles.searchBar}>
            <InputGroup.Prepend>
              <InputGroup.Text className={`${styles.searchIcon} border-right-0`}>
                <BsSearch />
              </InputGroup.Text>
            </InputGroup.Prepend>
            <FormControl
              placeholder="Search"
              className={`shadow-none border-left-0 ${styles.searchBox}`}
              value={searchQuery}
              onChange={(ev) => setSearchQuery(ev.target.value)}
            />
          </InputGroup>
        </div>

        {data.liquidity.length > 0 && (
          <div>
            <Table searchQuery={searchQuery} data={finalData} columns={columns} />
          </div>
        )}

        {data.liquidity.length === 0 && (isLoading || error) && (
          <div className="d-flex justify-content-between w-100" style={{ height: 800 }}>
            <div className="m-auto">
              {error ? <div>Something went wrong</div> : <PuffLoader color={'#813CE1'} size={56} />}
            </div>
          </div>
        )}
      </Container>

      <FavoriteIconGradient />
    </>
  );
}
Example #6
Source File: Tokens.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
Tokens = () => {
  const {
    data = [],
    isLoading,
    error,
  } = useGetTokensQuery(undefined, {
    pollingInterval: 30_000,
  });

  const { data: priceChangeData = {}, isLoading: priceChangeLoading } = useGet7DaysChangeQuery(
    undefined,
    {
      pollingInterval: 30_000,
    },
  );

  const { imgPaths } = useLazyImages({ data });

  const { isOnlyFavTokens, setIsOnlyFavTokens, favoriteTokens, editFavoriteTokenList } =
    useFavoriteToken('token');

  const { positiveOrNegative, valueFormat, stringSort, numberSort } = useTableNumberUtils();

  // ? Move to React Table filter later
  const finalData = useMemo(() => {
    if (isOnlyFavTokens) {
      return data?.filter((datum) => favoriteTokens.includes(datum.symbol_token)) ?? [];
    }

    return data;
  }, [favoriteTokens, isOnlyFavTokens, data]);

  const columns = useMemo(
    () => [
      {
        Header: (
          <TokensSymbolHeader
            className={styles.favoriteIcon}
            isOnlyFavTokens={isOnlyFavTokens}
            setIsOnlyFavTokens={setIsOnlyFavTokens}
          />
        ),
        id: 'favorite',
        accessor: 'symbol_token',
        disableSortBy: true,
        Cell: (row) => (
          <TokensSymbol
            tokenSymbol={row.value}
            className={styles.favoriteIcon}
            favoriteTokens={favoriteTokens}
            editFavoriteTokenList={editFavoriteTokenList}
          />
        ),
      },
      {
        Header: <span className="ml-2">Name</span>,
        id: 'token',
        accessor: 'symbol_token',
        sortType: stringSort,
        Cell: (row) => (
          <div className="d-flex pl-2 align-items-center">
            <Image src={imgPaths[row.value]?.url} height={32} width={32} alt={''} />
            <span className="ml-2 mr-4">
              {row.value === 'tez' ? 'TEZ' : row.value === 'ctez' ? 'CTEZ' : row.value}
            </span>
          </div>
        ),
        width: 120,
      },
      {
        Header: 'Price',
        accessor: 'token_price',
        sortType: numberSort,
        Cell: (row) => <span title={row.value}>{valueFormat(row.value)}</span>,
      },
      {
        Header: '24h Change',
        accessor: 'price_change_percentage',
        sortType: numberSort,
        Cell: (row) => (
          <span>{positiveOrNegative(valueFormat(row.value, { percentChange: true }))}</span>
        ),
      },
      {
        Header: '24h Volume',
        accessor: 'volume_token',
        sortType: numberSort,
        Cell: (row) => <span>{valueFormat(row.value)}</span>,
      },
      {
        Header: 'Liquidity',
        accessor: 'liquidity',
        sortType: numberSort,
        Cell: (row) => <span>{valueFormat(row.value)}</span>,
      },
      {
        id: 'price7d',
        Header: 'Last 7 Days',
        accessor: 'symbol_token',
        Cell: (row) => {
          let value = [...(priceChangeData[row.value] ?? [])].reverse();

          if (priceChangeLoading) return <div />;

          if (value.length === 0) return <div>N/A</div>;

          const changePositive = value[value.length - 1].value >= value[0].value;

          if (value.length <= 38) {
            const timeData = priceChangeData.PLENTY.map((x) => ({
              ...x,
              value: undefined,
            })).reverse();
            value = [...timeData.filter((x) => x.time < value[0].time), ...value];
          }

          return (
            <SimpleLineChart
              data={value}
              color={changePositive ? '#4FBF67' : '#FF7A68'}
              className="mx-2"
            />
          );
        },
        minWidth: 170,
        disableSortBy: true,
      },
      {
        disableSortBy: true,
        Header: '',
        id: 'trade',
        accessor: (x) => (
          <Link style={{ textDecoration: 'none' }} to={`/swap?from=${x.symbol_token}`}>
            <Button color="primary" className={styles.tradeBtn}>
              Trade
            </Button>
          </Link>
        ),
        width: 120,
      },
    ],
    [
      isOnlyFavTokens,
      setIsOnlyFavTokens,
      stringSort,
      numberSort,
      favoriteTokens,
      editFavoriteTokenList,
      imgPaths,
      priceChangeData,
      priceChangeLoading,
    ],
  );

  const [searchQuery, setSearchQuery] = useState('');

  return (
    <>
      <Container fluid className={clsx(styles.tokens, styles.tokensTable)}>
        <div className="w-100 d-flex justify-content-between px-5 align-items-center">
          <h5 className="font-weight-bolder">Tokens</h5>
          <InputGroup className={styles.searchBar}>
            <InputGroup.Prepend>
              <InputGroup.Text className={`${styles.searchIcon} border-right-0`}>
                <BsSearch />
              </InputGroup.Text>
            </InputGroup.Prepend>
            <FormControl
              placeholder="Search"
              className={`shadow-none border-left-0 ${styles.searchBox}`}
              value={searchQuery}
              onChange={(ev) => setSearchQuery(ev.target.value)}
            />
          </InputGroup>
        </div>

        {data.length > 0 && (
          <div>
            <Table searchQuery={searchQuery} data={finalData} columns={columns} />
          </div>
        )}

        {data.length === 0 && (isLoading || error) && (
          <div className="d-flex justify-content-between w-100" style={{ height: 800 }}>
            <div className="m-auto">
              {error ? <div>Something went wrong</div> : <PuffLoader color={'#813CE1'} size={56} />}
            </div>
          </div>
        )}
      </Container>

      <FavoriteIconGradient />
    </>
  );
}
Example #7
Source File: LocationFilter.jsx    From covince with MIT License 4 votes vote down vote up
LocationFilter = (props) => {
  const {
    className, loading, onChange,
    category, heading, subheading, showOverviewButton, loadOverview, overview,
    isSearching, setIsSearching, filteredItems, searchTerm, setSearchTerm
  } = props

  const searchButtonRef = useRef()
  const onSearchClose = useCallback(() => {
    setIsSearching(false)
  }, [setIsSearching])

  const previousIsSearching = useRef()
  useEffect(() => {
    if (previousIsSearching.current === true && isSearching === false) {
      searchButtonRef.current.focus()
    }
    previousIsSearching.current = isSearching
  }, [isSearching])

  const isMobile = useMobile()
  const { ontology } = useConfig()
  const { noun_plural, search_placeholder = noun_plural } = ontology.area

  return (
    <div className={className}>
      { isSearching
        ? <>
          <div className='flex justify-between items-center h-6 mb-3'>
            <DescriptiveHeading className='whitespace-nowrap'>
              Search
            </DescriptiveHeading>
            <Button
              className='box-content relative z-10 h-6 pt-0 pb-0 pl-1 pr-1'
              title='Close'
              onClick={onSearchClose}
            >
              <HiX className='h-4 w-4 fill-current text-gray-600 dark:text-gray-300' />
            </Button>
          </div>
          <ComboBox
            ariaLabel='Areas'
            items={filteredItems}
            onChange={setSearchTerm}
            onClose={onSearchClose}
            onSelect={onChange}
            placeholder={search_placeholder}
            popover={isMobile ? MobilePopover : undefined}
            value={searchTerm}
          />
        </>
        : <>
          <div className='flex justify-between items-center h-6'>
            <DescriptiveHeading className='whitespace-nowrap'>
              {category}
            </DescriptiveHeading>
            { showOverviewButton &&
              <Button
                title='Return to overview'
                className='relative z-10 -top-0.5 h-6 pl-0.5 pr-2 flex items-center !text-primary hover:bg-gray-50'
                onClick={loadOverview}
                tabIndex={isSearching ? '-1' : undefined}
              >
                <BsArrowUpShort className='h-6 w-6 fill-current' />
                {overview.short_heading}
              </Button> }
          </div>
          <div className='flex justify-between space-x-2 w-full'>
            <div className='flex-shrink min-w-0'>
              <Heading className='relative z-0 leading-6 truncate my-0.5'>
                {heading}
              </Heading>
              <p className='text-sm leading-6 h-6 text-gray-600 dark:text-gray-400 font-medium'>
                {subheading}
              </p>
            </div>
            <Button
              ref={searchButtonRef}
              className='flex-shrink-0 h-10 md:h-8 w-11 md:w-9 flex items-center justify-center mt-0.5'
              onClick={() => setIsSearching(true)} title='Search areas'
              tabIndex={isSearching ? '-1' : undefined}
            >
              <BsSearch className='flex-shrink-0 h-5 md:h-4 w-5 md:w-4 text-current' />
            </Button>
          </div>
        </> }
      <FadeTransition in={loading}>
        <div className='bg-white dark:bg-gray-700 absolute inset-1 grid place-content-center z-10'>
          <Spinner className='text-gray-500 dark:text-gray-300 w-6 h-6 mt-2' />
        </div>
      </FadeTransition>
    </div>
  )
}