mirror of
https://github.com/Einundzwanzig-Podcast/einundzwanzig-portal.git
synced 2025-12-11 06:46:47 +00:00
add media stuff
This commit is contained in:
@@ -2,9 +2,9 @@ models:
|
||||
Category: { name: string, slug: string }
|
||||
City: { country_id: biginteger, name: string, slug: string, longitude: 'float:10', latitude: 'float:10' }
|
||||
Country: { name: string, code: string }
|
||||
Course: { lecturer_id: biginteger, name: string }
|
||||
Event: { course_id: biginteger, venue_id: biginteger, '"from"': datetime, '"to"': datetime }
|
||||
Lecturer: { team_id: biginteger, name: string, slug: string, active: 'boolean default:1' }
|
||||
Course: { lecturer_id: biginteger, name: string, description: 'text nullable' }
|
||||
Event: { course_id: biginteger, venue_id: biginteger, '"from"': datetime, '"to"': datetime, link: string }
|
||||
Lecturer: { team_id: biginteger, name: string, slug: string, active: 'boolean default:1', description: 'text nullable' }
|
||||
LoginKey: { k1: string, user_id: biginteger }
|
||||
Membership: { team_id: biginteger, user_id: biginteger, role: 'string nullable' }
|
||||
Participant: { first_name: string, last_name: string }
|
||||
|
||||
@@ -13,6 +13,10 @@ class EventTable extends DataTableComponent
|
||||
|
||||
protected $model = Event::class;
|
||||
|
||||
public bool $viewingModal = false;
|
||||
|
||||
public $currentModal;
|
||||
|
||||
public function configure(): void
|
||||
{
|
||||
$this
|
||||
@@ -51,6 +55,10 @@ class EventTable extends DataTableComponent
|
||||
->sortable(),
|
||||
Column::make("Kurs", "course.name")
|
||||
->sortable(),
|
||||
Column::make("Art")
|
||||
->label(
|
||||
fn($row, Column $column) => view('columns.events.categories')->withRow($row)
|
||||
),
|
||||
Column::make("Von", "from")
|
||||
->format(
|
||||
fn($value, $row, Column $column) => $value->asDateTime()
|
||||
@@ -83,4 +91,20 @@ class EventTable extends DataTableComponent
|
||||
->whereHas('venue.city.country',
|
||||
fn($query) => $query->where('countries.code', $this->country));
|
||||
}
|
||||
|
||||
public function viewHistoryModal($modelId): void
|
||||
{
|
||||
$this->viewingModal = true;
|
||||
$this->currentModal = Event::findOrFail($modelId);
|
||||
}
|
||||
|
||||
public function resetModal(): void
|
||||
{
|
||||
$this->reset('viewingModal', 'currentModal');
|
||||
}
|
||||
|
||||
public function customView(): string
|
||||
{
|
||||
return 'modals.events.register';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,15 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Image\Manipulations;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class Course extends Model
|
||||
class Course extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithMedia;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
@@ -26,6 +31,27 @@ class Course extends Model
|
||||
'lecturer_id' => 'integer',
|
||||
];
|
||||
|
||||
public function registerMediaConversions(Media $media = null): void
|
||||
{
|
||||
$this
|
||||
->addMediaConversion('preview')
|
||||
->fit(Manipulations::FIT_CROP, 300, 300)
|
||||
->nonQueued();
|
||||
$this->addMediaConversion('thumb')
|
||||
->fit(Manipulations::FIT_CROP, 130, 130)
|
||||
->width(130)
|
||||
->height(130);
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('logo')
|
||||
->singleFile()
|
||||
->useFallbackUrl(asset('img/einundzwanzig-cover-lesestunde.png'));
|
||||
$this->addMediaCollection('images')
|
||||
->useFallbackUrl(asset('img/einundzwanzig-cover-lesestunde.png'));
|
||||
}
|
||||
|
||||
public function categories(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Category::class);
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Ebess\AdvancedNovaMediaLibrary\Fields\Images;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\BelongsToMany;
|
||||
use Laravel\Nova\Fields\Field;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Markdown;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
use ZiffMedia\NovaSelectPlus\SelectPlus;
|
||||
@@ -56,9 +58,20 @@ class Course extends Resource
|
||||
ID::make()
|
||||
->sortable(),
|
||||
|
||||
Images::make('Main picture', 'logo')
|
||||
->conversionOnIndexView('thumb'),
|
||||
|
||||
Images::make('Images', 'images')
|
||||
->conversionOnIndexView('thumb')
|
||||
->help('Lade hier Bilder hoch, um sie eventuell später in der Markdown Description einzufügen. Du musst vorher aber Speichern.'),
|
||||
|
||||
Text::make('Name')
|
||||
->rules('required', 'string'),
|
||||
|
||||
Markdown::make('Description')
|
||||
->alwaysShow()
|
||||
->help('Markdown ist erlaubt. Du kannst Bilder aus dem Feld "Images" hier einfügen. Benutze das Link Symbol der Bilder für die Urls, nach dem du auf "Aktualisieren und Weiterarbeiten" geklickt hast.'),
|
||||
|
||||
BelongsTo::make('Lecturer'),
|
||||
|
||||
SelectPlus::make('Categories', 'categories', Category::class)
|
||||
|
||||
@@ -8,6 +8,7 @@ use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\DateTime;
|
||||
use Laravel\Nova\Fields\Field;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\URL;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
|
||||
class Event extends Resource
|
||||
@@ -55,13 +56,18 @@ class Event extends Resource
|
||||
ID::make()
|
||||
->sortable(),
|
||||
|
||||
URL::make('Link')
|
||||
->rules('required', 'url'),
|
||||
|
||||
DateTime::make('From')
|
||||
->rules('required')
|
||||
->step(CarbonInterval::minutes(30))->displayUsing(fn ($value) => $value->asDateTime()),
|
||||
->step(CarbonInterval::minutes(30))
|
||||
->displayUsing(fn($value) => $value->asDateTime()),
|
||||
|
||||
DateTime::make('To')
|
||||
->rules('required')
|
||||
->step(CarbonInterval::minutes(30))->displayUsing(fn ($value) => $value->asDateTime()),
|
||||
->step(CarbonInterval::minutes(30))
|
||||
->displayUsing(fn($value) => $value->asDateTime()),
|
||||
|
||||
BelongsTo::make('Course'),
|
||||
BelongsTo::make('Venue')
|
||||
|
||||
22
composer.lock
generated
22
composer.lock
generated
@@ -3132,16 +3132,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.10.4",
|
||||
"version": "3.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "a7790f3dd1b27af81d380e6b2afa77c16ab7e181"
|
||||
"reference": "7e423e5dd240a60adfab9bde058d7668863b7731"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a7790f3dd1b27af81d380e6b2afa77c16ab7e181",
|
||||
"reference": "a7790f3dd1b27af81d380e6b2afa77c16ab7e181",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/7e423e5dd240a60adfab9bde058d7668863b7731",
|
||||
"reference": "7e423e5dd240a60adfab9bde058d7668863b7731",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3203,7 +3203,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.10.4"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.11.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3219,7 +3219,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-26T19:48:01+00:00"
|
||||
"time": "2022-12-02T14:39:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/glide",
|
||||
@@ -11254,16 +11254,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel-lang/lang",
|
||||
"version": "12.5.5",
|
||||
"version": "12.5.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Laravel-Lang/lang.git",
|
||||
"reference": "6d4f8ccd4694530f0c4c424eded37d5b1308c062"
|
||||
"reference": "f0503d6bb897070c906847858eab9b4d6e40a85c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Laravel-Lang/lang/zipball/6d4f8ccd4694530f0c4c424eded37d5b1308c062",
|
||||
"reference": "6d4f8ccd4694530f0c4c424eded37d5b1308c062",
|
||||
"url": "https://api.github.com/repos/Laravel-Lang/lang/zipball/f0503d6bb897070c906847858eab9b4d6e40a85c",
|
||||
"reference": "f0503d6bb897070c906847858eab9b4d6e40a85c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11325,7 +11325,7 @@
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-01T13:15:55+00:00"
|
||||
"time": "2022-12-03T12:40:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-lang/publisher",
|
||||
|
||||
@@ -13,6 +13,7 @@ return new class extends Migration {
|
||||
{
|
||||
Schema::table('lecturers', function (Blueprint $table) {
|
||||
$table->longText('description')
|
||||
->fulltext()
|
||||
->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('courses', function (Blueprint $table) {
|
||||
$table->longText('description')
|
||||
->fulltext()
|
||||
->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('courses', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('events', function (Blueprint $table) {
|
||||
$table->string('link');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('events', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -107,6 +107,7 @@ class DatabaseSeeder extends Seeder
|
||||
Event::create([
|
||||
'course_id' => 1,
|
||||
'venue_id' => 1,
|
||||
'link' => 'https://einundzwanzig.space',
|
||||
'from' => now()->startOfDay(),
|
||||
'to' => now()
|
||||
->startOfDay()
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"Done": "Fertig",
|
||||
"Registration": "Anmeldung",
|
||||
"Lecturers": "Dozenten",
|
||||
"Cities": "Städte",
|
||||
"Venues": "Veranstaltungs-Orte",
|
||||
|
||||
@@ -1 +1 @@
|
||||
<x-button amber>Anmelden</x-button>
|
||||
<x-button amber wire:click="viewHistoryModal({{ $row->id }})">Anmelden</x-button>
|
||||
|
||||
5
resources/views/columns/events/categories.blade.php
Normal file
5
resources/views/columns/events/categories.blade.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="flex space-x-1">
|
||||
@foreach($row->course->categories as $category)
|
||||
<x-badge>{{ $category->name }}</x-badge>
|
||||
@endforeach
|
||||
</div>
|
||||
56
resources/views/modals/events/register.blade.php
Normal file
56
resources/views/modals/events/register.blade.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<x-jet-dialog-modal wire:model="viewingModal" maxWidth="screen" bg="bg-21gray">
|
||||
<x-slot name="title">
|
||||
<div class="text-gray-200">
|
||||
{{ __('Registration') }}
|
||||
</div>
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="content">
|
||||
<div class="relative py-16">
|
||||
<div class="absolute inset-x-0 top-0 hidden h-1/2 lg:block" aria-hidden="true"></div>
|
||||
<div class="mx-auto max-w-7xl bg-indigo-600 lg:bg-transparent lg:px-8">
|
||||
<div class="lg:grid lg:grid-cols-12">
|
||||
<div class="relative z-10 lg:col-span-4 lg:col-start-1 lg:row-start-1 lg:bg-transparent lg:py-16">
|
||||
<div class="absolute inset-x-0 h-1/2 lg:hidden" aria-hidden="true"></div>
|
||||
<div class="mx-auto max-w-md px-4 sm:max-w-3xl sm:px-6 lg:max-w-none lg:p-0 space-y-2">
|
||||
<div class="aspect-w-10 aspect-h-6 sm:aspect-w-2 sm:aspect-h-1 lg:aspect-w-1">
|
||||
<img class="rounded-3xl object-cover object-center shadow-2xl"
|
||||
src="{{ $currentModal?->course->getFirstMediaUrl('logo') }}"
|
||||
alt="{{ $currentModal?->course->name }}">
|
||||
</div>
|
||||
@foreach($currentModal?->course->getMedia('images') ?? [] as $image)
|
||||
<div class="aspect-w-10 aspect-h-6 sm:aspect-w-2 sm:aspect-h-1 lg:aspect-w-1">
|
||||
<img class="rounded-3xl object-cover object-center shadow-2xl"
|
||||
src="{{ $image->getUrl() }}"
|
||||
alt="{{ $currentModal?->course->name }}">
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative bg-amber-600 py-4 lg:col-span-10 lg:col-start-3 lg:row-start-1 lg:grid lg:grid-cols-10 lg:items-center lg:rounded-3xl">
|
||||
<div
|
||||
class="relative mx-auto max-w-md space-y-6 py-12 px-4 sm:max-w-3xl sm:py-16 sm:px-6 lg:col-span-6 lg:col-start-4 lg:max-w-none lg:p-0">
|
||||
<h2 class="text-3xl font-bold tracking-tight text-white"
|
||||
id="join-heading">{{ $currentModal?->course->name }}</h2>
|
||||
<a class="block w-full rounded-md border border-transparent bg-white py-3 px-5 text-center text-base font-medium text-amber-500 shadow-md hover:bg-gray-50 sm:inline-block sm:w-auto"
|
||||
href="{{ $currentModal?->link }}" target="_blank">Link zur Anmeldung</a>
|
||||
<x-markdown>
|
||||
{{ $currentModal?->course->description }}
|
||||
</x-markdown>
|
||||
<a class="block w-full rounded-md border border-transparent bg-white py-3 px-5 text-center text-base font-medium text-amber-500 shadow-md hover:bg-gray-50 sm:inline-block sm:w-auto"
|
||||
href="{{ $currentModal?->link }}" target="_blank">Link zur Anmeldung</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="footer">
|
||||
<x-jet-secondary-button wire:click="resetModal" wire:loading.attr="disabled">
|
||||
@lang('Done')
|
||||
</x-jet-secondary-button>
|
||||
</x-slot>
|
||||
</x-jet-dialog-modal>
|
||||
@@ -1,6 +1,6 @@
|
||||
@props(['id' => null, 'maxWidth' => null])
|
||||
@props(['id' => null, 'maxWidth' => null, 'bg' => 'bg-white'])
|
||||
|
||||
<x-jet-modal :id="$id" :maxWidth="$maxWidth" {{ $attributes }}>
|
||||
<x-jet-modal :id="$id" :maxWidth="$maxWidth" :bg="$bg" {{ $attributes }}>
|
||||
<div class="px-6 py-4">
|
||||
<div class="text-lg">
|
||||
{{ $title }}
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row justify-end px-6 py-4 bg-gray-100 text-right">
|
||||
<div class="flex flex-row justify-end px-6 py-4 {{ $bg }} text-right">
|
||||
{{ $footer }}
|
||||
</div>
|
||||
</x-jet-modal>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@props(['id', 'maxWidth'])
|
||||
@props(['id', 'maxWidth', 'bg'])
|
||||
|
||||
@php
|
||||
$id = $id ?? md5($attributes->wire('model'));
|
||||
@@ -9,6 +9,7 @@ $maxWidth = [
|
||||
'lg' => 'sm:max-w-lg',
|
||||
'xl' => 'sm:max-w-xl',
|
||||
'2xl' => 'sm:max-w-2xl',
|
||||
'screen' => 'sm:max-w-screen-lg',
|
||||
][$maxWidth ?? '2xl'];
|
||||
@endphp
|
||||
|
||||
@@ -53,10 +54,10 @@ $maxWidth = [
|
||||
x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0">
|
||||
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
|
||||
<div class="absolute inset-0 {{ $bg }} opacity-75"></div>
|
||||
</div>
|
||||
|
||||
<div x-show="show" class="mb-6 bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }} sm:mx-auto"
|
||||
<div x-show="show" class="mb-6 {{ $bg }} rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }} sm:mx-auto"
|
||||
x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
||||
|
||||
Reference in New Issue
Block a user