Initial commit
This commit is contained in:
commit
5eeda308ce
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\Event;
|
||||||
|
|
||||||
|
use Backend;
|
||||||
|
use System\Classes\PluginBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event Plugin Information File.
|
||||||
|
*/
|
||||||
|
class Plugin extends PluginBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns information about this plugin.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function pluginDetails()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'event',
|
||||||
|
'description' => 'No description provided yet...',
|
||||||
|
'author' => 'zoomyboy',
|
||||||
|
'icon' => 'icon-leaf',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register method, called when the plugin is first registered.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boot method, called right before the request route.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers any front-end components implemented in this plugin.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function registerComponents()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Zoomyboy\Event\Components\EventForm' => 'event_form',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers any back-end permissions used by this plugin.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function registerPermissions()
|
||||||
|
{
|
||||||
|
return []; // Remove this line to activate
|
||||||
|
|
||||||
|
return [
|
||||||
|
'zoomyboy.event.some_permission' => [
|
||||||
|
'tab' => 'event',
|
||||||
|
'label' => 'Some permission',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers back-end navigation items for this plugin.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function registerNavigation()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'event' => [
|
||||||
|
'label' => 'Teilnehmer',
|
||||||
|
'url' => Backend::url('zoomyboy/event/participant'),
|
||||||
|
'icon' => 'icon-leaf',
|
||||||
|
'permissions' => ['zoomyboy.event.*'],
|
||||||
|
'order' => 500,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
import scrollToElement from './scrollToElement.js';
|
||||||
|
|
||||||
|
var toastedOptions = {
|
||||||
|
position: 'top-right',
|
||||||
|
duration: 3000,
|
||||||
|
fitToScreen: true,
|
||||||
|
fullWidth: true,
|
||||||
|
theme: 'material',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (toasted) {
|
||||||
|
var toasted = new toasted(toastedOptions);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
firstname: 'Philipp',
|
||||||
|
lastname: 'Lang',
|
||||||
|
address: 'Itterstr 3',
|
||||||
|
zip: '42719',
|
||||||
|
location: 'Solingen',
|
||||||
|
food_preferences: [],
|
||||||
|
activity: 'Teilnehmer*in',
|
||||||
|
gender: 'Weiblich',
|
||||||
|
email: 'philipp@aaa.de',
|
||||||
|
birthday: '1991-06-20',
|
||||||
|
agegroup: '',
|
||||||
|
group: '',
|
||||||
|
agegroup_leader: '',
|
||||||
|
emergency_phone: '',
|
||||||
|
phone: '+49 176 70342420',
|
||||||
|
misc: '',
|
||||||
|
foto: false,
|
||||||
|
vorteam: false,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
submitRequest: null,
|
||||||
|
errorFields: [],
|
||||||
|
active: 0,
|
||||||
|
slides: [
|
||||||
|
'Persönliches',
|
||||||
|
'Veranstaltung',
|
||||||
|
'Sonstiges'
|
||||||
|
],
|
||||||
|
activities: [
|
||||||
|
{"id": "Orga", "name": "Orga"},
|
||||||
|
{"id": "Teilnehmer*in", "name": "Teilnehmer*in"},
|
||||||
|
],
|
||||||
|
genders: [
|
||||||
|
{"id": "Männlich", "name": "Männlich"},
|
||||||
|
{"id": "Weiblich", "name": "Weiblich"},
|
||||||
|
{"id": "Divers", "name": "Divers"},
|
||||||
|
],
|
||||||
|
groups: [
|
||||||
|
{"id": "Gandalf", "name": "Gandalf"},
|
||||||
|
{"id": "Tenkterer", "name": "Tenkterer"},
|
||||||
|
],
|
||||||
|
agegroups: [
|
||||||
|
{"id": "Biber", "name": "Biber"},
|
||||||
|
{"id": "Wölfling", "name": "Wölfling"},
|
||||||
|
{"id": "Jungpfadfinder", "name": "Jungpfadfinder"},
|
||||||
|
{"id": "Pfadfinder", "name": "Pfadfinder"},
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
{"id": "Leiter", "name": "Leiter"},
|
||||||
|
],
|
||||||
|
agegroups_leaders: [
|
||||||
|
{"id": "Biber", "name": "Biber"},
|
||||||
|
{"id": "Wölfling", "name": "Wölfling"},
|
||||||
|
{"id": "Jungpfadfinder", "name": "Jungpfadfinder"},
|
||||||
|
{"id": "Pfadfinder", "name": "Pfadfinder"},
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
],
|
||||||
|
boolean: [
|
||||||
|
{"id": "Ja", "name": "Ja"},
|
||||||
|
{"id": "Nein", "name": "Nein"},
|
||||||
|
],
|
||||||
|
foodPreferences: [
|
||||||
|
{"id": "Fleisch", "name": "Fleisch"},
|
||||||
|
{"id": "Vegan", "name": "Vegan"},
|
||||||
|
{"id": "Glutenfrei", "name": "Glutenfrei"},
|
||||||
|
{"id": "Laktosefrei", "name": "Laktosefrei"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hasAddress() {
|
||||||
|
return this.data.location && this.data.address && this.data.zip;
|
||||||
|
},
|
||||||
|
slideTo(e, index) {
|
||||||
|
if (e !== null) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
this.scrollForm(this.$refs.form);
|
||||||
|
this.meta.active = index;
|
||||||
|
this.$refs.slider.scrollLeft = this.$refs.slider.scrollWidth / this.meta.slides.length * index;
|
||||||
|
// this.$refs.mobileSlider.scrollLeft = this.$refs.mobileSlider.scrollWidth / this.meta.slides.length * index;
|
||||||
|
},
|
||||||
|
scrollForm(el) {
|
||||||
|
var margin = window.getComputedStyle(el).marginTop.replace('px', '');
|
||||||
|
scrollToElement(el, 300, (margin?margin:0) * -1);
|
||||||
|
},
|
||||||
|
onNextButtonClick(e) {
|
||||||
|
if (this.meta.active != this.meta.slides.length - 1) {
|
||||||
|
this.slideTo(e, this.meta.active + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPrevButtonClick(e) {
|
||||||
|
if (this.meta.active != 0) {
|
||||||
|
this.slideTo(e, this.meta.active - 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
var _self = this;
|
||||||
|
var promise = fetch(window.location.href, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'X-WINTER-REQUEST-HANDLER': this.meta.submitRequest,
|
||||||
|
'X-WINTER-REQUEST-PARTIALS': [],
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(this.data),
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(function(response) {
|
||||||
|
if (response.status === 422) {
|
||||||
|
response.json().then((errors) => {
|
||||||
|
_self.scrollToFirstError(errors);
|
||||||
|
Object.keys(errors).forEach((field) => {
|
||||||
|
toasted.error(errors[field].join('<br>'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollToFirstError(errors) {
|
||||||
|
if (Object.keys(errors).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstField = Object.keys(errors)[0];
|
||||||
|
var field = this.$refs.form.querySelector('[name="'+firstField+'"]');
|
||||||
|
|
||||||
|
if (field === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slideElement = field.closest('.slider-element');
|
||||||
|
this.slideTo(null, Array.from(slideElement.parentNode.children).indexOf(slideElement));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spreads: {
|
||||||
|
prevButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == 0 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nextButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == this.meta.slides.length - 1 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.slideTo(null, this.meta.active);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* y: the y coordinate to scroll, 0 = top
|
||||||
|
* duration: scroll duration in milliseconds; default is 0 (no transition)
|
||||||
|
* element: the html element that should be scrolled ; default is the main scrolling element
|
||||||
|
*/
|
||||||
|
function scrollToY (y, duration = 0, element = document.scrollingElement) {
|
||||||
|
// cancel if already on target position
|
||||||
|
if (element.scrollTop === y) return;
|
||||||
|
|
||||||
|
const cosParameter = (element.scrollTop - y) / 2;
|
||||||
|
let scrollCount = 0, oldTimestamp = null;
|
||||||
|
|
||||||
|
function step (newTimestamp) {
|
||||||
|
if (oldTimestamp !== null) {
|
||||||
|
// if duration is 0 scrollCount will be Infinity
|
||||||
|
scrollCount += Math.PI * (newTimestamp - oldTimestamp) / duration;
|
||||||
|
if (scrollCount >= Math.PI) return element.scrollTop = y;
|
||||||
|
element.scrollTop = cosParameter + y + cosParameter * Math.cos(scrollCount);
|
||||||
|
}
|
||||||
|
oldTimestamp = newTimestamp;
|
||||||
|
window.requestAnimationFrame(step);
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(element, duration = 0, addedOffset = 0) {
|
||||||
|
const offset = Math.round(element.getBoundingClientRect().top);
|
||||||
|
scrollToY(document.scrollingElement.scrollTop + offset + addedOffset, duration);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\Event\Components;
|
||||||
|
|
||||||
|
use Cms\Classes\ComponentBase;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Lang;
|
||||||
|
use Input;
|
||||||
|
use Winter\Storm\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class EventForm extends ComponentBase
|
||||||
|
{
|
||||||
|
public function componentDetails()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'EventForm Component',
|
||||||
|
'description' => 'No description provided yet...',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineProperties()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSubmit(): JsonResponse
|
||||||
|
{
|
||||||
|
$validator = Validator::make(Input::all(), [
|
||||||
|
'activity' => 'required|max:255',
|
||||||
|
'gender' => 'required|max:255',
|
||||||
|
'firstname' => 'required|max:255',
|
||||||
|
'lastname' => 'required|max:255',
|
||||||
|
'birthday' => 'required|date|before_or_equal:'.now()->format('Y-m-d'),
|
||||||
|
'address' => 'required|max:255',
|
||||||
|
'zip' => 'required|numeric',
|
||||||
|
'location' => 'required|max:255',
|
||||||
|
'phone' => 'required|max:255',
|
||||||
|
'email' => 'required|max:255|email',
|
||||||
|
'agegroup' => 'required|max:255',
|
||||||
|
'group' => 'nullable|max:255',
|
||||||
|
'agegroup_leader' => 'nullable|max:255',
|
||||||
|
'emergency_phone' => 'required|max:255',
|
||||||
|
'food_preferences' => 'array',
|
||||||
|
'misc' => '',
|
||||||
|
'foto' => '',
|
||||||
|
], [], Lang::get('zoomyboy.event::validation.attributes'));
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json($validator->errors(), 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = $validator->validated();
|
||||||
|
dd($fields);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,317 @@
|
||||||
|
{% set labelwidth = 'w-48' %}
|
||||||
|
{% set p=participant %}
|
||||||
|
{% set formContainerClass = "bg-white rounded-lg shadow-lg " %}
|
||||||
|
|
||||||
|
{% macro field(context, name, label, required, type) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
|
<input name="{{name}}" type="{{type|default('text')}}" id="{{name}}" placeholder=" " class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-2 px-3 w-full" x-model="data.{{name}}" />
|
||||||
|
<span
|
||||||
|
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-sm peer-placeholder-shown:bottom-0 peer-placeholder-shown:-top-0 peer-placeholder-shown:text-base peer-focus:-top-3 peer-focus:bottom-auto peer-focus:text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro textarea(context, name, label, required, type) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
|
<textarea name="{{name}}" rows="6" id="{{name}}" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-2 px-3 w-full" x-model="data.{{name}}">
|
||||||
|
</textarea>
|
||||||
|
<span
|
||||||
|
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro select(context, name, label, required, options) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" for="{{name}}">
|
||||||
|
<select name="{{name}}" id="{{name}}" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left peer py-2 px-3 w-full" x-model="data.{{name}}">
|
||||||
|
<option :selected="data.{{name}} === ''" value="">-- kein --</option>
|
||||||
|
<template x-for="model in meta.{{options}}">
|
||||||
|
<option :selected="data.{{name}} === model.id" :value="model.id" x-text="model.name"></option>
|
||||||
|
</template>
|
||||||
|
</select>
|
||||||
|
<span
|
||||||
|
class="absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro radio(context, name, label, required, options) %}
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-gray-600 text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
<div class="flex flex-col space-y-1">
|
||||||
|
<template x-for="option, index in meta.{{options}}">
|
||||||
|
<label :for="`{{name}}-${index}`" class="block relative flex items-center">
|
||||||
|
<input type="radio" name="{{name}}" :value="option.name" x-model="data.{{name}}" class="peer absolute invisible" :id="`{{name}}-${index}`" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded-full block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-full block"></span>
|
||||||
|
<span class="pl-8" x-text="option.name"></span>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro yesno(context, name, label, required) %}
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-col space-y-1">
|
||||||
|
<label for="{{name}}" class="block relative flex items-center">
|
||||||
|
<input type="checkbox" name="{{name}}" x-model="data.{{name}}" class="peer absolute invisible" id="{{name}}" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-sm block"></span>
|
||||||
|
<span class="pl-8">{{label}}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro checkboxes(context, name, label, required, options) %}
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-gray-600 flex text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
<div class="flex flex-col space-y-1">
|
||||||
|
<template x-for="option, index in meta.{{options}}">
|
||||||
|
<label :for="`{{name}}-${index}`" class="block relative flex items-center">
|
||||||
|
<input type="checkbox" name="{{name}}[]" :value="option.name" x-model="data.{{name}}" class="peer absolute invisible" :id="`{{name}}-${index}`" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-sm block"></span>
|
||||||
|
<span class="pl-8" x-text="option.name"></span>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
{% import _self as form %}
|
||||||
|
|
||||||
|
<div x-data="{
|
||||||
|
data: eventRegistration.data,
|
||||||
|
meta: {
|
||||||
|
...eventRegistration.meta,
|
||||||
|
submitRequest: '{{__SELF__.alias ~ '::onSubmit'}}',
|
||||||
|
},
|
||||||
|
...eventRegistration.methods,
|
||||||
|
...eventRegistration.spreads,
|
||||||
|
}" x-init="eventRegistration.init">
|
||||||
|
|
||||||
|
{#+++ registrationForm +++#}
|
||||||
|
<form x-ref="form" @submit.prevent="submit" class="my-6" novalidate>
|
||||||
|
<div x-ref="eventFormContainer" class="{{formContainerClass}}">
|
||||||
|
{% set arrowClass = "flex flex-col md:flex-row items-center justify-center md:justify-start px-2 flex-auto md:pl-6 h-12 md:h-16 transition duration-300" %}
|
||||||
|
{% set positionClass = "flex items-center justify-center w-4 md:w-6 h-4 md:h-6 rounded-full bg-teal-800 mr-2 text-teal-200 font-goudy transition duration-300" %}
|
||||||
|
{% set arrowFont = "text-sm text-teal-100" %}
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="sticky top-0 z-10 hidden sm:flex overflow-hidden rounded-t-lg">
|
||||||
|
<template x-for="(slide, index) in meta.slides">
|
||||||
|
<a @click="slideTo($event, index)" href="#" class="{{arrowClass}}" :class="{ 'bg-emerald-500': index <= meta.active, 'bg-primary-700': index > meta.active }">
|
||||||
|
<span class="{{positionClass}}" x-html="index+1"></span>
|
||||||
|
<span class="{{arrowFont}}" x-html="slide"></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="flex items-center px-6 overflow-auto overflow-hidden rounded-t-lg sm:hidden bg-primary-700">
|
||||||
|
<a @click="slideTo($event, meta.active-1)" href="#" class="{{positionClass}} w-6 h-6 flex-none" :class="{'opacity-40': meta.active == 0}">
|
||||||
|
<svg class="{{arrowFont}} fill-current w-3 h-3"><use xlink:href="{{'icons/sprite.svg'|media}}#chevron"></use></svg>
|
||||||
|
</a>
|
||||||
|
<div x-ref="mobileSlider" class="flex flex-no-wrap w-full overflow-auto snap transition-all" x-on:resize.debounce.window="$refs.mobileSlider.scrollLeft = $refs.mobileSlider.scrollWidth / meta.slides.length * meta.active">
|
||||||
|
<template x-for="(slide, index) in meta.slides">
|
||||||
|
<div class="flex-none w-full">
|
||||||
|
<div @click="slideTo($event, index)" href="#" class="{{arrowClass}}">
|
||||||
|
<span class="{{positionClass}}" x-html="index+1"></span>
|
||||||
|
<span class="{{arrowFont}}" x-html="slide"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<a @click="slideTo($event, meta.active+1)" href="#" class="{{positionClass}} w-6 h-6 flex-none" :class="{'opacity-40': meta.active == meta.slides.length - 1}">
|
||||||
|
<svg class="{{arrowFont}} fill-current w-3 h-3 transform rotate-180"><use xlink:href="{{'icons/sprite.svg'|media}}#chevron"></use></svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="py-8">
|
||||||
|
<div x-ref="slider" class="relative flex flex-no-wrap overflow-hidden snap-x snap-mandatory snap-always scroll-smooth">
|
||||||
|
{% set labelClass = "fancy-textinput size-lg dark" %}
|
||||||
|
{% set gliderElClass = "w-full flex-none snap-center slider-element" %}
|
||||||
|
{% set descClass = "text-sm sm_text-base text-gray-800 leading-tight mb-5" %}
|
||||||
|
|
||||||
|
<div class="{{gliderElClass}}">
|
||||||
|
<div class="{{descClass}}">Gebe hier deine Funktion an, die du auf der Veranstaltung wahrnehmen willst. Danach benötigen wir ein paar persönliche Daten von dir. </div>
|
||||||
|
<div class="{{descClass}}"></div>
|
||||||
|
<div class="grid sm:grid-cols-2 gap-4 mt-6">
|
||||||
|
{{ form.select(_context, 'activity', 'Funktion', true, 'activities') }}
|
||||||
|
{{ form.select(_context, 'gender', 'Geschlecht', true, 'genders') }}
|
||||||
|
{{ form.field(_context, 'firstname', 'Vorname', true) }}
|
||||||
|
{{ form.field(_context, 'lastname', 'Nachname', true) }}
|
||||||
|
{{ form.field(_context, 'birthday', 'Geburtsdatum', true, 'date') }}
|
||||||
|
{{ form.field(_context, 'address', 'Straße & Hausnr', true) }}
|
||||||
|
{{ form.field(_context, 'zip', 'PLZ', true) }}
|
||||||
|
{{ form.field(_context, 'location', 'Ort', true) }}
|
||||||
|
{{ form.field(_context, 'phone', 'Telefonnummer', true, 'tel') }}
|
||||||
|
{{ form.field(_context, 'email', 'E-Mail-Adresse', true, 'email') }}
|
||||||
|
</div>
|
||||||
|
{% partial __SELF__.alias ~ '::navigation' %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="{{gliderElClass}}">
|
||||||
|
<div class="{{descClass}}">Gebe hier deine Gruppenzugehörigkeit und weitere wichtige Infos zur Veranstaltung an.</div>
|
||||||
|
<div class="grid sm:grid-cols-2 gap-4 mt-6">
|
||||||
|
{{ form.select(_context, 'group', 'Stamm', false, 'groups') }}
|
||||||
|
{{ form.field(_context, 'emergency_phone', 'Notfallkontakt (Tel)', true) }}
|
||||||
|
{{ form.select(_context, 'agegroup', 'Stufe (zum Zeitpunkt des Lagers)', true, 'agegroups') }}
|
||||||
|
<template x-if="data.agegroup === 'Leiter'">
|
||||||
|
{{ form.select(_context, 'agegroup_leader', 'Stufe die du leitest', false, 'agegroups_leaders') }}
|
||||||
|
</template>
|
||||||
|
<template x-if="data.agegroup !== 'Leiter'">
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
<template x-if="data.activity === 'Orga'">
|
||||||
|
{{ form.radio(_context, 'vorteam', 'Möchtest du am Vorteam teilnehmen?', true, 'boolean') }}
|
||||||
|
</template>
|
||||||
|
{{ form.checkboxes(_context, 'food_preferences', 'Essgewohnheiten & Unverträglichkeiten', false, 'foodPreferences') }}
|
||||||
|
</div>
|
||||||
|
{% partial __SELF__.alias ~ '::navigation' %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="{{gliderElClass}}">
|
||||||
|
<div class="{{descClass}}">Fast geschafft! Wenn du sonst noch etwas loswerden willst, kannst du das hier tun.</div>
|
||||||
|
<div class="flex flex-row items-center p-4 bg-red-100 border-2 border-red-400 rounded form-group shadow-sm" x-show="data.agegroup === 'Leiter'">
|
||||||
|
<div class="flex items-center justify-center w-8 h-8 mr-3 bg-red-500 rounded-full flex-none">
|
||||||
|
<div class="flex items-center justify-center w-5 h-5 bg-red-100 rounded-full">
|
||||||
|
<svg class="w-5 h-5 text-red-700 border-gray-400 fill-current border-5 fill-current"><use xlink:href="/themes/october-theme/resources/img/sprite.svg#exclamation"></use></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="grow text-sm font-semibold text-red-800">
|
||||||
|
<p>Als teilnehmende*r Leiter*in ist für die Teilnahme am BeLa ein eingereichtes Führungszeugnis ohne Einträge und eine aktive Präventionsschulung zwingend erforderlich.</p>
|
||||||
|
<p class="mt-2">Dies muss spätestens zu Beginn des BeLas vorliegen. Ansonsten kannst du nicht am BeLa teilnehmen.</p>
|
||||||
|
<p class="mt-2">Weitere Infos findest du in der <a class="text-rose-500 hover:text-rose-900" target="_BLANK" href="https://dpsg-koeln.de/fuer-mitglieder/faqs#pravention">FAQ-Sektion der Diözese Köln zu Prävention</a>. Außerdem kannst du dich auch an deinen StaVo oder den <a class="text-rose-500 hover:text-rose-900" href="mailto:vorstand@dpsgbergischland.de">Bezirksvorstand</a> wenden.</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-4 mt-6">
|
||||||
|
{{ form.textarea(_context, 'misc', 'Sonstige Anmerkungen', false) }}
|
||||||
|
{{ form.yesno(_context, 'foto', 'Ich akzeptiere, dass vor Ort Foto-und Videoaufnahmen von mir gemacht werden dürfen.', false) }}
|
||||||
|
</div>
|
||||||
|
{% partial __SELF__.alias ~ '::navigation' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
{#+++ Sidebar +++#}
|
||||||
|
<div class="relative hidden event-form-sidebar lg_block">
|
||||||
|
<div class="absolute w-full h-full">
|
||||||
|
<div class="sticky h-full bg-white rounded-lg shadow top-10">
|
||||||
|
<div class="relative">
|
||||||
|
<img src="{{__SELF__.event.header_image | media}}" class="object-cover w-full h-48">
|
||||||
|
<div class="absolute bottom-0 w-full px-4 py-2 leading-tight bg-white-t600">
|
||||||
|
<h3 class="text-primary-800 font-goudy">{{__SELF__.event.name}}</h3>
|
||||||
|
<div class="text-xs">{{ __SELF__.event.dates }} {{ __SELF__.event.times }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-auto" style="height: calc(100% - 12rem);">
|
||||||
|
<div class="p-4 text-gray-800 grid row-gap-2">
|
||||||
|
<h3 class="leading-tight text-primary-800 font-goudy">Persönliche Daten</h3>
|
||||||
|
<div class="leading-tight">
|
||||||
|
<div class="text-xs text-gray-600">Funktion</div>
|
||||||
|
<div class="text-sm" x-html="data.activity"></div>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight" x-show="hasAddress()">
|
||||||
|
<div class="text-xs text-gray-600">Name & Adresse</div>
|
||||||
|
<div class="text-sm">
|
||||||
|
<div x-html="`${data.firstname} ${data.lastname}`"></div>
|
||||||
|
<div x-html="data.address"></div>
|
||||||
|
<div x-html="`${data.zip} ${data.location}`"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight" x-show="data.birthday">
|
||||||
|
<div class="text-xs text-gray-600">Geburtsdatum</div>
|
||||||
|
<div class="text-sm" x-html="data.birthday"></div>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight" x-show="data.phone || data.email">
|
||||||
|
<div class="text-xs text-gray-600">Kontakt</div>
|
||||||
|
<div class="text-sm">
|
||||||
|
<div x-show="data.phone" x-html="`Tel: ${data.phone}`"></div>
|
||||||
|
<div x-show="data.email" x-html="`E-Mail: ${data.email}`"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 class="mt-4 leading-tight text-primary-800 font-goudy" x-show="data.region_id !=-1 || data.group_id != -1">Gruppierung</h3>
|
||||||
|
<div class="leading-tight" x-show="data.region_id != -1 || data.group_id != -1">
|
||||||
|
<div class="text-xs text-gray-600">Gruppierung</div>
|
||||||
|
<div class="text-sm">
|
||||||
|
<div x-html="data.group"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 class="mt-4 leading-tight text-primary-800 font-goudy" x-show="data.food_preferences.length > 0">Verpflegung</h3>
|
||||||
|
<div class="leading-tight" x-show="data.food_preferences.length > 0">
|
||||||
|
<div class="text-xs text-gray-600">Lebensmittelunverträglichkeiten</div>
|
||||||
|
<ul>
|
||||||
|
<template x-for="fi in data.food_preferences">
|
||||||
|
<li class="text-sm" x-html="fi"></li>
|
||||||
|
</template>
|
||||||
|
<li class="text-sm" x-show="data.further_food_intolerances" x-html="data.further_food_intolerances"></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<h3 class="mt-4 leading-tight text-primary-800 font-goudy" x-show="data.rooms || data.add_misc !== null || data.misc">Sonstiges</h3>
|
||||||
|
<div class="leading-tight" x-show="data.add_misc !== null">
|
||||||
|
<div class="text-xs text-gray-600">Barrierefreiheit</div>
|
||||||
|
<div class="text-sm" x-html="data.add_misc"></div>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight" x-show="data.rooms">
|
||||||
|
<div class="text-xs text-gray-600">Zimmerwünsche</div>
|
||||||
|
<div class="text-sm" x-html="data.rooms"></div>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight" x-show="data.misc">
|
||||||
|
<div class="text-xs text-gray-600">Sonstige Wünsche</div>
|
||||||
|
<div class="text-sm" x-html="data.misc"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
{#+++ Pflichtfeld +++ #}
|
||||||
|
<div class="mt-2 text-lg text-gray-800">
|
||||||
|
<span class="text-red-800">*</span> Pflichtfeld
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#+++ popup +++#}
|
||||||
|
|
||||||
|
<div class="popup" id="waiting-popup">
|
||||||
|
<div class="relative text-gray-600 popup-inner">
|
||||||
|
<script class="tmpl" type="text/html">
|
||||||
|
<div class="absolute top-0 right-0 flex items-center justify-center w-16 h-16 mt-4 mr-4 bg-yellow-500 rounded-full opacity-50">
|
||||||
|
<div class="flex items-center justify-center w-10 h-10 bg-yellow-100 rounded-full">
|
||||||
|
<svg class="w-10 h-10 text-yellow-700 border-gray-400 fill-current border-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 5h2v6H9V5zm0 8h2v2H9v-2z"/></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 class="flex-shrink-0 text-xl font-semibold text-gray-800">Auf die Warteliste setzen?</h2>
|
||||||
|
<h2 class="flex-shrink-0 text-sm font-semibold text-gray-600">Für <%= eventname %></h2>
|
||||||
|
<div class="relative mt-5 richeditor content small">
|
||||||
|
<h2>Was ist die Warteliste?</h2>
|
||||||
|
Wenn du dich für die Warteliste einträgst, wirst du automatisch per E-Mail benachrichtigt, wenn bei dieser Unterveranstaltung ein Platz frei wird. Du hast dann die Möglichkeit, zu dieser Unterveranstaltung zu wechseln, und meldest dich zeitgleich von einer beliebigen anderen Unterveranstaltung ab.
|
||||||
|
<h2>Was nun</h2>
|
||||||
|
Wähle bitte neben dieser Unterveranstaltung deine "regulären" Veranstatungen aus.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end mt-6">
|
||||||
|
<button class="mr-6 btn btn-shine btn-primary btn-sm" type="button" data-confirm>Auf Warteliste setzen</button>
|
||||||
|
<button class="btn-shine btn btn-danger btn-sm" type="button" data-reject>Nee, doch nicht</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</div>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<div class="flex mt-10 justify-evenly">
|
||||||
|
<a href="#" class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none rounded-lg" @click.prevent="onPrevButtonClick" :class="{'invisible': meta.active === 0}">
|
||||||
|
Zurück
|
||||||
|
</a>
|
||||||
|
<a href="#" class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none rounded-lg" @click.prevent="onNextButtonClick" x-show="meta.active != meta.slides.length-1">
|
||||||
|
Weiter
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none rounded-lg" x-show="meta.active == meta.slides.length-1">{% if p %} Anmeldung aktualisieren {% else %} Anmeldung absenden {% endif %}</button>
|
||||||
|
</div>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php namespace Zoomyboy\Event\Controllers;
|
||||||
|
|
||||||
|
use BackendMenu;
|
||||||
|
use Backend\Classes\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Participant Back-end Controller
|
||||||
|
*/
|
||||||
|
class Participant extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array Behaviors that are implemented by this controller.
|
||||||
|
*/
|
||||||
|
public $implement = [
|
||||||
|
'Backend.Behaviors.FormController',
|
||||||
|
'Backend.Behaviors.ListController'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Configuration file for the `FormController` behavior.
|
||||||
|
*/
|
||||||
|
public $formConfig = 'config_form.yaml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Configuration file for the `ListController` behavior.
|
||||||
|
*/
|
||||||
|
public $listConfig = 'config_list.yaml';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
BackendMenu::setContext('Zoomyboy.Event', 'event', 'participant');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div data-control="toolbar">
|
||||||
|
<a
|
||||||
|
href="<?= Backend::url('zoomyboy/event/participant/create') ?>"
|
||||||
|
class="btn btn-primary oc-icon-plus">
|
||||||
|
New Participant
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn btn-danger oc-icon-trash-o"
|
||||||
|
disabled="disabled"
|
||||||
|
onclick="$(this).data('request-data', { checked: $('.control-list').listWidget('getChecked') })"
|
||||||
|
data-request="onDelete"
|
||||||
|
data-request-confirm="Are you sure you want to delete the selected Participants?"
|
||||||
|
data-trigger-action="enable"
|
||||||
|
data-trigger=".control-list input[type=checkbox]"
|
||||||
|
data-trigger-condition="checked"
|
||||||
|
data-request-success="$(this).prop('disabled', 'disabled')"
|
||||||
|
data-stripe-load-indicator>
|
||||||
|
Delete selected
|
||||||
|
</button>
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
# ===================================
|
||||||
|
# Form Behavior Config
|
||||||
|
# ===================================
|
||||||
|
|
||||||
|
# Record name
|
||||||
|
name: Participant
|
||||||
|
|
||||||
|
# Model Form Field configuration
|
||||||
|
form: $/zoomyboy/event/models/participant/fields.yaml
|
||||||
|
|
||||||
|
# Model Class name
|
||||||
|
modelClass: Zoomyboy\Event\Models\Participant
|
||||||
|
|
||||||
|
# Default redirect location
|
||||||
|
defaultRedirect: zoomyboy/event/participant
|
||||||
|
|
||||||
|
# Create page
|
||||||
|
create:
|
||||||
|
title: backend::lang.form.create_title
|
||||||
|
redirect: zoomyboy/event/participant/update/:id
|
||||||
|
redirectClose: zoomyboy/event/participant
|
||||||
|
|
||||||
|
# Update page
|
||||||
|
update:
|
||||||
|
title: backend::lang.form.update_title
|
||||||
|
redirect: zoomyboy/event/participant
|
||||||
|
redirectClose: zoomyboy/event/participant
|
||||||
|
|
||||||
|
# Preview page
|
||||||
|
preview:
|
||||||
|
title: backend::lang.form.preview_title
|
|
@ -0,0 +1,50 @@
|
||||||
|
# ===================================
|
||||||
|
# List Behavior Config
|
||||||
|
# ===================================
|
||||||
|
|
||||||
|
# Model List Column configuration
|
||||||
|
list: $/zoomyboy/event/models/participant/columns.yaml
|
||||||
|
|
||||||
|
# Model Class name
|
||||||
|
modelClass: Zoomyboy\Event\Models\Participant
|
||||||
|
|
||||||
|
# List Title
|
||||||
|
title: Manage Participants
|
||||||
|
|
||||||
|
# Link URL for each record
|
||||||
|
recordUrl: zoomyboy/event/participant/update/:id
|
||||||
|
|
||||||
|
# Message to display if the list is empty
|
||||||
|
noRecordsMessage: backend::lang.list.no_records
|
||||||
|
|
||||||
|
# Records to display per page
|
||||||
|
recordsPerPage: 20
|
||||||
|
|
||||||
|
# Options to provide the user when selecting how many records to display per page
|
||||||
|
perPageOptions: [20, 40, 80, 100, 120]
|
||||||
|
|
||||||
|
# Display page numbers with pagination, disable to improve performance
|
||||||
|
showPageNumbers: true
|
||||||
|
|
||||||
|
# Displays the list column set up button
|
||||||
|
showSetup: true
|
||||||
|
|
||||||
|
# Displays the sorting link on each column
|
||||||
|
showSorting: true
|
||||||
|
|
||||||
|
# Default sorting column
|
||||||
|
# defaultSort:
|
||||||
|
# column: created_at
|
||||||
|
# direction: desc
|
||||||
|
|
||||||
|
# Display checkboxes next to each record
|
||||||
|
showCheckboxes: true
|
||||||
|
|
||||||
|
# Toolbar widget configuration
|
||||||
|
toolbar:
|
||||||
|
# Partial for toolbar buttons
|
||||||
|
buttons: list_toolbar
|
||||||
|
|
||||||
|
# Search widget configuration
|
||||||
|
search:
|
||||||
|
prompt: backend::lang.list.search_prompt
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php Block::put('breadcrumb') ?>
|
||||||
|
<ul>
|
||||||
|
<li><a href="<?= Backend::url('zoomyboy/event/participant') ?>">Participant</a></li>
|
||||||
|
<li><?= e($this->pageTitle) ?></li>
|
||||||
|
</ul>
|
||||||
|
<?php Block::endPut() ?>
|
||||||
|
|
||||||
|
<?php if (!$this->fatalError): ?>
|
||||||
|
|
||||||
|
<?= Form::open(['class' => 'layout']) ?>
|
||||||
|
|
||||||
|
<div class="layout-row">
|
||||||
|
<?= $this->formRender() ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-buttons">
|
||||||
|
<div class="loading-indicator-container">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
data-request="onSave"
|
||||||
|
data-hotkey="ctrl+s, cmd+s"
|
||||||
|
data-load-indicator="Creating Participant..."
|
||||||
|
class="btn btn-primary">
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-request="onSave"
|
||||||
|
data-request-data="close:1"
|
||||||
|
data-hotkey="ctrl+enter, cmd+enter"
|
||||||
|
data-load-indicator="Creating Participant..."
|
||||||
|
class="btn btn-default">
|
||||||
|
Create and Close
|
||||||
|
</button>
|
||||||
|
<span class="btn-text">
|
||||||
|
or <a href="<?= Backend::url('zoomyboy/event/participant') ?>">Cancel</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?= Form::close() ?>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
|
||||||
|
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||||
|
<p><a href="<?= Backend::url('zoomyboy/event/participant') ?>" class="btn btn-default">Return to participant list</a></p>
|
||||||
|
|
||||||
|
<?php endif ?>
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
<?= $this->listRender() ?>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php Block::put('breadcrumb') ?>
|
||||||
|
<ul>
|
||||||
|
<li><a href="<?= Backend::url('zoomyboy/event/participant') ?>">Participant</a></li>
|
||||||
|
<li><?= e($this->pageTitle) ?></li>
|
||||||
|
</ul>
|
||||||
|
<?php Block::endPut() ?>
|
||||||
|
|
||||||
|
<?php if (!$this->fatalError): ?>
|
||||||
|
|
||||||
|
<div class="form-preview">
|
||||||
|
<?= $this->formRenderPreview() ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
|
||||||
|
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||||
|
<p><a href="<?= Backend::url('zoomyboy/event/participant') ?>" class="btn btn-default">Return to participant list</a></p>
|
||||||
|
|
||||||
|
<?php endif ?>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php Block::put('breadcrumb') ?>
|
||||||
|
<ul>
|
||||||
|
<li><a href="<?= Backend::url('zoomyboy/event/participant') ?>">Participant</a></li>
|
||||||
|
<li><?= e($this->pageTitle) ?></li>
|
||||||
|
</ul>
|
||||||
|
<?php Block::endPut() ?>
|
||||||
|
|
||||||
|
<?php if (!$this->fatalError): ?>
|
||||||
|
|
||||||
|
<?= Form::open(['class' => 'layout']) ?>
|
||||||
|
|
||||||
|
<div class="layout-row">
|
||||||
|
<?= $this->formRender() ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-buttons">
|
||||||
|
<div class="loading-indicator-container">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
data-request="onSave"
|
||||||
|
data-request-data="redirect:0"
|
||||||
|
data-hotkey="ctrl+s, cmd+s"
|
||||||
|
data-load-indicator="Saving Participant..."
|
||||||
|
class="btn btn-primary">
|
||||||
|
<u>S</u>ave
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-request="onSave"
|
||||||
|
data-request-data="close:1"
|
||||||
|
data-hotkey="ctrl+enter, cmd+enter"
|
||||||
|
data-load-indicator="Saving Participant..."
|
||||||
|
class="btn btn-default">
|
||||||
|
Save and Close
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="oc-icon-trash-o btn-icon danger pull-right"
|
||||||
|
data-request="onDelete"
|
||||||
|
data-load-indicator="Deleting Participant..."
|
||||||
|
data-request-confirm="Delete this participant?">
|
||||||
|
</button>
|
||||||
|
<span class="btn-text">
|
||||||
|
or <a href="<?= Backend::url('zoomyboy/event/participant') ?>">Cancel</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?= Form::close() ?>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
|
||||||
|
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||||
|
<p><a href="<?= Backend::url('zoomyboy/event/participant') ?>" class="btn btn-default">Return to participant list</a></p>
|
||||||
|
|
||||||
|
<?php endif ?>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'attributes' => [
|
||||||
|
'firstname' => 'Vorname',
|
||||||
|
'lastname' => 'Nachname',
|
||||||
|
'activity' => 'Funktion',
|
||||||
|
'gender' => 'Geschlecht',
|
||||||
|
'birthday' => 'Geburtsdatum',
|
||||||
|
'address' => 'Straße & Hausnr',
|
||||||
|
'zip' => 'PLZ',
|
||||||
|
'location' => 'Ort',
|
||||||
|
'phone' => 'Telefonnummer',
|
||||||
|
'email' => 'E-Mail-Adresse',
|
||||||
|
'agegroup' => 'Stufe',
|
||||||
|
'emergency_phone' => 'Notfallkontakt',
|
||||||
|
],
|
||||||
|
];
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\Event\Models;
|
||||||
|
|
||||||
|
use Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Participant Model.
|
||||||
|
*/
|
||||||
|
class Participant extends Model
|
||||||
|
{
|
||||||
|
use \Winter\Storm\Database\Traits\Validation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string the database table used by the model
|
||||||
|
*/
|
||||||
|
public $table = 'zoomyboy_event_participants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Guarded fields
|
||||||
|
*/
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Fillable fields
|
||||||
|
*/
|
||||||
|
protected $fillable = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Validation rules for attributes
|
||||||
|
*/
|
||||||
|
public $rules = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Attributes to be cast to native types
|
||||||
|
*/
|
||||||
|
protected $casts = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Attributes to be cast to JSON
|
||||||
|
*/
|
||||||
|
protected $jsonable = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Attributes to be appended to the API representation of the model (ex. toArray())
|
||||||
|
*/
|
||||||
|
protected $appends = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Attributes to be removed from the API representation of the model (ex. toArray())
|
||||||
|
*/
|
||||||
|
protected $hidden = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Attributes to be cast to Argon (Carbon) instances
|
||||||
|
*/
|
||||||
|
protected $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Relations
|
||||||
|
*/
|
||||||
|
public $hasOne = [];
|
||||||
|
public $hasMany = [];
|
||||||
|
public $hasOneThrough = [];
|
||||||
|
public $hasManyThrough = [];
|
||||||
|
public $belongsTo = [];
|
||||||
|
public $belongsToMany = [];
|
||||||
|
public $morphTo = [];
|
||||||
|
public $morphOne = [];
|
||||||
|
public $morphMany = [];
|
||||||
|
public $attachOne = [];
|
||||||
|
public $attachMany = [];
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
# ===================================
|
||||||
|
# List Column Definitions
|
||||||
|
# ===================================
|
||||||
|
|
||||||
|
columns:
|
||||||
|
firstname:
|
||||||
|
label: Vorname
|
||||||
|
|
||||||
|
lastname:
|
||||||
|
label: Nachname
|
||||||
|
|
||||||
|
email:
|
||||||
|
label: E-Mail-Adresse
|
||||||
|
|
||||||
|
group:
|
||||||
|
label: Stamm
|
||||||
|
|
||||||
|
activity:
|
||||||
|
label: Funktion
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# ===================================
|
||||||
|
# Form Field Definitions
|
||||||
|
# ===================================
|
||||||
|
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
label: ID
|
||||||
|
disabled: true
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\Event\Updates;
|
||||||
|
|
||||||
|
use Schema;
|
||||||
|
use Winter\Storm\Database\Schema\Blueprint;
|
||||||
|
use Winter\Storm\Database\Updates\Migration;
|
||||||
|
|
||||||
|
class CreateParticipantsTable extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
|
||||||
|
$table->engine = 'InnoDB';
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('gender');
|
||||||
|
$table->string('firstname');
|
||||||
|
$table->string('lastname');
|
||||||
|
$table->date('birthday');
|
||||||
|
$table->string('email');
|
||||||
|
$table->string('group')->nullable();
|
||||||
|
$table->string('agegroup');
|
||||||
|
$table->string('agegroup_leader');
|
||||||
|
$table->boolean('vorteam');
|
||||||
|
$table->boolean('foto');
|
||||||
|
$table->string('emergency_phone');
|
||||||
|
$table->string('address');
|
||||||
|
$table->string('zip');
|
||||||
|
$table->string('location');
|
||||||
|
$table->string('phone');
|
||||||
|
$table->string('activity');
|
||||||
|
$table->json('food_preferences');
|
||||||
|
$table->string('further_food_preferences')->nullable();
|
||||||
|
$table->text('misc')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('zoomyboy_event_participants');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
1.0.1: First version of event
|
||||||
|
1.0.2:
|
||||||
|
- create_participants_table.php
|
Loading…
Reference in New Issue