diff --git a/app/Http/Controllers/Api/VenueController.php b/app/Http/Controllers/Api/VenueController.php new file mode 100644 index 00000000..72cb720f --- /dev/null +++ b/app/Http/Controllers/Api/VenueController.php @@ -0,0 +1,77 @@ +with(['city:id,name,country_id', 'city.country:id,name,code']) + ->select('id', 'name', 'city_id') + ->orderBy('name') + ->when( + $request->search, + fn(Builder $query) => $query + ->where('name', 'ilike', "%{$request->search}%") + ) + ->when( + $request->exists('selected'), + fn(Builder $query) => $query->whereIn('id', + $request->input('selected', [])), + fn(Builder $query) => $query->limit(10) + ) + ->get() + ->map(function (Venue $venue) { + $venue->flag = asset('vendor/blade-country-flags/4x3-'.$venue->city->country->code.'.svg'); + + return $venue; + }); + } + + /** + * Store a newly created resource in storage. + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + * @return \Illuminate\Http\Response + */ + public function show(Lecturer $lecturer) + { + // + } + + /** + * Update the specified resource in storage. + * @return \Illuminate\Http\Response + */ + public function update(Request $request, Lecturer $lecturer) + { + // + } + + /** + * Remove the specified resource from storage. + * @return \Illuminate\Http\Response + */ + public function destroy(Lecturer $lecturer) + { + // + } +} diff --git a/app/Http/Livewire/BitcoinEvent/Form/BitcoinEventForm.php b/app/Http/Livewire/BitcoinEvent/Form/BitcoinEventForm.php new file mode 100644 index 00000000..e3b06237 --- /dev/null +++ b/app/Http/Livewire/BitcoinEvent/Form/BitcoinEventForm.php @@ -0,0 +1,82 @@ + [ + 'except' => null, + ], + ]; + + public function rules() + { + return [ + 'image' => [Rule::requiredIf(!$this->bitcoinEvent->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'], + + 'bitcoinEvent.venue_id' => 'required', + 'bitcoinEvent.from' => 'required', + 'bitcoinEvent.to' => 'required', + 'bitcoinEvent.title' => 'required', + 'bitcoinEvent.description' => 'required', + 'bitcoinEvent.link' => 'required|url', + 'bitcoinEvent.show_worldwide' => 'bool', + ]; + } + + public function mount() + { + if (!$this->bitcoinEvent) { + $this->bitcoinEvent = new BitcoinEvent( + [ + 'description' => '', + 'show_worldwide' => true, + ] + ); + } elseif (!auth() + ->user() + ->can('update', $this->bitcoinEvent)) { + abort(403); + } + + if (!$this->fromUrl) { + $this->fromUrl = url()->previous(); + } + } + + public function submit() + { + $this->validate(); + $this->bitcoinEvent->save(); + + if ($this->image) { + $this->bitcoinEvent->addMedia($this->image) + ->toMediaCollection('logo'); + } + + return redirect($this->fromUrl); + } + + public function render() + { + return view('livewire.bitcoin-event.form.bitcoin-event-form'); + } +} diff --git a/app/Http/Livewire/Library/Form/LibraryItemForm.php b/app/Http/Livewire/Library/Form/LibraryItemForm.php index a9e46cea..9e153fb1 100644 --- a/app/Http/Livewire/Library/Form/LibraryItemForm.php +++ b/app/Http/Livewire/Library/Form/LibraryItemForm.php @@ -33,24 +33,24 @@ class LibraryItemForm extends Component public ?string $fromUrl = ''; protected $queryString = [ - 'fromUrl' => ['except' => ''], + 'fromUrl' => ['except' => ''], 'lecturer' => ['except' => false], ]; public function rules() { return [ - 'image' => [Rule::requiredIf(! $this->libraryItem->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'], + 'image' => [Rule::requiredIf(!$this->libraryItem->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'], 'library' => 'required', 'selectedTags' => 'array|min:1', - 'libraryItem.lecturer_id' => 'required', - 'libraryItem.name' => 'required', - 'libraryItem.type' => 'required', - 'libraryItem.language_code' => 'required', - 'libraryItem.value' => [ + 'libraryItem.lecturer_id' => 'required', + 'libraryItem.name' => 'required', + 'libraryItem.type' => 'required', + 'libraryItem.language_code' => 'required', + 'libraryItem.value' => [ 'required', Rule::when( $this->libraryItem->type !== LibraryItemType::MarkdownArticle @@ -58,19 +58,19 @@ class LibraryItemForm extends Component && $this->libraryItem->type !== LibraryItemType::DownloadableFile, ['url'] ), ], - 'libraryItem.subtitle' => 'required', - 'libraryItem.excerpt' => 'required', + 'libraryItem.subtitle' => 'required', + 'libraryItem.excerpt' => 'required', 'libraryItem.main_image_caption' => 'required', - 'libraryItem.read_time' => 'required', - 'libraryItem.approved' => 'boolean', + 'libraryItem.read_time' => 'required', + 'libraryItem.approved' => 'boolean', ]; } public function mount() { - if (! $this->libraryItem) { + if (!$this->libraryItem) { $this->libraryItem = new LibraryItem([ - 'approved' => true, + 'approved' => true, 'read_time' => 1, ]); if ($this->lecturer) { @@ -81,13 +81,13 @@ class LibraryItemForm extends Component $this->selectedTags = $this->libraryItem->tags() ->where('type', 'library_item') ->get() - ->map(fn ($tag) => $tag->name) + ->map(fn($tag) => $tag->name) ->toArray(); $this->library = $this->libraryItem->libraries() ->first() ->id; } - if (! $this->fromUrl) { + if (!$this->fromUrl) { $this->fromUrl = url()->previous(); } } @@ -123,7 +123,7 @@ class LibraryItemForm extends Component { $selectedTags = collect($this->selectedTags); if ($selectedTags->contains($name)) { - $selectedTags = $selectedTags->filter(fn ($tag) => $tag !== $name); + $selectedTags = $selectedTags->filter(fn($tag) => $tag !== $name); } else { $selectedTags->push($name); } @@ -134,21 +134,21 @@ class LibraryItemForm extends Component public function render() { return view('livewire.library.form.library-item-form', [ - 'types' => Options::forEnum(LibraryItemType::class) + 'types' => Options::forEnum(LibraryItemType::class) ->filter( - fn ($type) => $type !== LibraryItemType::PodcastEpisode + fn($type) => $type !== LibraryItemType::PodcastEpisode && $type !== LibraryItemType::MarkdownArticle ) ->toArray(), 'libraries' => Library::query() ->where('is_public', true) ->get() - ->map(fn ($library) => [ - 'id' => $library->id, + ->map(fn($library) => [ + 'id' => $library->id, 'name' => $library->name, ]) ->toArray(), - 'tags' => Tag::query() + 'tags' => Tag::query() ->where('type', 'library_item') ->get(), ]); diff --git a/app/Http/Livewire/Tables/BitcoinEventTable.php b/app/Http/Livewire/Tables/BitcoinEventTable.php index da99fd25..cd636af9 100644 --- a/app/Http/Livewire/Tables/BitcoinEventTable.php +++ b/app/Http/Livewire/Tables/BitcoinEventTable.php @@ -35,7 +35,14 @@ class BitcoinEventTable extends DataTableComponent ]; }) ->setColumnSelectStatus(false) - ->setPerPage(10); + ->setPerPage(10) + ->setConfigurableAreas([ + 'toolbar-left-end' => [ + 'columns.bitcoin_events.areas.toolbar-left-end', [ + 'country' => $this->country, + ], + ], + ]); } public function filters(): array diff --git a/app/Http/Livewire/Venue/Form/VenueForm.php b/app/Http/Livewire/Venue/Form/VenueForm.php new file mode 100644 index 00000000..1d8b7397 --- /dev/null +++ b/app/Http/Livewire/Venue/Form/VenueForm.php @@ -0,0 +1,71 @@ + ['except' => '']]; + + public function rules() + { + return [ + 'images.*' => [Rule::requiredIf(!$this->venue->id), 'nullable', 'mimes:jpeg,png,jpg,gif', 'max:10240'], + + 'venue.city_id' => 'required', + 'venue.name' => 'required', + 'venue.street' => 'required', + ]; + } + + public function mount() + { + if (!$this->venue) { + $this->venue = new Venue(); + } elseif (!auth() + ->user() + ->can('update', $this->venue)) { + abort(403); + } + + if (!$this->fromUrl) { + $this->fromUrl = url()->previous(); + } + } + + public function submit() + { + $this->validate(); + $this->venue->save(); + + if (count($this->images) > 0) { + foreach ($this->images as $item) { + $this->venue->addMedia($item) + ->toMediaCollection('images'); + } + } + + return redirect($this->fromUrl); + } + + public function render() + { + return view('livewire.venue.form.venue-form'); + } +} diff --git a/app/Traits/NostrTrait.php b/app/Traits/NostrTrait.php index 149a6b4e..b1377d36 100644 --- a/app/Traits/NostrTrait.php +++ b/app/Traits/NostrTrait.php @@ -15,6 +15,15 @@ trait NostrTrait { public function publishOnNostr($model, $text): array { + if (app()->environment('local')) { + return [ + 'success' => true, + 'output' => 'local', + 'exitCode' => 0, + 'errorOutput' => '' + ]; + } + //noscl publish "Good morning!" $result = Process::timeout(60 * 5) ->run('noscl publish "'.$text.'"'); diff --git a/resources/views/columns/bitcoin_events/areas/toolbar-left-end.blade.php b/resources/views/columns/bitcoin_events/areas/toolbar-left-end.blade.php new file mode 100644 index 00000000..d406affa --- /dev/null +++ b/resources/views/columns/bitcoin_events/areas/toolbar-left-end.blade.php @@ -0,0 +1,6 @@ +