Skip to content

Commit

Permalink
feat(Addresses): allow search
Browse files Browse the repository at this point in the history
see #59
  • Loading branch information
KayBeSee committed Oct 21, 2022
1 parent fb78938 commit fb5ca28
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { SortOptions } from '.';
interface Props {
searchQuery: string;
setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
toggleSort: () => void;
sort: SortOptions;
setShowTags: React.Dispatch<React.SetStateAction<boolean>>;
showTags: boolean;
toggleSort?: () => void;
sort?: SortOptions;
setShowTags?: React.Dispatch<React.SetStateAction<boolean>>;
showTags?: boolean;
}

export const SearchToolbar = ({
Expand All @@ -27,7 +27,7 @@ export const SearchToolbar = ({
showTags
}: Props) => {
return (
<div className='flex h-16 justify-between dark:bg-slate-800 px-4 border-t border-b border-gray-700/20 dark:border-slate-500/20'>
<div className='flex h-16 justify-between bg-transparent px-4 border-t border-b border-gray-700/20 dark:border-slate-500/20'>
<div className='flex flex-1 py-2'>
<form className='flex w-full lg:ml-0'>
<label htmlFor='search-field' className='sr-only'>
Expand All @@ -39,7 +39,7 @@ export const SearchToolbar = ({
</div>
<input
id='search-field'
className='block h-full w-full border-transparent dark:bg-slate-800 dark:text-slate-200 py-2 pl-8 pr-3 text-gray-900 placeholder-gray-500 focus:border-transparent focus:placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-sm'
className='block h-full w-full border-transparent bg-transparent dark:text-slate-200 py-2 pl-8 pr-3 text-gray-900 placeholder-gray-500 focus:border-transparent focus:placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-sm'
placeholder='Search'
type='text'
name='search'
Expand All @@ -52,41 +52,45 @@ export const SearchToolbar = ({
</div>
<div className='flex items-center'>
<div className='ml-1 flex items-center lg:ml-2'>
{toggleSort ? (
<button
type='button'
className={classNames(
!!sort
? 'bg-green-200 hover:bg-green-300 dark:bg-green-600 active:bg-green-400 dark:active:bg-green-800'
: 'bg-transparent hover:bg-gray-100 hover:border hover:border-gray-400 dark:hover:bg-green-700 active:bg-gray-200 dark:active:bg-green-800',
'inline-flex items-center rounded-md border border-transparent px-2 py-1 text-xs font-medium dark:text-white shadow-sm focus:outline-none focus:ring-2 ring-green-500'
)}
onClick={() => {
toggleSort();
}}
>
{sort === 'asc' ? (
<SortAscendingIcon className='w-4 h-4' />
) : (
<SortDescendingIcon className='w-4 h-4' />
)}
</button>
) : null}
</div>
</div>
<div className='ml-1 flex items-center lg:ml-2'>
{setShowTags ? (
<button
type='button'
className={classNames(
!!sort
showTags
? 'bg-green-200 hover:bg-green-300 dark:bg-green-600 active:bg-green-400 dark:active:bg-green-800'
: 'bg-transparent hover:bg-gray-100 hover:border hover:border-gray-400 dark:hover:bg-green-700 active:bg-gray-200 dark:active:bg-green-800',
'inline-flex items-center rounded-md border border-transparent px-2 py-1 text-xs font-medium dark:text-white shadow-sm focus:outline-none focus:ring-2 ring-green-500'
)}
onClick={() => {
toggleSort();
setShowTags(!showTags);
}}
>
{sort === 'asc' ? (
<SortAscendingIcon className='w-4 h-4' />
) : (
<SortDescendingIcon className='w-4 h-4' />
)}
<TagIcon className='w-4 h-4' />
</button>
</div>
</div>
<div className='ml-1 flex items-center lg:ml-2'>
<button
type='button'
className={classNames(
showTags
? 'bg-green-200 hover:bg-green-300 dark:bg-green-600 active:bg-green-400 dark:active:bg-green-800'
: 'bg-transparent hover:bg-gray-100 hover:border hover:border-gray-400 dark:hover:bg-green-700 active:bg-gray-200 dark:active:bg-green-800',
'inline-flex items-center rounded-md border border-transparent px-2 py-1 text-xs font-medium dark:text-white shadow-sm focus:outline-none focus:ring-2 ring-green-500'
)}
onClick={() => {
setShowTags(!showTags);
}}
>
<TagIcon className='w-4 h-4' />
</button>
) : null}
</div>
</div>
);
Expand Down
19 changes: 11 additions & 8 deletions apps/frontend/src/pages/Send/components/SelectInputsForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,17 @@ export const SelectInputsForm = ({ currentAccount, onSave, cancel, requiredSendA
</p>
</div>

<SearchToolbar
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
showTags={showTags}
setShowTags={setShowTags}
toggleSort={toggleSort}
sort={sort}
/>
<div className='dark:bg-slate-800'>
<SearchToolbar
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
showTags={showTags}
setShowTags={setShowTags}
toggleSort={toggleSort}
sort={sort}
/>
</div>

<div className='bg-gray-200 dark:bg-slate-900 overflow-y-auto flex-grow'>
<ul className='overflow-auto space-y-4 py-4 px-5'>
{[...filteredUtxos].map((utxo) => {
Expand Down
95 changes: 63 additions & 32 deletions apps/frontend/src/pages/Vault/Settings/Addresses/AddressRow.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useContext, useEffect, useState } from 'react';
import styled from 'styled-components';

import { Badge } from 'src/components';
import { Badge, SlideOver } from 'src/components';

import { LabelTag } from './LabelTag';
import AddressDetailsSlideover from './AddressDetailsSlideover';

import { gray500 } from 'src/utils/colors';
import { classNames } from 'src/utils/other';
Expand All @@ -14,50 +15,80 @@ import { PlatformContext } from 'src/context';
interface Props {
address: Address;
status: 'used' | 'unused';
onClick: () => void;
searchQuery?: string;
}

const AddressRow = ({ address, status, onClick }: Props) => {
const AddressRow = ({ address, status, searchQuery = '' }: Props) => {
const { platform } = useContext(PlatformContext);
const [labels, setLabels] = useState<AddressLabel[]>([]);
const [hidden, setHidden] = useState(false);

const [slideoverIsOpen, setSlideoverOpen] = useState(false);
const [slideoverContent, setSlideoverContent] = useState<JSX.Element | null>(null);

const openInSlideover = (component: JSX.Element) => {
setSlideoverOpen(true);
setSlideoverContent(component);
};

useEffect(() => {
const retrieveLabels = async () => {
const currentLabels = await platform.getAddressLabels(address.address);
setLabels(currentLabels);
};
retrieveLabels();
}, [address]);
}, [slideoverIsOpen]);

useEffect(() => {
const labelMatch = labels.some((label) => label.label.toLowerCase().includes(searchQuery));
const addressMatch = address.address.includes(searchQuery);

console.log('labelMatch: ', labelMatch);
console.log('addressMatch: ', addressMatch);

const visible = labelMatch || addressMatch;

setHidden(!visible);
}, [searchQuery, labels]);

if (hidden) {
return null;
}

return (
<tr
className='cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 py-2 items-center flex justify-between'
onClick={() => onClick()}
>
<td className=''>
<UtxoHeader className='text-gray-900 dark:text-gray-200'>{address.address}</UtxoHeader>
{/* <UtxoSubheader>{address.bip32derivation[0].path}</UtxoSubheader> */}
</td>
<td className='flex justify-end items-center space-x-1'>
<ul className='space-x-1'>
{labels.map((label) => (
<li className='inline' key={label.id}>
<LabelTag label={label} />
</li>
))}
</ul>
<Badge
className={classNames(
status === 'used'
? 'bg-yellow-100 dark:bg-yellow-600 text-yellow-800 dark:text-yellow-100'
: 'bg-green-100 dark:bg-green-600 text-green-800 dark:text-green-100'
)}
style={{ marginRight: '1em' }}
>
{status}
</Badge>
</td>
</tr>
<>
<button
className='w-full cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 py-2 items-center flex justify-between'
onClick={() =>
openInSlideover(<AddressDetailsSlideover address={address} setOpen={setSlideoverOpen} />)
}
>
<td className=''>
<UtxoHeader className='text-gray-900 dark:text-gray-200'>{address.address}</UtxoHeader>
{/* <UtxoSubheader>{address.bip32derivation[0].path}</UtxoSubheader> */}
</td>
<td className='flex justify-end items-center space-x-1'>
<ul className='space-x-1 flex overflow-x-auto max-w-xs'>
{labels.map((label) => (
<li className='inline' key={label.id}>
<LabelTag label={label} />
</li>
))}
</ul>
<Badge
className={classNames(
status === 'used'
? 'bg-yellow-100 dark:bg-yellow-600 text-yellow-800 dark:text-yellow-100'
: 'bg-green-100 dark:bg-green-600 text-green-800 dark:text-green-100'
)}
style={{ marginRight: '1em' }}
>
{status}
</Badge>
</td>
</button>
<SlideOver open={slideoverIsOpen} setOpen={setSlideoverOpen} content={slideoverContent} />
</>
);
};

Expand Down
48 changes: 13 additions & 35 deletions apps/frontend/src/pages/Vault/Settings/Addresses/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import AddressRow from './AddressRow';

import { requireOnchain } from 'src/hocs';

import { SettingsTable, SlideOver } from 'src/components';
import { SettingsTable } from 'src/components';
import { LilyOnchainAccount } from '@lily/types';

import AddressDetailsSlideover from './AddressDetailsSlideover';
import { SearchToolbar } from 'src/pages/Send/components/SelectInputsForm/SearchToolbar';

import { classNames } from 'src/utils/other';

Expand All @@ -20,14 +20,7 @@ const tabs = ['Receive', 'Change'];
const AddressesView = ({ currentAccount }: Props) => {
const { addresses, unusedAddresses, changeAddresses, unusedChangeAddresses } = currentAccount;
const [activeTab, setActiveTab] = useState(tabs[0]);

const [slideoverIsOpen, setSlideoverOpen] = useState(false);
const [slideoverContent, setSlideoverContent] = useState<JSX.Element | null>(null);

const openInSlideover = (component: JSX.Element) => {
setSlideoverOpen(true);
setSlideoverContent(component);
};
const [searchQuery, setSearchQuery] = useState('');

return (
<>
Expand All @@ -38,6 +31,8 @@ const AddressesView = ({ currentAccount }: Props) => {
</SettingsTable.HeaderSubtitle>
</SettingsTable.HeaderSection>

<SearchToolbar searchQuery={searchQuery} setSearchQuery={setSearchQuery} />

<div className='border-b border-gray-200'>
<nav className='-mb-px flex space-x-8' aria-label='Tabs'>
{tabs.map((tab) => (
Expand All @@ -64,30 +59,22 @@ const AddressesView = ({ currentAccount }: Props) => {
<table className='border-collapse w-full'>
<tbody className='divide-y dark:divide-slate-400/10'>
{activeTab === 'Receive'
? addresses.map((address) => (
? unusedAddresses.map((address) => (
<AddressRow
key={address.address}
address={address}
status='used'
onClick={() =>
openInSlideover(
<AddressDetailsSlideover address={address} setOpen={setSlideoverOpen} />
)
}
status='unused'
searchQuery={searchQuery}
/>
))
: null}
{activeTab === 'Receive'
? unusedAddresses.map((address) => (
? addresses.map((address) => (
<AddressRow
key={address.address}
address={address}
status='unused'
onClick={() =>
openInSlideover(
<AddressDetailsSlideover address={address} setOpen={setSlideoverOpen} />
)
}
status='used'
searchQuery={searchQuery}
/>
))
: null}
Expand All @@ -97,11 +84,7 @@ const AddressesView = ({ currentAccount }: Props) => {
key={address.address}
address={address}
status='used'
onClick={() =>
openInSlideover(
<AddressDetailsSlideover address={address} setOpen={setSlideoverOpen} />
)
}
searchQuery={searchQuery}
/>
))
: null}
Expand All @@ -111,11 +94,7 @@ const AddressesView = ({ currentAccount }: Props) => {
key={address.address}
address={address}
status='unused'
onClick={() =>
openInSlideover(
<AddressDetailsSlideover address={address} setOpen={setSlideoverOpen} />
)
}
searchQuery={searchQuery}
/>
))
: null}
Expand All @@ -124,7 +103,6 @@ const AddressesView = ({ currentAccount }: Props) => {
</div>
</div>
</div>
<SlideOver open={slideoverIsOpen} setOpen={setSlideoverOpen} content={slideoverContent} />
</>
);
};
Expand Down

0 comments on commit fb5ca28

Please sign in to comment.