mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 20:21:35 +00:00
Route refCode url to api/user and display rewards
This commit is contained in:
parent
a11419395f
commit
dea2b665fb
@ -405,6 +405,24 @@ class Profile(models.Model):
|
|||||||
default=False,
|
default=False,
|
||||||
null=False
|
null=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Referral program
|
||||||
|
is_referred = models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
null=False
|
||||||
|
)
|
||||||
|
referral_code = models.CharField(
|
||||||
|
max_length=15,
|
||||||
|
null=True,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
|
# Recent rewards from referred trades that will be "earned" at a later point to difficult spionage.
|
||||||
|
pending_rewards = models.PositiveIntegerField(null=False, default=0)
|
||||||
|
# Claimable rewards
|
||||||
|
earned_rewards = models.PositiveIntegerField(null=False, default=0)
|
||||||
|
# Total claimed rewards
|
||||||
|
claimed_rewarded = models.PositiveIntegerField(null=False, default=0)
|
||||||
|
|
||||||
# Disputes
|
# Disputes
|
||||||
num_disputes = models.PositiveIntegerField(null=False, default=0)
|
num_disputes = models.PositiveIntegerField(null=False, default=0)
|
||||||
lost_disputes = models.PositiveIntegerField(null=False, default=0)
|
lost_disputes = models.PositiveIntegerField(null=False, default=0)
|
||||||
|
@ -13,6 +13,7 @@ from api.serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrde
|
|||||||
from api.models import LNPayment, MarketTick, Order, Currency
|
from api.models import LNPayment, MarketTick, Order, Currency
|
||||||
from api.logics import Logics
|
from api.logics import Logics
|
||||||
from api.messages import Telegram
|
from api.messages import Telegram
|
||||||
|
from secrets import token_urlsafe
|
||||||
from api.utils import get_lnd_version, get_commit_robosats, compute_premium_percentile
|
from api.utils import get_lnd_version, get_commit_robosats, compute_premium_percentile
|
||||||
|
|
||||||
from .nick_generator.nick_generator import NickGenerator
|
from .nick_generator.nick_generator import NickGenerator
|
||||||
@ -521,6 +522,7 @@ class UserView(APIView):
|
|||||||
is_staff=False)
|
is_staff=False)
|
||||||
user = authenticate(request, username=nickname, password=token)
|
user = authenticate(request, username=nickname, password=token)
|
||||||
user.profile.avatar = "static/assets/avatars/" + nickname + ".png"
|
user.profile.avatar = "static/assets/avatars/" + nickname + ".png"
|
||||||
|
#user.profile.referral_code = token_urlsafe(8)
|
||||||
login(request, user)
|
login(request, user)
|
||||||
return Response(context, status=status.HTTP_201_CREATED)
|
return Response(context, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
@ -637,7 +639,7 @@ class InfoView(ListAPIView):
|
|||||||
status=Order.Status.PUB))
|
status=Order.Status.PUB))
|
||||||
context["book_liquidity"] = Order.objects.filter(status=Order.Status.PUB).aggregate(Sum('last_satoshis'))['last_satoshis__sum']
|
context["book_liquidity"] = Order.objects.filter(status=Order.Status.PUB).aggregate(Sum('last_satoshis'))['last_satoshis__sum']
|
||||||
context["book_liquidity"] = 0 if context["book_liquidity"] == None else context["book_liquidity"]
|
context["book_liquidity"] = 0 if context["book_liquidity"] == None else context["book_liquidity"]
|
||||||
|
|
||||||
# Number of active users (logged in in last 30 minutes)
|
# Number of active users (logged in in last 30 minutes)
|
||||||
today = datetime.today()
|
today = datetime.today()
|
||||||
context["active_robots_today"] = len(
|
context["active_robots_today"] = len(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import {Badge, Tooltip, TextField, ListItemAvatar, Avatar,Paper, Grid, IconButton, Typography, Select, MenuItem, List, ListItemText, ListItem, ListItemIcon, ListItemButton, Divider, Dialog, DialogContent} from "@mui/material";
|
import {Badge, Tooltip, TextField, ListItemAvatar, Button, Avatar,Paper, Grid, IconButton, Typography, Select, MenuItem, List, ListItemText, ListItem, ListItemIcon, ListItemButton, Divider, Dialog, DialogContent} from "@mui/material";
|
||||||
import MediaQuery from 'react-responsive'
|
import MediaQuery from 'react-responsive'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ import DnsIcon from '@mui/icons-material/Dns';
|
|||||||
import WebIcon from '@mui/icons-material/Web';
|
import WebIcon from '@mui/icons-material/Web';
|
||||||
import BookIcon from '@mui/icons-material/Book';
|
import BookIcon from '@mui/icons-material/Book';
|
||||||
import PersonAddAltIcon from '@mui/icons-material/PersonAddAlt';
|
import PersonAddAltIcon from '@mui/icons-material/PersonAddAlt';
|
||||||
|
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
||||||
|
|
||||||
// pretty numbers
|
// pretty numbers
|
||||||
function pn(x) {
|
function pn(x) {
|
||||||
@ -56,6 +57,8 @@ export default class BottomBar extends Component {
|
|||||||
profileShown: false,
|
profileShown: false,
|
||||||
alternative_site: 'robosats...',
|
alternative_site: 'robosats...',
|
||||||
node_id: '00000000',
|
node_id: '00000000',
|
||||||
|
referral_link: 'No referral link',
|
||||||
|
earned_rewards: 0,
|
||||||
};
|
};
|
||||||
this.getInfo();
|
this.getInfo();
|
||||||
}
|
}
|
||||||
@ -275,13 +278,13 @@ export default class BottomBar extends Component {
|
|||||||
{this.props.token ?
|
{this.props.token ?
|
||||||
<TextField
|
<TextField
|
||||||
disabled
|
disabled
|
||||||
label='Store safely'
|
label='Store Safely'
|
||||||
value={this.props.token }
|
value={this.props.token }
|
||||||
variant='filled'
|
variant='filled'
|
||||||
size='small'
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment:
|
||||||
<Tooltip disableHoverListener open={this.state.copied} enterTouchDelay="0" title="Copied!">
|
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
|
||||||
<IconButton onClick= {()=>navigator.clipboard.writeText(this.props.token)}>
|
<IconButton onClick= {()=>navigator.clipboard.writeText(this.props.token)}>
|
||||||
<ContentCopy />
|
<ContentCopy />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -300,15 +303,14 @@ export default class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary="Your referral link">
|
<ListItemText secondary="Your referral link">
|
||||||
<TextField
|
<TextField
|
||||||
label='Share to earn satoshis'
|
label='Share to Earn Satoshis'
|
||||||
// value={this.props.referral_link}
|
value={this.state.referral_link}
|
||||||
value={'LINKKKKKKK732hcd23j98j2iuwh78c2i3jd9cy2hiudn8723ihdcniu2hdci23923jiuxjw'}
|
|
||||||
// variant='filled'
|
// variant='filled'
|
||||||
size='small'
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment:
|
||||||
<Tooltip disableHoverListener open={this.state.copied} enterTouchDelay="0" title="Copied!">
|
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
|
||||||
<IconButton onClick= {()=>navigator.clipboard.writeText('LINKKKKKKK732hcd23j98j2iuwh78c2i3jd9cy2hiudn8723ihdcniu2hdci23923jiuxjw')}>
|
<IconButton onClick= {()=>navigator.clipboard.writeText(this.state.referral_link)}>
|
||||||
<ContentCopy />
|
<ContentCopy />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
@ -316,6 +318,24 @@ export default class BottomBar extends Component {
|
|||||||
/>
|
/>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<ListItemIcon>
|
||||||
|
<EmojiEventsIcon/>
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText secondary="Your earned rewards">
|
||||||
|
<Grid container xs={12}>
|
||||||
|
<Grid item xs={9}>
|
||||||
|
<Typography>{this.state.earned_rewards+" Sats"}</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={3}>
|
||||||
|
{/* WIP: BUTTON ALWAYS DISABLED <Button disabled={this.state.earned_rewards==0? true : false} variant="contained" size="small">Claim</Button> */}
|
||||||
|
<Button disabled={this.state.earned_rewards==0? true : true} variant="contained" size="small">Claim</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
</List>
|
</List>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -30,7 +30,8 @@ export default class HomePage extends Component {
|
|||||||
<Router >
|
<Router >
|
||||||
<div className='appCenter'>
|
<div className='appCenter'>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path='/' render={(props) => <UserGenPage {...this.state} setAppState={this.setAppState}/>}/>
|
<Route exact path='/' render={(props) => <UserGenPage {...props} {...this.state} setAppState={this.setAppState}/>}/>
|
||||||
|
<Route path='/ref/:refCode' render={(props) => <UserGenPage {...props} {...this.state} setAppState={this.setAppState}/>}/>
|
||||||
<Route path='/make' component={MakerPage}/>
|
<Route path='/make' component={MakerPage}/>
|
||||||
<Route path='/book' component={BookPage}/>
|
<Route path='/book' component={BookPage}/>
|
||||||
<Route path="/order/:orderId" component={OrderPage}/>
|
<Route path="/order/:orderId" component={OrderPage}/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Tooltip, Paper, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup, dividerClasses} from "@mui/material"
|
import { Tooltip, Paper, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup} from "@mui/material"
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import getFlags from './getFlags'
|
import getFlags from './getFlags'
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ export default class UserGenPage extends Component {
|
|||||||
tokenHasChanged: false,
|
tokenHasChanged: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
//this.props.setAppState({avatarLoaded: false, nickname: null, token: null});
|
this.refCode = this.props.match.params.refCode;
|
||||||
|
|
||||||
// Checks in parent HomePage if there is already a nick and token
|
// Checks in parent HomePage if there is already a nick and token
|
||||||
// Displays the existing one
|
// Displays the existing one
|
||||||
@ -40,7 +40,7 @@ export default class UserGenPage extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
nickname: this.props.nickname,
|
nickname: this.props.nickname,
|
||||||
token: this.props.token? this.props.token : null,
|
token: this.props.token? this.props.token : null,
|
||||||
avatar_url: 'static/assets/avatars/' + this.props.nickname + '.png',
|
avatar_url: '/static/assets/avatars/' + this.props.nickname + '.png',
|
||||||
loadingRobot: false
|
loadingRobot: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,6 +56,7 @@ export default class UserGenPage extends Component {
|
|||||||
// sort of cryptographically strong function to generate Base62 token client-side
|
// sort of cryptographically strong function to generate Base62 token client-side
|
||||||
genBase62Token(length)
|
genBase62Token(length)
|
||||||
{
|
{
|
||||||
|
console.log(this.refCode)
|
||||||
return window.btoa(Array.from(
|
return window.btoa(Array.from(
|
||||||
window.crypto.getRandomValues(
|
window.crypto.getRandomValues(
|
||||||
new Uint8Array(length * 2)))
|
new Uint8Array(length * 2)))
|
||||||
@ -71,7 +72,7 @@ export default class UserGenPage extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
bit_entropy: data.token_bits_entropy,
|
bit_entropy: data.token_bits_entropy,
|
||||||
avatar_url: 'static/assets/avatars/' + data.nickname + '.png',
|
avatar_url: '/static/assets/avatars/' + data.nickname + '.png',
|
||||||
shannon_entropy: data.token_shannon_entropy,
|
shannon_entropy: data.token_shannon_entropy,
|
||||||
bad_request: data.bad_request,
|
bad_request: data.bad_request,
|
||||||
found: data.found,
|
found: data.found,
|
||||||
|
File diff suppressed because one or more lines are too long
@ -758,6 +758,10 @@
|
|||||||
!*** ./node_modules/@mui/icons-material/ContentCopy.js ***!
|
!*** ./node_modules/@mui/icons-material/ContentCopy.js ***!
|
||||||
\*********************************************************/
|
\*********************************************************/
|
||||||
|
|
||||||
|
/*!*********************************************************!*\
|
||||||
|
!*** ./node_modules/@mui/icons-material/EmojiEvents.js ***!
|
||||||
|
\*********************************************************/
|
||||||
|
|
||||||
/*!*********************************************************!*\
|
/*!*********************************************************!*\
|
||||||
!*** ./node_modules/@mui/icons-material/PriceChange.js ***!
|
!*** ./node_modules/@mui/icons-material/PriceChange.js ***!
|
||||||
\*********************************************************/
|
\*********************************************************/
|
||||||
|
@ -2,11 +2,9 @@ from django.urls import path
|
|||||||
from .views import index
|
from .views import index
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", index),
|
|
||||||
path("info/", index),
|
|
||||||
path("login/", index),
|
|
||||||
path("make/", index),
|
path("make/", index),
|
||||||
path("book/", index),
|
path("book/", index),
|
||||||
path("order/<int:orderId>", index),
|
path("order/<int:orderId>", index),
|
||||||
path("wait/", index),
|
path("", index),
|
||||||
|
path("ref/<refCode>", index),
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user