Finish rebrand implementation

pull/47/head
J M Rossy 1 year ago
parent 342fb1efb0
commit b19c1ff78e
  1. BIN
      public/hyperlane-banner.png
  2. 4
      public/images/lines-bg-mid.svg
  3. 4
      public/images/lines-bg-top.svg
  4. 0
      public/images/logo-blue.png
  5. 0
      public/images/logo-with-text.png
  6. 0
      public/images/logo.png
  7. 0
      public/images/logo.svg
  8. 10
      src/components/buttons/SolidButton.tsx
  9. 6
      src/components/icons/Chevron.tsx
  10. 38
      src/components/icons/HyperlaneLogo.tsx
  11. 2
      src/components/input/Checkbox.module.css
  12. 2
      src/components/input/SelectField.tsx
  13. 11
      src/components/layout/AppLayout.tsx
  14. 11
      src/components/layout/Card.tsx
  15. 2
      src/components/layout/Modal.tsx
  16. 13
      src/components/nav/Footer.tsx
  17. 8
      src/components/nav/Header.tsx
  18. 4
      src/components/search/MiniSearchBar.tsx
  19. 4
      src/components/search/SearchBar.tsx
  20. 71
      src/components/search/SearchFilterBar.tsx
  21. 4
      src/components/search/SearchStates.tsx
  22. 36
      src/features/chains/ConfigureChains.tsx
  23. 29
      src/features/messages/MessageDetails.tsx
  24. 9
      src/features/messages/MessageSearch.tsx
  25. 18
      src/features/messages/MessageTable.tsx
  26. 4
      src/features/messages/cards/ContentDetailsCard.tsx
  27. 6
      src/features/messages/cards/GasDetailsCard.tsx
  28. 4
      src/features/messages/cards/IcaDetailsCard.tsx
  29. 4
      src/features/messages/cards/IsmDetailsCard.tsx
  30. 2
      src/features/messages/cards/KeyValueRow.tsx
  31. 4
      src/features/messages/cards/TimelineCard.tsx
  32. 4
      src/features/messages/cards/TransactionCard.tsx
  33. 2
      src/features/messages/queries/useMessageQuery.ts
  34. 0
      src/images/backgrounds/footer-bg.svg
  35. 0
      src/images/backgrounds/footer-line-desktop.svg
  36. 0
      src/images/backgrounds/footer-line-mobile.svg
  37. 0
      src/images/backgrounds/footer-top-border.svg
  38. 4
      src/images/backgrounds/main-bg.svg
  39. 5
      src/images/footer/footer-logo.svg
  40. 2
      src/images/icons/checkmark-circle.svg
  41. 2
      src/pages/_document.tsx
  42. 20
      src/pages/api-docs.tsx
  43. 21
      src/styles/Color.ts
  44. 20
      tailwind.config.js

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

@ -0,0 +1,4 @@
<svg width="1440" height="1422" viewBox="0 0 1440 1422" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-31.5 462.274C2081.5 638.912 -628.5 757.774 1473.5 932.774" stroke="white" stroke-width="8"/>
<path d="M-34 484.774C1976.5 621.774 -688.5 763.274 1470.5 960.774" stroke="white" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 317 B

