Skip to content

Commit ecc1f29

Browse files
authored
feat: add auto complete function (#44)
1 parent 08f359d commit ecc1f29

File tree

16 files changed

+249
-35
lines changed

16 files changed

+249
-35
lines changed

apps/etdstats/lib/Layout.tsx

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { AppBar, Box, Drawer, Stack, Toolbar } from "@mui/material";
22
import { useRouter } from "next/router";
33

4-
import React from "react";
4+
import React, { useCallback } from "react";
55
import {
66
ConnectWalletButton,
77
NextCirculatProgressBar,
88
UniversalSearchButton,
99
} from "ui";
10+
import { db } from "./models/SearchModel";
1011
import { DrawerWidth } from "./settings/ui";
1112

1213
export default function Layout(props: {
@@ -15,6 +16,18 @@ export default function Layout(props: {
1516
}) {
1617
const router = useRouter();
1718

19+
const search = useCallback(async (value: string) => {
20+
const result = await db.searchResults
21+
.where("id")
22+
.startsWithAnyOfIgnoreCase(value)
23+
.toArray();
24+
25+
return result.map((r) => ({
26+
title: r.id,
27+
subtitle: r.result.type,
28+
}));
29+
}, []);
30+
1831
return (
1932
<Box>
2033
<AppBar
@@ -35,6 +48,7 @@ export default function Layout(props: {
3548
onSearch={async (v) => {
3649
await router.push(`/info/${v}`);
3750
}}
51+
onType={search}
3852
/>
3953
</Stack>
4054
<Stack direction={"row"} alignItems="center" spacing={2}>

apps/etdstats/lib/components/card/DataCard.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { numberWithCommas } from "../../utils/format";
1111
import TrendingDownIcon from "@mui/icons-material/TrendingDown";
1212
import TrendingUpIcon from "@mui/icons-material/TrendingUp";
1313
import { Box } from "@mui/system";
14+
import Image from "next/image";
1415

1516
interface Props {
1617
title: string;
@@ -40,9 +41,9 @@ export default function DataCard(props: Props) {
4041
</Stack>
4142
<Typography variant="h4" fontWeight={600}>
4243
{props.number ? (
43-
numberWithCommas(props.number)
44+
numberWithCommas(props.number!)
4445
) : (
45-
<CircularProgress />
46+
<Image src={"/Progressbar.webp"} width={50} height={50} />
4647
)}
4748
</Typography>
4849
</Stack>

apps/etdstats/lib/components/display/TransactionDisplay.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@ export default function TransactionDisplay({ data }: Props) {
7979
/>
8080
</Grid>
8181
<Grid item xs={12} md={6}>
82-
<ListItemButton
83-
title="Timestamp"
84-
subtitle={data.data.block.timestamp}
85-
/>
82+
<ListItemButton title="Timestamp" subtitle={data.data.timestamp} />
8683
</Grid>
8784
</Grid>
8885
<Box p={2}>

apps/etdstats/lib/components/display/UserDisplay.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ export default function TransactionDisplay({ data, id, currentPage }: Props) {
256256
</Typography>
257257
</Stack>
258258
<Pagination
259-
count={pageCount}
259+
count={Number.isNaN(pageCount) ? 0 : pageCount}
260260
page={page}
261261
onChange={async (e, page) => {
262262
await onPageChange(page);
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Dexie, { Table } from "dexie";
2+
import { TransactionResponse } from "openapi_client";
3+
4+
export interface SearchResult {
5+
id: string;
6+
result: TransactionResponse;
7+
}
8+
9+
export class SearchModel extends Dexie {
10+
searchResults: Table<SearchResult>;
11+
12+
constructor() {
13+
super("SearchModel");
14+
this.version(1).stores({
15+
searchResults: "++id",
16+
});
17+
this.searchResults = this.table("searchResults");
18+
}
19+
}
20+
21+
export const db = new SearchModel();

apps/etdstats/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
"recharts": "^2.1.11",
3030
"prop-types": "15.8.1",
3131
"metamask-react": "2.4.0",
32-
"react-query": "3.39.1"
32+
"react-query": "3.39.1",
33+
"dexie": "3.2.2",
34+
"dexie-react-hooks": "1.1.1"
3335
},
3436
"devDependencies": {
3537
"@types/node": "18.0.0",

apps/etdstats/pages/info/[id].tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Box, capitalize, Stack, Typography } from "@mui/material";
22
import axios from "axios";
33
import { GetServerSideProps } from "next";
44
import { TransactionResponse, TransactionService } from "openapi_client";
5+
import { useEffect } from "react";
56
import {
67
Breadcrumbs,
78
DownloadDataButton,
@@ -11,6 +12,7 @@ import {
1112
import BlockDisplay from "../../lib/components/display/BlockDisplay";
1213
import TransactionDisplay from "../../lib/components/display/TransactionDisplay";
1314
import UserDisplay from "../../lib/components/display/UserDisplay";
15+
import { db } from "../../lib/models/SearchModel";
1416

1517
interface Props {
1618
data: TransactionResponse;
@@ -19,6 +21,14 @@ interface Props {
1921
}
2022

2123
export default function Details({ data, id, currentPage }: Props) {
24+
useEffect(() => {
25+
(async () => {
26+
if ((await db.searchResults.where("id").equals(id).count()) === 0) {
27+
await db.searchResults.add({ id, result: data });
28+
}
29+
})();
30+
}, [id]);
31+
2232
const menus = [
2333
{
2434
title: "Home",
@@ -51,8 +61,8 @@ export default function Details({ data, id, currentPage }: Props) {
5161
justifyItems={"center"}
5262
>
5363
<Box>
54-
<DownloadDataButton />
55-
<ShareDataButton />
64+
<DownloadDataButton id={id} data={data} />
65+
<ShareDataButton data={data} />
5666
</Box>
5767
<Box>
5868
<SaveToFavoriteButton />

apps/etdstats/pages/info/index.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@ export default function Index(props: Props) {
2727
});
2828

2929
return (
30-
<Box mt={10} p={2}>
30+
<Box
31+
mt={10}
32+
sx={{
33+
paddingX: {
34+
xs: 2,
35+
sm: 15,
36+
},
37+
}}
38+
>
3139
<Grid container spacing={5}>
3240
<Grid item xs={12} md={7}>
3341
<Card sx={{ backgroundColor: green }}>
@@ -107,7 +115,7 @@ export default function Index(props: Props) {
107115
<Typography fontWeight={800} fontSize={20}>
108116
Vistors statistics
109117
</Typography>
110-
<Box minHeight="500px">
118+
<Box>
111119
<PieChart
112120
data={[
113121
{ name: "Mobile", value: analyticsResult.data?.mobile },

apps/etdstats/public/Progressbar.webp

351 KB
Binary file not shown.

node_packages/ui/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"@mui/system": "5.8.4",
2424
"recharts": "2.1.11",
2525
"metamask-react": "2.4.0",
26-
"next": "12.1.6"
26+
"next": "12.1.6",
27+
"qrcode.react": "3.1.0",
28+
"material-ui-popup-state": "3.1.1"
2729
}
2830
}

node_packages/ui/src/buttons/DownloadDataButton.tsx

+22-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,33 @@ import { IconButton, Tooltip } from "@mui/material";
22
import DownloadIcon from "@mui/icons-material/Download";
33

44
interface Props {
5+
id: string;
56
data?: any;
67
}
78

8-
export function DownloadDataButton({ data }: Props) {
9+
function download(filename: string, text: string) {
10+
var element = document.createElement("a");
11+
element.setAttribute(
12+
"href",
13+
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
14+
);
15+
element.setAttribute("download", filename);
16+
17+
element.style.display = "none";
18+
document.body.appendChild(element);
19+
20+
element.click();
21+
22+
document.body.removeChild(element);
23+
}
24+
25+
export function DownloadDataButton({ id, data }: Props) {
926
return (
1027
<Tooltip title="Download">
11-
<IconButton disabled={data === undefined}>
28+
<IconButton
29+
disabled={data === undefined}
30+
onClick={() => download(`${id}.json`, JSON.stringify(data))}
31+
>
1232
<DownloadIcon />
1333
</IconButton>
1434
</Tooltip>
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
11
import { ShareRounded } from "@mui/icons-material";
2-
import { IconButton, Tooltip } from "@mui/material";
2+
import { Box, IconButton, Paper, Popover, Tooltip } from "@mui/material";
33
import React from "react";
4+
import {
5+
usePopupState,
6+
bindTrigger,
7+
bindMenu,
8+
bindPopover,
9+
} from "material-ui-popup-state/hooks";
10+
import { QRCodeCanvas } from "qrcode.react";
411

512
interface Props {
613
data?: any;
714
}
815

916
export function ShareDataButton({ data }: Props) {
17+
const popupState = usePopupState({ variant: "popover", popupId: "demoMenu" });
18+
1019
return (
11-
<Tooltip title="Share">
12-
<IconButton disabled={data === undefined}>
13-
<ShareRounded />
14-
</IconButton>
15-
</Tooltip>
20+
<>
21+
<Tooltip title="Share">
22+
<IconButton disabled={data === undefined} {...bindTrigger(popupState)}>
23+
<ShareRounded />
24+
</IconButton>
25+
</Tooltip>
26+
<Popover
27+
{...bindPopover(popupState)}
28+
anchorOrigin={{
29+
vertical: "bottom",
30+
horizontal: "center",
31+
}}
32+
>
33+
<Paper>
34+
<Box p={2}>
35+
<QRCodeCanvas value={JSON.stringify(data)} />,
36+
</Box>
37+
</Paper>
38+
</Popover>
39+
</>
1640
);
1741
}

0 commit comments

Comments
 (0)