diff --git a/content/site.json b/content/site.json index 0c231e412..3e3378201 100644 --- a/content/site.json +++ b/content/site.json @@ -14,7 +14,7 @@ "link": "/profile" } ], - "announcement": "Explore [OceanONDA V4](https://blog.oceanprotocol.com/how-to-publish-a-data-nft-f58ad2a622a9).", + "announcement": "[Lock your OCEAN](https://df.oceandao.org/) to get veOCEAN, earn rewards and curate data.", "warning": { "ctd": "Compute-to-Data is still in a testing phase, please use it only on test networks." } diff --git a/package-lock.json b/package-lock.json index 11fcc6297..5c14421a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@coingecko/cryptoformat": "^0.5.4", "@loadable/component": "^5.15.2", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^2.2.1", + "@oceanprotocol/lib": "^2.2.3", "@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/use-dark-mode": "^2.4.3", "@tippyjs/react": "^4.2.6", @@ -4539,9 +4539,9 @@ "integrity": "sha512-Oe+oBRiu1dlco9PQ7eUYcTYi2Nua69S3TiSw62H46AIpwnFK8ORuO0Ny20No++KisBA9F+84b5lDn6kQy5Lt/Q==" }, "node_modules/@oceanprotocol/lib": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.2.1.tgz", - "integrity": "sha512-HNmT3DJJeyvFRwCbmgJucGpte90epIhgSy+68PSc83TLKRW2CF4N1mioMkoGxMwnK3rJzj6tEy4R9NKKLbdT5w==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.2.3.tgz", + "integrity": "sha512-jBD6bD1dPd7MHiiMA0V2hBntHM0vhmYpzeuv2dNj/2i1FNvTzpQO3v4a5V+Ahxs6L6YirBBfzT3HHtGKOghc5w==", "dependencies": { "@oceanprotocol/contracts": "^1.1.7", "bignumber.js": "^9.1.0", @@ -44803,9 +44803,9 @@ "integrity": "sha512-Oe+oBRiu1dlco9PQ7eUYcTYi2Nua69S3TiSw62H46AIpwnFK8ORuO0Ny20No++KisBA9F+84b5lDn6kQy5Lt/Q==" }, "@oceanprotocol/lib": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.2.1.tgz", - "integrity": "sha512-HNmT3DJJeyvFRwCbmgJucGpte90epIhgSy+68PSc83TLKRW2CF4N1mioMkoGxMwnK3rJzj6tEy4R9NKKLbdT5w==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.2.3.tgz", + "integrity": "sha512-jBD6bD1dPd7MHiiMA0V2hBntHM0vhmYpzeuv2dNj/2i1FNvTzpQO3v4a5V+Ahxs6L6YirBBfzT3HHtGKOghc5w==", "requires": { "@oceanprotocol/contracts": "^1.1.7", "bignumber.js": "^9.1.0", diff --git a/package.json b/package.json index d9dc37b96..454d933f2 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@coingecko/cryptoformat": "^0.5.4", "@loadable/component": "^5.15.2", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^2.2.1", + "@oceanprotocol/lib": "^2.2.3", "@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/use-dark-mode": "^2.4.3", "@tippyjs/react": "^4.2.6", diff --git a/src/@hooks/useNetworkMetadata/utils.ts b/src/@hooks/useNetworkMetadata/utils.ts index f3ec518f1..c97dcdc2e 100644 --- a/src/@hooks/useNetworkMetadata/utils.ts +++ b/src/@hooks/useNetworkMetadata/utils.ts @@ -32,22 +32,25 @@ export function getNetworkDisplayName( displayName = 'Polygon' break case 1287: - displayName = 'Moonbase Alpha' + displayName = 'Moonbase' break case 1285: displayName = 'Moonriver' break case 80001: - displayName = 'Polygon Mumbai' + displayName = 'Mumbai' break case 8996: displayName = 'Development' break case 3: - displayName = 'ETH Ropsten' + displayName = 'Ropsten' + break + case 5: + displayName = 'Görli' break case 2021000: - displayName = 'GAIA-X Testnet' + displayName = 'GAIA-X' break default: displayName = data diff --git a/src/@types/aquarius/SearchQuery.ts b/src/@types/aquarius/SearchQuery.ts index 3e4543c39..026adbcfd 100644 --- a/src/@types/aquarius/SearchQuery.ts +++ b/src/@types/aquarius/SearchQuery.ts @@ -7,7 +7,8 @@ export enum SortTermOptions { Created = 'nft.created', Relevance = '_score', Orders = 'stats.orders', - Allocated = 'stats.allocated' + Allocated = 'stats.allocated', + Price = 'stats.price.value' } // Note: could not figure out how to get `enum` to be ambiant diff --git a/src/@utils/aquarius.ts b/src/@utils/aquarius.ts index c0f7697ea..2e0ed6c60 100644 --- a/src/@utils/aquarius.ts +++ b/src/@utils/aquarius.ts @@ -215,6 +215,28 @@ export async function getAssetsFromDtList( } } +export async function getAssetsFromNftList( + nftList: string[], + chainIds: number[], + cancelToken: CancelToken +): Promise { + try { + if (!(nftList.length > 0)) return + + const baseParams = { + chainIds, + filters: [getFilterTerm('nftAddress', nftList)], + ignorePurgatory: true + } as BaseQueryParams + const query = generateBaseQuery(baseParams) + + const queryResult = await queryMetadata(query, cancelToken) + return queryResult?.results + } catch (error) { + LoggerInstance.error(error.message) + } +} + export async function retrieveDDOListByDIDs( didList: string[], chainIds: number[], diff --git a/src/@utils/veAllocation.ts b/src/@utils/veAllocation.ts index 351d5e25f..2b1c3efad 100644 --- a/src/@utils/veAllocation.ts +++ b/src/@utils/veAllocation.ts @@ -1,7 +1,19 @@ import { AllLocked } from 'src/@types/subgraph/AllLocked' +import { OwnAllocations } from 'src/@types/subgraph/OwnAllocations' +import { NftOwnAllocation } from 'src/@types/subgraph/NftOwnAllocation' +import { OceanLocked } from 'src/@types/subgraph/OceanLocked' import { gql, OperationResult } from 'urql' import { fetchData, getQueryContext } from './subgraph' import axios from 'axios' +import networkdata from '../../content/networks-metadata.json' +import { + getNetworkDataById, + getNetworkType, + NetworkType +} from '@hooks/useNetworkMetadata' +import { getAssetsFromNftList } from './aquarius' +import { chainIdsSupported } from 'app.config' +import { Asset, LoggerInstance } from '@oceanprotocol/lib' const AllLocked = gql` query AllLocked { @@ -11,10 +23,82 @@ const AllLocked = gql` } ` -interface TotalVe { +const OwnAllocations = gql` + query OwnAllocations($address: String) { + veAllocations(where: { allocationUser: $address }) { + id + nftAddress + allocated + } + } +` +const NftOwnAllocation = gql` + query NftOwnAllocation($address: String, $nftAddress: String) { + veAllocations( + where: { allocationUser: $address, nftAddress: $nftAddress } + ) { + allocated + } + } +` +const OceanLocked = gql` + query OceanLocked($address: String) { + veOCEAN(id: $address) { + id + lockedAmount + unlockTime + } + } +` + +export interface TotalVe { totalLocked: number totalAllocated: number } +export interface Allocation { + nftAddress: string + allocation: number +} + +export interface AssetWithOwnAllocation { + asset: AssetExtended + allocation: string +} + +export function getVeChainNetworkId(assetNetworkId: number): number { + const networkData = getNetworkDataById(networkdata, assetNetworkId) + const networkType = getNetworkType(networkData) + if (networkType === NetworkType.Mainnet) return 1 + else return 5 +} + +export function getVeChainNetworkIds(assetNetworkIds: number[]): number[] { + const veNetworkIds: number[] = [] + assetNetworkIds.forEach((x) => { + const id = getVeChainNetworkId(x) + veNetworkIds.indexOf(id) === -1 && veNetworkIds.push(id) + }) + return veNetworkIds +} +export async function getNftOwnAllocation( + userAddress: string, + nftAddress: string, + networkId: number +): Promise { + const veNetworkId = getVeChainNetworkId(networkId) + const queryContext = getQueryContext(veNetworkId) + const fetchedAllocation: OperationResult = + await fetchData( + NftOwnAllocation, + { + address: userAddress.toLowerCase(), + nftAddress: nftAddress.toLowerCase() + }, + queryContext + ) + + return fetchedAllocation.data?.veAllocations[0]?.allocated +} export async function getTotalAllocatedAndLocked(): Promise { const totals = { @@ -26,7 +110,7 @@ export async function getTotalAllocatedAndLocked(): Promise { const response = await axios.post(`https://df-sql.oceandao.org/nftinfo`) totals.totalAllocated = response.data?.reduce( - (previousValue: number, currentValue: { ve_allocated: any }) => + (previousValue: number, currentValue: { ve_allocated: string }) => previousValue + Number(currentValue.ve_allocated), 0 ) @@ -43,3 +127,66 @@ export async function getTotalAllocatedAndLocked(): Promise { ) return totals } + +export async function getLocked( + userAddress: string, + networkIds: number[] +): Promise { + let total = 0 + const veNetworkIds = getVeChainNetworkIds(networkIds) + for (let i = 0; i < veNetworkIds.length; i++) { + const queryContext = getQueryContext(veNetworkIds[i]) + const fetchedLocked: OperationResult = await fetchData( + OceanLocked, + { address: userAddress.toLowerCase() }, + queryContext + ) + + fetchedLocked.data?.veOCEAN?.lockedAmount && + (total += Number(fetchedLocked.data?.veOCEAN?.lockedAmount)) + } + + return total +} + +export async function getOwnAllocations( + networkIds: number[], + userAddress: string +): Promise { + const allocations: Allocation[] = [] + const veNetworkIds = getVeChainNetworkIds(networkIds) + for (let i = 0; i < veNetworkIds.length; i++) { + const queryContext = getQueryContext(veNetworkIds[i]) + const fetchedAllocations: OperationResult = + await fetchData( + OwnAllocations, + { address: userAddress.toLowerCase() }, + queryContext + ) + + fetchedAllocations.data?.veAllocations.forEach( + (x) => + x.allocated !== '0' && + allocations.push({ + nftAddress: x.nftAddress, + allocation: x.allocated / 100 + }) + ) + } + + return allocations +} + +export async function getOwnAssetsWithAllocation( + networkIds: number[], + userAddress: string +): Promise { + const allocations = await getOwnAllocations(networkIds, userAddress) + const assets = await getAssetsFromNftList( + allocations.map((x) => x.nftAddress), + chainIdsSupported, + null + ) + + return assets +} diff --git a/src/components/@shared/AssetTeaser/index.module.css b/src/components/@shared/AssetTeaser/index.module.css index 9069d7647..ca468094f 100644 --- a/src/components/@shared/AssetTeaser/index.module.css +++ b/src/components/@shared/AssetTeaser/index.module.css @@ -51,7 +51,7 @@ font-size: var(--font-size-mini); display: inline-block; border-left: 1px solid var(--border-color); - padding-left: calc(var(--spacer) / 3.5); + padding-left: calc(var(--spacer) / 4); margin-left: calc(var(--spacer) / 4); } diff --git a/src/components/@shared/AssetTeaser/index.tsx b/src/components/@shared/AssetTeaser/index.tsx index 4099b4137..f0db24936 100644 --- a/src/components/@shared/AssetTeaser/index.tsx +++ b/src/components/@shared/AssetTeaser/index.tsx @@ -39,7 +39,9 @@ export default function AssetTeaser({ type={type} accessType={accessType} /> - {datatokens[0]?.symbol} + + {datatokens[0]?.symbol.substring(0, 9)} + { - if (!prices || !price || !priceTokenId || !prices[priceTokenId]) { + if (!prices || !priceTokenId || !prices[priceTokenId]) { return } @@ -41,7 +41,7 @@ export default function Conversion({ isFiat ? currency : '', locale, false, - { decimalPlaces: 2 } + { decimalPlaces: price === 0 ? 0 : 2 } ) // It's a hack! Wrap everything in the string which is not a number or `.` or `,` // with a span for consistent visual symbol formatting. diff --git a/src/components/@shared/Price/PriceUnit.module.css b/src/components/@shared/Price/PriceUnit.module.css index 1a965e00d..bcf01e4a2 100644 --- a/src/components/@shared/Price/PriceUnit.module.css +++ b/src/components/@shared/Price/PriceUnit.module.css @@ -7,7 +7,7 @@ line-height: 1.2; } -.price > div:firt-child { +.price > div:first-child { white-space: nowrap; } diff --git a/src/components/@shared/atoms/Table/Empty.tsx b/src/components/@shared/atoms/Table/Empty.tsx index f3ca115ce..68b5fbffd 100644 --- a/src/components/@shared/atoms/Table/Empty.tsx +++ b/src/components/@shared/atoms/Table/Empty.tsx @@ -1,6 +1,14 @@ +import { markdownToHtml } from '@utils/markdown' import React, { ReactElement } from 'react' import styles from './Empty.module.css' export default function Empty({ message }: { message?: string }): ReactElement { - return
{message || 'No results found'}
+ return ( +
+ ) } diff --git a/src/components/Asset/AssetActions/AssetStats/index.tsx b/src/components/Asset/AssetActions/AssetStats/index.tsx index dd6e79991..a32dc2d38 100644 --- a/src/components/Asset/AssetActions/AssetStats/index.tsx +++ b/src/components/Asset/AssetActions/AssetStats/index.tsx @@ -1,44 +1,61 @@ import { useAsset } from '@context/Asset' import { useUserPreferences } from '@context/UserPreferences' +import { useWeb3 } from '@context/Web3' +import Tooltip from '@shared/atoms/Tooltip' import { formatPrice } from '@shared/Price/PriceUnit' +import { getNftOwnAllocation } from '@utils/veAllocation' import React, { useEffect, useState } from 'react' import styles from './index.module.css' export default function AssetStats() { const { locale } = useUserPreferences() const { asset } = useAsset() - const [orders, setOrders] = useState(0) - const [allocated, setAllocated] = useState(0) + const { accountId } = useWeb3() + + const [ownAllocation, setOwnAllocation] = useState(0) useEffect(() => { - if (!asset) return + if (!asset || !accountId) return - const { orders, allocated } = asset.stats - - setOrders(orders) - setAllocated(allocated) - }, [asset]) + async function init() { + const allocation = await getNftOwnAllocation( + accountId, + asset.nftAddress, + asset.chainId + ) + setOwnAllocation(allocation / 100) + } + init() + }, [accountId, asset]) return (
- {allocated && allocated > 0 ? ( + {asset?.stats?.allocated && asset?.stats?.allocated > 0 ? ( - {formatPrice(allocated, locale)} + {formatPrice(asset.stats.allocated, locale)} veOCEAN ) : null} - {!asset || !asset?.stats || orders < 0 ? ( + {!asset?.stats || asset?.stats?.orders < 0 ? ( 'N/A' - ) : orders === 0 ? ( + ) : asset?.stats?.orders === 0 ? ( 'No sales yet' ) : ( - {orders} sale - {orders === 1 ? '' : 's'} + {asset.stats.orders} sale + {asset.stats.orders === 1 ? '' : 's'} )} + {ownAllocation && ownAllocation > 0 ? ( + + {ownAllocation}% allocated + + + ) : null}
) } diff --git a/src/components/Footer/MarketStats/Total.tsx b/src/components/Footer/MarketStats/Total.tsx index 01b883ab5..34ee13b18 100644 --- a/src/components/Footer/MarketStats/Total.tsx +++ b/src/components/Footer/MarketStats/Total.tsx @@ -11,10 +11,7 @@ export default function MarketStatsTotal({ <> orders across{' '} assets with{' '} - different datatokens.{' '} - {' '} - allocated.{' '} - locked. + different datatokens. ) } diff --git a/src/components/Footer/MarketStats/index.tsx b/src/components/Footer/MarketStats/index.tsx index 563be5839..19f4ab32d 100644 --- a/src/components/Footer/MarketStats/index.tsx +++ b/src/components/Footer/MarketStats/index.tsx @@ -15,6 +15,7 @@ import Tooltip from '@shared/atoms/Tooltip' import Markdown from '@shared/Markdown' import content from '../../../../content/footer.json' import { getTotalAllocatedAndLocked } from '@utils/veAllocation' +import PriceUnit from '@shared/Price/PriceUnit' const initialTotal: StatsTotal = { nfts: 0, @@ -113,7 +114,7 @@ export default function MarketStats(): ReactElement { return (
- <> +
{' '} } /> - +
+
+ locked.{' '} + {' '} + allocated. +
) } diff --git a/src/components/Header/SearchBar.module.css b/src/components/Header/SearchBar.module.css index a2f582104..2192c23a5 100644 --- a/src/components/Header/SearchBar.module.css +++ b/src/components/Header/SearchBar.module.css @@ -58,9 +58,6 @@ width: auto; left: auto; background: none; - } - - .input:focus + .button { z-index: 3; } } diff --git a/src/components/Home/Allocations/AssetListTable.tsx b/src/components/Home/Allocations/AssetListTable.tsx new file mode 100644 index 000000000..36a22bae5 --- /dev/null +++ b/src/components/Home/Allocations/AssetListTable.tsx @@ -0,0 +1,47 @@ +import React from 'react' +import Table, { TableOceanColumn } from '@shared/atoms/Table' +import AssetTitle from '@shared/AssetList/AssetListTitle' +import { AssetWithOwnAllocation } from '@utils/veAllocation' + +const columns: TableOceanColumn[] = [ + { + name: 'Dataset', + selector: (row) => { + const { metadata } = row.asset + return + }, + maxWidth: '45rem', + grow: 1 + }, + { + name: 'Datatoken Symbol', + selector: (row) => row.asset.datatokens[0].symbol, + maxWidth: '10rem' + }, + { + name: 'Allocated', + selector: (row) => row.allocation, + right: true, + sortable: true + } +] + +export default function AssetListTable({ + data, + isLoading +}: { + data: AssetWithOwnAllocation[] + isLoading: boolean +}) { + return ( + + ) +} diff --git a/src/components/Home/Allocations/index.module.css b/src/components/Home/Allocations/index.module.css new file mode 100644 index 000000000..d176386d7 --- /dev/null +++ b/src/components/Home/Allocations/index.module.css @@ -0,0 +1,3 @@ +.section { + composes: section from '../index.module.css'; +} diff --git a/src/components/Home/Allocations/index.tsx b/src/components/Home/Allocations/index.tsx new file mode 100644 index 000000000..a58c7890f --- /dev/null +++ b/src/components/Home/Allocations/index.tsx @@ -0,0 +1,93 @@ +import React, { ReactElement, useEffect, useState } from 'react' +import { useWeb3 } from '@context/Web3' +import { AssetWithOwnAllocation, getOwnAllocations } from '@utils/veAllocation' +import styles from './index.module.css' +import { + getFilterTerm, + generateBaseQuery, + queryMetadata +} from '@utils/aquarius' +import { useUserPreferences } from '@context/UserPreferences' +import { useCancelToken } from '@hooks/useCancelToken' +import { useIsMounted } from '@hooks/useIsMounted' +import { LoggerInstance } from '@oceanprotocol/lib' +import AssetListTable from './AssetListTable' + +export default function Allocations(): ReactElement { + const { accountId } = useWeb3() + const { chainIds } = useUserPreferences() + const isMounted = useIsMounted() + const newCancelToken = useCancelToken() + + const [loading, setLoading] = useState() + const [data, setData] = useState() + const [hasAllocations, setHasAllocations] = useState(false) + + useEffect(() => { + if (!accountId) return + + async function checkAllocations() { + try { + const allocations = await getOwnAllocations(chainIds, accountId) + setHasAllocations(allocations && allocations.length > 0) + } catch (error) { + LoggerInstance.error(error.message) + } + } + checkAllocations() + }, [accountId, chainIds]) + + useEffect(() => { + async function getAllocationAssets() { + if (!hasAllocations) return + + try { + setLoading(true) + + const allocations = await getOwnAllocations(chainIds, accountId) + setHasAllocations(allocations && allocations.length > 0) + + const baseParams = { + chainIds, + filters: [ + getFilterTerm( + 'nftAddress', + allocations.map((x) => x.nftAddress) + ) + ], + ignorePurgatory: true + } as BaseQueryParams + + const query = generateBaseQuery(baseParams) + + const result = await queryMetadata(query, newCancelToken()) + + const assetsWithAllocation: AssetWithOwnAllocation[] = [] + + result?.results.forEach((asset) => { + const allocation = allocations.find( + (x) => x.nftAddress.toLowerCase() === asset.nftAddress.toLowerCase() + ) + assetsWithAllocation.push({ + asset, + allocation: `${allocation.allocation} %` + }) + }) + + if (!isMounted()) return + setData(assetsWithAllocation) + setLoading(false) + } catch (error) { + LoggerInstance.error(error.message) + } + } + getAllocationAssets() + }, [hasAllocations, accountId, chainIds, isMounted, newCancelToken]) + + return ( +
+

Your Allocated Assets

+ +
+ ) +} diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index 1cd7cc4c5..59672f9b4 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -8,12 +8,14 @@ import TopSales from './TopSales' import TopTags from './TopTags' import SectionQueryResult from './SectionQueryResult' import styles from './index.module.css' +import Allocations from './Allocations' export default function HomePage(): ReactElement { + const { chainIds } = useUserPreferences() + const [queryLatest, setQueryLatest] = useState() const [queryMostSales, setQueryMostSales] = useState() const [queryMostAllocation, setQueryMostAllocation] = useState() - const { chainIds } = useUserPreferences() useEffect(() => { const baseParams = { @@ -52,10 +54,12 @@ export default function HomePage(): ReactElement { return ( <>
-

Bookmarks

+

Your Bookmarks

+ + { + async function getLockedOcean() { + if (!accountId) return + const locked = await getLocked(accountId, chainIds) + setLockedOcean(locked) + } + getLockedOcean() + }, [accountId, chainIds]) useEffect(() => { if (!assets || !accountId || !chainIds) return @@ -59,6 +74,30 @@ export default function Stats({ value={sales < 0 ? 0 : sales} /> + + Lock OCEAN + + ) : ( + <> + locked + + ) + } + value={ + 0 ? lockedOcean : 0} + symbol="OCEAN" + hideApproximateSymbol + /> + } + /> ) } diff --git a/src/components/Search/Filters.module.css b/src/components/Search/Filters.module.css index 70359b151..2138604a4 100644 --- a/src/components/Search/Filters.module.css +++ b/src/components/Search/Filters.module.css @@ -3,13 +3,11 @@ div.filterList { white-space: normal; margin-top: 0; margin-bottom: 0; - display: flex; gap: calc(var(--spacer) / 4) calc(var(--spacer) / 2); - flex-direction: column; - align-items: baseline; } -.filter { +.filter, +.filterList > div { display: inline-block; } diff --git a/src/components/Search/index.module.css b/src/components/Search/index.module.css index 9a3840e2e..0d8ccfa23 100644 --- a/src/components/Search/index.module.css +++ b/src/components/Search/index.module.css @@ -1,10 +1,8 @@ .row { display: inline-flex; flex-direction: column; - align-items: stretch; justify-content: space-between; width: 100%; - white-space: nowrap; margin-bottom: calc(var(--spacer) / 2); } diff --git a/src/components/Search/sort.module.css b/src/components/Search/sort.module.css index dad17cba1..5a774c7b5 100644 --- a/src/components/Search/sort.module.css +++ b/src/components/Search/sort.module.css @@ -8,15 +8,9 @@ overflow-y: auto; } -@media (min-width: 55rem) { - .sortList { - align-self: flex-end; - overflow-y: unset; - } -} - .sortLabel { composes: label from '@shared/FormInput/Label.module.css'; + padding: 0; margin-bottom: 0; margin-left: calc(var(--spacer) / 2); margin-right: calc(var(--spacer) / 1.5); @@ -26,7 +20,7 @@ } .sorted { - display: flex; + display: inline-block; padding: calc(var(--spacer) / 6) calc(var(--spacer) / 2); margin-right: calc(var(--spacer) / 4); color: var(--color-secondary); @@ -35,6 +29,7 @@ font-weight: var(--font-weight-base); background: var(--background-content); box-shadow: none; + white-space: nowrap; } .sorted:hover, @@ -47,7 +42,6 @@ } .direction { - display: flex; background: transparent; border: none; color: inherit; diff --git a/src/components/Search/sort.tsx b/src/components/Search/sort.tsx index 710854c57..b71371496 100644 --- a/src/components/Search/sort.tsx +++ b/src/components/Search/sort.tsx @@ -13,7 +13,10 @@ const cx = classNames.bind(styles) const sortItems = [ { display: 'Relevance', value: SortTermOptions.Relevance }, - { display: 'Published', value: SortTermOptions.Created } + { display: 'Published', value: SortTermOptions.Created }, + { display: 'Sales', value: SortTermOptions.Orders }, + { display: 'Total allocation', value: SortTermOptions.Allocated }, + { display: 'Price', value: SortTermOptions.Price } ] export default function Sort({