220 lines
6.3 KiB
PHP
220 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use App\Models\Feed;
|
|
use App\Models\Keyword;
|
|
use App\Models\PlatformChannel;
|
|
use App\Models\Route;
|
|
use Illuminate\Contracts\View\View;
|
|
use Livewire\Component;
|
|
|
|
class Routes extends Component
|
|
{
|
|
public bool $showCreateModal = false;
|
|
|
|
public ?int $editingFeedId = null;
|
|
|
|
public ?int $editingChannelId = null;
|
|
|
|
// Create form
|
|
public ?int $newFeedId = null;
|
|
|
|
public ?int $newChannelId = null;
|
|
|
|
public int $newPriority = 50;
|
|
|
|
// Edit form
|
|
public int $editPriority = 50;
|
|
|
|
public string $editAutoApprove = '';
|
|
|
|
// Keyword management
|
|
public string $newKeyword = '';
|
|
|
|
public bool $showKeywordInput = false;
|
|
|
|
public function openCreateModal(): void
|
|
{
|
|
$this->showCreateModal = true;
|
|
$this->newFeedId = null;
|
|
$this->newChannelId = null;
|
|
$this->newPriority = 50;
|
|
}
|
|
|
|
public function closeCreateModal(): void
|
|
{
|
|
$this->showCreateModal = false;
|
|
}
|
|
|
|
public function createRoute(): void
|
|
{
|
|
$this->validate([
|
|
'newFeedId' => 'required|exists:feeds,id',
|
|
'newChannelId' => 'required|exists:platform_channels,id',
|
|
'newPriority' => 'required|integer|min:0',
|
|
]);
|
|
|
|
$exists = Route::where('feed_id', $this->newFeedId)
|
|
->where('platform_channel_id', $this->newChannelId)
|
|
->exists();
|
|
|
|
if ($exists) {
|
|
$this->addError('newFeedId', 'This route already exists.');
|
|
|
|
return;
|
|
}
|
|
|
|
Route::create([
|
|
'feed_id' => $this->newFeedId,
|
|
'platform_channel_id' => $this->newChannelId,
|
|
'priority' => $this->newPriority,
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->closeCreateModal();
|
|
}
|
|
|
|
public function openEditModal(int $feedId, int $channelId): void
|
|
{
|
|
$route = Route::where('feed_id', $feedId)
|
|
->where('platform_channel_id', $channelId)
|
|
->firstOrFail();
|
|
|
|
$this->editingFeedId = $feedId;
|
|
$this->editingChannelId = $channelId;
|
|
$this->editPriority = $route->priority;
|
|
$this->editAutoApprove = $route->auto_approve === null ? '' : ($route->auto_approve ? '1' : '0');
|
|
$this->newKeyword = '';
|
|
$this->showKeywordInput = false;
|
|
}
|
|
|
|
public function closeEditModal(): void
|
|
{
|
|
$this->editingFeedId = null;
|
|
$this->editingChannelId = null;
|
|
}
|
|
|
|
public function updateRoute(): void
|
|
{
|
|
if (! $this->editingFeedId || ! $this->editingChannelId) {
|
|
return;
|
|
}
|
|
|
|
$this->validate([
|
|
'editPriority' => 'required|integer|min:0',
|
|
]);
|
|
|
|
$autoApprove = match ($this->editAutoApprove) {
|
|
'1' => true,
|
|
'0' => false,
|
|
default => null,
|
|
};
|
|
|
|
Route::where('feed_id', $this->editingFeedId)
|
|
->where('platform_channel_id', $this->editingChannelId)
|
|
->update([
|
|
'priority' => $this->editPriority,
|
|
'auto_approve' => $autoApprove,
|
|
]);
|
|
|
|
$this->closeEditModal();
|
|
}
|
|
|
|
public function toggle(int $feedId, int $channelId): void
|
|
{
|
|
$route = Route::where('feed_id', $feedId)
|
|
->where('platform_channel_id', $channelId)
|
|
->firstOrFail();
|
|
|
|
$route->is_active = ! $route->is_active;
|
|
$route->save();
|
|
}
|
|
|
|
public function delete(int $feedId, int $channelId): void
|
|
{
|
|
// Delete associated keywords first
|
|
Keyword::where('feed_id', $feedId)
|
|
->where('platform_channel_id', $channelId)
|
|
->delete();
|
|
|
|
Route::where('feed_id', $feedId)
|
|
->where('platform_channel_id', $channelId)
|
|
->delete();
|
|
}
|
|
|
|
public function addKeyword(): void
|
|
{
|
|
if (! $this->editingFeedId || ! $this->editingChannelId || empty(trim($this->newKeyword))) {
|
|
return;
|
|
}
|
|
|
|
Keyword::create([
|
|
'feed_id' => $this->editingFeedId,
|
|
'platform_channel_id' => $this->editingChannelId,
|
|
'keyword' => trim($this->newKeyword),
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->newKeyword = '';
|
|
$this->showKeywordInput = false;
|
|
}
|
|
|
|
public function toggleKeyword(int $keywordId): void
|
|
{
|
|
$keyword = Keyword::findOrFail($keywordId);
|
|
$keyword->is_active = ! $keyword->is_active;
|
|
$keyword->save();
|
|
}
|
|
|
|
public function deleteKeyword(int $keywordId): void
|
|
{
|
|
Keyword::destroy($keywordId);
|
|
}
|
|
|
|
public function render(): View
|
|
{
|
|
$routes = Route::with(['feed', 'platformChannel.platformInstance'])
|
|
->orderBy('priority', 'desc')
|
|
->get();
|
|
|
|
// Batch load keywords for all routes to avoid N+1 queries
|
|
$routeKeys = $routes->map(fn ($r) => $r->feed_id.'-'.$r->platform_channel_id);
|
|
$allKeywords = Keyword::whereIn('feed_id', $routes->pluck('feed_id'))
|
|
->whereIn('platform_channel_id', $routes->pluck('platform_channel_id'))
|
|
->get()
|
|
->groupBy(fn ($k) => $k->feed_id.'-'.$k->platform_channel_id);
|
|
|
|
$routes = $routes->map(function ($route) use ($allKeywords) {
|
|
$key = $route->feed_id.'-'.$route->platform_channel_id;
|
|
$route->setRelation('keywords', $allKeywords->get($key, collect()));
|
|
|
|
return $route;
|
|
});
|
|
|
|
$feeds = Feed::where('is_active', true)->orderBy('name')->get();
|
|
$channels = PlatformChannel::where('is_active', true)->orderBy('name')->get();
|
|
|
|
$editingRoute = null;
|
|
$editingKeywords = collect();
|
|
|
|
if ($this->editingFeedId && $this->editingChannelId) {
|
|
$editingRoute = Route::with(['feed', 'platformChannel.platformInstance'])
|
|
->where('feed_id', $this->editingFeedId)
|
|
->where('platform_channel_id', $this->editingChannelId)
|
|
->first();
|
|
|
|
$editingKeywords = Keyword::where('feed_id', $this->editingFeedId)
|
|
->where('platform_channel_id', $this->editingChannelId)
|
|
->get();
|
|
}
|
|
|
|
return view('livewire.routes', [
|
|
'routes' => $routes,
|
|
'feeds' => $feeds,
|
|
'channels' => $channels,
|
|
'editingRoute' => $editingRoute,
|
|
'editingKeywords' => $editingKeywords,
|
|
])->layout('layouts.app');
|
|
}
|
|
}
|