Added ability to order tickets (closes #214)
This commit is contained in:
parent
16a125ff66
commit
cc0c22a743
|
|
@ -253,4 +253,28 @@ class EventTicketsController extends MyBaseController
|
|||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the sort order of tickets
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function postUpdateTicketsOrder(Request $request)
|
||||
{
|
||||
$ticket_ids = $request->get('ticket_ids');
|
||||
$sort = 1;
|
||||
|
||||
foreach ($ticket_ids as $ticket_id) {
|
||||
$ticket = Ticket::scope()->find($ticket_id);
|
||||
$ticket->sort_order = $sort;
|
||||
$ticket->save();
|
||||
$sort++;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => 'Ticket Order Successfully Updated',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class EventViewController extends Controller
|
|||
|
||||
$data = [
|
||||
'event' => $event,
|
||||
'tickets' => $event->tickets()->where('is_hidden', 0)->orderBy('created_at', 'desc')->get(),
|
||||
'tickets' => $event->tickets()->where('is_hidden', 0)->orderBy('sort_order', 'asc')->get(),
|
||||
'is_embedded' => 0,
|
||||
];
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class EventViewEmbeddedController extends Controller
|
|||
|
||||
$data = [
|
||||
'event' => $event,
|
||||
'tickets' => $event->tickets()->where('is_hidden', 0)->orderBy('created_at', 'desc')->get(),
|
||||
'tickets' => $event->tickets()->where('is_hidden', 0)->orderBy('sort_order', 'asc')->get(),
|
||||
'is_embedded' => '1',
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -364,6 +364,10 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
|
|||
'as' => 'postPauseTicket',
|
||||
'uses' => 'EventTicketsController@postPauseTicket',
|
||||
]);
|
||||
Route::post('{event_id}/tickets/order', [
|
||||
'as' => 'postUpdateTicketsOrder',
|
||||
'uses' => 'EventTicketsController@postUpdateTicketsOrder',
|
||||
]);
|
||||
|
||||
/*
|
||||
* Ticket questions
|
||||
|
|
|
|||
|
|
@ -475,4 +475,4 @@ body {
|
|||
.minicolors-theme-semanticui input {
|
||||
text-indent: 30px;
|
||||
}
|
||||
.page-title .title .organiser_logo{position:absolute;height:45px;right:20px;top:5px;bottom:5px}.page-title .title .organiser_logo img{max-height:45px}#calendar{border:1px solid #ddd;background:#fff}#calendar .fc-button{background:transparent;border:none;color:inherit;box-shadow:none}#calendar .fc-event{border-color:#fff;-webkit-border-radius:0;border-radius:0;padding:2px;transition:none}#calendar .fc-toolbar{text-align:center;margin-bottom:0em;padding:7px}#calendar h2{font-size:15px;text-transform:uppercase;margin-top:6px}#calendar .fc-view{margin:-1px}.nav li.nav-button a span{padding:10px}.event.panel{margin-top:10px}.event .event-date{border:1px solid #fff;padding-bottom:9px;padding-top:7px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,0.1);width:46px;position:absolute;background-color:#ffffff;top:-13px;border-color:#404675;color:#666}.event .event-date .day{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:500;margin:-2px auto -6px auto}.event .event-date .month{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:10px;font-weight:500;margin:-2px auto 0 auto}.event .event-meta{margin:0;padding:0;margin-left:60px;height:55px;margin-top:10px;color:#ffffff}.event .event-meta li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;list-style:none;font-size:12px}.event .event-meta li a{color:#ffffff}.event .event-meta li.event-title a{font-size:16px}.event .event-meta li.event-organiser a{font-weight:bold}.event .panel-title{height:60px;padding:10px}.event .panel-title a{margin:0;height:40px;display:table-cell;vertical-align:middle;text-indent:50px}.stat-box{padding:20px;background-color:#fff;color:#2e3254;text-align:center;margin-bottom:10px;border:1px solid #e0e0e0}.stat-box h3{margin-bottom:5px;margin-top:0;font-weight:200}.stat-box span{text-transform:uppercase;font-weight:lighter;color:#aeb2d3}.top_of_page_alert{border:none;margin:0;text-align:center;border-bottom:5px solid}.v-align-text{text-align:center;position:relative;top:50%;-ms-transform:translateY(-50%);-wekbit-transform:translateY(-50%);transform:translateY(-50%)}@media (max-width:992px){.page-header>[class*=" col-"],.page-header>[class^="col-"]{margin-bottom:10px}}@media (max-width:480px){.btn-group-responsive{margin-bottom:-10px;float:none !important;display:block !important}.btn-group-responsive .btn{width:100%;padding-left:0;padding-right:0;margin-bottom:10px}.btn-group-responsive .pull-left,.btn-group-responsive .pull-right{float:none !important}}label.required::after{content:'*';color:red;padding-left:3px;font-size:9px}.hasDatepicker[disabled],.hasDatepicker[readonly],fieldset[disabled] .hasDatepicker{cursor:pointer !important;background-color:#fff !important;opacity:1}.more-options{display:none}.col-sort{color:#fff}.col-sort :hover{color:#fff}.pac-container{z-index:9999}.dtpicker-overlay{z-index:9999}.dtpicker-close{display:none}.dtpicker-header .dtpicker-title{color:#AFAFAF;text-align:center;font-size:18px;font-weight:normal}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em .2em;color:#404675;text-align:center;font-size:1.4em}.dtpicker-buttonCont .dtpicker-button{background:#404675;border-radius:0}.dtpicker-content{border-radius:0}.sidebar-open-ltr body{overflow-x:hidden}.order_options .event_count{font-weight:bold;color:#777}.well{background-color:#f9f9f9;box-shadow:none}.input-group-btn select{width:115px !important;border-left:0;font-size:12px}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}input[readonly]{background-color:white !important;cursor:text !important}html.working{cursor:progress}.order_options{padding:10px 0}.minicolors-theme-default.minicolors{width:auto;display:block}.minicolors-theme-default .minicolors-input{padding-left:35px;height:auto;width:100%;display:block}.minicolors-theme-default .minicolors-swatch{top:8px;left:6px;width:18px;height:18px}.pagination>.active>span,.pagination>.active:focus>span,.pagination>.active:hover>span,.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default,.pagination>li>a:hover,.pager>li>a:hover,.pagination>li>span:hover,.pager>li>span:hover,.pagination>li>a:focus,.pager>li>a:focus,.pagination>li>span:focus,.pager>li>span:focus{color:#ffffff !important}.btn-default .caret{border-top-color:#fff}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-right:none}.modal-backdrop{background:url(../images/background.png) repeat;background-color:#2e3254}
|
||||
.page-title .title .organiser_logo{position:absolute;height:45px;right:20px;top:5px;bottom:5px}.page-title .title .organiser_logo img{max-height:45px}#calendar{border:1px solid #ddd;background:#fff}#calendar .fc-button{background:transparent;border:none;color:inherit;box-shadow:none}#calendar .fc-event{border-color:#fff;-webkit-border-radius:0;border-radius:0;padding:2px;transition:none}#calendar .fc-toolbar{text-align:center;margin-bottom:0em;padding:7px}#calendar h2{font-size:15px;text-transform:uppercase;margin-top:6px}#calendar .fc-view{margin:-1px}.nav li.nav-button a span{padding:10px}.event.panel{margin-top:10px}.event .event-date{border:1px solid #fff;padding-bottom:9px;padding-top:7px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,0.1);width:46px;position:absolute;background-color:#ffffff;top:-13px;border-color:#404675;color:#666}.event .event-date .day{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:500;margin:-2px auto -6px auto}.event .event-date .month{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:10px;font-weight:500;margin:-2px auto 0 auto}.event .event-meta{margin:0;padding:0;margin-left:60px;height:55px;margin-top:10px;color:#ffffff}.event .event-meta li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;list-style:none;font-size:12px}.event .event-meta li a{color:#ffffff}.event .event-meta li.event-title a{font-size:16px}.event .event-meta li.event-organiser a{font-weight:bold}.event .panel-title{height:60px;padding:10px}.event .panel-title a{margin:0;height:40px;display:table-cell;vertical-align:middle;text-indent:50px}.stat-box{padding:20px;background-color:#fff;color:#2e3254;text-align:center;margin-bottom:10px;border:1px solid #e0e0e0}.stat-box h3{margin-bottom:5px;margin-top:0;font-weight:200}.stat-box span{text-transform:uppercase;font-weight:lighter;color:#aeb2d3}.top_of_page_alert{border:none;margin:0;text-align:center;border-bottom:5px solid}.v-align-text{text-align:center;position:relative;top:50%;-ms-transform:translateY(-50%);-wekbit-transform:translateY(-50%);transform:translateY(-50%)}@media (max-width:992px){.page-header>[class*=" col-"],.page-header>[class^="col-"]{margin-bottom:10px}}@media (max-width:480px){.btn-group-responsive{margin-bottom:-10px;float:none !important;display:block !important}.btn-group-responsive .btn{width:100%;padding-left:0;padding-right:0;margin-bottom:10px}.btn-group-responsive .pull-left,.btn-group-responsive .pull-right{float:none !important}}label.required::after{content:'*';color:red;padding-left:3px;font-size:9px}.hasDatepicker[disabled],.hasDatepicker[readonly],fieldset[disabled] .hasDatepicker{cursor:pointer !important;background-color:#fff !important;opacity:1}.more-options{display:none}.col-sort{color:#fff}.col-sort :hover{color:#fff}.pac-container{z-index:9999}.dtpicker-overlay{z-index:9999}.dtpicker-close{display:none}.dtpicker-header .dtpicker-title{color:#AFAFAF;text-align:center;font-size:18px;font-weight:normal}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em .2em;color:#404675;text-align:center;font-size:1.4em}.dtpicker-buttonCont .dtpicker-button{background:#404675;border-radius:0}.dtpicker-content{border-radius:0}.sidebar-open-ltr body{overflow-x:hidden}.order_options .event_count{font-weight:bold;color:#777}.well{background-color:#f9f9f9;box-shadow:none}.input-group-btn select{width:115px !important;border-left:0;font-size:12px}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}input[readonly]{background-color:white !important;cursor:text !important}html.working{cursor:progress}.order_options{padding:10px 0}.minicolors-theme-default.minicolors{width:auto;display:block}.minicolors-theme-default .minicolors-input{padding-left:35px;height:auto;width:100%;display:block}.minicolors-theme-default .minicolors-swatch{top:8px;left:6px;width:18px;height:18px}.pagination>.active>span,.pagination>.active:focus>span,.pagination>.active:hover>span,.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default,.pagination>li>a:hover,.pager>li>a:hover,.pagination>li>span:hover,.pager>li>span:hover,.pagination>li>a:focus,.pager>li>a:focus,.pagination>li>span:focus,.pager>li>span:focus{color:#ffffff !important}.btn-default .caret{border-top-color:#fff}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-right:none}.modal-backdrop{background:url(../images/background.png) repeat;background-color:#2e3254}.ticket .sortHandle{width:20px;height:20px;color:#dfdfdf;font-size:20px;position:absolute;bottom:20px;left:15px;cursor:move;z-index:10}
|
||||
|
|
@ -426,4 +426,14 @@ html.working {
|
|||
background-color: @attendize-base-color;
|
||||
}
|
||||
|
||||
|
||||
.ticket .sortHandle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: #dfdfdf;
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 15px;
|
||||
cursor: move;
|
||||
z-index: 10;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,38 +14,35 @@
|
|||
Event Tickets
|
||||
@stop
|
||||
|
||||
|
||||
@section('head')
|
||||
<script>
|
||||
$(function () {
|
||||
|
||||
|
||||
$('.sortable').sortable({
|
||||
handle: '.sortHanlde',
|
||||
forcePlaceholderSize: true,
|
||||
placeholderClass: 'col-md-4 col-sm-6 col-xs-12',
|
||||
}).bind('sortupdate', function (e, ui) {
|
||||
|
||||
var data = $('.sortable tr').map(function () {
|
||||
return $(this).data('question-id');
|
||||
var data = $('.sortable .ticket').map(function () {
|
||||
return $(this).data('ticket-id');
|
||||
}).get();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '',//Attendize.postUpdateTicketsOrderRoute,
|
||||
url: '{{ route('postUpdateTicketsOrder' ,['event_id' => $event->id]) }}',
|
||||
dataType: 'json',
|
||||
data: {question_ids: data},
|
||||
data: {ticket_ids: data},
|
||||
success: function (data) {
|
||||
showMessage(data.message)
|
||||
showMessage(data.message);
|
||||
},
|
||||
error: function (data) {
|
||||
console.log(data);
|
||||
showMessage('Something went wrong. Please try again.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@stop
|
||||
@stop
|
||||
|
||||
@section('menu')
|
||||
@include('ManageEvent.Partials.Sidebar')
|
||||
|
|
@ -93,7 +90,6 @@
|
|||
|
||||
@section('content')
|
||||
@if($tickets->count())
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xs-6">
|
||||
<div class='order_options'>
|
||||
|
|
@ -106,109 +102,104 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<!--Start ticket table-->
|
||||
<div class="row sortable">
|
||||
@if($tickets->count())
|
||||
@endif
|
||||
<!--Start ticket table-->
|
||||
<div class="row sortable">
|
||||
@if($tickets->count())
|
||||
|
||||
@foreach($tickets as $ticket)
|
||||
<div id="ticket_{{$ticket->id}}" class="col-md-4 col-sm-6 col-xs-12 ">
|
||||
<div class="panel panel-success ticket">
|
||||
|
||||
<div style="cursor: pointer;" data-modal-id='ticket-{{ $ticket->id }}'
|
||||
data-href="{{ route('showEditTicket', ['event_id' => $event->id, 'ticket_id' => $ticket->id]) }}"
|
||||
class="panel-heading loadModal">
|
||||
<h3 class="panel-title">
|
||||
@if($ticket->is_hidden)
|
||||
<i title="This ticket is hidden" class="ico-eye-blocked ticket_icon mr5 ellipsis"></i>
|
||||
@else
|
||||
<i class="ico-ticket ticket_icon mr5 ellipsis"></i>
|
||||
@endif
|
||||
{{$ticket->title}}
|
||||
<span class="pull-right">
|
||||
@foreach($tickets as $ticket)
|
||||
<div id="ticket_{{$ticket->id}}" class="col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="panel panel-success ticket" data-ticket-id="{{$ticket->id}}">
|
||||
<div style="cursor: pointer;" data-modal-id='ticket-{{ $ticket->id }}'
|
||||
data-href="{{ route('showEditTicket', ['event_id' => $event->id, 'ticket_id' => $ticket->id]) }}"
|
||||
class="panel-heading loadModal">
|
||||
<h3 class="panel-title">
|
||||
@if($ticket->is_hidden)
|
||||
<i title="This ticket is hidden"
|
||||
class="ico-eye-blocked ticket_icon mr5 ellipsis"></i>
|
||||
@else
|
||||
<i class="ico-ticket ticket_icon mr5 ellipsis"></i>
|
||||
@endif
|
||||
{{$ticket->title}}
|
||||
<span class="pull-right">
|
||||
{{ ($ticket->is_free) ? "FREE" : money($ticket->price, $event->currency) }}
|
||||
</span>
|
||||
</h3>
|
||||
</h3>
|
||||
</div>
|
||||
<div class='panel-body'>
|
||||
<ul class="nav nav-section nav-justified mt5 mb5">
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm">{{ $ticket->quantity_sold }}</h4>
|
||||
|
||||
<p class="nm text-muted">Sold</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm">
|
||||
{{ ($ticket->quantity_available === null) ? '∞' : $ticket->quantity_remaining }}
|
||||
</h4>
|
||||
|
||||
<p class="nm text-muted">Remaining</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm hint--top"
|
||||
title="{{money($ticket->sales_volume, $event->currency)}} + {{money($ticket->organiser_fees_volume, $event->currency)}} Organiser Booking Fees">
|
||||
{{money($ticket->sales_volume + $ticket->organiser_fees_volume, $event->currency)}}
|
||||
<sub title="Doesn't account for refunds.">*</sub>
|
||||
</h4>
|
||||
<p class="nm text-muted">Revenue</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel-footer" style="height: 56px;">
|
||||
<div class="sortHandle" title="Drag to re-order">
|
||||
<i class="ico-paragraph-justify"></i>
|
||||
</div>
|
||||
|
||||
<div class='panel-body'>
|
||||
<ul class="nav nav-section nav-justified mt5 mb5">
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm">{{ $ticket->quantity_sold }}</h4>
|
||||
|
||||
<p class="nm text-muted">Sold</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm">
|
||||
{{ ($ticket->quantity_available === null) ? '∞' : $ticket->quantity_remaining }}
|
||||
</h4>
|
||||
|
||||
<p class="nm text-muted">Remaining</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="section">
|
||||
<h4 class="nm hint--top"
|
||||
title="{{money($ticket->sales_volume, $event->currency)}} + {{money($ticket->organiser_fees_volume, $event->currency)}} Organiser Booking Fees">
|
||||
{{money($ticket->sales_volume + $ticket->organiser_fees_volume, $event->currency)}}
|
||||
<sub title="Doesn't account for refunds.">*</sub>
|
||||
</h4>
|
||||
|
||||
<p class="nm text-muted">Revenue</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel-footer sortHandle" style="height: 56px;">
|
||||
<ul class="nav nav-section nav-justified">
|
||||
<li>
|
||||
<a href="javascript:void(0);">
|
||||
@if($ticket->sale_status === config('attendize.ticket_status_on_sale'))
|
||||
@if($ticket->is_paused)
|
||||
Ticket Sales Paused
|
||||
<span class="pauseTicketSales label label-info"
|
||||
data-id="{{$ticket->id}}"
|
||||
data-route="{{route('postPauseTicket', ['event_id'=>$event->id])}}">
|
||||
<ul class="nav nav-section nav-justified">
|
||||
<li>
|
||||
<a href="javascript:void(0);">
|
||||
@if($ticket->sale_status === config('attendize.ticket_status_on_sale'))
|
||||
@if($ticket->is_paused)
|
||||
Ticket Sales Paused
|
||||
<span class="pauseTicketSales label label-info"
|
||||
data-id="{{$ticket->id}}"
|
||||
data-route="{{route('postPauseTicket', ['event_id'=>$event->id])}}">
|
||||
<i class="ico-play4"></i> Resume
|
||||
</span>
|
||||
@else
|
||||
On Sale
|
||||
<span class="pauseTicketSales label label-info"
|
||||
data-id="{{$ticket->id}}"
|
||||
data-route="{{route('postPauseTicket', ['event_id'=>$event->id])}}">
|
||||
@else
|
||||
On Sale
|
||||
<span class="pauseTicketSales label label-info"
|
||||
data-id="{{$ticket->id}}"
|
||||
data-route="{{route('postPauseTicket', ['event_id'=>$event->id])}}">
|
||||
<i class="ico-pause"></i> Pause
|
||||
</span>
|
||||
@endif
|
||||
@else
|
||||
{{\App\Models\TicketStatus::find($ticket->sale_status)->name}}
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@else
|
||||
{{\App\Models\TicketStatus::find($ticket->sale_status)->name}}
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
@if($q)
|
||||
@include('Shared.Partials.NoSearchResults')
|
||||
@else
|
||||
|
||||
@if($q)
|
||||
@include('Shared.Partials.NoSearchResults')
|
||||
@else
|
||||
@include('ManageEvent.Partials.TicketsBlankSlate')
|
||||
@endif
|
||||
|
||||
|
||||
@include('ManageEvent.Partials.TicketsBlankSlate')
|
||||
@endif
|
||||
</div><!--/ end ticket table-->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{!! $tickets->appends(['q' => $q, 'sort_by' => $sort_by])->render() !!}
|
||||
</div>
|
||||
@endif
|
||||
</div><!--/ end ticket table-->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{!! $tickets->appends(['q' => $q, 'sort_by' => $sort_by])->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue