Add event relation

This commit is contained in:
philipp lang 2023-02-12 01:25:16 +01:00
parent 70e2eef16f
commit 810ced2efb
22 changed files with 505 additions and 39 deletions

View File

@ -86,6 +86,22 @@ class Plugin extends PluginBase
'icon' => 'icon-leaf',
'permissions' => ['zoomyboy.event.*'],
'order' => 500,
'sideMenu' => [
'event' => [
'label' => 'Veranstaltungen',
'url' => Backend::url('zoomyboy/event/event'),
'icon' => 'icon-leaf',
'permissions' => ['zoomyboy.event.*'],
'order' => 500,
],
'participant' => [
'label' => 'Teilnehmer',
'url' => Backend::url('zoomyboy/event/participant'),
'icon' => 'icon-leaf',
'permissions' => ['zoomyboy.event.*'],
'order' => 500,
],
],
],
];
}

View File

@ -13,6 +13,7 @@ export default function (toasted) {
return {
data: {
event_id: null,
firstname: '',
lastname: '',
address: '',
@ -30,6 +31,7 @@ export default function (toasted) {
phone: '',
misc: '',
foto: false,
parent: false,
vorteam: null,
},
meta: {
@ -52,14 +54,14 @@ export default function (toasted) {
{"id": "Divers", "name": "Divers"},
],
groups: [
{"id": "Gallier", "name": "Gallier"},
{"id": "Gandalf", "name": "Gandalf"},
{"id": "Gravenrode", "name": "Gravenrode"},
{"id": "Lennep", "name": "Lennep"},
{"id": "Silva", "name": "Silva"},
{"id": "Sugambrer", "name": "Sugambrer"},
{"id": "Tenkterer", "name": "Tenkterer"},
{"id": "von Berg", "name": "von Berg"},
{"id": "Gallier", "name": "Gallier (Wuppertal)"},
{"id": "Gandalf", "name": "Gandalf (SG-Mangenberg)"},
{"id": "Gravenrode", "name": "Gravenrode (SG-Gräfrath)"},
{"id": "Lennep", "name": "Lennep (RS-Lennep)"},
{"id": "Silva", "name": "Silva (SG-Wald)"},
{"id": "Sugambrer", "name": "Sugambrer (SG-Höhscheid)"},
{"id": "Tenkterer", "name": "Tenkterer (SG-Löhdorf)"},
{"id": "von Berg", "name": "von Berg (SG-Ohligs)"},
],
agegroups: [
{"id": "Biber", "name": "Biber"},
@ -81,13 +83,16 @@ export default function (toasted) {
{"id": "Nein", "name": "Nein"},
],
foodPreferences: [
{"id": "Fleisch", "name": "Fleisch"},
{"id": "Vegan", "name": "Vegan"},
{"id": "Glutenfrei", "name": "Glutenfrei"},
{"id": "Laktosefrei", "name": "Laktosefrei"},
{"id": "Fleisch", "name": "Ich esse Fleisch"},
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
]
},
methods: {
uuu(event) {
console.log(event);
},
hasAddress() {
return this.data.location && this.data.address && this.data.zip;
},
@ -132,6 +137,7 @@ export default function (toasted) {
}
if (response.status === 201) {
_self.meta.finished = true;
_self.scrollForm(_self.$refs.form);
}
});
},

View File

@ -8,10 +8,13 @@ use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Mail;
use Input;
use Winter\Storm\Support\Facades\Validator;
use Zoomyboy\Event\Models\Event;
use Zoomyboy\Event\Models\Participant;
class EventForm extends ComponentBase
{
public Event $event;
public function componentDetails()
{
return [
@ -22,11 +25,27 @@ class EventForm extends ComponentBase
public function defineProperties()
{
return [];
return [
'event_id' => [
'label' => 'ID',
],
];
}
private function customInit(int $eventId)
{
$this->event = Event::findOrFail($eventId);
}
public function onRender()
{
$this->customInit($this->property('event_id'));
}
public function onSubmit(): JsonResponse
{
$this->customInit(Input::get('event_id'));
$rules = [
'activity' => 'required|max:255',
'gender' => 'required|max:255',
@ -45,6 +64,7 @@ class EventForm extends ComponentBase
'food_preferences' => 'array',
'misc' => '',
'foto' => '',
'parent' => 'boolean|accepted',
];
if ('Orga' === Input::get('activity')) {
@ -53,6 +73,7 @@ class EventForm extends ComponentBase
$validator = Validator::make(Input::all(), $rules, [
'vorteam.in' => 'Bitte gebe an, ob du am Vorteam teilnehmen willst.',
'parent.accepted' => 'Bitte gebe an, dass du volljährig bzw. ein Elternteil bist.',
], Lang::get('zoomyboy.event::validation.attributes'));
if ($validator->fails()) {
@ -61,11 +82,12 @@ class EventForm extends ComponentBase
$participant = Participant::create(array_merge($validator->validated(), [
'vorteam' => 'Ja' === Input::get('vorteam'),
'event_id' => $this->event->id,
]));
// Mail::send('zoomyboy.event::mail.confirm', ['data' => $participant, 'until' => '1.9.2023', 'iban' => 'XXX', 'birthday' => $participant->birthday->format('d.m.Y')], function ($message) use ($participant) {
// $message->to($participant->email, $participant->firstname.' '.$participant->lastname);
// $message->subject('Deine Anmeldung fürs Bezirkslager');
// });
Mail::send('zoomyboy.event::mail.confirm', ['data' => $participant, 'until' => '1.9.2023', 'iban' => 'XXX', 'birthday' => $participant->birthday->format('d.m.Y')], function ($message) use ($participant) {
$message->to($participant->email, $participant->firstname.' '.$participant->lastname);
$message->subject('Deine Anmeldung fürs Bezirkslager');
});
return response()->json([], 201);
}

View File

@ -4,9 +4,11 @@
{% 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-1 px-2 sm:py-2 text-sm sm:text-base sm:px-3 w-full" x-model="data.{{name}}" />
<input name="{{name}}" type="{{type|default('text')}}" id="{{name}}" placeholder=" " @keyup="uuu" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-1 px-2 sm:py-2 text-sm sm:text-base sm: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-xs xs: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-xs xs:peer-focus:text-sm"
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 peer-placeholder-shown:bottom-0 peer-placeholder-shown:-top-0
text-xs xs:text-sm peer-placeholder-shown:text-sm xs:peer-placeholder-shown:text-base peer-focus:text-xs xs:peer-focus:text-sm
peer-focus:-top-3 peer-focus:bottom-auto "
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
>
</label>
@ -16,7 +18,7 @@
<textarea name="{{name}}" rows="6" id="{{name}}" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-1 px-2 sm:py-2 text-sm sm:text-base sm: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-xs sm:text-sm"
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-xs xs:text-sm"
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
>
</label>
@ -30,7 +32,7 @@
</template>
</select>
<span
class="absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-xs sm:text-sm"
class="absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-xs xs:text-sm"
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
>
</label>
@ -60,7 +62,7 @@
<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>
<span class="pl-8">{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span>
</label>
</div>
</div>
@ -71,7 +73,7 @@
class="text-gray-600 flex text-sm"
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
>
<div class="grid grid-cols-2 sm:grid-cols-1 gap-2">
<div class="mt-2 grid gap-2">
<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}`" />
@ -86,7 +88,10 @@
{% import _self as form %}
<div x-data="{
data: eventRegistration.data,
data: {
...eventRegistration.data,
event_id: {{__SELF__.event.id}}
},
meta: {
...eventRegistration.meta,
submitRequest: '{{__SELF__.alias ~ '::onSubmit'}}',
@ -98,13 +103,16 @@
{#+++ registrationForm +++#}
<form x-ref="form" @submit.prevent="submit" class="my-6" novalidate>
<div x-ref="eventFormContainer" class="{{formContainerClass}}" x-show="meta.finished === false">
{% 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 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 relative" %}
{% set positionClass = "flex items-center justify-center w-4 md:w-6 h-4 md:h-6 rounded-full bg-teal-800 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 }">
<svg preserveAspectRatio="none" class="h-full w-3 absolute left-0 text-emerald-500 transition duration-300" viewBox="0 0 100 100" :class="{'opacity-100': index !== 0 && index-1 <= meta.active, 'opacity-0': !(index !== 0 && index-1 <= meta.active)}">
<path d="M0,0 100,50 0,100" fill="currentColor"></path>
</svg>
<span class="{{positionClass}}" x-html="index+1"></span>
<span class="{{arrowFont}}" x-html="slide"></span>
</a>
@ -147,9 +155,13 @@
{{ form.field(_context, 'birthday', 'Geburtsdatum', true, 'date') }}
{{ form.field(_context, 'address', 'Addresse', true) }}
{{ form.field(_context, 'zip', 'PLZ', true) }}
{{ form.field(_context, 'location', 'Ort', true) }}
{{ form.field(_context, 'phone', 'Tel', true, 'tel') }}
{{ form.field(_context, 'email', 'E-Mail', true, 'email') }}
{{ form.field(_context, 'location', 'Wohnort', true) }}
<div class="col-span-full sm:col-span-1">
{{ form.field(_context, 'phone', 'Telefonnummer', true, 'tel') }}
</div>
<div class="col-span-full sm:col-span-1">
{{ form.field(_context, 'email', 'E-Mail-Adresse', true, 'email') }}
</div>
</div>
{% partial __SELF__.alias ~ '::navigation' first="1" %}
</div>
@ -191,6 +203,7 @@
<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) }}
{{ form.yesno(_context, 'parent', 'Ich bin über 18 Jahre alt oder für die genannte Person erziehungsberechtigt.', true) }}
</div>
{% partial __SELF__.alias ~ '::navigation' last="1" %}
</div>
@ -199,9 +212,9 @@
</div>
<div class="{{formContainerClass}} max-w-[700px] mx-auto" x-show="meta.finished === true">
<div class="bg-white shadow-2xl ring-1 ring-gray-900/5 rounded-xl grid grid-cols-1 sm:grid-cols-[1fr_250px] grid-rows-[10rem_1fr] gap-6 overflow-hidden bg-gradient-to-bl from-white via-white to-black/10">
<div class="bg-primary w-40 h-40 flex justify-center items-center [clip-path:circle(70%_at_30%_30%)]">
<svg class="w-24 h-24 text-emerald-300 relative -left-3 -top-3" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<div class="bg-white shadow-2xl ring-1 ring-gray-900/5 rounded-xl grid grid-cols-1 sm:grid-cols-[1fr_250px] grid-rows-[5rem_1fr] sm:grid-rows-[12rem_1fr] gap-6 overflow-hidden bg-gradient-to-bl from-white via-white to-black/10">
<div class="bg-primary w-32 h-32 md:w-40 md:h-40 flex justify-center items-center [clip-path:circle(70%_at_30%_30%)]">
<svg class="w-20 h-20 md:w-24 md:h-24 text-emerald-300 relative -left-3 -top-3" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</div>
@ -216,9 +229,9 @@
<img class="w-64 h-32 object-cover" src="{{'danke/2.jpg'|media}}" />
</div>
</div>
<div class="self-end flex-grow pb-8 pl-8 pr-8 sm:pr-0">
<div class="self-end flex-grow pb-8 pl-8 pr-8 sm:pr-0 pt-6 sm:pt-0">
<div class="font-bold text-xl">Vielen Dank für deine Anmeldung.</div>
<div class="text-sm mt-4">In Kürze erhalten Sie eine Bestätigung per E-Mail mit weiteren Zahlungs-Infos. Eine letzte Info wird dir zeitnah vor dem Lager zugeschickt.</div>
<div class="text-sm mt-4">In Kürze erhälst du eine Bestätigung per E-Mail mit weiteren Zahlungs-Infos. Eine letzte Info wird dir zeitnah vor dem Lager zugeschickt.</div>
</div>
</div>
</div>

25
controllers/Event.php Normal file
View File

@ -0,0 +1,25 @@
<?php namespace Zoomyboy\Event\Controllers;
use BackendMenu;
use Backend\Classes\Controller;
/**
* Event Backend Controller
*/
class Event extends Controller
{
/**
* @var array Behaviors that are implemented by this controller.
*/
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class,
];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Zoomyboy.Event', 'event', 'event');
}
}

View File

@ -0,0 +1,21 @@
<div data-control="toolbar">
<a
href="<?= Backend::url('zoomyboy/event/event/create') ?>"
class="btn btn-primary wn-icon-plus">
<?= e(trans('backend::lang.form.create_title', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>
</a>
<button
class="btn btn-danger wn-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', { checked: $('.control-list').listWidget('getChecked') })"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')); ?>"
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>
<?= e(trans('backend::lang.list.delete_selected')); ?>
</button>
</div>

View File

@ -0,0 +1,31 @@
# ===================================
# Form Behavior Config
# ===================================
# Record name
name: 'zoomyboy.event::lang.models.event.label'
# Model Form Field configuration
form: $/zoomyboy/event/models/event/fields.yaml
# Model Class name
modelClass: Zoomyboy\Event\Models\Event
# Default redirect location
defaultRedirect: zoomyboy/event/event
# Create page
create:
title: backend::lang.form.create_title
redirect: zoomyboy/event/event/update/:id
redirectClose: zoomyboy/event/event
# Update page
update:
title: backend::lang.form.update_title
redirect: zoomyboy/event/event
redirectClose: zoomyboy/event/event
# Preview page
preview:
title: backend::lang.form.preview_title

View File

@ -0,0 +1,50 @@
# ===================================
# List Behavior Config
# ===================================
# Model List Column configuration
list: $/zoomyboy/event/models/event/columns.yaml
# Model Class name
modelClass: Zoomyboy\Event\Models\Event
# List Title
title: 'zoomyboy.event::lang.models.event.label_plural'
# Link URL for each record
recordUrl: zoomyboy/event/event/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

View File

@ -0,0 +1,48 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('zoomyboy/event/event') ?>"><?= e(trans('zoomyboy.event::lang.models.event.label_plural')); ?></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="button"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')); ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')); ?>
</button>
<span class="btn-text">
or <a href="<?= Backend::url('zoomyboy/event/event') ?>"><?= e(trans('backend::lang.form.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/event') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,19 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('zoomyboy/event/event') ?>"><?= e(trans('zoomyboy.event::lang.models.event.label_plural')); ?></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/event') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,56 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('zoomyboy/event/event') ?>">Event</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="button"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')); ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')); ?>
</button>
<button
type="button"
class="wn-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting_name', ['name' => trans('zoomyboy.event::lang.models.event.label')])); ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')); ?>">
</button>
<span class="btn-text">
or <a href="<?= Backend::url('zoomyboy/event/event') ?>"><?= e(trans('backend::lang.form.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/event') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

15
lang/de/lang.php Normal file
View File

@ -0,0 +1,15 @@
<?php
return [
'models' => [
'general' => [
'id' => 'ID',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
],
'event' => [
'label' => 'Event',
'label_plural' => 'Events',
],
],
];

84
models/Event.php Normal file
View File

@ -0,0 +1,84 @@
<?php
namespace Zoomyboy\Event\Models;
use Model;
/**
* Event Model.
*/
class Event extends Model
{
use \Winter\Storm\Database\Traits\Validation;
use \Winter\Storm\Database\Traits\Sluggable;
/**
* @var string the database table used by the model
*/
public $table = 'zoomyboy_event_events';
protected $slugs = ['slug' => 'name'];
/**
* @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 = [];
public static function getOptions(): array
{
return static::pluck('name', 'id')->toArray();
}
}

View File

@ -67,7 +67,9 @@ class Participant extends Model
public $hasMany = [];
public $hasOneThrough = [];
public $hasManyThrough = [];
public $belongsTo = [];
public $belongsTo = [
'event' => [Event::class],
];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];

View File

@ -0,0 +1,8 @@
# ===================================
# List Column Definitions
# ===================================
columns:
name:
label: Name
searchable: true

7
models/event/fields.yaml Normal file
View File

@ -0,0 +1,7 @@
# ===================================
# Form Field Definitions
# ===================================
fields:
name:
label: Name

View File

@ -18,3 +18,7 @@ columns:
activity:
label: Funktion
event:
relation: event
label: Veranstaltung
valueFrom: name

View File

@ -3,6 +3,7 @@
# ===================================
fields:
id:
label: ID
disabled: true
firstname:
label: Vorname
lastname:
label: Nachname

View File

@ -0,0 +1,33 @@
<?php
namespace Zoomyboy\Event\Updates;
use Schema;
use Winter\Storm\Database\Schema\Blueprint;
use Winter\Storm\Database\Updates\Migration;
class CreateEventsTable extends Migration
{
public function up()
{
Schema::create('zoomyboy_event_events', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
Schema::table('zoomyboy_event_participants', function (Blueprint $table) {
$table->foreignId('event_id')->constrained('zoomyboy_event_events');
});
}
public function down()
{
Schema::dropIfExists('zoomyboy_event_events');
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
$table->dropColumn('event_id');
});
}
}

View File

@ -11,8 +11,7 @@ class CreateParticipantsTable extends Migration
public function up()
{
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->id();
$table->string('gender');
$table->string('firstname');
$table->string('lastname');
@ -23,6 +22,7 @@ class CreateParticipantsTable extends Migration
$table->string('agegroup_leader');
$table->boolean('vorteam')->default(false);
$table->boolean('foto');
$table->boolean('parent');
$table->string('emergency_phone');
$table->string('address');
$table->string('zip');

View File

@ -1,3 +1,7 @@
1.0.1: First version of event
1.0.2:
- part
- create_participants_table.php
1.0.3:
- event
- create_events_table.php