diff --git a/frontend/src/apis/communityAPI.js b/frontend/src/apis/communityAPI.js index a1fe3faf6..25ef10f43 100644 --- a/frontend/src/apis/communityAPI.js +++ b/frontend/src/apis/communityAPI.js @@ -51,14 +51,11 @@ const communityAPI = { } return apiPost(CONFIG.COMMUNITY_API__URL + 'createCoins/', payload) }, */ - send: async (sessionId, email, amount, memo, targetDate) => { + send: async (sessionId, data) => { const payload = { session_id: sessionId, - email, - amount, - memo, - target_date: targetDate, auto_sign: true, + ...data, } return apiPost(CONFIG.COMMUNITY_API_URL + 'sendCoins/', payload) }, diff --git a/frontend/src/views/Pages/AccountOverview.spec.js b/frontend/src/views/Pages/AccountOverview.spec.js index 1454ada5c..68d91ee98 100644 --- a/frontend/src/views/Pages/AccountOverview.spec.js +++ b/frontend/src/views/Pages/AccountOverview.spec.js @@ -34,30 +34,5 @@ describe('AccountOverview', () => { it('has a transactions table', () => { expect(wrapper.find('gdd-table-stub').exists()).toBeTruthy() }) - - describe('updateBalance method', () => { - beforeEach(async () => { - wrapper.find('gdd-send-stub').vm.$emit('update-balance', { - ammount: 42, - }) - await wrapper.vm.$nextTick() - }) - - it('emmits updateBalance with correct value', () => { - expect(wrapper.emitted('update-balance')).toEqual([[42]]) - }) - }) - - describe('toggleShowList method', () => { - beforeEach(async () => { - wrapper.setProps({ showTransactionList: false }) - wrapper.find('gdd-send-stub').vm.$emit('toggle-show-list', true) - await wrapper.vm.$nextTick() - }) - - it('changes the value of property showTransactionList', () => { - expect(wrapper.vm.showTransactionList).toBeTruthy() - }) - }) }) }) diff --git a/frontend/src/views/Pages/AccountOverview.vue b/frontend/src/views/Pages/AccountOverview.vue index 41dcc7848..3ca7ef9af 100644 --- a/frontend/src/views/Pages/AccountOverview.vue +++ b/frontend/src/views/Pages/AccountOverview.vue @@ -2,24 +2,36 @@
- +
- + + + + +
- +
@@ -28,6 +40,17 @@ import GddStatus from './AccountOverview/GddStatus.vue' import GddSend from './AccountOverview/GddSend.vue' import GddTable from './AccountOverview/GddTable.vue' import GddTableFooter from './AccountOverview/GddTableFooter.vue' +import TransactionForm from './AccountOverview/GddSend/TransactionForm.vue' +import TransactionConfirmation from './AccountOverview/GddSend/TransactionConfirmation.vue' +import TransactionResult from './AccountOverview/GddSend/TransactionResult.vue' +import communityAPI from '../../apis/communityAPI.js' + +const EMPTY_TRANSACTION_DATA = { + email: '', + amount: 0, + memo: '', + target_date: '', +} export default { name: 'Overview', @@ -36,11 +59,16 @@ export default { GddSend, GddTable, GddTableFooter, + TransactionForm, + TransactionConfirmation, + TransactionResult, }, data() { return { - showTransactionList: true, timestamp: Date.now(), + transactionData: EMPTY_TRANSACTION_DATA, + error: false, + currentTransactionStep: 0, } }, props: { @@ -51,15 +79,30 @@ export default { }, transactionCount: { type: Number, default: 0 }, }, + computed: { + showContext() { + return this.currentTransactionStep === 0 + }, + }, methods: { - toggleShowList(bool) { - this.showTransactionList = bool + setTransaction(data) { + data.target_date = new Date(Date.now()).toISOString() + this.transactionData = { ...data } + this.currentTransactionStep = 1 }, - updateBalance(data) { - this.$emit('update-balance', data.ammount) + async sendTransaction() { + const result = await communityAPI.send(this.$store.state.sessionId, this.transactionData) + if (result.success) { + this.error = false + this.$emit('update-balance', this.transactionData.amount) + } else { + this.error = true + } + this.currentTransactionStep = 2 }, - updateTransactions() { - this.$emit('update-transactions') + onReset() { + this.transactionData = EMPTY_TRANSACTION_DATA + this.currentTransactionStep = 0 }, }, } diff --git a/frontend/src/views/Pages/AccountOverview/GddSend.spec.js b/frontend/src/views/Pages/AccountOverview/GddSend.spec.js index d7130aeca..c7005ddf5 100644 --- a/frontend/src/views/Pages/AccountOverview/GddSend.spec.js +++ b/frontend/src/views/Pages/AccountOverview/GddSend.spec.js @@ -1,29 +1,18 @@ import { mount } from '@vue/test-utils' import GddSend from './GddSend' -import Vuex from 'vuex' const localVue = global.localVue describe('GddSend', () => { let wrapper - const state = { - user: { - balance: 1234, - balance_gdt: 9876, - }, - } - - const store = new Vuex.Store({ - state, - }) - const mocks = { - // $n: jest.fn((n) => n), $t: jest.fn((t) => t), - $moment: jest.fn((m) => ({ - format: () => m, - })), + $store: { + state: { + sessionId: 1234, + }, + }, $i18n: { locale: jest.fn(() => 'en'), }, @@ -31,7 +20,7 @@ describe('GddSend', () => { } const Wrapper = () => { - return mount(GddSend, { localVue, store, mocks }) + return mount(GddSend, { localVue, mocks }) } describe('mount', () => { @@ -42,88 +31,5 @@ describe('GddSend', () => { it('renders the component', () => { expect(wrapper.find('div.gdd-send').exists()).toBeTruthy() }) - - describe('warning messages', () => { - it('has a warning message', () => { - expect(wrapper.find('div.alert-default').find('span').text()).toBe('form.attention') - }) - }) - - describe('transaction form', () => { - describe('email field', () => { - it('has an input field of type email', () => { - expect(wrapper.find('#input-group-1').find('input').attributes('type')).toBe('email') - }) - - it('has an envelope icon', () => { - expect(wrapper.find('#input-group-1').find('svg').attributes('aria-label')).toBe( - 'envelope', - ) - }) - - it('has a label form.receiver', () => { - expect(wrapper.findAll('div.text-left').at(0).text()).toBe('form.receiver') - }) - - it('has a placeholder "E-Mail"', () => { - expect(wrapper.find('#input-group-1').find('input').attributes('placeholder')).toBe( - 'E-Mail', - ) - }) - }) - - describe('ammount field', () => { - it('has an input field of type number', () => { - expect(wrapper.find('#input-group-2').find('input').attributes('type')).toBe('number') - }) - - it('has an GDD text icon', () => { - expect(wrapper.find('#input-group-2').find('div.h3').text()).toBe('GDD') - }) - - it('has a label form.amount', () => { - expect(wrapper.findAll('div.text-left').at(1).text()).toBe('form.amount') - }) - - it('has a placeholder "0.01"', () => { - expect(wrapper.find('#input-group-2').find('input').attributes('placeholder')).toBe( - '0.01', - ) - }) - }) - - describe('message text box', () => { - it('has an textarea field', () => { - expect(wrapper.find('#input-group-3').find('textarea').exists()).toBeTruthy() - }) - - it('has an chat-right-text icon', () => { - expect(wrapper.find('#input-group-3').find('svg').attributes('aria-label')).toBe( - 'chat right text', - ) - }) - - it('has a label form.memo', () => { - expect(wrapper.findAll('div.text-left').at(2).text()).toBe('form.memo') - }) - }) - - describe('cancel button', () => { - it('has a cancel button', () => { - expect(wrapper.find('button[type="reset"]').exists()).toBeTruthy() - }) - - it('has the text "form.cancel"', () => { - expect(wrapper.find('button[type="reset"]').text()).toBe('form.reset') - }) - - it.skip('clears the email field on click', async () => { - wrapper.find('#input-group-1').find('input').setValue('someone@watches.tv') - wrapper.find('button[type="reset"]').trigger('click') - await wrapper.vm.$nextTick() - expect(wrapper.vm.form.email).toBeNull() - }) - }) - }) }) }) diff --git a/frontend/src/views/Pages/AccountOverview/GddSend.vue b/frontend/src/views/Pages/AccountOverview/GddSend.vue index 7c78f993c..cfab0899a 100644 --- a/frontend/src/views/Pages/AccountOverview/GddSend.vue +++ b/frontend/src/views/Pages/AccountOverview/GddSend.vue @@ -1,346 +1,18 @@ - - diff --git a/frontend/src/views/Pages/AccountOverview/GddSend/QrCode.vue b/frontend/src/views/Pages/AccountOverview/GddSend/QrCode.vue new file mode 100644 index 000000000..edf027aef --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GddSend/QrCode.vue @@ -0,0 +1,65 @@ + + + diff --git a/frontend/src/views/Pages/AccountOverview/GddSend/TransactionConfirmation.vue b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionConfirmation.vue new file mode 100644 index 000000000..586e9104e --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionConfirmation.vue @@ -0,0 +1,48 @@ + + diff --git a/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.spec.js b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.spec.js new file mode 100644 index 000000000..61656f86c --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.spec.js @@ -0,0 +1,121 @@ +import { mount } from '@vue/test-utils' +import TransactionForm from './TransactionForm' + +const localVue = global.localVue + +describe('GddSend', () => { + let wrapper + + const mocks = { + $t: jest.fn((t) => t), + $moment: jest.fn((m) => ({ + format: () => m, + })), + $i18n: { + locale: jest.fn(() => 'en'), + }, + $n: jest.fn((n) => String(n)), + $store: { + state: { + email: 'user@example.org', + }, + }, + } + + const Wrapper = () => { + return mount(TransactionForm, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the component', () => { + expect(wrapper.find('div.transaction-form').exists()).toBeTruthy() + }) + + describe('warning messages', () => { + it('has a warning message', () => { + expect(wrapper.find('div.alert-default').find('span').text()).toBe('form.attention') + }) + }) + + describe('transaction form', () => { + describe('email field', () => { + it('has an input field of type email', () => { + expect(wrapper.find('#input-group-1').find('input').attributes('type')).toBe('email') + }) + + it('has an envelope icon', () => { + expect(wrapper.find('#input-group-1').find('svg').attributes('aria-label')).toBe( + 'envelope', + ) + }) + + it('has a label form.receiver', () => { + expect(wrapper.findAll('div.text-left').at(0).text()).toBe('form.receiver') + }) + + it('has a placeholder "E-Mail"', () => { + expect(wrapper.find('#input-group-1').find('input').attributes('placeholder')).toBe( + 'E-Mail', + ) + }) + }) + + describe('ammount field', () => { + it('has an input field of type number', () => { + expect(wrapper.find('#input-group-2').find('input').attributes('type')).toBe('number') + }) + + it('has an GDD text icon', () => { + expect(wrapper.find('#input-group-2').find('div.h3').text()).toBe('GDD') + }) + + it('has a label form.amount', () => { + expect(wrapper.findAll('div.text-left').at(1).text()).toBe('form.amount') + }) + + it('has a placeholder "0.01"', () => { + expect(wrapper.find('#input-group-2').find('input').attributes('placeholder')).toBe( + '0.01', + ) + }) + }) + + describe('message text box', () => { + it('has an textarea field', () => { + expect(wrapper.find('#input-group-3').find('textarea').exists()).toBeTruthy() + }) + + it('has an chat-right-text icon', () => { + expect(wrapper.find('#input-group-3').find('svg').attributes('aria-label')).toBe( + 'chat right text', + ) + }) + + it('has a label form.memo', () => { + expect(wrapper.findAll('div.text-left').at(2).text()).toBe('form.memo') + }) + }) + + describe('cancel button', () => { + it('has a cancel button', () => { + expect(wrapper.find('button[type="reset"]').exists()).toBeTruthy() + }) + + it('has the text "form.cancel"', () => { + expect(wrapper.find('button[type="reset"]').text()).toBe('form.reset') + }) + + it.skip('clears the email field on click', async () => { + wrapper.find('#input-group-1').find('input').setValue('someone@watches.tv') + wrapper.find('button[type="reset"]').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.vm.form.email).toBeNull() + }) + }) + }) + }) +}) diff --git a/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.vue b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.vue new file mode 100644 index 000000000..3967bbec0 --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionForm.vue @@ -0,0 +1,175 @@ + + + diff --git a/frontend/src/views/Pages/AccountOverview/GddSend/TransactionResult.vue b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionResult.vue new file mode 100644 index 000000000..11d52fef5 --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GddSend/TransactionResult.vue @@ -0,0 +1,38 @@ + +