mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-01 12:44:43 +00:00
Merge branch 'master' into community_0_decay_transaction
This commit is contained in:
commit
5dd0d473db
@ -22,6 +22,7 @@ class AppRequestsController extends AppController
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->loadComponent('GradidoNumber');
|
||||
//$this->loadComponent('JsonRpcRequestClient');
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['index', 'sendCoins', 'createCoins', 'getBalance', 'listTransactions']);
|
||||
@ -115,9 +116,10 @@ class AppRequestsController extends AppController
|
||||
return $required_fields;
|
||||
}
|
||||
|
||||
if(intval($param['amount']) <= 0) {
|
||||
if(floatval($param['amount']) <= 0.0) {
|
||||
return ['state' => 'error', 'msg' => 'amount is invalid', 'details' => $param['amount']];
|
||||
}
|
||||
$param['amount'] = $this->GradidoNumber->parseInputNumberToCentNumber($param['amount']);
|
||||
|
||||
if(isset($data->memo)) {
|
||||
$param['memo'] = $data->memo;
|
||||
@ -268,7 +270,7 @@ class AppRequestsController extends AppController
|
||||
|
||||
public function getBalance($session_id = 0)
|
||||
{
|
||||
|
||||
$this->viewBuilder()->setLayout('ajax');
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
@ -284,16 +286,18 @@ class AppRequestsController extends AppController
|
||||
return $this->returnJson(['state' => 'success', 'balance' => 0]);
|
||||
}
|
||||
$now = new FrozenTime();
|
||||
return $this->returnJson([
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'balance' => $state_balance->amount,
|
||||
'decay' => $state_balance->partDecay($now),
|
||||
'decay_date' => $now
|
||||
]);
|
||||
];
|
||||
$this->set('body', $body);
|
||||
}
|
||||
|
||||
public function listTransactions($page = 1, $count = 25, $orderDirection = 'ASC', $session_id = 0)
|
||||
{
|
||||
$this->viewBuilder()->setLayout('ajax');
|
||||
$startTime = microtime(true);
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
@ -337,14 +341,29 @@ class AppRequestsController extends AppController
|
||||
$transactions = array_reverse($transactions);
|
||||
}
|
||||
}
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => count($transactions),
|
||||
'gdtSum' => $gdtSum,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
|
||||
$state_balance = $stateBalancesTable->find()->where(['state_user_id' => $user['id']])->first();
|
||||
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => count($transactions),
|
||||
'gdtSum' => $gdtSum,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
];
|
||||
$now = new FrozenTime();
|
||||
$body['decay_date'] = $now;
|
||||
|
||||
if(!$state_balance) {
|
||||
$body['balance'] = 0.0;
|
||||
$body['decay'] = 0.0;
|
||||
} else {
|
||||
$body['balance'] = $state_balance->amount;
|
||||
$body['decay'] = $state_balance->partDecay($now);
|
||||
}
|
||||
|
||||
$this->set('body', $body);
|
||||
}
|
||||
|
||||
private function acquireAccessToken($session_id)
|
||||
|
||||
@ -3,6 +3,7 @@ namespace App\Model\Entity;
|
||||
|
||||
use Cake\ORM\Entity;
|
||||
use Cake\I18n\Time;
|
||||
use Cake\I18n\Number;
|
||||
|
||||
/**
|
||||
* StateBalance Entity
|
||||
@ -34,7 +35,7 @@ class StateBalance extends Entity
|
||||
'state_user' => true
|
||||
];
|
||||
|
||||
protected $_virtual = ['decay'];
|
||||
protected $_virtual = ['decay','amount_float'];
|
||||
|
||||
private function convertToTimestamp($dateOrTime)
|
||||
{
|
||||
@ -67,6 +68,7 @@ class StateBalance extends Entity
|
||||
return intval($this->amount * pow(0.99999997802044727, $decay_duration));
|
||||
|
||||
}
|
||||
|
||||
public function partDecay($target_date)
|
||||
{
|
||||
$decay_duration = intval($this->convertToTimestamp($target_date) - $this->convertToTimestamp($this->record_date));
|
||||
|
||||
@ -122,9 +122,9 @@ class StateUsersTable extends Table
|
||||
// exchange back
|
||||
$involvedUserIds = array_flip($involvedUser_temp);
|
||||
$involvedUser = $this->find('all', [
|
||||
'contain' => false,
|
||||
'contain' => [],
|
||||
'where' => ['id IN' => $involvedUserIds],
|
||||
'fields' => ['id', 'first_name', 'last_name', 'email']
|
||||
'fields' => ['id', 'first_name', 'last_name', 'email'],
|
||||
]);
|
||||
//var_dump($involvedUser->toArray());
|
||||
$involvedUserIndices = [];
|
||||
|
||||
@ -6,7 +6,7 @@ use Cake\ORM\RulesChecker;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\Validation\Validator;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
use Cake\I18n\Number;
|
||||
/**
|
||||
* Transactions Model
|
||||
*
|
||||
@ -260,7 +260,7 @@ class TransactionsTable extends Table
|
||||
$state_balance->record_date = $su_transaction->balance_date;
|
||||
$final_transactions[] = [
|
||||
'type' => 'decay',
|
||||
'balance' => -intval($su_transaction->balance - $state_balance->decay),
|
||||
'balance' => floatval(intval($su_transaction->balance - $state_balance->decay)),
|
||||
'decay_duration' => $su_transaction->balance_date->timeAgoInWords(),
|
||||
'memo' => ''
|
||||
];
|
||||
|
||||
@ -99,12 +99,12 @@ class TransactionTransfer extends TransactionBase {
|
||||
->where(['public_key' => $senderPublic])
|
||||
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]])->first();
|
||||
if(!$user) {
|
||||
$this->addError($functionName, 'couldn\'t find sender ' . $i .' in db' );
|
||||
$this->addError($functionName, 'couldn\'t find sender in db' );
|
||||
return false;
|
||||
}
|
||||
//var_dump($user);
|
||||
if(intval($user->state_balances[0]->amount) < intval($amount)) {
|
||||
$this->addError($functionName, 'sender ' . $i . ' hasn\t enough GDD');
|
||||
$this->addError($functionName, 'sender hasn\t enough GDD');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ class TransactionTransfer extends TransactionBase {
|
||||
// check if receiver exist
|
||||
$receiver_user = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $receiver_public_key])->first();
|
||||
if(!$receiver_user) {
|
||||
$this->addError($functionName, 'couldn\'t find receiver ' . $i .' in db' );
|
||||
$this->addError($functionName, 'couldn\'t find receiver in db' );
|
||||
return false;
|
||||
}
|
||||
if($amount < 0) {
|
||||
|
||||
11
community_server/src/Template/AppRequests/get_balance.ctp
Normal file
11
community_server/src/Template/AppRequests/get_balance.ctp
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
$body['balance'] = $this->element('centToFloat', ['cent' => $body['balance'], 'precision' => 4]);
|
||||
$body['decay'] = $this->element('centToFloat', ['cent' => $body['decay'], 'precision' => 4]);
|
||||
?><?= json_encode($body) ?>
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
$body['balance'] = $this->element('centToFloat', ['cent' => $body['balance'], 'precision' => 4]);
|
||||
$body['decay'] = $this->element('centToFloat', ['cent' => $body['decay'], 'precision' => 4]);
|
||||
$body['gdtSum'] = $this->element('centToFloat', ['cent' => $body['gdtSum'], 'precision' => 2]);
|
||||
|
||||
foreach($body['transactions'] as $i => $transaction) {
|
||||
$body['transactions'][$i]['balance'] = $this->element('centToFloat', ['cent' => $transaction['balance'], 'precision' => 4]);
|
||||
}
|
||||
|
||||
?><?= json_encode($body) ?>
|
||||
18
community_server/src/Template/Element/centToFloat.ctp
Normal file
18
community_server/src/Template/Element/centToFloat.ctp
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
$cut_places = $precision - 2;
|
||||
$transformAmount = $cent;
|
||||
if($cut_places > 0) {
|
||||
$transformAmount = floor($cent / pow(10, $cut_places));
|
||||
}
|
||||
if($cut_places < 0) {
|
||||
$cut_places = 0;
|
||||
}
|
||||
echo $transformAmount / pow(10, $precision - $cut_places);
|
||||
|
||||
@ -23,13 +23,13 @@ Additional session can be provided as GET-Parameter
|
||||
```json
|
||||
{
|
||||
"state":"success",
|
||||
"balance":15906078,
|
||||
"balance":1590.60,
|
||||
"decay":15873851,
|
||||
"decay_date":"2021-04-16T11:47:21+00:00"
|
||||
}
|
||||
```
|
||||
|
||||
- `balance` : balance describes gradido cents which are 4 digits behind the separator. A balance value of 174500 equals therefor 17,45 GDD
|
||||
- `balance` : balance describes gradido
|
||||
- `decay` : balance with decay on it at the time in decay_date, so it is the precise balance of user at time of calling this function
|
||||
- `decay_date`: date and time for decay amount, should be the time and date of function call
|
||||
|
||||
@ -65,7 +65,7 @@ Assuming: session is valid
|
||||
"type": "send",
|
||||
"transaction_id": 2,
|
||||
"date": "2021-02-19T13:25:36+00:00",
|
||||
"balance": 1920000,
|
||||
"balance": 192.0,
|
||||
"memo": "a piece of cake :)",
|
||||
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
|
||||
}
|
||||
@ -95,7 +95,7 @@ Transaction:
|
||||
- `receiver`: user has received gradidos from another user
|
||||
- `transaction_id`: id of transaction in db, in stage2 also the hedera sequence number of transaction
|
||||
- `date`: date of ordering transaction (booking date)
|
||||
- `balance`: Gradido Cent, 4 Nachkommastellen (2 Reserve), 1920000 = 192,00 GDD
|
||||
- `balance`: Gradido
|
||||
- `memo`: Details about transaction
|
||||
|
||||
## Creation transaction
|
||||
@ -245,4 +245,3 @@ Without auto-sign the transaction is pending on the login-server and waits for t
|
||||
// TODO Is this in line with our usability goals?
|
||||
// TODO Should this not be handled client side?
|
||||
|
||||
|
||||
|
||||
@ -176,7 +176,7 @@ Wenn alles okay:
|
||||
"type": "creation|send|receive",
|
||||
"transaction_id": <transaction_id>, // db id not id from blockchain
|
||||
"date": "<date string>",
|
||||
"balance": <GDD balance in GDD cent /10000>,
|
||||
"balance": <GDD balance in GDD cent>,
|
||||
"memo": "<Verwendungszweck>",
|
||||
"pubkey": "<other_user.public_key in hex>"
|
||||
|
||||
@ -319,7 +319,7 @@ Wenn alles okay:
|
||||
"type": "creation|send|receive",
|
||||
"transaction_id": <transaction_id>, // db id not id from blockchain
|
||||
"date": "<date string>",
|
||||
"balance": <GDD balance in GDD cent /10000>,
|
||||
"balance": <GDD balance in GDD cent>,
|
||||
"memo": "<Verwendungszweck>",
|
||||
"pubkey": "<other_user.public_key in hex>"
|
||||
|
||||
|
||||
@ -35,8 +35,10 @@ const communityAPI = {
|
||||
balance: async (session_id) => {
|
||||
return apiGet(CONFIG.COMMUNITY_API_URL + 'getBalance/' + session_id)
|
||||
},
|
||||
transactions: async (session_id) => {
|
||||
return apiGet(CONFIG.COMMUNITY_API_URL + 'listTransactions/1/25/ASC/' + session_id)
|
||||
transactions: async (session_id, firstPage = 1, items = 25, order = 'DESC') => {
|
||||
return apiGet(
|
||||
`${CONFIG.COMMUNITY_API_URL}listTransactions/${firstPage}/${items}/${order}/${session_id}`,
|
||||
)
|
||||
},
|
||||
/*create: async (session_id, email, amount, memo, target_date = new Date() ) => {
|
||||
const payload = {
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
"form": {
|
||||
"attention": "<strong>Achtung!</strong> Bitte überprüfe alle deine Eingaben sehr genau. Du bist alleine Verantwortlich für deine Entscheidungen. Versendete Gradidos können nicht wieder zurück geholt werden.",
|
||||
"cancel":"Abbrechen",
|
||||
"reset": "Zurücksetzen",
|
||||
"close":"schließen",
|
||||
"receiver":"Empfänger",
|
||||
"sender":"Absender",
|
||||
@ -45,6 +46,9 @@
|
||||
"thx":"Danke,",
|
||||
"send_success":"deine Transaktion wurde erfolgreich ausgeführt"
|
||||
},
|
||||
"error": {
|
||||
"error":"Fehler"
|
||||
},
|
||||
"transaction":{
|
||||
"show_all":"Alle <strong>{count}</strong> Transaktionen ansehen",
|
||||
"nullTransactions":"Du hast noch keine Transaktionen auf deinem Konto.",
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
"form": {
|
||||
"attention": "Achtung! Bitte überprüfe alle deine Eingaben sehr genau. Du bist alleine Verantwortlich für deine Entscheidungen. Versendete Gradidos können nicht wieder zurück geholt werden.",
|
||||
"cancel":"Cancel",
|
||||
"reset": "Reset",
|
||||
"close":"Close",
|
||||
"receiver":"Receiver",
|
||||
"sender":"Sender",
|
||||
@ -45,8 +46,12 @@
|
||||
"thx":"Thank you,",
|
||||
"send_success":"your transaction was successfully completed"
|
||||
},
|
||||
"error": {
|
||||
"error":"Error"
|
||||
},
|
||||
"transaction":{
|
||||
"show_part": "The last <strong>{count}</strong> transactions",
|
||||
"show_all":"View all <strong>{count}</strong> transactions.",
|
||||
"show_part": "The last <strong>{count}</strong> transactions.",
|
||||
"nullTransactions":"You don't have any transactions on your account yet.",
|
||||
"more": "more"
|
||||
},
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<div class="main-content">
|
||||
<template>
|
||||
<div class="main-content">
|
||||
<router-view></router-view>
|
||||
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
||||
</div>
|
||||
</template>
|
||||
<div class="wrapper">
|
||||
<div class="main-content">
|
||||
<router-view></router-view>
|
||||
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -79,7 +79,7 @@ describe('DashboardLayoutGdd', () => {
|
||||
})
|
||||
|
||||
it('has five items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > li')).toHaveLength(3)
|
||||
expect(navbar.findAll('ul > li')).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('has first item "send" in navbar', () => {
|
||||
@ -104,17 +104,17 @@ describe('DashboardLayoutGdd', () => {
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/transactions')
|
||||
})
|
||||
|
||||
it('has third item "My profile" in navbar', () => {
|
||||
expect(navbar.findAll('ul > li').at(2).text()).toEqual('site.navbar.my-profil')
|
||||
})
|
||||
|
||||
it.skip('has third item "My profile" linked to profile in navbar', async () => {
|
||||
navbar.findAll('ul > li > a').at(2).trigger('click')
|
||||
await flushPromises()
|
||||
await jest.runAllTimers()
|
||||
await flushPromises()
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
||||
})
|
||||
//it('has third item "My profile" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(2).text()).toEqual('site.navbar.my-profil')
|
||||
//})
|
||||
//
|
||||
//it.skip('has third item "My profile" linked to profile in navbar', async () => {
|
||||
// navbar.findAll('ul > li > a').at(2).trigger('click')
|
||||
// await flushPromises()
|
||||
// await jest.runAllTimers()
|
||||
// await flushPromises()
|
||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
||||
//})
|
||||
|
||||
//it('has fourth item "Settigs" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(3).text()).toEqual('site.navbar.settings')
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
<b-nav-item href="#!" to="/transactions">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('transactions') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<!--
|
||||
<b-nav-item href="#!" to="/profile">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.my-profil') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<!--
|
||||
</b-nav-item>
|
||||
<b-nav-item href="#!" to="/profileedit">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.settings') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
@ -32,6 +32,7 @@
|
||||
:balance="balance"
|
||||
:gdt-balance="GdtBalance"
|
||||
:transactions="transactions"
|
||||
:transactionCount="transactionCount"
|
||||
@update-balance="updateBalance"
|
||||
@update-transactions="updateTransactions"
|
||||
></router-view>
|
||||
@ -79,6 +80,8 @@ export default {
|
||||
balance: 0,
|
||||
GdtBalance: 0,
|
||||
transactions: [],
|
||||
bookedBalance: 0,
|
||||
transactionCount: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -94,19 +97,14 @@ export default {
|
||||
this.$store.dispatch('logout')
|
||||
this.$router.push('/login')
|
||||
},
|
||||
async loadBalance() {
|
||||
const result = await communityAPI.balance(this.$store.state.session_id)
|
||||
if (result.success) {
|
||||
this.balance = result.result.data.balance / 10000
|
||||
} else {
|
||||
// what to do when loading balance fails?
|
||||
}
|
||||
},
|
||||
async updateTransactions() {
|
||||
const result = await communityAPI.transactions(this.$store.state.session_id)
|
||||
if (result.success) {
|
||||
this.GdtBalance = result.result.data.gdtSum / 10000
|
||||
this.GdtBalance = Number(result.result.data.gdtSum)
|
||||
this.transactions = result.result.data.transactions
|
||||
this.balance = Number(result.result.data.decay)
|
||||
this.bookedBalance = Number(result.result.data.balance)
|
||||
this.transactionCount = result.result.data.count
|
||||
} else {
|
||||
// what to do when loading balance fails?
|
||||
}
|
||||
@ -119,7 +117,6 @@ export default {
|
||||
this.initScrollbar()
|
||||
},
|
||||
created() {
|
||||
this.loadBalance()
|
||||
this.updateTransactions()
|
||||
},
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
<div>
|
||||
<!-- Header -->
|
||||
<div class="header py-1 py-lg-1 pt-lg-3">
|
||||
<b-container>xx</b-container>
|
||||
<b-container>
|
||||
<div class="header-body text-center mb-3">
|
||||
<a href="/login" to="/login">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<base-header class="pb-6 pb-8 pt-5 pt-md-8 bg-transparent"></base-header>
|
||||
<b-container fluid class="mt--7">
|
||||
<base-header class="pb-4 pt-2 bg-transparent"></base-header>
|
||||
<b-container fluid class="p-2 mt-5">
|
||||
<gdd-status v-if="showTransactionList" :balance="balance" :gdt-balance="GdtBalance" />
|
||||
<br />
|
||||
<gdd-send
|
||||
@ -14,6 +14,9 @@
|
||||
<gdd-table
|
||||
v-if="showTransactionList"
|
||||
:transactions="transactions"
|
||||
:max="5"
|
||||
:timestamp="timestamp"
|
||||
:transactionCount="transactionCount"
|
||||
@update-transactions="updateTransactions"
|
||||
/>
|
||||
</b-container>
|
||||
@ -29,6 +32,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
showTransactionList: true,
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@ -37,6 +41,7 @@ export default {
|
||||
transactions: {
|
||||
default: () => [],
|
||||
},
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
},
|
||||
components: {
|
||||
GddStatus,
|
||||
|
||||
@ -120,7 +120,7 @@ describe('GddSend', () => {
|
||||
})
|
||||
|
||||
it('has the text "form.cancel"', () => {
|
||||
expect(wrapper.find('button[type="reset"]').text()).toBe('form.cancel')
|
||||
expect(wrapper.find('button[type="reset"]').text()).toBe('form.reset')
|
||||
})
|
||||
|
||||
it.skip('clears the email field on click', async () => {
|
||||
|
||||
@ -121,8 +121,8 @@
|
||||
<br />
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-button type="reset" variant="secondary">
|
||||
{{ $t('form.cancel') }}
|
||||
<b-button type="reset" variant="secondary" @click="onReset">
|
||||
{{ $t('form.reset') }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
<b-col class="text-right">
|
||||
@ -254,7 +254,7 @@ export default {
|
||||
const result = await communityAPI.send(
|
||||
this.$store.state.session_id,
|
||||
this.ajaxCreateData.email,
|
||||
this.ajaxCreateData.amount * 10000,
|
||||
this.ajaxCreateData.amount,
|
||||
this.ajaxCreateData.memo,
|
||||
this.ajaxCreateData.target_date,
|
||||
)
|
||||
@ -274,6 +274,7 @@ export default {
|
||||
event.preventDefault()
|
||||
this.form.email = ''
|
||||
this.form.amount = ''
|
||||
this.form.memo = ''
|
||||
this.show = false
|
||||
this.$emit('toggle-show-list', true)
|
||||
this.row_check = false
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-row>
|
||||
<b-col xl="6" md="6">
|
||||
<b-col col="6">
|
||||
<stats-card
|
||||
type="gradient-red"
|
||||
sub-title="balance_gdd"
|
||||
@ -11,7 +11,7 @@
|
||||
{{ $n(balance) }} GDD
|
||||
</stats-card>
|
||||
</b-col>
|
||||
<b-col xl="6" md="6">
|
||||
<b-col col="6">
|
||||
<stats-card
|
||||
type="gradient-orange"
|
||||
sub-title="balance_gdt"
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-list-group v-show="showTransactionList">
|
||||
<b-list-group>
|
||||
<b-list-group-item
|
||||
v-for="item in transactions"
|
||||
v-for="item in transactions.slice(0, max)"
|
||||
:key="item.id"
|
||||
style="background-color: #ebebeba3 !important"
|
||||
>
|
||||
@ -38,7 +38,7 @@
|
||||
<h1 class="">
|
||||
<span v-if="item.type === 'receive' || item.type === 'creation'">+</span>
|
||||
<span v-else>-</span>
|
||||
{{ $n(item.balance / 10000) }}
|
||||
{{ $n(item.balance) }}
|
||||
<small>GDD</small>
|
||||
</h1>
|
||||
<h2 class="text-muted">{{ item.name }}</h2>
|
||||
@ -95,7 +95,7 @@
|
||||
<router-link
|
||||
v-else-if="transactions.length > 5"
|
||||
to="/transactions"
|
||||
v-html="$t('transaction.show_all', { count: count })"
|
||||
v-html="$t('transaction.show_all', { count: transactionCount })"
|
||||
></router-link>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
@ -106,39 +106,27 @@
|
||||
export default {
|
||||
name: 'GddTable',
|
||||
props: {
|
||||
showTransactionList: { type: Boolean, default: true },
|
||||
transactions: { default: [] },
|
||||
max: { type: Number, default: 25 },
|
||||
timestamp: { type: Number, default: 0 },
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: [],
|
||||
fields: ['balance', 'date', 'memo', 'name', 'transaction_id', 'type', 'details'],
|
||||
items: [],
|
||||
count: 0,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$emit('change-transactions')
|
||||
},
|
||||
computed: {
|
||||
filteredItems() {
|
||||
return this.ojectToArray(this.items).reverse()
|
||||
watch: {
|
||||
timestamp: {
|
||||
immediate: true,
|
||||
handler: 'updateTransactions',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
ojectToArray(obj) {
|
||||
let result = new Array(Object.keys(obj).length)
|
||||
Object.entries(obj).forEach((entry) => {
|
||||
const [key, value] = entry
|
||||
result[key] = value
|
||||
})
|
||||
return result
|
||||
},
|
||||
rowClass(item, type) {
|
||||
if (!item || type !== 'row') return
|
||||
if (item.type === 'receive') return 'table-success'
|
||||
if (item.type === 'send') return 'table-warning'
|
||||
if (item.type === 'creation') return 'table-primary'
|
||||
updateTransactions() {
|
||||
this.$emit('update-transactions')
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-card no-body class="border-0" style="background-color: #ebebeba3 !important">
|
||||
<b-card-body class="px-lg-5 py-lg-5">
|
||||
<b-card-body class="p-4">
|
||||
<validation-observer v-slot="{ handleSubmit }" ref="formValidator">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<base-input
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="login-form">
|
||||
<!-- Header -->
|
||||
<div class="header p-4">
|
||||
<div class="p-3">
|
||||
<b-container>
|
||||
<div class="text-center mb-7">
|
||||
<div class="text-center mb-7 header">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>Gradido</h1>
|
||||
@ -14,11 +14,11 @@
|
||||
</b-container>
|
||||
</div>
|
||||
<!-- Page content -->
|
||||
<b-container class="mt--8 p-1">
|
||||
<b-container class="mt--8">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="5" md="7">
|
||||
<b-card no-body class="border-0 mb-0" style="background-color: #ebebeba3 !important">
|
||||
<b-card-body class="py-lg-4 px-sm-0 px-0 px-md-2 px-lg-4">
|
||||
<b-card-body class="p-4">
|
||||
<div class="text-center text-muted mb-4">
|
||||
<small>{{ $t('login') }}</small>
|
||||
</div>
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-card no-body class="border-0" style="background-color: #ebebeba3 !important">
|
||||
<b-card-body class="py-lg-4 px-sm-0 px-0 px-md-2 px-lg-4">
|
||||
<b-card-body class="p-4">
|
||||
<div class="text-center text-muted mb-4">
|
||||
<small>{{ $t('signup') }}</small>
|
||||
</div>
|
||||
@ -110,6 +110,20 @@
|
||||
</base-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-alert
|
||||
v-if="showError"
|
||||
show
|
||||
dismissible
|
||||
variant="warning"
|
||||
@dismissed="closeAlert"
|
||||
>
|
||||
<span class="alert-icon"><i class="ni ni-point"></i></span>
|
||||
<span class="alert-text">
|
||||
<strong>{{ $t('error.error') }}!</strong>
|
||||
{{ messageError }}
|
||||
</span>
|
||||
</b-alert>
|
||||
|
||||
<div
|
||||
class="text-center"
|
||||
v-if="
|
||||
@ -160,6 +174,8 @@ export default {
|
||||
checkPassword: '',
|
||||
passwordVisible: false,
|
||||
submitted: false,
|
||||
showError: false,
|
||||
messageError: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -184,11 +200,18 @@ export default {
|
||||
this.password = ''
|
||||
this.$router.push('/thx')
|
||||
} else {
|
||||
// todo: Display a proper error message!
|
||||
this.$store.dispatch('logout')
|
||||
this.$router.push('/login')
|
||||
this.showError = true
|
||||
this.messageError = result.result.message
|
||||
}
|
||||
},
|
||||
closeAlert() {
|
||||
this.showError = false
|
||||
this.messageError = ''
|
||||
this.model.email = ''
|
||||
this.model.firstname = ''
|
||||
this.model.lastname = ''
|
||||
this.password = ''
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
samePasswords() {
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-card no-body class="border-0" style="background-color: #ebebeba3 !important">
|
||||
<b-card-body class="py-lg-4 px-sm-0 px-0 px-md-2 px-lg-4">
|
||||
<b-card-body class="p-4">
|
||||
<validation-observer v-slot="{ handleSubmit }" ref="formValidator">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<b-form-group :label="$t('form.password')">
|
||||
|
||||
@ -7,7 +7,12 @@
|
||||
<b-container fluid class="mt--6">
|
||||
<b-row>
|
||||
<b-col class="order-xl-1">
|
||||
<gdd-table :transactions="transactions" @update-transactions="updateTransactions" />
|
||||
<gdd-table
|
||||
:timestamp="timestamp"
|
||||
:transactionCount="transactionCount"
|
||||
:transactions="transactions"
|
||||
@update-transactions="updateTransactions"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="text-center mb-6" v-if="transactions.length == 0">
|
||||
@ -27,6 +32,12 @@ export default {
|
||||
transactions: {
|
||||
default: [],
|
||||
},
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateTransactions() {
|
||||
|
||||
@ -121,8 +121,12 @@ Poco::JSON::Object* JsonCreateTransaction::transfer(Poco::Dynamic::Var params)
|
||||
result = stateError("user not in group", "receiver user isn't in target group");
|
||||
}
|
||||
}
|
||||
auto sender_user = mSession->getNewUser();
|
||||
if (sender_user->getGradidoKeyPair()->isTheSame(*target_pubkey)) {
|
||||
result = stateError("sender and receiver are the same");
|
||||
}
|
||||
if (!result) {
|
||||
auto transaction = model::gradido::Transaction::createTransfer(mSession->getNewUser(), target_pubkey, mTargetGroup, amount, mMemo, mBlockchainType);
|
||||
auto transaction = model::gradido::Transaction::createTransfer(sender_user, target_pubkey, mTargetGroup, amount, mMemo, mBlockchainType);
|
||||
|
||||
if (mAutoSign) {
|
||||
Poco::JSON::Array errors;
|
||||
|
||||
@ -110,7 +110,7 @@ Poco::JSON::Object* JsonSendEmail::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
session = sm->getNewSession();
|
||||
if (emailType == model::EMAIL_USER_RESET_PASSWORD) {
|
||||
auto r = session->sendResetPasswordEmail(receiver_user, false, receiver_user->getGroupBaseUrl());
|
||||
auto r = session->sendResetPasswordEmail(receiver_user, true, receiver_user->getGroupBaseUrl());
|
||||
if (1 == r) {
|
||||
return stateWarning("email already sended");
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
|
||||
default:
|
||||
result->set("state", "error");
|
||||
result->set("msg", "unknown user state");
|
||||
result->set("details", USER_NO_GROUP);
|
||||
result->set("details", user_state);
|
||||
}
|
||||
|
||||
sm->releaseSession(session);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user