is_active = ! $feed->is_active; $feed->save(); } public function openCreateModal(): void { $this->reset(['newName', 'newProvider', 'newLanguageId', 'newDescription']); $this->resetErrorBag(); $this->showCreateModal = true; } public function closeCreateModal(): void { $this->showCreateModal = false; } public function createFeed(CreateFeedAction $action): void { $providers = array_keys($this->activeProviders()); $this->validate([ 'newName' => 'required|string|max:255', 'newProvider' => ['required', 'string', 'in:'.implode(',', $providers)], 'newLanguageId' => 'required|integer|exists:languages,id', ]); try { $action->execute( $this->newName, $this->newProvider, $this->newLanguageId, // Blade textarea binds an empty string when blank; the action expects null for "no description". $this->newDescription !== '' ? $this->newDescription : null, ); } catch (InvalidArgumentException $e) { $this->addError('newProvider', 'This provider is not available for the selected language.'); return; } $this->closeCreateModal(); } public function openEditModal(int $feedId): void { $feed = Feed::findOrFail($feedId); $this->resetErrorBag(); $this->editingFeedId = $feedId; $this->editName = $feed->name; $this->editDescription = $feed->description ?? ''; } public function closeEditModal(): void { $this->editingFeedId = null; } // Provider and language are deliberately not editable: CreateFeedAction derives the unique // feeds.url from that pair, so changing either re-points the feed and orphans its articles. public function updateFeed(): void { if ($this->editingFeedId === null) { return; } $this->validate([ 'editName' => 'required|string|max:255', ]); Feed::findOrFail($this->editingFeedId)->update([ 'name' => $this->editName, 'description' => $this->editDescription !== '' ? $this->editDescription : null, ]); $this->closeEditModal(); } /** * @return array> */ private function activeProviders(): array { /** @var array> $providers */ $providers = config('feed.providers', []); return array_filter($providers, fn (array $provider): bool => ($provider['is_active'] ?? false) === true); } public function render(): View { $feeds = Feed::orderBy('name')->get(); return view('livewire.feeds', [ 'feeds' => $feeds, 'providers' => $this->activeProviders(), 'languages' => Language::where('is_active', true)->orderBy('name')->get(), 'editingFeed' => $this->editingFeedId !== null ? Feed::with('language')->find($this->editingFeedId) : null, ])->layout('layouts.app'); } }