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(), ]), ]); } }