@ -0,0 +1,4 @@
<svg width="886" height="114" viewBox="0 0 886 114" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M783.5 -3.5C621.953 133.053 158.722 87.2984 8 -3.5" stroke="white" stroke-width="2"/>
<path d="M884.5 -5.5C586 201.5 152.904 88.164 2 -5.5" stroke="white" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -1,7 +1,7 @@
import { PropsWithChildren, ReactElement } from 'react'; import { PropsWithChildren, ReactElement } from 'react';
interface ButtonProps { interface ButtonProps {
color?: 'white' | 'blue' | 'green' | 'red'; // defaults to blue color?: 'white' | 'blue' | 'green' | 'red' | 'pink'; // defaults to blue
type?: 'submit' | 'reset' | 'button'; type?: 'submit' | 'reset' | 'button';
onClick?: () => void; onClick?: () => void;
classes?: string; classes?: string;
@ -18,7 +18,7 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
onClick, onClick,
color: _color, color: _color,
classes, classes,
bold, bold = true,
icon, icon,
disabled, disabled,
title, title,
@ -26,12 +26,16 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
} = props; } = props;
const color = _color ?? 'blue'; const color = _color ?? 'blue';
const base = 'flex items-center justify-center rounded transition-all duration-500'; const base = 'flex items-center justify-center rounded-full transition-all duration-500';
let baseColors, onHover, onActive; let baseColors, onHover, onActive;
if (color === 'blue') { if (color === 'blue') {
baseColors = 'bg-blue-500 text-white'; baseColors = 'bg-blue-500 text-white';
onHover = 'hover:bg-blue-600'; onHover = 'hover:bg-blue-600';
onActive = 'active:bg-blue-700'; onActive = 'active:bg-blue-700';
} else if (color === 'pink') {
baseColors = 'bg-pink-500 text-white';
onHover = 'hover:bg-pink-600';
onActive = 'active:bg-pink-700';
} else if (color === 'green') { } else if (color === 'green') {
baseColors = 'bg-green-500 text-white'; baseColors = 'bg-green-500 text-white';
onHover = 'hover:bg-green-600'; onHover = 'hover:bg-green-600';

@ -40,7 +40,7 @@ function _ChevronIcon({ width, height, direction, color, classes }: Props) {
<path <path
d="M1 1l6 6 6-6" d="M1 1l6 6 6-6"
strokeWidth="2" strokeWidth="2"
stroke={color || Color.primaryBlack} stroke={color || Color.Black}
fill="none" fill="none"
fillRule="evenodd" fillRule="evenodd"
strokeLinecap="round" strokeLinecap="round"
@ -90,7 +90,7 @@ function _HyperlaneChevron({ width, height, direction, color, classes }: Props)
> >
<path <path
d="M6.3 1h61.3a20 20 0 0 1 18.7 13L140 158.3a5 5 0 0 1 0 3.4l-.3.9-53.5 147.2A20 20 0 0 1 67.4 323H6.2a5 5 0 0 1-4.7-6.6l55.2-158.1L1.7 7.7A5 5 0 0 1 6.2 1Z" d="M6.3 1h61.3a20 20 0 0 1 18.7 13L140 158.3a5 5 0 0 1 0 3.4l-.3.9-53.5 147.2A20 20 0 0 1 67.4 323H6.2a5 5 0 0 1-4.7-6.6l55.2-158.1L1.7 7.7A5 5 0 0 1 6.2 1Z"
fill={color || Color.primaryBlue} fill={color || Color.Blue}
></path> ></path>
</svg> </svg>
); );
@ -124,7 +124,7 @@ function _HyperlaneWideChevron({ width, height, direction, color, classes }: Pro
width={width} width={width}
height={height} height={height}
className={`${directionClass} ${classes}`} className={`${directionClass} ${classes}`}
fill={color || Color.primaryBlue} fill={color || Color.Blue}
> >
<path d="M4.4 0h53c7.2 0 13.7 3 16.2 7.7l46.5 85.1a2 2 0 0 1 0 2l-.2.5-46.3 87c-2.5 4.6-9 7.7-16.3 7.7h-53c-3 0-5-2-4-4L48 92.9.4 4c-1-2 1-4 4-4Z" /> <path d="M4.4 0h53c7.2 0 13.7 3 16.2 7.7l46.5 85.1a2 2 0 0 1 0 2l-.2.5-46.3 87c-2.5 4.6-9 7.7-16.3 7.7h-53c-3 0-5-2-4-4L48 92.9.4 4c-1-2 1-4 4-4Z" />
</svg> </svg>

@ -0,0 +1,38 @@
import { memo } from 'react';
function _HyperlaneLogo({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 117 118"
>
<path
d="M64.4787 0H88.4134C91.6788 0 94.6004 1.89614 95.7403 4.7553L116.749 57.4498C116.911 57.8563 116.913 58.3035 116.754 58.7112L116.637 59.014L116.635 59.017L95.7152 112.81C94.5921 115.698 91.6551 117.62 88.3666 117.62H64.4355C63.0897 117.62 62.1465 116.379 62.59 115.192L84.1615 57.4498L62.6428 2.45353C62.1766 1.26188 63.1208 0 64.4787 0Z"
fill={fill}
/>
<path
d="M1.99945 0H25.9342C29.1996 0 32.1211 1.89614 33.261 4.7553L54.2696 57.4498C54.4316 57.8563 54.4336 58.3035 54.275 58.7112L54.1573 59.014L54.1561 59.017L33.236 112.81C32.1129 115.698 29.1759 117.62 25.8874 117.62H1.95626C0.610483 117.62 -0.332722 116.379 0.110804 115.192L21.6823 57.4498L0.163626 2.45353C-0.302638 1.26188 0.641544 0 1.99945 0Z"
fill={fill}
/>
<path
d="M80.7202 46.2178H46.9324V71.7089H80.7202L86.2411 58.5992L80.7202 46.2178Z"
fill={fill}
/>
</svg>
);
}
export const HyperlaneLogo = memo(_HyperlaneLogo);

@ -20,7 +20,7 @@
border-radius: 0.2rem; border-radius: 0.2rem;
transform: scale(0); transform: scale(0);
transition: 200ms all ease-in-out; transition: 200ms all ease-in-out;
background-color: #2362c1; background-color: #2362C0;
} }
.checkbox:checked::before { .checkbox:checked::before {

@ -19,7 +19,7 @@ export function SelectField(props: Props) {
return ( return (
<select <select
className={`px-2 py-1 text-sm border border-gray-400 rounded bg-transparent invalid:text-gray-400 ${ className={`px-2 py-1 text-sm font-light border border-gray-400 rounded bg-transparent invalid:text-gray-400 ${
classes || '' classes || ''
}`} }`}
{...passThruProps} {...passThruProps}

@ -18,13 +18,14 @@ export function AppLayout({ pathName, children }: PropsWithChildren<Props>) {
<title>{`Hyperlane Explorer | ${getHeadTitle(pathName)}`}</title> <title>{`Hyperlane Explorer | ${getHeadTitle(pathName)}`}</title>
</Head> </Head>
<div <div
style={styles.container}
id="app-content" id="app-content"
className="w-full min-w-screen h-full min-h-screen flex flex-col justify-between bg-blue-500" className="relative w-full min-w-screen h-full min-h-screen flex flex-col justify-between bg-blue-500"
> >
{/* <InfoBanner /> */} {/* <InfoBanner /> */}
<Header pathName={pathName} /> <Header pathName={pathName} />
<div className="max-w-5xl mx-auto grow"> <div className="max-w-5xl mx-auto grow">
<main style={styles.container} className="min-h-full pt-2 "> <main style={styles.main} className="relative min-h-full pt-3 z-20">
{children} {children}
</main> </main>
</div> </div>
@ -42,6 +43,12 @@ function getHeadTitle(pathName: string) {
const styles = { const styles = {
container: { container: {
backgroundImage: 'url(/images/lines-bg-top.svg)',
backgroundSize: '94vw',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center 80px',
},
main: {
width: 'min(900px,96vw)', width: 'min(900px,96vw)',
}, },
}; };

@ -1,11 +1,16 @@
import { PropsWithChildren } from 'react'; import { PropsWithChildren } from 'react';
interface Props { interface Props {
classes?: string; className?: string;
padding?: string;
} }
export function Card({ classes, children }: PropsWithChildren<Props>) { export function Card({ className, padding = 'p-4 sm:p-5', children }: PropsWithChildren<Props>) {
return ( return (
<div className={`p-4 bg-white shadow border rounded overflow-auto ${classes}`}>{children}</div> <div
className={`bg-white ring ring-blue-300 rounded-3xl overflow-auto ${padding} ${className}`}
>
{children}
</div>
); );
} }

@ -42,7 +42,7 @@ export function Modal({
maxWidth || 'max-w-xs' maxWidth || 'max-w-xs'
} max-h-[90vh] transform overflow-auto rounded-md bg-white px-4 py-4 text-left shadow-lg transition-all`} } max-h-[90vh] transform overflow-auto rounded-md bg-white px-4 py-4 text-left shadow-lg transition-all`}
> >
<Dialog.Title as="h3" className="text text-gray-700"> <Dialog.Title as="h3" className="font-medium text-blue-500">
{title} {title}
</Dialog.Title> </Dialog.Title>
{children} {children}

@ -3,13 +3,14 @@ import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { links } from '../../consts/links'; import { links } from '../../consts/links';
// import FooterLine from '../../images/footer/footer-line-desktop.svg'; // import FooterLine from '../../images/backgrounds/footer-line-desktop.svg';
// import FooterLineMobile from '../../images/footer/footer-line-mobile.svg'; // import FooterLineMobile from '../../images/backgrounds/footer-line-mobile.svg';
import FooterBg from '../../images/footer/footer-bg.svg'; import FooterBg from '../../images/backgrounds/footer-bg.svg';
import FooterLogo from '../../images/footer/footer-logo.svg'; import FooterTopBorder from '../../images/backgrounds/footer-top-border.svg';
import FooterTopBorder from '../../images/footer/footer-top-border.svg'; import { Color } from '../../styles/Color';
import { Discord } from '../icons/Discord'; import { Discord } from '../icons/Discord';
import { Github } from '../icons/Github'; import { Github } from '../icons/Github';
import { HyperlaneLogo } from '../icons/HyperlaneLogo';
import { Medium } from '../icons/Medium'; import { Medium } from '../icons/Medium';
import { Twitter } from '../icons/Twitter'; import { Twitter } from '../icons/Twitter';
@ -47,7 +48,7 @@ export function Footer() {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center justify-center"> <div className="flex items-center justify-center">
<div className="ml-2 h-20 w-20"> <div className="ml-2 h-20 w-20">
<Image src={FooterLogo} alt="footer-logo" /> <HyperlaneLogo fill={Color.White} />
</div> </div>
<div className="text-2xl font-medium ml-6 space-y-1 "> <div className="text-2xl font-medium ml-6 space-y-1 ">
<div>Go Interchain</div> <div>Go Interchain</div>

@ -36,7 +36,7 @@ export function Header({ pathName }: { pathName: string }) {
return ( return (
<header <header
className={`z-30 sticky top-0 px-2 sm:px-6 lg:px-12 w-full bg-blue-500 transition-all ease-in-out duration-500 ${ className={`z-30 sticky top-0 px-2 sm:px-6 lg:px-12 w-full bg-blue-500 transition-all ease-in-out duration-500 ${
animateHeader ? 'py-1 border-b border-blue-400' : 'py-4 sm:py-5' animateHeader ? 'py-1 border-b border-white' : 'py-4 sm:py-5'
}`} }`}
> >
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -122,21 +122,21 @@ function DropdownButton({ isOpen }: { isOpen: boolean }) {
width={10} width={10}
height={14} height={14}
direction={isOpen ? 'n' : 's'} direction={isOpen ? 'n' : 's'}
color={Color.primaryWhite} color={Color.White}
classes="transition-all" classes="transition-all"
/> />
<HyperlaneWideChevron <HyperlaneWideChevron
width={10} width={10}
height={14} height={14}
direction={isOpen ? 'n' : 's'} direction={isOpen ? 'n' : 's'}
color={Color.primaryWhite} color={Color.White}
classes="-mt-1 transition-all" classes="-mt-1 transition-all"
/> />
<HyperlaneWideChevron <HyperlaneWideChevron
width={10} width={10}
height={14} height={14}
direction={isOpen ? 'n' : 's'} direction={isOpen ? 'n' : 's'}
color={Color.primaryWhite} color={Color.White}
classes="-mt-1 transition-all" classes="-mt-1 transition-all"
/> />
</div> </div>

@ -22,13 +22,13 @@ export function MiniSearchBar() {
return ( return (
<Formik<FormValues> initialValues={initialValues} onSubmit={onSubmit}> <Formik<FormValues> initialValues={initialValues} onSubmit={onSubmit}>
<Form> <Form>
<div className="p-1 flex items-center bg-white ring-4 ring-blue-400 hover:ring-blue-200 rounded-full transition-all"> <div className="p-1 flex items-center bg-white ring ring-blue-400 hover:ring-blue-200 rounded-full transition-all">
<Field <Field
id="search" id="search"
name="search" name="search"
type="search" type="search"
placeholder="Hash or address" placeholder="Hash or address"
className="w-32 focus:w-64 py-2 px-2.5 h-8 text-sm rounded-full placeholder:text-gray-500 focus:outline-none transition-[width] ease-in-out duration-500" className="w-32 focus:w-64 py-2 px-2.5 h-8 text-sm font-light placeholder:text-gray-600 rounded-full focus:outline-none transition-[width] ease-in-out duration-500"
/> />
<div className="h-8 w-8 flex items-center justify-center rounded-full bg-pink-500"> <div className="h-8 w-8 flex items-center justify-center rounded-full bg-pink-500">
<IconButton <IconButton

@ -20,13 +20,13 @@ export function SearchBar({ value, placeholder, onChangeValue, isFetching }: Pro
}; };
return ( return (
<div className="p-1 flex items-center bg-white w-full rounded-full ring-4 ring-blue-400 hover:ring-blue-200 transition-all duration-500"> <div className="p-1 flex items-center bg-white w-full rounded-full ring ring-blue-400 hover:ring-blue-200 transition-all duration-500">
<input <input
value={value} value={value}
onChange={onChange} onChange={onChange}
type="search" type="search"
placeholder={placeholder} placeholder={placeholder}
className="p-1 sm:px-4 md:px-5 flex-1 h-10 sm:h-12 rounded-full placeholder:text-gray-500 focus:outline-none" className="p-1 sm:px-4 md:px-5 flex-1 h-10 sm:h-12 font-light rounded-full placeholder:text-gray-600 focus:outline-none"
/> />
<div className="h-10 sm:h-12 w-10 sm:w-12 flex items-center justify-center rounded-full bg-pink-500"> <div className="h-10 sm:h-12 w-10 sm:w-12 flex items-center justify-center rounded-full bg-pink-500">
{isFetching && <Spinner classes="scale-[30%] mr-2.5 invert" />} {isFetching && <Spinner classes="scale-[30%] mr-2.5 invert" />}

@ -7,8 +7,9 @@ import { ChainMetadata, mainnetChainsMetadata, testnetChainsMetadata } from '@hy
import { getChainDisplayName } from '../../features/chains/utils'; import { getChainDisplayName } from '../../features/chains/utils';
import { useMultiProvider } from '../../features/providers/multiProvider'; import { useMultiProvider } from '../../features/providers/multiProvider';
import GearIcon from '../../images/icons/gear.svg'; import GearIcon from '../../images/icons/gear.svg';
import { Color } from '../../styles/Color';
import { arrayToObject } from '../../utils/objects'; import { arrayToObject } from '../../utils/objects';
import { BorderedButton } from '../buttons/BorderedButton'; import { SolidButton } from '../buttons/SolidButton';
import { TextButton } from '../buttons/TextButton'; import { TextButton } from '../buttons/TextButton';
import { ChainLogo } from '../icons/ChainLogo'; import { ChainLogo } from '../icons/ChainLogo';
import { ChevronIcon } from '../icons/Chevron'; import { ChevronIcon } from '../icons/Chevron';
@ -61,15 +62,10 @@ export function SearchFilterBar({
endValue={endTimestamp} endValue={endTimestamp}
onChangeEndValue={onChangeEndTimestamp} onChangeEndValue={onChangeEndTimestamp}
/> />
<div className="w-px h-8 bg-gray-200"></div>
<Link href="/settings" title="View explorer settings"> <Link href="/settings" title="View explorer settings">
<Image <div className="p-1.5 bg-pink-500 rounded-full active:opacity-90 hover:rotate-90 transition-all">
src={GearIcon} <Image src={GearIcon} width={16} height={16} className="invert" alt="Settings" />
width={24} </div>
height={24}
className="opacity-40 hover:opacity-30 active:opacity-20 hover:rotate-90 transition-all"
alt=""
/>
</Link> </Link>
</div> </div>
); );
@ -151,23 +147,26 @@ function ChainMultiSelector({
<DropdownModal <DropdownModal
buttonContent={ buttonContent={
<> <>
<span className="text-gray-700 py-px">{text}</span> <span className="text-white font-medium py-px">{text}</span>
<ChevronIcon direction="s" width={9} height={5} classes="ml-2 opacity-80" /> <ChevronIcon
direction="s"
width={9}
height={5}
classes="ml-2 opacity-80"
color={Color.White}
/>
</> </>
} }
buttonClasses="text-sm sm:min-w-[5.8rem] px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded border border-gray-500 hover:opacity-70 active:opacity-60 transition-all" buttonClasses="text-sm sm:min-w-[5.8rem] px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded-full bg-pink-500 hover:opacity-80 active:opacity-70 transition-all"
modalContent={(closeDropdown) => ( modalContent={(closeDropdown) => (
<div className="p-4"> <div className="p-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-gray-700 text-lg">{header}</h3> <h3 className="font-medium text-blue-500">{header}</h3>
<div className="flex mr-4"> <div className="flex mr-4">
<TextButton classes="text-sm underline underline-offset-2" onClick={onToggleAll}> <TextButton classes="text-sm font-medium text-pink-500" onClick={onToggleAll}>
All All
</TextButton> </TextButton>
<TextButton <TextButton classes="ml-3.5 text-sm font-medium text-pink-500" onClick={onToggleNone}>
classes="ml-3.5 text-sm underline underline-offset-2"
onClick={onToggleNone}
>
None None
</TextButton> </TextButton>
</div> </div>
@ -180,7 +179,7 @@ function ChainMultiSelector({
onToggle={onToggleSection(mainnetChainsMetadata)} onToggle={onToggleSection(mainnetChainsMetadata)}
name="mainnet-chains" name="mainnet-chains"
> >
<h4 className="ml-2 text-gray-700">Mainnet Chains</h4> <h4 className="ml-2 text-gray-800">Mainnet Chains</h4>
</CheckBox> </CheckBox>
</div> </div>
{mainnetChainsMetadata.map((c) => ( {mainnetChainsMetadata.map((c) => (
@ -191,7 +190,7 @@ function ChainMultiSelector({
name={c.name} name={c.name}
> >
<div className="py-0.5 ml-2 text-sm flex items-center"> <div className="py-0.5 ml-2 text-sm flex items-center">
<span className="mr-2"> <span className="mr-2 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)} {getChainDisplayName(multiProvider, c.chainId, true)}
</span> </span>
<ChainLogo chainId={c.chainId} size={12} color={false} background={false} /> <ChainLogo chainId={c.chainId} size={12} color={false} background={false} />
@ -207,7 +206,7 @@ function ChainMultiSelector({
onToggle={onToggleSection(testnetChainsMetadata)} onToggle={onToggleSection(testnetChainsMetadata)}
name="testnet-chains" name="testnet-chains"
> >
<h4 className="ml-2 text-gray-700">Testnet Chains</h4> <h4 className="ml-2 text-gray-800">Testnet Chains</h4>
</CheckBox> </CheckBox>
</div> </div>
{testnetChainsMetadata.map((c) => ( {testnetChainsMetadata.map((c) => (
@ -218,7 +217,7 @@ function ChainMultiSelector({
name={c.name} name={c.name}
> >
<div className="py-0.5 ml-2 text-sm flex items-center"> <div className="py-0.5 ml-2 text-sm flex items-center">
<span className="mr-2"> <span className="mr-2 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)} {getChainDisplayName(multiProvider, c.chainId, true)}
</span> </span>
<ChainLogo chainId={c.chainId} size={12} color={false} background={false} /> <ChainLogo chainId={c.chainId} size={12} color={false} background={false} />
@ -227,12 +226,12 @@ function ChainMultiSelector({
))} ))}
</div> </div>
</div> </div>
<BorderedButton <SolidButton
classes="mt-2.5 text-sm px-2 py-1 w-full" classes="mt-2.5 text-sm px-2 py-1 w-full"
onClick={() => onClickApply(closeDropdown)} onClick={() => onClickApply(closeDropdown)}
> >
Apply Apply
</BorderedButton> </SolidButton>
</div> </div>
)} )}
modalClasses={`w-88 ${position || 'right-0'}`} modalClasses={`w-88 ${position || 'right-0'}`}
@ -270,33 +269,39 @@ function DatetimeSelector({
<DropdownModal <DropdownModal
buttonContent={ buttonContent={
<> <>
<span className="text-gray-700 py-px px-2">Time</span> <span className="text-white font-medium py-px px-2">Time</span>
<ChevronIcon direction="s" width={9} height={5} classes="ml-2 opacity-80" /> <ChevronIcon
direction="s"
width={9}
height={5}
classes="ml-2 opacity-80"
color={Color.White}
/>
</> </>
} }
buttonClasses="text-sm px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded border border-gray-500 hover:opacity-70 active:opacity-60 transition-all" buttonClasses="text-sm px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded-full bg-pink-500 hover:opacity-80 active:opacity-70 transition-all"
modalContent={(closeDropdown) => ( modalContent={(closeDropdown) => (
<div className="p-4" key="date-time-selector"> <div className="p-4" key="date-time-selector">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-gray-700 text-lg">Time Range</h3> <h3 className="text-blue-500 font-medium">Time Range</h3>
<div className="flex pt-1"> <div className="flex pt-1">
<TextButton classes="text-sm underline underline-offset-2" onClick={onClickClear}> <TextButton classes="text-sm font-medium text-pink-500" onClick={onClickClear}>
Clear Clear
</TextButton> </TextButton>
</div> </div>
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<h4 className="mt-3 mb-1 text-gray-700">Start Time</h4> <h4 className="mt-3 mb-1 text-gray-500 text-sm font-medium">Start Time</h4>
<DatetimeField timestamp={startTime} onChange={setStartTime} /> <DatetimeField timestamp={startTime} onChange={setStartTime} />
<h4 className="mt-3 mb-1 text-gray-700">End Time</h4> <h4 className="mt-3 mb-1 text-gray-500 text-sm font-medium">End Time</h4>
<DatetimeField timestamp={endTime} onChange={setEndTime} /> <DatetimeField timestamp={endTime} onChange={setEndTime} />
</div> </div>
<BorderedButton <SolidButton
classes="mt-4 text-sm px-2 py-1 w-full" classes="mt-4 text-sm px-2 py-1 w-full"
onClick={() => onClickApply(closeDropdown)} onClick={() => onClickApply(closeDropdown)}
> >
Apply Apply
</BorderedButton> </SolidButton>
</div> </div>
)} )}
modalClasses="w-60 -right-8" modalClasses="w-60 -right-8"

@ -17,7 +17,7 @@ export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetc
<div className="flex items-center justify-center scale-90"> <div className="flex items-center justify-center scale-90">
<Spinner /> <Spinner />
</div> </div>
<div className="mt-4 text-center leading-loose text-gray-700"> <div className="mt-4 text-center font-light leading-loose text-gray-700">
{isPiFetching ? 'Searching custom chains for messages' : 'Searching for messages'} {isPiFetching ? 'Searching custom chains for messages' : 'Searching for messages'}
</div> </div>
</div> </div>
@ -45,7 +45,7 @@ export function SearchError({
<div className="flex justify-center my-10"> <div className="flex justify-center my-10">
<div className="flex flex-col items-center justify-center max-w-md px-3 py-5"> <div className="flex flex-col items-center justify-center max-w-md px-3 py-5">
<Image src={imgSrc} width={imgWidth} className="opacity-80" alt="" /> <Image src={imgSrc} width={imgWidth} className="opacity-80" alt="" />
<div className="mt-4 text-center leading-loose text-gray-700">{text}</div> <div className="mt-4 text-center font-light leading-loose text-gray-700">{text}</div>
</div> </div>
</div> </div>
</Fade> </Fade>

@ -57,8 +57,8 @@ export function ConfigureChains() {
return ( return (
<Card> <Card>
<h2 className="mt-1 text-xl text-blue-500">Chain Settings</h2> <h2 className="mt-1 text-lg text-blue-500 font-medium">Chain Settings</h2>
<p className="mt-3"> <p className="mt-3 font-light">
Hyperlane can be deployed to any chain using{' '} Hyperlane can be deployed to any chain using{' '}
<a <a
href={`${links.docs}/docs/deploy/permissionless-interoperability`} href={`${links.docs}/docs/deploy/permissionless-interoperability`}
@ -70,31 +70,35 @@ export function ConfigureChains() {
</a> </a>
. This explorer can be configured to search for messages on any PI chain. . This explorer can be configured to search for messages on any PI chain.
</p> </p>
<h3 className="mt-4 text-lg text-blue-500">Default Chains</h3> <h3 className="mt-6 text-lg text-blue-500 font-medium">Default Chains</h3>
<div className="mt-4 flex"> <div className="mt-4 flex">
<h4 className="text-gray-600">Mainnets:</h4> <h4 className="text-gray-600 font-medium text-sm">Mainnets:</h4>
<div className="ml-3 flex gap-3.5 flex-wrap"> <div className="ml-3 flex gap-3.5 flex-wrap">
{mainnetChainsMetadata.map((c) => ( {mainnetChainsMetadata.map((c) => (
<div className="shrink-0 text-sm flex items-center" key={c.name}> <div className="shrink-0 text-sm flex items-center" key={c.name}>
<ChainLogo chainId={c.chainId} size={15} color={true} background={false} /> <ChainLogo chainId={c.chainId} size={15} color={true} background={false} />
<span className="ml-1.5">{getChainDisplayName(multiProvider, c.chainId, true)}</span> <span className="ml-1.5 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</span>
</div> </div>
))} ))}
</div> </div>
</div> </div>
<div className="mt-4 flex"> <div className="mt-5 flex">
<h4 className="text-gray-600">Testnets:</h4> <h4 className="text-gray-600 font-medium text-sm">Testnets:</h4>
<div className="ml-3 flex gap-3.5 flex-wrap"> <div className="ml-3 flex gap-3.5 flex-wrap">
{testnetChainsMetadata.map((c) => ( {testnetChainsMetadata.map((c) => (
<div className="shrink-0 text-sm flex items-center" key={c.name}> <div className="shrink-0 text-sm flex items-center" key={c.name}>
<ChainLogo chainId={c.chainId} size={15} color={true} background={false} /> <ChainLogo chainId={c.chainId} size={15} color={true} background={false} />
<div className="ml-1.5">{getChainDisplayName(multiProvider, c.chainId, true)}</div> <div className="ml-1.5 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</div>
</div> </div>
))} ))}
</div> </div>
</div> </div>
<h3 className="mt-4 text-lg text-blue-500">Custom Chains</h3> <h3 className="mt-6 text-lg text-blue-500 font-medium">Custom Chains</h3>
<table className="mt-4 w-full"> <table className="mt-2 w-full">
<thead> <thead>
<tr> <tr>
<th className={styles.header}>Chain</th> <th className={styles.header}>Chain</th>
@ -141,7 +145,7 @@ export function ConfigureChains() {
title="Add Custom Chain" title="Add Custom Chain"
maxWidth="max-w-xl" maxWidth="max-w-xl"
> >
<p className="mt-2"> <p className="mt-2 font-light">
Input a chain metadata config including core contract addresses to enable exploration of Input a chain metadata config including core contract addresses to enable exploration of
that chain. See{' '} that chain. See{' '}
<a <a
@ -156,7 +160,7 @@ export function ConfigureChains() {
</p> </p>
<div className="relative mt-4"> <div className="relative mt-4">
<textarea <textarea
className="w-full min-h-[20rem] p-2 border border-gray-400 rounded text-sm focus:outline-none" className="w-full min-h-[20rem] p-2 border border-gray-400 rounded-xl text-sm font-light focus:outline-none"
placeholder={customChainTextareaPlaceholder} placeholder={customChainTextareaPlaceholder}
value={customChainInput} value={customChainInput}
onChange={onCustomChainInputChange} onChange={onCustomChainInputChange}
@ -165,7 +169,7 @@ export function ConfigureChains() {
copyValue={customChainInput || customChainTextareaPlaceholder} copyValue={customChainInput || customChainTextareaPlaceholder}
width={16} width={16}
height={16} height={16}
classes="absolute top-2 right-2" classes="absolute top-3 right-3"
/> />
</div> </div>
{chainInputErr && <div className="mt-2 text-red-600 text-sm">{chainInputErr}</div>} {chainInputErr && <div className="mt-2 text-red-600 text-sm">{chainInputErr}</div>}
@ -197,7 +201,7 @@ const customChainTextareaPlaceholder = `{
`; `;
const styles = { const styles = {
header: 'text-sm text-gray-700 font-normal pt-2 pb-1 text-left', header: 'pt-2 pb-1 text-sm text-gray-700 font-normal text-left',
value: 'py-4 text-sm px-1', value: 'py-4 px-1 text-sm font-light',
valueTruncated: 'py-4 text-sm truncate', valueTruncated: 'py-4 text-sm font-light truncate',
}; };

@ -3,11 +3,12 @@ import { useEffect, useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { Spinner } from '../../components/animations/Spinner'; import { Spinner } from '../../components/animations/Spinner';
import { Card } from '../../components/layout/Card';
import CheckmarkIcon from '../../images/icons/checkmark-circle.svg'; import CheckmarkIcon from '../../images/icons/checkmark-circle.svg';
import { useStore } from '../../store'; import { useStore } from '../../store';
import { Message, MessageStatus } from '../../types'; import { Message, MessageStatus } from '../../types';
import { logger } from '../../utils/logger'; import { logger } from '../../utils/logger';
import { toTitleCase } from '../../utils/string'; import { toTitleCase, trimToLength } from '../../utils/string';
import { getChainDisplayName } from '../chains/utils'; import { getChainDisplayName } from '../chains/utils';
import { useMessageDeliveryStatus } from '../deliveryStatus/useMessageDeliveryStatus'; import { useMessageDeliveryStatus } from '../deliveryStatus/useMessageDeliveryStatus';
import { useMultiProvider } from '../providers/multiProvider'; import { useMultiProvider } from '../providers/multiProvider';
@ -75,7 +76,14 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
pause: !isMessageFound, pause: !isMessageFound,
}); });
const { status, originChainId, destinationChainId: destChainId, origin, destination } = message; const {
msgId,
status,
originChainId,
destinationChainId: destChainId,
origin,
destination,
} = message;
// Mark delivery found to prevent pause queries // Mark delivery found to prevent pause queries
useEffect(() => { useEffect(() => {
@ -87,18 +95,21 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
return ( return (
<> <>
<div className="flex items-center justify-between px-1"> <Card className="flex items-center justify-between px-1 rounded-full">
<h2 className="text-white text-lg">{`${ <h2 className="text-blue-500 font-medium">{`${
isIcaMsg ? 'ICA ' : '' isIcaMsg ? 'ICA ' : ''
} Message to ${getChainDisplayName(multiProvider, destChainId)}`}</h2> } Message ${trimToLength(msgId, 6)} to ${getChainDisplayName(
multiProvider,
destChainId,
)}`}</h2>
<StatusHeader <StatusHeader
messageStatus={status} messageStatus={status}
isMessageFound={isMessageFound} isMessageFound={isMessageFound}
isFetching={isFetching} isFetching={isFetching}
isError={isError} isError={isError}
/> />
</div> </Card>
<div className="flex flex-wrap items-stretch justify-between mt-5 gap-3"> <div className="flex flex-wrap items-stretch justify-between mt-3 md:mt-4 gap-3 md:gap-4">
<OriginTransactionCard chainId={originChainId} transaction={origin} blur={blur} /> <OriginTransactionCard chainId={originChainId} transaction={origin} blur={blur} />
<DestinationTransactionCard <DestinationTransactionCard
chainId={destChainId} chainId={destChainId}
@ -150,7 +161,7 @@ function StatusHeader({
icon = ( icon = (
<div className="w-7 h-7 overflow-hidden flex items-center justify-center"> <div className="w-7 h-7 overflow-hidden flex items-center justify-center">
<div className="scale-[35%]"> <div className="scale-[35%]">
<Spinner white={true} /> <Spinner />
</div> </div>
</div> </div>
); );
@ -163,7 +174,7 @@ function StatusHeader({
return ( return (
<div className="flex items-center"> <div className="flex items-center">
<h3 className="text-white text-lg mr-3">{text}</h3> <h3 className="text-blue-500 font-medium lg mr-3">{text}</h3>
{icon} {icon}
</div> </div>
); );

@ -1,6 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import { Fade } from '../../components/animations/Fade'; import { Fade } from '../../components/animations/Fade';
import { Card } from '../../components/layout/Card';
import { SearchBar } from '../../components/search/SearchBar'; import { SearchBar } from '../../components/search/SearchBar';
import { SearchFilterBar } from '../../components/search/SearchFilterBar'; import { SearchFilterBar } from '../../components/search/SearchFilterBar';
import { import {
@ -75,9 +76,9 @@ export function MessageSearch() {
isFetching={isAnyFetching} isFetching={isAnyFetching}
placeholder="Search by address, hash, or message id" placeholder="Search by address, hash, or message id"
/> />
<div className="relative w-full min-h-[38rem] mt-5 bg-white ring-4 ring-blue-300 rounded-3xl overflow-auto"> <Card className="relative w-full min-h-[38rem] mt-4" padding="">
<div className="px-2 py-3 sm:px-4 md:px-5 flex items-center justify-between"> <div className="px-2 pt-3.5 pb-3 sm:px-4 md:px-5 flex items-center justify-between">
<h2 className="w-min sm:w-fit pl-0.5 text-gray-700"> <h2 className="w-min sm:w-fit pl-0.5 text-blue-500 font-medium">
{!hasInput ? 'Latest Messages' : 'Search Results'} {!hasInput ? 'Latest Messages' : 'Search Results'}
</h2> </h2>
<SearchFilterBar <SearchFilterBar
@ -105,7 +106,7 @@ export function MessageSearch() {
/> />
<SearchUnknownError show={isAnyError && isValidInput} /> <SearchUnknownError show={isAnyError && isValidInput} />
<SearchInvalidError show={!isValidInput} allowAddress={true} /> <SearchInvalidError show={!isValidInput} allowAddress={true} />
</div> </Card>
</> </>
); );
} }

@ -38,7 +38,7 @@ export function MessageTable({
{messageList.map((m) => ( {messageList.map((m) => (
<tr <tr
key={`message-${m.id}`} key={`message-${m.id}`}
className={`cursor-pointer hover:bg-gray-100 active:bg-gray-200 border-b border-gray-100 last:border-0 ${ className={`cursor-pointer hover:bg-pink-50 active:bg-pink-100 border-b border-blue-50 last:border-0 ${
isFetching && 'blur-xs' isFetching && 'blur-xs'
} transition-all duration-500`} } transition-all duration-500`}
> >
@ -62,10 +62,10 @@ export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: M
destination, destination,
} = message; } = message;
let statusColor = 'bg-beige-500'; let statusColor = 'bg-blue-50 text-gray-700';
let statusText = 'Pending'; let statusText = 'Pending';
if (status === MessageStatus.Delivered) { if (status === MessageStatus.Delivered) {
statusColor = 'bg-green-400 text-white'; statusColor = 'bg-[#14825d] text-white';
statusText = 'Delivered'; statusText = 'Delivered';
} else if (status === MessageStatus.Failing) { } else if (status === MessageStatus.Failing) {
statusColor = 'bg-red-500 text-white'; statusColor = 'bg-red-500 text-white';
@ -107,7 +107,9 @@ export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: M
: '-'} : '-'}
</LinkCell> </LinkCell>
<LinkCell id={msgId} base64={base64} aClasses="flex items-center justify-center"> <LinkCell id={msgId} base64={base64} aClasses="flex items-center justify-center">
<div className={`text-center w-20 md:w-[5.25rem] py-1.5 text-sm rounded ${statusColor}`}> <div
className={`text-center w-20 md:w-[5.25rem] py-1.5 text-sm rounded-full ${statusColor}`}
>
{statusText} {statusText}
</div> </div>
</LinkCell> </LinkCell>
@ -134,8 +136,8 @@ function LinkCell({
} }
const styles = { const styles = {
header: 'text-sm text-gray-700 font-normal pt-2 pb-3 text-center', header: 'text-sm text-blue-500 font-medium pt-2 pb-3 text-center',
value: 'py-3.5 flex items-center justify-center text-sm text-center px-1', value: 'py-3.5 flex items-center justify-center text-sm text-center font-light px-1',
valueTruncated: 'py-3.5 flex items-center justify-center text-sm text-center truncate', valueTruncated: 'py-3.5 flex items-center justify-center text-sm text-center font-light truncate',
chainName: 'text-sm ml-2', chainName: 'text-sm font-light ml-2',
}; };

@ -67,11 +67,11 @@ export function ContentDetailsCard({
}, [nonce, originDomainId, sender, destinationDomainId, recipient, body]); }, [nonce, originDomainId, sender, destinationDomainId, recipient, body]);
return ( return (
<Card classes="w-full space-y-4"> <Card className="w-full space-y-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Image src={EnvelopeInfo} width={28} height={28} alt="" className="opacity-80" /> <Image src={EnvelopeInfo} width={28} height={28} alt="" className="opacity-80" />
<div className="flex items-center pb-1"> <div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Message Details</h3> <h3 className="text-blue-500 font-medium text-md mr-2">Message Details</h3>
<HelpIcon <HelpIcon
size={16} size={16}
text="Immutable information about the message itself such as its contents." text="Immutable information about the message itself such as its contents."

@ -69,18 +69,18 @@ export function GasDetailsCard({ message, blur, igpPayments = {} }: Props) {
}, [unit, message, igpPayments]); }, [unit, message, igpPayments]);
return ( return (
<Card classes="w-full space-y-4 relative"> <Card className="w-full space-y-4 relative">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Image src={FuelPump} width={24} height={24} alt="" className="opacity-80" /> <Image src={FuelPump} width={24} height={24} alt="" className="opacity-80" />
<div className="flex items-center pb-1"> <div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Interchain Gas Payments</h3> <h3 className="text-blue-500 font-medium text-md mr-2">Interchain Gas Payments</h3>
<HelpIcon <HelpIcon
size={16} size={16}
text="Amounts paid to the Interchain Gas Paymaster for message delivery." text="Amounts paid to the Interchain Gas Paymaster for message delivery."
/> />
</div> </div>
</div> </div>
<p className="text-sm"> <p className="text-sm font-light">
Interchain gas payments are required to fund message delivery on the destination chain.{' '} Interchain gas payments are required to fund message delivery on the destination chain.{' '}
<a <a
href={`${links.docs}/docs/protocol/interchain-gas-payments`} href={`${links.docs}/docs/protocol/interchain-gas-payments`}

@ -24,13 +24,13 @@ export function IcaDetailsCard({ message: { originDomainId, body }, blur }: Prop
} = useIcaAddress(originDomainId, decodeResult?.sender); } = useIcaAddress(originDomainId, decodeResult?.sender);
return ( return (
<Card classes="w-full space-y-4"> <Card className="w-full space-y-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="relative -top-px -left-0.5"> <div className="relative -top-px -left-0.5">
<Image src={AccountStar} width={28} height={28} alt="" className="opacity-80" /> <Image src={AccountStar} width={28} height={28} alt="" className="opacity-80" />
</div> </div>
<div className="flex items-center pb-1"> <div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">ICA Details</h3> <h3 className="text-blue-500 font-medium text-md mr-2">ICA Details</h3>
<HelpIcon size={16} text="Extra information for messages from/to Interchain Accounts." /> <HelpIcon size={16} text="Extra information for messages from/to Interchain Accounts." />
</div> </div>
</div> </div>

@ -16,11 +16,11 @@ interface Props {
export function IsmDetailsCard({ ismDetails, blur }: Props) { export function IsmDetailsCard({ ismDetails, blur }: Props) {
return ( return (
<Card classes="w-full space-y-4 relative"> <Card className="w-full space-y-4 relative">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Image src={ShieldLock} width={24} height={24} alt="" className="opacity-80" /> <Image src={ShieldLock} width={24} height={24} alt="" className="opacity-80" />
<div className="flex items-center pb-1"> <div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Interchain Security Modules</h3> <h3 className="text-blue-500 font-medium text-md mr-2">Interchain Security Modules</h3>
<HelpIcon <HelpIcon
size={16} size={16}
text="Details about the Interchain Security Modules (ISM) that must verify this message." text="Details about the Interchain Security Modules (ISM) that must verify this message."

@ -26,7 +26,7 @@ export function KeyValueRow({
}: Props) { }: Props) {
const useFallbackVal = isZeroish(display) && !allowZeroish; const useFallbackVal = isZeroish(display) && !allowZeroish;
return ( return (
<div className={`flex items-center pl-px ${classes}`}> <div className={`flex items-center pl-px font-light ${classes}`}>
<label className={`text-sm text-gray-500 ${labelWidth}`}>{label}</label> <label className={`text-sm text-gray-500 ${labelWidth}`}>{label}</label>
<div className={`text-sm ml-1 truncate ${displayWidth || ''} ${blurValue && 'blur-xs'}`}> <div className={`text-sm ml-1 truncate ${displayWidth || ''} ${blurValue && 'blur-xs'}`}>
<span>{!useFallbackVal ? display : 'Unknown'}</span> <span>{!useFallbackVal ? display : 'Unknown'}</span>

@ -12,12 +12,12 @@ export function TimelineCard({ message, blur }: Props) {
const { stage, timings } = useMessageStage({ message }); const { stage, timings } = useMessageStage({ message });
return ( return (
<Card classes="w-full"> <Card className="w-full">
{/* <div className="flex items-center justify-end"> {/* <div className="flex items-center justify-end">
<h3 className="text-gray-500 font-medium text-md mr-2">Delivery Timeline</h3> <h3 className="text-gray-500 font-medium text-md mr-2">Delivery Timeline</h3>
<HelpIcon size={16} text="A breakdown of the stages for delivering a message" /> <HelpIcon size={16} text="A breakdown of the stages for delivering a message" />
</div> */} </div> */}
<div className={`-mx-2 sm:mx-0 -my-2 ${blur && 'blur-xs'}`}> <div className={`-mx-2 sm:mx-0 -my-2 font-light ${blur && 'blur-xs'}`}>
<MessageTimeline status={message.status} stage={stage} timings={timings} /> <MessageTimeline status={message.status} stage={stage} timings={timings} />
</div> </div>
</Card> </Card>

@ -118,13 +118,13 @@ function TransactionCard({
children, children,
}: PropsWithChildren<{ chainId: ChainId; title: string; helpText: string }>) { }: PropsWithChildren<{ chainId: ChainId; title: string; helpText: string }>) {
return ( return (
<Card classes="flex flex-col flex-1 min-w-fit space-y-3"> <Card className="flex flex-col flex-1 min-w-fit space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="relative -top-px -left-0.5"> <div className="relative -top-px -left-0.5">
<ChainLogo chainId={chainId} /> <ChainLogo chainId={chainId} />
</div> </div>
<div className="flex items-center pb-1"> <div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">{title}</h3> <h3 className="text-blue-500 font-medium text-md mr-2">{title}</h3>
<HelpIcon size={16} text={helpText} /> <HelpIcon size={16} text={helpText} />
</div> </div>
</div> </div>

@ -15,7 +15,7 @@ import { parseMessageQueryResult, parseMessageStubResult } from '../queries/pars
const SEARCH_AUTO_REFRESH_DELAY = 15000; const SEARCH_AUTO_REFRESH_DELAY = 15000;
const MSG_AUTO_REFRESH_DELAY = 10000; const MSG_AUTO_REFRESH_DELAY = 10000;
const LATEST_QUERY_LIMIT = 30; const LATEST_QUERY_LIMIT = 20;
const SEARCH_QUERY_LIMIT = 50; const SEARCH_QUERY_LIMIT = 50;
export function isValidSearchQuery(input: string, allowAddress?: boolean) { export function isValidSearchQuery(input: string, allowAddress?: boolean) {

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 199 B

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 454 B

@ -0,0 +1,4 @@
<svg width="886" height="114" viewBox="0 0 886 114" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M783.5 -3.5C621.953 133.053 158.722 87.2984 8 -3.5" stroke="white" stroke-width="2"/>
<path d="M884.5 -5.5C586 201.5 152.904 88.164 2 -5.5" stroke="white" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -1,5 +0,0 @@
<svg width="117" height="118" viewBox="0 0 117 118" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M64.4787 0H88.4134C91.6788 0 94.6004 1.89614 95.7403 4.7553L116.749 57.4498C116.911 57.8563 116.913 58.3035 116.754 58.7112L116.637 59.014L116.635 59.017L95.7152 112.81C94.5921 115.698 91.6551 117.62 88.3666 117.62H64.4355C63.0897 117.62 62.1465 116.379 62.59 115.192L84.1615 57.4498L62.6428 2.45353C62.1766 1.26188 63.1208 0 64.4787 0Z" fill="white"/>
<path d="M1.99945 0H25.9342C29.1996 0 32.1211 1.89614 33.261 4.7553L54.2696 57.4498C54.4316 57.8563 54.4336 58.3035 54.275 58.7112L54.1573 59.014L54.1561 59.017L33.236 112.81C32.1129 115.698 29.1759 117.62 25.8874 117.62H1.95626C0.610483 117.62 -0.332722 116.379 0.110804 115.192L21.6823 57.4498L0.163626 2.45353C-0.302638 1.26188 0.641544 0 1.99945 0Z" fill="white"/>
<path d="M80.7202 46.2178H46.9324V71.7089H80.7202L86.2411 58.5992L80.7202 46.2178Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 937 B

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#FFFFFF" class="bi bi-check2-circle" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" fill="#2362C1" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/> <path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z"/> <path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

@ -34,7 +34,7 @@ export default function Document() {
<meta property="og:url" content={links.baseUrl} /> <meta property="og:url" content={links.baseUrl} />
<meta property="og:title" content="Hyperlane Explorer" /> <meta property="og:title" content="Hyperlane Explorer" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:image" content={links.baseUrl + '/logo.png'} /> <meta property="og:image" content={links.baseUrl + '/images/logo.png'} />
<meta <meta
property="og:description" property="og:description"
content="The official interchain explorer for the Hyperlane protocol and network." content="The official interchain explorer for the Hyperlane protocol and network."

@ -6,28 +6,30 @@ const ApiDocs: NextPage = () => {
return ( return (
<div className="mt-4 mb-2 px-2 sm:px-6 lg:pr-14 w-full"> <div className="mt-4 mb-2 px-2 sm:px-6 lg:pr-14 w-full">
<Card> <Card>
<h2 className="mt-1 text-xl text-blue-500">Explorer APIs - Overview and documentation</h2> <h2 className="mt-1 text-lg text-blue-500 font-medium">
<p className="mt-3"> Explorer APIs - Overview and documentation
</h2>
<p className="mt-3 font-light">
The Explorer REST API provides endpoints to retrieve data about messages. The Explorer REST API provides endpoints to retrieve data about messages.
</p> </p>
<p className="mt-1"> <p className="mt-1 font-light">
The APIs are currently available free of charge and without authentication required. The APIs are currently available free of charge and without authentication required.
</p> </p>
<h3 className="mt-4 text-lg text-blue-500">Example Request</h3> <h3 className="mt-5 text-blue-500 font-medium">Example Request</h3>
<div className="mt-2 bg-gray-50 rounded p-2.5 text-sm overflow-auto"> <div className="mt-2 bg-gray-50 rounded-xl p-2.5 text-sm overflow-auto">
<pre> <pre>
<code>{exampleRequest}</code> <code>{exampleRequest}</code>
</pre> </pre>
</div> </div>
<h3 className="mt-4 text-lg text-blue-500">Example Response</h3> <h3 className="mt-5 text-blue-500 font-medium">Example Response</h3>
<div className="mt-2 bg-gray-50 rounded p-2.5 text-sm overflow-auto"> <div className="mt-2 bg-gray-50 rounded-xl p-2.5 text-sm overflow-auto">
<pre> <pre>
<code>{exampleResponse}</code> <code>{exampleResponse}</code>
</pre> </pre>
</div> </div>
<h3 className="mt-4 text-lg text-blue-500">API Reference</h3> <h3 className="mt-4 font-medium text-blue-500">API Reference</h3>
<h4 className="mt-2 text-gray-600"> <h4 className="mt-2 text-gray-600">
Module:<code className="ml-2">message</code> Module:<code className="ml-2">message</code>
</h4> </h4>
@ -76,7 +78,7 @@ function ParamItem({ name, desc }: { name: string; desc: string }) {
return ( return (
<li> <li>
<code className="mr-2">{name + ':'}</code> <code className="mr-2">{name + ':'}</code>
{desc} <span className="font-light">{desc}</span>
</li> </li>
); );
} }

@ -1,11 +1,12 @@
// Should match tailwind.config.js // Should match tailwind.config.js
export enum Color { export enum Color {
primaryBlack = '#010101', Black = '#010101',
primaryWhite = '#FFFFFF', White = '#FFFFFF',
primaryGray = '#6B7280', Gray = '#6B7280',
primaryBlue = '#2362C1', Blue = '#2362C1',
primaryBeige = '#F1EDE9', Pink = '#D631B9',
primaryRed = '#BF1B15', Beige = '#F1EDE9',
Red = '#BF1B15',
} }
// Useful for cases when using class names isn't convenient // Useful for cases when using class names isn't convenient
@ -13,11 +14,13 @@ export enum Color {
export function classNameToColor(className) { export function classNameToColor(className) {
switch (className) { switch (className) {
case 'bg-blue-500': case 'bg-blue-500':
return Color.primaryBlue; return Color.Blue;
case 'bg-pink-500':
return Color.Pink;
case 'bg-red-500': case 'bg-red-500':
return Color.primaryRed; return Color.Red;
case 'bg-gray-500': case 'bg-gray-500':
return Color.primaryGray; return Color.Gray;
default: default:
throw new Error('Missing color for className: ' + className); throw new Error('Missing color for className: ' + className);
} }

@ -43,16 +43,16 @@ module.exports = {
900: '#908E8B', 900: '#908E8B',
}, },
pink: { pink: {
50: '#FAEAF7', 50: '#FCF2FA',
100: '#F0C0E8', 100: '#F2C1EA',
200: '#EBABE0', 200: '#EA98DC',
300: '#E282D1', 300: '#E26ECE',
400: '#D858C2', 400: '#DA45C0',
500: '#CF2FB3', 500: '#D631B9',
600: '#BA2AA1', 600: '#C02CA6',
700: '#A5258F', 700: '#952281',
800: '#90207D', 800: '#6B185C',
900: '#7C1C6B', 900: '#400E37',
}, },
red: { red: {
100: '#EBBAB8', 100: '#EBBAB8',

Loading…
Cancel
Save