Files
SkinbaseNova/app/Services/Studio/CreatorStudioSearchService.php

154 lines
6.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Studio;
use App\Models\User;
final class CreatorStudioSearchService
{
public function __construct(
private readonly CreatorStudioContentService $content,
private readonly CreatorStudioCommentService $comments,
private readonly CreatorStudioActivityService $activity,
private readonly CreatorStudioAssetService $assets,
) {
}
public function build(User $user, array $filters = []): array
{
$query = trim((string) ($filters['q'] ?? ''));
$module = $this->normalizeModule((string) ($filters['module'] ?? 'all'));
$type = $this->normalizeType((string) ($filters['type'] ?? 'all'));
if ($query === '') {
return [
'filters' => ['q' => '', 'module' => $module, 'type' => $type],
'sections' => [],
'summary' => [
'total' => 0,
'query' => '',
],
'empty_state' => [
'continue_working' => $this->content->continueWorking($user, 'resume-last', 5),
'stale_drafts' => $this->content->staleDrafts($user, 5),
'scheduled' => $this->content->providers() ? collect($this->content->providers())->flatMap(fn ($provider) => $provider->scheduledItems($user, 3))->take(5)->values()->all() : [],
],
];
}
$sections = collect();
if (in_array($type, ['all', 'content'], true)) {
$content = $this->content->list($user, ['module' => $module, 'q' => $query, 'per_page' => 12]);
$sections->push([
'key' => 'content',
'label' => 'Content',
'count' => count($content['items']),
'items' => collect($content['items'])->map(fn (array $item): array => [
'id' => $item['id'],
'title' => $item['title'],
'subtitle' => $item['module_label'] . ' · ' . ($item['status'] ?? 'draft'),
'description' => $item['description'],
'href' => $item['edit_url'] ?? $item['manage_url'] ?? $item['view_url'],
'icon' => $item['module_icon'] ?? 'fa-solid fa-table-cells-large',
'module' => $item['module'],
'kind' => 'content',
])->all(),
]);
}
if (in_array($type, ['all', 'comments'], true)) {
$comments = $this->comments->list($user, ['module' => $module, 'q' => $query, 'per_page' => 8]);
$sections->push([
'key' => 'comments',
'label' => 'Comments',
'count' => count($comments['items']),
'items' => collect($comments['items'])->map(fn (array $item): array => [
'id' => $item['id'],
'title' => $item['author_name'] . ' on ' . ($item['item_title'] ?? 'Untitled'),
'subtitle' => $item['module_label'],
'description' => $item['body'],
'href' => $item['context_url'],
'icon' => 'fa-solid fa-comments',
'module' => $item['module'],
'kind' => 'comment',
])->all(),
]);
}
if (in_array($type, ['all', 'inbox'], true)) {
$activity = $this->activity->list($user, ['module' => $module, 'q' => $query, 'per_page' => 8]);
$sections->push([
'key' => 'inbox',
'label' => 'Inbox',
'count' => count($activity['items']),
'items' => collect($activity['items'])->map(fn (array $item): array => [
'id' => $item['id'],
'title' => $item['title'],
'subtitle' => $item['module_label'],
'description' => $item['body'],
'href' => $item['url'],
'icon' => 'fa-solid fa-bell',
'module' => $item['module'],
'kind' => 'inbox',
])->all(),
]);
}
if (in_array($type, ['all', 'assets'], true)) {
$assets = $this->assets->library($user, ['q' => $query, 'per_page' => 8]);
$sections->push([
'key' => 'assets',
'label' => 'Assets',
'count' => count($assets['items']),
'items' => collect($assets['items'])->map(fn (array $item): array => [
'id' => $item['id'],
'title' => $item['title'],
'subtitle' => $item['type_label'],
'description' => $item['description'],
'href' => $item['manage_url'] ?? $item['view_url'],
'icon' => 'fa-solid fa-photo-film',
'module' => $item['source_key'] ?? 'assets',
'kind' => 'asset',
])->all(),
]);
}
$sections = $sections->filter(fn (array $section): bool => $section['count'] > 0)->values();
return [
'filters' => ['q' => $query, 'module' => $module, 'type' => $type],
'sections' => $sections->all(),
'summary' => [
'total' => $sections->sum('count'),
'query' => $query,
],
'type_options' => [
['value' => 'all', 'label' => 'Everywhere'],
['value' => 'content', 'label' => 'Content'],
['value' => 'comments', 'label' => 'Comments'],
['value' => 'inbox', 'label' => 'Inbox'],
['value' => 'assets', 'label' => 'Assets'],
],
'module_options' => [
['value' => 'all', 'label' => 'All modules'],
['value' => 'artworks', 'label' => 'Artworks'],
['value' => 'cards', 'label' => 'Cards'],
['value' => 'collections', 'label' => 'Collections'],
['value' => 'stories', 'label' => 'Stories'],
],
];
}
private function normalizeModule(string $value): string
{
return in_array($value, ['all', 'artworks', 'cards', 'collections', 'stories'], true) ? $value : 'all';
}
private function normalizeType(string $value): string
{
return in_array($value, ['all', 'content', 'comments', 'inbox', 'assets'], true) ? $value : 'all';
}
}