'System Config', 'User' => 'User Profile', 'Role' => 'Access Role', 'Permission' => 'Access Permission', 'MobileSetting' => 'Mobile Config', ]; return $mapping[$className] ?? Str::headline($className); } /** * Get badge class for the event. */ public static function getEventBadgeClass(string $event): string { return match (strtolower($event)) { 'created' => 'text-bg-success', 'updated' => 'text-bg-warning', 'deleted' => 'text-bg-danger', 'restored' => 'text-bg-info', 'login', 'login_attempt' => 'text-bg-info', 'logout' => 'text-bg-secondary', 'password_changed', 'password reset' => 'text-bg-primary', default => 'text-bg-theme-1', }; } /** * Get icon for the event. */ public static function getEventIcon(string $event): string { return match (strtolower($event)) { 'created' => 'bi-plus-circle', 'updated' => 'bi-pencil-square', 'deleted' => 'bi-trash', 'restored' => 'bi-arrow-counterclockwise', 'login', 'login_attempt' => 'bi-box-arrow-in-right', 'logout' => 'bi-box-arrow-right', 'password_changed', 'password reset' => 'bi-key', default => 'bi-info-circle', }; } /** * Formats the changes between old and new properties. */ public static function formatChanges(array $properties): array { $old = $properties['old'] ?? []; $new = $properties['attributes'] ?? []; $changes = []; // If it's a "created" event, show all attributes if (empty($old) && ! empty($new)) { foreach ($new as $key => $value) { if (self::isSensitive($key)) { continue; } $changes[] = [ 'field' => Str::headline($key), 'old' => null, 'new' => self::formatValue($value), ]; } return $changes; } // For updates, show only changed fields foreach ($new as $key => $value) { if (self::isSensitive($key)) { continue; } $oldValue = $old[$key] ?? null; // Loose comparison to handle type juggling from DB if ($oldValue != $value) { $changes[] = [ 'field' => Str::headline($key), 'old' => self::formatValue($oldValue), 'new' => self::formatValue($value), ]; } } return $changes; } private static function isSensitive(string $key): bool { $sensitive = ['password', 'remember_token', 'secret', 'key', 'token', '2fa_secret']; foreach ($sensitive as $s) { if (str_contains(strtolower($key), $s)) { return true; } } return false; } private static function formatValue(mixed $value): string { if (is_null($value)) { return 'NULL'; } if (is_bool($value)) { return $value ? 'TRUE' : 'FALSE'; } if (is_array($value) || is_object($value)) { return json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } if ($value === '') { return '[empty]'; } // Truncate long values but keep it readable if (is_string($value) && strlen($value) > 200) { return substr($value, 0, 197).'...'; } return (string) $value; } }