user()->can('use_global_search'), 403); $data = $request->validate(['q' => 'required|string|min:2|max:100']); $q = $data['q']; $user = $request->user(); $leads = Lead::query(); AccessControl::scopeLeads($leads, $user); $companies = Company::query(); AccessControl::scopeCompanies($companies, $user); $contacts = Contact::query(); AccessControl::scopeContacts($contacts, $user); $calls = Call::with('lead:id,first_name,last_name,company'); AccessControl::scopeCalls($calls, $user); return response()->json([ 'leads' => $leads->where(fn (Builder $x) => $x->where('first_name', 'like', "%{$q}%")->orWhere('last_name', 'like', "%{$q}%")->orWhere('company', 'like', "%{$q}%")->orWhere('phone', 'like', "%{$q}%"))->limit(5)->get(['id', 'first_name', 'last_name', 'company', 'lead_score', 'score_level']), 'companies' => $companies->where('name', 'like', "%{$q}%")->limit(5)->get(['id', 'name', 'industry']), 'contacts' => $contacts->where('name', 'like', "%{$q}%")->limit(5)->get(['id', 'name', 'email']), 'calls' => $calls->where('notes', 'like', "%{$q}%")->limit(5)->latest()->get(['id', 'lead_id', 'result', 'created_at']), ]); } public function savedViews(Request $request): JsonResponse { abort_unless($request->user()->can('manage_saved_views'), 403); $entity = $request->validate(['entity_type' => 'nullable|string|in:lead,deal,company,contact,call,task'])['entity_type'] ?? null; $teamIds = AccessControl::teamIds($request->user()); $query = SavedView::where(fn (Builder $q) => $q->where('user_id', $request->user()->id)->orWhere('visibility', 'public')->orWhere(fn (Builder $team) => $team->where('visibility', 'team')->whereIn('team_id', $teamIds))); if ($entity) { $query->where('entity_type', $entity); } return response()->json($query->orderByDesc('is_default')->latest()->get()); } public function storeSavedView(Request $request): JsonResponse { abort_unless($request->user()->can('manage_saved_views'), 403); $data = $request->validate([ 'entity_type' => 'required|in:lead,deal,company,contact,call,task', 'name' => 'required|string|max:100', 'visibility' => 'required|in:private,team,public', 'team_id' => 'nullable|exists:teams,id', 'filters' => 'required|array|max:30', 'columns' => 'nullable|array|max:30', 'sort' => 'nullable|array|max:5', 'is_default' => 'boolean', ]); if ($data['visibility'] !== 'private') { abort_unless($request->user()->can('share_team_views'), 403); } if (($data['visibility'] ?? '') === 'team') { abort_unless(in_array((int) ($data['team_id'] ?? 0), AccessControl::teamIds($request->user()), true), 403); } if ($data['is_default'] ?? false) { SavedView::where('user_id', $request->user()->id)->where('entity_type', $data['entity_type'])->update(['is_default' => false]); } return response()->json(SavedView::create($data + ['user_id' => $request->user()->id]), 201); } public function deleteSavedView(Request $request, SavedView $savedView): JsonResponse { abort_unless($savedView->user_id === $request->user()->id || $request->user()->hasRole('admin'), 403); $savedView->delete(); return response()->json(['message' => 'نمای ذخیره‌شده حذف شد.']); } public function preferences(Request $request): JsonResponse { return response()->json([ 'dashboard' => DashboardPreference::firstOrCreate(['user_id' => $request->user()->id]), 'notifications' => NotificationPreference::where('user_id', $request->user()->id)->get(), ]); } public function updatePreferences(Request $request): JsonResponse { $data = $request->validate([ 'widget_order' => 'nullable|array|max:30', 'hidden_widgets' => 'nullable|array|max:30', 'default_filters' => 'nullable|array|max:20', 'notifications' => 'nullable|array|max:30', 'notifications.*.notification_type' => 'required|string|max:60', 'notifications.*.in_app_enabled' => 'boolean', 'notifications.*.is_muted' => 'boolean', ]); $dashboard = DashboardPreference::updateOrCreate(['user_id' => $request->user()->id], collect($data)->only(['widget_order', 'hidden_widgets', 'default_filters'])->all()); foreach ($data['notifications'] ?? [] as $preference) { NotificationPreference::updateOrCreate(['user_id' => $request->user()->id, 'notification_type' => $preference['notification_type']], $preference); } return response()->json(['dashboard' => $dashboard, 'notifications' => NotificationPreference::where('user_id', $request->user()->id)->get()]); } }