diff --git a/components/Layout/SearchBlock.js b/components/Layout/SearchBlock.js index 08579167..37510a11 100644 --- a/components/Layout/SearchBlock.js +++ b/components/Layout/SearchBlock.js @@ -5,6 +5,7 @@ import { useRouter } from 'next/router' import axios from 'axios' import { useSearchParams } from 'next/navigation' import Link from 'next/link' +import { classicAddressToXAddress } from 'ripple-address-codec' import { IoMdClose } from 'react-icons/io' import { @@ -153,9 +154,9 @@ export default function SearchBlock({ searchPlaceholderText, tab = null, userDat const searchOnChange = (option) => { if (!option) return if (option.username && !option.username.includes('-')) { - onSearch(option.username) + onSearch(option.username, option?.tag) } else { - onSearch(option.address) + onSearch(option.address, option?.tag) } } @@ -178,7 +179,7 @@ export default function SearchBlock({ searchPlaceholderText, tab = null, userDat } } - const onSearch = async (si) => { + const onSearch = async (si, tag = null) => { setErrorMessage('') let searchFor = null @@ -279,14 +280,15 @@ export default function SearchBlock({ searchPlaceholderText, tab = null, userDat return } - if (isValidPayString(searchFor) || isValidXAddress(searchFor)) { + if (isValidPayString(searchItem) || isValidXAddress(searchItem)) { // the check for paystring/xAddress should be before the check for addressOrUsername, // as if there is no destination tag, we will treat it as an address or username - - // we need to resolve paystring and x-address first before redirecting! - // if there is a tag - - // get the new page which we can show an address and a tag - router.push('/account/' + encodeURI(searchFor) + addParams) //replace with a new page to show a tag + if(tag) { + const xAddress = classicAddressToXAddress(searchFor, tag) + router.push('/account/tag/' + encodeURI(xAddress) + addParams) + } else { + router.push('/account/' + encodeURI(searchFor) + addParams) + } return } diff --git a/pages/_app.js b/pages/_app.js index adc2ce99..6df5cac2 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -25,6 +25,7 @@ const WalletConnectModalSign = dynamic( import '../styles/globals.css' import '../styles/ui.scss' import '../styles/components/nprogress.css' +import '../styles/pages/account-tag.scss' import { ThemeProvider } from '../components/Layout/ThemeContext' import { fetchCurrentFiatRate } from '../utils/common' diff --git a/pages/account/tag/[...id].js b/pages/account/tag/[...id].js new file mode 100644 index 00000000..a2a1be74 --- /dev/null +++ b/pages/account/tag/[...id].js @@ -0,0 +1,267 @@ +import { useTranslation } from 'next-i18next' +import { useEffect } from 'react' +import { useRouter } from 'next/router' +import { serverSideTranslations } from 'next-i18next/serverSideTranslations' +import { axiosServer, passHeaders } from '../../../utils/axios' +import { xAddressToClassicAddress } from 'ripple-address-codec' + +import SEO from '../../../components/SEO' +import SearchBlock from '../../../components/Layout/SearchBlock' +import { + FaFacebook, + FaInstagram, + FaLinkedin, + FaMedium, + FaReddit, + FaTelegram, + FaYoutube, + FaXTwitter +} from 'react-icons/fa6' + +export async function getServerSideProps(context) { + const { locale, query, req } = context + let resolvedData = null + let errorMessage = null + + const { id } = query + const searchInput = id ? (Array.isArray(id) ? id[0] : id) : '' + + if (searchInput) { + try { + let address = null + let destinationTag = null + + try { + const decoded = xAddressToClassicAddress(searchInput) + address = decoded.classicAddress + destinationTag = decoded.tag + } catch (error) { + errorMessage = 'Invalid xAddress format' + } + + if (address) { + // Fetch account data for the resolved address + const accountResponse = await axiosServer({ + method: 'get', + url: `v2/address/${address}?username=true&service=true&verifiedDomain=true&parent=true&nickname=true&inception=true&flare=true&blacklist=true&payString=true&ledgerInfo=true&xamanMeta=true&bithomp=true&obligations=true`, + headers: passHeaders(req) + }) + + resolvedData = { + originalInput: searchInput, + address, + destinationTag, + accountData: accountResponse?.data + } + } + } catch (error) { + errorMessage = 'Error processing request' + } + } + + return { + props: { + resolvedData: resolvedData || {}, + errorMessage: errorMessage || null, + ...(await serverSideTranslations(locale, ['common', 'account'])) + } + } +} + +export default function AccountTag({ resolvedData, errorMessage }) { + const { t } = useTranslation() + const router = useRouter() + + // Function to render social links dynamically based on account data + const renderSocialLinks = (socialAccounts) => { + if (!socialAccounts) return null + + return ( +