Hidden ticket access codes (#1)
# Summary Added the ability to specify hidden ticket access codes on an event. This would allow for special types of tickets to be created on an event and have an unlock code link to one or many hidden tickets. ## Value The value this adds is to allow event organisers to play with marketing to aid in ticket sales etc. ## Changes **Admin** - Added migrations to allow for the access codes table on events and the pivot for many to many codes to tickets - Added the ability to create an access code in the event customisation - Added the ability to view access codes on a hidden ticket - Added the ability to attach one or multiple access code(s) onto the hidden ticket **Public event page** - Shows a box to enter your access code if the event has hidden tickets - Added the validation messages for empty codes - Added the check to fetch the hidden tickets if the code was entered correctly
This commit is contained in:
parent
ef58b27212
commit
54861755b4
15
Gruntfile.js
15
Gruntfile.js
|
|
@ -70,17 +70,22 @@ module.exports = function (grunt) {
|
|||
}
|
||||
},
|
||||
},
|
||||
phpunit: {
|
||||
classes: {},
|
||||
options: {}
|
||||
},
|
||||
watch: {
|
||||
scripts: {
|
||||
files: ['./public/assets/**/*.js'],
|
||||
tasks: ['default'],
|
||||
options: {
|
||||
spawn: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
// Plugin loading
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
//grunt.loadNpmTasks('grunt-phpunit');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
// Task definition
|
||||
grunt.registerTask('default', ['less', 'concat']);
|
||||
grunt.registerTask('deploy', ['less', 'concat', 'uglify']);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Event;
|
||||
use App\Models\EventAccessCodes;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EventAccessCodesController extends MyBaseController
|
||||
{
|
||||
/**
|
||||
* @param $event_id
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function showCreate($event_id)
|
||||
{
|
||||
return view('ManageEvent.Modals.CreateAccessCode', [
|
||||
'event' => Event::scope()->find($event_id),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ticket
|
||||
*
|
||||
* @param Request $request
|
||||
* @param $event_id
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function postCreate(Request $request, $event_id)
|
||||
{
|
||||
$eventAccessCode = new EventAccessCodes();
|
||||
|
||||
if (!$eventAccessCode->validate($request->all())) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'messages' => $eventAccessCode->errors(),
|
||||
]);
|
||||
}
|
||||
|
||||
$eventAccessCode->event_id = $event_id;
|
||||
$eventAccessCode->code = strtoupper(strip_tags($request->get('code')));
|
||||
$eventAccessCode->save();
|
||||
|
||||
session()->flash('message', 'Successfully Created Access Code');
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'id' => $eventAccessCode->id,
|
||||
'message' => trans("Controllers.refreshing"),
|
||||
'redirectUrl' => route('showEventCustomize', [
|
||||
'event_id' => $event_id,
|
||||
'#access_codes',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,6 +111,15 @@ class EventTicketsController extends MyBaseController
|
|||
|
||||
$ticket->save();
|
||||
|
||||
// Attach the access codes to the ticket if it's hidden and the code ids have come from the front
|
||||
if ($ticket->is_hidden) {
|
||||
$ticketAccessCodes = $request->get('ticket_access_codes', []);
|
||||
if (empty($ticketAccessCodes) === false) {
|
||||
// Sync the access codes on the ticket
|
||||
$ticket->event_access_codes()->attach($ticketAccessCodes);
|
||||
}
|
||||
}
|
||||
|
||||
session()->flash('message', 'Successfully Created Ticket');
|
||||
|
||||
return response()->json([
|
||||
|
|
@ -223,6 +232,9 @@ class EventTicketsController extends MyBaseController
|
|||
]);
|
||||
}
|
||||
|
||||
// Check if the ticket visibility changed on update
|
||||
$ticketPreviouslyHidden = (bool)$ticket->is_hidden;
|
||||
|
||||
$ticket->title = $request->get('title');
|
||||
$ticket->quantity_available = !$request->get('quantity_available') ? null : $request->get('quantity_available');
|
||||
$ticket->price = $request->get('price');
|
||||
|
|
@ -235,6 +247,19 @@ class EventTicketsController extends MyBaseController
|
|||
|
||||
$ticket->save();
|
||||
|
||||
// Attach the access codes to the ticket if it's hidden and the code ids have come from the front
|
||||
if ($ticket->is_hidden) {
|
||||
$ticketAccessCodes = $request->get('ticket_access_codes', []);
|
||||
if (empty($ticketAccessCodes) === false) {
|
||||
// Sync the access codes on the ticket
|
||||
$ticket->event_access_codes()->detach();
|
||||
$ticket->event_access_codes()->attach($ticketAccessCodes);
|
||||
}
|
||||
} else if ($ticketPreviouslyHidden) {
|
||||
// Delete access codes on ticket if the visibility changed to visible
|
||||
$ticket->event_access_codes()->detach();
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'id' => $ticket->id,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ class EventViewController extends Controller
|
|||
}
|
||||
|
||||
$data = [
|
||||
'event' => $event,
|
||||
'tickets' => $event->tickets()->where('is_hidden', 0)->orderBy('sort_order', 'asc')->get(),
|
||||
'event' => $event,
|
||||
'tickets' => $event->tickets()->orderBy('sort_order', 'asc')->get(),
|
||||
'is_embedded' => 0,
|
||||
];
|
||||
/*
|
||||
|
|
@ -136,4 +136,46 @@ class EventViewController extends Controller
|
|||
'Content-Disposition' => 'attachment; filename="event.ics'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $event_id
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function postShowHiddenTickets(Request $request, $event_id)
|
||||
{
|
||||
$event = Event::findOrFail($event_id);
|
||||
|
||||
$accessCode = $request->get('access_code');
|
||||
if (!$accessCode) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'A valid access code is required',
|
||||
]);
|
||||
}
|
||||
|
||||
$unlockedHiddenTickets = $event->tickets()
|
||||
->where('is_hidden', true)
|
||||
->orderBy('sort_order', 'asc')
|
||||
->get()
|
||||
->filter(function($ticket) use ($accessCode) {
|
||||
// Only return the hidden tickets that match the access code
|
||||
return ($ticket->event_access_codes()->where('code', $accessCode)->get()->count() > 0);
|
||||
});
|
||||
|
||||
if ($unlockedHiddenTickets->count() === 0) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'No Tickets matched to your unlock code',
|
||||
]);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'event' => $event,
|
||||
'tickets' => $unlockedHiddenTickets,
|
||||
'is_embedded' => 0,
|
||||
];
|
||||
|
||||
return view('Public.ViewEvent.Partials.EventHiddenTicketsSelection', $data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,11 @@ Route::group(
|
|||
'uses' => 'EventViewController@postContactOrganiser',
|
||||
]);
|
||||
|
||||
Route::post('/{event_id}/show_hidden', [
|
||||
'as' => 'postShowHiddenTickets',
|
||||
'uses' => 'EventViewController@postShowHiddenTickets',
|
||||
]);
|
||||
|
||||
/*
|
||||
* Used for previewing designs in the backend. Doesn't log page views etc.
|
||||
*/
|
||||
|
|
@ -559,12 +564,10 @@ Route::group(
|
|||
'as' => 'showEventCustomize',
|
||||
'uses' => 'EventCustomizeController@showCustomize',
|
||||
]);
|
||||
|
||||
Route::get('{event_id}/customize/{tab?}', [
|
||||
'as' => 'showEventCustomizeTab',
|
||||
'uses' => 'EventCustomizeController@showCustomize',
|
||||
]);
|
||||
|
||||
Route::post('{event_id}/customize/order_page', [
|
||||
'as' => 'postEditEventOrderPage',
|
||||
'uses' => 'EventCustomizeController@postEditEventOrderPage',
|
||||
|
|
@ -581,12 +584,23 @@ Route::group(
|
|||
'as' => 'postEditEventSocial',
|
||||
'uses' => 'EventCustomizeController@postEditEventSocial',
|
||||
]);
|
||||
|
||||
Route::post('{event_id}/customize/fees', [
|
||||
'as' => 'postEditEventFees',
|
||||
'uses' => 'EventCustomizeController@postEditEventFees',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Event access codes
|
||||
*/
|
||||
Route::get('{event_id}/access_codes/create', [
|
||||
'as' => 'showCreateEventAccessCode',
|
||||
'uses' => 'EventAccessCodesController@showCreate',
|
||||
]);
|
||||
|
||||
Route::post('{event_id}/access_codes/create', [
|
||||
'as' => 'postCreateEventAccessCode',
|
||||
'uses' => 'EventAccessCodesController@postCreate',
|
||||
]);
|
||||
|
||||
/*
|
||||
* -------
|
||||
|
|
|
|||
|
|
@ -137,6 +137,16 @@ class Event extends MyBaseModel
|
|||
return $this->hasMany(\App\Models\Order::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The access codes associated with the event.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function access_codes()
|
||||
{
|
||||
return $this->hasMany(\App\Models\EventAccessCodes::class, 'event_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The account associated with the event.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class EventAccessCodes extends MyBaseModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @return array $rules
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'code' => 'required|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The Event associated with the event access code.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function event()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Event::class, 'event_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
function tickets()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
Ticket::class,
|
||||
'ticket_event_access_code',
|
||||
'event_access_code_id',
|
||||
'ticket_id'
|
||||
)->withTimestamps();
|
||||
}
|
||||
}
|
||||
|
|
@ -72,6 +72,19 @@ class Ticket extends MyBaseModel
|
|||
return $this->belongsToMany(\App\Models\Question::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
function event_access_codes()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
EventAccessCodes::class,
|
||||
'ticket_event_access_code',
|
||||
'ticket_id',
|
||||
'event_access_code_id'
|
||||
)->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:implement the reserved method.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
"illuminate/support": "~5.6",
|
||||
"intervention/image": "~2.4",
|
||||
"laracasts/utilities": "~2.1",
|
||||
"laravel/framework": "~5.6",
|
||||
"laravel/framework": "~5.6",
|
||||
"laravel/socialite": "~3.0",
|
||||
"laravelcollective/html": "~5.6",
|
||||
"league/flysystem-aws-s3-v3": "~1.0",
|
||||
|
|
@ -37,14 +37,15 @@
|
|||
"php-http/curl-client": "^1.7",
|
||||
"php-http/message": "^1.6",
|
||||
"predis/predis": "~1.1",
|
||||
"vinelab/http": "~1.5"
|
||||
"vinelab/http": "~1.5",
|
||||
"laravel/tinker": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "7.3.*",
|
||||
"phpspec/phpspec": "5.0.*",
|
||||
"fzaninotto/faker": "1.8.*",
|
||||
"symfony/dom-crawler": "~3.0",
|
||||
"symfony/css-selector": "~3.0"
|
||||
"symfony/css-selector": "~3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateEventAccessCodesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('event_access_codes', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('event_id');
|
||||
$table->string('code')->default('');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
// Add events table foreign key
|
||||
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('event_access_codes');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateTicketEventAccessCodeTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('ticket_event_access_code', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('ticket_id');
|
||||
$table->unsignedInteger('event_access_code_id');
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('ticket_id')->references('id')->on('tickets');
|
||||
$table->foreign('event_access_code_id')->references('id')->on('event_access_codes');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::disableForeignKeyConstraints();
|
||||
Schema::dropIfExists('ticket_event_access_code');
|
||||
Schema::enableForeignKeyConstraints();
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +176,32 @@ $(function() {
|
|||
|
||||
}).change();
|
||||
|
||||
// Apply access code here to unlock hidden tickets
|
||||
$('#apply_access_code').click(function(e) {
|
||||
var $clicked = $(this);
|
||||
// Hide any previous errors
|
||||
$clicked.closest('.form-group')
|
||||
.removeClass('has-error');
|
||||
|
||||
var url = $clicked.closest('.has-access-codes').data('url');
|
||||
var data = {
|
||||
'access_code': $('#unlock_code').val(),
|
||||
'_token': $('input:hidden[name=_token]').val()
|
||||
};
|
||||
|
||||
$.post(url, data, function(response) {
|
||||
if (response.status === 'error') {
|
||||
// Show any access code errors
|
||||
$clicked.closest('.form-group').addClass('has-error');
|
||||
showMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
$clicked.closest('.has-access-codes').before(response);
|
||||
$('#unlock_code').val('');
|
||||
$clicked.closest('.has-access-codes').remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function processFormErrors($form, errors)
|
||||
|
|
|
|||
|
|
@ -4744,7 +4744,32 @@ function log() {
|
|||
|
||||
}).change();
|
||||
|
||||
// Apply access code here to unlock hidden tickets
|
||||
$('#apply_access_code').click(function(e) {
|
||||
var $clicked = $(this);
|
||||
// Hide any previous errors
|
||||
$clicked.closest('.form-group')
|
||||
.removeClass('has-error');
|
||||
|
||||
var url = $clicked.closest('.has-access-codes').data('url');
|
||||
var data = {
|
||||
'access_code': $('#unlock_code').val(),
|
||||
'_token': $('input:hidden[name=_token]').val()
|
||||
};
|
||||
|
||||
$.post(url, data, function(response) {
|
||||
if (response.status === 'error') {
|
||||
// Show any access code errors
|
||||
$clicked.closest('.form-group').addClass('has-error');
|
||||
showMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
$clicked.closest('.has-access-codes').before(response);
|
||||
$('#unlock_code').val('');
|
||||
$clicked.closest('.has-access-codes').remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function processFormErrors($form, errors)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
return [
|
||||
'access_codes_heading' => 'Access Codes to unlock hidden tickets',
|
||||
'access_codes_code' => 'Code',
|
||||
'access_codes_created_at' => 'Created At',
|
||||
'no_access_codes_yet' => 'No Access Codes yet!',
|
||||
'create_access_code' => 'Create Access Code',
|
||||
'access_code_title' => 'Code',
|
||||
'access_code_title_placeholder' => 'ex: CONFERENCE2019',
|
||||
];
|
||||
|
|
@ -36,6 +36,7 @@ return [
|
|||
'expiry_year' => 'Expiry year',
|
||||
'first_name' => 'First name',
|
||||
'free' => 'FREE',
|
||||
'has_unlock_codes' => 'Do you have an unlock code?',
|
||||
'inc_fees' => 'Booking Fees',
|
||||
'last_name' => 'Last name',
|
||||
'offline_payment_instructions' => 'Offline payment instructions',
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ return array (
|
|||
'ticket_background_color' => 'Ticket Background Color',
|
||||
'ticket_border_color' => 'Ticket Border Color',
|
||||
'ticket_design' => 'Ticket Design',
|
||||
'access_codes' => 'Access Codes',
|
||||
'ticket_preview' => 'Ticket Preview',
|
||||
'ticket_sales_paused' => 'Sales Paused',
|
||||
'ticket_sub_text_color' => 'Ticket Sub Text Color',
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
return array (
|
||||
//==================================== Translations ====================================//
|
||||
'apply' => 'Apply',
|
||||
'action' => 'Action',
|
||||
'affiliates' => 'Affiliates',
|
||||
'attendees' => 'Attendees',
|
||||
|
|
@ -42,21 +43,21 @@ return array (
|
|||
'submit' => 'Submit',
|
||||
'success' => 'Success',
|
||||
'ticket_design' => 'Ticket Design',
|
||||
'access_codes' => 'Access Codes',
|
||||
'tickets' => 'Tickets',
|
||||
'TOP' => 'TOP',
|
||||
'TOP' => 'TOP',
|
||||
'total' => 'total',
|
||||
'whoops' => 'Whoops!',
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
/*
|
||||
* Lines below will turn obsolete in localization helper, it is declared in app/Helpers/macros.
|
||||
* If you run it, it will break file input fields.
|
||||
*/
|
||||
'upload' => 'Upload',
|
||||
'browse' => 'Browse',
|
||||
/*
|
||||
* Lines below will turn obsolete in localization helper, it is declared in app/Helpers/macros.
|
||||
* If you run it, it will break file input fields.
|
||||
*/
|
||||
'upload' => 'Upload',
|
||||
'browse' => 'Browse',
|
||||
//================================== Obsolete strings ==================================//
|
||||
'LLH:obsolete' =>
|
||||
array (
|
||||
'LLH:obsolete' => [
|
||||
'months_long' => 'January|February|March|April|May|June|July|August|September|October|November|December',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
@ -201,6 +201,8 @@
|
|||
class="{{$tab == 'fees' ? 'active' : ''}}"><a href="#fees" data-toggle="tab">@lang("basic.service_fees")</a></li>
|
||||
<li data-route="{{route('showEventCustomizeTab', ['event_id' => $event->id, 'tab' => 'ticket_design'])}}"
|
||||
class="{{$tab == 'ticket_design' ? 'active' : ''}}"><a href="#ticket_design" data-toggle="tab">@lang("basic.ticket_design")</a></li>
|
||||
<li data-route="{{route('showEventCustomizeTab', ['event_id' => $event->id, 'tab' => 'access_codes'])}}"
|
||||
class="{{$tab == 'access_codes' ? 'active' : ''}}"><a href="#access_codes" data-toggle="tab">@lang("basic.access_codes")</a></li>
|
||||
|
||||
</ul>
|
||||
<!--/ tab -->
|
||||
|
|
@ -587,6 +589,50 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane {{$tab == 'access_codes' ? 'active' : ''}}" id="access_codes">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-responsive">
|
||||
<button data-modal-id='CreateAccessCode'
|
||||
data-href="{{route('showCreateEventAccessCode', [ 'event_id' => $event->id ])}}"
|
||||
class='loadModal btn btn-success' type="button"><i class="ico-ticket"></i> @lang("EventAccessCode.create_access_code")
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row"><div class="col-md-12"> </div></div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@if($event->access_codes->count())
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@lang("EventAccessCode.access_codes_code")</th>
|
||||
<th>@lang("EventAccessCode.access_codes_created_at")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach($event->access_codes as $access_code)
|
||||
<tr>
|
||||
<td><strong>{{ $access_code->code }}</strong></td>
|
||||
<td>{{ $access_code->created_at }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-info">
|
||||
@lang("EventAccessCode.no_access_codes_yet")
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ tab content -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<div role="dialog" class="modal fade" style="display: none;">
|
||||
{!! Form::open(['url' => route('postCreateEventAccessCode', ['event_id' => $event->id]), 'class' => 'ajax']) !!}
|
||||
<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-ticket"></i>
|
||||
@lang("EventAccessCode.create_access_code")</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
{!! Form::label('code', trans("EventAccessCode.access_code_title"), ['class'=>'control-label required']) !!}
|
||||
{!! Form::text('code', Input::old('code'),
|
||||
[
|
||||
'class'=>'form-control',
|
||||
'placeholder' => trans("EventAccessCode.access_code_title_placeholder")
|
||||
]) !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- /end modal body-->
|
||||
<div class="modal-footer">
|
||||
{!! Form::button(trans("basic.cancel"), ['class'=>"btn modal-close btn-danger",'data-dismiss'=>'modal']) !!}
|
||||
{!! Form::submit(trans("EventAccessCode.create_access_code"), ['class'=>"btn btn-success"]) !!}
|
||||
</div>
|
||||
</div><!-- /end modal content-->
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -100,9 +100,35 @@
|
|||
{!! Form::checkbox('is_hidden', null, null, ['id' => 'is_hidden']) !!}
|
||||
{!! Form::label('is_hidden', trans("ManageEvent.hide_this_ticket"), array('class'=>' control-label')) !!}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@if ($ticket->is_hidden)
|
||||
<div class="col-md-12">
|
||||
<h4>Select access codes</h4>
|
||||
@if($ticket->event->access_codes->count())
|
||||
<?php
|
||||
$isSelected = false;
|
||||
$selectedAccessCodes = $ticket->event_access_codes()->get()->map(function($accessCode) {
|
||||
return $accessCode->pivot->event_access_code_id;
|
||||
})->toArray();
|
||||
?>
|
||||
@foreach($ticket->event->access_codes as $access_code)
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="custom-checkbox mb5">
|
||||
{!! Form::checkbox('ticket_access_codes[]', $access_code->id, in_array($access_code->id, $selectedAccessCodes), ['id' => 'ticket_access_code_' . $access_code->id, 'data-toggle' => 'toggle']) !!}
|
||||
{!! Form::label('ticket_access_code_' . $access_code->id, $access_code->code) !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
<div class="alert alert-info">
|
||||
@lang("EventAccessCode.no_access_codes_yet")
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<a href="javascript:void(0);" class="show-more-options">
|
||||
@lang("ManageEvent.more_options")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
$is_free_event = true;
|
||||
?>
|
||||
@foreach($tickets as $ticket)
|
||||
<tr class="ticket" property="offers" typeof="Offer">
|
||||
<td>
|
||||
<span class="ticket-title semibold" property="name">
|
||||
{{$ticket->title}}
|
||||
</span>
|
||||
<p class="ticket-descripton mb0 text-muted" property="description">
|
||||
{{$ticket->description}}
|
||||
</p>
|
||||
</td>
|
||||
<td style="width:200px; text-align: right;">
|
||||
<div class="ticket-pricing" style="margin-right: 20px;">
|
||||
@if($ticket->is_free)
|
||||
@lang("Public_ViewEvent.free")
|
||||
<meta property="price" content="0">
|
||||
@else
|
||||
<?php
|
||||
$is_free_event = false;
|
||||
?>
|
||||
<span title='{{money($ticket->price, $event->currency)}} @lang("Public_ViewEvent.ticket_price") + {{money($ticket->total_booking_fee, $event->currency)}} @lang("Public_ViewEvent.booking_fees")'>{{money($ticket->total_price, $event->currency)}} </span>
|
||||
<span class="tax-amount text-muted text-smaller">{{ ($event->organiser->tax_name && $event->organiser->tax_value) ? '(+'.money(($ticket->total_price*($event->organiser->tax_value)/100), $event->currency).' '.$event->organiser->tax_name.')' : '' }}</span>
|
||||
<meta property="priceCurrency"
|
||||
content="{{ $event->currency->code }}">
|
||||
<meta property="price"
|
||||
content="{{ number_format($ticket->price, 2, '.', '') }}">
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:85px;">
|
||||
@if($ticket->is_paused)
|
||||
|
||||
<span class="text-danger">
|
||||
@lang("Public_ViewEvent.currently_not_on_sale")
|
||||
</span>
|
||||
|
||||
@else
|
||||
|
||||
@if($ticket->sale_status === config('attendize.ticket_status_sold_out'))
|
||||
<span class="text-danger" property="availability"
|
||||
content="http://schema.org/SoldOut">
|
||||
@lang("Public_ViewEvent.sold_out")
|
||||
</span>
|
||||
@elseif($ticket->sale_status === config('attendize.ticket_status_before_sale_date'))
|
||||
<span class="text-danger">
|
||||
@lang("Public_ViewEvent.sales_have_not_started")
|
||||
</span>
|
||||
@elseif($ticket->sale_status === config('attendize.ticket_status_after_sale_date'))
|
||||
<span class="text-danger">
|
||||
@lang("Public_ViewEvent.sales_have_ended")
|
||||
</span>
|
||||
@else
|
||||
{!! Form::hidden('tickets[]', $ticket->id) !!}
|
||||
<meta property="availability" content="http://schema.org/InStock">
|
||||
<select name="ticket_{{$ticket->id}}" class="form-control"
|
||||
style="text-align: center">
|
||||
@if ($tickets->count() > 1)
|
||||
<option value="0">0</option>
|
||||
@endif
|
||||
@for($i=$ticket->min_per_person; $i<=$ticket->max_per_person; $i++)
|
||||
<option value="{{$i}}">{{$i}}</option>
|
||||
@endfor
|
||||
</select>
|
||||
@endif
|
||||
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
<?php
|
||||
$is_free_event = true;
|
||||
?>
|
||||
@foreach($tickets as $ticket)
|
||||
@foreach($tickets->where('is_hidden', false) as $ticket)
|
||||
<tr class="ticket" property="offers" typeof="Offer">
|
||||
<td>
|
||||
<span class="ticket-title semibold" property="name">
|
||||
|
|
@ -90,12 +90,32 @@
|
|||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: center">
|
||||
@lang("Public_ViewEvent.below_tickets")
|
||||
</td>
|
||||
</tr>
|
||||
@if ($tickets->where('is_hidden', true)->count() > 0)
|
||||
<tr class="has-access-codes" data-url="{{route('postShowHiddenTickets', ['event_id' => $event->id])}}">
|
||||
<td colspan="3" style="text-align: left">
|
||||
@lang("Public_ViewEvent.has_unlock_codes")
|
||||
<div class="form-group" style="display:inline-block;margin-bottom:0;margin-left:15px;">
|
||||
{!! Form::text('unlock_code', null, [
|
||||
'class' => 'form-control',
|
||||
'id' => 'unlock_code',
|
||||
'style' => 'display:inline-block;width:65%;text-transform:uppercase;',
|
||||
'placeholder' => 'ex: UNLOCKCODE01',
|
||||
]) !!}
|
||||
{!! Form::button(trans("basic.apply"), [
|
||||
'class' => "btn btn-success",
|
||||
'id' => 'apply_access_code',
|
||||
'style' => 'display:inline-block;margin-top:-2px;',
|
||||
'data-dismiss' => 'modal',
|
||||
]) !!}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: center">
|
||||
@lang("Public_ViewEvent.below_tickets")
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="checkout">
|
||||
<td colspan="3">
|
||||
@if(!$is_free_event)
|
||||
|
|
|
|||
Loading…
Reference in New Issue