Skip to content

Commit 6f4268a

Browse files
authored
Merge pull request #106 from dharmesh03/api-keys
added apikey page
2 parents 88c6210 + 3603b83 commit 6f4268a

File tree

10 files changed

+179
-11
lines changed

10 files changed

+179
-11
lines changed

public/images/api.svg

Lines changed: 5 additions & 0 deletions
Loading

public/images/eye.svg

Lines changed: 5 additions & 0 deletions
Loading

public/images/plus.svg

Lines changed: 5 additions & 0 deletions
Loading

src/components/common/Token.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import Link from 'next/link';
2-
import React, { useContext } from 'react';
2+
import React, {useContext, useState} from 'react';
33
import CopyButton from './copy_button/CopyButton';
44
import { useConfig } from '@/context/config';
55
import { useRouter } from 'next/router';
66
import { shortenString } from './utils';
77
import { NETWORK_SCANNER_MAP } from './constants';
8+
import TextVisibleButton from "@/components/common/textVisiblebutton/textVisibleButton";
89

910
export interface TokenType {
1011
icon?: string;
@@ -13,27 +14,30 @@ export interface TokenType {
1314
type?: string;
1415
onTokenClicked?: (value: number) => void;
1516
value?: number;
17+
eyes?: boolean;
1618
}
1719

18-
function Token({ icon, text, copyIcon, type, onTokenClicked, value }: TokenType) {
20+
function Token({ icon, text, copyIcon, type, onTokenClicked, value, eyes }: TokenType) {
1921
const { selectedNetwork } = useConfig();
22+
const [ showText, setShowText] = useState(false);
2023

2124
if (text == "Unavailable!")
2225
return <div className="flex items-center gap-2.5">{text}</div>
26+
const renderString = showText? text: shortenString(text, eyes)
2327

2428
return (
2529
<div className="flex items-center gap-2.5">
2630
{icon && <img src={icon} alt="" style={{ width: '20px', height: '20px' }} />}
2731
{onTokenClicked ? (
2832
<a onClick={() => onTokenClicked(value ? value : 0)} className="text-blue-200 cursor-pointer">
29-
{shortenString(text)}
33+
{renderString}
3034
</a>
3135
) : (
3236
<Link href={getHrefLink(type, text, selectedNetwork)} target={getTarget(type)} className="text-blue-200">
33-
{shortenString(text)}
37+
{renderString}
3438
</Link>
3539
)}
36-
40+
{eyes && <TextVisibleButton isShow={showText} handleText={(showText)=>setShowText(!!showText)} />}
3741
<CopyButton text={text} copyIcon={copyIcon} />
3842
</div>
3943
);

src/components/common/table/Table.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export interface tableDataT {
2424
fee?: fee;
2525
userOps?: string;
2626
status?: Boolean;
27+
created?: string;
28+
keys?: string;
2729
account?: TokenType;
2830
count?: string;
2931
poweredBy?: string;
@@ -98,10 +100,10 @@ function Table(props: tableDataT) {
98100
className={`flex items-center gap-2.5 ${
99101
columns.length <= 3 ? 'group-last:justify-end' : ''
100102
}`}
101-
onClick={() => name === 'Age' && handleSort()}
103+
onClick={() => sort && handleSort()}
102104
>
103105
<span>{name}</span>
104-
{name === 'Age' ? sort && <img src="/images/span.svg" alt="" /> : null}
106+
{sort ? <img src="/images/span.svg" alt="" /> : null}
105107
</div>
106108
</th>
107109
);
@@ -124,7 +126,7 @@ function Table(props: tableDataT) {
124126
</tbody>
125127
) : (
126128
<tbody>
127-
{sortedRows?.map(({ ago, fee, sender, target, token, userOps, status, count, poweredBy }, index) => {
129+
{sortedRows?.map(({ ago, fee, sender, target, token, userOps, status, count, poweredBy, created, keys }, index) => {
128130
return (
129131
<tr
130132
key={index}
@@ -136,6 +138,7 @@ function Table(props: tableDataT) {
136138
</td>
137139
)}
138140

141+
139142
{ago && (
140143
<td className="">
141144
{status === true ? (
@@ -157,7 +160,11 @@ function Table(props: tableDataT) {
157160
<span className="block text-center">{userOps}</span>
158161
</td>
159162
)}
160-
163+
{keys && (
164+
<td className="">
165+
<Token text={keys} type="address" eyes/>
166+
</td>
167+
)}
161168
{sender && (
162169
<td className="">
163170
<Token text={sender} type="address" />
@@ -189,6 +196,13 @@ function Table(props: tableDataT) {
189196
</div>
190197
</td>
191198
)}
199+
{created && (
200+
<td className="">
201+
<div className="flex items-center justify-end gap-2 text-right">
202+
{created}
203+
</div>
204+
</td>
205+
)}
192206
</tr>
193207
);
194208
})}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
3+
interface Props {
4+
isShow?: boolean;
5+
handleText?: (isShow?: boolean ) => void
6+
}
7+
8+
function TextVisibleButton({ isShow, handleText }: Props) {
9+
10+
const toggleVisibility = () => {
11+
if (handleText) handleText(!isShow);
12+
}
13+
14+
return (
15+
<button
16+
onClick={toggleVisibility}
17+
className="active:shadow-300 pd-2"
18+
type="button"
19+
>
20+
<img className="h-[20px] w-[20px] md:h-[16px] md:w-[16px]" src={ isShow? '/images/eye.svg': '/images/eye.svg'} alt="" />
21+
</button>
22+
);
23+
}
24+
export default TextVisibleButton;

src/components/common/utils.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ export const getCurrencySymbol = (amount: number, network: string): string => {
5959
}
6060
};
6161

62-
export const shortenString = (str: string) => {
62+
export const shortenString = (str: string, star = false) => {
6363
if (str?.length <= 10) {
6464
return str;
6565
}
6666
const firstChars = str?.slice(0, 6);
6767
const lastChars = str?.slice(-4);
6868

69-
return `${firstChars}...${lastChars}`;
69+
return `${firstChars}${star ? '**************': '...' }${lastChars}`;
7070
};
7171

7272
const getNetworkFromUrl = () => {

src/pages/apiKeys.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React, { ReactElement, useEffect } from 'react';
2+
import Layout from '@/components/global/Layout';
3+
import ManageApi from '@/views/ApiKeys';
4+
import ReactGA from 'react-ga4';
5+
import SEO from '@/components/common/SEO';
6+
7+
function ApiKeys() {
8+
useEffect(() => {
9+
ReactGA.send({ hitType: 'CreateAPIKey', page: window.location.pathname });
10+
}, []);
11+
12+
return (
13+
<div>
14+
<SEO/>
15+
<ManageApi />
16+
</div>
17+
);
18+
}
19+
20+
export default ApiKeys;
21+
22+
ApiKeys.getLayout = (page: ReactElement) => <Layout>{page}</Layout>;

src/views/ApiKeys/index.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Footer from '@/components/global/footer/Footer';
2+
import Navbar from '@/components/global/navbar/Navbar';
3+
import React, { useEffect, useState } from 'react';
4+
import Table, { tableDataT } from '@/components/common/table/Table';
5+
import table_data from './table_data.json';
6+
import { ToastContainer } from 'react-toastify';
7+
import 'react-toastify/dist/ReactToastify.css';
8+
9+
10+
function APIKeys() {
11+
const [apiKeysTable] = useState<tableDataT>( table_data as tableDataT);
12+
const [tableLoading] = useState(false);
13+
const [captionText, setCaptionText] = useState('');
14+
15+
useEffect(() => {
16+
setCaptionText(`${apiKeysTable.rows.length} API Keys found`);
17+
}, []);
18+
19+
20+
21+
return (
22+
<div className="">
23+
<Navbar searchbar />
24+
<section className="py-10">
25+
<div className="container">
26+
<h1 className="text-3xl font-bold">API Keys</h1>
27+
</div>
28+
</section>
29+
<div className="container">
30+
<div className="flex flex-wrap items-center gap-3 py-2 mb-4 md:gap-10">
31+
<button
32+
className="text-sm border border-dark-200 text-md gap-2 inline-flex tracking-[1.25px] pt-[9px] pb-[9px] px-4 uppercase rounded bg-black text-white"
33+
style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}
34+
>
35+
<img className="-translate-y-[1px]" src="/images/plus.svg" alt="" />
36+
<span>CREATE NEW KEY</span>
37+
</button>
38+
<button
39+
className="text-sm border border-dark-200 text-md gap-2 inline-flex tracking-[1.25px] pt-[9px] pb-[9px] px-4 uppercase rounded bg-white"
40+
style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}
41+
>
42+
<img className="-translate-y-[1px]" src="/images/api.svg" alt="" />
43+
<span>Check Api Plan</span>
44+
</button>
45+
</div>
46+
</div>
47+
<section className="mb-10">
48+
<div className="container">
49+
<div>
50+
<Table
51+
{...apiKeysTable}
52+
loading={tableLoading}
53+
hideHeader={true}
54+
caption={{
55+
children: captionText,
56+
icon: '/images/cube.svg',
57+
text: 'Approx Number of API Keys Created',
58+
}}
59+
/>
60+
</div>
61+
</div>
62+
</section>
63+
<ToastContainer />
64+
<Footer />
65+
</div>
66+
);
67+
}
68+
69+
export default APIKeys;

src/views/ApiKeys/table_data.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"columns": [
3+
{ "name": "Keys", "sort": true },
4+
{ "name": "Created", "sort": true }
5+
],
6+
"rows": [
7+
{
8+
"keys": "0x2824r6o923dqe3d7f",
9+
"created": "08/12/2023"
10+
},
11+
{
12+
"keys": "0x2824r6o923dqe3d7f",
13+
"created": "08/12/2023"
14+
},
15+
{
16+
"keys": "0x2824r6o923dqe3d7f",
17+
"created": "08/12/2023"
18+
}
19+
]
20+
}

0 commit comments

Comments
 (0)