diff --git a/app/assets/javascripts/components/transaction_form.jsx.coffee b/app/assets/javascripts/components/transaction_form.jsx.coffee
index 1a54e1c..2aa6c24 100644
--- a/app/assets/javascripts/components/transaction_form.jsx.coffee
+++ b/app/assets/javascripts/components/transaction_form.jsx.coffee
@@ -1,4 +1,4 @@
-{ button, div, h3, input, option, select } = React.DOM
+{ button, div, form, h3, input, option, select } = React.DOM
Action = React.createFactory React.createClass
buttonClass: (b) ->
@@ -22,23 +22,21 @@ Amount = React.createFactory React.createClass
@props.setAmount ref.target.value
format: (ref) ->
t = ref.target
- t.value = parseFloat(t.value).toFixed(2)
+ t.value = parseFloat(t.value).toFixed(2) if t.value
render: ->
div className: 'row',
div className: 'col-xs-4',
div className: 'input-group',
div className: 'input-group-addon', '€'
input {
- type: 'number',
className: 'form-control input-lg',
- placeholder: '0.00',
+ name: 'transaction[euros]'
+ onBlur: @format,
onChange: @onChange,
- onBlur: @format
+ placeholder: '0.00',
+ type: 'number',
}
-Suggestions = React.createFactory React.createClass
- render: ->
-
Peer = React.createFactory React.createClass
onChange: (ref) ->
@props.setPeer ref.target.value
@@ -62,7 +60,13 @@ Peer = React.createFactory React.createClass
div className: 'row',
div className: 'col-xs-4',
div className: 'suggestions-wrapper',
- input type: 'text', className: @inputClass(options.length), onChange: @onChange, placeholder: 'Zeus member', value: (@props.peer || '')
+ input {
+ className: @inputClass(options.length),
+ onChange: @onChange,
+ placeholder: 'Zeus member',
+ type: 'text',
+ value: (@props.peer || '')
+ }
if options.length != 0
div className: 'suggestions',
@options().map (s, i) =>
@@ -75,53 +79,135 @@ Message = React.createFactory React.createClass
render: ->
div className: 'row',
div className: 'col-xs-8',
- input type: 'text', className: 'form-control input-lg', onChange: @onChange, placeholder: 'Message'
+ input {
+ className: 'form-control input-lg',
+ name: 'transaction[message]',
+ onChange: @onChange,
+ placeholder: 'Message'
+ type: 'text',
+ }
Submit = React.createFactory React.createClass
render: ->
+ { onClick } = @props
div className: 'row',
div className: 'col-xs-4 col-xs-offset-4',
- button type: 'submit', onClick: @props.onClick, className: 'btn btn-default btn-lg form-control', 'Confirm'
+ button {
+ className: 'btn btn-default btn-lg btn-block',
+ onClick: onClick,
+ type: 'submit',
+ }, 'Confirm'
Step = React.createFactory React.createClass
render: ->
+ { error } = @props
div className: 'form-step',
div className: 'form-step-counter', @props.step
div className: 'form-step-content',
- div className: 'form-step-title', @props.title
+ div className: 'form-step-title',
+ @props.title,
+ div className: 'form-step-error',
+ error
div className: 'clear-both'
@props.children
div className: 'clear-both'
@TransactionForm = React.createClass
getInitialState: ->
- giving: null, amount: null, peer: null, message: null
+ step: 1, giving: null, amount: null, peer: null, message: null
setAction: (b) ->
@setState giving: b
+ @setState step: 2 unless @state.step > 1
setAmount: (a) ->
@setState amount: a
+ @setState step: 3 unless @state.step > 2
setPeer: (p) ->
@setState peer: p
+ @setState step: 4 unless @state.step > 3
setMessage: (m) ->
@setState message: m
+ @setState step: 5 unless @state.step > 4
submit: (e) ->
- console.log 'submit'
- render: ->
+ e.preventDefault()
+
+ { giving, peer } = @state
+ { user } = @props
+
+ errors = @errors()
+ if Object.keys(errors).length != 0
+ return
+
+ if giving
+ debtor = user.name
+ creditor = peer
+ else
+ debtor = peer
+ creditor = user.name
+
+ $('')
+ .attr('name', 'transaction[debtor]')
+ .attr('value', debtor)
+ .attr('type', 'hidden')
+ .appendTo(@refs.form)
+ $('')
+ .attr('name', 'transaction[creditor]')
+ .attr('value', creditor)
+ .attr('type', 'hidden')
+ .appendTo(@refs.form)
+
+ @refs.form.submit()
+ errors: ->
{ amount, giving, message, peer } = @state
- { peers } = @props
+ { peers, user } = @props
+
+ errors = {}
+
+ errors['giving'] = 'Please select an action.' unless giving != null
+
+ unless amount
+ errors['amount'] = 'Please fill in an amount.'
+ else if parseFloat(amount) <= 0
+ errors['amount'] = 'Please fill in a positive number.'
+
+ unless message && message != ""
+ errors['message'] = 'Please fill in a message.'
+
+ unless peer && peers.includes(peer) && peer != user
+ errors['peer'] = 'Please select a valid Zeus member.'
+
+ errors
+ render: ->
+ { step, amount, giving, message, peer } = @state
+ { peers } = @props
+
+ errors = @errors()
+
div id: 'transaction-form',
h3 null, 'Transfer some money'
- Step step: 1, title: 'What do you want to do?',
- Action giving: giving, setAction: @setAction
- if giving != null
- Step step: 2, title: 'How much do you want to give?',
- Amount setAmount: @setAmount
- if amount != null
- Step step: 3, title: 'Who do you want to give it to?',
- Peer peer: peer, peers: peers, setPeer: @setPeer
- if peer != null
- Step step: 4, title: 'Why do you want to give this?',
- Message setMessage: @setMessage
- if message != null
- Submit null
+ form ref: 'form', action: '/transactions', acceptCharset: 'UTF-8', method: 'post',
+ Step step: 1, title: 'What do you want to do?',
+ Action giving: giving, setAction: @setAction
+ if step >= 2
+ Step {
+ step: 2,
+ title: "How much do you want to #{if giving then 'give' else 'receive'}?",
+ error: errors['amount'] if step > 2
+ },
+ Amount setAmount: @setAmount
+ if step >= 3
+ Step {
+ step: 3,
+ title: "Who do you want to #{if giving then 'give it to' else 'receive it from'}?",
+ error: errors['peer'] if step > 3
+ },
+ Peer peer: peer, peers: peers, setPeer: @setPeer
+ if step >= 4
+ Step {
+ step: 4,
+ title: "Why do you want to #{if giving then 'give' else 'receive'} this?",
+ error: errors['message'] if step > 4
+ },
+ Message setMessage: @setMessage
+ if step >= 5
+ Submit onClick: @submit
div className: 'clear-both'
diff --git a/app/assets/stylesheets/transaction_form.scss b/app/assets/stylesheets/transaction_form.scss
index 3617b15..e92de6e 100644
--- a/app/assets/stylesheets/transaction_form.scss
+++ b/app/assets/stylesheets/transaction_form.scss
@@ -31,7 +31,13 @@ $step-width: 26px;
.form-step-title {
display: inline-block;
font-weight: bold;
- margin-bottom: 10px;
+ margin-bottom: 5px;
+ }
+
+ .form-step-error {
+ color: red;
+ font-size: 11px;
+ height: 15px;
}
.form-options {
diff --git a/app/controllers/concerns/transactions_query.rb b/app/controllers/concerns/transactions_query.rb
index bd87edc..2311809 100644
--- a/app/controllers/concerns/transactions_query.rb
+++ b/app/controllers/concerns/transactions_query.rb
@@ -6,7 +6,7 @@ class TransactionsQuery
@transactions = Arel::Table.new(:transactions)
@perspectived = Arel::Table.new(:perspectived_transactions)
@peers = Arel::Table.new(:users).alias('peers')
- @arel_table = Arel::Table.new(@user.name.concat('_transactions'))
+ @arel_table = Arel::Table.new("#{@user.name}_transactions")
end
def query
diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb
index d4d1a45..4227c7e 100644
--- a/app/controllers/transactions_controller.rb
+++ b/app/controllers/transactions_controller.rb
@@ -10,21 +10,21 @@ class TransactionsController < ApplicationController
@transaction = Transaction.new(transaction_params)
@transaction.reverse if @transaction.amount < 0
- if can? :create, @transaction
- if @transaction.save
- render json: @transaction, status: :created
- else
- render json: @transaction.errors.full_messages,
- status: :unprocessable_entity
+ unless can? :create, @transaction
+ @transaction = Request.new @transaction.info
+ authorize!(:create, @transaction)
+ end
+
+ if @transaction.save
+ respond_to do |format|
+ format.html { redirect_to root_path }
+ format.json { render json: @transaction, status: :created }
end
else
- request = Request.new @transaction.info
- authorize!(:create, request)
- if request.save
- render json: request, status: :created
- else
- render json: request.errors.full_messages,
- status: :unprocessable_entity
+ respond_to do |format|
+ format.html { redirect_to root_path }
+ format.json { render json: @transaction.errors.full_messages,
+ status: :unprocessable_entity }
end
end
end
diff --git a/app/models/concerns/base_transaction.rb b/app/models/concerns/base_transaction.rb
index ece8add..80fb884 100644
--- a/app/models/concerns/base_transaction.rb
+++ b/app/models/concerns/base_transaction.rb
@@ -8,7 +8,9 @@ module BaseTransaction
belongs_to :creditor, class_name: 'User'
belongs_to :issuer, polymorphic: true
- validates :amount, numericality: { greater_than: 0 }
+ validates :debtor, presence: true
+ validates :creditor, presence: true
+ validates :amount, numericality: { greater_than: 0 }
validate :different_debtor_creditor
end