parent
83a464dd35
commit
14910020ba
@ -1,76 +0,0 @@ |
||||
import Link from 'next/link'; |
||||
|
||||
import { ChainToChain } from '../../components/icons/ChainToChain'; |
||||
import { MessageStatus, MessageStub } from '../../types'; |
||||
import { shortenAddress } from '../../utils/addresses'; |
||||
import { getHumanReadableDuration, getHumanReadableTimeString } from '../../utils/time'; |
||||
|
||||
export function MessageSummary({ message }: { message: MessageStub }) { |
||||
const { |
||||
id, |
||||
status, |
||||
sender, |
||||
recipient, |
||||
originChainId, |
||||
destinationChainId, |
||||
originTimestamp, |
||||
destinationTimestamp, |
||||
} = message; |
||||
|
||||
let statusColor = 'bg-beige-500'; |
||||
let statusText = 'Pending'; |
||||
if (status === MessageStatus.Delivered) { |
||||
statusColor = 'bg-green-400 text-white'; |
||||
statusText = 'Delivered'; |
||||
} else if (status === MessageStatus.Failing) { |
||||
statusColor = 'bg-red-500 text-white'; |
||||
statusText = 'Failing'; |
||||
} |
||||
|
||||
return ( |
||||
<Link href={`/message/${id}`}> |
||||
<a className="flex items-center justify-between space-x-4 xs:space-x-9 sm:space-x-12 md:space-x-16"> |
||||
<ChainToChain |
||||
originChainId={originChainId} |
||||
destinationChainId={destinationChainId} |
||||
size={40} |
||||
arrowSize={30} |
||||
isNarrow={true} |
||||
/> |
||||
<div className="flex items-center justify-between flex-1"> |
||||
<div className="flex flex-col"> |
||||
<div className={styles.label}>Sender</div> |
||||
<div className={styles.value}>{shortenAddress(sender) || 'Invalid Address'}</div> |
||||
</div> |
||||
<div className="hidden sm:flex flex-col"> |
||||
<div className={styles.label}>Recipient</div> |
||||
<div className={styles.value}>{shortenAddress(recipient) || 'Invalid Address'}</div> |
||||
</div> |
||||
<div className="flex flex-col sm:w-24"> |
||||
<div className={styles.label}>Time sent</div> |
||||
<div className={styles.valueTruncated}> |
||||
{getHumanReadableTimeString(originTimestamp)} |
||||
</div> |
||||
</div> |
||||
<div className="hidden lg:flex flex-col sm:w-16"> |
||||
<div className={styles.label}>Duration</div> |
||||
<div className={styles.valueTruncated}> |
||||
{destinationTimestamp |
||||
? getHumanReadableDuration(destinationTimestamp - originTimestamp) |
||||
: '-'} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div className={`w-20 md:w-[5.5rem] py-2 text-sm text-center rounded ${statusColor}`}> |
||||
{statusText} |
||||
</div> |
||||
</a> |
||||
</Link> |
||||
); |
||||
} |
||||
|
||||
const styles = { |
||||
label: 'text-sm text-gray-500', |
||||
value: 'text-sm mt-1', |
||||
valueTruncated: 'text-sm mt-1 truncate', |
||||
}; |
@ -0,0 +1,105 @@ |
||||
import { useRouter } from 'next/router'; |
||||
|
||||
import { ChainToChain } from '../../components/icons/ChainToChain'; |
||||
import { MessageStatus, MessageStub } from '../../types'; |
||||
import { shortenAddress } from '../../utils/addresses'; |
||||
import { getHumanReadableDuration, getHumanReadableTimeString } from '../../utils/time'; |
||||
|
||||
export function MessageTable({ |
||||
messageList, |
||||
isFetching, |
||||
}: { |
||||
messageList: MessageStub[]; |
||||
isFetching: boolean; |
||||
}) { |
||||
const router = useRouter(); |
||||
|
||||
return ( |
||||
<table className="w-full mb-1"> |
||||
<tr className="px-2 py-2 sm:px-4 md:px-5 md:py-2.5 border-b border-gray-100 bg-gray-50"> |
||||
<th className={`${styles.header} pr-1`}>Chains</th> |
||||
<th className={styles.header}>Sender</th> |
||||
<th className={`${styles.header} hidden sm:table-cell`}>Recipient</th> |
||||
<th className={styles.header}>Time Sent</th> |
||||
<th className={`${styles.header} hidden lg:table-cell`}>Duration</th> |
||||
<th className={styles.header}>Status</th> |
||||
</tr> |
||||
{messageList.map((m) => ( |
||||
<tr |
||||
key={`message-${m.id}`} |
||||
className={`px-2 py-2 sm:px-4 md:px-5 md:py-2.5 cursor-pointer hover:bg-gray-100 active:bg-gray-200 border-b border-gray-100 last:border-0 ${ |
||||
isFetching && 'blur-xs' |
||||
} transition-all duration-500`}
|
||||
onClick={() => router.push(`/message/${m.id}`)} |
||||
> |
||||
<MessageSummaryRow message={m} /> |
||||
</tr> |
||||
))} |
||||
</table> |
||||
); |
||||
} |
||||
|
||||
export function MessageSummaryRow({ message }: { message: MessageStub }) { |
||||
const { |
||||
status, |
||||
sender, |
||||
recipient, |
||||
originChainId, |
||||
destinationChainId, |
||||
originTimestamp, |
||||
destinationTimestamp, |
||||
} = message; |
||||
|
||||
let statusColor = 'bg-beige-500'; |
||||
let statusText = 'Pending'; |
||||
if (status === MessageStatus.Delivered) { |
||||
statusColor = 'bg-green-400 text-white'; |
||||
statusText = 'Delivered'; |
||||
} else if (status === MessageStatus.Failing) { |
||||
statusColor = 'bg-red-500 text-white'; |
||||
statusText = 'Failing'; |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<td className="py-2.5"> |
||||
<ChainToChain |
||||
originChainId={originChainId} |
||||
destinationChainId={destinationChainId} |
||||
size={38} |
||||
arrowSize={30} |
||||
isNarrow={true} |
||||
/> |
||||
</td> |
||||
<td> |
||||
<div className={styles.value}>{shortenAddress(sender) || 'Invalid Address'}</div> |
||||
</td> |
||||
<td className="hidden sm:table-cell"> |
||||
<div className={styles.value}>{shortenAddress(recipient) || 'Invalid Address'}</div> |
||||
</td> |
||||
<td> |
||||
<div className={styles.valueTruncated}>{getHumanReadableTimeString(originTimestamp)}</div> |
||||
</td> |
||||
<td className="hidden lg:table-cell text-center px-4"> |
||||
<div className={styles.valueTruncated}> |
||||
{destinationTimestamp |
||||
? getHumanReadableDuration(destinationTimestamp - originTimestamp) |
||||
: '-'} |
||||
</div> |
||||
</td> |
||||
<td> |
||||
<div className="flex items-center justify-center"> |
||||
<div className={`text-center w-20 md:w-[5.25rem] py-1.5 text-sm rounded ${statusColor}`}> |
||||
{statusText} |
||||
</div> |
||||
</div> |
||||
</td> |
||||
</> |
||||
); |
||||
} |
||||
|
||||
const styles = { |
||||
header: 'text-sm text-gray-700 font-normal pt-2 pb-3 text-center', |
||||
value: 'text-sm text-center', |
||||
valueTruncated: 'text-sm text-center truncate', |
||||
}; |
@ -0,0 +1,59 @@ |
||||
import Image from 'next/future/image'; |
||||
import { useMemo } from 'react'; |
||||
|
||||
import { SelectField } from '../../components/input/SelectField'; |
||||
import { prodAndTestChains } from '../../consts/chains'; |
||||
import ArrowRightIcon from '../../images/icons/arrow-right-short.svg'; |
||||
import FunnelIcon from '../../images/icons/funnel.svg'; |
||||
import { trimToLength } from '../../utils/string'; |
||||
|
||||
interface Props { |
||||
originChainFilter: string; |
||||
onChangeOriginFilter: (value: string) => void; |
||||
destinationChainFilter: string; |
||||
onChangeDestinationFilter: (value: string) => void; |
||||
} |
||||
|
||||
export function SearchFilterBar({ |
||||
originChainFilter, |
||||
onChangeOriginFilter, |
||||
destinationChainFilter, |
||||
onChangeDestinationFilter, |
||||
}: Props) { |
||||
const chainOptions = useMemo(getChainOptionList, []); |
||||
return ( |
||||
<div className="flex items-center space-x-1 sm:space-x-2 md:space-x-3"> |
||||
<div className="w-px h-8 bg-gray-200"></div> |
||||
<Image |
||||
src={FunnelIcon} |
||||
width={20} |
||||
height={20} |
||||
className="hidden sm:block opacity-20" |
||||
alt="" |
||||
/> |
||||
<SelectField |
||||
classes="w-24 md:w-32" |
||||
options={chainOptions} |
||||
value={originChainFilter} |
||||
onValueSelect={onChangeOriginFilter} |
||||
/> |
||||
<Image src={ArrowRightIcon} width={30} height={30} className="opacity-30" alt="" /> |
||||
<SelectField |
||||
classes="w-24 md:w-32" |
||||
options={chainOptions} |
||||
value={destinationChainFilter} |
||||
onValueSelect={onChangeDestinationFilter} |
||||
/> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
function getChainOptionList(): Array<{ value: string; display: string }> { |
||||
return [ |
||||
{ value: '', display: 'All Chains' }, |
||||
...prodAndTestChains.map((c) => ({ |
||||
value: c.id.toString(), |
||||
display: trimToLength(c.name, 12), |
||||
})), |
||||
]; |
||||
} |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 313 B |
Loading…
Reference in new issue