Skip to content

Commit

Permalink
Add ROFL details page route
Browse files Browse the repository at this point in the history
  • Loading branch information
buberdds committed Feb 28, 2025
1 parent 15c3f06 commit 7dd0cee
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/app/pages/RoflAppDetailPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { RoflApp, Runtime, useGetRuntimeRoflAppsId } from '../../../oasis-nexus/api'
import { StyledDescriptionList } from '../../components/StyledDescriptionList'
import { PageLayout } from '../../components/PageLayout'
import { SubPageCard } from '../../components/SubPageCard'
import { useScreenSize } from '../../hooks/useScreensize'
import { AppErrors } from '../../../types/errors'
import { TextSkeleton } from '../../components/Skeleton'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { DashboardLink } from '../ParatimeDashboardPage/DashboardLink'
import { useParams } from 'react-router-dom'

export const RoflAppDetailPage: FC = () => {
const { t } = useTranslation()
const scope = useRequiredScopeParam()
const id = useParams().id!
const { isLoading, data } = useGetRuntimeRoflAppsId(scope.network, scope.layer as Runtime, id)
const roflApp = data?.data

if (!roflApp && !isLoading) {
throw AppErrors.NotFoundTxHash
}

return (
<PageLayout>
<SubPageCard featured title={t('rofl.header')}>
<RoflAppDetailView detailsPage isLoading={isLoading} app={roflApp} />
</SubPageCard>
</PageLayout>
)
}

export const RoflAppDetailView: FC<{
isLoading?: boolean
app: RoflApp | undefined
detailsPage?: boolean
showLayer?: boolean
}> = ({ app, detailsPage, isLoading, showLayer }) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()

if (isLoading) return <TextSkeleton numberOfRows={detailsPage ? 15 : 10} />
if (!app) return <></>

return (
<StyledDescriptionList titleWidth={isMobile ? '100px' : '200px'} standalone={!detailsPage}>
{showLayer && (
<>
<dt>{t('common.paratime')}</dt>
<dd>
<DashboardLink scope={app} />
</dd>
</>
)}
<dt>TODO</dt>
<dd>TODO</dd>

{detailsPage && (
<>
<dt>TODO</dt>
<dd>TODO</dd>
</>
)}
</StyledDescriptionList>
)
}
26 changes: 26 additions & 0 deletions src/app/utils/route-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,17 @@ const validateConsensusAddressParam = (address: string) => {
return isValid
}

const validateRoflAppIdParam = (id: string) => {
// TOOD: Use real validation once added to client SDK
const isValid = id.startsWith('rofl1')

if (!isValid) {
throw new AppError(AppErrors.InvalidAddress)
}

return isValid
}

const validateRuntimeAddressParam = (address: string) => {
const isValid = isValidOasisAddress(address) || isValidEthAddress(address)
if (!isValid) {
Expand Down Expand Up @@ -310,6 +321,11 @@ export type AddressLoaderData = {
searchTerm: string
}

export type RoflAppLoaderData = {
id: string
searchTerm: string
}

const validateProposalIdParam = (proposalId: string) => {
const isValid = isValidProposalId(proposalId)
if (!isValid) {
Expand Down Expand Up @@ -340,6 +356,16 @@ export const runtimeAddressParamLoader =
}
}

export const roflAppParamLoader =
(queryParam: string = 'id') =>
({ params, request }: LoaderFunctionArgs): RoflAppLoaderData => {
validateRoflAppIdParam(params[queryParam]!)
return {
id: params[queryParam]!,
searchTerm: getSearchTermFromRequest(request),
}
}

export const blockHeightParamLoader = async ({ params }: LoaderFunctionArgs) => {
return validateBlockHeightParam(params.blockHeight!)
}
Expand Down
1 change: 1 addition & 0 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@
"emptyRoflAppsList": "No ROFL apps found.",
"instances": "Instances",
"listTitle": "ROFL Apps",
"header": "ROFL App",
"tee": "TEE"
},
"search": {
Expand Down
5 changes: 5 additions & 0 deletions src/oasis-nexus/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ declare module './generated/api' {
export interface ValidatorAggStats {
ticker: Ticker
}

export interface RoflApp {
network: Network
layer: Layer
}
}

export const isAccountEmpty = (account: RuntimeAccount | Account) => {
Expand Down
7 changes: 7 additions & 0 deletions src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
fixedLayer,
RouteUtils,
skipGraph,
roflAppParamLoader,
} from './app/utils/route-utils'
import { RoutingErrorPage } from './app/pages/RoutingErrorPage'
import { ThemeByScope, withDefaultTheme } from './app/components/ThemeByScope'
Expand Down Expand Up @@ -64,6 +65,7 @@ import { ConsensusAccountEventsCard } from './app/pages/ConsensusAccountDetailsP
import { useConsensusAccountDetailsProps } from './app/pages/ConsensusAccountDetailsPage/hooks'
import { ConsensusAccountTransactionsCard } from './app/pages/ConsensusAccountDetailsPage/ConsensusAccountTransactionsCard'
import { RoflAppsPage } from './app/pages/RoflAppsPage'
import { RoflAppDetailPage } from 'app/pages/RoflAppDetailPage'
import { FC, useEffect } from 'react'
import { AnalyticsConsentProvider } from './app/components/AnalyticsConsent'

Expand Down Expand Up @@ -355,6 +357,11 @@ export const routes: RouteObject[] = [
path: `rofl/app`,
element: <RoflAppsPage />,
},
{
path: `rofl/app/:id`,
element: <RoflAppDetailPage />,
loader: roflAppParamLoader(),
},
],
},
],
Expand Down

0 comments on commit 7dd0cee

Please sign in to comment.