user = $user->load(['roles.permissions', 'permissions', 'customer']); } public function render() { $userRoles = $this->user->roles() ->where('user_roles.is_active', true) ->where(function ($q) { $q->whereNull('user_roles.expires_at') ->orWhere('user_roles.expires_at', '>', now()); }) ->withPivot(['branch_code', 'assigned_at', 'expires_at']) ->get(); $userDirectPermissions = $this->user->permissions() ->where('user_permissions.granted', true) ->where(function ($q) { $q->whereNull('user_permissions.expires_at') ->orWhere('user_permissions.expires_at', '>', now()); }) ->withPivot(['branch_code', 'assigned_at', 'expires_at']) ->get(); $allPermissions = $this->user->getAllPermissions(); $permissionsByModule = $allPermissions->groupBy('module'); // Get role-based permissions $rolePermissions = collect(); foreach ($userRoles as $role) { $rolePermissions = $rolePermissions->merge($role->permissions); } $rolePermissions = $rolePermissions->unique('id'); // Get recent activity $causedByUser = Activity::where('causer_id', $this->user->id) ->where('causer_type', User::class) ->latest() ->limit(10) ->get(); $performedOnUser = Activity::where('subject_id', $this->user->id) ->where('subject_type', User::class) ->latest() ->limit(10) ->get(); $recentActivity = $causedByUser->merge($performedOnUser) ->sortByDesc('created_at') ->take(20); // Get user metrics $metrics = $this->getUserMetrics(); // Get user's work orders, service orders, etc. (if applicable) $workStats = $this->getUserWorkStats(); return view('livewire.users.show', [ 'userRoles' => $userRoles, 'userDirectPermissions' => $userDirectPermissions, 'allPermissions' => $allPermissions, 'permissionsByModule' => $permissionsByModule, 'rolePermissions' => $rolePermissions, 'recentActivity' => $recentActivity, 'metrics' => $metrics, 'workStats' => $workStats, ]); } public function setActiveTab($tab) { $this->activeTab = $tab; } public function showRoleDetails($roleId) { $this->selectedRole = Role::with('permissions')->find($roleId); $this->showRoleModal = true; } public function showPermissionDetails($permissionId) { $this->selectedPermission = Permission::find($permissionId); $this->showPermissionModal = true; } public function closeModals() { $this->showRoleModal = false; $this->showPermissionModal = false; $this->showDeleteModal = false; $this->showImpersonateModal = false; $this->showActivityModal = false; $this->selectedRole = null; $this->selectedPermission = null; } public function removeRole($roleId) { try { $this->user->roles()->detach($roleId); $this->user->refresh(); // Log the action activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->withProperties(['role_id' => $roleId]) ->log('Role removed from user'); session()->flash('success', 'Role removed successfully.'); } catch (\Exception $e) { session()->flash('error', 'Failed to remove role: ' . $e->getMessage()); } } public function removePermission($permissionId) { try { $this->user->permissions()->detach($permissionId); $this->user->refresh(); // Log the action activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->withProperties(['permission_id' => $permissionId]) ->log('Permission removed from user'); session()->flash('success', 'Permission removed successfully.'); } catch (\Exception $e) { session()->flash('error', 'Failed to remove permission: ' . $e->getMessage()); } } public function toggleUserStatus() { if ($this->user->id === auth()->id()) { session()->flash('error', 'You cannot change your own status.'); return; } try { $newStatus = $this->user->status === 'active' ? 'inactive' : 'active'; $oldStatus = $this->user->status; $this->user->update(['status' => $newStatus]); // Log the action activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->withProperties([ 'old_status' => $oldStatus, 'new_status' => $newStatus, ]) ->log('User status changed'); $statusText = $newStatus === 'active' ? 'activated' : 'deactivated'; session()->flash('success', "User {$statusText} successfully."); } catch (\Exception $e) { session()->flash('error', 'Failed to update status: ' . $e->getMessage()); } } public function suspendUser() { if ($this->user->id === auth()->id()) { session()->flash('error', 'You cannot suspend your own account.'); return; } try { $oldStatus = $this->user->status; $this->user->update(['status' => 'suspended']); // Log the action activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->withProperties([ 'old_status' => $oldStatus, 'new_status' => 'suspended', ]) ->log('User suspended'); session()->flash('success', 'User suspended successfully.'); } catch (\Exception $e) { session()->flash('error', 'Failed to suspend user: ' . $e->getMessage()); } } public function impersonateUser() { if ($this->user->id === auth()->id()) { session()->flash('error', 'You cannot impersonate yourself.'); return; } if ($this->user->status !== 'active') { session()->flash('error', 'Cannot impersonate inactive user.'); return; } try { // Log the impersonation start activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->log('Impersonation started'); // Store original user ID for returning later session(['impersonate_original_user' => auth()->id()]); auth()->loginUsingId($this->user->id); session()->flash('success', 'Now impersonating ' . $this->user->name); return redirect()->route('dashboard'); } catch (\Exception $e) { session()->flash('error', 'Failed to impersonate user: ' . $e->getMessage()); } } public function sendPasswordReset() { try { // Generate a secure temporary password $tempPassword = $this->generateSecurePassword(); $this->user->update([ 'password' => Hash::make($tempPassword), 'password_changed_at' => now(), ]); // Log the action activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->log('Password reset by admin'); // TODO: Send password reset email with new temporary password // $this->user->notify(new PasswordResetByAdminNotification($tempPassword)); session()->flash('success', "Password reset successfully. New temporary password: {$tempPassword}"); } catch (\Exception $e) { session()->flash('error', 'Failed to reset password: ' . $e->getMessage()); } } public function generateSecurePassword($length = 12) { $uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $lowercase = 'abcdefghijklmnopqrstuvwxyz'; $numbers = '0123456789'; $symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?'; $password = ''; $password .= $uppercase[random_int(0, strlen($uppercase) - 1)]; $password .= $lowercase[random_int(0, strlen($lowercase) - 1)]; $password .= $numbers[random_int(0, strlen($numbers) - 1)]; $password .= $symbols[random_int(0, strlen($symbols) - 1)]; $allChars = $uppercase . $lowercase . $numbers . $symbols; for ($i = 4; $i < $length; $i++) { $password .= $allChars[random_int(0, strlen($allChars) - 1)]; } return str_shuffle($password); } public function exportUserData() { try { // Log the export request activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->log('User data export requested'); // TODO: Implement user data export (GDPR compliance) // This should include all user data, activity logs, etc. session()->flash('success', 'User data export initiated. You will receive an email when ready.'); } catch (\Exception $e) { session()->flash('error', 'Failed to export user data: ' . $e->getMessage()); } } public function deleteUser() { if ($this->user->id === auth()->id()) { session()->flash('error', 'You cannot delete your own account.'); return; } try { // Log before deletion activity() ->performedOn($this->user) ->causedBy(auth()->user()) ->withProperties([ 'deleted_user_data' => [ 'name' => $this->user->name, 'email' => $this->user->email, 'employee_id' => $this->user->employee_id, ] ]) ->log('User deleted by admin'); $userName = $this->user->name; $this->user->delete(); session()->flash('success', "User '{$userName}' deleted successfully."); return redirect()->route('users.index'); } catch (\Exception $e) { session()->flash('error', 'Failed to delete user: ' . $e->getMessage()); } $this->showDeleteModal = false; } public function confirmDelete() { $this->showDeleteModal = true; } public function confirmImpersonate() { $this->showImpersonateModal = true; } public function getUserMetrics() { $totalPermissions = $this->user->getAllPermissions()->count(); $directPermissions = $this->user->permissions() ->where('user_permissions.granted', true) ->where(function ($q) { $q->whereNull('user_permissions.expires_at') ->orWhere('user_permissions.expires_at', '>', now()); }) ->count(); $activeRoles = $this->user->roles() ->where('user_roles.is_active', true) ->where(function ($q) { $q->whereNull('user_roles.expires_at') ->orWhere('user_roles.expires_at', '>', now()); }) ->count(); return [ 'total_permissions' => $totalPermissions, 'direct_permissions' => $directPermissions, 'role_permissions' => $totalPermissions - $directPermissions, 'active_roles' => $activeRoles, 'days_since_created' => $this->user->created_at->diffInDays(now()), 'last_login' => $this->user->last_login_at ? $this->user->last_login_at->diffForHumans() : 'Never', 'password_age' => $this->user->password_changed_at ? $this->user->password_changed_at->diffInDays(now()) : null, ]; } public function getUserWorkStats() { // Get work-related statistics for the user $stats = [ 'work_orders_assigned' => 0, 'work_orders_completed' => 0, 'service_orders_created' => 0, 'total_revenue_generated' => 0, ]; try { // Work orders assigned to user (if technician) if (\Schema::hasTable('work_orders')) { $stats['work_orders_assigned'] = \DB::table('work_orders') ->where('assigned_technician_id', $this->user->id) ->count(); $stats['work_orders_completed'] = \DB::table('work_orders') ->where('assigned_technician_id', $this->user->id) ->where('status', 'completed') ->count(); } // Service orders created by user (if service advisor) if (\Schema::hasTable('service_orders')) { $stats['service_orders_created'] = \DB::table('service_orders') ->where('created_by', $this->user->id) ->count(); $stats['total_revenue_generated'] = \DB::table('service_orders') ->where('created_by', $this->user->id) ->where('status', 'completed') ->sum('total_amount') ?? 0; } } catch (\Exception $e) { // Tables might not exist, return default stats } return $stats; } public function getStatusBadgeClass($status) { return match($status) { 'active' => 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200', 'inactive' => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200', 'suspended' => 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200', default => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200' }; } public function getRoleBadgeClass($roleName) { return match($roleName) { 'super_admin' => 'bg-gradient-to-r from-purple-500 to-pink-500 text-white', 'administrator' => 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200', 'manager' => 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200', 'service_manager' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200', 'technician' => 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200', 'senior_technician' => 'bg-emerald-100 dark:bg-emerald-900 text-emerald-800 dark:text-emerald-200', 'parts_clerk' => 'bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200', 'service_advisor' => 'bg-teal-100 dark:bg-teal-900 text-teal-800 dark:text-teal-200', 'receptionist' => 'bg-pink-100 dark:bg-pink-900 text-pink-800 dark:text-pink-200', 'cashier' => 'bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200', 'customer_portal' => 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200', 'customer' => 'bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200', 'viewer' => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200', default => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200' }; } public function canPerformAction($action) { // Check if current user can perform certain actions on this user $currentUser = auth()->user(); // Super admin can do anything if ($currentUser->hasRole('super_admin')) { return true; } // Can't perform actions on yourself (except view) if ($currentUser->id === $this->user->id && $action !== 'view') { return false; } // Check specific permissions based on action return match($action) { 'edit' => $currentUser->can('users.edit'), 'delete' => $currentUser->can('users.delete'), 'impersonate' => $currentUser->can('users.impersonate'), 'reset_password' => $currentUser->can('users.reset-password'), 'manage_roles' => $currentUser->can('users.manage-roles'), 'view_activity' => $currentUser->can('users.view-activity'), default => false, }; } public function getLastActivityDate() { $lastActivity = Activity::where('causer_id', $this->user->id) ->where('causer_type', User::class) ->latest() ->first(); return $lastActivity ? $lastActivity->created_at->diffForHumans() : 'No activity recorded'; } public function getTotalLoginCount() { // This would require a login tracking system return Activity::where('causer_id', $this->user->id) ->where('causer_type', User::class) ->where('description', 'like', '%login%') ->count(); } }