Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add link to subscan explore on the transaction status pop up #557

Merged
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@hookform/resolvers": "^2.9.11",
"@netlify/functions": "^2.8.1",
"@pendulum-chain/api": "^0.3.8",
"@pendulum-chain/api-solang": "^0.4.0",
"@pendulum-chain/api-solang": "^0.6.1",
"@polkadot/api": "^10.9.1",
"@polkadot/api-base": "^10.9.1",
"@polkadot/api-contract": "^10.9.1",
Expand Down
14 changes: 7 additions & 7 deletions src/components/Layout/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { memo, useEffect, useMemo, useState } from 'preact/compat';
import { memo, useEffect, useMemo, useState, useRef } from 'preact/compat';
import { NavLink, useLocation } from 'react-router-dom';

import { useGlobalState } from '../../GlobalStateProvider';
import useBoolean from '../../hooks/useBoolean';
import { createLinks, LinkItem } from './links';
import { NavCollapseButtonContent } from './NavCollapseButtonContent';

Expand All @@ -25,17 +24,18 @@ const CollapseMenu = ({
const paths = path.split('/').filter(Boolean);
return paths[1] && paths[1].startsWith(link.replace('/', '')) ? true : false;
}, [link, pathname]);
const [isOpen, { toggle }] = useBoolean(isActive);

const inputRef = useRef<HTMLInputElement>(null);

