546 lines
26 KiB
PHP
546 lines
26 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Settings;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\NovaCards\AdminStoreNovaCardAssetPackRequest;
|
|
use App\Http\Requests\NovaCards\AdminStoreNovaCardCategoryRequest;
|
|
use App\Http\Requests\NovaCards\AdminStoreNovaCardChallengeRequest;
|
|
use App\Http\Requests\NovaCards\AdminStoreNovaCardTemplateRequest;
|
|
use App\Http\Requests\NovaCards\AdminUpdateNovaCardRequest;
|
|
use App\Models\NovaCardAssetPack;
|
|
use App\Models\NovaCard;
|
|
use App\Models\NovaCardCategory;
|
|
use App\Models\NovaCardChallenge;
|
|
use App\Models\NovaCardCollection;
|
|
use App\Models\Report;
|
|
use App\Models\NovaCardTemplate;
|
|
use App\Models\User;
|
|
use App\Services\NovaCards\NovaCardCollectionService;
|
|
use App\Services\NovaCards\NovaCardPublishModerationService;
|
|
use App\Services\NovaCards\NovaCardPresenter;
|
|
use App\Support\Moderation\ReportTargetResolver;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class NovaCardAdminController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly NovaCardPresenter $presenter,
|
|
private readonly ReportTargetResolver $reportTargets,
|
|
private readonly NovaCardCollectionService $collections,
|
|
private readonly NovaCardPublishModerationService $moderation,
|
|
) {}
|
|
|
|
public function index(Request $request): Response
|
|
{
|
|
$cards = NovaCard::query()
|
|
->with(['user.profile', 'category', 'template', 'backgroundImage', 'tags'])
|
|
->latest('updated_at')
|
|
->paginate(24)
|
|
->withQueryString();
|
|
$featuredCreators = User::query()
|
|
->whereHas('novaCards', fn ($query) => $query->publiclyVisible())
|
|
->withCount([
|
|
'novaCards as public_cards_count' => fn ($query) => $query->publiclyVisible(),
|
|
'novaCards as featured_cards_count' => fn ($query) => $query->publiclyVisible()->where('featured', true),
|
|
])
|
|
->withSum([
|
|
'novaCards as total_views_count' => fn ($query) => $query->publiclyVisible(),
|
|
], 'views_count')
|
|
->orderByDesc('nova_featured_creator')
|
|
->orderByDesc('featured_cards_count')
|
|
->orderByDesc('public_cards_count')
|
|
->orderBy('username')
|
|
->limit(8)
|
|
->get();
|
|
|
|
$reportCounts = Report::query()
|
|
->selectRaw('status, COUNT(*) as aggregate')
|
|
->whereIn('target_type', $this->reportTargets->novaCardTargetTypes())
|
|
->groupBy('status')
|
|
->pluck('aggregate', 'status');
|
|
|
|
return Inertia::render('Collection/NovaCardsAdminIndex', [
|
|
'cards' => $this->presenter->paginator($cards, false, $request->user()),
|
|
'featuredCreators' => $featuredCreators->map(fn (User $creator): array => [
|
|
'id' => (int) $creator->id,
|
|
'username' => (string) $creator->username,
|
|
'name' => $creator->name,
|
|
'display_name' => $creator->name ?: '@' . $creator->username,
|
|
'public_url' => route('cards.creator', ['username' => $creator->username]),
|
|
'nova_featured_creator' => (bool) $creator->nova_featured_creator,
|
|
'public_cards_count' => (int) ($creator->public_cards_count ?? 0),
|
|
'featured_cards_count' => (int) ($creator->featured_cards_count ?? 0),
|
|
'total_views_count' => (int) ($creator->total_views_count ?? 0),
|
|
])->values()->all(),
|
|
'categories' => NovaCardCategory::query()->orderBy('order_num')->orderBy('name')->get()->map(fn (NovaCardCategory $category): array => [
|
|
'id' => (int) $category->id,
|
|
'slug' => (string) $category->slug,
|
|
'name' => (string) $category->name,
|
|
'description' => $category->description,
|
|
'active' => (bool) $category->active,
|
|
'order_num' => (int) $category->order_num,
|
|
'cards_count' => (int) $category->cards()->count(),
|
|
])->values()->all(),
|
|
'stats' => [
|
|
'pending' => NovaCard::query()->where('moderation_status', NovaCard::MOD_PENDING)->count(),
|
|
'flagged' => NovaCard::query()->where('moderation_status', NovaCard::MOD_FLAGGED)->count(),
|
|
'featured' => NovaCard::query()->where('featured', true)->count(),
|
|
'published' => NovaCard::query()->where('status', NovaCard::STATUS_PUBLISHED)->count(),
|
|
'remixable' => NovaCard::query()->where('allow_remix', true)->count(),
|
|
'challenges' => NovaCardChallenge::query()->count(),
|
|
],
|
|
'reportingQueue' => [
|
|
'enabled' => true,
|
|
'pending' => (int) ($reportCounts['open'] ?? 0),
|
|
'label' => 'Nova Cards report queue',
|
|
'description' => 'Review open, investigating, and resolved reports for cards, challenge prompts, and challenge entries.',
|
|
'statuses' => [
|
|
'open' => (int) ($reportCounts['open'] ?? 0),
|
|
'reviewing' => (int) ($reportCounts['reviewing'] ?? 0),
|
|
'closed' => (int) ($reportCounts['closed'] ?? 0),
|
|
],
|
|
],
|
|
'endpoints' => [
|
|
'updateCardPattern' => route('cp.cards.update', ['card' => '__CARD__']),
|
|
'updateCreatorPattern' => route('cp.cards.creators.update', ['user' => '__CREATOR__']),
|
|
'templates' => route('cp.cards.templates.index'),
|
|
'assetPacks' => route('cp.cards.asset-packs.index'),
|
|
'challenges' => route('cp.cards.challenges.index'),
|
|
'collections' => route('cp.cards.collections.index'),
|
|
'storeCategory' => route('cp.cards.categories.store'),
|
|
'updateCategoryPattern' => route('cp.cards.categories.update', ['category' => '__CATEGORY__']),
|
|
'reportsQueue' => route('api.admin.reports.queue', ['group' => 'nova_cards']),
|
|
'updateReportPattern' => route('api.admin.reports.update', ['report' => '__REPORT__']),
|
|
'moderateReportTargetPattern' => route('api.admin.reports.moderate-target', ['report' => '__REPORT__']),
|
|
],
|
|
'moderationDispositionOptions' => [
|
|
NovaCard::MOD_PENDING => $this->moderation->dispositionOptions(NovaCard::MOD_PENDING),
|
|
NovaCard::MOD_APPROVED => $this->moderation->dispositionOptions(NovaCard::MOD_APPROVED),
|
|
NovaCard::MOD_FLAGGED => $this->moderation->dispositionOptions(NovaCard::MOD_FLAGGED),
|
|
NovaCard::MOD_REJECTED => $this->moderation->dispositionOptions(NovaCard::MOD_REJECTED),
|
|
],
|
|
'editorOptions' => $this->presenter->options(),
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function templates(Request $request): Response
|
|
{
|
|
return Inertia::render('Collection/NovaCardsTemplateAdmin', [
|
|
'templates' => NovaCardTemplate::query()->orderBy('order_num')->orderBy('name')->get()->map(fn (NovaCardTemplate $template): array => [
|
|
'id' => (int) $template->id,
|
|
'slug' => (string) $template->slug,
|
|
'name' => (string) $template->name,
|
|
'description' => $template->description,
|
|
'preview_image' => $template->preview_image,
|
|
'config_json' => $template->config_json,
|
|
'supported_formats' => $template->supported_formats,
|
|
'active' => (bool) $template->active,
|
|
'official' => (bool) $template->official,
|
|
'order_num' => (int) $template->order_num,
|
|
])->values()->all(),
|
|
'editorOptions' => $this->presenter->options(),
|
|
'endpoints' => [
|
|
'store' => route('cp.cards.templates.store'),
|
|
'updatePattern' => route('cp.cards.templates.update', ['template' => '__TEMPLATE__']),
|
|
'cards' => route('cp.cards.index'),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function assetPacks(Request $request): Response
|
|
{
|
|
return Inertia::render('Collection/NovaCardsAssetPackAdmin', [
|
|
'packs' => NovaCardAssetPack::query()->orderBy('type')->orderBy('order_num')->orderBy('name')->get()->map(fn (NovaCardAssetPack $pack): array => [
|
|
'id' => (int) $pack->id,
|
|
'slug' => (string) $pack->slug,
|
|
'name' => (string) $pack->name,
|
|
'description' => $pack->description,
|
|
'type' => (string) $pack->type,
|
|
'preview_image' => $pack->preview_image,
|
|
'manifest_json' => $pack->manifest_json,
|
|
'official' => (bool) $pack->official,
|
|
'active' => (bool) $pack->active,
|
|
'order_num' => (int) $pack->order_num,
|
|
])->values()->all(),
|
|
'endpoints' => [
|
|
'store' => route('cp.cards.asset-packs.store'),
|
|
'updatePattern' => route('cp.cards.asset-packs.update', ['assetPack' => '__PACK__']),
|
|
'cards' => route('cp.cards.index'),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function challenges(Request $request): Response
|
|
{
|
|
return Inertia::render('Collection/NovaCardsChallengeAdmin', [
|
|
'challenges' => NovaCardChallenge::query()->with('winnerCard')->orderByDesc('featured')->orderByDesc('starts_at')->get()->map(fn (NovaCardChallenge $challenge): array => [
|
|
'id' => (int) $challenge->id,
|
|
'slug' => (string) $challenge->slug,
|
|
'title' => (string) $challenge->title,
|
|
'description' => $challenge->description,
|
|
'prompt' => $challenge->prompt,
|
|
'rules_json' => $challenge->rules_json,
|
|
'status' => (string) $challenge->status,
|
|
'official' => (bool) $challenge->official,
|
|
'featured' => (bool) $challenge->featured,
|
|
'winner_card_id' => $challenge->winner_card_id ? (int) $challenge->winner_card_id : null,
|
|
'entries_count' => (int) $challenge->entries_count,
|
|
'starts_at' => optional($challenge->starts_at)?->format('Y-m-d\TH:i'),
|
|
'ends_at' => optional($challenge->ends_at)?->format('Y-m-d\TH:i'),
|
|
])->values()->all(),
|
|
'cards' => NovaCard::query()->published()->latest('published_at')->limit(100)->get()->map(fn (NovaCard $card): array => [
|
|
'id' => (int) $card->id,
|
|
'title' => (string) $card->title,
|
|
])->values()->all(),
|
|
'endpoints' => [
|
|
'store' => route('cp.cards.challenges.store'),
|
|
'updatePattern' => route('cp.cards.challenges.update', ['challenge' => '__CHALLENGE__']),
|
|
'cards' => route('cp.cards.index'),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function collections(Request $request): Response
|
|
{
|
|
return Inertia::render('Collection/NovaCardsCollectionAdmin', [
|
|
'collections' => NovaCardCollection::query()
|
|
->with(['user', 'items.card.user.profile', 'items.card.category', 'items.card.template', 'items.card.backgroundImage', 'items.card.tags'])
|
|
->orderByDesc('featured')
|
|
->orderByDesc('official')
|
|
->orderByDesc('updated_at')
|
|
->get()
|
|
->map(fn (NovaCardCollection $collection): array => $this->presenter->collection($collection, $request->user(), true))
|
|
->values()
|
|
->all(),
|
|
'cards' => NovaCard::query()
|
|
->published()
|
|
->latest('published_at')
|
|
->limit(200)
|
|
->get()
|
|
->map(fn (NovaCard $card): array => [
|
|
'id' => (int) $card->id,
|
|
'title' => (string) $card->title,
|
|
'slug' => (string) $card->slug,
|
|
'creator' => $card->user?->username,
|
|
])
|
|
->values()
|
|
->all(),
|
|
'admins' => \App\Models\User::query()
|
|
->whereIn('role', ['admin', 'moderator'])
|
|
->orderBy('username')
|
|
->limit(50)
|
|
->get(['id', 'username', 'name'])
|
|
->map(fn ($user): array => [
|
|
'id' => (int) $user->id,
|
|
'username' => (string) $user->username,
|
|
'name' => $user->name,
|
|
])
|
|
->values()
|
|
->all(),
|
|
'endpoints' => [
|
|
'store' => route('cp.cards.collections.store'),
|
|
'updatePattern' => route('cp.cards.collections.update', ['collection' => '__COLLECTION__']),
|
|
'attachCardPattern' => route('cp.cards.collections.cards.store', ['collection' => '__COLLECTION__']),
|
|
'detachCardPattern' => route('cp.cards.collections.cards.destroy', ['collection' => '__COLLECTION__', 'card' => '__CARD__']),
|
|
'cards' => route('cp.cards.index'),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function storeTemplate(AdminStoreNovaCardTemplateRequest $request): JsonResponse
|
|
{
|
|
$template = NovaCardTemplate::query()->create($request->validated());
|
|
|
|
return response()->json([
|
|
'template' => [
|
|
'id' => (int) $template->id,
|
|
'slug' => (string) $template->slug,
|
|
'name' => (string) $template->name,
|
|
'description' => $template->description,
|
|
'preview_image' => $template->preview_image,
|
|
'config_json' => $template->config_json,
|
|
'supported_formats' => $template->supported_formats,
|
|
'active' => (bool) $template->active,
|
|
'official' => (bool) $template->official,
|
|
'order_num' => (int) $template->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function updateTemplate(AdminStoreNovaCardTemplateRequest $request, NovaCardTemplate $template): JsonResponse
|
|
{
|
|
$template->update($request->validated());
|
|
|
|
return response()->json([
|
|
'template' => [
|
|
'id' => (int) $template->id,
|
|
'slug' => (string) $template->slug,
|
|
'name' => (string) $template->name,
|
|
'description' => $template->description,
|
|
'preview_image' => $template->preview_image,
|
|
'config_json' => $template->config_json,
|
|
'supported_formats' => $template->supported_formats,
|
|
'active' => (bool) $template->active,
|
|
'official' => (bool) $template->official,
|
|
'order_num' => (int) $template->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function storeAssetPack(AdminStoreNovaCardAssetPackRequest $request): JsonResponse
|
|
{
|
|
$pack = NovaCardAssetPack::query()->create($request->validated());
|
|
|
|
return response()->json([
|
|
'pack' => [
|
|
'id' => (int) $pack->id,
|
|
'slug' => (string) $pack->slug,
|
|
'name' => (string) $pack->name,
|
|
'description' => $pack->description,
|
|
'type' => (string) $pack->type,
|
|
'preview_image' => $pack->preview_image,
|
|
'manifest_json' => $pack->manifest_json,
|
|
'official' => (bool) $pack->official,
|
|
'active' => (bool) $pack->active,
|
|
'order_num' => (int) $pack->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function updateAssetPack(AdminStoreNovaCardAssetPackRequest $request, NovaCardAssetPack $assetPack): JsonResponse
|
|
{
|
|
$assetPack->update($request->validated());
|
|
|
|
return response()->json([
|
|
'pack' => [
|
|
'id' => (int) $assetPack->id,
|
|
'slug' => (string) $assetPack->slug,
|
|
'name' => (string) $assetPack->name,
|
|
'description' => $assetPack->description,
|
|
'type' => (string) $assetPack->type,
|
|
'preview_image' => $assetPack->preview_image,
|
|
'manifest_json' => $assetPack->manifest_json,
|
|
'official' => (bool) $assetPack->official,
|
|
'active' => (bool) $assetPack->active,
|
|
'order_num' => (int) $assetPack->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function storeChallenge(AdminStoreNovaCardChallengeRequest $request): JsonResponse
|
|
{
|
|
$challenge = NovaCardChallenge::query()->create($request->validated() + [
|
|
'user_id' => $request->user()->id,
|
|
]);
|
|
|
|
return response()->json([
|
|
'challenge' => [
|
|
'id' => (int) $challenge->id,
|
|
'slug' => (string) $challenge->slug,
|
|
'title' => (string) $challenge->title,
|
|
'description' => $challenge->description,
|
|
'prompt' => $challenge->prompt,
|
|
'rules_json' => $challenge->rules_json,
|
|
'status' => (string) $challenge->status,
|
|
'official' => (bool) $challenge->official,
|
|
'featured' => (bool) $challenge->featured,
|
|
'winner_card_id' => $challenge->winner_card_id ? (int) $challenge->winner_card_id : null,
|
|
'entries_count' => (int) $challenge->entries_count,
|
|
'starts_at' => optional($challenge->starts_at)?->format('Y-m-d\TH:i'),
|
|
'ends_at' => optional($challenge->ends_at)?->format('Y-m-d\TH:i'),
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function updateChallenge(AdminStoreNovaCardChallengeRequest $request, NovaCardChallenge $challenge): JsonResponse
|
|
{
|
|
$challenge->update($request->validated());
|
|
|
|
return response()->json([
|
|
'challenge' => [
|
|
'id' => (int) $challenge->id,
|
|
'slug' => (string) $challenge->slug,
|
|
'title' => (string) $challenge->title,
|
|
'description' => $challenge->description,
|
|
'prompt' => $challenge->prompt,
|
|
'rules_json' => $challenge->rules_json,
|
|
'status' => (string) $challenge->status,
|
|
'official' => (bool) $challenge->official,
|
|
'featured' => (bool) $challenge->featured,
|
|
'winner_card_id' => $challenge->winner_card_id ? (int) $challenge->winner_card_id : null,
|
|
'entries_count' => (int) $challenge->entries_count,
|
|
'starts_at' => optional($challenge->starts_at)?->format('Y-m-d\TH:i'),
|
|
'ends_at' => optional($challenge->ends_at)?->format('Y-m-d\TH:i'),
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function storeCategory(AdminStoreNovaCardCategoryRequest $request): JsonResponse
|
|
{
|
|
$category = NovaCardCategory::query()->create($request->validated());
|
|
|
|
return response()->json([
|
|
'category' => [
|
|
'id' => (int) $category->id,
|
|
'slug' => (string) $category->slug,
|
|
'name' => (string) $category->name,
|
|
'description' => $category->description,
|
|
'active' => (bool) $category->active,
|
|
'order_num' => (int) $category->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function updateCategory(AdminStoreNovaCardCategoryRequest $request, NovaCardCategory $category): JsonResponse
|
|
{
|
|
$category->update($request->validated());
|
|
|
|
return response()->json([
|
|
'category' => [
|
|
'id' => (int) $category->id,
|
|
'slug' => (string) $category->slug,
|
|
'name' => (string) $category->name,
|
|
'description' => $category->description,
|
|
'active' => (bool) $category->active,
|
|
'order_num' => (int) $category->order_num,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function storeCollection(Request $request): JsonResponse
|
|
{
|
|
$payload = $request->validate([
|
|
'user_id' => ['required', 'integer', 'exists:users,id'],
|
|
'slug' => ['nullable', 'string', 'max:140'],
|
|
'name' => ['required', 'string', 'min:2', 'max:120'],
|
|
'description' => ['nullable', 'string', 'max:1000'],
|
|
'visibility' => ['required', 'in:private,public'],
|
|
'official' => ['nullable', 'boolean'],
|
|
'featured' => ['nullable', 'boolean'],
|
|
]);
|
|
|
|
$collection = $this->collections->createManagedCollection($payload);
|
|
|
|
return response()->json([
|
|
'collection' => $this->presenter->collection($collection->fresh(['user', 'items.card.user.profile', 'items.card.category', 'items.card.template', 'items.card.backgroundImage', 'items.card.tags']), $request->user(), true),
|
|
]);
|
|
}
|
|
|
|
public function updateCollection(Request $request, NovaCardCollection $collection): JsonResponse
|
|
{
|
|
$payload = $request->validate([
|
|
'user_id' => ['required', 'integer', 'exists:users,id'],
|
|
'slug' => ['required', 'string', 'max:140'],
|
|
'name' => ['required', 'string', 'min:2', 'max:120'],
|
|
'description' => ['nullable', 'string', 'max:1000'],
|
|
'visibility' => ['required', 'in:private,public'],
|
|
'official' => ['nullable', 'boolean'],
|
|
'featured' => ['nullable', 'boolean'],
|
|
]);
|
|
|
|
$collection->update([
|
|
'user_id' => (int) $payload['user_id'],
|
|
'slug' => $payload['slug'],
|
|
'name' => $payload['name'],
|
|
'description' => $payload['description'] ?? null,
|
|
'visibility' => $payload['visibility'],
|
|
'official' => (bool) ($payload['official'] ?? false),
|
|
'featured' => (bool) ($payload['featured'] ?? false),
|
|
]);
|
|
|
|
return response()->json([
|
|
'collection' => $this->presenter->collection($collection->fresh(['user', 'items.card.user.profile', 'items.card.category', 'items.card.template', 'items.card.backgroundImage', 'items.card.tags']), $request->user(), true),
|
|
]);
|
|
}
|
|
|
|
public function storeCollectionCard(Request $request, NovaCardCollection $collection): JsonResponse
|
|
{
|
|
$payload = $request->validate([
|
|
'card_id' => ['required', 'integer', 'exists:nova_cards,id'],
|
|
'note' => ['nullable', 'string', 'max:1000'],
|
|
]);
|
|
|
|
$card = NovaCard::query()->findOrFail((int) $payload['card_id']);
|
|
$this->collections->addCardToCollection($collection, $card, $payload['note'] ?? null);
|
|
|
|
return response()->json([
|
|
'collection' => $this->presenter->collection($collection->fresh(['user', 'items.card.user.profile', 'items.card.category', 'items.card.template', 'items.card.backgroundImage', 'items.card.tags']), $request->user(), true),
|
|
]);
|
|
}
|
|
|
|
public function destroyCollectionCard(Request $request, NovaCardCollection $collection, NovaCard $card): JsonResponse
|
|
{
|
|
$this->collections->removeCardFromCollection($collection, $card);
|
|
|
|
return response()->json([
|
|
'collection' => $this->presenter->collection($collection->fresh(['user', 'items.card.user.profile', 'items.card.category', 'items.card.template', 'items.card.backgroundImage', 'items.card.tags']), $request->user(), true),
|
|
]);
|
|
}
|
|
|
|
public function updateCard(AdminUpdateNovaCardRequest $request, NovaCard $card): JsonResponse
|
|
{
|
|
$attributes = $request->validated();
|
|
$requestedDisposition = $attributes['disposition'] ?? null;
|
|
$hasModerationChange = array_key_exists('moderation_status', $attributes)
|
|
&& $attributes['moderation_status'] !== $card->moderation_status;
|
|
$hasDispositionChange = array_key_exists('disposition', $attributes)
|
|
&& $requestedDisposition !== (($this->moderation->latestOverride($card) ?? [])['disposition'] ?? null);
|
|
if (isset($attributes['featured']) && (! isset($attributes['status']) || $attributes['status'] !== NovaCard::STATUS_PUBLISHED)) {
|
|
$attributes['featured'] = (bool) $attributes['featured'] && $card->status === NovaCard::STATUS_PUBLISHED;
|
|
}
|
|
|
|
unset($attributes['disposition']);
|
|
|
|
$card->update($attributes);
|
|
|
|
if ($hasModerationChange || $hasDispositionChange) {
|
|
$card = $this->moderation->recordStaffOverride(
|
|
$card->fresh(),
|
|
(string) ($attributes['moderation_status'] ?? $card->moderation_status),
|
|
$request->user(),
|
|
'admin_card_update',
|
|
[
|
|
'disposition' => $requestedDisposition,
|
|
],
|
|
);
|
|
}
|
|
|
|
return response()->json([
|
|
'card' => $this->presenter->card($card->fresh()->loadMissing(['user.profile', 'category', 'template', 'backgroundImage', 'tags']), false, $request->user()),
|
|
]);
|
|
}
|
|
|
|
public function updateCreator(Request $request, User $user): JsonResponse
|
|
{
|
|
$attributes = $request->validate([
|
|
'nova_featured_creator' => ['required', 'boolean'],
|
|
]);
|
|
|
|
$user->update($attributes);
|
|
|
|
$publicCardsCount = $user->novaCards()->publiclyVisible()->count();
|
|
$featuredCardsCount = $user->novaCards()->publiclyVisible()->where('featured', true)->count();
|
|
$totalViewsCount = (int) ($user->novaCards()->publiclyVisible()->sum('views_count') ?? 0);
|
|
|
|
return response()->json([
|
|
'creator' => [
|
|
'id' => (int) $user->id,
|
|
'username' => (string) $user->username,
|
|
'name' => $user->name,
|
|
'display_name' => $user->name ?: '@' . $user->username,
|
|
'public_url' => route('cards.creator', ['username' => $user->username]),
|
|
'nova_featured_creator' => (bool) $user->nova_featured_creator,
|
|
'public_cards_count' => $publicCardsCount,
|
|
'featured_cards_count' => $featuredCardsCount,
|
|
'total_views_count' => $totalViewsCount,
|
|
],
|
|
]);
|
|
}
|
|
}
|