@pioneer-platform/pioneer-react 0.0.2 → 0.2.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +24 -0
- package/.github/workflows/release.yml +22 -0
- package/.github/workflows/update-license.yml +11 -0
- package/.lintstagedrc.json +6 -0
- package/.prettierrc +7 -0
- package/.vscode/extensions.json +8 -0
- package/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/commitlint.config.js +3 -0
- package/dist/assets/404 Error-rafiki.svg +1 -0
- package/dist/assets/Building blocks-amico.svg +1 -0
- package/dist/assets/chakra-ui-logomark-colored.svg +10 -0
- package/dist/assets/favicon.svg +0 -0
- package/dist/assets/react-icon.svg +7 -0
- package/dist/assets/ts-logo-512.svg +1 -0
- package/dist/assets/vite-logo.svg +15 -0
- package/dist/index.js +384249 -0
- package/dist/index_3bde86fb.js +205 -0
- package/dist/index_49fce0b0.js +384033 -0
- package/dist/index_d01e819c.css +63 -0
- package/dist/manifest.json +12 -0
- package/dist/robots.txt +6 -0
- package/index.html +13 -0
- package/netlify.toml +10 -0
- package/package.json +70 -10
- package/public/assets/404 Error-rafiki.svg +1 -0
- package/public/assets/Building blocks-amico.svg +1 -0
- package/public/assets/chakra-ui-logomark-colored.svg +10 -0
- package/public/assets/favicon.svg +0 -0
- package/public/assets/react-icon.svg +7 -0
- package/public/assets/ts-logo-512.svg +1 -0
- package/public/assets/vite-logo.svg +15 -0
- package/public/manifest.json +12 -0
- package/public/robots.txt +6 -0
- package/renovate.json +11 -0
- package/src/App.tsx +21 -0
- package/src/index.tsx +41 -0
- package/src/lib/assets/Icons/KeepKeyIcon.tsx +13 -0
- package/src/lib/assets/Icons/KeplrIcon.tsx +140 -0
- package/src/lib/assets/Icons/MetaMaskIcon.tsx +126 -0
- package/src/lib/assets/Icons/TallyHoIcon.tsx +17 -0
- package/src/lib/assets/Icons/XDEFIIcon.tsx +32 -0
- package/src/lib/assets/favicon.ico +0 -0
- package/src/lib/assets/png/keepkey.png +0 -0
- package/src/lib/assets/png/keplr.png +0 -0
- package/src/lib/assets/png/metamask.png +0 -0
- package/src/lib/assets/png/pioneer.png +0 -0
- package/src/lib/components/AssetSelect/index.tsx +166 -0
- package/src/lib/components/BlockchainSelect/index.tsx +166 -0
- package/src/lib/components/MiddleEllipsis/index.tsx +27 -0
- package/src/lib/components/WalletSelect/index.tsx +112 -0
- package/src/lib/components/auth/RequireAuth.tsx +22 -0
- package/src/lib/components/modals/AssetModal.tsx +67 -0
- package/src/lib/components/modals/SettingsModal.tsx +76 -0
- package/src/lib/components/pioneer/Pioneer/Balances.tsx +266 -0
- package/src/lib/components/pioneer/Pioneer/MiddleEllipsis.tsx +27 -0
- package/src/lib/components/pioneer/Pioneer/Nodes.tsx +0 -0
- package/src/lib/components/pioneer/Pioneer/Paths.tsx +290 -0
- package/src/lib/components/pioneer/Pioneer/Pubkey.tsx +67 -0
- package/src/lib/components/pioneer/Pioneer/Pubkeys.tsx +265 -0
- package/src/lib/components/pioneer/Pioneer/Receive.tsx +26 -0
- package/src/lib/components/pioneer/Pioneer/Send.tsx +135 -0
- package/src/lib/components/pioneer/Pioneer/View.tsx +44 -0
- package/src/lib/components/pioneer/Pioneer/Wallets.tsx +166 -0
- package/src/lib/components/pioneer/index.tsx +525 -0
- package/src/lib/components/utils/index.tsx +47 -0
- package/src/lib/context/Pioneer/index.tsx +420 -0
- package/src/lib/layout/Footer.tsx +22 -0
- package/src/lib/layout/Header.tsx +38 -0
- package/src/lib/layout/Meta.tsx +25 -0
- package/src/lib/layout/Pioneer/Balances.tsx +290 -0
- package/src/lib/layout/Pioneer/MiddleEllipsis.tsx +27 -0
- package/src/lib/layout/Pioneer/Pubkey.tsx +67 -0
- package/src/lib/layout/Pioneer/Receive.tsx +26 -0
- package/src/lib/layout/Pioneer/Send.tsx +135 -0
- package/src/lib/layout/Pioneer/View.tsx +44 -0
- package/src/lib/layout/Pioneer/Wallets.tsx +166 -0
- package/src/lib/layout/ThemeToggle.tsx +16 -0
- package/src/lib/layout/index.tsx +29 -0
- package/src/lib/pages/404/index.tsx +36 -0
- package/src/lib/pages/home/components/CTASection.tsx +36 -0
- package/src/lib/pages/home/components/SomeImage.tsx +36 -0
- package/src/lib/pages/home/components/SomeText.tsx +16 -0
- package/src/lib/pages/home/index.tsx +87 -0
- package/src/lib/router/Routings.tsx +45 -0
- package/src/lib/router/routes.tsx +13 -0
- package/src/lib/styles/theme/config.ts +5 -0
- package/src/lib/styles/theme/index.ts +17 -0
- package/tsconfig.json +19 -9
- package/turbo.json +17 -0
- package/vercel.json +4 -0
- package/vite.config.ts +110 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Navigate } from "react-router-dom";
|
|
2
|
+
|
|
3
|
+
type PrivateRouteProps = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
redirectTo?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const RequireAuth = ({
|
|
9
|
+
children,
|
|
10
|
+
redirectTo = "/login",
|
|
11
|
+
}: PrivateRouteProps) => {
|
|
12
|
+
// add your own authentication logic here
|
|
13
|
+
const isAuthenticated = true;
|
|
14
|
+
|
|
15
|
+
return isAuthenticated ? (
|
|
16
|
+
(children as React.ReactElement)
|
|
17
|
+
) : (
|
|
18
|
+
<Navigate to={redirectTo} />
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default RequireAuth;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
Modal,
|
|
4
|
+
ModalOverlay,
|
|
5
|
+
ModalContent,
|
|
6
|
+
ModalHeader,
|
|
7
|
+
ModalCloseButton,
|
|
8
|
+
ModalBody,
|
|
9
|
+
ModalFooter,
|
|
10
|
+
Tabs,
|
|
11
|
+
TabList,
|
|
12
|
+
Tab,
|
|
13
|
+
TabPanels,
|
|
14
|
+
Card,
|
|
15
|
+
CardBody,
|
|
16
|
+
TabPanel,
|
|
17
|
+
} from "@chakra-ui/react";
|
|
18
|
+
import { useState, useEffect } from "react";
|
|
19
|
+
|
|
20
|
+
import { usePioneer } from "lib/context/Pioneer";
|
|
21
|
+
|
|
22
|
+
interface ModalProps {
|
|
23
|
+
isOpen: boolean;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
}
|
|
26
|
+
//@ts-ignore
|
|
27
|
+
const AssetModal: React.FC<ModalProps> = ({ isOpen, onClose }) => {
|
|
28
|
+
const { state, dispatch } = usePioneer();
|
|
29
|
+
const { api, app, user, context } = state;
|
|
30
|
+
const [walletDescriptions, setWalletDescriptions] = useState([]);
|
|
31
|
+
const [balances, setBalances] = useState([]);
|
|
32
|
+
|
|
33
|
+
const setUser = async function () {
|
|
34
|
+
try {
|
|
35
|
+
if (user && user.wallets) {
|
|
36
|
+
const { wallets, walletDescriptions, balances, pubkeys } = user;
|
|
37
|
+
setWalletDescriptions(walletDescriptions);
|
|
38
|
+
setBalances(balances);
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.error("header e: ", e);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setUser();
|
|
47
|
+
}, [user]); // once on startup
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Modal isOpen={isOpen} onClose={onClose} size="xl">
|
|
51
|
+
<ModalOverlay />
|
|
52
|
+
<ModalContent>
|
|
53
|
+
<ModalHeader>Asset Select</ModalHeader>
|
|
54
|
+
<ModalCloseButton />
|
|
55
|
+
<ModalBody></ModalBody>
|
|
56
|
+
<ModalFooter>
|
|
57
|
+
<Button colorScheme="blue" mr={3} onClick={onClose}>
|
|
58
|
+
Close
|
|
59
|
+
</Button>
|
|
60
|
+
<Button variant="ghost">Secondary Action</Button>
|
|
61
|
+
</ModalFooter>
|
|
62
|
+
</ModalContent>
|
|
63
|
+
</Modal>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default AssetModal;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Modal,
|
|
5
|
+
ModalOverlay,
|
|
6
|
+
ModalContent,
|
|
7
|
+
ModalHeader,
|
|
8
|
+
ModalCloseButton,
|
|
9
|
+
ModalBody,
|
|
10
|
+
ModalFooter,
|
|
11
|
+
Tabs,
|
|
12
|
+
Tab,
|
|
13
|
+
TabList,
|
|
14
|
+
TabPanel,
|
|
15
|
+
TabPanels,
|
|
16
|
+
} from "@chakra-ui/react";
|
|
17
|
+
import Balances from "lib/components/pioneer/Pioneer/Balances";
|
|
18
|
+
import Wallets from "lib/components/pioneer/Pioneer/Wallets";
|
|
19
|
+
import Paths from "lib/components/pioneer/Pioneer/Paths";
|
|
20
|
+
import Pubkeys from "lib/components/pioneer/Pioneer/Pubkeys";
|
|
21
|
+
import { usePioneer } from "lib/context/Pioneer";
|
|
22
|
+
|
|
23
|
+
interface SettingsModalProps {
|
|
24
|
+
isOpen: boolean;
|
|
25
|
+
onClose: () => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const SettingsModal: React.FC<SettingsModalProps> = ({ isOpen, onClose }) => {
|
|
29
|
+
const { state } = usePioneer();
|
|
30
|
+
const { app, status } = state;
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
//console.log("app: ", app);
|
|
34
|
+
}, [app, app?.balances, app?.pubkeys, app?.wallets, app?.paths, status]);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Modal isOpen={isOpen} onClose={onClose} size={"xl"}>
|
|
38
|
+
<ModalOverlay />
|
|
39
|
+
<ModalContent>
|
|
40
|
+
<ModalHeader>Pioneer Settings</ModalHeader>
|
|
41
|
+
<ModalCloseButton />
|
|
42
|
+
<ModalBody>
|
|
43
|
+
<Tabs variant="enclosed">
|
|
44
|
+
<TabList>
|
|
45
|
+
<Tab>Wallets</Tab>
|
|
46
|
+
<Tab>Nodes</Tab>
|
|
47
|
+
<Tab>PubKeys</Tab>
|
|
48
|
+
<Tab>Balances</Tab>
|
|
49
|
+
</TabList>
|
|
50
|
+
<TabPanels>
|
|
51
|
+
<TabPanel>
|
|
52
|
+
<Wallets wallets={app?.wallets || []} />
|
|
53
|
+
</TabPanel>
|
|
54
|
+
{/*<TabPanel>*/}
|
|
55
|
+
{/* <Paths paths={app?.paths || []} />*/}
|
|
56
|
+
{/*</TabPanel>*/}
|
|
57
|
+
<TabPanel>
|
|
58
|
+
<Pubkeys pubkeys={app?.pubkeys || []} />
|
|
59
|
+
</TabPanel>
|
|
60
|
+
<TabPanel>
|
|
61
|
+
<Balances balances={app?.balances || []} />
|
|
62
|
+
</TabPanel>
|
|
63
|
+
</TabPanels>
|
|
64
|
+
</Tabs>
|
|
65
|
+
</ModalBody>
|
|
66
|
+
<ModalFooter>
|
|
67
|
+
<Button colorScheme="blue" mr={3} onClick={onClose}>
|
|
68
|
+
Close
|
|
69
|
+
</Button>
|
|
70
|
+
</ModalFooter>
|
|
71
|
+
</ModalContent>
|
|
72
|
+
</Modal>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default SettingsModal;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { Search2Icon } from "@chakra-ui/icons";
|
|
2
|
+
import {
|
|
3
|
+
Avatar,
|
|
4
|
+
AvatarBadge,
|
|
5
|
+
Box,
|
|
6
|
+
Button,
|
|
7
|
+
HStack,
|
|
8
|
+
Stack,
|
|
9
|
+
Image,
|
|
10
|
+
Modal,
|
|
11
|
+
ModalOverlay,
|
|
12
|
+
ModalContent,
|
|
13
|
+
ModalHeader,
|
|
14
|
+
ModalCloseButton,
|
|
15
|
+
ModalBody,
|
|
16
|
+
ModalFooter,
|
|
17
|
+
useDisclosure,
|
|
18
|
+
InputGroup,
|
|
19
|
+
InputLeftElement,
|
|
20
|
+
Input,
|
|
21
|
+
} from "@chakra-ui/react";
|
|
22
|
+
import React, { useState, useEffect } from "react";
|
|
23
|
+
//@ts-ignore
|
|
24
|
+
import KEEPKEY_ICON from "lib/assets/png/keepkey.png";
|
|
25
|
+
//@ts-ignore
|
|
26
|
+
import METAMASK_ICON from "lib/assets/png/metamask.png";
|
|
27
|
+
//@ts-ignore
|
|
28
|
+
import PIONEER_ICON from "lib/assets/png/pioneer.png";
|
|
29
|
+
import { usePioneer } from "lib/context/Pioneer";
|
|
30
|
+
|
|
31
|
+
import Receive from "./Receive";
|
|
32
|
+
import Send from "./Send";
|
|
33
|
+
import View from "./View";
|
|
34
|
+
|
|
35
|
+
interface Balance {
|
|
36
|
+
image?: string;
|
|
37
|
+
symbol: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
balance?: any;
|
|
40
|
+
size?: string;
|
|
41
|
+
context?: string; // Added context field
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const getWalletType = (app: { wallets: any[] }, context: any) => {
|
|
45
|
+
if (app && app.wallets) {
|
|
46
|
+
const wallet = app.wallets.find((w) => w.id === context);
|
|
47
|
+
return wallet ? wallet.type : null;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const getWalletBadgeContent = (walletType: string) => {
|
|
53
|
+
const icons: any = {
|
|
54
|
+
metamask: METAMASK_ICON,
|
|
55
|
+
keepkey: KEEPKEY_ICON,
|
|
56
|
+
native: PIONEER_ICON,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const icon = icons[walletType];
|
|
60
|
+
|
|
61
|
+
if (!icon) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<AvatarBadge boxSize="1.25em" bg="green.500">
|
|
67
|
+
<Image rounded="full" src={icon} />
|
|
68
|
+
</AvatarBadge>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default function Balances({ balances }: { balances: Balance[] }) {
|
|
73
|
+
const { state, dispatch } = usePioneer();
|
|
74
|
+
const { api, app } = state;
|
|
75
|
+
const [selectedBalance, setSelectedBalance] = useState<Balance | null>(null);
|
|
76
|
+
const [selectedAction, setSelectedAction] = useState<string | null>(null);
|
|
77
|
+
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
78
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
79
|
+
|
|
80
|
+
const handleSelectClick = async (balance: Balance) => {
|
|
81
|
+
try {
|
|
82
|
+
//
|
|
83
|
+
// console.log("balance: ", balance);
|
|
84
|
+
|
|
85
|
+
//set Balance
|
|
86
|
+
let assetFromPioneer = await api.GetAsset({ symbol: balance.symbol });
|
|
87
|
+
assetFromPioneer = assetFromPioneer.data[0];
|
|
88
|
+
let blockchainFromPioneer = await api.GetBlockchain({
|
|
89
|
+
symbol: balance.symbol,
|
|
90
|
+
});
|
|
91
|
+
blockchainFromPioneer = blockchainFromPioneer.data[0];
|
|
92
|
+
// console.log("assetFromPioneer: ", balance);
|
|
93
|
+
//set Blockchain
|
|
94
|
+
await app.setBlockchainContext(blockchainFromPioneer);
|
|
95
|
+
await app.setAssetContext(assetFromPioneer);
|
|
96
|
+
//set pubkey
|
|
97
|
+
// await app.setPubkeyContext(balance.context)
|
|
98
|
+
// console.log("app.assetContext: ", app.assetContext);
|
|
99
|
+
// console.log("app.blockchainContext: ", app.blockchainContext);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
console.error(e);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const handleSendClick = (balance: Balance) => {
|
|
106
|
+
setSelectedBalance(balance);
|
|
107
|
+
setSelectedAction("send");
|
|
108
|
+
onOpen();
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const handleReceiveClick = (balance: Balance) => {
|
|
112
|
+
setSelectedBalance(balance);
|
|
113
|
+
setSelectedAction("receive");
|
|
114
|
+
onOpen();
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const handleViewClick = (balance: Balance) => {
|
|
118
|
+
setSelectedBalance(balance);
|
|
119
|
+
setSelectedAction("view");
|
|
120
|
+
onOpen();
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
const setUser = async () => {
|
|
125
|
+
try {
|
|
126
|
+
console.log("balances: ",app.balances)
|
|
127
|
+
if (app && app.wallets) {
|
|
128
|
+
const { wallets, balances } = app;
|
|
129
|
+
const updatedBalances = balances.map((balance: Balance) => {
|
|
130
|
+
const walletType = getWalletType(app, balance.context);
|
|
131
|
+
const badgeContent = getWalletBadgeContent(walletType);
|
|
132
|
+
return {
|
|
133
|
+
//@ts-ignore
|
|
134
|
+
...balance,
|
|
135
|
+
context: {
|
|
136
|
+
//@ts-ignore
|
|
137
|
+
...balance.context,
|
|
138
|
+
badge: badgeContent,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
dispatch({ type: "SET_BALANCES", payload: updatedBalances });
|
|
143
|
+
}
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error("Error: ", e);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
setUser();
|
|
150
|
+
}, [app, app?.balances, app?.pubkeys, app?.wallets, app?.paths, status]);
|
|
151
|
+
|
|
152
|
+
// Filter and sort balances based on search query
|
|
153
|
+
const filteredBalances = balances.filter((balance: Balance) => {
|
|
154
|
+
// Convert the search query and balance symbol/name to lowercase for case-insensitive search
|
|
155
|
+
const query = searchQuery.toLowerCase();
|
|
156
|
+
const symbol = balance.symbol.toLowerCase();
|
|
157
|
+
const name = balance.name ? balance.name.toLowerCase() : "";
|
|
158
|
+
|
|
159
|
+
// Check if the symbol or name contains the search query
|
|
160
|
+
return symbol.includes(query) || name.includes(query);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const sortedBalances = filteredBalances.sort(
|
|
164
|
+
(a: Balance, b: Balance) => b.balance - a.balance
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// CSS for the scrollable container
|
|
168
|
+
const scrollContainerStyles: React.CSSProperties = {
|
|
169
|
+
maxHeight: "15em", // This value may need to be adjusted according to your design
|
|
170
|
+
overflowY: "scroll",
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<Stack spacing={4}>
|
|
175
|
+
<InputGroup>
|
|
176
|
+
<InputLeftElement pointerEvents="none">
|
|
177
|
+
<Search2Icon color="gray.300" />
|
|
178
|
+
</InputLeftElement>
|
|
179
|
+
<Input
|
|
180
|
+
placeholder="Bitcoin..."
|
|
181
|
+
type="text"
|
|
182
|
+
value={searchQuery}
|
|
183
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
184
|
+
/>
|
|
185
|
+
</InputGroup>
|
|
186
|
+
<Box style={scrollContainerStyles}>
|
|
187
|
+
{sortedBalances.map((balance: Balance, index: number) => (
|
|
188
|
+
<Box key={index}>
|
|
189
|
+
<HStack spacing={4} alignItems="center">
|
|
190
|
+
<Avatar src={balance.image} />
|
|
191
|
+
<Box>
|
|
192
|
+
<small>asset: {balance.symbol}</small>
|
|
193
|
+
<br />
|
|
194
|
+
<small>balance: {balance.balance}</small>
|
|
195
|
+
</Box>
|
|
196
|
+
</HStack>
|
|
197
|
+
<HStack mt={2} spacing={2}>
|
|
198
|
+
<Button
|
|
199
|
+
size="sm"
|
|
200
|
+
variant="outline"
|
|
201
|
+
onClick={() => handleSelectClick(balance)}
|
|
202
|
+
>
|
|
203
|
+
Select
|
|
204
|
+
</Button>
|
|
205
|
+
{/*<Button*/}
|
|
206
|
+
{/* size="sm"*/}
|
|
207
|
+
{/* variant="outline"*/}
|
|
208
|
+
{/* onClick={() => handleSendClick(balance)}*/}
|
|
209
|
+
{/*>*/}
|
|
210
|
+
{/* Send*/}
|
|
211
|
+
{/*</Button>*/}
|
|
212
|
+
{/*<Button*/}
|
|
213
|
+
{/* size="sm"*/}
|
|
214
|
+
{/* variant="outline"*/}
|
|
215
|
+
{/* onClick={() => handleReceiveClick(balance)}*/}
|
|
216
|
+
{/*>*/}
|
|
217
|
+
{/* Receive*/}
|
|
218
|
+
{/*</Button>*/}
|
|
219
|
+
{/*<Button*/}
|
|
220
|
+
{/* size="sm"*/}
|
|
221
|
+
{/* variant="outline"*/}
|
|
222
|
+
{/* onClick={() => handleViewClick(balance)}*/}
|
|
223
|
+
{/*>*/}
|
|
224
|
+
{/* View*/}
|
|
225
|
+
{/*</Button>*/}
|
|
226
|
+
</HStack>
|
|
227
|
+
</Box>
|
|
228
|
+
))}
|
|
229
|
+
</Box>
|
|
230
|
+
|
|
231
|
+
<Modal isOpen={isOpen} onClose={onClose} isCentered blockScrollOnMount>
|
|
232
|
+
<ModalOverlay />
|
|
233
|
+
<ModalContent>
|
|
234
|
+
<ModalHeader>{selectedAction}</ModalHeader>
|
|
235
|
+
<ModalCloseButton />
|
|
236
|
+
{selectedAction === "send" && (
|
|
237
|
+
<div>
|
|
238
|
+
<h3>Selected Action: Send</h3>
|
|
239
|
+
<p>Selected Asset: {selectedBalance?.symbol}</p>
|
|
240
|
+
<Send asset={selectedBalance} />
|
|
241
|
+
</div>
|
|
242
|
+
)}
|
|
243
|
+
{selectedAction === "receive" && (
|
|
244
|
+
<div>
|
|
245
|
+
<h3>Selected Action: Receive</h3>
|
|
246
|
+
<p>Selected Asset: {selectedBalance?.symbol}</p>
|
|
247
|
+
<Receive />
|
|
248
|
+
</div>
|
|
249
|
+
)}
|
|
250
|
+
{selectedAction === "view" && (
|
|
251
|
+
<div>
|
|
252
|
+
<h3>Selected Action: View</h3>
|
|
253
|
+
<p>Selected Asset: {selectedBalance?.symbol}</p>
|
|
254
|
+
<View />
|
|
255
|
+
</div>
|
|
256
|
+
)}
|
|
257
|
+
<ModalFooter>
|
|
258
|
+
<Button colorScheme="blue" onClick={onClose}>
|
|
259
|
+
Cancel
|
|
260
|
+
</Button>
|
|
261
|
+
</ModalFooter>
|
|
262
|
+
</ModalContent>
|
|
263
|
+
</Modal>
|
|
264
|
+
</Stack>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
|
|
3
|
+
interface MiddleEllipsisProps {
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const MiddleEllipsis: React.FC<MiddleEllipsisProps> = ({ text }) => {
|
|
8
|
+
const maxLength = 20;
|
|
9
|
+
const ellipsis = "...";
|
|
10
|
+
|
|
11
|
+
if (!text || text.length <= maxLength) {
|
|
12
|
+
return <span>{text}</span>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const frontPart = text.slice(0, 7);
|
|
16
|
+
const backPart = text.slice(-10);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<span>
|
|
20
|
+
{frontPart}
|
|
21
|
+
{ellipsis}
|
|
22
|
+
{backPart}
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default MiddleEllipsis;
|
|
File without changes
|