From 83f1b0609f2918ff7a75f2dde9de4e96fccd34c4 Mon Sep 17 00:00:00 2001 From: Benjamin Takats Date: Mon, 5 Dec 2022 19:04:57 +0100 Subject: [PATCH] new library added --- .blueprint | 3 + app/Console/Commands/Database/CreateTags.php | 11 +- app/Http/Livewire/Frontend/Header.php | 1 + app/Http/Livewire/Frontend/Library.php | 27 ++ app/Http/Livewire/Frontend/SearchByTag.php | 1 + .../Frontend/SearchByTagInLibrary.php | 25 ++ app/Http/Livewire/Tables/CourseTable.php | 2 +- app/Http/Livewire/Tables/LecturerTable.php | 6 + app/Http/Livewire/Tables/LibraryItemTable.php | 61 +++++ app/Models/Country.php | 5 +- app/Models/Lecturer.php | 5 + app/Models/Library.php | 33 +++ app/Models/LibraryItem.php | 71 ++++++ app/Nova/Country.php | 23 +- app/Nova/Course.php | 2 +- app/Nova/Library.php | 106 ++++++++ app/Nova/LibraryItem.php | 146 +++++++++++ app/Nova/Tag.php | 3 +- app/Providers/NovaServiceProvider.php | 9 + composer.json | 1 + composer.lock | 2 +- config/eloquent-sortable.php | 14 ++ config/ignition.php | 234 ++++++++++++++++++ config/languages/languages.php | 188 ++++++++++++++ config/tags/tags.php | 130 +++++++--- database/factories/LibraryFactory.php | 30 +++ database/factories/LibraryItemsFactory.php | 35 +++ ...22_12_01_145948_create_countries_table.php | 4 +- ...22_12_05_160932_create_libraries_table.php | 32 +++ ...2_05_160933_create_library_items_table.php | 42 ++++ ...5957_create_library_library_item_table.php | 39 +++ database/seeders/DatabaseSeeder.php | 78 +++++- .../views/columns/lectures/action.blade.php | 11 +- .../columns/library_items/action.blade.php | 6 + .../views/livewire/frontend/header.blade.php | 93 +++---- .../views/livewire/frontend/library.blade.php | 47 ++++ .../search-by-tag-in-library.blade.php | 54 ++++ resources/views/navigation-menu.blade.php | 14 +- routes/web.php | 3 + 39 files changed, 1482 insertions(+), 115 deletions(-) create mode 100644 app/Http/Livewire/Frontend/Library.php create mode 100644 app/Http/Livewire/Frontend/SearchByTagInLibrary.php create mode 100644 app/Http/Livewire/Tables/LibraryItemTable.php create mode 100644 app/Models/Library.php create mode 100644 app/Models/LibraryItem.php create mode 100644 app/Nova/Library.php create mode 100644 app/Nova/LibraryItem.php create mode 100644 config/eloquent-sortable.php create mode 100644 config/ignition.php create mode 100644 config/languages/languages.php create mode 100644 database/factories/LibraryFactory.php create mode 100644 database/factories/LibraryItemsFactory.php create mode 100644 database/migrations/2022_12_05_160932_create_libraries_table.php create mode 100644 database/migrations/2022_12_05_160933_create_library_items_table.php create mode 100644 database/migrations/2022_12_05_175957_create_library_library_item_table.php create mode 100644 resources/views/columns/library_items/action.blade.php create mode 100644 resources/views/livewire/frontend/library.blade.php create mode 100644 resources/views/livewire/frontend/search-by-tag-in-library.blade.php diff --git a/.blueprint b/.blueprint index f51be3e2..891623c0 100644 --- a/.blueprint +++ b/.blueprint @@ -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 } diff --git a/app/Console/Commands/Database/CreateTags.php b/app/Console/Commands/Database/CreateTags.php index a9601108..f6c20103 100644 --- a/app/Console/Commands/Database/CreateTags.php +++ b/app/Console/Commands/Database/CreateTags.php @@ -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(); diff --git a/app/Http/Livewire/Frontend/Header.php b/app/Http/Livewire/Frontend/Header.php index b24d10ee..f45ec561 100644 --- a/app/Http/Livewire/Frontend/Header.php +++ b/app/Http/Livewire/Frontend/Header.php @@ -12,6 +12,7 @@ class Header extends Component public Country $country; public $currentRouteName; public string $c = 'de'; + public bool $withGlobe = true; public function rules() { diff --git a/app/Http/Livewire/Frontend/Library.php b/app/Http/Livewire/Frontend/Library.php new file mode 100644 index 00000000..d33c4a2c --- /dev/null +++ b/app/Http/Livewire/Frontend/Library.php @@ -0,0 +1,27 @@ + ['except' => 'alle'], + ]; + + public function render() + { + return view('livewire.frontend.library', [ + 'libraries' => \App\Models\Library::get() + ->prepend(\App\Models\Library::make([ + 'name' => 'Alle', + ])), + ]); + } +} diff --git a/app/Http/Livewire/Frontend/SearchByTag.php b/app/Http/Livewire/Frontend/SearchByTag.php index f61f4209..d7b819cb 100644 --- a/app/Http/Livewire/Frontend/SearchByTag.php +++ b/app/Http/Livewire/Frontend/SearchByTag.php @@ -18,6 +18,7 @@ class SearchByTag extends Component { return view('livewire.frontend.search-by-tag', [ 'tags' => Tag::query() + ->where('type', 'course') ->with([ 'courses.lecturer', ]) diff --git a/app/Http/Livewire/Frontend/SearchByTagInLibrary.php b/app/Http/Livewire/Frontend/SearchByTagInLibrary.php new file mode 100644 index 00000000..2627172a --- /dev/null +++ b/app/Http/Livewire/Frontend/SearchByTagInLibrary.php @@ -0,0 +1,25 @@ + Tag::query() + ->where('type', 'library_item') + ->get(), + ]); + } +} diff --git a/app/Http/Livewire/Tables/CourseTable.php b/app/Http/Livewire/Tables/CourseTable.php index c4d980a9..cdb1f6b9 100644 --- a/app/Http/Livewire/Tables/CourseTable.php +++ b/app/Http/Livewire/Tables/CourseTable.php @@ -45,7 +45,7 @@ class CourseTable extends DataTableComponent ->toArray() ) ->filter(function (Builder $builder, array $values) { - $builder->withAnyTags($values, 'search'); + $builder->withAnyTags($values, 'course'); }), ]; } diff --git a/app/Http/Livewire/Tables/LecturerTable.php b/app/Http/Livewire/Tables/LecturerTable.php index fc1c6423..14375230 100644 --- a/app/Http/Livewire/Tables/LecturerTable.php +++ b/app/Http/Livewire/Tables/LecturerTable.php @@ -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', ]); } diff --git a/app/Http/Livewire/Tables/LibraryItemTable.php b/app/Http/Livewire/Tables/LibraryItemTable.php new file mode 100644 index 00000000..d81e2255 --- /dev/null +++ b/app/Http/Livewire/Tables/LibraryItemTable.php @@ -0,0 +1,61 @@ +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', + ]); + } +} diff --git a/app/Models/Country.php b/app/Models/Country.php index 115129b3..5168dbbc 100644 --- a/app/Models/Country.php +++ b/app/Models/Country.php @@ -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', + 'id' => 'integer', + 'language_codes' => 'array', ]; public function cities(): \Illuminate\Database\Eloquent\Relations\HasMany diff --git a/app/Models/Lecturer.php b/app/Models/Lecturer.php index 116d202b..844a4093 100644 --- a/app/Models/Lecturer.php +++ b/app/Models/Lecturer.php @@ -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); + } } diff --git a/app/Models/Library.php b/app/Models/Library.php new file mode 100644 index 00000000..3fb15bdd --- /dev/null +++ b/app/Models/Library.php @@ -0,0 +1,33 @@ + 'integer', + 'language_codes' => 'array', + ]; + + public function libraryItems(): \Illuminate\Database\Eloquent\Relations\BelongsToMany + { + return $this->belongsToMany(LibraryItem::class); + } +} diff --git a/app/Models/LibraryItem.php b/app/Models/LibraryItem.php new file mode 100644 index 00000000..bc6a210d --- /dev/null +++ b/app/Models/LibraryItem.php @@ -0,0 +1,71 @@ + '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); + } +} diff --git a/app/Nova/Country.php b/app/Nova/Country.php index 3e5a9796..b8823bbc 100644 --- a/app/Nova/Country.php +++ b/app/Nova/Country.php @@ -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) diff --git a/app/Nova/Course.php b/app/Nova/Course.php index ebf23c9d..49a5807a 100644 --- a/app/Nova/Course.php +++ b/app/Nova/Course.php @@ -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'), diff --git a/app/Nova/Library.php b/app/Nova/Library.php new file mode 100644 index 00000000..e419186a --- /dev/null +++ b/app/Nova/Library.php @@ -0,0 +1,106 @@ +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 []; + } +} diff --git a/app/Nova/LibraryItem.php b/app/Nova/LibraryItem.php new file mode 100644 index 00000000..cfeb1abf --- /dev/null +++ b/app/Nova/LibraryItem.php @@ -0,0 +1,146 @@ +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 []; + } +} diff --git a/app/Nova/Tag.php b/app/Nova/Tag.php index 4421229b..0a8f063b 100644 --- a/app/Nova/Tag.php +++ b/app/Nova/Tag.php @@ -28,7 +28,8 @@ class Tag extends Resource Select::make('Type') ->options([ - 'search' => 'search', + 'course' => 'course', + 'library_item' => 'library_item', ]), ]; diff --git a/app/Providers/NovaServiceProvider.php b/app/Providers/NovaServiceProvider.php index 73ed6aac..d1eb5ef8 100644 --- a/app/Providers/NovaServiceProvider.php +++ b/app/Providers/NovaServiceProvider.php @@ -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), diff --git a/composer.json b/composer.json index 49ace2a2..b23136a2 100644 --- a/composer.json +++ b/composer.json @@ -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", diff --git a/composer.lock b/composer.lock index 0769a1a4..84dea70f 100644 --- a/composer.lock +++ b/composer.lock @@ -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", diff --git a/config/eloquent-sortable.php b/config/eloquent-sortable.php new file mode 100644 index 00000000..fa578210 --- /dev/null +++ b/config/eloquent-sortable.php @@ -0,0 +1,14 @@ + '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, +]; diff --git a/config/ignition.php b/config/ignition.php new file mode 100644 index 00000000..596fd613 --- /dev/null +++ b/config/ignition.php @@ -0,0 +1,234 @@ + 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//Code", "C:\Users\\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 + ] +]; diff --git a/config/languages/languages.php b/config/languages/languages.php new file mode 100644 index 00000000..d19c1950 --- /dev/null +++ b/config/languages/languages.php @@ -0,0 +1,188 @@ + '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' +]; diff --git a/config/tags/tags.php b/config/tags/tags.php index d26ec924..6d5bf3e5 100644 --- a/config/tags/tags.php +++ b/config/tags/tags.php @@ -1,44 +1,98 @@ 'Hardware Wallet', - 'en' => 'Hardware Wallet', - 'icon' => 'wallet', + 'course' => [ + [ + 'de' => 'Hardware Wallet', + 'en' => 'Hardware Wallet', + 'icon' => 'wallet', + ], + [ + 'de' => 'Software Wallet', + 'en' => 'Software Wallet', + 'icon' => 'message-code', + ], + [ + 'de' => 'Lightning', + 'en' => 'Lightning', + 'icon' => 'bolt-lightning', + ], + [ + 'de' => 'On-Chain', + 'en' => 'On-Chain', + 'icon' => 'link-horizontal', + ], + [ + 'de' => 'Off-Chain', + 'en' => 'Off-Chain', + 'icon' => 'link-horizontal-slash', + ], + [ + 'de' => 'Für Unternehmen', + 'en' => 'For Businesses', + 'icon' => 'buildings', + ], + [ + 'de' => 'Mining', + 'en' => 'Mining', + 'icon' => 'pickaxe', + ], + [ + 'de' => 'Datenschutz', + 'en' => 'Privacy', + 'icon' => 'shield-keyhole', + ], ], - [ - 'de' => 'Software Wallet', - 'en' => 'Software Wallet', - 'icon' => 'message-code', - ], - [ - 'de' => 'Lightning', - 'en' => 'Lightning', - 'icon' => 'bolt-lightning', - ], - [ - 'de' => 'On-Chain', - 'en' => 'On-Chain', - 'icon' => 'link-horizontal', - ], - [ - 'de' => 'Off-Chain', - 'en' => 'Off-Chain', - 'icon' => 'link-horizontal-slash', - ], - [ - 'de' => 'Für Unternehmen', - 'en' => 'For Businesses', - 'icon' => 'buildings', - ], - [ - 'de' => 'Mining', - 'en' => 'Mining', - 'icon' => 'pickaxe', - ], - [ - 'de' => 'Datenschutz', - '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', + ], ], ]; diff --git a/database/factories/LibraryFactory.php b/database/factories/LibraryFactory.php new file mode 100644 index 00000000..91a54646 --- /dev/null +++ b/database/factories/LibraryFactory.php @@ -0,0 +1,30 @@ + $this->faker->name, + 'language_code' => $this->faker->word, + ]; + } +} diff --git a/database/factories/LibraryItemsFactory.php b/database/factories/LibraryItemsFactory.php new file mode 100644 index 00000000..e3583215 --- /dev/null +++ b/database/factories/LibraryItemsFactory.php @@ -0,0 +1,35 @@ + Lecturer::factory(), + 'library_id' => Library::factory(), + 'order_column' => $this->faker->randomNumber(), + 'type' => $this->faker->word, + 'value' => $this->faker->text, + ]; + } +} diff --git a/database/migrations/2022_12_01_145948_create_countries_table.php b/database/migrations/2022_12_01_145948_create_countries_table.php index 00bbbdf7..cb91b47c 100644 --- a/database/migrations/2022_12_01_145948_create_countries_table.php +++ b/database/migrations/2022_12_01_145948_create_countries_table.php @@ -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 diff --git a/database/migrations/2022_12_05_160932_create_libraries_table.php b/database/migrations/2022_12_05_160932_create_libraries_table.php new file mode 100644 index 00000000..eef762c5 --- /dev/null +++ b/database/migrations/2022_12_05_160932_create_libraries_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name'); + $table->json('language_codes') + ->default('[]'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * @return void + */ + public function down(): void + { + Schema::dropIfExists('libraries'); + } +} diff --git a/database/migrations/2022_12_05_160933_create_library_items_table.php b/database/migrations/2022_12_05_160933_create_library_items_table.php new file mode 100644 index 00000000..65a25a00 --- /dev/null +++ b/database/migrations/2022_12_05_160933_create_library_items_table.php @@ -0,0 +1,42 @@ +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'); + } +} diff --git a/database/migrations/2022_12_05_175957_create_library_library_item_table.php b/database/migrations/2022_12_05_175957_create_library_library_item_table.php new file mode 100644 index 00000000..7e1229f4 --- /dev/null +++ b/database/migrations/2022_12_05_175957_create_library_library_item_table.php @@ -0,0 +1,39 @@ +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'); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 76257560..68f46f29 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -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; @@ -49,16 +51,24 @@ class DatabaseSeeder extends Seeder $user->current_team_id = $team->id; $user->save(); Country::create([ - 'name' => 'Deutschland', - 'code' => 'de', + 'name' => 'Deutschland', + 'code' => 'de', + 'language_codes' => ['de'], ]); Country::create([ - 'name' => 'Österreich', - 'code' => 'at', + 'name' => 'Österreich', + 'code' => 'at', + 'language_codes' => ['de'], ]); Country::create([ - 'name' => 'Schweiz', - 'code' => 'ch', + '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'); } } diff --git a/resources/views/columns/lectures/action.blade.php b/resources/views/columns/lectures/action.blade.php index d436cbf4..747ecd69 100644 --- a/resources/views/columns/lectures/action.blade.php +++ b/resources/views/columns/lectures/action.blade.php @@ -1 +1,10 @@ -Termine anzeigen +
+ + + Termine anzeigen + + + + Inhalte anzeigen + +
diff --git a/resources/views/columns/library_items/action.blade.php b/resources/views/columns/library_items/action.blade.php new file mode 100644 index 00000000..2e7acb1a --- /dev/null +++ b/resources/views/columns/library_items/action.blade.php @@ -0,0 +1,6 @@ +
+ + + Öffnen + +
diff --git a/resources/views/livewire/frontend/header.blade.php b/resources/views/livewire/frontend/header.blade.php index 3e05961d..da6330b7 100644 --- a/resources/views/livewire/frontend/header.blade.php +++ b/resources/views/livewire/frontend/header.blade.php @@ -12,7 +12,8 @@
- -
-
+ @if($withGlobe) +
+
-

