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

Portal 240606 #1837

Merged
merged 9 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion infra/rooch-portal/src/components/banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ export const Banner: React.FC<BannerProps> = ({ onClose }) => {
<span className="sr-only">Rooch</span>
</span>
<span>
Rooch Portal is at the beta testing version. Learn More about {' '}
Rooch Portal is at the beta testing version. Learn More about{' '}
<a
href="https://rooch.network/learn/miscellaneous/portal"
target="_blank"
className="inline font-medium text-blue-600 underline dark:text-blue-500 underline-offset-2 decoration-600 dark:decoration-500 decoration-solid hover:text-blue-500 dark:hover:text-blue-400 transition-all"
rel="noreferrer"
>
Rooch Portal
</a>
Expand Down
17 changes: 8 additions & 9 deletions infra/rooch-portal/src/components/session-key-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ interface SessionKeyModalProps {
}

export const SessionKeyModal: React.FC<SessionKeyModalProps> = ({
isOpen,
scopes,
onAuthorize,
error,
}) => {
isOpen,
scopes,
onAuthorize,
error,
}) => {
const [loading, setLoading] = useState(false)

const onAuthorizeWrapper = async () => {
Expand All @@ -36,12 +36,11 @@ export const SessionKeyModal: React.FC<SessionKeyModalProps> = ({
<div className="bg-white dark:bg-zinc-800 p-4 rounded-lg shadow-lg max-w-sm w-full relative">
<h2 className="text-lg font-bold mb-4">Session Authorize</h2>
<p className="text-sm text-muted-foreground mb-2">
The current session does not exist or has expired. Please authorize the creation of a new session.
The current session does not exist or has expired. Please authorize the creation of a new
session.
</p>
{error && (
<div className="bg-red-100 text-red-700 p-3 rounded mb-4 text-sm">
{error}
</div>
<div className="bg-red-100 text-red-700 p-3 rounded-lg mb-4 text-sm">{error}</div>
)}
<div className="bg-zinc-700 p-4 rounded-lg">
{/* SCOPE */}
Expand Down
6 changes: 4 additions & 2 deletions infra/rooch-portal/src/guard/session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const SessionGuard = (props: SessionGuardProps) => {

setOpen(
sessionKey === null &&
navItems().find((item) => s.pathname.startsWith(item.path) && item.auth) !== undefined,
navItems().find((item) => s.pathname.startsWith(item.path) && item.auth) !== undefined,
)
}, [isConnected, s, sessionKey])

Expand All @@ -52,7 +52,9 @@ export const SessionGuard = (props: SessionGuardProps) => {
})

if (result === null) {
setError('Authorization failed due to insufficient gas fees. Please ensure you have enough gas fees.')
setError(
'Authorization failed due to insufficient gas fees. Please ensure you have enough gas fees.',
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ export const AssetsCoin = () => {
{data?.data.map((coin) => (
<TableRow key={coin.name}>
<TableCell>{coin.name}</TableCell>
<TableCell>{formatCoin(Number(coin.balance), coin.decimals, coin.decimals)}</TableCell>
<TableCell>
{formatCoin(Number(coin.balance), coin.decimals, coin.decimals)}
</TableCell>
<TableCell className="text-right">
<Button
variant="link"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0
import React, { useState, useCallback } from 'react'
import React, { useCallback, useState } from 'react'
import {
Table,
TableBody,
Expand All @@ -16,26 +16,23 @@ import {
useRemoveSession,
useRoochClientQuery,
} from '@roochnetwork/rooch-sdk-kit'
import { Copy, ChevronDown, ChevronUp, Check, AlertCircle } from 'lucide-react'
import { AlertCircle, Check, ChevronDown, ChevronUp, Copy, Loader } from 'lucide-react'

import { formatTimestamp } from '@/utils/format.ts'

import {SessionInfoResult} from '@roochnetwork/rooch-sdk';
import { SessionInfoResult } from '@roochnetwork/rooch-sdk'
import { copyToClipboard } from '@/utils/copyToClipboard.ts'

interface ExpandableRowProps {
session: SessionInfoResult
remove: (authKey: string) => void
loading: boolean
}

const copyToClipboard = async (text: string, setCopied: (value: boolean) => void) => {
try {
await navigator.clipboard.writeText(text)
setCopied(true)
console.log('Copied to clipboard:', text)
setTimeout(() => setCopied(false), 2000) // Reset after 2 seconds
} catch (err) {
console.error('Could not copy text:', err)
}
const isSessionExpired = (createTime: number, maxInactiveInterval: number) => {
const currentTime = Date.now()
const expirationTime = createTime + maxInactiveInterval * 1000
return currentTime > expirationTime
}

export const ManageSessions: React.FC = () => {
Expand All @@ -45,17 +42,24 @@ export const ManageSessions: React.FC = () => {
data: sessionKeys,
isLoading,
isError,
refetch
refetch,
} = useRoochClientQuery('querySessionKeys', {
address: sessionKey?.getAddress() || '',
})

const [loading, setLoading] = useState<string | null>(null)

const remove = useCallback(
async (authKey: string) => {
await removeSession({
authKey: authKey,
})
await refetch()
setLoading(authKey)
try {
await removeSession({
authKey: authKey,
})
await refetch()
} finally {
setLoading(null)
}
},
[removeSession, refetch],
)
Expand Down Expand Up @@ -110,15 +114,20 @@ export const ManageSessions: React.FC = () => {
</TableHeader>
<TableBody>
{sessionKeys?.data.map((session) => (
<ExpandableRow key={session.authenticationKey} session={session} remove={remove} />
<ExpandableRow
key={session.authenticationKey}
session={session}
remove={remove}
loading={loading === session.authenticationKey}
/>
))}
</TableBody>
</Table>
</div>
)
}

const ExpandableRow: React.FC<ExpandableRowProps> = ({ session, remove }) => {
const ExpandableRow: React.FC<ExpandableRowProps> = ({ session, remove, loading }) => {
const [isExpanded, setIsExpanded] = useState(false)
const [copiedKeys, setCopiedKeys] = useState<string[]>([])

Expand All @@ -132,6 +141,8 @@ const ExpandableRow: React.FC<ExpandableRowProps> = ({ session, remove }) => {
})
}

const expired = isSessionExpired(Number(session.createTime), session.maxInactiveInterval)

return (
<>
<TableRow>
Expand All @@ -148,20 +159,32 @@ const ExpandableRow: React.FC<ExpandableRowProps> = ({ session, remove }) => {
)}
</div>
</TableCell>
<TableCell className="text-muted-foreground">{formatTimestamp(session.createTime)}</TableCell>
<TableCell className="text-muted-foreground">{formatTimestamp(session.lastActiveTime)}</TableCell>
<TableCell className="text-muted-foreground">
{formatTimestamp(session.createTime)}
</TableCell>
<TableCell className="text-muted-foreground">
{formatTimestamp(session.lastActiveTime)}
</TableCell>
<TableCell className="text-muted-foreground">{session.maxInactiveInterval}</TableCell>
<TableCell className="text-center">
<Button
variant="link"
size="sm"
onClick={() => remove(session.authenticationKey)}
className="text-red-500 dark:text-red-400 dark:hover:text-red-300 hover:text-red-600"
>
{
session.lastActiveTime > new Date().getSeconds() ? 'Disconnect' : 'Expired (Clear)'
}
</Button>
{loading ? (
<div className="flex justify-center">
<Loader className="w-5 h-5 animate-spin" />
</div>
) : (
<Button
variant="link"
size="sm"
onClick={() => remove(session.authenticationKey)}
className={`${
expired
? 'dark:text-gray-400 dark:hover:text-gray-300 hover:text-gray-600 h-full'
: 'text-red-500 dark:text-red-400 dark:hover:text-red-300 hover:text-red-600 h-full'
}`}
>
{expired ? 'Expired (Clear)' : 'Disconnect'}
</Button>
)}
</TableCell>
</TableRow>
{isExpanded && (
Expand Down
6 changes: 2 additions & 4 deletions infra/rooch-portal/src/pages/trade/trade-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0
import { ComingSoon } from '@/components/coming-soon.tsx'
import {useTranslation} from 'react-i18next';
import { useTranslation } from 'react-i18next'

export const TradeLayout = () => {
const { t } = useTranslation()
Expand All @@ -10,9 +10,7 @@ export const TradeLayout = () => {
<div className="flex items-center justify-between space-y-2">
<span>
<h1 className="text-3xl font-bold tracking-tight">{t('Trade.title')}</h1>
<p className="text-muted-foreground text-wrap">
{t('Trade.subTitle')}
</p>
<p className="text-muted-foreground text-wrap">{t('Trade.subTitle')}</p>
</span>
</div>
<ComingSoon />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0
import { TransactionsTable } from './components/transactions-table'
import {useTranslation} from 'react-i18next';
import { useTranslation } from 'react-i18next'

export const TransactionsLayout = () => {
const { t } = useTranslation()
Expand Down
12 changes: 12 additions & 0 deletions infra/rooch-portal/src/utils/copyToClipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0
export async function copyToClipboard(text: string, setCopied: (value: boolean) => void) {
try {
await navigator.clipboard.writeText(text)
setCopied(true)
console.log('Copied to clipboard', text)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error('Could not copy text', err)
}
}
4 changes: 2 additions & 2 deletions infra/rooch-portal/src/utils/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const formatTimestamp = (timestamp: number): string => {
if (timestamp < 1e10) {
timestamp *= 1000
}
const date = new Date(timestamp);
return date.toLocaleString();
const date = new Date(timestamp)
return date.toLocaleString()
}

export const formatCoin = (balance: number, decimals: number, precision = 2) => {
Expand Down
Loading
Loading