Files
SkinbaseNova/app/Http/Controllers/Studio/StudioPreferencesApiController.php

114 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Studio;
use App\Http\Controllers\Controller;
use App\Models\UserProfile;
use App\Services\NotificationService;
use App\Services\Studio\CreatorStudioPreferenceService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
final class StudioPreferencesApiController extends Controller
{
public function __construct(
private readonly CreatorStudioPreferenceService $preferences,
private readonly NotificationService $notifications,
) {
}
public function updatePreferences(Request $request): JsonResponse
{
$payload = $request->validate([
'default_content_view' => ['required', Rule::in(['grid', 'list'])],
'analytics_range_days' => ['required', Rule::in([7, 14, 30, 60, 90])],
'dashboard_shortcuts' => ['required', 'array', 'max:8'],
'dashboard_shortcuts.*' => ['string'],
'draft_behavior' => ['required', Rule::in(['resume-last', 'open-drafts', 'focus-published'])],
'featured_modules' => ['nullable', 'array'],
'featured_modules.*' => [Rule::in(['artworks', 'cards', 'collections', 'stories'])],
'default_landing_page' => ['nullable', Rule::in(['overview', 'content', 'drafts', 'scheduled', 'analytics', 'activity', 'calendar', 'inbox', 'search', 'growth', 'challenges', 'preferences'])],
'widget_visibility' => ['nullable', 'array'],
'widget_order' => ['nullable', 'array'],
'widget_order.*' => ['string'],
'card_density' => ['nullable', Rule::in(['compact', 'comfortable'])],
'scheduling_timezone' => ['nullable', 'string', 'max:64'],
]);
return response()->json([
'data' => $this->preferences->update($request->user(), $payload),
]);
}
public function updateProfile(Request $request): JsonResponse
{
$payload = $request->validate([
'display_name' => ['required', 'string', 'max:60'],
'tagline' => ['nullable', 'string', 'max:1000'],
'bio' => ['nullable', 'string', 'max:1000'],
'website' => ['nullable', 'url', 'max:255'],
'social_links' => ['nullable', 'array', 'max:8'],
'social_links.*.platform' => ['required_with:social_links', 'string', 'max:32'],
'social_links.*.url' => ['required_with:social_links', 'url', 'max:255'],
]);
$user = $request->user();
$user->forceFill(['name' => (string) $payload['display_name']])->save();
UserProfile::query()->updateOrCreate(
['user_id' => $user->id],
[
'about' => $payload['bio'] ?? null,
'description' => $payload['tagline'] ?? null,
'website' => $payload['website'] ?? null,
]
);
DB::table('user_social_links')->where('user_id', $user->id)->delete();
foreach ($payload['social_links'] ?? [] as $link) {
DB::table('user_social_links')->insert([
'user_id' => $user->id,
'platform' => strtolower(trim((string) $link['platform'])),
'url' => trim((string) $link['url']),
'created_at' => now(),
'updated_at' => now(),
]);
}
return response()->json([
'ok' => true,
]);
}
public function updateFeatured(Request $request): JsonResponse
{
$payload = $request->validate([
'featured_modules' => ['nullable', 'array'],
'featured_modules.*' => [Rule::in(['artworks', 'cards', 'collections', 'stories'])],
'featured_content' => ['nullable', 'array'],
'featured_content.artworks' => ['nullable', 'integer', 'min:1'],
'featured_content.cards' => ['nullable', 'integer', 'min:1'],
'featured_content.collections' => ['nullable', 'integer', 'min:1'],
'featured_content.stories' => ['nullable', 'integer', 'min:1'],
]);
return response()->json([
'data' => $this->preferences->update($request->user(), $payload),
]);
}
public function markActivityRead(Request $request): JsonResponse
{
$this->notifications->markAllRead($request->user());
return response()->json([
'data' => $this->preferences->update($request->user(), [
'activity_last_read_at' => now()->toIso8601String(),
]),
]);
}
}