From f49f847a7e2661eb6becf2fb3d915d8bebab3a3c Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 14 Oct 2024 14:10:14 +0200 Subject: [PATCH 01/14] feat: initialize modal in launchpadERC20 --- .../LaunchpadERC20TokensScreen.tsx | 12 ++++-- .../LaunchpadERC20SelectTokenModal.tsx | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index 1c6b5dc0a..320a9d0cc 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -15,6 +15,7 @@ import { useForceNetworkSelection } from "@/hooks/useForceNetworkSelection"; import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; +import { SelectTokenModal } from "../component/LaunchpadERC20SelectTokenModal"; export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ route: { params }, @@ -24,6 +25,11 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ const networkId = useSelectedNetworkId(); const { width } = useWindowDimensions(); const navigation = useAppNavigation(); + const [isModalVisible, setIsModalVisible] = React.useState(false); + + const toggleModal = () => { + setIsModalVisible(!isModalVisible); + } return ( = ({ label="Manage" description="Mint, burn, or transfer the tokens you own" iconSVG={penSVG} - onPress={() => {}} + onPress={() => { setIsModalVisible(true) }} style={{ marginHorizontal: width >= breakpoints.MD_BREAKPOINT ? 12 : 0, marginVertical: width >= breakpoints.LG_BREAKPOINT ? 0 : 12, }} - disabled /> {}} + onPress={() => { }} disabled /> + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx new file mode 100644 index 000000000..2e9a6fd6f --- /dev/null +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx @@ -0,0 +1,40 @@ +import { BrandText } from "@/components/BrandText"; +import ModalBase from "@/components/modals/ModalBase"; +import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; +import { useAppNavigation } from "@/utils/navigation"; +import { neutral77 } from "@/utils/style/colors"; +import { fontSemibold14 } from "@/utils/style/fonts"; +import { View } from "react-native"; + + +interface SelectTokenModalProps { + isVisible: boolean; + onClose: () => void; +} + +export const SelectTokenModal: React.FC = ({ isVisible, onClose }) => { + const props = { isVisible: isVisible, onClose: onClose }; + const navigation = useAppNavigation(); + const networkId = useSelectedNetworkId(); + + return ( + + + + Select your ERC20 Token + + + + + ) +} \ No newline at end of file From fecd2c93e7105392c6dbef30010bf45baaa5ae21 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 14 Oct 2024 14:36:45 +0200 Subject: [PATCH 02/14] feat: add get user tokens json function in launchpad_grc20 realm --- gno/r/launchpad_grc20/token_factory_grc20.gno | 12 ++++++++++++ .../component/LaunchpadERC20SelectTokenModal.tsx | 4 ---- .../screens/LaunchpadERC20/hooks/useUserTokens.ts | 0 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 packages/screens/LaunchpadERC20/hooks/useUserTokens.ts diff --git a/gno/r/launchpad_grc20/token_factory_grc20.gno b/gno/r/launchpad_grc20/token_factory_grc20.gno index 5f6e279cf..db5b33579 100644 --- a/gno/r/launchpad_grc20/token_factory_grc20.gno +++ b/gno/r/launchpad_grc20/token_factory_grc20.gno @@ -190,6 +190,18 @@ func GetLastTokensJSON() string { return json.ArrayNode("", nodes).String() } +func GetUserTokensJSON(user std.Address) string { + var nodes []*json.Node + tokens.Iterate("", "", func(key string, value interface{}) bool { + token, _ := value.(*Token) + if token.admin.Owner() == user { + nodes = append(nodes, token.ToJSON()) + } + return false + }) + return json.ArrayNode("", nodes).String() +} + func mustGetToken(name string) *Token { t, exists := tokens.Get(name) if !exists { diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx index 2e9a6fd6f..ee86c372f 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx @@ -1,7 +1,5 @@ import { BrandText } from "@/components/BrandText"; import ModalBase from "@/components/modals/ModalBase"; -import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; -import { useAppNavigation } from "@/utils/navigation"; import { neutral77 } from "@/utils/style/colors"; import { fontSemibold14 } from "@/utils/style/fonts"; import { View } from "react-native"; @@ -14,8 +12,6 @@ interface SelectTokenModalProps { export const SelectTokenModal: React.FC = ({ isVisible, onClose }) => { const props = { isVisible: isVisible, onClose: onClose }; - const navigation = useAppNavigation(); - const networkId = useSelectedNetworkId(); return ( Date: Mon, 14 Oct 2024 15:50:30 +0200 Subject: [PATCH 03/14] feat: add error if user does not have any ERC 20 token --- .../LaunchpadERC20CreateTokenSign.tsx | 1 + .../LaunchpadERC20TokensScreen.tsx | 4 +- .../LaunchpadERC20SelectTokenModal.tsx | 36 ----------- .../LaunchpadERC20SelectUserTokenModal.tsx | 64 +++++++++++++++++++ .../LaunchpadERC20/hooks/useUserTokens.ts | 34 ++++++++++ 5 files changed, 101 insertions(+), 38 deletions(-) delete mode 100644 packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx create mode 100644 packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20CreateTokenSign.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20CreateTokenSign.tsx index d26605235..145756e52 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20CreateTokenSign.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20CreateTokenSign.tsx @@ -117,6 +117,7 @@ export const CreateTokenSign: React.FC = () => { ); await queryClient.invalidateQueries(["lastTokens"]); + await queryClient.invalidateQueries(["userTokens"]); setIsShowConfirmModal(false); setIsShowModal(true); diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index 320a9d0cc..ad7462520 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -15,7 +15,7 @@ import { useForceNetworkSelection } from "@/hooks/useForceNetworkSelection"; import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; -import { SelectTokenModal } from "../component/LaunchpadERC20SelectTokenModal"; +import { SelectUserTokenModal } from "../component/LaunchpadERC20SelectUserTokenModal"; export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ route: { params }, @@ -71,7 +71,7 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ disabled /> - + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx deleted file mode 100644 index ee86c372f..000000000 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectTokenModal.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { BrandText } from "@/components/BrandText"; -import ModalBase from "@/components/modals/ModalBase"; -import { neutral77 } from "@/utils/style/colors"; -import { fontSemibold14 } from "@/utils/style/fonts"; -import { View } from "react-native"; - - -interface SelectTokenModalProps { - isVisible: boolean; - onClose: () => void; -} - -export const SelectTokenModal: React.FC = ({ isVisible, onClose }) => { - const props = { isVisible: isVisible, onClose: onClose }; - - return ( - - - - Select your ERC20 Token - - - - - ) -} \ No newline at end of file diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx new file mode 100644 index 000000000..d6c3d5f1e --- /dev/null +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -0,0 +1,64 @@ +import { BrandText } from "@/components/BrandText"; +import { DropdownWithListItem } from "@/components/mini/DropdownWithListItem"; +import ModalBase from "@/components/modals/ModalBase"; +import { SpacerColumn } from "@/components/spacer"; +import { errorColor, neutral77 } from "@/utils/style/colors"; +import { fontSemibold14 } from "@/utils/style/fonts"; +import { useState } from "react"; +import { View } from "react-native"; +import { useUserTokens } from "../hooks/useUserTokens"; + + +// type DropdownItemType = { +// icon?: FC | string; +// name: string; +// onPress?: (navigation: NavigationProp) => void; +// }; + +interface SelectTokenModalProps { + isVisible: boolean; + onClose: () => void; + networkId: string; +} + +export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, networkId }) => { + const [error, setError] = useState(null); + const { data: userTokens } = useUserTokens(networkId); + const dropdownItems = userTokens?.map((token) => { + return { + name: token.name, + onPress: () => console.log("Token selected"), + } + }); + + const props = { isVisible: isVisible, onClose: onClose }; + + return ( + + + + Select your ERC20 Token + + + {dropdownItems && dropdownItems.length === 0 ? + + : + You don't have any ERC20 tokens + + } + + + + + ) +} \ No newline at end of file diff --git a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts index e69de29bb..680a17a0c 100644 --- a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts +++ b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts @@ -0,0 +1,34 @@ +import { getGnoNetwork, getNetworkFeature, NetworkFeature } from "@/networks"; +import { extractGnoJSONString } from "@/utils/gno"; +import { zodToken } from "@/utils/launchpadERC20/types"; +import { GnoJSONRPCProvider } from "@gnolang/gno-js-client"; +import { useQuery } from "@tanstack/react-query"; +import { z } from "zod"; + +export const useUserTokens = (networkId: string) => { + return useQuery(["userTokens"], async () => { + const gnoNetwork = getGnoNetwork(networkId); + if (!gnoNetwork) { + return null; + } + + const pmFeature = getNetworkFeature( + networkId, + NetworkFeature.LaunchpadERC20, + ); + + if (!pmFeature) { + return null; + } + + const client = new GnoJSONRPCProvider(gnoNetwork.endpoint); + const pkgPath = pmFeature.launchpadERC20PkgPath; + const query = `GetUserTokensJSON()`; + const contractData = await client.evaluateExpression(pkgPath, query); + + const res = extractGnoJSONString(contractData); + + const tokens = z.array(zodToken).parse(res); + return tokens; + }); +}; \ No newline at end of file From 335aac62a500d97d77ba562ae5233291282ba150 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 14 Oct 2024 16:35:46 +0200 Subject: [PATCH 04/14] fix: use string instead of std.addr in get user tokens json to call it from front-end --- gno/r/launchpad_grc20/token_factory_grc20.gno | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gno/r/launchpad_grc20/token_factory_grc20.gno b/gno/r/launchpad_grc20/token_factory_grc20.gno index db5b33579..0fcf3d414 100644 --- a/gno/r/launchpad_grc20/token_factory_grc20.gno +++ b/gno/r/launchpad_grc20/token_factory_grc20.gno @@ -190,11 +190,12 @@ func GetLastTokensJSON() string { return json.ArrayNode("", nodes).String() } -func GetUserTokensJSON(user std.Address) string { +func GetUserTokensJSON(user string) string { + userAddr := std.Address(user) var nodes []*json.Node tokens.Iterate("", "", func(key string, value interface{}) bool { token, _ := value.(*Token) - if token.admin.Owner() == user { + if token.admin.Owner() == userAddr { nodes = append(nodes, token.ToJSON()) } return false From e5ccc4d859bb6972a9beccf5a105d7ab80a56e2b Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 14 Oct 2024 16:58:27 +0200 Subject: [PATCH 05/14] fix: debug non working evaluate expression --- packages/screens/LaunchpadERC20/hooks/useUserTokens.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts index 680a17a0c..e8e0b8253 100644 --- a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts +++ b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts @@ -1,3 +1,4 @@ +import useSelectedWallet from "@/hooks/useSelectedWallet"; import { getGnoNetwork, getNetworkFeature, NetworkFeature } from "@/networks"; import { extractGnoJSONString } from "@/utils/gno"; import { zodToken } from "@/utils/launchpadERC20/types"; @@ -6,6 +7,8 @@ import { useQuery } from "@tanstack/react-query"; import { z } from "zod"; export const useUserTokens = (networkId: string) => { + const selectedWallet = useSelectedWallet(); + const caller = selectedWallet?.address; return useQuery(["userTokens"], async () => { const gnoNetwork = getGnoNetwork(networkId); if (!gnoNetwork) { @@ -23,10 +26,12 @@ export const useUserTokens = (networkId: string) => { const client = new GnoJSONRPCProvider(gnoNetwork.endpoint); const pkgPath = pmFeature.launchpadERC20PkgPath; - const query = `GetUserTokensJSON()`; + const query = `GetUserTokensJSON(${caller})`; + console.log(query); const contractData = await client.evaluateExpression(pkgPath, query); const res = extractGnoJSONString(contractData); + console.log(res); const tokens = z.array(zodToken).parse(res); return tokens; From f3f5ec37a1c6967583a144655804b1074a700721 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Tue, 15 Oct 2024 13:28:29 +0200 Subject: [PATCH 06/14] fix: add quotes to evaluate expression param to pass it as a string --- packages/screens/LaunchpadERC20/hooks/useUserTokens.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts index e8e0b8253..722e726f8 100644 --- a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts +++ b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts @@ -26,14 +26,12 @@ export const useUserTokens = (networkId: string) => { const client = new GnoJSONRPCProvider(gnoNetwork.endpoint); const pkgPath = pmFeature.launchpadERC20PkgPath; - const query = `GetUserTokensJSON(${caller})`; - console.log(query); + const query = `GetUserTokensJSON("${caller}")`; const contractData = await client.evaluateExpression(pkgPath, query); const res = extractGnoJSONString(contractData); - console.log(res); - const tokens = z.array(zodToken).parse(res); + return tokens; }); }; \ No newline at end of file From de49b72a36009b84da3bb9ff2bfee80302d651dd Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Wed, 16 Oct 2024 13:12:38 +0200 Subject: [PATCH 07/14] wip: developing dropdown --- .../NetworkSelector/NetworkSelectorMenu.tsx | 218 +++++++++--------- .../LaunchpadERC20SelectUserTokenModal.tsx | 13 +- .../LaunchpadERC20TokensDropdown.tsx | 82 +++++++ 3 files changed, 197 insertions(+), 116 deletions(-) create mode 100644 packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx diff --git a/packages/components/NetworkSelector/NetworkSelectorMenu.tsx b/packages/components/NetworkSelector/NetworkSelectorMenu.tsx index 7b502ba11..0210e07d6 100644 --- a/packages/components/NetworkSelector/NetworkSelectorMenu.tsx +++ b/packages/components/NetworkSelector/NetworkSelectorMenu.tsx @@ -38,120 +38,120 @@ export const NetworkSelectorMenu: FC<{ onSelect, optionsMenuwidth = 172, }) => { - const { resetMediaPlayer } = useMediaPlayer(); - const dispatch = useAppDispatch(); - const { wallets } = useWallets(); - const { setToastError } = useFeedbacks(); - const selectedNetworkInfo = useSelectedNetworkInfo(); - const [networksModalVisible, setNetworksModalVisible] = useState(false); - const enabledNetworks = useEnabledNetworks(); - const isMobile = useIsMobile(); + const { resetMediaPlayer } = useMediaPlayer(); + const dispatch = useAppDispatch(); + const { wallets } = useWallets(); + const { setToastError } = useFeedbacks(); + const selectedNetworkInfo = useSelectedNetworkInfo(); + const [networksModalVisible, setNetworksModalVisible] = useState(false); + const enabledNetworks = useEnabledNetworks(); + const isMobile = useIsMobile(); - const onPressNetwork = (networkId: string) => { - onSelect(); - let walletProvider: WalletProvider | null = null; + const onPressNetwork = (networkId: string) => { + onSelect(); + let walletProvider: WalletProvider | null = null; - const network = getNetwork(networkId); - if (!network) { - setToastError({ - title: "Error", - message: `unsupported network ${networkId}`, - }); - return; - } + const network = getNetwork(networkId); + if (!network) { + setToastError({ + title: "Error", + message: `unsupported network ${networkId}`, + }); + return; + } - switch (network.kind) { - case NetworkKind.Ethereum: - walletProvider = WalletProvider.Metamask; - break; - case NetworkKind.Cosmos: - walletProvider = WalletProvider.Keplr; - break; - } + switch (network.kind) { + case NetworkKind.Ethereum: + walletProvider = WalletProvider.Metamask; + break; + case NetworkKind.Cosmos: + walletProvider = WalletProvider.Keplr; + break; + } - // Auto select the first connected wallet when switching network - dispatch(setSelectedNetworkId(networkId)); + // Auto select the first connected wallet when switching network + dispatch(setSelectedNetworkId(networkId)); - const selectedWallet = wallets.find( - (w) => w.connected && w.provider === walletProvider, - ); + const selectedWallet = wallets.find( + (w) => w.connected && w.provider === walletProvider, + ); - dispatch(setSelectedWalletId(selectedWallet?.id || "")); + dispatch(setSelectedWalletId(selectedWallet?.id || "")); - resetMediaPlayer(); - }; + resetMediaPlayer(); + }; - return ( - - {enabledNetworks - .filter((network) => { - return ( - (!forceNetworkId || network.id === forceNetworkId) && // check that it's the forced network id if forced to - (!forceNetworkKind || network.kind === forceNetworkKind) && // check that it's the correct network kind if forced to - (!forceNetworkFeatures || - forceNetworkFeatures.every((feature) => - network.features.includes(feature), - )) && - selectedNetworkInfo?.id !== network.id // check that it's not already selected - ); - }) - .map((network, index) => { - const selectable = true; - return ( - onPressNetwork(network.id)} - > - - - - {network?.displayName || "Unknown"} - - - - ); - })} - { - setNetworksModalVisible(true); - }} - fullWidth - /> - { - setNetworksModalVisible(false); - }} - /> - - ); -}; + return ( + + {enabledNetworks + .filter((network) => { + return ( + (!forceNetworkId || network.id === forceNetworkId) && // check that it's the forced network id if forced to + (!forceNetworkKind || network.kind === forceNetworkKind) && // check that it's the correct network kind if forced to + (!forceNetworkFeatures || + forceNetworkFeatures.every((feature) => + network.features.includes(feature), + )) && + selectedNetworkInfo?.id !== network.id // check that it's not already selected + ); + }) + .map((network, index) => { + const selectable = true; + return ( + onPressNetwork(network.id)} + > + + + + {network?.displayName || "Unknown"} + + + + ); + })} + { + setNetworksModalVisible(true); + }} + fullWidth + /> + { + setNetworksModalVisible(false); + }} + /> + + ); + }; diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx index d6c3d5f1e..9e7cddfe3 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -1,5 +1,4 @@ import { BrandText } from "@/components/BrandText"; -import { DropdownWithListItem } from "@/components/mini/DropdownWithListItem"; import ModalBase from "@/components/modals/ModalBase"; import { SpacerColumn } from "@/components/spacer"; import { errorColor, neutral77 } from "@/utils/style/colors"; @@ -7,6 +6,7 @@ import { fontSemibold14 } from "@/utils/style/fonts"; import { useState } from "react"; import { View } from "react-native"; import { useUserTokens } from "../hooks/useUserTokens"; +import { LaunchpadERC20TokensDropdown } from "./LaunchpadERC20TokensDropdown"; // type DropdownItemType = { @@ -24,12 +24,11 @@ interface SelectTokenModalProps { export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, networkId }) => { const [error, setError] = useState(null); const { data: userTokens } = useUserTokens(networkId); + console.log(userTokens); const dropdownItems = userTokens?.map((token) => { - return { - name: token.name, - onPress: () => console.log("Token selected"), - } + return token.name; }); + console.log(dropdownItems); const props = { isVisible: isVisible, onClose: onClose }; @@ -50,8 +49,8 @@ export const SelectUserTokenModal: React.FC = ({ isVisibl Select your ERC20 Token - {dropdownItems && dropdownItems.length === 0 ? - + {dropdownItems && dropdownItems.length !== 0 ? + : You don't have any ERC20 tokens diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx new file mode 100644 index 000000000..a73be9830 --- /dev/null +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -0,0 +1,82 @@ +import React, { useState } from 'react'; +import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; + +interface LaunchpadERC20TokensDropdownProps { + items: string[]; + placeholder?: string; +} + +export const LaunchpadERC20TokensDropdown: React.FC = ({ items, placeholder = "Select an item" }) => { + const [isOpen, setIsOpen] = useState(false); + const [selectedItem, setSelectedItem] = useState(null); + + const toggleDropdown = () => { + setIsOpen(!isOpen); + }; + + const selectItem = (item: string) => { + setSelectedItem(item); + setIsOpen(false); + }; + + return ( + + {/* Dropdown Button (TextInput style) */} + + + {selectedItem ? selectedItem : placeholder} + + + + {/* Dropdown Modal for Items */} + {isOpen && ( + + {items.map((item, index) => ( + selectItem(item)} style={styles.dropdownItem}> + {item} + + ))} + + )} + + ); +}; + +const styles = StyleSheet.create({ + container: { + padding: 10, + width: '100%', + }, + inputField: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingVertical: 10, + paddingHorizontal: 15, + borderWidth: 1, + borderColor: '#ccc', + borderRadius: 5, + backgroundColor: '#fff', + }, + inputText: { + fontSize: 16, + color: '#333', + }, + dropdownMenu: { + marginTop: 5, + borderWidth: 1, + borderColor: '#ccc', + borderRadius: 5, + backgroundColor: '#fff', + }, + dropdownItem: { + paddingVertical: 10, + paddingHorizontal: 15, + borderBottomWidth: 1, + borderBottomColor: '#eee', + }, + itemText: { + fontSize: 16, + color: '#333', + }, +}); \ No newline at end of file From 6030a558a48ad9749ef051fb11b7ee04299a49ee Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Wed, 16 Oct 2024 15:53:41 +0200 Subject: [PATCH 08/14] feat: wip dropdown to select user tokens --- .../components/TopMenu/TopMenuMyWallets.tsx | 2 +- .../LaunchpadERC20TokensScreen.tsx | 10 +- .../LaunchpadERC20SelectUserTokenModal.tsx | 17 +-- .../LaunchpadERC20TokensDropdown.tsx | 107 ++++++++++++++---- .../LaunchpadERC20/hooks/useUserTokens.ts | 7 +- 5 files changed, 98 insertions(+), 45 deletions(-) diff --git a/packages/components/TopMenu/TopMenuMyWallets.tsx b/packages/components/TopMenu/TopMenuMyWallets.tsx index d8ff4e665..4e78e6db8 100644 --- a/packages/components/TopMenu/TopMenuMyWallets.tsx +++ b/packages/components/TopMenu/TopMenuMyWallets.tsx @@ -2,7 +2,6 @@ import { LinearGradient } from "expo-linear-gradient"; import React, { useMemo, useState } from "react"; import { StyleSheet, TouchableOpacity, View } from "react-native"; -import { TopMenuSection } from "./TopMenuSection"; import walletsSVG from "../../../assets/icons/wallets.svg"; import { useBalances } from "../../hooks/useBalances"; import { useDelegations } from "../../hooks/useDelegations"; @@ -38,6 +37,7 @@ import FlexRow from "../FlexRow"; import { SVG } from "../SVG"; import { SecondaryButton } from "../buttons/SecondaryButton"; import { SendModal } from "../modals/SendModal"; +import { TopMenuSection } from "./TopMenuSection"; import { DepositWithdrawModal } from "@/components/modals/DepositWithdrawModal"; import { useAppNavigation } from "@/hooks/navigation/useAppNavigation"; diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index ad7462520..2a8a2111b 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -13,9 +13,11 @@ import { FlowCard } from "@/components/cards/FlowCard"; import { SpacerColumn } from "@/components/spacer"; import { useForceNetworkSelection } from "@/hooks/useForceNetworkSelection"; import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; +import useSelectedWallet from "@/hooks/useSelectedWallet"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; import { SelectUserTokenModal } from "../component/LaunchpadERC20SelectUserTokenModal"; +import { useUserTokens } from "../hooks/useUserTokens"; export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ route: { params }, @@ -26,6 +28,12 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ const { width } = useWindowDimensions(); const navigation = useAppNavigation(); const [isModalVisible, setIsModalVisible] = React.useState(false); + const selectedWallet = useSelectedWallet(); + const caller = selectedWallet?.address; + const { data: tokens } = useUserTokens(networkId, caller || ""); + const dropdownItems = tokens?.map((token) => + token.name + ); const toggleModal = () => { setIsModalVisible(!isModalVisible); @@ -71,7 +79,7 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ disabled /> - + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx index 9e7cddfe3..f98466c6d 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -3,9 +3,7 @@ import ModalBase from "@/components/modals/ModalBase"; import { SpacerColumn } from "@/components/spacer"; import { errorColor, neutral77 } from "@/utils/style/colors"; import { fontSemibold14 } from "@/utils/style/fonts"; -import { useState } from "react"; import { View } from "react-native"; -import { useUserTokens } from "../hooks/useUserTokens"; import { LaunchpadERC20TokensDropdown } from "./LaunchpadERC20TokensDropdown"; @@ -19,17 +17,10 @@ interface SelectTokenModalProps { isVisible: boolean; onClose: () => void; networkId: string; + items: string[] | undefined; } -export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, networkId }) => { - const [error, setError] = useState(null); - const { data: userTokens } = useUserTokens(networkId); - console.log(userTokens); - const dropdownItems = userTokens?.map((token) => { - return token.name; - }); - console.log(dropdownItems); - +export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, networkId, items }) => { const props = { isVisible: isVisible, onClose: onClose }; return ( @@ -49,8 +40,8 @@ export const SelectUserTokenModal: React.FC = ({ isVisibl Select your ERC20 Token - {dropdownItems && dropdownItems.length !== 0 ? - + {items && items.length !== 0 ? + : You don't have any ERC20 tokens diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx index a73be9830..98eb5c02e 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -1,5 +1,17 @@ +import { LegacyTertiaryBox } from '@/components/boxes/LegacyTertiaryBox'; +import { TertiaryBox } from '@/components/boxes/TertiaryBox'; +import { BrandText } from '@/components/BrandText'; +import { Label } from '@/components/inputs/TextInputCustom'; +import { useDropdowns } from '@/hooks/useDropdowns'; +import { neutral17, neutral77, secondaryColor } from '@/utils/style/colors'; +import { fontSemibold14, fontSemibold16 } from '@/utils/style/fonts'; +import { layout } from '@/utils/style/layout'; import React, { useState } from 'react'; -import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { StyleSheet, TouchableOpacity, View } from 'react-native'; + +import { SVG } from '@/components/SVG'; +import chevronDownSVG from "../../../../assets/icons/chevron-down.svg"; +import chevronUpSVG from "../../../../assets/icons/chevron-up.svg"; interface LaunchpadERC20TokensDropdownProps { items: string[]; @@ -7,37 +19,83 @@ interface LaunchpadERC20TokensDropdownProps { } export const LaunchpadERC20TokensDropdown: React.FC = ({ items, placeholder = "Select an item" }) => { - const [isOpen, setIsOpen] = useState(false); const [selectedItem, setSelectedItem] = useState(null); - - const toggleDropdown = () => { - setIsOpen(!isOpen); - }; + const [isDropdownOpen, setDropdownState, ref] = useDropdowns(); const selectItem = (item: string) => { - setSelectedItem(item); - setIsOpen(false); + setSelectedItem(item);; }; return ( - - {/* Dropdown Button (TextInput style) */} - - - {selectedItem ? selectedItem : placeholder} - - + + - {/* Dropdown Modal for Items */} - {isOpen && ( - - {items.map((item, index) => ( - selectItem(item)} style={styles.dropdownItem}> - {item} + + setDropdownState()} + > + + Select your Token + + + + + + + {items && items.map((item, index) => ( + selectItem(item)} + > + + {item} + ))} - - )} + + ); }; @@ -76,7 +134,6 @@ const styles = StyleSheet.create({ borderBottomColor: '#eee', }, itemText: { - fontSize: 16, - color: '#333', + }, }); \ No newline at end of file diff --git a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts index 722e726f8..0485c7a33 100644 --- a/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts +++ b/packages/screens/LaunchpadERC20/hooks/useUserTokens.ts @@ -1,4 +1,3 @@ -import useSelectedWallet from "@/hooks/useSelectedWallet"; import { getGnoNetwork, getNetworkFeature, NetworkFeature } from "@/networks"; import { extractGnoJSONString } from "@/utils/gno"; import { zodToken } from "@/utils/launchpadERC20/types"; @@ -6,9 +5,7 @@ import { GnoJSONRPCProvider } from "@gnolang/gno-js-client"; import { useQuery } from "@tanstack/react-query"; import { z } from "zod"; -export const useUserTokens = (networkId: string) => { - const selectedWallet = useSelectedWallet(); - const caller = selectedWallet?.address; +export const useUserTokens = (networkId: string, addr: string) => { return useQuery(["userTokens"], async () => { const gnoNetwork = getGnoNetwork(networkId); if (!gnoNetwork) { @@ -26,7 +23,7 @@ export const useUserTokens = (networkId: string) => { const client = new GnoJSONRPCProvider(gnoNetwork.endpoint); const pkgPath = pmFeature.launchpadERC20PkgPath; - const query = `GetUserTokensJSON("${caller}")`; + const query = `GetUserTokensJSON("${addr}")`; const contractData = await client.evaluateExpression(pkgPath, query); const res = extractGnoJSONString(contractData); From 9bf022a60fbf99f37190b502c27676304928c022 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Wed, 16 Oct 2024 17:46:13 +0200 Subject: [PATCH 09/14] feat: dropdown to select user tokens --- .../LaunchpadERC20TokensDropdown.tsx | 235 +++++++++--------- 1 file changed, 116 insertions(+), 119 deletions(-) diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx index 98eb5c02e..b9c723d52 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -1,139 +1,136 @@ -import { LegacyTertiaryBox } from '@/components/boxes/LegacyTertiaryBox'; -import { TertiaryBox } from '@/components/boxes/TertiaryBox'; -import { BrandText } from '@/components/BrandText'; -import { Label } from '@/components/inputs/TextInputCustom'; -import { useDropdowns } from '@/hooks/useDropdowns'; -import { neutral17, neutral77, secondaryColor } from '@/utils/style/colors'; -import { fontSemibold14, fontSemibold16 } from '@/utils/style/fonts'; -import { layout } from '@/utils/style/layout'; -import React, { useState } from 'react'; -import { StyleSheet, TouchableOpacity, View } from 'react-native'; +import React, { useState } from "react"; +import { StyleSheet, TouchableOpacity, View } from "react-native"; -import { SVG } from '@/components/SVG'; import chevronDownSVG from "../../../../assets/icons/chevron-down.svg"; import chevronUpSVG from "../../../../assets/icons/chevron-up.svg"; +import { BrandText } from "@/components/BrandText"; +import FlexRow from "@/components/FlexRow"; +import { SVG } from "@/components/SVG"; +import { TertiaryBox } from "@/components/boxes/TertiaryBox"; +import { PrimaryButton } from "@/components/buttons/PrimaryButton"; +import { Label } from "@/components/inputs/TextInputCustom"; +import { SpacerColumn } from "@/components/spacer"; +import { neutral17, secondaryColor } from "@/utils/style/colors"; +import { fontSemibold16 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; + interface LaunchpadERC20TokensDropdownProps { - items: string[]; - placeholder?: string; + items: string[]; + placeholder?: string; } -export const LaunchpadERC20TokensDropdown: React.FC = ({ items, placeholder = "Select an item" }) => { - const [selectedItem, setSelectedItem] = useState(null); - const [isDropdownOpen, setDropdownState, ref] = useDropdowns(); +export const LaunchpadERC20TokensDropdown: React.FC< + LaunchpadERC20TokensDropdownProps +> = ({ items, placeholder = "Select an item" }) => { + const [selectedItem, setSelectedItem] = useState(null); + const [isDropdownOpen, setDropdownState] = useState(false); - const selectItem = (item: string) => { - setSelectedItem(item);; - }; + const selectItem = (item: string) => { + setSelectedItem(item); + setDropdownState(false); + }; - return ( - - + return ( + + - + + setDropdownState(!isDropdownOpen)} + > + + {selectedItem || placeholder} + + + + + {isDropdownOpen && ( + + + {items && + items.map((item, index) => ( setDropdownState()} + key={index} + style={styles.dropdownItem} + onPress={() => selectItem(item)} > + - Select your Token + {item} - + - - - - {items && items.map((item, index) => ( - selectItem(item)} - > - - {item} - - - ))} - - + ))} + - ); + )} + + + {}} + text="Open" + size="SM" + disabled={!selectedItem} + /> + + + ); }; +// eslint-disable-next-line no-restricted-syntax const styles = StyleSheet.create({ - container: { - padding: 10, - width: '100%', - }, - inputField: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - paddingVertical: 10, - paddingHorizontal: 15, - borderWidth: 1, - borderColor: '#ccc', - borderRadius: 5, - backgroundColor: '#fff', - }, - inputText: { - fontSize: 16, - color: '#333', - }, - dropdownMenu: { - marginTop: 5, - borderWidth: 1, - borderColor: '#ccc', - borderRadius: 5, - backgroundColor: '#fff', - }, - dropdownItem: { - paddingVertical: 10, - paddingHorizontal: 15, - borderBottomWidth: 1, - borderBottomColor: '#eee', - }, - itemText: { - - }, -}); \ No newline at end of file + label: { + marginBottom: layout.spacing_x1, + }, + dropdownBox: { + width: "100%", + height: 40, + flexDirection: "row", + paddingHorizontal: 12, + backgroundColor: neutral17, + alignItems: "center", + }, + dropdownButton: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + flex: 1, + }, + dropdownItem: { + marginBottom: layout.spacing_x2, + opacity: 1, + }, + dropdownContent: { + paddingTop: layout.spacing_x2, + backgroundColor: neutral17, + alignItems: "flex-start", + borderRadius: 8, + }, +}); From ca028082f50cc47f9f456ba2b5d798c4e30e369a Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Thu, 17 Oct 2024 14:53:54 +0200 Subject: [PATCH 10/14] wip: redirect to manage token page --- .../navigation/getNormalModeScreens.tsx | 10 +++++++ .../LaunchpadERC20ManageToken.tsx | 29 +++++++++++++++++++ .../LaunchpadERC20TokensScreen.tsx | 2 +- .../LaunchpadERC20SelectUserTokenModal.tsx | 29 ++++++++++++------- .../LaunchpadERC20TokensDropdown.tsx | 17 ++--------- packages/utils/navigation.ts | 12 ++++---- 6 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx diff --git a/packages/components/navigation/getNormalModeScreens.tsx b/packages/components/navigation/getNormalModeScreens.tsx index daefa37c4..6cdb4c1cd 100644 --- a/packages/components/navigation/getNormalModeScreens.tsx +++ b/packages/components/navigation/getNormalModeScreens.tsx @@ -28,6 +28,7 @@ import { LaunchpadERC20CreateSaleScreen } from "@/screens/LaunchpadERC20/Launchp import { LaunchpadERC20SalesScreen } from "@/screens/LaunchpadERC20/LaunchpadERC20Sales/LaunchpadERC20SalesScreen"; import { LaunchpadERC20Screen } from "@/screens/LaunchpadERC20/LaunchpadERC20Screen"; import { LaunchpadERC20CreateTokenScreen } from "@/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20CreateTokenScreen"; +import { LaunchpadERC20ManageTokenScreen } from "@/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken"; import { LaunchpadERC20TokensScreen } from "@/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen"; import { LaunchpadERC20AirdropsScreen } from "@/screens/LaunchpadERC20/LaunchpadERCAirdrops/LaunchpadERC20AirdropsScreen"; import { LaunchpadERC20CreateAirdropScreen } from "@/screens/LaunchpadERC20/LaunchpadERCAirdrops/LaunchpadERC20CreateAirdropScreen"; @@ -315,6 +316,15 @@ export const getNormalModeScreens = ({ appMode }: { appMode: AppMode }) => { }} /> + null, + title: screenTitle("Launchpad ERC20 Manage Token"), + }} + /> + = ({ + route: { params }, +}) => { + const network = params?.network; + useForceNetworkSelection(network); + const navigation = useAppNavigation(); + + return ( + Launchpad ERC 20} + forceNetworkFeatures={[NetworkFeature.LaunchpadERC20]} + forceNetworkKind={NetworkKind.Gno} + isLarge + responsive + onBackPress={() => navigation.navigate("LaunchpadERC20Tokens")} + > + + + ); +}; diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index 2a8a2111b..899e6d854 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -79,7 +79,7 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ disabled /> - + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx index f98466c6d..0aefb149d 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -1,27 +1,25 @@ import { BrandText } from "@/components/BrandText"; +import FlexRow from "@/components/FlexRow"; +import { PrimaryButton } from "@/components/buttons/PrimaryButton"; import ModalBase from "@/components/modals/ModalBase"; import { SpacerColumn } from "@/components/spacer"; +import { useAppNavigation } from "@/utils/navigation"; import { errorColor, neutral77 } from "@/utils/style/colors"; import { fontSemibold14 } from "@/utils/style/fonts"; +import { useState } from "react"; import { View } from "react-native"; import { LaunchpadERC20TokensDropdown } from "./LaunchpadERC20TokensDropdown"; - -// type DropdownItemType = { -// icon?: FC | string; -// name: string; -// onPress?: (navigation: NavigationProp) => void; -// }; - interface SelectTokenModalProps { isVisible: boolean; onClose: () => void; - networkId: string; items: string[] | undefined; } -export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, networkId, items }) => { +export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, items }) => { + const [selectedItem, setSelectedItem] = useState(null); const props = { isVisible: isVisible, onClose: onClose }; + const navigation = useAppNavigation(); return ( = ({ isVisibl {items && items.length !== 0 ? - + : You don't have any ERC20 tokens } - + + + { navigation.navigate("LaunchpadERC20ManageToken", {}); onClose(); }} + text="Open" + size="SM" + disabled={!selectedItem} + /> + + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx index b9c723d52..dd9d9c1be 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -5,25 +5,23 @@ import chevronDownSVG from "../../../../assets/icons/chevron-down.svg"; import chevronUpSVG from "../../../../assets/icons/chevron-up.svg"; import { BrandText } from "@/components/BrandText"; -import FlexRow from "@/components/FlexRow"; import { SVG } from "@/components/SVG"; import { TertiaryBox } from "@/components/boxes/TertiaryBox"; -import { PrimaryButton } from "@/components/buttons/PrimaryButton"; import { Label } from "@/components/inputs/TextInputCustom"; -import { SpacerColumn } from "@/components/spacer"; import { neutral17, secondaryColor } from "@/utils/style/colors"; import { fontSemibold16 } from "@/utils/style/fonts"; import { layout } from "@/utils/style/layout"; interface LaunchpadERC20TokensDropdownProps { items: string[]; + setSelectedItem: (item: string) => void; + selectedItem?: string | null; placeholder?: string; } export const LaunchpadERC20TokensDropdown: React.FC< LaunchpadERC20TokensDropdownProps -> = ({ items, placeholder = "Select an item" }) => { - const [selectedItem, setSelectedItem] = useState(null); +> = ({ items, setSelectedItem, selectedItem, placeholder = "Select an item" }) => { const [isDropdownOpen, setDropdownState] = useState(false); const selectItem = (item: string) => { @@ -91,15 +89,6 @@ export const LaunchpadERC20TokensDropdown: React.FC< )} - - - {}} - text="Open" - size="SM" - disabled={!selectedItem} - /> - ); }; diff --git a/packages/utils/navigation.ts b/packages/utils/navigation.ts index ecb6498e2..d759bfe54 100644 --- a/packages/utils/navigation.ts +++ b/packages/utils/navigation.ts @@ -43,6 +43,7 @@ export type RootStackParamList = { LaunchpadERC20: undefined; LaunchpadERC20Tokens?: { network?: string }; LaunchpadERC20CreateToken: { step?: number }; + LaunchpadERC20ManageToken: { network?: string }; LaunchpadERC20Airdrops?: { network?: string }; LaunchpadERC20CreateAirdrop: { step?: number }; LaunchpadERC20Sales?: { network?: string }; @@ -62,11 +63,11 @@ export type RootStackParamList = { post?: string; }; FeedNewArticle: - | (NewPostFormValues & { - additionalMention?: string; - additionalHashtag?: string; - }) - | undefined; + | (NewPostFormValues & { + additionalMention?: string; + additionalHashtag?: string; + }) + | undefined; FeedPostView: { id: string }; HashtagFeed: { hashtag: string }; @@ -229,6 +230,7 @@ const navConfig: { LaunchpadERC20: "launchpad-erc20", LaunchpadERC20Tokens: "launchpad-erc20/tokens", LaunchpadERC20CreateToken: "launchpad-erc20/create-token", + LaunchpadERC20ManageToken: "launchpad-erc20/manage-token", LaunchpadERC20Airdrops: "launchpad-erc20/airdrops", LaunchpadERC20CreateAirdrop: "launchpad-erc20/create-airdrop", LaunchpadERC20Sales: "launchpad-erc20/sales", From 54bb6a71ab39d260e9b9cd200c232a8ef69d8835 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Thu, 17 Oct 2024 23:04:42 +0200 Subject: [PATCH 11/14] fix: lint & fix few bugs --- .../NetworkSelector/NetworkSelectorMenu.tsx | 218 +++++++++--------- .../components/TopMenu/TopMenuMyWallets.tsx | 2 +- .../LaunchpadERC20ManageToken.tsx | 37 ++- .../LaunchpadERC20TokensScreen.tsx | 26 ++- .../component/LaunchpadERC20AirdropsTable.tsx | 2 +- .../component/LaunchpadERC20SalesTable.tsx | 2 +- .../LaunchpadERC20SelectUserTokenModal.tsx | 107 +++++---- .../LaunchpadERC20TokensDropdown.tsx | 78 +++---- .../component/LaunchpadERC20TokensTable.tsx | 2 +- .../LaunchpadERC20/hooks/useLastAirdrops.ts | 2 +- .../LaunchpadERC20/hooks/useLastSales.ts | 2 +- .../LaunchpadERC20/hooks/useLastTokens.ts | 2 +- .../LaunchpadERC20/hooks/useUserTokens.ts | 49 ++-- .../Projects/components/MilestoneBoard.tsx | 4 +- .../components/ProjectInfo/RelatedUsers.tsx | 2 +- .../Projects/components/ProjectMilestones.tsx | 4 +- packages/utils/navigation.ts | 10 +- .../utils/{launchpadERC20 => types}/types.ts | 0 18 files changed, 280 insertions(+), 269 deletions(-) rename packages/utils/{launchpadERC20 => types}/types.ts (100%) diff --git a/packages/components/NetworkSelector/NetworkSelectorMenu.tsx b/packages/components/NetworkSelector/NetworkSelectorMenu.tsx index 0210e07d6..7b502ba11 100644 --- a/packages/components/NetworkSelector/NetworkSelectorMenu.tsx +++ b/packages/components/NetworkSelector/NetworkSelectorMenu.tsx @@ -38,120 +38,120 @@ export const NetworkSelectorMenu: FC<{ onSelect, optionsMenuwidth = 172, }) => { - const { resetMediaPlayer } = useMediaPlayer(); - const dispatch = useAppDispatch(); - const { wallets } = useWallets(); - const { setToastError } = useFeedbacks(); - const selectedNetworkInfo = useSelectedNetworkInfo(); - const [networksModalVisible, setNetworksModalVisible] = useState(false); - const enabledNetworks = useEnabledNetworks(); - const isMobile = useIsMobile(); + const { resetMediaPlayer } = useMediaPlayer(); + const dispatch = useAppDispatch(); + const { wallets } = useWallets(); + const { setToastError } = useFeedbacks(); + const selectedNetworkInfo = useSelectedNetworkInfo(); + const [networksModalVisible, setNetworksModalVisible] = useState(false); + const enabledNetworks = useEnabledNetworks(); + const isMobile = useIsMobile(); - const onPressNetwork = (networkId: string) => { - onSelect(); - let walletProvider: WalletProvider | null = null; + const onPressNetwork = (networkId: string) => { + onSelect(); + let walletProvider: WalletProvider | null = null; - const network = getNetwork(networkId); - if (!network) { - setToastError({ - title: "Error", - message: `unsupported network ${networkId}`, - }); - return; - } + const network = getNetwork(networkId); + if (!network) { + setToastError({ + title: "Error", + message: `unsupported network ${networkId}`, + }); + return; + } - switch (network.kind) { - case NetworkKind.Ethereum: - walletProvider = WalletProvider.Metamask; - break; - case NetworkKind.Cosmos: - walletProvider = WalletProvider.Keplr; - break; - } + switch (network.kind) { + case NetworkKind.Ethereum: + walletProvider = WalletProvider.Metamask; + break; + case NetworkKind.Cosmos: + walletProvider = WalletProvider.Keplr; + break; + } - // Auto select the first connected wallet when switching network - dispatch(setSelectedNetworkId(networkId)); + // Auto select the first connected wallet when switching network + dispatch(setSelectedNetworkId(networkId)); - const selectedWallet = wallets.find( - (w) => w.connected && w.provider === walletProvider, - ); - - dispatch(setSelectedWalletId(selectedWallet?.id || "")); + const selectedWallet = wallets.find( + (w) => w.connected && w.provider === walletProvider, + ); - resetMediaPlayer(); - }; + dispatch(setSelectedWalletId(selectedWallet?.id || "")); - return ( - - {enabledNetworks - .filter((network) => { - return ( - (!forceNetworkId || network.id === forceNetworkId) && // check that it's the forced network id if forced to - (!forceNetworkKind || network.kind === forceNetworkKind) && // check that it's the correct network kind if forced to - (!forceNetworkFeatures || - forceNetworkFeatures.every((feature) => - network.features.includes(feature), - )) && - selectedNetworkInfo?.id !== network.id // check that it's not already selected - ); - }) - .map((network, index) => { - const selectable = true; - return ( - onPressNetwork(network.id)} - > - - - - {network?.displayName || "Unknown"} - - - - ); - })} - { - setNetworksModalVisible(true); - }} - fullWidth - /> - { - setNetworksModalVisible(false); - }} - /> - - ); + resetMediaPlayer(); }; + + return ( + + {enabledNetworks + .filter((network) => { + return ( + (!forceNetworkId || network.id === forceNetworkId) && // check that it's the forced network id if forced to + (!forceNetworkKind || network.kind === forceNetworkKind) && // check that it's the correct network kind if forced to + (!forceNetworkFeatures || + forceNetworkFeatures.every((feature) => + network.features.includes(feature), + )) && + selectedNetworkInfo?.id !== network.id // check that it's not already selected + ); + }) + .map((network, index) => { + const selectable = true; + return ( + onPressNetwork(network.id)} + > + + + + {network?.displayName || "Unknown"} + + + + ); + })} + { + setNetworksModalVisible(true); + }} + fullWidth + /> + { + setNetworksModalVisible(false); + }} + /> + + ); +}; diff --git a/packages/components/TopMenu/TopMenuMyWallets.tsx b/packages/components/TopMenu/TopMenuMyWallets.tsx index 4e78e6db8..d8ff4e665 100644 --- a/packages/components/TopMenu/TopMenuMyWallets.tsx +++ b/packages/components/TopMenu/TopMenuMyWallets.tsx @@ -2,6 +2,7 @@ import { LinearGradient } from "expo-linear-gradient"; import React, { useMemo, useState } from "react"; import { StyleSheet, TouchableOpacity, View } from "react-native"; +import { TopMenuSection } from "./TopMenuSection"; import walletsSVG from "../../../assets/icons/wallets.svg"; import { useBalances } from "../../hooks/useBalances"; import { useDelegations } from "../../hooks/useDelegations"; @@ -37,7 +38,6 @@ import FlexRow from "../FlexRow"; import { SVG } from "../SVG"; import { SecondaryButton } from "../buttons/SecondaryButton"; import { SendModal } from "../modals/SendModal"; -import { TopMenuSection } from "./TopMenuSection"; import { DepositWithdrawModal } from "@/components/modals/DepositWithdrawModal"; import { useAppNavigation } from "@/hooks/navigation/useAppNavigation"; diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx index ec13e99a2..5177e0c41 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx @@ -1,29 +1,24 @@ -import React from "react"; - - import { BrandText } from "@/components/BrandText"; import { ScreenContainer } from "@/components/ScreenContainer"; import { useForceNetworkSelection } from "@/hooks/useForceNetworkSelection"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; -export const LaunchpadERC20ManageTokenScreen: ScreenFC<"LaunchpadERC20ManageToken"> = ({ - route: { params }, -}) => { - const network = params?.network; - useForceNetworkSelection(network); - const navigation = useAppNavigation(); - - return ( - Launchpad ERC 20} - forceNetworkFeatures={[NetworkFeature.LaunchpadERC20]} - forceNetworkKind={NetworkKind.Gno} - isLarge - responsive - onBackPress={() => navigation.navigate("LaunchpadERC20Tokens")} - > +export const LaunchpadERC20ManageTokenScreen: ScreenFC< + "LaunchpadERC20ManageToken" +> = ({ route: { params } }) => { + const network = params?.network; + useForceNetworkSelection(network); + const navigation = useAppNavigation(); - - ); + return ( + Launchpad ERC 20} + forceNetworkFeatures={[NetworkFeature.LaunchpadERC20]} + forceNetworkKind={NetworkKind.Gno} + isLarge + responsive + onBackPress={() => navigation.navigate("LaunchpadERC20Tokens")} + /> + ); }; diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index 899e6d854..bb2a445a4 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -1,10 +1,12 @@ -import React from "react"; +import { useState } from "react"; import { useWindowDimensions, View } from "react-native"; import exploreSVG from "../../../../assets/icons/explore-neutral77.svg"; import penSVG from "../../../../assets/icons/pen-neutral77.svg"; import registerSVG from "../../../../assets/icons/register-neutral77.svg"; +import { SelectUserTokenModal } from "../component/LaunchpadERC20SelectUserTokenModal"; import { TokensTable } from "../component/LaunchpadERC20TokensTable"; +import { useUserTokens } from "../hooks/useUserTokens"; import { breakpoints } from "../utils/breakpoints"; import { BrandText } from "@/components/BrandText"; @@ -16,8 +18,6 @@ import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; import useSelectedWallet from "@/hooks/useSelectedWallet"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; -import { SelectUserTokenModal } from "../component/LaunchpadERC20SelectUserTokenModal"; -import { useUserTokens } from "../hooks/useUserTokens"; export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ route: { params }, @@ -27,17 +27,15 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ const networkId = useSelectedNetworkId(); const { width } = useWindowDimensions(); const navigation = useAppNavigation(); - const [isModalVisible, setIsModalVisible] = React.useState(false); + const [isModalVisible, setIsModalVisible] = useState(false); const selectedWallet = useSelectedWallet(); const caller = selectedWallet?.address; const { data: tokens } = useUserTokens(networkId, caller || ""); - const dropdownItems = tokens?.map((token) => - token.name - ); + const dropdownItems = tokens?.map((token) => token.name); const toggleModal = () => { setIsModalVisible(!isModalVisible); - } + }; return ( = ({ label="Manage" description="Mint, burn, or transfer the tokens you own" iconSVG={penSVG} - onPress={() => { setIsModalVisible(true) }} + onPress={() => { + setIsModalVisible(true); + }} style={{ marginHorizontal: width >= breakpoints.MD_BREAKPOINT ? 12 : 0, marginVertical: width >= breakpoints.LG_BREAKPOINT ? 0 : 12, @@ -75,11 +75,15 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ label="Explore" description="Lookup tokens and explore their details" iconSVG={exploreSVG} - onPress={() => { }} + onPress={() => {}} disabled /> - + diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx index f8c1a3c15..6da10cd32 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx @@ -15,8 +15,8 @@ import { TableRow } from "@/components/table/TableRow"; import { TableTextCell } from "@/components/table/TableTextCell"; import { TableWrapper } from "@/components/table/TableWrapper"; import { TableColumns } from "@/components/table/utils"; -import { Airdrop } from "@/utils/launchpadERC20/types"; import { screenContentMaxWidthLarge } from "@/utils/style/layout"; +import { Airdrop } from "@/utils/types/types"; const columns: TableColumns = { id: { diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SalesTable.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SalesTable.tsx index 69627f08b..dfc6ff893 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SalesTable.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SalesTable.tsx @@ -11,8 +11,8 @@ import { TableRow } from "@/components/table/TableRow"; import { TableTextCell } from "@/components/table/TableTextCell"; import { TableWrapper } from "@/components/table/TableWrapper"; import { TableColumns } from "@/components/table/utils"; -import { Sale } from "@/utils/launchpadERC20/types"; import { screenContentMaxWidthLarge } from "@/utils/style/layout"; +import { Sale } from "@/utils/types/types"; const columns: TableColumns = { id: { diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx index 0aefb149d..fd6bb1f1f 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -1,3 +1,8 @@ +import { useState } from "react"; +import { View } from "react-native"; + +import { LaunchpadERC20TokensDropdown } from "./LaunchpadERC20TokensDropdown"; + import { BrandText } from "@/components/BrandText"; import FlexRow from "@/components/FlexRow"; import { PrimaryButton } from "@/components/buttons/PrimaryButton"; @@ -6,56 +11,64 @@ import { SpacerColumn } from "@/components/spacer"; import { useAppNavigation } from "@/utils/navigation"; import { errorColor, neutral77 } from "@/utils/style/colors"; import { fontSemibold14 } from "@/utils/style/fonts"; -import { useState } from "react"; -import { View } from "react-native"; -import { LaunchpadERC20TokensDropdown } from "./LaunchpadERC20TokensDropdown"; interface SelectTokenModalProps { - isVisible: boolean; - onClose: () => void; - items: string[] | undefined; + isVisible: boolean; + onClose: () => void; + items: string[] | undefined; } -export const SelectUserTokenModal: React.FC = ({ isVisible, onClose, items }) => { - const [selectedItem, setSelectedItem] = useState(null); - const props = { isVisible: isVisible, onClose: onClose }; - const navigation = useAppNavigation(); +export const SelectUserTokenModal: React.FC = ({ + isVisible, + onClose, + items, +}) => { + const [selectedItem, setSelectedItem] = useState(null); + const props = { isVisible, onClose }; + const navigation = useAppNavigation(); - return ( - + + + Select your ERC20 Token + + + {items && items.length !== 0 ? ( + + ) : ( + + You don't have any ERC20 tokens + + )} + + + { + navigation.navigate("LaunchpadERC20ManageToken", {}); + onClose(); }} - > - - - Select your ERC20 Token - - - {items && items.length !== 0 ? - - : - You don't have any ERC20 tokens - - } - - - { navigation.navigate("LaunchpadERC20ManageToken", {}); onClose(); }} - text="Open" - size="SM" - disabled={!selectedItem} - /> - - - - - - ) -} \ No newline at end of file + text="Open" + size="SM" + disabled={!selectedItem} + /> + + + + + ); +}; diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx index dd9d9c1be..ba7dd5ac5 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { StyleSheet, TouchableOpacity, View } from "react-native"; +import { TouchableOpacity, View } from "react-native"; import chevronDownSVG from "../../../../assets/icons/chevron-down.svg"; import chevronUpSVG from "../../../../assets/icons/chevron-up.svg"; @@ -8,7 +8,7 @@ import { BrandText } from "@/components/BrandText"; import { SVG } from "@/components/SVG"; import { TertiaryBox } from "@/components/boxes/TertiaryBox"; import { Label } from "@/components/inputs/TextInputCustom"; -import { neutral17, secondaryColor } from "@/utils/style/colors"; +import { neutral17, neutralFF, secondaryColor } from "@/utils/style/colors"; import { fontSemibold16 } from "@/utils/style/fonts"; import { layout } from "@/utils/style/layout"; @@ -21,7 +21,12 @@ interface LaunchpadERC20TokensDropdownProps { export const LaunchpadERC20TokensDropdown: React.FC< LaunchpadERC20TokensDropdownProps -> = ({ items, setSelectedItem, selectedItem, placeholder = "Select an item" }) => { +> = ({ + items, + setSelectedItem, + selectedItem, + placeholder = "Select an item", +}) => { const [isDropdownOpen, setDropdownState] = useState(false); const selectItem = (item: string) => { @@ -31,13 +36,27 @@ export const LaunchpadERC20TokensDropdown: React.FC< return ( - ); }; diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx index bb2a445a4..4d7a77e4f 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20TokensScreen.tsx @@ -31,7 +31,6 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ const selectedWallet = useSelectedWallet(); const caller = selectedWallet?.address; const { data: tokens } = useUserTokens(networkId, caller || ""); - const dropdownItems = tokens?.map((token) => token.name); const toggleModal = () => { setIsModalVisible(!isModalVisible); @@ -82,7 +81,7 @@ export const LaunchpadERC20TokensScreen: ScreenFC<"LaunchpadERC20Tokens"> = ({ diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20DetailTokenBox.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20DetailTokenBox.tsx new file mode 100644 index 000000000..f6dee4a2a --- /dev/null +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20DetailTokenBox.tsx @@ -0,0 +1,36 @@ +import { View } from "react-native"; + +import { BrandText } from "@/components/BrandText"; +import { neutralA3 } from "@/utils/style/colors"; +import { layout } from "@/utils/style/layout"; +import { Token } from "@/utils/types/types"; + +interface SelectTokenModalProps { + item: Token; +} + +export const LaunchpadERC20DetailTokenBox: React.FC = ({ + item, +}) => { + return ( + + {"Name: " + item.name} + {"Symbol: " + item.symbol} + {"Decimals: " + item.decimals} + + {"Total Supply : " + item.totalSupply + " " + item.symbol} + + {item.allowMint ? "Allow Mint" : "Not Allow Mint"} + {item.allowBurn ? "Allow Burn" : "Not Allow Burn"} + + ); +}; diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx index fd6bb1f1f..643c4832d 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20SelectUserTokenModal.tsx @@ -11,11 +11,12 @@ import { SpacerColumn } from "@/components/spacer"; import { useAppNavigation } from "@/utils/navigation"; import { errorColor, neutral77 } from "@/utils/style/colors"; import { fontSemibold14 } from "@/utils/style/fonts"; +import { emptyToken, Token } from "@/utils/types/types"; interface SelectTokenModalProps { isVisible: boolean; onClose: () => void; - items: string[] | undefined; + items: Token[] | undefined | null; } export const SelectUserTokenModal: React.FC = ({ @@ -23,7 +24,7 @@ export const SelectUserTokenModal: React.FC = ({ onClose, items, }) => { - const [selectedItem, setSelectedItem] = useState(null); + const [selectedItem, setSelectedItem] = useState(emptyToken); const props = { isVisible, onClose }; const navigation = useAppNavigation(); @@ -59,7 +60,9 @@ export const SelectUserTokenModal: React.FC = ({ { - navigation.navigate("LaunchpadERC20ManageToken", {}); + navigation.navigate("LaunchpadERC20ManageToken", { + token: selectedItem, + }); onClose(); }} text="Open" diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx index ba7dd5ac5..8b0172049 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokensDropdown.tsx @@ -11,11 +11,12 @@ import { Label } from "@/components/inputs/TextInputCustom"; import { neutral17, neutralFF, secondaryColor } from "@/utils/style/colors"; import { fontSemibold16 } from "@/utils/style/fonts"; import { layout } from "@/utils/style/layout"; +import { Token } from "@/utils/types/types"; interface LaunchpadERC20TokensDropdownProps { - items: string[]; - setSelectedItem: (item: string) => void; - selectedItem?: string | null; + items: Token[]; + setSelectedItem: (token: Token) => void; + selectedItem?: Token | null; placeholder?: string; } @@ -29,7 +30,7 @@ export const LaunchpadERC20TokensDropdown: React.FC< }) => { const [isDropdownOpen, setDropdownState] = useState(false); - const selectItem = (item: string) => { + const selectItem = (item: Token) => { setSelectedItem(item); setDropdownState(false); }; @@ -68,7 +69,7 @@ export const LaunchpadERC20TokensDropdown: React.FC< }, ]} > - {selectedItem || placeholder} + {selectedItem?.name || placeholder} - {item} + {item.name} diff --git a/packages/utils/navigation.ts b/packages/utils/navigation.ts index 70a50c567..a16b30cef 100644 --- a/packages/utils/navigation.ts +++ b/packages/utils/navigation.ts @@ -6,6 +6,7 @@ import { feedsTabItems } from "./social-feed"; import { AppMode } from "./types/app-mode"; import { NewPostFormValues } from "./types/feed"; import { MessageFriendsTabItem } from "./types/message"; +import { Token } from "./types/types"; import { uppTabItems } from "./upp"; export type RouteName = keyof RootStackParamList; @@ -43,7 +44,7 @@ export type RootStackParamList = { LaunchpadERC20: undefined; LaunchpadERC20Tokens?: { network?: string }; LaunchpadERC20CreateToken: { step?: number }; - LaunchpadERC20ManageToken: { network?: string }; + LaunchpadERC20ManageToken: { network?: string; token: Token }; LaunchpadERC20Airdrops?: { network?: string }; LaunchpadERC20CreateAirdrop: { step?: number }; LaunchpadERC20Sales?: { network?: string }; diff --git a/packages/utils/types/types.ts b/packages/utils/types/types.ts index 9da691e6b..fce712b6a 100644 --- a/packages/utils/types/types.ts +++ b/packages/utils/types/types.ts @@ -14,6 +14,18 @@ export const zodToken = z.object({ export type Token = z.infer; +export const emptyToken = { + symbol: "", + name: "", + decimals: "", + admin: "", + image: "", + totalSupply: "", + totalSupplyCap: "", + allowMint: false, + allowBurn: false, +}; + export const zodAidrop = z.object({ id: z.string(), tokenName: z.string(), From a0b7effd82262edabdc74774b9baff304928b554 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Tue, 22 Oct 2024 14:22:58 +0200 Subject: [PATCH 14/14] wip: redirect to manage token page --- .../LaunchpadERC20ManageToken.tsx | 9 +++ .../LaunchpadERC20TokenAmountButton.tsx | 67 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 packages/screens/LaunchpadERC20/component/LaunchpadERC20TokenAmountButton.tsx diff --git a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx index bedaeb657..04540eb54 100644 --- a/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx +++ b/packages/screens/LaunchpadERC20/LaunchpadERC20Tokens/LaunchpadERC20ManageToken.tsx @@ -6,6 +6,8 @@ import { SpacerColumn } from "@/components/spacer"; import { useForceNetworkSelection } from "@/hooks/useForceNetworkSelection"; import { NetworkFeature, NetworkKind } from "@/networks"; import { ScreenFC, useAppNavigation } from "@/utils/navigation"; +import { useState } from "react"; +import { LaunchpadERC20TokenAmountButton } from "../component/LaunchpadERC20TokenAmountButton"; export const LaunchpadERC20ManageTokenScreen: ScreenFC< "LaunchpadERC20ManageToken" @@ -14,6 +16,8 @@ export const LaunchpadERC20ManageTokenScreen: ScreenFC< const token = params.token; useForceNetworkSelection(network); const navigation = useAppNavigation(); + const [mintAmount, setMintAmount] = useState(0); + const [burnAmount, setBurnAmount] = useState(0); return ( navigation.navigate("LaunchpadERC20Tokens")} > + + Tokens Details + + + ); }; diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokenAmountButton.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokenAmountButton.tsx new file mode 100644 index 000000000..1564c832d --- /dev/null +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20TokenAmountButton.tsx @@ -0,0 +1,67 @@ +import { TertiaryBox } from "@/components/boxes/TertiaryBox"; +import { PrimaryButton } from "@/components/buttons/PrimaryButton"; +import { Label } from "@/components/inputs/TextInputCustom"; +import { neutral17, neutralFF } from "@/utils/style/colors"; +import { fontSemibold16 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; +import { StyleProp, TextInput, View, ViewStyle } from "react-native"; + +interface LaunchpadERC20TokenAmountButtonProps { + amount: number; + setAmount: (amount: number) => void; + placeholder?: string; + buttonLabel: string; + onPress?: () => void; + disabled?: boolean; + viewStyle: StyleProp; +} + +export const LaunchpadERC20TokenAmountButton: React.FC = ({ + amount, + setAmount, + placeholder = "Amount", + buttonLabel, + onPress, + disabled, + viewStyle +}) => { + return ( + + + + + setAmount(Number(text))} + keyboardType="numeric" + /> + + + + ); +}; \ No newline at end of file