Skip to content

Commit

Permalink
HF 30 - My NFT offers\bets page
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed May 30, 2024
1 parent 14c299e commit b84c6f3
Show file tree
Hide file tree
Showing 11 changed files with 346 additions and 23 deletions.
4 changes: 2 additions & 2 deletions app/ResolveRoute.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const routeRegex = {
UserProfile1: /^\/(@[\w\.\d-]+)\/?$/,
UserProfile2: /^\/(@[\w\.\d-]+)\/(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft-history|nft-tokens|nft-collections|filled-orders|permissions|created|password|witness|settings)\/??(?:&?[^=&]*=[^=&]*)*$/,
UserProfile2: /^\/(@[\w\.\d-]+)\/(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft-history|nft-tokens|nft-collections|nft-orders|filled-orders|permissions|created|password|witness|settings)\/??(?:&?[^=&]*=[^=&]*)*$/,
UserProfile3: /^\/(@[\w\.\d-]+)\/[\w\.\d-]+/,
UserNFTEndPoints: /^\/(@[\w\.\d-]+)\/nft-tokens\/([\w\d.-]+)\/?$/,
UserAssetEndPoints: /^\/(@[\w\.\d-]+)\/assets\/([\w\d.-]+)\/(update|transfer)$/,
UserEndPoints: /^(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft-history|nft-tokens|nft-collections|filled-orders|permissions|created|password|witness|settings)$/,
UserEndPoints: /^(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft-history|nft-tokens|nft-collections|nft-orders|filled-orders|permissions|created|password|witness|settings)$/,
WorkerSort: /^\/workers\/([\w\d\-]+)\/?($|\?)/,
WorkerSearchByAuthor: /^\/workers\/([\w\d\-]+)\/(\@[\w\d.-]+)\/?($|\?)/,
WorkerRequest: /^\/workers\/([\w\d\-]+)\/(\@[\w\d.-]+)\/([\w\d-]+)\/?($|\?)/,
Expand Down
1 change: 1 addition & 0 deletions app/components/all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
@import "./modules/nft/CreateNFTCollection";
@import "./modules/nft/IssueNFTToken";
@import "./modules/nft/NFTAuction";
@import "./modules/nft/NFTMyOrders";
@import "./modules/nft/NFTTokens";
@import "./modules/nft/NFTPlaceOfferBet";
@import "./modules/nft/NFTTokenSell";
Expand Down
6 changes: 3 additions & 3 deletions app/components/elements/nft/NFTSmallIcon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { proxifyNFTImage } from 'app/utils/ProxifyUrl'

class NFTSmallIcon extends Component {
render() {
const { image, ...rest } = this.props
const { image, size, href, ...rest } = this.props

const url = image.startsWith('http') ? proxifyNFTImage(image) : image

return <a className='NFTSmallIcon'
style={{ backgroundImage: `url(${url})` }} href={url} target='_blank' rel='nofollow noreferrer' {...rest}></a>
return <a className={'NFTSmallIcon ' + size}
style={{ backgroundImage: `url(${url})` }} href={href || url} target='_blank' rel='nofollow noreferrer' {...rest}></a>
}
}

Expand Down
5 changes: 5 additions & 0 deletions app/components/elements/nft/NFTSmallIcon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@
height: 3rem;
display: inline-block;
vertical-align: top;

&.mini {
width: 2rem !important;
height: 2rem !important;
}
}
2 changes: 2 additions & 0 deletions app/components/modules/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class Header extends React.Component {
page_title = tt('header_jsx.nft_collections') + " " + user_title
} else if (route.params[1] === "nft-history"){
page_title = tt('g.nft_history') + " " + user_title
} else if (route.params[1] === "nft-orders"){
page_title = tt('g.nft_orders') + " " + user_title
}
} else if (route.page === 'ConvertAssetsPage') {
page_title = tt('g.convert_assets')
Expand Down
209 changes: 209 additions & 0 deletions app/components/modules/nft/NFTMyOrders.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import {connect} from 'react-redux'
import { Link } from 'react-router'
import tt from 'counterpart'
import { Asset } from 'golos-lib-js/lib/utils'

import Icon from 'app/components/elements/Icon'
import LoadingIndicator from 'app/components/elements/LoadingIndicator'
import NFTSmallIcon from 'app/components/elements/nft/NFTSmallIcon'
import PriceIcon from 'app/components/elements/nft/PriceIcon'
import TimeExactWrapper from 'app/components/elements/TimeExactWrapper'
import g from 'app/redux/GlobalReducer'
import transaction from 'app/redux/Transaction'

const wrapAsTable = (immData, onRender, emptyHint) => {
immData = immData.get('data').toJS()

let res = []
for (const item of immData) {
res.push(onRender(item))
}
if (res.length) {
res = <table><tbody>
{res}
</tbody></table>
} else {
res = emptyHint
}

return res
}

class NFTMyOrders extends React.Component {
state = {}

componentDidMount() {
this.refetch()
}

refetch = () => {
this.props.fetchNftOrders()
}

cancelOffer = (e, owner, order_id) => {
e.preventDefault()
this.refetch()
}

_renderOffer = (no, assets) => {
const { token, price } = no
const { image, name, token_id, json_metadata, } = token

let data
if (json_metadata) {
data = JSON.parse(json_metadata)
}
data = data || {} // node allows to use '', null, object, or array

const title = data.title || (name + ' #' + token_id)

const pr = Asset(price)

const url = '/nft-tokens/' + token_id

return <tr key={no.order_id}>
<td title={title}>
<NFTSmallIcon image={image} size='mini'
href={url} />
</td>
<td style={{ width: '33%' }}>
<Link to={url} target='_blank' rel='noreferrer nofollow'>
{title}
</Link>
</td>
<td style={{ width: '33%' }}>
<PriceIcon text={a => {
return pr.amountFloat
}} asset={pr} assets={assets} title={pr.floatString} />
</td>
<td style={{ width: '33%' }}>
<button className='button small hollow alert' onClick={e => this.cancelOffer(e, no.owner, no.order_id)}>
{tt('nft_tokens_jsx.cancel')}
</button>
</td>
</tr>
}

_renderBet = (nb, assets) => {
const { token, price } = nb
const { image, name, token_id, json_metadata, auction_expiration } = token

let data
if (json_metadata) {
data = JSON.parse(json_metadata)
}
data = data || {} // node allows to use '', null, object, or array

const title = data.title || (name + ' #' + token_id)

const pr = Asset(price)

const url = '/nft-tokens/' + token_id

return <tr key={nb.ud}>
<td title={title}>
<NFTSmallIcon image={image} size='mini'
href={url} />
</td>
<td style={{ width: '33%' }}>
<Link to={url} target='_blank' rel='noreferrer nofollow'>
{title}
</Link>
</td>
<td style={{ width: '16%' }}>
<PriceIcon text={a => {
return pr.amountFloat
}} asset={pr} assets={assets} title={pr.floatString} />
</td>
<td style={{ width: '16%' }}>
<TimeExactWrapper date={auction_expiration} shorter={true}
tooltipRender={(tooltip) => tt('nft_tokens_jsx.auction_expiration3') + ': ' + tooltip}
contentRender={(content) => <React.Fragment>
<Icon name='clock' className='space-right' />
{content}
</React.Fragment>}
/>
</td>
<td style={{ width: '33%' }}>
<button className='button small hollow alert' title={tt('nft_token_page_jsx.cancel_bet')}>
{tt('nft_tokens_jsx.cancel')}
</button>
</td>
</tr>
}

_renderOffers = (assets) => {
let { my_nft_offers } = this.props
return wrapAsTable(my_nft_offers, no => this._renderOffer(no, assets),
tt('nft_my_orders_jsx.offers_empty'))
}

_renderBets = (assets) => {
let { my_nft_bets } = this.props

return wrapAsTable(my_nft_bets, nb => this._renderBet(nb, assets),
tt('nft_my_orders_jsx.bets_empty'))
}

render() {
let { my_nft_offers, my_nft_bets, nft_assets } = this.props

if (!my_nft_offers) {
return <div className="UserWallet NFTMyOrders">
<div className="row">
<LoadingIndicator type='circle' />
</div>
</div>
}

const assets = nft_assets ? nft_assets.toJS() : {}

return (<div className="UserWallet NFTMyOrders">
<div className="row">
<div className="column small-12">
<h4>{tt('nft_my_orders_jsx.offers')}</h4>
{this._renderOffers(assets)}
<hr />
<h4>{tt('nft_my_orders_jsx.bets')}</h4>
{this._renderBets(assets)}
</div>
</div>
</div>);
}
}

export default connect(
// mapStateToProps
(state, ownProps) => {
return {
...ownProps,
my_nft_offers: state.global.get('my_nft_offers'),
my_nft_bets: state.global.get('my_nft_bets'),
nft_assets: state.global.get('nft_assets')
}
},
dispatch => ({
fetchNftOrders: () => {
dispatch(g.actions.fetchNftOrders({ }))
},
cancelOrder: (
owner, order_id, successCallback, errorCallback
) => {
const operation = {
owner,
order_id,
}

dispatch(transaction.actions.broadcastOperation({
type: 'nft_cancel_order',
confirm: tt('g.are_you_sure'),
username,
operation,
successCallback,
errorCallback
}))
},
})
)(NFTMyOrders)
11 changes: 11 additions & 0 deletions app/components/modules/nft/NFTMyOrders.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.NFTMyOrders {
.price-icon {
width: 20px;
height: 20px;
margin-right: 0.25rem;
}

.button {
margin-bottom: 0px;
}
}
11 changes: 11 additions & 0 deletions app/components/pages/UserProfile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import CurationRewards from 'app/components/modules/CurationRewards';
import AuthorRewards from 'app/components/modules/AuthorRewards';
import FilledOrders from 'app/components/modules/FilledOrders'
import NFTHistory from 'app/components/modules/nft/NFTHistory'
import NFTMyOrders from 'app/components/modules/nft/NFTMyOrders'
import LoadingIndicator from 'app/components/elements/LoadingIndicator';
import { authUrl, } from 'app/utils/AuthApiClient'
import { getGameLevel } from 'app/utils/GameUtils'
Expand Down Expand Up @@ -284,6 +285,15 @@ export default class UserProfile extends React.Component {
<MarkNotificationRead fields='nft_token_sold,nft_buy_offer' account={account.name} />
</div>
}
else if( section === 'nft-orders' ) {
nftClass = 'active'
tab_content = <div>
<NFTMyOrders
account={account}
current_user={current_user}
/>
</div>
}
else if( section === 'donates-from' ) {
rewardsClass = 'active';
tab_content = <DonatesFrom
Expand Down Expand Up @@ -383,6 +393,7 @@ export default class UserProfile extends React.Component {
let nftMenu = [
{link: `/@${accountname}/nft-tokens`, label: tt('g.nft_tokens'), value: tt('g.nft_tokens'), addon: isMyAccount && <NotifiCounter fields='nft_receive' /> },
{link: `/@${accountname}/nft-collections`, label: tt('g.nft_collections'), value: tt('g.nft_collections')},
{link: `/@${accountname}/nft-orders`, label: tt('g.nft_orders'), value: tt('g.nft_orders'), },
{link: `/@${accountname}/nft-history`, label: tt('g.nft_history'), value: tt('g.nft_history'), addon: isMyAccount && <NotifiCounter fields='nft_token_sold,nft_buy_offer' /> },
];

Expand Down
7 changes: 7 additions & 0 deletions app/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
"nft_tokens": "Токены NFT",
"nft_collections": "Коллекции NFT",
"nft_history": "История NFT",
"nft_orders": "Сделки NFT",
"help_wallet": "Функции кошелька",
"phone": "телефон",
"post": "Пост",
Expand Down Expand Up @@ -1235,6 +1236,12 @@
"other": "%(count)s ордеров"
}
},
"nft_my_orders_jsx": {
"offers": "NFT-предложения",
"offers_empty": "У вас на данный момент нет предложений о покупке NFT.",
"bets": "Ставки в NFT-аукционах",
"bets_empty": "У вас нет ставок в открытых аукционах."
},
"invites_jsx": {
"create_invite": "Создание чека",
"create_invite_info": "Чеки (инвайт-коды) — инструмент для передачи токенов другим людям вне блокчейна. Использовать чек можно двумя способами: перевести его баланс на аккаунт (форма для этого ниже) или зарегистрировать с его помощью новый аккаунт.",
Expand Down
Loading

0 comments on commit b84c6f3

Please sign in to comment.