mirror of
https://github.com/Einundzwanzig-Podcast/einundzwanzig-portal.git
synced 2025-12-11 06:46:47 +00:00
new library added
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
created: 'database/factories/LibraryFactory.php database/factories/LibraryItemsFactory.php database/migrations/2022_12_05_160932_create_libraries_table.php database/migrations/2022_12_05_160933_create_library_items_table.php app/Models/Library.php app/Models/LibraryItems.php app/Nova/Library.php app/Nova/LibraryItems.php'
|
||||
models:
|
||||
Category: { name: string, slug: string }
|
||||
City: { country_id: biginteger, name: string, slug: string, longitude: 'float:10', latitude: 'float:10' }
|
||||
@@ -5,6 +6,8 @@ models:
|
||||
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' }
|
||||
Library: { name: string, language_code: string }
|
||||
LibraryItem: { lecturer_id: biginteger, library_id: biginteger, order_column: integer, type: string, value: text }
|
||||
LoginKey: { k1: string, user_id: biginteger }
|
||||
Membership: { team_id: biginteger, user_id: biginteger, role: 'string nullable' }
|
||||
Participant: { first_name: string, last_name: string }
|
||||
|
||||
@@ -25,9 +25,16 @@ class CreateTags extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$tags = config('tags.tags');
|
||||
$tags = config('tags.tags.course');
|
||||
foreach ($tags as $tag) {
|
||||
$t = Tag::findOrCreate($tag['de'], 'search');
|
||||
$t = Tag::findOrCreate($tag['de'], 'course');
|
||||
$t->icon = $tag['icon'];
|
||||
$t->setTranslation('name', 'en', $tag['en']);
|
||||
$t->save();
|
||||
}
|
||||
$tags = config('tags.tags.library_item');
|
||||
foreach ($tags as $tag) {
|
||||
$t = Tag::findOrCreate($tag['de'], 'library_item');
|
||||
$t->icon = $tag['icon'];
|
||||
$t->setTranslation('name', 'en', $tag['en']);
|
||||
$t->save();
|
||||
|
||||
@@ -12,6 +12,7 @@ class Header extends Component
|
||||
public Country $country;
|
||||
public $currentRouteName;
|
||||
public string $c = 'de';
|
||||
public bool $withGlobe = true;
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
27
app/Http/Livewire/Frontend/Library.php
Normal file
27
app/Http/Livewire/Frontend/Library.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Frontend;
|
||||
|
||||
use App\Models\Country;
|
||||
use Livewire\Component;
|
||||
|
||||
class Library extends Component
|
||||
{
|
||||
public Country $country;
|
||||
|
||||
public $currentTab = 'Alle';
|
||||
|
||||
protected $queryString = [
|
||||
'currentTab' => ['except' => 'alle'],
|
||||
];
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.frontend.library', [
|
||||
'libraries' => \App\Models\Library::get()
|
||||
->prepend(\App\Models\Library::make([
|
||||
'name' => 'Alle',
|
||||
])),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ class SearchByTag extends Component
|
||||
{
|
||||
return view('livewire.frontend.search-by-tag', [
|
||||
'tags' => Tag::query()
|
||||
->where('type', 'course')
|
||||
->with([
|
||||
'courses.lecturer',
|
||||
])
|
||||
|
||||
25
app/Http/Livewire/Frontend/SearchByTagInLibrary.php
Normal file
25
app/Http/Livewire/Frontend/SearchByTagInLibrary.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Frontend;
|
||||
|
||||
use App\Models\Tag;
|
||||
use Livewire\Component;
|
||||
|
||||
class SearchByTagInLibrary extends Component
|
||||
{
|
||||
public string $country = 'de';
|
||||
public ?array $table = [];
|
||||
|
||||
protected $queryString = [
|
||||
'table',
|
||||
];
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.frontend.search-by-tag-in-library', [
|
||||
'tags' => Tag::query()
|
||||
->where('type', 'library_item')
|
||||
->get(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ class CourseTable extends DataTableComponent
|
||||
->toArray()
|
||||
)
|
||||
->filter(function (Builder $builder, array $values) {
|
||||
$builder->withAnyTags($values, 'search');
|
||||
$builder->withAnyTags($values, 'course');
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ class LecturerTable extends DataTableComponent
|
||||
fn($row, Column $column) => $row->courses_count
|
||||
)
|
||||
->collapseOnMobile(),
|
||||
Column::make('Inhalte')
|
||||
->label(
|
||||
fn($row, Column $column) => $row->library_items_count
|
||||
)
|
||||
->collapseOnMobile(),
|
||||
Column::make('')
|
||||
->label(
|
||||
fn($row, Column $column) => view('columns.lectures.action')->withRow($row)
|
||||
@@ -68,6 +73,7 @@ class LecturerTable extends DataTableComponent
|
||||
return Lecturer::query()
|
||||
->withCount([
|
||||
'courses',
|
||||
'libraryItems',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
61
app/Http/Livewire/Tables/LibraryItemTable.php
Normal file
61
app/Http/Livewire/Tables/LibraryItemTable.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Tables;
|
||||
|
||||
use App\Models\LibraryItem;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Rappasoft\LaravelLivewireTables\DataTableComponent;
|
||||
use Rappasoft\LaravelLivewireTables\Views\Column;
|
||||
use Rappasoft\LaravelLivewireTables\Views\Columns\ImageColumn;
|
||||
|
||||
class LibraryItemTable extends DataTableComponent
|
||||
{
|
||||
protected $model = LibraryItem::class;
|
||||
|
||||
public function configure(): void
|
||||
{
|
||||
$this
|
||||
->setPrimaryKey('id')
|
||||
->setDefaultSort('order_column', 'asc');
|
||||
}
|
||||
|
||||
public function columns(): array
|
||||
{
|
||||
return [
|
||||
ImageColumn::make('Bild')
|
||||
->location(
|
||||
fn($row) => $row->getFirstMediaUrl('main', 'thumb')
|
||||
)
|
||||
->attributes(fn($row) => [
|
||||
'class' => 'rounded h-16',
|
||||
'alt' => $row->name.' Avatar',
|
||||
])
|
||||
->collapseOnMobile(),
|
||||
Column::make('Dozent', "lecturer.name")
|
||||
->label(
|
||||
fn($row, Column $column) => view('columns.courses.lecturer')->withRow($row)
|
||||
)
|
||||
->sortable()
|
||||
->collapseOnMobile(),
|
||||
Column::make("Name", "name")
|
||||
->sortable(),
|
||||
Column::make("Art", "type")
|
||||
->sortable(),
|
||||
Column::make("Sprache", "language_code")
|
||||
->sortable(),
|
||||
|
||||
Column::make('')
|
||||
->label(
|
||||
fn($row, Column $column) => view('columns.library_items.action')->withRow($row)
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
public function builder(): Builder
|
||||
{
|
||||
return LibraryItem::query()
|
||||
->withCount([
|
||||
'lecturer',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -11,18 +11,17 @@ class Country extends Model
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'language_codes' => 'array',
|
||||
];
|
||||
|
||||
public function cities(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
|
||||
@@ -73,4 +73,9 @@ class Lecturer extends Model implements HasMedia
|
||||
{
|
||||
return $this->hasMany(Course::class);
|
||||
}
|
||||
|
||||
public function libraryItems(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(LibraryItem::class);
|
||||
}
|
||||
}
|
||||
|
||||
33
app/Models/Library.php
Normal file
33
app/Models/Library.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Library extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'language_codes' => 'array',
|
||||
];
|
||||
|
||||
public function libraryItems(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(LibraryItem::class);
|
||||
}
|
||||
}
|
||||
71
app/Models/LibraryItem.php
Normal file
71
app/Models/LibraryItem.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\EloquentSortable\Sortable;
|
||||
use Spatie\EloquentSortable\SortableTrait;
|
||||
use Spatie\Image\Manipulations;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
use Spatie\Tags\HasTags;
|
||||
|
||||
class LibraryItem extends Model implements HasMedia, Sortable
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithMedia;
|
||||
use HasTags;
|
||||
use SortableTrait;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'lecturer_id' => 'integer',
|
||||
'library_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('main')
|
||||
->singleFile()
|
||||
->useFallbackUrl(asset('img/einundzwanzig-cover-lesestunde.png'));
|
||||
$this->addMediaCollection('single_file')
|
||||
->acceptsMimeTypes(['application/pdf'])
|
||||
->singleFile();
|
||||
$this->addMediaCollection('images')
|
||||
->useFallbackUrl(asset('img/einundzwanzig-cover-lesestunde.png'));
|
||||
}
|
||||
|
||||
public function lecturer(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Lecturer::class);
|
||||
}
|
||||
|
||||
public function library(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Library::class);
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,28 @@
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Fields\HasMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\MultiSelect;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
|
||||
class Country extends Resource
|
||||
{
|
||||
/**
|
||||
* The model the resource corresponds to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $model = \App\Models\Country::class;
|
||||
|
||||
/**
|
||||
* The single value that should be used to represent the resource when being displayed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $title = 'name';
|
||||
|
||||
/**
|
||||
* The columns that should be searched.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
@@ -37,22 +35,27 @@ class Country extends Resource
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields(Request $request)
|
||||
{
|
||||
return [
|
||||
ID::make()->sortable(),
|
||||
ID::make()
|
||||
->sortable(),
|
||||
|
||||
Text::make('Name')
|
||||
->rules('required', 'string'),
|
||||
|
||||
MultiSelect::make('Languages', 'language_codes')
|
||||
->options(
|
||||
config('languages.languages'),
|
||||
),
|
||||
|
||||
Text::make('Code')
|
||||
->rules('required', 'string'),
|
||||
|
||||
HasMany::make('Cities'),
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
@@ -60,6 +63,7 @@ class Country extends Resource
|
||||
* Get the cards available for the request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cards(Request $request)
|
||||
@@ -71,6 +75,7 @@ class Country extends Resource
|
||||
* Get the filters available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filters(Request $request)
|
||||
@@ -82,6 +87,7 @@ class Country extends Resource
|
||||
* Get the lenses available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function lenses(Request $request)
|
||||
@@ -93,6 +99,7 @@ class Country extends Resource
|
||||
* Get the actions available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function actions(Request $request)
|
||||
|
||||
@@ -66,7 +66,7 @@ class Course extends Resource
|
||||
->conversionOnIndexView('thumb')
|
||||
->help('Lade hier Bilder hoch, um sie eventuell später in der Markdown Description einzufügen. Du musst vorher aber Speichern.'),
|
||||
|
||||
Tags::make('Tags')->type('search')->withLinkToTagResource(Tag::class),
|
||||
Tags::make('Tags')->type('course')->withLinkToTagResource(Tag::class),
|
||||
|
||||
Text::make('Name')
|
||||
->rules('required', 'string'),
|
||||
|
||||
106
app/Nova/Library.php
Normal file
106
app/Nova/Library.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Fields\BelongsToMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\MultiSelect;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
|
||||
class Library extends Resource
|
||||
{
|
||||
/**
|
||||
* The model the resource corresponds to.
|
||||
* @var string
|
||||
*/
|
||||
public static $model = \App\Models\Library::class;
|
||||
|
||||
/**
|
||||
* The single value that should be used to represent the resource when being displayed.
|
||||
* @var string
|
||||
*/
|
||||
public static $title = 'name';
|
||||
|
||||
/**
|
||||
* The columns that should be searched.
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
'id',
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields(Request $request)
|
||||
{
|
||||
return [
|
||||
ID::make()
|
||||
->sortable(),
|
||||
|
||||
Text::make('Name')
|
||||
->rules('required', 'string'),
|
||||
|
||||
MultiSelect::make('Languages', 'language_codes')
|
||||
->options(
|
||||
config('languages.languages'),
|
||||
),
|
||||
|
||||
BelongsToMany::make('Library Items'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cards available for the request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cards(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filters available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filters(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lenses available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function lenses(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function actions(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
146
app/Nova/LibraryItem.php
Normal file
146
app/Nova/LibraryItem.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Ebess\AdvancedNovaMediaLibrary\Fields\Files;
|
||||
use Ebess\AdvancedNovaMediaLibrary\Fields\Images;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\BelongsToMany;
|
||||
use Laravel\Nova\Fields\Code;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Select;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Spatie\TagsField\Tags;
|
||||
|
||||
class LibraryItem extends Resource
|
||||
{
|
||||
/**
|
||||
* The model the resource corresponds to.
|
||||
* @var string
|
||||
*/
|
||||
public static $model = \App\Models\LibraryItem::class;
|
||||
|
||||
/**
|
||||
* The single value that should be used to represent the resource when being displayed.
|
||||
* @var string
|
||||
*/
|
||||
public static $title = 'name';
|
||||
|
||||
/**
|
||||
* The columns that should be searched.
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
'id',
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields(Request $request)
|
||||
{
|
||||
return [
|
||||
ID::make()
|
||||
->sortable(),
|
||||
|
||||
Images::make('Main picture', 'main')
|
||||
->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.'),
|
||||
|
||||
Files::make('Downloadable File', 'single_file')
|
||||
->help('Für neue Datei-Typen bitte bei den Admins melden. (Derzeit: PDF)'),
|
||||
|
||||
Select::make('Language Code', 'language_code')
|
||||
->options(
|
||||
config('languages.languages')
|
||||
)
|
||||
->rules('required', 'string'),
|
||||
|
||||
Tags::make('Tags')
|
||||
->type('library_item')
|
||||
->withLinkToTagResource(Tag::class),
|
||||
|
||||
Text::make('Name')
|
||||
->rules('required', 'string'),
|
||||
|
||||
Select::make('Type')
|
||||
->options(
|
||||
[
|
||||
'book' => 'book',
|
||||
'blog_article' => 'blog_article',
|
||||
'markdown_article' => 'markdown_article',
|
||||
'youtube_video' => 'youtube_video',
|
||||
'vimeo_video' => 'vimeo_video',
|
||||
'downloadable_file' => 'downloadable_file',
|
||||
]
|
||||
)
|
||||
->rules('required', 'string'),
|
||||
|
||||
Code::make('Value')
|
||||
->rules('required', 'string')
|
||||
->help('Hier bitte die URL zum Video einfügen, oder den Link zum Blog-Artikel, oder den Link zum Buch, oder das Markdown selbst einfügen.'),
|
||||
|
||||
BelongsTo::make('Lecturer'),
|
||||
|
||||
BelongsToMany::make('Library'),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cards available for the request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cards(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filters available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filters(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lenses available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function lenses(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions available for the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function actions(Request $request)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ class Tag extends Resource
|
||||
|
||||
Select::make('Type')
|
||||
->options([
|
||||
'search' => 'search',
|
||||
'course' => 'course',
|
||||
'library_item' => 'library_item',
|
||||
]),
|
||||
|
||||
];
|
||||
|
||||
@@ -9,6 +9,8 @@ use App\Nova\Course;
|
||||
use App\Nova\Dashboards\Main;
|
||||
use App\Nova\Event;
|
||||
use App\Nova\Lecturer;
|
||||
use App\Nova\Library;
|
||||
use App\Nova\LibraryItem;
|
||||
use App\Nova\Participant;
|
||||
use App\Nova\Registration;
|
||||
use App\Nova\Tag;
|
||||
@@ -50,6 +52,13 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
|
||||
->icon('academic-cap')
|
||||
->collapsable(),
|
||||
|
||||
MenuSection::make('Bibliothek', [
|
||||
MenuItem::resource(Library::class),
|
||||
MenuItem::resource(LibraryItem::class),
|
||||
])
|
||||
->icon('library')
|
||||
->collapsable(),
|
||||
|
||||
MenuSection::make('Admin', [
|
||||
MenuItem::resource(Category::class),
|
||||
MenuItem::resource(Country::class),
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"rappasoft/laravel-livewire-tables": "^2.8",
|
||||
"sentry/sentry-laravel": "^3.1",
|
||||
"simplesoftwareio/simple-qrcode": "^4.2",
|
||||
"spatie/eloquent-sortable": "^4.0",
|
||||
"spatie/laravel-google-fonts": "^1.2",
|
||||
"spatie/laravel-markdown": "^2.2",
|
||||
"spatie/laravel-medialibrary": "^10.0.0",
|
||||
|
||||
2
composer.lock
generated
2
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ff7b4ac8af19364e547306d58f6c9479",
|
||||
"content-hash": "fe13b4c19e33aebc3926e4dcd5ddf8e8",
|
||||
"packages": [
|
||||
{
|
||||
"name": "akuechler/laravel-geoly",
|
||||
|
||||
14
config/eloquent-sortable.php
Normal file
14
config/eloquent-sortable.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
* Which column will be used as the order column.
|
||||
*/
|
||||
'order_column_name' => 'order_column',
|
||||
|
||||
/*
|
||||
* Define if the models should sort when creating.
|
||||
* When true, the package will automatically assign the highest order number to a new mode
|
||||
*/
|
||||
'sort_when_creating' => true,
|
||||
];
|
||||
234
config/ignition.php
Normal file
234
config/ignition.php
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
use Spatie\Ignition\Solutions\SolutionProviders\BadMethodCallSolutionProvider;
|
||||
use Spatie\Ignition\Solutions\SolutionProviders\MergeConflictSolutionProvider;
|
||||
use Spatie\Ignition\Solutions\SolutionProviders\UndefinedPropertySolutionProvider;
|
||||
use Spatie\LaravelIgnition\Recorders\DumpRecorder\DumpRecorder;
|
||||
use Spatie\LaravelIgnition\Recorders\JobRecorder\JobRecorder;
|
||||
use Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder;
|
||||
use Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\DefaultDbNameSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\GenericLaravelExceptionSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\IncorrectValetDbCredentialsSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\InvalidRouteActionSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingAppKeySolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingColumnSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingImportSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingLivewireComponentSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingMixManifestSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\MissingViteManifestSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\RunningLaravelDuskInProductionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\TableNotFoundSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\UndefinedViewVariableSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\UnknownValidationSolutionProvider;
|
||||
use Spatie\LaravelIgnition\Solutions\SolutionProviders\ViewNotFoundSolutionProvider;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Editor
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Choose your preferred editor to use when clicking any edit button.
|
||||
|
|
||||
| Supported: "phpstorm", "vscode", "vscode-insiders", "textmate", "emacs",
|
||||
| "sublime", "atom", "nova", "macvim", "idea", "netbeans",
|
||||
| "xdebug"
|
||||
|
|
||||
*/
|
||||
|
||||
'editor' => env('IGNITION_EDITOR', 'phpstorm'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Theme
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which theme Ignition should use.
|
||||
|
|
||||
| Supported: "light", "dark", "auto"
|
||||
|
|
||||
*/
|
||||
|
||||
'theme' => env('IGNITION_THEME', 'dark'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sharing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You can share local errors with colleagues or others around the world.
|
||||
| Sharing is completely free and doesn't require an account on Flare.
|
||||
|
|
||||
| If necessary, you can completely disable sharing below.
|
||||
|
|
||||
*/
|
||||
|
||||
'enable_share_button' => env('IGNITION_SHARING_ENABLED', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Ignition commands
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition comes with an additional make command that lets you create
|
||||
| new solution classes more easily. To keep your default Laravel
|
||||
| installation clean, this command is not registered by default.
|
||||
|
|
||||
| You can enable the command registration below.
|
||||
|
|
||||
*/
|
||||
|
||||
'register_commands' => env('REGISTER_IGNITION_COMMANDS', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Solution Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may specify a list of solution providers (as fully qualified class
|
||||
| names) that shouldn't be loaded. Ignition will ignore these classes
|
||||
| and possible solutions provided by them will never be displayed.
|
||||
|
|
||||
*/
|
||||
|
||||
'solution_providers' => [
|
||||
// from spatie/ignition
|
||||
BadMethodCallSolutionProvider::class,
|
||||
MergeConflictSolutionProvider::class,
|
||||
UndefinedPropertySolutionProvider::class,
|
||||
|
||||
// from spatie/laravel-ignition
|
||||
IncorrectValetDbCredentialsSolutionProvider::class,
|
||||
MissingAppKeySolutionProvider::class,
|
||||
DefaultDbNameSolutionProvider::class,
|
||||
TableNotFoundSolutionProvider::class,
|
||||
MissingImportSolutionProvider::class,
|
||||
InvalidRouteActionSolutionProvider::class,
|
||||
ViewNotFoundSolutionProvider::class,
|
||||
RunningLaravelDuskInProductionProvider::class,
|
||||
MissingColumnSolutionProvider::class,
|
||||
UnknownValidationSolutionProvider::class,
|
||||
MissingMixManifestSolutionProvider::class,
|
||||
MissingViteManifestSolutionProvider::class,
|
||||
MissingLivewireComponentSolutionProvider::class,
|
||||
UndefinedViewVariableSolutionProvider::class,
|
||||
GenericLaravelExceptionSolutionProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Ignored Solution Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may specify a list of solution providers (as fully qualified class
|
||||
| names) that shouldn't be loaded. Ignition will ignore these classes
|
||||
| and possible solutions provided by them will never be displayed.
|
||||
|
|
||||
*/
|
||||
|
||||
'ignored_solution_providers' => [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Runnable Solutions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Some solutions that Ignition displays are runnable and can perform
|
||||
| various tasks. By default, runnable solutions are only enabled when your
|
||||
| app has debug mode enabled and the environment is `local` or
|
||||
| `development`.
|
||||
|
|
||||
| Using the `IGNITION_ENABLE_RUNNABLE_SOLUTIONS` environment variable, you
|
||||
| can override this behaviour and enable or disable runnable solutions
|
||||
| regardless of the application's environment.
|
||||
|
|
||||
| Default: env('IGNITION_ENABLE_RUNNABLE_SOLUTIONS')
|
||||
|
|
||||
*/
|
||||
|
||||
'enable_runnable_solutions' => env('IGNITION_ENABLE_RUNNABLE_SOLUTIONS'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Remote Path Mapping
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you are using a remote dev server, like Laravel Homestead, Docker, or
|
||||
| even a remote VPS, it will be necessary to specify your path mapping.
|
||||
|
|
||||
| Leaving one, or both of these, empty or null will not trigger the remote
|
||||
| URL changes and Ignition will treat your editor links as local files.
|
||||
|
|
||||
| "remote_sites_path" is an absolute base path for your sites or projects
|
||||
| in Homestead, Vagrant, Docker, or another remote development server.
|
||||
|
|
||||
| Example value: "/home/vagrant/Code"
|
||||
|
|
||||
| "local_sites_path" is an absolute base path for your sites or projects
|
||||
| on your local computer where your IDE or code editor is running on.
|
||||
|
|
||||
| Example values: "/Users/<name>/Code", "C:\Users\<name>\Documents\Code"
|
||||
|
|
||||
*/
|
||||
|
||||
'remote_sites_path' => env('IGNITION_REMOTE_SITES_PATH', '/var/www/html'),
|
||||
'local_sites_path' => env('IGNITION_LOCAL_SITES_PATH', '/home/fsociety/Code/side/einundzwanzig-bitcoin-school'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Housekeeping Endpoint Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition registers a couple of routes when it is enabled. Below you may
|
||||
| specify a route prefix that will be used to host all internal links.
|
||||
|
|
||||
*/
|
||||
|
||||
'housekeeping_endpoint_prefix' => '_ignition',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Settings File
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition allows you to save your settings to a specific global file.
|
||||
|
|
||||
| If no path is specified, a file with settings will be saved to the user's
|
||||
| home directory. The directory depends on the OS and its settings but it's
|
||||
| typically `~/.ignition.json`. In this case, the settings will be applied
|
||||
| to all of your projects where Ignition is used and the path is not
|
||||
| specified.
|
||||
|
|
||||
| However, if you want to store your settings on a project basis, or you
|
||||
| want to keep them in another directory, you can specify a path where
|
||||
| the settings file will be saved. The path should be an existing directory
|
||||
| with correct write access.
|
||||
| For example, create a new `ignition` folder in the storage directory and
|
||||
| use `storage_path('ignition')` as the `settings_file_path`.
|
||||
|
|
||||
| Default value: '' (empty string)
|
||||
*/
|
||||
|
||||
'settings_file_path' => '',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Recorders
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition registers a couple of recorders when it is enabled. Below you may
|
||||
| specify a recorders will be used to record specific events.
|
||||
|
|
||||
*/
|
||||
|
||||
'recorders' => [
|
||||
DumpRecorder::class,
|
||||
JobRecorder::class,
|
||||
LogRecorder::class,
|
||||
QueryRecorder::class
|
||||
]
|
||||
];
|
||||
188
config/languages/languages.php
Normal file
188
config/languages/languages.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'ab' => 'Abkhazian',
|
||||
'aa' => 'Afar',
|
||||
'af' => 'Afrikaans',
|
||||
'ak' => 'Akan',
|
||||
'sq' => 'Albanian',
|
||||
'am' => 'Amharic',
|
||||
'ar' => 'Arabic',
|
||||
'an' => 'Aragonese',
|
||||
'hy' => 'Armenian',
|
||||
'as' => 'Assamese',
|
||||
'av' => 'Avaric',
|
||||
'ae' => 'Avestan',
|
||||
'ay' => 'Aymara',
|
||||
'az' => 'Azerbaijani',
|
||||
'bm' => 'Bambara',
|
||||
'ba' => 'Bashkir',
|
||||
'eu' => 'Basque',
|
||||
'be' => 'Belarusian',
|
||||
'bn' => 'Bengali',
|
||||
'bh' => 'Bihari languages',
|
||||
'bi' => 'Bislama',
|
||||
'bs' => 'Bosnian',
|
||||
'br' => 'Breton',
|
||||
'bg' => 'Bulgarian',
|
||||
'my' => 'Burmese',
|
||||
'ca' => 'Catalan, Valencian',
|
||||
'km' => 'Central Khmer',
|
||||
'ch' => 'Chamorro',
|
||||
'ce' => 'Chechen',
|
||||
'ny' => 'Chichewa, Chewa, Nyanja',
|
||||
'zh' => 'Chinese',
|
||||
'cu' => 'Church Slavonic, Old Bulgarian, Old Church Slavonic',
|
||||
'cv' => 'Chuvash',
|
||||
'kw' => 'Cornish',
|
||||
'co' => 'Corsican',
|
||||
'cr' => 'Cree',
|
||||
'hr' => 'Croatian',
|
||||
'cs' => 'Czech',
|
||||
'da' => 'Danish',
|
||||
'dv' => 'Divehi, Dhivehi, Maldivian',
|
||||
'nl' => 'Dutch, Flemish',
|
||||
'dz' => 'Dzongkha',
|
||||
'en' => 'English',
|
||||
'eo' => 'Esperanto',
|
||||
'et' => 'Estonian',
|
||||
'ee' => 'Ewe',
|
||||
'fo' => 'Faroese',
|
||||
'fj' => 'Fijian',
|
||||
'fi' => 'Finnish',
|
||||
'fr' => 'French',
|
||||
'ff' => 'Fulah',
|
||||
'gd' => 'Gaelic, Scottish Gaelic',
|
||||
'gl' => 'Galician',
|
||||
'lg' => 'Ganda',
|
||||
'ka' => 'Georgian',
|
||||
'de' => 'German',
|
||||
'ki' => 'Gikuyu, Kikuyu',
|
||||
'el' => 'Greek (Modern)',
|
||||
'kl' => 'Greenlandic, Kalaallisut',
|
||||
'gn' => 'Guarani',
|
||||
'gu' => 'Gujarati',
|
||||
'ht' => 'Haitian, Haitian Creole',
|
||||
'ha' => 'Hausa',
|
||||
'he' => 'Hebrew',
|
||||
'hz' => 'Herero',
|
||||
'hi' => 'Hindi',
|
||||
'ho' => 'Hiri Motu',
|
||||
'hu' => 'Hungarian',
|
||||
'is' => 'Icelandic',
|
||||
'io' => 'Ido',
|
||||
'ig' => 'Igbo',
|
||||
'id' => 'Indonesian',
|
||||
'ia' => 'Interlingua (International Auxiliary Language Association)',
|
||||
'ie' => 'Interlingue',
|
||||
'iu' => 'Inuktitut',
|
||||
'ik' => 'Inupiaq',
|
||||
'ga' => 'Irish',
|
||||
'it' => 'Italian',
|
||||
'ja' => 'Japanese',
|
||||
'jv' => 'Javanese',
|
||||
'kn' => 'Kannada',
|
||||
'kr' => 'Kanuri',
|
||||
'ks' => 'Kashmiri',
|
||||
'kk' => 'Kazakh',
|
||||
'rw' => 'Kinyarwanda',
|
||||
'kv' => 'Komi',
|
||||
'kg' => 'Kongo',
|
||||
'ko' => 'Korean',
|
||||
'kj' => 'Kwanyama, Kuanyama',
|
||||
'ku' => 'Kurdish',
|
||||
'ky' => 'Kyrgyz',
|
||||
'lo' => 'Lao',
|
||||
'la' => 'Latin',
|
||||
'lv' => 'Latvian',
|
||||
'lb' => 'Letzeburgesch, Luxembourgish',
|
||||
'li' => 'Limburgish, Limburgan, Limburger',
|
||||
'ln' => 'Lingala',
|
||||
'lt' => 'Lithuanian',
|
||||
'lu' => 'Luba-Katanga',
|
||||
'mk' => 'Macedonian',
|
||||
'mg' => 'Malagasy',
|
||||
'ms' => 'Malay',
|
||||
'ml' => 'Malayalam',
|
||||
'mt' => 'Maltese',
|
||||
'gv' => 'Manx',
|
||||
'mi' => 'Maori',
|
||||
'mr' => 'Marathi',
|
||||
'mh' => 'Marshallese',
|
||||
'ro' => 'Moldovan, Moldavian, Romanian',
|
||||
'mn' => 'Mongolian',
|
||||
'na' => 'Nauru',
|
||||
'nv' => 'Navajo, Navaho',
|
||||
'nd' => 'Northern Ndebele',
|
||||
'ng' => 'Ndonga',
|
||||
'ne' => 'Nepali',
|
||||
'se' => 'Northern Sami',
|
||||
'no' => 'Norwegian',
|
||||
'nb' => 'Norwegian Bokmål',
|
||||
'nn' => 'Norwegian Nynorsk',
|
||||
'ii' => 'Nuosu, Sichuan Yi',
|
||||
'oc' => 'Occitan (post 1500)',
|
||||
'oj' => 'Ojibwa',
|
||||
'or' => 'Oriya',
|
||||
'om' => 'Oromo',
|
||||
'os' => 'Ossetian, Ossetic',
|
||||
'pi' => 'Pali',
|
||||
'pa' => 'Panjabi, Punjabi',
|
||||
'ps' => 'Pashto, Pushto',
|
||||
'fa' => 'Persian',
|
||||
'pl' => 'Polish',
|
||||
'pt' => 'Portuguese',
|
||||
'qu' => 'Quechua',
|
||||
'rm' => 'Romansh',
|
||||
'rn' => 'Rundi',
|
||||
'ru' => 'Russian',
|
||||
'sm' => 'Samoan',
|
||||
'sg' => 'Sango',
|
||||
'sa' => 'Sanskrit',
|
||||
'sc' => 'Sardinian',
|
||||
'sr' => 'Serbian',
|
||||
'sn' => 'Shona',
|
||||
'sd' => 'Sindhi',
|
||||
'si' => 'Sinhala, Sinhalese',
|
||||
'sk' => 'Slovak',
|
||||
'sl' => 'Slovenian',
|
||||
'so' => 'Somali',
|
||||
'st' => 'Sotho, Southern',
|
||||
'nr' => 'South Ndebele',
|
||||
'es' => 'Spanish, Castilian',
|
||||
'su' => 'Sundanese',
|
||||
'sw' => 'Swahili',
|
||||
'ss' => 'Swati',
|
||||
'sv' => 'Swedish',
|
||||
'tl' => 'Tagalog',
|
||||
'ty' => 'Tahitian',
|
||||
'tg' => 'Tajik',
|
||||
'ta' => 'Tamil',
|
||||
'tt' => 'Tatar',
|
||||
'te' => 'Telugu',
|
||||
'th' => 'Thai',
|
||||
'bo' => 'Tibetan',
|
||||
'ti' => 'Tigrinya',
|
||||
'to' => 'Tonga (Tonga Islands)',
|
||||
'ts' => 'Tsonga',
|
||||
'tn' => 'Tswana',
|
||||
'tr' => 'Turkish',
|
||||
'tk' => 'Turkmen',
|
||||
'tw' => 'Twi',
|
||||
'ug' => 'Uighur, Uyghur',
|
||||
'uk' => 'Ukrainian',
|
||||
'ur' => 'Urdu',
|
||||
'uz' => 'Uzbek',
|
||||
've' => 'Venda',
|
||||
'vi' => 'Vietnamese',
|
||||
'vo' => 'Volap_k',
|
||||
'wa' => 'Walloon',
|
||||
'cy' => 'Welsh',
|
||||
'fy' => 'Western Frisian',
|
||||
'wo' => 'Wolof',
|
||||
'xh' => 'Xhosa',
|
||||
'yi' => 'Yiddish',
|
||||
'yo' => 'Yoruba',
|
||||
'za' => 'Zhuang, Chuang',
|
||||
'zu' => 'Zulu'
|
||||
];
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'course' => [
|
||||
[
|
||||
'de' => 'Hardware Wallet',
|
||||
'en' => 'Hardware Wallet',
|
||||
@@ -41,4 +42,57 @@ return [
|
||||
'en' => 'Privacy',
|
||||
'icon' => 'shield-keyhole',
|
||||
],
|
||||
],
|
||||
'library_item' => [
|
||||
[
|
||||
'de' => 'Bitcoin',
|
||||
'en' => 'Bitcoin',
|
||||
'icon' => 'book',
|
||||
],
|
||||
[
|
||||
'de' => 'Lightning',
|
||||
'en' => 'Lightning',
|
||||
'icon' => 'bolt-lightning',
|
||||
],
|
||||
[
|
||||
'de' => 'Blockchain',
|
||||
'en' => 'Blockchain',
|
||||
'icon' => 'link-horizontal',
|
||||
],
|
||||
[
|
||||
'de' => 'On-Chain',
|
||||
'en' => 'On-Chain',
|
||||
'icon' => 'link-horizontal',
|
||||
],
|
||||
[
|
||||
'de' => 'Off-Chain',
|
||||
'en' => 'Off-Chain',
|
||||
'icon' => 'link-horizontal-slash',
|
||||
],
|
||||
[
|
||||
'de' => 'Mining',
|
||||
'en' => 'Mining',
|
||||
'icon' => 'pickaxe',
|
||||
],
|
||||
[
|
||||
'de' => 'Proof of Work',
|
||||
'en' => 'Proof of Work',
|
||||
'icon' => 'pickaxe',
|
||||
],
|
||||
[
|
||||
'de' => 'Datenschutz',
|
||||
'en' => 'Privacy',
|
||||
'icon' => 'shield-keyhole',
|
||||
],
|
||||
[
|
||||
'de' => 'Downloads',
|
||||
'en' => 'Downloads',
|
||||
'icon' => 'download',
|
||||
],
|
||||
[
|
||||
'de' => 'Präsentationen',
|
||||
'en' => 'Presentations',
|
||||
'icon' => 'presentation-screen',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
30
database/factories/LibraryFactory.php
Normal file
30
database/factories/LibraryFactory.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Library;
|
||||
|
||||
class LibraryFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Library::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name,
|
||||
'language_code' => $this->faker->word,
|
||||
];
|
||||
}
|
||||
}
|
||||
35
database/factories/LibraryItemsFactory.php
Normal file
35
database/factories/LibraryItemsFactory.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Lecturer;
|
||||
use App\Models\Library;
|
||||
use App\Models\LibraryItems;
|
||||
|
||||
class LibraryItemsFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = LibraryItems::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'lecturer_id' => Lecturer::factory(),
|
||||
'library_id' => Library::factory(),
|
||||
'order_column' => $this->faker->randomNumber(),
|
||||
'type' => $this->faker->word,
|
||||
'value' => $this->faker->text,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ class CreateCountriesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
@@ -17,13 +16,14 @@ class CreateCountriesTable extends Migration
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('code');
|
||||
$table->json('language_codes')
|
||||
->default('[]');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLibrariesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('libraries', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->json('language_codes')
|
||||
->default('[]');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('libraries');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLibraryItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::disableForeignKeyConstraints();
|
||||
|
||||
Schema::create('library_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('lecturer_id')
|
||||
->constrained()
|
||||
->cascadeOnDelete()
|
||||
->cascadeOnUpdate();
|
||||
$table->unsignedInteger('order_column');
|
||||
$table->string('name');
|
||||
$table->string('type');
|
||||
$table->string('language_code');
|
||||
$table->longText('value');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::enableForeignKeyConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('library_items');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLibraryLibraryItemTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::disableForeignKeyConstraints();
|
||||
|
||||
Schema::create('library_library_item', function (Blueprint $table) {
|
||||
$table->foreignId('library_id')
|
||||
->constrained()
|
||||
->cascadeOnDelete()
|
||||
->cascadeOnUpdate();
|
||||
$table->foreignId('library_item_id')
|
||||
->constrained()
|
||||
->cascadeOnDelete()
|
||||
->cascadeOnUpdate();
|
||||
});
|
||||
|
||||
Schema::enableForeignKeyConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('library_library_item');
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ use App\Models\Country;
|
||||
use App\Models\Course;
|
||||
use App\Models\Event;
|
||||
use App\Models\Lecturer;
|
||||
use App\Models\Library;
|
||||
use App\Models\LibraryItem;
|
||||
use App\Models\Participant;
|
||||
use App\Models\Registration;
|
||||
use App\Models\Team;
|
||||
@@ -51,14 +53,22 @@ class DatabaseSeeder extends Seeder
|
||||
Country::create([
|
||||
'name' => 'Deutschland',
|
||||
'code' => 'de',
|
||||
'language_codes' => ['de'],
|
||||
]);
|
||||
Country::create([
|
||||
'name' => 'Österreich',
|
||||
'code' => 'at',
|
||||
'language_codes' => ['de'],
|
||||
]);
|
||||
Country::create([
|
||||
'name' => 'Schweiz',
|
||||
'code' => 'ch',
|
||||
'language_codes' => ['de'],
|
||||
]);
|
||||
Country::create([
|
||||
'name' => 'France',
|
||||
'code' => 'fr',
|
||||
'language_codes' => ['fr'],
|
||||
]);
|
||||
City::create([
|
||||
'country_id' => 1,
|
||||
@@ -115,6 +125,16 @@ class DatabaseSeeder extends Seeder
|
||||
'name' => 'Beppo',
|
||||
'active' => true,
|
||||
]);
|
||||
Lecturer::create([
|
||||
'team_id' => 1,
|
||||
'name' => 'Helper',
|
||||
'active' => true,
|
||||
]);
|
||||
Lecturer::create([
|
||||
'team_id' => 1,
|
||||
'name' => 'Gigi',
|
||||
'active' => true,
|
||||
]);
|
||||
$category = Category::create([
|
||||
'name' => 'Präsenzunterricht',
|
||||
'slug' => str('Präsenzunterricht')->slug('-', 'de'),
|
||||
@@ -127,21 +147,21 @@ class DatabaseSeeder extends Seeder
|
||||
'lecturer_id' => 1,
|
||||
'name' => 'Hands on Bitcoin',
|
||||
]);
|
||||
$course->syncTagsWithType(['Hardware Wallet'],'search');
|
||||
$course->syncTagsWithType(['Hardware Wallet'], 'course');
|
||||
$course->categories()
|
||||
->attach($category);
|
||||
$course = Course::create([
|
||||
'lecturer_id' => 1,
|
||||
'name' => 'Bitcoin <> Crypto',
|
||||
]);
|
||||
$course->syncTagsWithType(['Lightning'],'search');
|
||||
$course->syncTagsWithType(['Lightning'], 'course');
|
||||
$course->categories()
|
||||
->attach($categoryOnline);
|
||||
$course = Course::create([
|
||||
'lecturer_id' => 2,
|
||||
'name' => 'Bitcoin Lightning Network',
|
||||
]);
|
||||
$course->syncTagsWithType(['Für Unternehmen'],'search');
|
||||
$course->syncTagsWithType(['Für Unternehmen'], 'course');
|
||||
$course->categories()
|
||||
->attach($categoryOnline);
|
||||
Participant::create([
|
||||
@@ -200,5 +220,45 @@ class DatabaseSeeder extends Seeder
|
||||
'event_id' => 1,
|
||||
'participant_id' => 1,
|
||||
]);
|
||||
$library = Library::create([
|
||||
'name' => 'Einundzwanzig',
|
||||
'language_codes' => ['de'],
|
||||
]);
|
||||
$libraryItem = LibraryItem::create([
|
||||
'lecturer_id' => 3,
|
||||
'name' => 'BITCOIN - Eine Reise in den Kaninchenbau🐇🕳️',
|
||||
'type' => 'youtube_video',
|
||||
'language_code' => 'de',
|
||||
'value' => 'https://www.youtube.com/watch?v=Oztd2Sja4k0',
|
||||
]);
|
||||
$libraryItem->syncTagsWithType(['Bitcoin'], 'library_item');
|
||||
$library->libraryItems()
|
||||
->attach($libraryItem);
|
||||
$library = Library::create([
|
||||
'name' => 'Apricot',
|
||||
'language_codes' => ['de', 'en'],
|
||||
]);
|
||||
$libraryItem = LibraryItem::create([
|
||||
'lecturer_id' => 4,
|
||||
'name' => 'Liebe Krypto- und Fiat-Bros️',
|
||||
'type' => 'blog_article',
|
||||
'language_code' => 'de',
|
||||
'value' => 'https://aprycot.media/blog/liebe-krypto-und-fiat-bros/',
|
||||
]);
|
||||
$libraryItem->syncTagsWithType(['Bitcoin'], 'library_item');
|
||||
$library->libraryItems()
|
||||
->attach($libraryItem);
|
||||
$library = Library::create([
|
||||
'name' => 'Gigi',
|
||||
'language_codes' => ['de', 'en'],
|
||||
]);
|
||||
$libraryItem = LibraryItem::create([
|
||||
'lecturer_id' => 4,
|
||||
'name' => 'Cryptography is Not Enough - Gigi @ Baltic Honeybadger 2022 ️',
|
||||
'type' => 'youtube_video',
|
||||
'language_code' => 'de',
|
||||
'value' => 'https://www.youtube.com/watch?v=C7ynm0Zkwfk',
|
||||
]);
|
||||
$libraryItem->syncTagsWithType(['Proof of Work'], 'library_item');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
<x-button amber wire:click="lecturerSearch({{ $row->id }})">Termine anzeigen</x-button>
|
||||
<div>
|
||||
<x-button amber wire:click="lecturerSearch({{ $row->id }})">
|
||||
<i class="fa fa-thin fa-calendar mr-2"></i>
|
||||
Termine anzeigen
|
||||
</x-button>
|
||||
<x-button amber wire:click="lecturerSearch({{ $row->id }})">
|
||||
<i class="fa fa-thin fa-book mr-2"></i>
|
||||
Inhalte anzeigen
|
||||
</x-button>
|
||||
</div>
|
||||
|
||||
6
resources/views/columns/library_items/action.blade.php
Normal file
6
resources/views/columns/library_items/action.blade.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<div>
|
||||
<x-button amber>
|
||||
<i class="fa fa-thin fa-book-open mr-2"></i>
|
||||
Öffnen
|
||||
</x-button>
|
||||
</div>
|
||||
@@ -12,7 +12,8 @@
|
||||
</style>
|
||||
<section class="w-full">
|
||||
<div class="max-w-screen-2xl mx-auto px-2 sm:px-10">
|
||||
<div class="relative sm:sticky sm:top-0 bg-21gray z-10 flex flex-col flex-wrap items-center justify-between py-7 mx-auto md:flex-row max-w-screen-2xl">
|
||||
<div
|
||||
class="relative sm:sticky sm:top-0 bg-21gray z-10 flex flex-col flex-wrap items-center justify-between py-7 mx-auto md:flex-row max-w-screen-2xl">
|
||||
<div class="relative flex flex-col md:flex-row">
|
||||
<a href="{{ route('search.city', ['country' => $c]) }}"
|
||||
class="flex items-center mb-5 font-medium text-gray-900 lg:w-auto lg:items-center lg:justify-center md:mb-0">
|
||||
@@ -30,6 +31,8 @@
|
||||
class="{{ request()->routeIs('search.course') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Kurse</a>
|
||||
<a href="{{ route('search.event', ['country' => $c, '#table']) }}"
|
||||
class="{{ request()->routeIs('search.event') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Termine</a>
|
||||
<a href="{{ route('library', ['country' => $c]) }}"
|
||||
class="{{ request()->routeIs('library') ? 'text-amber-500 underline' : 'text-gray-400' }} mr-5 font-medium leading-6 hover:text-gray-300">Bibliothek</a>
|
||||
</nav>
|
||||
</div>
|
||||
@auth
|
||||
@@ -47,6 +50,7 @@
|
||||
</div>
|
||||
@endauth
|
||||
</div>
|
||||
@if($withGlobe)
|
||||
<div class="flex lg:flex-row flex-col pt-4 md:pt-4 lg:pt-4">
|
||||
<div
|
||||
class="w-full lg:w-1/2 flex lg:px-0 px-5 flex-col md:items-center lg:items-start justify-center -mt-12">
|
||||
@@ -123,6 +127,7 @@
|
||||
<div x-ref="myearth" class="earth-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
47
resources/views/livewire/frontend/library.blade.php
Normal file
47
resources/views/livewire/frontend/library.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<div class="bg-21gray flex flex-col h-screen justify-between">
|
||||
{{-- HEADER --}}
|
||||
<livewire:frontend.header :country="$country" :withGlobe="false"/>
|
||||
{{-- MAIN --}}
|
||||
<section class="w-full mb-12">
|
||||
<div class="max-w-screen-2xl mx-auto px-2 sm:px-10" id="table">
|
||||
|
||||
<div class="relative border-b border-gray-200 pb-5 sm:pb-0">
|
||||
<div class="md:flex md:items-center md:justify-between">
|
||||
<h3 class="text-2xl font-medium leading-6 text-gray-200">Bibliotheken</h3>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<!-- Dropdown menu on small screens -->
|
||||
{{--<div class="sm:hidden">
|
||||
<label for="current-tab" class="sr-only">Select a tab</label>
|
||||
<select id="current-tab" name="current-tab" class="block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-base focus:border-amber-500 focus:outline-none focus:ring-amber-500 sm:text-sm">
|
||||
<option>Applied</option>
|
||||
<option>Phone Screening</option>
|
||||
<option>Interview</option>
|
||||
<option>Offer</option>
|
||||
<option>Hired</option>
|
||||
</select>
|
||||
</div>--}}
|
||||
<!-- Tabs at small breakpoint and up -->
|
||||
<div class="hidden sm:block">
|
||||
<nav class="-mb-px flex space-x-8">
|
||||
@foreach($libraries as $library)
|
||||
@php
|
||||
$currentLibraryClass = $currentTab === $library->name ? 'border-amber-500 text-amber-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300';
|
||||
@endphp
|
||||
<a href="{{ route('library', ['country' => $country, 'currentTab' => $library->name]) }}"
|
||||
class="{{ $currentLibraryClass }} whitespace-nowrap pb-4 px-1 border-b-2 font-medium text-sm">{{ $library->name }}</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<livewire:frontend.search-by-tag-in-library/>
|
||||
<div class="my-12">
|
||||
<livewire:tables.library-item-table/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{-- FOOTER --}}
|
||||
<livewire:frontend.footer/>
|
||||
</div>
|
||||
@@ -0,0 +1,54 @@
|
||||
<div
|
||||
class="flex overflow-auto relative flex-wrap gap-x-5 gap-y-6 justify-center p-0 mx-auto mt-8 mb-3 w-full font-normal leading-6 text-white align-baseline border-0 border-solid md:mx-auto md:mb-0 md:max-w-screen-md"
|
||||
style="max-width: 1350px; font-size: 128%; background-position: 0px center; max-height: 500px; list-style: outside;"
|
||||
>
|
||||
@foreach($tags->sortBy('name') as $tag)
|
||||
<div
|
||||
class="flex flex-1 justify-center p-0 m-0 leading-6 text-center align-baseline border-0 border-solid"
|
||||
style="font-size: 128%; background-position: 0px center; list-style: outside;"
|
||||
>
|
||||
@php
|
||||
$isActive = collect($table)->pluck('tag')->collapse()->contains($tag->name);
|
||||
$activeClass = $isActive ? 'text-amber-500 bg-amber-500' : 'bg-blue-50 text-white hover:text-amber-500';
|
||||
@endphp
|
||||
<a
|
||||
class="{{ $activeClass }} flex relative flex-col flex-shrink-0 justify-between py-1 px-3 w-full h-20 border-0 border-solid duration-300 ease-in-out cursor-pointer bg-opacity-[0.07]"
|
||||
href="#"
|
||||
>
|
||||
<div
|
||||
class="flex flex-1 items-center p-0 m-0 text-center align-baseline border-0 border-solid"
|
||||
>
|
||||
<div
|
||||
class="flex flex-shrink-0 justify-center p-0 my-0 mr-4 ml-0 align-baseline border-0 border-solid"
|
||||
>
|
||||
<i class="fa fa-thin fa-{{ $tag->icon }} text-4xl"></i>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between p-0 m-0 w-full align-baseline border-0 border-solid md:block lg:w-auto"
|
||||
>
|
||||
<h2
|
||||
class="p-0 m-0 font-sans text-base font-semibold tracking-wide leading-tight text-left align-baseline border-0 border-solid"
|
||||
style="background-position: 0px center; list-style: outside;"
|
||||
>
|
||||
{{ $tag->name }}
|
||||
</h2>
|
||||
<div
|
||||
class="hidden p-0 m-0 text-sm leading-3 text-left text-blue-100 align-baseline border-0 border-solid md:block md:text-blue-100 whitespace-nowrap"
|
||||
>
|
||||
0
|
||||
Dozenten
|
||||
<span
|
||||
class="inline-block relative top-px py-0 px-1 m-0 text-xs leading-4 align-baseline border-0 border-solid"
|
||||
>
|
||||
•
|
||||
</span>
|
||||
0
|
||||
Inhalte
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a
|
||||
>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@@ -12,15 +12,21 @@
|
||||
|
||||
<!-- Navigation Links -->
|
||||
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
|
||||
<x-jet-nav-link href="/nova" target="_blank">
|
||||
<x-jet-nav-link href="/nova/resources/lecturers" target="_blank">
|
||||
{{ __('Dozent eintragen') }}
|
||||
</x-jet-nav-link>
|
||||
<x-jet-nav-link href="/nova/resources/courses" target="_blank">
|
||||
{{ __('Kurs eintragen') }}
|
||||
</x-jet-nav-link>
|
||||
<x-jet-nav-link href="/nova/resources/events" target="_blank">
|
||||
{{ __('Kurs-Termin eintragen') }}
|
||||
</x-jet-nav-link>
|
||||
<x-jet-nav-link href="/nova/resources/library-items" target="_blank">
|
||||
{{ __('Inhalte eintragen') }}
|
||||
</x-jet-nav-link>
|
||||
<x-jet-nav-link href="{{ route('profile.show') }}" :active="request()->routeIs('profile.show')">
|
||||
{{ __('Mein Profil') }}
|
||||
</x-jet-nav-link>
|
||||
<x-jet-nav-link href="/nova/resources/events" target="_blank">
|
||||
{{ __('Meine Termine') }}
|
||||
</x-jet-nav-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ Route::get('/{country:code}/suche/kurs', \App\Http\Livewire\Frontend\SearchCours
|
||||
Route::get('/{country:code}/suche/termin', \App\Http\Livewire\Frontend\SearchEvent::class)
|
||||
->name('search.event');
|
||||
|
||||
Route::get('/{country:code}/bibliothek', \App\Http\Livewire\Frontend\Library::class)
|
||||
->name('library');
|
||||
|
||||
Route::get('/dozenten', \App\Http\Livewire\Guest\Welcome::class)
|
||||
->name('search.lecturers');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user