Skip to content

Commit

Permalink
feat(app): add csr in search (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
yudhomax authored Oct 15, 2024
1 parent 2dd7cf7 commit 6f2b211
Show file tree
Hide file tree
Showing 46 changed files with 240 additions and 975 deletions.
1 change: 1 addition & 0 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"next-sitemap": "4.2.3",
"next-themes": "^0.3.0",
"next-translate": "2.6.2",
"nextjs-toploader": "3.7.15",
"qs": "^6.12.3",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/components/Address/Receipts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ const Receipts = ({ txns, count, error, cursor, tab }: TxnsProps) => {
className="absolute h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words"
>
<span
className={`truncate max-w-[120px] inline-block align-bottom text-green-500 dark:text-green-250 whitespace-nowrap border rounded-md ${
className={`truncate max-w-[120px] inline-block align-bottom text-green-500 p-0.5 px-1 dark:text-green-250 whitespace-nowrap border rounded-md ${
row?.transaction_hash === address
? 'bg-[#FFC10740] border-[#FFC10740] dark:bg-black-200 dark:border-neargray-50 border-dashed cursor-pointer text-[#033F40]'
: 'text-green-500 dark:text-green-250 border-transparent'
Expand Down
39 changes: 3 additions & 36 deletions apps/app/src/components/Address/Transactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,42 +194,7 @@ const Transactions = ({ txns, count, error, cursor, tab }: TxnsProps) => {
'px-4 py-4 text-left whitespace-nowrap text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider',
},
{
header: (
<Menu>
<MenuButton className="flex items-center px-4 py-4 text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider focus:outline-none">
{t ? t('txns:type') : 'METHOD'}{' '}
<Filter className="h-4 w-4 fill-current ml-2" />
</MenuButton>
<MenuList className="bg-white shadow-lg border rounded-b-lg p-2">
<form onSubmit={onFilter} className="flex flex-col">
<input
name="type"
value={form.action || form.method}
onChange={onChange}
placeholder="Search by method"
className="border dark:border-black-200 rounded h-8 mb-2 px-2 text-nearblue-600 dark:text-neargray-10 text-xs"
/>
<div className="flex">
<button
type="submit"
className="flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white dark:text-black text-xs mr-2"
>
<Filter className="h-3 w-3 fill-current mr-2" />{' '}
{t ? t('txns:filter.filter') : 'Filter'}
</button>
<button
name="type"
type="button"
onClick={onClear}
className="flex-1 rounded bg-gray-300 dark:bg-black-200 dark:text-white text-xs h-7"
>
{t ? t('txns:filter.clear') : 'Clear'}
</button>
</div>
</form>
</MenuList>
</Menu>
),
header: <span className="pl-2"> {t ? t('txns:type') : 'METHOD'}</span>,
key: 'actions',
cell: (row: TransactionInfo) => (
<span>
Expand All @@ -247,6 +212,8 @@ const Transactions = ({ txns, count, error, cursor, tab }: TxnsProps) => {
),
tdClassName:
'px-4 py-2 whitespace-nowrap text-sm text-nearblue-600 dark:text-neargray-10',
thClassName:
'px-4 py-4 text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider whitespace-nowrap',
},
{
header: <span>{t ? t('txns:depositValue') : 'DEPOSIT VALUE'}</span>,
Expand Down
15 changes: 2 additions & 13 deletions apps/app/src/components/Layouts/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,9 @@ const languages = [
interface Props {
statsDetails?: { stats: Stats[] };
latestBlocks?: { blocks: BlocksInfo[] };
searchResultDetails?: any;
searchRedirectDetails?: any;
}

const Header = ({
statsDetails,
latestBlocks,
searchResultDetails,
searchRedirectDetails,
}: Props) => {
const Header = ({ statsDetails, latestBlocks }: Props) => {
/* eslint-disable @next/next/no-img-element */

const router = useRouter();
Expand Down Expand Up @@ -301,11 +294,7 @@ const Header = ({
{showSearch && (
<div className="relative h-full w-full md:!w-3/4 lg:!w-3/5 md:!ml-auto px-3 md:!pt-2 md:!pb-0 order-2 md:!order-1">
<div className="h-11">
<Search
result={searchResultDetails}
redirectResult={searchRedirectDetails}
header
/>
<Search header />
</div>
</div>
)}
Expand Down
29 changes: 14 additions & 15 deletions apps/app/src/components/Layouts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { ReactNode } from 'react';
import { ReactNode, useEffect, useState } from 'react';
import Header from './Header';
import Footer from './Footer';
import { useRouter } from 'next/router';
import { BlocksInfo, Stats } from '@/utils/types';
import useLoading from '@/hooks/useLoading';
import { Spinner } from '../common/Spinner';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import NextTopLoader from 'nextjs-toploader';
import { useTheme } from 'next-themes';

interface LayoutProps {
children: ReactNode;
notice?: ReactNode;
statsDetails?: { stats: Stats[] };
latestBlocks?: { blocks: BlocksInfo[] };
searchResultDetails?: any;
searchRedirectDetails?: any;
}

const Layout = ({
children,
notice,
statsDetails,
latestBlocks,
searchResultDetails,
searchRedirectDetails,
}: LayoutProps) => {
const router = useRouter();
const { loading, setLoading } = useLoading();
const [isMounted, setIsMounted] = useState(false);
const { theme } = useTheme();

useEffect(() => {
setIsMounted(true);
}, []);

const className =
router.pathname === '/404'
? 'bg-white dark:bg-black-300'
Expand All @@ -36,14 +38,11 @@ const Layout = ({
<div className={className}>
{notice}
<header>
<Header
statsDetails={statsDetails}
latestBlocks={latestBlocks}
searchResultDetails={searchResultDetails}
searchRedirectDetails={searchRedirectDetails}
/>
<Header statsDetails={statsDetails} latestBlocks={latestBlocks} />
</header>
{loading && <Spinner loading={loading} setLoading={setLoading} />}
{isMounted && (
<NextTopLoader color={`${theme === 'dark' ? '#31766A' : '#0d494a'}`} />
)}
<ToastContainer />
<main>{children}</main>
<Footer />
Expand Down
10 changes: 5 additions & 5 deletions apps/app/src/components/Tokens/NFT/Transfers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const Transfers = ({ txns, count, cursor, error, tab }: Props) => {
'px-5 py-4 whitespace-nowrap text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider',
},
{
header: <span>METHOD</span>,
header: <span className="pl-2">METHOD</span>,
key: 'cause',
cell: (row: TransactionInfo) => (
<span>
Expand All @@ -95,7 +95,7 @@ const Transfers = ({ txns, count, cursor, error, tab }: Props) => {
'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider',
},
{
header: <span>From</span>,
header: <span className="pl-1">From</span>,
key: 'affected_account_id',
cell: (row: TransactionInfo) => {
return Number(row.delta_amount) < 0 ? (
Expand Down Expand Up @@ -161,9 +161,9 @@ const Transfers = ({ txns, count, cursor, error, tab }: Props) => {
);
},
tdClassName:
'px-5 py-3 whitespace-nowrap text-sm text-nearblue-600 dark:text-neargray-10 font-medium',
'px-3 py-3 whitespace-nowrap text-sm text-nearblue-600 dark:text-neargray-10 font-medium',
thClassName:
'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider',
'px-3 py-3 text-left text-xs font-semibold text-nearblue-600 dark:text-neargray-10 uppercase tracking-wider',
},
{
header: <span></span>,
Expand All @@ -182,7 +182,7 @@ const Transfers = ({ txns, count, cursor, error, tab }: Props) => {
tdClassName: 'text-center',
},
{
header: <span>To</span>,
header: <span className="pl-1">To</span>,
key: 'involved_account_id',
cell: (row: TransactionInfo) => {
return Number(row.delta_amount) < 0 ? (
Expand Down
33 changes: 18 additions & 15 deletions apps/app/src/components/Transactions/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,33 @@ const Details = (props: Props) => {
let nfts: NftsInfo[] = [];

receipts &&
receipts.forEach(
receipts?.forEach(
(receipt) =>
receipt?.fts?.forEach((ft) => {
if (ft.ft_meta && ft.cause === 'TRANSFER') {
if (ft.ft_meta && Number(ft.delta_amount) < 0) fts.push(ft);
if (ft?.ft_meta && ft.cause === 'TRANSFER') {
if (ft?.ft_meta && Number(ft?.delta_amount) < 0) fts?.push(ft);
} else {
if (ft.ft_meta) fts.push(ft);
if (ft?.ft_meta) fts?.push(ft);
}
}),
);
receipts &&
receipts.forEach(
receipts?.forEach(
(receipt) =>
receipt?.nfts?.forEach((nft) => {
if (
nft.nft_meta &&
nft.nft_token_meta &&
nft.cause === 'TRANSFER'
nft?.nft_meta &&
nft?.nft_token_meta &&
nft?.cause === 'TRANSFER'
) {
if (
nft.nft_meta &&
nft.nft_token_meta &&
Number(nft.delta_amount) < 0
nft?.nft_meta &&
nft?.nft_token_meta &&
Number(nft?.delta_amount) < 0
)
nfts.push(nft);
nfts?.push(nft);
} else {
if (nft.nft_meta && nft.nft_token_meta) nfts.push(nft);
if (nft?.nft_meta && nft?.nft_token_meta) nfts?.push(nft);
}
}),
);
Expand All @@ -103,7 +103,7 @@ const Details = (props: Props) => {
}

if (txn?.receipts?.length) {
return tokensTransfers(txn.receipts);
return tokensTransfers(txn?.receipts);
}

return { fts: [], nfts: [] };
Expand Down Expand Up @@ -836,7 +836,10 @@ const Details = (props: Props) => {
|
</span>{' '}
{txn?.receipt_conversion_tokens_burnt
? yoctoToNear(txn.receipt_conversion_tokens_burnt, true)
? yoctoToNear(
txn?.receipt_conversion_tokens_burnt,
true,
)
: txn?.receipt_conversion_tokens_burnt ?? ''}{' '}
</div>
Expand Down
69 changes: 16 additions & 53 deletions apps/app/src/components/common/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { networkId } from '@/utils/config';
import ArrowDown from '../Icons/ArrowDown';
import { localFormat, shortenAddress, shortenHex } from '@/utils/libs';
import SearchIcon from '../Icons/SearchIcon';
import search from '@/utils/search';

export const SearchToast = () => {
if (networkId === 'testnet') {
Expand Down Expand Up @@ -55,19 +56,13 @@ export const redirect = (route: any) => {
}
};

const Search = ({
header = false,
result = {} as any,
redirectResult = {} as any,
}) => {
const Search = ({ header = false }) => {
const router = useRouter();
const { t } = useTranslation('common');
const [keyword, setKeyword] = useState('');
const [result, setResult] = useState({} as any);
const [filter, setFilter] = useState('all');

const query = router?.query?.query;
const q = typeof query === 'string' ? query.replace(/[\s,]/g, '') : '';

const homeSearch = router.pathname === '/';

const showResults =
Expand All @@ -76,51 +71,20 @@ const Search = ({
result?.accounts?.length > 0 ||
result?.receipts?.length > 0;

useEffect(() => {
const redirects = (route: any) => {
switch (route?.type) {
case 'block':
return router.push(`/blocks/${route?.path}`);
case 'txn':
case 'receipt':
return router.push(`/txns/${route?.path}`);
case 'address':
return router.push(`/address/${route?.path}`);
default:
return toast.error(SearchToast);
}
};

if (q) {
redirects(redirectResult);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [q, redirectResult]);

useEffect(() => {
if (filter && keyword) {
const { query, ...currentQuery } = router.query;
const newQuery = {
...currentQuery,
keyword: keyword,
filter: filter,
};
router.push({
pathname: router.pathname,
query: newQuery,
});
search(keyword, filter).then((data) => setResult(data || {}));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filter, keyword]);

// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedSave = useCallback(
debounce((nextValue) => setKeyword(nextValue), 300),
debounce((nextValue) => setKeyword(nextValue), 500),
[],
);

const handleChange = (event: any) => {
const { value: nextValue } = event.target;
const { value: nextValue } = event?.target;
debouncedSave(nextValue.replace(/[\s,]/g, ''));
};

Expand All @@ -134,19 +98,18 @@ const Search = ({
const text = (
document.getElementsByClassName('search')[0] as HTMLInputElement
).value;
const qs = text.replace(/[\s,]/g, '');

const { query, keyword, ...currentQuery } = router.query;
const newQuery = {
...currentQuery,
query: qs,
filter: filter,
};
const query = text.replace(/[\s,]/g, '');

if (!query) return toast.error(SearchToast);

const route = await search(query, filter, true);

if (route) {
return redirect(route);
}

return router.push({
pathname: router.pathname,
query: newQuery,
});
return toast.error(SearchToast);
};

return (
Expand Down
Loading

0 comments on commit 6f2b211

Please sign in to comment.