mirror of
https://github.com/Einundzwanzig-Podcast/einundzwanzig-portal.git
synced 2025-12-11 06:46:47 +00:00
libraryItem forms added
This commit is contained in:
@@ -17,6 +17,7 @@ enum LibraryItemType: string
|
|||||||
case Book = 'book';
|
case Book = 'book';
|
||||||
case BlogArticle = 'blog_article';
|
case BlogArticle = 'blog_article';
|
||||||
case MarkdownArticle = 'markdown_article';
|
case MarkdownArticle = 'markdown_article';
|
||||||
|
case MarkdownArticleExtern = 'markdown_article_extern';
|
||||||
case YoutubeVideo = 'youtube_video';
|
case YoutubeVideo = 'youtube_video';
|
||||||
case VimeoVideo = 'vimeo_video';
|
case VimeoVideo = 'vimeo_video';
|
||||||
case PodcastEpisode = 'podcast_episode';
|
case PodcastEpisode = 'podcast_episode';
|
||||||
@@ -25,26 +26,28 @@ enum LibraryItemType: string
|
|||||||
public static function labels(): array
|
public static function labels(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'book' => __('Book'),
|
'book' => __('Book'),
|
||||||
'blog_article' => __('Article'),
|
'blog_article' => __('Article'),
|
||||||
'markdown_article' => __('Markdown Article'),
|
'markdown_article' => __('Markdown Article'),
|
||||||
'youtube_video' => __('Youtube Video'),
|
'markdown_article_extern' => __('Markdown Article Extern'),
|
||||||
'vimeo_video' => __('Vimeo Video'),
|
'youtube_video' => __('Youtube Video'),
|
||||||
'podcast_episode' => __('Podcast Episode'),
|
'vimeo_video' => __('Vimeo Video'),
|
||||||
'downloadable_file' => __('Downloadable File'),
|
'podcast_episode' => __('Podcast Episode'),
|
||||||
|
'downloadable_file' => __('Downloadable File'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function icons(): array
|
public static function icons(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'book' => 'book',
|
'book' => 'book',
|
||||||
'blog_article' => 'newspaper',
|
'blog_article' => 'newspaper',
|
||||||
'markdown_article' => 'newspaper',
|
'markdown_article' => 'newspaper',
|
||||||
'youtube_video' => 'video',
|
'markdown_article_extern' => 'newspaper',
|
||||||
'vimeo_video' => 'video',
|
'youtube_video' => 'video',
|
||||||
'podcast_episode' => 'podcast',
|
'vimeo_video' => 'video',
|
||||||
'downloadable_file' => 'download',
|
'podcast_episode' => 'podcast',
|
||||||
|
'downloadable_file' => 'download',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ class CityForm extends Component
|
|||||||
if (!$this->city) {
|
if (!$this->city) {
|
||||||
$this->city = new City();
|
$this->city = new City();
|
||||||
}
|
}
|
||||||
|
if (!$this->fromUrl) {
|
||||||
|
$this->fromUrl = url()->previous();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save()
|
public function save()
|
||||||
@@ -39,7 +42,7 @@ class CityForm extends Component
|
|||||||
$this->validate();
|
$this->validate();
|
||||||
$this->city->save();
|
$this->city->save();
|
||||||
|
|
||||||
return redirect($this->fromUrl);
|
return redirect($this->fromUrl ?? url()->route('welcome'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
|||||||
69
app/Http/Livewire/ContentCreator/Form/ContentCreatorForm.php
Normal file
69
app/Http/Livewire/ContentCreator/Form/ContentCreatorForm.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\ContentCreator\Form;
|
||||||
|
|
||||||
|
use App\Models\Lecturer;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithFileUploads;
|
||||||
|
|
||||||
|
class ContentCreatorForm extends Component
|
||||||
|
{
|
||||||
|
use WithFileUploads;
|
||||||
|
|
||||||
|
public ?Lecturer $lecturer = null;
|
||||||
|
public $image;
|
||||||
|
|
||||||
|
public ?string $fromUrl = '';
|
||||||
|
|
||||||
|
protected $queryString = ['fromUrl' => ['except' => '']];
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'image' => [Rule::requiredIf(!$this->lecturer->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'],
|
||||||
|
|
||||||
|
'lecturer.name' => 'required',
|
||||||
|
'lecturer.active' => 'boolean',
|
||||||
|
'lecturer.subtitle' => 'required',
|
||||||
|
'lecturer.intro' => 'required',
|
||||||
|
'lecturer.twitter_username' => 'nullable|string',
|
||||||
|
'lecturer.website' => 'nullable|url',
|
||||||
|
'lecturer.lightning_address' => 'nullable|string',
|
||||||
|
'lecturer.lnurl' => 'nullable|string',
|
||||||
|
'lecturer.node_id' => 'nullable|string',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
if (!$this->lecturer) {
|
||||||
|
$this->lecturer = new Lecturer([
|
||||||
|
'intro' => '',
|
||||||
|
'active' => true,
|
||||||
|
'team_id' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (!$this->fromUrl) {
|
||||||
|
$this->fromUrl = url()->previous();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$this->validate();
|
||||||
|
$this->lecturer->save();
|
||||||
|
|
||||||
|
if ($this->image) {
|
||||||
|
$this->lecturer->addMedia($this->image)
|
||||||
|
->toMediaCollection('avatar');
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect($this->fromUrl ?? url()->route('welcome'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.content-creator.form.content-creator-form');
|
||||||
|
}
|
||||||
|
}
|
||||||
122
app/Http/Livewire/Library/Form/LibraryItemForm.php
Normal file
122
app/Http/Livewire/Library/Form/LibraryItemForm.php
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\Library\Form;
|
||||||
|
|
||||||
|
use App\Enums\LibraryItemType;
|
||||||
|
use App\Models\Country;
|
||||||
|
use App\Models\Library;
|
||||||
|
use App\Models\LibraryItem;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithFileUploads;
|
||||||
|
use Spatie\LaravelOptions\Options;
|
||||||
|
|
||||||
|
class LibraryItemForm extends Component
|
||||||
|
{
|
||||||
|
use WithFileUploads;
|
||||||
|
|
||||||
|
public Country $country;
|
||||||
|
|
||||||
|
public ?LibraryItem $libraryItem = null;
|
||||||
|
public $library;
|
||||||
|
public $image;
|
||||||
|
public $file;
|
||||||
|
|
||||||
|
public bool $lecturer = false;
|
||||||
|
public ?string $fromUrl = '';
|
||||||
|
|
||||||
|
protected $queryString = [
|
||||||
|
'fromUrl' => ['except' => ''],
|
||||||
|
'lecturer' => ['except' => false],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'image' => [Rule::requiredIf(!$this->libraryItem->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'],
|
||||||
|
|
||||||
|
'library' => 'required',
|
||||||
|
|
||||||
|
'libraryItem.lecturer_id' => 'required',
|
||||||
|
'libraryItem.name' => 'required',
|
||||||
|
'libraryItem.type' => 'required',
|
||||||
|
'libraryItem.language_code' => 'required',
|
||||||
|
'libraryItem.value' => [
|
||||||
|
'required',
|
||||||
|
Rule::when(
|
||||||
|
$this->libraryItem->type !== LibraryItemType::MarkdownArticle
|
||||||
|
&& $this->libraryItem->type !== LibraryItemType::MarkdownArticleExtern
|
||||||
|
&& $this->libraryItem->type !== LibraryItemType::DownloadableFile, ['url']
|
||||||
|
)
|
||||||
|
],
|
||||||
|
'libraryItem.subtitle' => 'required',
|
||||||
|
'libraryItem.excerpt' => 'required',
|
||||||
|
'libraryItem.main_image_caption' => 'required',
|
||||||
|
'libraryItem.read_time' => 'required',
|
||||||
|
'libraryItem.approved' => 'boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
if (!$this->libraryItem) {
|
||||||
|
$this->libraryItem = new LibraryItem([
|
||||||
|
'approved' => true,
|
||||||
|
'read_time' => 1,
|
||||||
|
]);
|
||||||
|
if ($this->lecturer) {
|
||||||
|
$this->library = Library::query()
|
||||||
|
->firstWhere('name', '=', 'Dozentenmaterial')?->id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->library = $this->libraryItem->libraries()
|
||||||
|
->first()
|
||||||
|
->id;
|
||||||
|
}
|
||||||
|
if (!$this->fromUrl) {
|
||||||
|
$this->fromUrl = url()->previous();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$this->validate();
|
||||||
|
$this->libraryItem->save();
|
||||||
|
$this->libraryItem->setStatus('published');
|
||||||
|
|
||||||
|
if ($this->image) {
|
||||||
|
$this->libraryItem->addMedia($this->image)
|
||||||
|
->toMediaCollection('main');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->file) {
|
||||||
|
$this->libraryItem->addMedia($this->file)
|
||||||
|
->toMediaCollection('single_file');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->libraryItem->libraries()
|
||||||
|
->syncWithoutDetaching([(int) $this->library]);
|
||||||
|
|
||||||
|
return to_route('library.table.libraryItems', ['country' => $this->country]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.library.form.library-item-form', [
|
||||||
|
'types' => Options::forEnum(LibraryItemType::class)
|
||||||
|
->filter(
|
||||||
|
fn($type) => $type !== LibraryItemType::PodcastEpisode
|
||||||
|
&& $type !== LibraryItemType::MarkdownArticle
|
||||||
|
)
|
||||||
|
->toArray(),
|
||||||
|
'libraries' => Library::query()
|
||||||
|
->where('is_public', true)
|
||||||
|
->get()
|
||||||
|
->map(fn($library) => [
|
||||||
|
'id' => $library->id,
|
||||||
|
'name' => $library->name,
|
||||||
|
])
|
||||||
|
->toArray(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -758,5 +758,10 @@
|
|||||||
"Article tweeted": "Artikel getwittert",
|
"Article tweeted": "Artikel getwittert",
|
||||||
"Error tweeting article": "Fehler beim Twittern des Artikels",
|
"Error tweeting article": "Fehler beim Twittern des Artikels",
|
||||||
"Tweet": "Tweet",
|
"Tweet": "Tweet",
|
||||||
"Are you sure you want to tweet this article?": "Bitte bestätige, dass du diesen Artikel tweeten möchtest."
|
"Are you sure you want to tweet this article?": "Bitte bestätige, dass du diesen Artikel tweeten möchtest.",
|
||||||
|
"Markdown Article Extern": "Markdown Artikel",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "Bitte klassifiziere deinen Eintrag nach Art.",
|
||||||
|
"Choose language": "Wähle Sprache",
|
||||||
|
"File": "Datei"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -754,5 +754,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -754,5 +754,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -755,5 +755,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -717,5 +717,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -729,5 +729,10 @@
|
|||||||
"Article tweeted": "",
|
"Article tweeted": "",
|
||||||
"Error tweeting article": "",
|
"Error tweeting article": "",
|
||||||
"Tweet": "",
|
"Tweet": "",
|
||||||
"Are you sure you want to tweet this article?": ""
|
"Are you sure you want to tweet this article?": "",
|
||||||
|
"Markdown Article Extern": "",
|
||||||
|
"twitter_username": "",
|
||||||
|
"Please classify by type of your entry.": "",
|
||||||
|
"Choose language": "",
|
||||||
|
"File": ""
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="w-full mb-4 md:w-auto md:mb-0" x-data="{currentUrl: window.location.href}">
|
<div class="w-full mb-4 md:w-auto md:mb-0" x-data="{currentUrl: window.location.href}">
|
||||||
<a x-bind:href="'http://localhost/city/form/?fromUrl='+currentUrl">
|
<a x-bind:href="'/city/form/?fromUrl='+currentUrl">
|
||||||
<x-button>
|
<x-button>
|
||||||
<i class="fa fa-thin fa-plus"></i>
|
<i class="fa fa-thin fa-plus"></i>
|
||||||
{{ __('New City') }}
|
{{ __('New City') }}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
<div class="container p-4 mx-auto bg-21gray my-2">
|
||||||
|
|
||||||
|
<div class="pb-5 flex flex-row justify-between">
|
||||||
|
<h3 class="text-lg font-medium leading-6 text-gray-200">{{ __('Lecturer/Content Creator') }}</h3>
|
||||||
|
<div class="flex flex-row space-x-2 items-center">
|
||||||
|
<div>
|
||||||
|
<x-button :href="$fromUrl">
|
||||||
|
<i class="fa fa-thin fa-arrow-left"></i>
|
||||||
|
{{ __('Back') }}
|
||||||
|
</x-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="space-y-8 divide-y divide-gray-700 pb-24">
|
||||||
|
<div class="space-y-8 divide-y divide-gray-700 sm:space-y-5">
|
||||||
|
<div class="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
|
||||||
|
|
||||||
|
<x-input.group :for=" md5('image')" :label="__('Main picture')">
|
||||||
|
<div class="py-4">
|
||||||
|
@if ($image)
|
||||||
|
<div class="text-gray-200">{{ __('Preview') }}:</div>
|
||||||
|
<img class="h-48 object-contain" src="{{ $image->temporaryUrl() }}">
|
||||||
|
@endif
|
||||||
|
@if ($lecturer->getFirstMediaUrl('avatar'))
|
||||||
|
<div class="text-gray-200">{{ __('Current picture') }}:</div>
|
||||||
|
<img class="h-48 object-contain" src="{{ $lecturer->getFirstMediaUrl('avatar') }}">
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<input class="text-gray-200" type="file" wire:model="image">
|
||||||
|
@error('image') <span class="text-red-500">{{ $message }}</span> @enderror
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.name')" :label="__('Title')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.name"
|
||||||
|
:placeholder="__('Title')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.subtitle')" :label="__('Subtitle')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.subtitle"
|
||||||
|
:placeholder="__('Subtitle')" :hint="__('This is the subtitle on the landing page.')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.intro')" :label="__('Intro')">
|
||||||
|
<div
|
||||||
|
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</div>
|
||||||
|
<x-input.simple-mde wire:model.defer="lecturer.intro"/>
|
||||||
|
@error('lecturer.intro') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
|
||||||
|
<span class="text-gray-400 text-xs py-2">{{ __('This is the introduction text that is shown on the landing page.') }}</span>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.twitter_username')" :label="__('Twitter Username')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.twitter_username"
|
||||||
|
:placeholder="__('Twitter Username')" :hint="__('Without @')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.website')" :label="__('Website')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.website"
|
||||||
|
:placeholder="__('Website')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.lightning_address')" :label="__('Lightning Address')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.lightning_address"
|
||||||
|
:placeholder="__('Lightning Address')" :hint="__('for example xy@getalby.com')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.lnurl')" :label="__('LNURL')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.lnurl"
|
||||||
|
:placeholder="__('LNURL')" :hint="__('starts with: lnurl1dp68gurn8gh....')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('lecturer.node_id')" :label="__('Node Id')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="lecturer.node_id"
|
||||||
|
:placeholder="__('Node Id')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('meetupEvent.link')" label="">
|
||||||
|
<x-button primary wire:click="save">
|
||||||
|
<i class="fa fa-thin fa-save"></i>
|
||||||
|
{{ __('Save') }}
|
||||||
|
</x-button>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@@ -188,6 +188,19 @@
|
|||||||
<p class="px-0 mb-2 text-lg text-gray-600 md:text-xl lg:px-24">
|
<p class="px-0 mb-2 text-lg text-gray-600 md:text-xl lg:px-24">
|
||||||
{{ __('Choose a topic that is right for you.') }}
|
{{ __('Choose a topic that is right for you.') }}
|
||||||
</p>
|
</p>
|
||||||
|
@auth
|
||||||
|
@if(str(request()->route()->getName())->contains('lecturer'))
|
||||||
|
<x-button :href="route('library.libraryItem.form', ['country' => $c, 'lecturer' => true, 'fromUrl' => url()->route('library.table.libraryItems', ['country' => $country])])">
|
||||||
|
<i class="fa fa-thin fa-plus"></i>
|
||||||
|
{{ __('Submit contents') }}
|
||||||
|
</x-button>
|
||||||
|
@else
|
||||||
|
<x-button :href="route('library.libraryItem.form', ['country' => $c, 'fromUrl' => url()->route('library.table.libraryItems', ['country' => $country])])">
|
||||||
|
<i class="fa fa-thin fa-plus"></i>
|
||||||
|
{{ __('Submit contents') }}
|
||||||
|
</x-button>
|
||||||
|
@endif
|
||||||
|
@endauth
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
<div class="container p-4 mx-auto bg-21gray my-2">
|
||||||
|
|
||||||
|
<div class="pb-5 flex flex-row justify-between">
|
||||||
|
<h3 class="text-lg font-medium leading-6 text-gray-200">{{ __('Library Item') }}</h3>
|
||||||
|
<div class="flex flex-row space-x-2 items-center">
|
||||||
|
<div>
|
||||||
|
<x-button :href="$fromUrl">
|
||||||
|
<i class="fa fa-thin fa-arrow-left"></i>
|
||||||
|
{{ __('Back') }}
|
||||||
|
</x-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="space-y-8 divide-y divide-gray-700 pb-24">
|
||||||
|
<div class="space-y-8 divide-y divide-gray-700 sm:space-y-5">
|
||||||
|
<div class="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.lecturer_id')">
|
||||||
|
<x-slot name="label">
|
||||||
|
<div class="flex flex-row space-x-4 items-center">
|
||||||
|
<div>
|
||||||
|
{{ __('Author') }}
|
||||||
|
</div>
|
||||||
|
<div x-data="{currentUrl: window.location.href}">
|
||||||
|
<a x-bind:href="'/content-creator/form/?fromUrl='+currentUrl">
|
||||||
|
<x-button xs>
|
||||||
|
<i class="fa fa-thin fa-plus"></i>
|
||||||
|
{{ __('Create new author') }}
|
||||||
|
</x-button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-slot>
|
||||||
|
<x-select
|
||||||
|
:clearable="false"
|
||||||
|
wire:model="libraryItem.lecturer_id"
|
||||||
|
:searchable="true"
|
||||||
|
:async-data="[
|
||||||
|
'api' => route('api.lecturers.index'),
|
||||||
|
'method' => 'GET', // default is GET
|
||||||
|
]"
|
||||||
|
:template="[
|
||||||
|
'name' => 'user-option',
|
||||||
|
'config' => ['src' => 'image']
|
||||||
|
]"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.type')" label="{{ __('Type') }}">
|
||||||
|
<x-select
|
||||||
|
:clearable="false"
|
||||||
|
wire:model="libraryItem.type"
|
||||||
|
:options="$types"
|
||||||
|
option-label="label"
|
||||||
|
option-value="value"
|
||||||
|
/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('library')" label="{{ __('Library') }}">
|
||||||
|
<x-select
|
||||||
|
:disabled="$lecturer"
|
||||||
|
hint="{{ __('Please classify by type of your entry.') }}"
|
||||||
|
:clearable="false"
|
||||||
|
wire:model="library"
|
||||||
|
:options="$libraries"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
@if($libraryItem->lecturer_id && $libraryItem->type && $library)
|
||||||
|
<x-input.group :for=" md5('image')" :label="__('Main picture')">
|
||||||
|
<div class="py-4">
|
||||||
|
@if ($image)
|
||||||
|
<div class="text-gray-200">{{ __('Preview') }}:</div>
|
||||||
|
<img class="h-48 object-contain" src="{{ $image->temporaryUrl() }}">
|
||||||
|
@endif
|
||||||
|
@if ($libraryItem->getFirstMediaUrl('main'))
|
||||||
|
<div class="text-gray-200">{{ __('Current picture') }}:</div>
|
||||||
|
<img class="h-48 object-contain" src="{{ $libraryItem->getFirstMediaUrl('main') }}">
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<input class="text-gray-200" type="file" wire:model="image">
|
||||||
|
@error('image') <span class="text-red-500">{{ $message }}</span> @enderror
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.main_image_caption')" :label="__('Main image caption')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="libraryItem.main_image_caption"
|
||||||
|
:placeholder="__('Main image caption')"
|
||||||
|
:cornerHint="__('Ex: Photo by Timothy Vollmer/ CC BY')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.name')" :label="__('Title')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="libraryItem.name"
|
||||||
|
:placeholder="__('Title')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.subtitle')" :label="__('Subtitle')">
|
||||||
|
<x-input autocomplete="off" wire:model.debounce="libraryItem.subtitle"
|
||||||
|
:placeholder="__('Subtitle')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.excerpt')" :label="__('Excerpt')">
|
||||||
|
<x-textarea autocomplete="off" wire:model.debounce="libraryItem.excerpt"
|
||||||
|
:placeholder="__('Excerpt')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.language_code')" :label="__('Language Code')">
|
||||||
|
<x-select
|
||||||
|
placeholder="{{ __('Choose language') }}"
|
||||||
|
wire:model="libraryItem.language_code"
|
||||||
|
:clearable="false"
|
||||||
|
:searchable="true"
|
||||||
|
:async-data="route('api.languages.index')"
|
||||||
|
option-label="name"
|
||||||
|
option-value="language"
|
||||||
|
/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
@if($libraryItem->type === App\Enums\LibraryItemType::MarkdownArticleExtern())
|
||||||
|
<x-input.group :for="md5('libraryItem.value')" :label="__('Article as Markdown')">
|
||||||
|
<div
|
||||||
|
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</div>
|
||||||
|
<x-input.simple-mde wire:model.defer="libraryItem.value"/>
|
||||||
|
@error('libraryItem.value') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
|
||||||
|
</x-input.group>
|
||||||
|
@elseif($libraryItem->type !== App\Enums\LibraryItemType::DownloadableFile())
|
||||||
|
<x-input.group :for="md5('libraryItem.value')" :label="__('Link')">
|
||||||
|
<x-input type="url" autocomplete="off" wire:model.debounce="libraryItem.value"
|
||||||
|
:placeholder="__('Link')"/>
|
||||||
|
</x-input.group>
|
||||||
|
@elseif($libraryItem->type === App\Enums\LibraryItemType::DownloadableFile())
|
||||||
|
<x-input.group :for="md5('file')" :label="__('File')">
|
||||||
|
<input class="text-gray-200" type="file" wire:model="file">
|
||||||
|
@error('file') <span class="text-red-500">{{ $message }}</span> @enderror
|
||||||
|
</x-input.group>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<x-input.group :for="md5('libraryItem.read_time')" :label="__('Time to read')">
|
||||||
|
<x-inputs.number min="1" autocomplete="off" wire:model.debounce="libraryItem.read_time"
|
||||||
|
:placeholder="__('Time to read')" :hint="__('How many minutes to read?')"/>
|
||||||
|
</x-input.group>
|
||||||
|
|
||||||
|
<x-input.group :for="md5('meetupEvent.link')" label="">
|
||||||
|
<x-button primary wire:click="save">
|
||||||
|
<i class="fa fa-thin fa-save"></i>
|
||||||
|
{{ __('Save') }}
|
||||||
|
</x-button>
|
||||||
|
</x-input.group>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@@ -108,9 +108,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3">
|
<div class="ml-3">
|
||||||
<p class="text-sm font-medium text-gray-200">
|
<div class="text-sm font-medium text-gray-200">
|
||||||
<div class="text-gray-200">{{ $libraryItem->lecturer->name }}</div>
|
<div class="text-gray-200">{{ $libraryItem->lecturer->name }}</div>
|
||||||
</p>
|
</div>
|
||||||
<div class="flex space-x-1 text-sm text-gray-400">
|
<div class="flex space-x-1 text-sm text-gray-400">
|
||||||
<time
|
<time
|
||||||
datetime="2020-03-16">{{ $libraryItem->created_at->asDateTime() }}</time>
|
datetime="2020-03-16">{{ $libraryItem->created_at->asDateTime() }}</time>
|
||||||
@@ -119,14 +119,24 @@
|
|||||||
<span>{{ $libraryItem->read_time }} {{ __('min read') }}</span>
|
<span>{{ $libraryItem->read_time }} {{ __('min read') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex space-x-1 text-sm text-gray-500 justify-end items-end">
|
||||||
|
<div>
|
||||||
|
<x-button xs
|
||||||
|
:href="route('library.libraryItem.form', ['country' => $country, 'libraryItem' => $libraryItem])">
|
||||||
|
<i class="fa fa-thin fa-edit"></i>
|
||||||
|
{{ __('Edit') }}
|
||||||
|
</x-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<div
|
<div
|
||||||
x-data="{
|
x-data="{
|
||||||
observe () {
|
observe () {
|
||||||
let observer = new IntersectionObserver((entries) => {
|
let observer = new IntersectionObserver((entries) => {
|
||||||
entries.forEach(entry => {
|
entries.forEach(entry => {
|
||||||
@@ -140,8 +150,8 @@
|
|||||||
observer.observe(this.$el)
|
observer.observe(this.$el)
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
x-init="observe"
|
x-init="observe"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
@if($libraryItems->hasMorePages())
|
@if($libraryItems->hasMorePages())
|
||||||
<x-button outline wire:click.prevent="loadMore">{{ __('load more...') }}</x-button>
|
<x-button outline wire:click.prevent="loadMore">{{ __('load more...') }}</x-button>
|
||||||
|
|||||||
@@ -159,9 +159,10 @@
|
|||||||
id: 'attend-event',
|
id: 'attend-event',
|
||||||
icon: 'question',
|
icon: 'question',
|
||||||
accept: {label: '{{ __('Yes') }}',
|
accept: {label: '{{ __('Yes') }}',
|
||||||
execute: () => $wire.attend()},
|
execute: () => $wire.attend()},
|
||||||
reject: {label: '{{ __('No, cancel') }}',
|
reject: {label: '{{ __('No, cancel') }}',
|
||||||
execute: () => window.$wireui.notify({'title': '{{ __('You have not confirmed your participation.') }}','icon': 'warning'})}})"
|
execute: () => window.$wireui.notify({'title': '{{ __('You have not confirmed your participation.') }}','icon': 'warning'})}
|
||||||
|
})"
|
||||||
>
|
>
|
||||||
<i class="fa fa-thin fa-check mr-2"></i>
|
<i class="fa fa-thin fa-check mr-2"></i>
|
||||||
{{ __('I will show up') }}
|
{{ __('I will show up') }}
|
||||||
|
|||||||
@@ -93,8 +93,8 @@
|
|||||||
</x-input.group>
|
</x-input.group>
|
||||||
|
|
||||||
<x-input.group :for="md5('libraryItem.value')" :label="__('Article as Markdown')">
|
<x-input.group :for="md5('libraryItem.value')" :label="__('Article as Markdown')">
|
||||||
<span
|
<div
|
||||||
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</span>
|
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</div>
|
||||||
<x-input.simple-mde wire:model.defer="libraryItem.value"/>
|
<x-input.simple-mde wire:model.defer="libraryItem.value"/>
|
||||||
@error('libraryItem.value') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
|
@error('libraryItem.value') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
|
||||||
</x-input.group>
|
</x-input.group>
|
||||||
|
|||||||
@@ -49,15 +49,6 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(str(request()->route()->getName())->contains(['library.', 'article.']))
|
|
||||||
<div>
|
|
||||||
<x-button xs amber href="/nova/resources/library-items" target="_blank">
|
|
||||||
<i class="fa fa-thin fa-plus"></i>
|
|
||||||
{{ __('Submit contents') }}
|
|
||||||
</x-button>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if(str(request()->route()->getName())->contains('bitcoinEvent.'))
|
@if(str(request()->route()->getName())->contains('bitcoinEvent.'))
|
||||||
<div>
|
<div>
|
||||||
<x-button xs amber href="/nova/resources/bitcoin-events" target="_blank">
|
<x-button xs amber href="/nova/resources/bitcoin-events" target="_blank">
|
||||||
@@ -240,12 +231,6 @@
|
|||||||
</x-jet-responsive-nav-link>
|
</x-jet-responsive-nav-link>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(str(request()->route()->getName())->contains('library.'))
|
|
||||||
<x-jet-responsive-nav-link href="/nova/resources/library-items" :active="false">
|
|
||||||
{{ __('Submit contents') }}
|
|
||||||
</x-jet-responsive-nav-link>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if(str(request()->route()->getName())->contains('bitcoinEvent.'))
|
@if(str(request()->route()->getName())->contains('bitcoinEvent.'))
|
||||||
<x-jet-responsive-nav-link href="/nova/resources/bitcoin-events" :active="false">
|
<x-jet-responsive-nav-link href="/nova/resources/bitcoin-events" :active="false">
|
||||||
{{ __('Register event') }}
|
{{ __('Register event') }}
|
||||||
|
|||||||
@@ -36,6 +36,20 @@ Route::middleware([
|
|||||||
->name('form');
|
->name('form');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Content Creator
|
||||||
|
* */
|
||||||
|
Route::middleware([
|
||||||
|
'auth'
|
||||||
|
])
|
||||||
|
->as('contentCreator.')
|
||||||
|
->prefix('/content-creator')
|
||||||
|
->group(function () {
|
||||||
|
Route::get('/form/{lecturer?}', \App\Http\Livewire\ContentCreator\Form\ContentCreatorForm::class)
|
||||||
|
->name('form');
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cities
|
* Cities
|
||||||
* */
|
* */
|
||||||
@@ -131,6 +145,9 @@ Route::middleware([])
|
|||||||
->as('library.')
|
->as('library.')
|
||||||
->prefix('/{country:code}/library')
|
->prefix('/{country:code}/library')
|
||||||
->group(function () {
|
->group(function () {
|
||||||
|
Route::get('/library-item/form/{libraryItem?}', \App\Http\Livewire\Library\Form\LibraryItemForm::class)
|
||||||
|
->name('libraryItem.form')->middleware(['auth']);
|
||||||
|
|
||||||
Route::get('/library-item', \App\Http\Livewire\Library\LibraryTable::class)
|
Route::get('/library-item', \App\Http\Livewire\Library\LibraryTable::class)
|
||||||
->name('table.libraryItems');
|
->name('table.libraryItems');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user