Working on surveys/attendee questions
Working on attendee check-in page
This commit is contained in:
parent
cef552ed04
commit
6127084c36
|
|
@ -45,7 +45,8 @@ class EventAttendeesController extends MyBaseController
|
|||
->where(function ($query) use ($searchQuery) {
|
||||
$query->where('orders.order_reference', 'like', $searchQuery.'%')
|
||||
->orWhere('attendees.first_name', 'like', $searchQuery.'%')
|
||||
->orWhere('attendees.email', 'like', $searchQuery.'%')
|
||||
->orWhere('attendees.email', 'like', $searchQuery.'%')
|
||||
->orWhere('attendees.reference', 'like', $searchQuery.'%')
|
||||
->orWhere('attendees.last_name', 'like', $searchQuery.'%');
|
||||
})
|
||||
->orderBy(($sort_by == 'order_reference' ? 'orders.' : 'attendees.').$sort_by, $sort_order)
|
||||
|
|
|
|||
|
|
@ -18,12 +18,20 @@ class EventCheckInController extends MyBaseController
|
|||
*/
|
||||
public function showCheckIn($event_id)
|
||||
{
|
||||
|
||||
|
||||
$data['event'] = Event::scope()->findOrFail($event_id);
|
||||
$data['attendees'] = $data['event']->attendees;
|
||||
|
||||
|
||||
return view('ManageEvent.CheckIn', $data);
|
||||
}
|
||||
|
||||
public function showQRCodeModal(Request $request, $event_id)
|
||||
{
|
||||
return view('ManageEvent.Modals.QrcodeCheckIn');
|
||||
}
|
||||
|
||||
/**
|
||||
* Search attendees
|
||||
*
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ class EventCheckoutController extends Controller
|
|||
$event = Event::findOrFail($ticket_order['event_id']);
|
||||
$attendee_increment = 1;
|
||||
$mirror_buyer_info = isset($request_data['mirror_buyer_info']) ? ($request_data['mirror_buyer_info'] == 'on') : false;
|
||||
$ticket_questions = $request_data['ticket_holder_questions'];
|
||||
$ticket_questions = isset($request_data['ticket_holder_questions']) ? $request_data['ticket_holder_questions'] : [];
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use App\Models\Question;
|
|||
use App\Models\QuestionAnswer;
|
||||
use App\Models\QuestionType;
|
||||
use Illuminate\Http\Request;
|
||||
use Excel;
|
||||
|
||||
/*
|
||||
Attendize.com - Event Management & Ticketing
|
||||
|
|
@ -222,7 +223,6 @@ class EventSurveyController extends MyBaseController
|
|||
*/
|
||||
public function showEventQuestionAnswers(Request $request, $event_id, $question_id)
|
||||
{
|
||||
|
||||
$answers = QuestionAnswer::scope()->where('question_id', $question_id)->get();
|
||||
$question = Question::scope()->withTrashed()->find($question_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -609,6 +609,10 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
|
|||
'uses' => 'EventCheckInController@postCheckInAttendee',
|
||||
]);
|
||||
|
||||
Route::get('{event_id}/check_in_qrcode', [
|
||||
'as' => 'showQRCodeModal',
|
||||
'uses' => 'EventCheckInController@showQRCodeModal'
|
||||
]);
|
||||
|
||||
/*
|
||||
* -------
|
||||
|
|
|
|||
|
|
@ -51,6 +51,16 @@ class Event extends MyBaseModel
|
|||
return $this->belongsToMany('\App\Models\Question', 'event_question');
|
||||
}
|
||||
|
||||
/**
|
||||
* The questions associated with the event.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function questions_with_tashed()
|
||||
{
|
||||
return $this->belongsToMany('\App\Models\Question', 'event_question')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* The attendees associated with the event.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Question extends MyBaseModel
|
|||
|
||||
public function answers()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Answers');
|
||||
return $this->hasMany('\App\Models\QuestionAnswer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -94,6 +94,6 @@ a:hover{
|
|||
}
|
||||
|
||||
#v{
|
||||
width: 300px;
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
{!! HTML::style('assets/stylesheet/application.css') !!}
|
||||
{!! HTML::script('vendor/jquery/jquery.js') !!}
|
||||
{!! HTML::style('assets/stylesheet/qrcode-check-in.css') !!}
|
||||
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
|
||||
|
||||
|
|
@ -40,6 +41,11 @@
|
|||
:-ms-input-placeholder { /* Internet Explorer 10+ */
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background-color: #0384a6;
|
||||
}
|
||||
|
||||
.attendeeList .container {
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
|
|
@ -65,7 +71,7 @@
|
|||
}
|
||||
|
||||
header {
|
||||
background: #6784DB;
|
||||
background-color: #FFF;
|
||||
padding: 10px 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
|
@ -93,11 +99,20 @@
|
|||
height: 40px;
|
||||
}
|
||||
|
||||
.qr_search {
|
||||
height: 40px;
|
||||
background: #FFF;
|
||||
color: #000;
|
||||
font-size: 25px;
|
||||
border: none;
|
||||
border-right: 1px solid #999;
|
||||
}
|
||||
|
||||
.clearSearch {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 8px;
|
||||
right: 25px;
|
||||
font-size: 20px;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -149,6 +164,10 @@
|
|||
|
||||
@media (min-width: 100px) and (max-width: 767px) {
|
||||
|
||||
header {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
section.attendeeList {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
|
@ -300,6 +319,12 @@
|
|||
search();
|
||||
});
|
||||
|
||||
|
||||
$('.qr_search').on('click', function(e) {
|
||||
load();
|
||||
$('#QrModal').modal('show');
|
||||
});
|
||||
|
||||
$("input#search").on("keyup", function(e) {
|
||||
clearTimeout($.data(this, 'timer'));
|
||||
var search_string = $(this).val();
|
||||
|
|
@ -319,6 +344,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div class="menuToggle hide">
|
||||
<i class="ico-menu"></i>
|
||||
|
|
@ -327,11 +353,19 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="attendee_input_wrap">
|
||||
{!! Form::text('attendees_q', null, [
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button title="Scan QR Code" class="btn btn-default qr_search" type="button"><i class="ico-qrcode"></i> </button>
|
||||
</span>
|
||||
{!! Form::text('attendees_q', null, [
|
||||
'class' => 'form-control attendee_search',
|
||||
'id' => 'search',
|
||||
'placeholder' => 'Search by Attendee Name, Order Reference, Attendee Reference... '
|
||||
]) !!}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<span class="clearSearch ico-cancel"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -345,9 +379,9 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="attendee_list">
|
||||
<h3 class="attendees_title">
|
||||
<h4 class="attendees_title">
|
||||
All Attendees
|
||||
</h3>
|
||||
</h4>
|
||||
<ul class="list-group" id="attendee_list">
|
||||
Loading Attendees...
|
||||
</ul>
|
||||
|
|
@ -361,10 +395,221 @@
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
23/145 attendees checked in.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{{--QR Modal--}}
|
||||
<div role="dialog" id="QrModal" class="modal fade" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header text-center">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h3 class="modal-title">
|
||||
<i class="ico-qrcode"></i>
|
||||
Check-in
|
||||
</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if(session()->has('success_message'))
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3 col-xs-12">
|
||||
<div class="alert alert-success alert-dismissible text-center" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<p><strong>Success</strong>: {{ session('success_message') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div id="outdiv">
|
||||
</div>
|
||||
<p><a onclick="event.preventDefault(); workingAway = false; load();" href="{{ Request::url() }}"><i class="fa fa-refresh"></i> Scan another ticket</a></p>
|
||||
<div id="result"></div>
|
||||
<canvas id="qr-canvas" width="800" height="600"></canvas>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{!! Form::button('Close', ['class'=>"btn modal-close btn-danger",'data-dismiss'=>'modal']) !!}
|
||||
</div>
|
||||
</div><!-- /end modal content-->
|
||||
</div>
|
||||
</div>
|
||||
{{-- /END QR Modal--}}
|
||||
|
||||
|
||||
{!! HTML::script('vendor/qrcode-scan/llqrcode.js') !!}
|
||||
|
||||
{{--QR JS - THIS WILL BE MOVED--}}
|
||||
<script>
|
||||
// QRCODE reader Copyright 2011 Lazar Laszlo
|
||||
// http://www.webqr.com
|
||||
|
||||
var workingAway = false;
|
||||
var gCtx = null;
|
||||
var gCanvas = null;
|
||||
var c=0;
|
||||
var stype=0;
|
||||
var gUM=false;
|
||||
var webkit=false;
|
||||
var moz=false;
|
||||
var v=null;
|
||||
|
||||
var beepSound = new Audio('/mp3/beep.mp3');
|
||||
|
||||
var vidhtml = '<video id="v" autoplay></video>';
|
||||
|
||||
function initCanvas(w,h)
|
||||
{
|
||||
gCanvas = document.getElementById("qr-canvas");
|
||||
gCanvas.style.width = w + "px";
|
||||
gCanvas.style.height = h + "px";
|
||||
gCanvas.width = w;
|
||||
gCanvas.height = h;
|
||||
gCtx = gCanvas.getContext("2d");
|
||||
gCtx.clearRect(0, 0, w, h);
|
||||
}
|
||||
|
||||
|
||||
function captureToCanvas() {
|
||||
if(stype!=1)
|
||||
return;
|
||||
if(gUM)
|
||||
{
|
||||
try{
|
||||
gCtx.drawImage(v,0,0);
|
||||
try{
|
||||
qrcode.decode();
|
||||
}
|
||||
catch(e){
|
||||
console.log(e);
|
||||
setTimeout(captureToCanvas, 500);
|
||||
};
|
||||
}
|
||||
catch(e){
|
||||
console.log(e);
|
||||
setTimeout(captureToCanvas, 500);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function htmlEntities(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
function read(qrcode_token)
|
||||
{
|
||||
if(workingAway) {
|
||||
return;
|
||||
}
|
||||
|
||||
workingAway = true;
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '{{ route('postQRCodeCheckInAttendee', ['event_id' => $event->id]) }}',
|
||||
data: {qrcode_token: htmlEntities(qrcode_token)},
|
||||
cache: false,
|
||||
complete: function(){
|
||||
beepSound.play();
|
||||
},
|
||||
error: function() {
|
||||
},
|
||||
success: function(response) {
|
||||
document.getElementById("result").innerHTML = "<b>" + response.message +"</b>";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isCanvasSupported(){
|
||||
var elem = document.createElement('canvas');
|
||||
return !!(elem.getContext && elem.getContext('2d'));
|
||||
}
|
||||
|
||||
function success(stream) {
|
||||
if(webkit)
|
||||
v.src = window.webkitURL.createObjectURL(stream);
|
||||
else
|
||||
if(moz)
|
||||
{
|
||||
v.mozSrcObject = stream;
|
||||
v.play();
|
||||
}
|
||||
else
|
||||
v.src = stream;
|
||||
gUM=true;
|
||||
setTimeout(captureToCanvas, 500);
|
||||
}
|
||||
|
||||
function error(error) {
|
||||
gUM=false;
|
||||
return;
|
||||
}
|
||||
|
||||
function load()
|
||||
{
|
||||
if(isCanvasSupported() && window.File && window.FileReader)
|
||||
{
|
||||
initCanvas(800, 600);
|
||||
qrcode.callback = read;
|
||||
setwebcam();
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("mainbody").style.display="inline";
|
||||
document.getElementById("mainbody").innerHTML='<p id="mp1">Attendize Checkpoint Manager for HTML5 capable browsers</p><br>'+
|
||||
'<br><p id="mp2">sorry your browser is not supported</p><br><br>'+
|
||||
'<p id="mp1">try <a href="http://www.mozilla.com/firefox"><img src="/assets/images/firefox.png"/></a> or <a href="http://chrome.google.com"><img src="/assets/images/chrome_logo.gif"/></a> or <a href="http://www.opera.com"><img src="/assets/images/Opera-logo.png"/></a></p>';
|
||||
}
|
||||
}
|
||||
|
||||
function setwebcam()
|
||||
{
|
||||
// document.getElementById("help-text").style.display = "block";
|
||||
document.getElementById("result").innerHTML='Scanning <i class="fa fa-spinner fa-spin"></i>';
|
||||
if(stype==1)
|
||||
{
|
||||
setTimeout(captureToCanvas, 500);
|
||||
return;
|
||||
}
|
||||
var n=navigator;
|
||||
document.getElementById("outdiv").innerHTML = vidhtml;
|
||||
v=document.getElementById("v");
|
||||
|
||||
if(n.getUserMedia)
|
||||
n.getUserMedia({video: true, audio: false}, success, error);
|
||||
else
|
||||
if(n.webkitGetUserMedia)
|
||||
{
|
||||
webkit=true;
|
||||
n.webkitGetUserMedia({video:true, audio: false}, success, error);
|
||||
}
|
||||
else
|
||||
if(n.mediaDevices.getUserMedia)
|
||||
{
|
||||
moz=true;
|
||||
n.mozGetUserMedia({video: true, audio: false}, success, error);
|
||||
}
|
||||
else
|
||||
if(n.mozGetUserMedia)
|
||||
{
|
||||
moz=true;
|
||||
n.mozGetUserMedia({video: true, audio: false}, success, error);
|
||||
}
|
||||
|
||||
|
||||
stype=1;
|
||||
setTimeout(captureToCanvas, 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
{!! HTML::script('assets/javascript/backend.js') !!}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
<div role="dialog" id="{{ $modal_id }}" class="modal fade" style="display: none;">
|
||||
<div role="dialog" class="modal fade" style="display: none;">
|
||||
{!! Form::open(['url' => route('postCreateEventQuestion', ['event_id'=>$event->id]), 'id' => 'edit-question-form', 'class' => 'ajax']) !!}
|
||||
<script id="question-option-template" type="text/template">
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div role="dialog" id="{{ $modal_id }}" class="modal fade" style="display: none;">
|
||||
<div role="dialog" class="modal fade" style="display: none;">
|
||||
{!! Form::model($question, ['url' => route('postEditEventQuestion', ['event_id' => $event->id, 'question_id' => $question->id]), 'id' => 'edit-question-form', 'class' => 'ajax']) !!}
|
||||
<script id="question-option-template" type="text/template">
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@
|
|||
<div class="modal-header text-center">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h3 class="modal-title">
|
||||
|
||||
Q: {{ $question->title }}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@if(count($answers))
|
||||
<div class="table-responsive">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -30,8 +29,12 @@
|
|||
@foreach($answers as $answer)
|
||||
<tr>
|
||||
<td>
|
||||
{{ $answer->attendee->full_name }}<br>
|
||||
<a href="javascript:void(0);">{{ $answer->attendee->email }}</a><br>
|
||||
|
||||
{{ $answer->attendee->full_name }}
|
||||
@if($answer->attendee->is_cancelled)
|
||||
(<span title="This attendee has been cancelled" class="text-danger">Cancelled</span>)
|
||||
@endif<br>
|
||||
<a title="Go to attendee: {{ $answer->attendee->full_name }}" href="{{route('showEventAttendees', ['event_id' => $answer->attendee->event_id, 'q' => $answer->attendee->reference])}}">{{ $answer->attendee->email }}</a><br>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
|
@ -46,6 +49,14 @@
|
|||
</table>
|
||||
|
||||
</div>
|
||||
@else
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-info">
|
||||
Sorry, there's no answers to this question yet.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
|
||||
<div class="modal-footer">
|
||||
{!! Form::button('Close', ['class'=>"btn modal-close btn-danger",'data-dismiss'=>'modal']) !!}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,8 @@
|
|||
Attendize QRCode Check In: {{ $event->title }}
|
||||
</title>
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
|
||||
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700' rel='stylesheet' type='text/css'>
|
||||
{!! HTML::style('assets/stylesheet/qrcode-check-in.css') !!}
|
||||
{!! HTML::style('assets/stylesheet/application.css') !!}
|
||||
{!! HTML::style('assets/stylesheet/qrcode-check-in.css') !!}
|
||||
{!! HTML::script('vendor/jquery/jquery.js') !!}
|
||||
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
|
||||
|
|
@ -86,7 +84,7 @@
|
|||
<footer id="footer">
|
||||
<br>
|
||||
<br>
|
||||
<h5 align="center" style="color: #6D717A;">© <a href="https://www.attendize.com/">Attendize</a> {{ date('Y') }} · All Rights Reserved.</h5>
|
||||
<h5 align="center" style="color: #6D717A;">Powered By <a href="https://www.attendize.com/">Attendize</a> </h5>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ Event Surveys
|
|||
<th>
|
||||
Applies to tickets
|
||||
</th>
|
||||
<th>
|
||||
# Replies
|
||||
</th>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
|
|
@ -99,6 +102,13 @@ Event Surveys
|
|||
<td>
|
||||
{{implode(', ', array_column($question->tickets->toArray(), 'title'))}}
|
||||
</td>
|
||||
<td>
|
||||
<a class="loadModal" data-modal-id="showEventQuestionAnswers" href="javascript:void(0);"
|
||||
data-href="{{route('showEventQuestionAnswers', ['event_id' => $event->id, 'question_id' => $question->id])}}">
|
||||
{{ $question->answers->count() }}
|
||||
</a>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-xs btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Action <span class="caret"></span></button>
|
||||
|
|
|
|||
|
|
@ -142,5 +142,6 @@
|
|||
@yield('foot')
|
||||
|
||||
@include('Shared.Partials.GlobalFooterJS')
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue