You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
8.6 KiB
PHTML

<?php
namespace App\Http\Controllers\Administracion;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
use Spatie\Permission\Models\Role;
class UserController extends Controller
{
public function index(Request $request)
{
try {
$query = User::with('roles');
if ($request->filled('buscar')) {
$query->where(function ($q) use ($request) {
$q->where('name', 'like', "%{$request->buscar}%")
->orWhere('email', 'like', "%{$request->buscar}%");
});
}
if ($request->filled('rol')) {
$query->whereHas('roles', function ($q) use ($request) {
$q->where('name', $request->rol);
});
}
$usuarios = $query->orderBy('id', 'desc')->paginate(15);
$usuarios->getCollection()->transform(function ($user) {
return [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'roles' => $user->getRoleNames(),
'created_at' => $user->created_at,
];
});
return response()->json([
'success' => true,
'data' => $usuarios,
]);
} catch (\Exception $e) {
Log::error('Error al listar usuarios', ['error' => $e->getMessage()]);
return response()->json(['success' => false, 'message' => 'Error al obtener usuarios'], 500);
}
}
public function store(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255|regex:/^[\pL\s\-]+$/u',
'email' => 'required|email|unique:users,email|max:255',
'password' => 'required|string|min:8|confirmed',
'rol' => 'required|string|exists:roles,name',
], [
'name.regex' => 'El nombre solo puede contener letras y espacios.',
'rol.exists' => 'El rol seleccionado no existe.',
'email.unique' => 'Este correo ya está registrado.',
]);
if ($validator->fails()) {
return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
}
$user = User::create([
'name' => strip_tags(trim($request->name)),
'email' => strtolower(trim($request->email)),
'password' => Hash::make($request->password),
]);
$user->assignRole($request->rol);
Log::info('Usuario creado por admin', [
'admin_id' => $request->user()->id,
'nuevo_user_id' => $user->id,
]);
return response()->json([
'success' => true,
'message' => 'Usuario creado correctamente',
'data' => [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'roles' => $user->getRoleNames(),
'created_at' => $user->created_at,
],
], 201);
} catch (\Exception $e) {
Log::error('Error al crear usuario', ['error' => $e->getMessage()]);
return response()->json(['success' => false, 'message' => 'Error al crear usuario'], 500);
}
}
public function update(Request $request, $id)
{
try {
$user = User::findOrFail($id);
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255|regex:/^[\pL\s\-]+$/u',
'email' => 'required|email|max:255|unique:users,email,' . $user->id,
'rol' => 'required|string|exists:roles,name',
], [
'name.regex' => 'El nombre solo puede contener letras y espacios.',
'rol.exists' => 'El rol seleccionado no existe.',
'email.unique' => 'Este correo ya está registrado.',
]);
if ($validator->fails()) {
return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
}
$user->update([
'name' => strip_tags(trim($request->name)),
'email' => strtolower(trim($request->email)),
]);
$user->syncRoles([$request->rol]);
Log::info('Usuario actualizado', [
'admin_id' => $request->user()->id,
'user_id' => $user->id,
]);
return response()->json([
'success' => true,
'message' => 'Usuario actualizado correctamente',
'data' => [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'roles' => $user->getRoleNames(),
'created_at' => $user->created_at,
],
]);
} catch (\Exception $e) {
Log::error('Error al actualizar usuario', ['error' => $e->getMessage()]);
return response()->json(['success' => false, 'message' => 'Error al actualizar usuario'], 500);
}
}
public function changePassword(Request $request, $id)
{
try {
$user = User::findOrFail($id);
$authUser = $request->user();
$rules = ['password' => 'required|string|min:8|confirmed'];
if ($authUser->id === $user->id) {
$rules['current_password'] = 'required|string';
}
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
}
if ($authUser->id === $user->id) {
if (!Hash::check($request->current_password, $user->password)) {
return response()->json([
'success' => false,
'errors' => ['current_password' => ['La contraseña actual no es correcta']],
], 422);
}
} else {
// Al cambiar la contraseña de otro usuario, revocar sus tokens
$user->tokens()->delete();
}
$user->update(['password' => Hash::make($request->password)]);
Log::info('Contraseña cambiada', [
'admin_id' => $authUser->id,
'user_id' => $user->id,
]);
return response()->json([
'success' => true,
'message' => 'Contraseña actualizada correctamente',
]);
} catch (\Exception $e) {
Log::error('Error al cambiar contraseña', ['error' => $e->getMessage()]);
return response()->json(['success' => false, 'message' => 'Error al cambiar contraseña'], 500);
}
}
public function destroy(Request $request, $id)
{
try {
$user = User::findOrFail($id);
if ($request->user()->id === $user->id) {
return response()->json([
'success' => false,
'message' => 'No puedes eliminar tu propia cuenta',
], 403);
}
$user->tokens()->delete();
$user->delete();
Log::info('Usuario eliminado', [
'admin_id' => $request->user()->id,
'user_id' => $id,
]);
return response()->json([
'success' => true,
'message' => 'Usuario eliminado correctamente',
]);
} catch (\Exception $e) {
Log::error('Error al eliminar usuario', ['error' => $e->getMessage()]);
return response()->json(['success' => false, 'message' => 'Error al eliminar usuario'], 500);
}
}
public function roles()
{
try {
$roles = Role::orderBy('name')->get(['id', 'name']);
return response()->json(['success' => true, 'data' => $roles]);
} catch (\Exception $e) {
return response()->json(['success' => false, 'message' => 'Error al obtener roles'], 500);
}
}
}