11import { FC } from 'react'
2+ import { useHref , useParams } from 'react-router-dom'
23import { useTranslation } from 'react-i18next'
34import { formatDistanceStrict } from 'date-fns'
45import Box from '@mui/material/Box'
56import Grid from '@mui/material/Grid'
7+ import Skeleton from '@mui/material/Skeleton'
68import Typography from '@mui/material/Typography'
79import { styled } from '@mui/material/styles'
8- import { RoflApp } from '../../../oasis-nexus/api'
10+ import { Layer , RoflApp , useGetRuntimeRoflAppsId } from '../../../oasis-nexus/api'
911import { getPreciseNumberFormat } from '../../../locales/getPreciseNumberFormat'
12+ import { AppErrors } from '../../../types/errors'
13+ import { useRequiredScopeParam } from '../../hooks/useScopeParam'
14+ import { useTypedSearchParam } from '../../hooks/useTypedSearchParam'
1015import { useScreenSize } from '../../hooks/useScreensize'
16+ import { PageLayout } from '../../components/PageLayout'
17+ import { SubPageCard } from '../../components/SubPageCard'
1118import { TextSkeleton } from '../../components/Skeleton'
1219import { StyledDescriptionList } from '../../components/StyledDescriptionList'
1320import { RoflAppStatusBadge } from '../../components/Rofl/RoflAppStatusBadge'
@@ -19,6 +26,67 @@ import { TeeType } from './TeeType'
1926import { Endorsement } from './Endorsement'
2027import { Enclaves } from './Enclaves'
2128import { Secrets } from './Secrets'
29+ import { RouterTabs } from '../../components/RouterTabs'
30+ import { instancesContainerId } from '../../utils/tabAnchors'
31+ import { RoflAppDetailsContext } from '../RoflAppDetailsPage/hooks'
32+ import { MetaDataCard } from './MetaDataCard'
33+ import { PolicyCard } from './PolicyCard'
34+
35+ export const RoflAppDetailsPage : FC = ( ) => {
36+ const { t } = useTranslation ( )
37+ const scope = useRequiredScopeParam ( )
38+ const id = useParams ( ) . id !
39+ const txLink = useHref ( '' )
40+ const instancesLink = useHref ( `instances#${ instancesContainerId } ` )
41+ const [ method , setMethod ] = useTypedSearchParam ( 'method' , 'any' , {
42+ deleteParams : [ 'page' ] ,
43+ } )
44+ const context : RoflAppDetailsContext = { scope, id, method, setMethod }
45+ const { isFetched, isLoading, data } = useGetRuntimeRoflAppsId ( scope . network , Layer . sapphire , id )
46+ const roflApp = data ?. data
47+
48+ if ( ! roflApp && isFetched ) {
49+ throw AppErrors . NotFoundRoflApp
50+ }
51+
52+ return (
53+ < PageLayout >
54+ < SubPageCard
55+ featured
56+ title = {
57+ isLoading ? < Skeleton variant = "text" /> : roflApp ?. metadata [ 'net.oasis.rofl.name' ] || roflApp ?. id
58+ }
59+ >
60+ < RoflAppDetailsView detailsPage isLoading = { isLoading } app = { roflApp } />
61+ </ SubPageCard >
62+ < Grid container spacing = { 4 } >
63+ < StyledGrid item xs = { 12 } md = { 6 } >
64+ < MetaDataCard isFetched = { isFetched } metadata = { roflApp ?. metadata } />
65+ </ StyledGrid >
66+ < StyledGrid item xs = { 12 } md = { 6 } >
67+ { roflApp && (
68+ < PolicyCard
69+ id = { roflApp ?. id }
70+ network = { roflApp ?. network }
71+ isFetched = { isFetched }
72+ policy = { roflApp ?. policy }
73+ />
74+ ) }
75+ </ StyledGrid >
76+ </ Grid >
77+ < RouterTabs
78+ tabs = { [
79+ { label : t ( 'common.transactions' ) , to : txLink } ,
80+ {
81+ label : t ( 'rofl.instances' ) ,
82+ to : instancesLink ,
83+ } ,
84+ ] }
85+ context = { context }
86+ />
87+ </ PageLayout >
88+ )
89+ }
2290
2391export const StyledGrid = styled ( Grid ) ( ( { theme } ) => ( {
2492 [ theme . breakpoints . up ( 'sm' ) ] : {
0 commit comments