return (
<section className={`collapse ${disabled ? 'disabled' : 'collapse-arrow'} ${isOpen ? 'collapse-open' : ''}`}>
<section className={`collapse ${disabled ? 'disabled' : 'collapse-arrow'}`}>
<input type="checkbox" checked={isActive} ref={inputRef} />
<button
type="button"
className={`nav-item collapse-btn collapse-title ${isActive ? 'active' : ''}`}
onClick={() => toggle()}
aria-controls={ariaControls}
aria-expanded={isOpen}
aria-disabled={disabled}
aria-expanded={inputRef.current?.checked}
>
{button}
</button>
Expand Down Expand Up @@ -109,7 +109,7 @@ const Nav = memo(({ onClick }: NavProps) => {
ariaControls="submenu"
button={<NavCollapseButtonContent item={item} isPlaying={isPlaying} />}
>
<ul className="submenu" id="submenu">
<ul className="submenu" id={`submenu-${i}`}>
{item.submenu.map((subItem, j) => (
<li key={`${i}-${j}`} className="ml-[3px]">
<NavItem item={subItem} onClick={onClick} isSubNavItem={true} />
Expand Down
16 changes: 8 additions & 8 deletions src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function Layout(): JSX.Element | null {
<div id="sidebar-wrapper" className="z-50 flex flex-wrap">
<aside
id="sidebar"
className={`flex self-start text-center bottom-0 top-0 h-160 pt-8 h-screen transition-all lg:left-0 lg:relative absolute ${bgColor} ${
className={`scroll-thin h-160 absolute bottom-0 top-0 flex h-screen self-start pt-8 text-center transition-all lg:relative lg:left-0 ${bgColor} ${
visible ? 'open left-0' : 'closed -left-full'
}`}
>
Expand All @@ -57,20 +57,20 @@ export default function Layout(): JSX.Element | null {
</a>
</div>
<Nav onClick={() => setVisible(false)} />
<footer className="mx-auto sidebar-footer">
<footer className="sidebar-footer mx-auto">
<NetworkId />
<SocialAndTermLinks />
</footer>
</aside>
</div>
<section className={visible && isMobile ? 'opacity-25' : ''}>
<header>
<div className="flex items-center justify-end gap-2 h-15">
<div className="h-15 flex items-center justify-end gap-2">
<GetToken />
<ChainSelector />
<div className="hidden mr-2 dropdown dropdown-end">
<button className="flex items-center py-2 space-x-2 btn no-animation">
<span className={`${isPendulum ? 'text-white' : ''} text-md`}>
<div className="dropdown dropdown-end mr-2 hidden">
<button className="btn no-animation flex items-center space-x-2 py-2">
<span className={`${isPendulum ? 'text-white' : ''} text-md`}>
{isPendulum ? 'Pendulum' : 'Amplitude'}
</span>
<svg
Expand All @@ -89,7 +89,7 @@ export default function Layout(): JSX.Element | null {
/>
</svg>
</button>
<ul tabIndex={0} className="p-2 shadow dropdown-content menu bg-base-100 rounded-box w-52">
<ul tabIndex={0} className="menu dropdown-content w-52 rounded-box bg-base-100 p-2 shadow">
<li>
<FooterLink />
</li>
Expand All @@ -104,7 +104,7 @@ export default function Layout(): JSX.Element | null {
</div>
</header>
<main
className="flex-wrap flex-grow w-full px-4 py-4"
className="w-full flex-grow flex-wrap px-4 py-4"
onClick={() => {
if (visible && isMobile) {
setVisible(false);
Expand Down
4 changes: 2 additions & 2 deletions src/components/nabla/common/NablaFootnote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ const nablaHomepageUrl = 'https://nabla.fi';

export function NablaFootnote() {
return (
<div className="text-center mt-3 font-bold text-sm">
<div className="mt-3 text-center text-sm font-bold">
Powered by{' '}
<a href={nablaHomepageUrl} target="_blank" rel="noreferrer">
Nabla technology
Vortex Finance
</a>
</div>
);
Expand Down
40 changes: 30 additions & 10 deletions src/components/nabla/common/TransactionProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ExecuteMessageResult } from '@pendulum-chain/api-solang';

import Spinner from '../../../assets/spinner';
import { UseContractWriteResponse } from '../../../hooks/nabla/useContractWrite';
import { TenantName } from '../../../models/Tenant';
import { useGlobalState } from '../../../GlobalStateProvider';

export interface TransactionProgressProps {
mutation: UseContractWriteResponse;
Expand All @@ -26,43 +28,61 @@ const getErrorMessage = (data?: ExecuteMessageResult['result']) => {
}
};

export function TransactionProgress({ mutation, children, onClose }: TransactionProgressProps): JSX.Element | null {
if (mutation.isIdle) return null;
function getExplorerUrl(tenant: TenantName, data?: ExecuteMessageResult['execution']) {
if (tenant === TenantName.Pendulum && data?.type === 'extrinsic') {
return `https://pendulum.subscan.io/extrinsic/${data.txHash.toHex()}`;
}
}

export function TransactionProgress({ mutation, children, onClose }: TransactionProgressProps) {
const { tenantName } = useGlobalState();
const errorMsg = getErrorMessage(mutation.data?.result);

const explorerUrl = getExplorerUrl(tenantName, mutation.data?.execution);

if (mutation.isIdle) return null;

if (mutation.isLoading) {
const isPending = false; // TODO: currently there is not status for this (waiting confirmation in wallet)
return (
<>
<div className="flex flex-col items-center justify-center text-center mt-4">
<div className="mt-4 flex flex-col items-center justify-center text-center">
<Spinner size={100} color="#ddd" />
<h4 className="text-2xl mt-12 text-[--text]">
<h4 className="mt-12 text-2xl text-[--text]">
{isPending ? 'Waiting for confirmation' : 'Executing transaction'}
</h4>
{children}
<p className="text-neutral-500 my-5">
<p className="my-5 text-neutral-500">
{isPending ? 'Confirm this transaction in your wallet' : 'Proceed in your wallet'}
</p>
</div>
</>
);
}

return (
<>
<div className="center mt-6">
{mutation.isSuccess ? (
<CheckCircleIcon className="w-36 h-36 text-green-400" stroke-width={1} />
<CheckCircleIcon className="h-36 w-36 text-green-400" stroke-width={1} />
) : (
<ExclamationCircleIcon className="w-36 h-36 text-red-400" stroke-width={1} />
<ExclamationCircleIcon className="h-36 w-36 text-red-400" stroke-width={1} />
)}
</div>
<div className="text-center mt-4">
<div className="mt-4 text-center">
<h4 className="text-2xl text-[--text]">
{mutation.isSuccess ? 'Transaction successful' : 'Transaction failed'}
</h4>
</div>
{!mutation.isSuccess && !!errorMsg && <p className="text-center mt-1">{errorMsg}</p>}
{!mutation.isSuccess && !!errorMsg && <p className="mt-1 text-center">{errorMsg}</p>}
<div className="mt-6"></div>
{!!explorerUrl && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question because it is the first time I see it that way: Is there a difference between !!explorerUrl && ... and explorerUrl && since explorerUrl can only be undefined or a truthy (nonempty) string?

From the official docs:

React considers false as a “hole” in the JSX tree, just like null or undefined, and doesn’t render anything in its place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No you are right, there is no need for this here. I just used it to cast it to a boolean value but that's not really necessary here. Removed.

<a href={explorerUrl} target="_blank" rel="noreferrer" className="btn btn-secondary w-full">
View on Explorer
</a>
)}
{!!onClose && (
<Button color="primary" className="w-full mt-6" onClick={onClose}>
<Button color="primary" className="mt-2 w-full" onClick={onClose}>
Close
</Button>
)}
Expand Down
10 changes: 8 additions & 2 deletions src/config/apps/nabla.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TenantName } from '../../models/Tenant';
import { AppConfigBase } from './types';

export type NablaConfig = AppConfigBase &
Partial<
Record<
Expand All @@ -13,11 +14,16 @@ export type NablaConfig = AppConfigBase &
>;

export const nablaConfig: NablaConfig = {
tenants: [TenantName.Foucoco],
environment: ['staging', 'development'],
tenants: [TenantName.Foucoco, TenantName.Pendulum],
environment: ['staging', 'development', 'production'],
foucoco: {
indexerUrl: 'https://pendulum.squids.live/foucoco-squid/graphql',
router: '6mYwT4yRrrMK978NszqBvxkvXjYnsmKfs2BkYGJGiR4XY9Sc',
oracle: '6kqj1tnYUGY3L93YFArXKF2E4tpQ2tUJ4DARwkAjZEyDoof6',
},
pendulum: {
indexerUrl: 'https://pendulum.squids.live/pendulum-squid/graphql',
router: '6buMJsFCbXpHRyacKTjBn3Jss241b2aA7CZf9tKzKHMJWpcJ',
oracle: '6f9uHwN2r5w82Bjrywc4wmZYb6TN64bZH5Ev87qmJ675uFvq',
},
};
4 changes: 4 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ w3m-modal {
scrollbar-width: none;
}

.scroll-thin {
scrollbar-width: thin;
}

:root:has(:is(.modal-open, .modal:target, .modal-toggle:checked + .modal, .modal[open])) {
scrollbar-gutter: unset;
}
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3342,9 +3342,9 @@ __metadata:
languageName: node
linkType: hard

"@pendulum-chain/api-solang@npm:^0.4.0":
version: 0.4.0
resolution: "@pendulum-chain/api-solang@npm:0.4.0"
"@pendulum-chain/api-solang@npm:^0.6.1":
version: 0.6.1
resolution: "@pendulum-chain/api-solang@npm:0.6.1"
peerDependencies:
"@polkadot/api": ^10.0
"@polkadot/api-contract": ^10.12.1
Expand All @@ -3353,7 +3353,7 @@ __metadata:
"@polkadot/types-codec": ^10.0
"@polkadot/util": "*"
"@polkadot/util-crypto": "*"
checksum: 10c0/37f0b225b1529dd46b38e050a4fac89acb706bc62b10855db83f4e8658423aeb921f8ad16fadcd21e9aef68aa5ac66274dbdd829247005a3e207a94411ab1cd0
checksum: 10c0/9db47f45bad07c33820b73bd0ef0c4573102a6fa11a135f4e31f9381c8a9d76804c5b217433ac63c25ebd17f2126457c50e41cb4867641aeffa027b247811905
languageName: node
linkType: hard

Expand Down Expand Up @@ -13453,7 +13453,7 @@ __metadata:
"@hookform/resolvers": "npm:^2.9.11"
"@netlify/functions": "npm:^2.8.1"
"@pendulum-chain/api": "npm:^0.3.8"
"@pendulum-chain/api-solang": "npm:^0.4.0"
"@pendulum-chain/api-solang": "npm:^0.6.1"
"@pendulum-chain/types": "npm:^0.3.8"
"@polkadot/api": "npm:^10.9.1"
"@polkadot/api-base": "npm:^10.9.1"
Expand Down
Loading