- Bitcoin School +

+ Bitcoin School
{{ str($country->name)->upper() }} -

-
- - @foreach($countries as $country) - - @endforeach - +

+
+ + @foreach($countries as $country) + + @endforeach + +
+

+ Finde Bitcoin Kurse in deiner City

+ @php + $searchTitle = match ($currentRouteName) { + 'search.city' => 'Stadt', + 'search.lecturer' => 'Dozent', + 'search.venue' => 'Veranstaltungs-Ort', + 'search.course' => 'Kurs', + 'search.event' => 'Termin', + }; + @endphp + + 👇 {{ $searchTitle }} finden 👇 + +

{{-- TEXT --}}

-

- Finde Bitcoin Kurse in deiner City

- @php - $searchTitle = match ($currentRouteName) { - 'search.city' => 'Stadt', - 'search.lecturer' => 'Dozent', - 'search.venue' => 'Veranstaltungs-Ort', - 'search.course' => 'Kurs', - 'search.event' => 'Termin', - }; - @endphp - - 👇 {{ $searchTitle }} finden 👇 - -

{{-- TEXT --}}

-
-
-
+ @endif
diff --git a/resources/views/livewire/frontend/library.blade.php b/resources/views/livewire/frontend/library.blade.php new file mode 100644 index 00000000..c5a92d51 --- /dev/null +++ b/resources/views/livewire/frontend/library.blade.php @@ -0,0 +1,47 @@ +
+ {{-- HEADER --}} + + {{-- MAIN --}} +
+
+ +
+
+

Bibliotheken

+
+
+ + {{--
+ + +
--}} + + +
+
+ + +
+ +
+
+
+ {{-- FOOTER --}} + +
diff --git a/resources/views/livewire/frontend/search-by-tag-in-library.blade.php b/resources/views/livewire/frontend/search-by-tag-in-library.blade.php new file mode 100644 index 00000000..574a1190 --- /dev/null +++ b/resources/views/livewire/frontend/search-by-tag-in-library.blade.php @@ -0,0 +1,54 @@ +
+ @foreach($tags->sortBy('name') as $tag) +
+ @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 + +
+
+ +
+
+

+ {{ $tag->name }} +

+ +
+
+
+
+ @endforeach +
diff --git a/resources/views/navigation-menu.blade.php b/resources/views/navigation-menu.blade.php index 42a6f9e7..86c218c4 100644 --- a/resources/views/navigation-menu.blade.php +++ b/resources/views/navigation-menu.blade.php @@ -12,15 +12,21 @@ diff --git a/routes/web.php b/routes/web.php index 9857fffb..ed076b20 100644 --- a/routes/web.php +++ b/routes/web.php @@ -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');