Skip to content

Commit

Permalink
fixed #496
Browse files Browse the repository at this point in the history
  • Loading branch information
iasoon committed Mar 24, 2015
1 parent 1bbbab7 commit 2c91db5
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 26 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Expand Up @@ -134,6 +134,9 @@ gem 'airbrake'
# select2 is beautiful
gem 'select2-rails'

# Typeahead
gem 'twitter-typeahead-rails'

group :production do
gem 'mysql2' # Database
end
5 changes: 5 additions & 0 deletions Gemfile.lock
Expand Up @@ -253,6 +253,10 @@ GEM
ttfunk (1.4.0)
turbolinks (2.5.3)
coffee-rails
twitter-typeahead-rails (0.10.5)
actionpack (>= 3.1)
jquery-rails
railties (>= 3.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.1)
Expand Down Expand Up @@ -319,6 +323,7 @@ DEPENDENCIES
sqlite3
therubyracer
turbolinks
twitter-typeahead-rails
uglifier (>= 1.3.0)
webmock
whenever
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Expand Up @@ -15,4 +15,5 @@
//= require turbolinks
//= require ckeditor-jquery
//= require select2
//= require twitter/typeahead.min
//= require_tree .
189 changes: 189 additions & 0 deletions app/assets/stylesheets/typeahead.css
@@ -0,0 +1,189 @@
/*
* typehead.js-bootstrap3.less
* @version 0.2.3
* https://github.com/hyspace/typeahead.js-bootstrap3.less
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
.has-warning .twitter-typeahead .tt-input,
.has-warning .twitter-typeahead .tt-hint {
border-color: #8a6d3b;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-warning .twitter-typeahead .tt-input:focus,
.has-warning .twitter-typeahead .tt-hint:focus {
border-color: #66512c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
}
.has-error .twitter-typeahead .tt-input,
.has-error .twitter-typeahead .tt-hint {
border-color: #a94442;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-error .twitter-typeahead .tt-input:focus,
.has-error .twitter-typeahead .tt-hint:focus {
border-color: #843534;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
}
.has-success .twitter-typeahead .tt-input,
.has-success .twitter-typeahead .tt-hint {
border-color: #3c763d;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-success .twitter-typeahead .tt-input:focus,
.has-success .twitter-typeahead .tt-hint:focus {
border-color: #2b542c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
}
.input-group .twitter-typeahead:first-child .tt-input,
.input-group .twitter-typeahead:first-child .tt-hint {
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
}
.input-group .twitter-typeahead:last-child .tt-input,
.input-group .twitter-typeahead:last-child .tt-hint {
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
}
.input-group.input-group-sm .twitter-typeahead .tt-input,
.input-group.input-group-sm .twitter-typeahead .tt-hint {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
select.input-group.input-group-sm .twitter-typeahead .tt-input,
select.input-group.input-group-sm .twitter-typeahead .tt-hint {
height: 30px;
line-height: 30px;
}
textarea.input-group.input-group-sm .twitter-typeahead .tt-input,
textarea.input-group.input-group-sm .twitter-typeahead .tt-hint,
select[multiple].input-group.input-group-sm .twitter-typeahead .tt-input,
select[multiple].input-group.input-group-sm .twitter-typeahead .tt-hint {
height: auto;
}
.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-input,
.input-group.input-group-sm .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint {
border-radius: 0;
}
.input-group.input-group-sm .twitter-typeahead:first-child .tt-input,
.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint {
border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.input-group.input-group-sm .twitter-typeahead:last-child .tt-input,
.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
}
.input-group.input-group-lg .twitter-typeahead .tt-input,
.input-group.input-group-lg .twitter-typeahead .tt-hint {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.33;
border-radius: 6px;
}
select.input-group.input-group-lg .twitter-typeahead .tt-input,
select.input-group.input-group-lg .twitter-typeahead .tt-hint {
height: 46px;
line-height: 46px;
}
textarea.input-group.input-group-lg .twitter-typeahead .tt-input,
textarea.input-group.input-group-lg .twitter-typeahead .tt-hint,
select[multiple].input-group.input-group-lg .twitter-typeahead .tt-input,
select[multiple].input-group.input-group-lg .twitter-typeahead .tt-hint {
height: auto;
}
.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-input,
.input-group.input-group-lg .twitter-typeahead:not(:first-child):not(:last-child) .tt-hint {
border-radius: 0;
}
.input-group.input-group-lg .twitter-typeahead:first-child .tt-input,
.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint {
border-bottom-left-radius: 6px;
border-top-left-radius: 6px;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.input-group.input-group-lg .twitter-typeahead:last-child .tt-input,
.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
border-bottom-right-radius: 6px;
border-top-right-radius: 6px;
}
.twitter-typeahead {
width: 100%;
}
.input-group .twitter-typeahead {
display: table-cell !important;
float: left;
}
.twitter-typeahead .tt-hint {
color: #999999;
}
.twitter-typeahead .tt-input {
z-index: 2;
}
.twitter-typeahead .tt-input[disabled],
.twitter-typeahead .tt-input[readonly],
fieldset[disabled] .twitter-typeahead .tt-input {
cursor: not-allowed;
background-color: #eeeeee !important;
}
.tt-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
min-width: 160px;
width: 100%;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
font-size: 14px;
background-color: #ffffff;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
*border-right-width: 2px;
*border-bottom-width: 2px;
}
.tt-dropdown-menu .tt-suggestion {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.42857143;
color: #333333;
white-space: nowrap;
}
.tt-dropdown-menu .tt-suggestion.tt-cursor {
text-decoration: none;
outline: 0;
background-color: #f5f5f5;
color: #262626;
}
.tt-dropdown-menu .tt-suggestion.tt-cursor a {
color: #262626;
}
.tt-dropdown-menu .tt-suggestion p {
margin: 0;
}
56 changes: 38 additions & 18 deletions app/controllers/events_controller.rb
Expand Up @@ -90,30 +90,23 @@ def scan
authorize! :update, @event
end

def check_in
def scan_barcode
@event = Event.find params.require(:id)
authorize! :update, @event
barcode = params.require(:code)
@registration = @event.registrations.find_by barcode: barcode
check_in
end

@registration = @event.registrations.find_by_barcode barcode

if @registration
if not @registration.is_paid
flash.now[:warning] = "Person has not paid yet! Resting amount: €" + @registration.to_pay.to_s
elsif @registration.checked_in_at
flash.now[:warning] = "Person already checked in at " + view_context.nice_time(@registration.checked_in_at) + "!"
else
flash.now[:success] = "Person has been scanned!"
@registration.checked_in_at = Time.now
@registration.save!
end
else
flash.now[:error] = "Barcode not found"
end

render action: :scan
def scan_username
@event = Event.find params.require(:id)
authorize! :update, @event
username = params.require(:username)
@registration = @event.registrations.find_by name: username
check_in
end


def export_status
@event = Event.find params.require(:id)
authorize! :read, @event
Expand All @@ -132,4 +125,31 @@ def generate_export
@event.generate_xls
end

def list_registrations
@event = Event.find params.require(:id)
authorize! :read, @event
render json: @event.registrations
end

private
def check_in

if @registration
if not @registration.is_paid
flash.now[:warning] =
"Person has not paid yet! Resting amount: €" + @registration.to_pay.to_s
elsif @registration.checked_in_at
flash.now[:warning] = "Person already checked in at " +
view_context.nice_time(@registration.checked_in_at) + "!"
else
flash.now[:success] = "Person has been scanned!"
@registration.checked_in_at = Time.now
@registration.save!
end
else
flash.now[:error] = "Registration not found"
end
render action: :scan
end

end
58 changes: 51 additions & 7 deletions app/views/events/scan.html.erb
Expand Up @@ -27,18 +27,62 @@

<div class="row">
<div class="col-sm-6">
<%= form_tag check_in_event_path(@event),
url: scan_event_path(@event),
remote: false do %>
<div class="form-group">
<label for="code">Barcode:</label>
<input required class="form-control" id="code" name="code" type="text" autofocus="autofocus">
<%= form_tag scan_barcode_event_path(@event), remote: false do %>
<div class="input-group">
<div class="input-group">
<input required type="text" autofocus="autofocus"
class="form-control" placeholder="Barcode" name="code" id="code">
<span class="input-group-btn">
<button class="btn btn-primary" name="button" type="submit">
Submit
</button>
</span>
</div>
</div>
<% end %>

<br/>

<button class="btn btn-group btn-primary" name="button" type="submit">submit</button>
<%= form_tag scan_username_event_path(@event), remote: false do %>
<div class="input-group">
<div class="input-group">
<input required type="text" class="form-control typeahead"
placeholder="Ugent username" name="username" id="username">
<span class="input-group-btn">
<button class="btn btn-primary" name="button" type="submit">
Submit
</button>
</span>
</div>
</div>
<% end %>
<br/>

</div>
</div>

</div>
</div>

<script>
var registrations = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: '<%= list_registrations_event_path %>'

});

registrations.initialize();

$('#username').typeahead(
{
highlight: true,
minLength: 1
},
{
name: 'registrations',
displayKey: 'name',
source: registrations.ttAdapter()
}
);
</script>
4 changes: 3 additions & 1 deletion config/routes.rb
Expand Up @@ -47,7 +47,9 @@
member do
get 'statistics'
get 'scan'
post 'check_in'
get 'list_registrations'
post 'scan_barcode'
post 'scan_username'
end

resources :periods
Expand Down

1 comment on commit 2c91db5

@TomNaessens
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool :D Looking clean and good 👍

Please sign in to comment.