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

feat(offers): marketplace v2 offer #131

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@fluencelabs/deal-ts-clients": "patch:@fluencelabs/deal-ts-clients@npm%3A0.23.1#~/.yarn/patches/@fluencelabs-deal-ts-clients-npm-0.23.1-637f5fb879.patch",
"@fluencelabs/deal-ts-clients": "0.23.2-ts-client-offers-v2-433c4f8-7387-1.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-checkbox": "^1.0.4",
Expand All @@ -26,6 +26,7 @@
"@tanstack/react-query": "^5.29.2",
"copy-to-clipboard": "^3.3.3",
"date-fns": "^3.6.0",
"js-yaml": "^4.1.0",
"lodash.merge": "^4.6.2",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
Expand All @@ -42,6 +43,7 @@
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.23.0",
"@emotion/babel-plugin": "^11.11.0",
"@types/js-yaml": "^4",
"@types/lodash.merge": "^4.6.9",
"@types/react": "^18.2.25",
"@types/react-datepicker": "^4.19.3",
Expand Down
24 changes: 24 additions & 0 deletions src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Component, ReactNode } from 'react'

export class ErrorBoundary extends Component<{
fallback?: ReactNode
children?: ReactNode
}> {
state: { hasError?: boolean } = {}

static getDerivedStateFromError() {
return { hasError: true }
}

componentDidCatch(error: unknown) {
console.error(error)
}

render() {
if (this.state.hasError) {
return this.props.fallback
}

return this.props.children
}
}
15 changes: 15 additions & 0 deletions src/components/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,18 @@ export const TablePagination = styled.div`
justify-content: flex-start;
}
`

export const ContentBlock = styled.div`
display: flex;
flex-direction: column;
background-color: ${colors.white};
border-radius: 8px;

${TableHeader} {
border-bottom: 1px solid ${colors.grey300};
}

${RowHeader} + ${RowHeader} {
border-top: 1px solid ${colors.grey300};
}
`
18 changes: 18 additions & 0 deletions src/components/YamlView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import yaml from 'js-yaml'

import { ErrorBoundary } from './ErrorBoundary'

const JsonToYamlViewBase = ({ data }: { data: string }) => {
const yamlString = data === '{}' ? '' : yaml.dump(JSON.parse(data))

return <pre>{yamlString}</pre>
}

export const JsonToYamlView = ({ data }: { data: string }) => {
return (
<ErrorBoundary fallback={<pre>{data}</pre>}>
<JsonToYamlViewBase data={data} />
</ErrorBoundary>
)
}
8 changes: 6 additions & 2 deletions src/constants/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
ContractsENV,
DEPLOYMENTS,
RPC_URLS,
SUBGRAPH_URLS,
} from '@fluencelabs/deal-ts-clients'
import { Chain } from 'viem'
import { createConfig, createStorage, http } from 'wagmi'
Expand All @@ -28,8 +27,13 @@ export const FILTER_ONLY_APPROVED_PROVIDERS_DEFAULT =
export const FORMAT_PAYMENT_TOKEN_TO_FIXED_DEFAULT = 3
export const FORMAT_NATIVE_TOKEN_TO_FIXED_DEFAULT = 6

// TODO: remove hardcoded subgraph before merging
export const SUBGRAPH_URL =
import.meta.env.VITE_SUBGRAPH_URL ?? SUBGRAPH_URLS[FLUENCE_CLIENT_NETWORK]
'https://subgraph.testnet.fluence.dev/subgraphs/name/fluence-deal-contracts-04bb860b'

// export const SUBGRAPH_URL =
// import.meta.env.VITE_SUBGRAPH_URL ?? SUBGRAPH_URLS[FLUENCE_CLIENT_NETWORK]

export const DEPLOYMENT = DEPLOYMENTS[FLUENCE_CLIENT_NETWORK]
export const USDC_DECIMALS = 6

Expand Down
17 changes: 11 additions & 6 deletions src/pages/offer/OfferInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { formatUnixTimestamp } from '../../utils/formatUnixTimestamp'

import { ROUTES } from '../../constants'

import { OfferResourceTable } from './OfferResourceTable'
import { PeersTable } from './PeersTable'
import { SupportedEffectorsTable } from './SupportedEffectorsTable'

export const OfferInfo: React.FC = () => {
const params = useParams()
Expand Down Expand Up @@ -125,11 +125,16 @@ export const OfferInfo: React.FC = () => {
</Parameter>
</ParametersRow>
<Space height="60px" />
<Text size={20}>Supported effectors</Text>
<Space height="24px" />
<PeersTableWrapper>
<SupportedEffectorsTable effectors={offer.effectors} />
</PeersTableWrapper>
{offer.resources && (
<>
<Space height="40px" />
<Text size={20}>Available resources</Text>
<Space height="24px" />
<PeersTableWrapper>
<OfferResourceTable resources={offer.resources} />
</PeersTableWrapper>
</>
)}
<Space height="40px" />
<Text size={20}>Peers</Text>
<Space height="24px" />
Expand Down
105 changes: 105 additions & 0 deletions src/pages/offer/OfferResourceTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react'
import styled from '@emotion/styled'
import { OfferResource } from '@fluencelabs/deal-ts-clients/dist/dealExplorerClient/indexerClient/generated.types'

import {
Cell,
Row,
RowBlock,
RowHeader,
RowTrigger,
ScrollableTable,
TableBody,
TableColumnTitle,
TableHeader,
} from '../../components/Table'
import { Text } from '../../components/Text'
import { TokenBadge } from '../../components/TokenBadge'
import { JsonToYamlView } from '../../components/YamlView'
import { formatUSDcTokenValue } from '../../utils'
import { formatHexData } from '../../utils/helpers'

import { ResourceType, ResourceTypeNames } from './ResourceTable'

const TextWithBadge = styled.div`
display: flex;
align-items: center;
gap: 4px;
`

const template = [
'minmax(10px, 1fr)',
'minmax(10px, 1fr)',
'minmax(10px, 1fr)',
'minmax(10px, 1fr)',
]

interface ResourceTableProps {
resources: Omit<OfferResource, 'offer'>[]
}

export const OfferResourceTable: React.FC<ResourceTableProps> = ({
resources,
}) => {
return (
<>
<ScrollableTable>
<TableHeader template={template}>
<TableColumnTitle>Resource ID</TableColumnTitle>
<TableColumnTitle>Type</TableColumnTitle>
<TableColumnTitle>Price</TableColumnTitle>
<TableColumnTitle>Metadata</TableColumnTitle>
</TableHeader>
<TableBody>
{resources.map((resource) => (
<ResourceRow key={resource.id} offerResource={resource} />
))}
</TableBody>
</ScrollableTable>
</>
)
}

interface OfferResourceRowProps {
offerResource: Omit<OfferResource, 'offer'>
}

const ResourceRow: React.FC<OfferResourceRowProps> = ({
offerResource: { id, resource, price },
}: OfferResourceRowProps) => {
const resourceName = Object.values(ResourceType).includes(resource.type)
? ResourceTypeNames[resource.type as ResourceType]
: 'Unknown'

return (
<RowBlock>
<RowHeader>
<RowTrigger>
<Row template={template}>
<Cell>
<Text size={12}>{formatHexData(id, 8, 10)}</Text>
</Cell>
<Cell>
<Text size={12}>{resourceName}</Text>
</Cell>
<Cell>
<TextWithBadge>
<Text size={12}>{formatUSDcTokenValue(BigInt(price))}</Text>
<TokenBadge bg="grey200">
<Text size={10} weight={800} color="grey500">
USDC
</Text>
</TokenBadge>
</TextWithBadge>
</Cell>
<Cell>
<Text size={12}>
<JsonToYamlView data={resource.metadata} />
</Text>
</Cell>
</Row>
</RowTrigger>
</RowHeader>
</RowBlock>
)
}
13 changes: 13 additions & 0 deletions src/pages/offer/PeersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Peer } from '@fluencelabs/deal-ts-clients/dist/dealExplorerClient/types

import { A } from '../../components/A'
import { CapacityStatus } from '../../components/CapacityStatus'
import { Space } from '../../components/Space'
import {
Cell,
ContentBlock,
Row,
RowBlock,
RowHeader,
Expand All @@ -17,6 +19,8 @@ import {
import { Text } from '../../components/Text'
import { formatHexData } from '../../utils/helpers'

import { ResourceTable } from './ResourceTable'

const template = [
'20px',
'minmax(10px, 1fr)',
Expand Down Expand Up @@ -89,6 +93,15 @@ const PeerRow: React.FC<PeerRowProps> = ({ index, peer }) => {
)}
</Cell>
</Row>

{peer.resources && (
<>
<Space height="1rem" />
<ContentBlock>
<ResourceTable resources={peer.resources} />
</ContentBlock>
</>
)}
</RowTrigger>
</RowHeader>
</RowBlock>
Expand Down
Loading