Loading app/Http/Controllers/AuditoriaController.php +2 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ class AuditoriaController extends Controller */ public function index() { // $datos = Auditoria::with('contacto', 'user')->orderBy('id', 'desc')->get(); return view('adminGen.auditoria.index', compact('datos')); } /** Loading app/Http/Controllers/ContactoController.php +48 −33 Original line number Diff line number Diff line Loading @@ -227,8 +227,8 @@ public function update(Request $request, string $id) } // Guardar auditoría de teléfonos $telefonosAnteriores = $contacto->telefonos->toArray(); $telefonos = collect($request->input('prefijo'))->map(function($prefijo, $index) use ($request) { $telefonosAnteriores = collect($contacto->telefonos); $telefonosNuevos = collect($request->input('prefijo'))->map(function($prefijo, $index) use ($request) { return [ 'prefijo' => $prefijo, 'lada' => $request->input('lada')[$index], Loading @@ -239,15 +239,22 @@ public function update(Request $request, string $id) 'id_radio' => $request->input('id_radio')[$index], 'observaciones' => $request->input('observaciones')[$index], ]; })->toArray(); }); foreach ($telefonosAnteriores as $index => $telefonoAnterior) { foreach ($telefonoAnterior as $key => $value) { if (isset($telefonos[$index][$key]) && $value != $telefonos[$index][$key]) { // Unificar comparación entre teléfonos anteriores y nuevos $telefonosNuevos->each(function ($telefonoNuevo, $index) use ($telefonosAnteriores, &$changes, $contacto, $user) { // Asegurarse de que $telefonosAnteriores sea accesible y no usar get(), ya que es un array simple $telefonoAnterior = $telefonosAnteriores[$index] ?? []; // Si no hay un teléfono anterior en ese índice, usa un array vacío foreach ($telefonoNuevo as $key => $nuevoValor) { $valorAnterior = $telefonoAnterior[$key] ?? null; // Usa null si no existe el valor anterior // Solo registrar cambios si hay una diferencia if (strval($valorAnterior) !== $nuevoValor) { $changes[] = [ 'campo_editado' => "telefono_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $telefonos[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -255,24 +262,28 @@ public function update(Request $request, string $id) ]; } } } }); // Guardar auditoría de redes sociales $redesAnteriores = $contacto->redes->toArray(); $redes = collect($request->input('red_social'))->map(function($url, $index) use ($request) { $redesAnteriores = collect($contacto->redes); $redesNuevos = collect($request->input('red_social'))->map(function($url, $index) use ($request) { return [ 'red_social' => $url, 'tipo_red_social' => $request->input('tipo_red_social')[$index], ]; })->toArray(); }); $redesNuevos->each(function ($redNuevo, $index) use ($redesAnteriores, &$changes, $contacto, $user){ $redAnterior = $redesAnteriores->get($index, []); foreach ($redNuevo as $key => $nuevoValor){ $valorAnterior = $redAnterior[$key] ?? null; foreach ($redesAnteriores as $index => $redAnterior) { foreach ($redAnterior as $key => $value) { if (isset($redes[$index][$key]) && $value != $redes[$index][$key]) { if(strval($valorAnterior) !== $nuevoValor){ $changes[] = [ 'campo_editado' => "red_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $redes[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -280,24 +291,28 @@ public function update(Request $request, string $id) ]; } } } }); // Guardar auditoría de correos $correosAnteriores = $contacto->correos->toArray(); $correos = collect($request->input('correo_electronico'))->map(function($email, $index) use ($request) { $correosAnteriores = collect($contacto->correos); $correosNuevos = collect($request->input('correo_electronico'))->map(function($email, $index) use ($request) { return [ 'correo_electronico' => $email, 'tipo_correo_electronico' => $request->input('tipo_correo_electronico')[$index], ]; })->toArray(); }); $correosNuevos->each(function ($correoNuevo, $index) use ($correosAnteriores, &$changes, $contacto, $user){ $redAnterior = $correosAnteriores->get($index, []); foreach ($correosAnteriores as $index => $correoAnterior) { foreach ($correoAnterior as $key => $value) { if (isset($correos[$index][$key]) && $value != $correos[$index][$key]) { foreach ($correoNuevo as $key => $nuevoValor){ $valorAnterior = $redAnterior[$key] ?? null; if(strval($valorAnterior) !== $nuevoValor){ $changes[] = [ 'campo_editado' => "correo_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $correos[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -305,7 +320,7 @@ public function update(Request $request, string $id) ]; } } } }); if (!empty($changes)) { Auditoria::insert($changes); Loading Loading @@ -349,15 +364,15 @@ public function update(Request $request, string $id) // Guardar teléfonos $contacto->telefonos()->delete(); $contacto->telefonos()->createMany($telefonos); $contacto->telefonos()->createMany($telefonosNuevos->toArray()); // Guardar redes sociales $contacto->redes()->delete(); $contacto->redes()->createMany($redes); $contacto->redes()->createMany($redesNuevos->toArray()); // Guardar correos electrónicos $contacto->correos()->delete(); $contacto->correos()->createMany($correos); $contacto->correos()->createMany($correosNuevos->toArray()); return redirect()->route('contacto.get')->with('success', 'Contacto actualizado correctamente'); } Loading database/factories/AuditoriaFactory.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use App\Models\Auditoria; use App\Models\Contacto; use App\Models\User; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Auditoria> */ class AuditoriaFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ protected $model = Auditoria::class; public function definition(): array { return [ 'campo_editado' => $this->faker->word(), 'valor_anterior' => $this->faker->sentence(), 'nuevo_valor' => $this->faker->sentence(), 'contacto_id' => Contacto::inRandomOrder()->first()->id ?? null, 'user_id' => User::inRandomOrder()->first()->id ?? null, ]; } } database/seeders/AuditoriaSeeder.php 0 → 100644 +43 −0 Original line number Diff line number Diff line <?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use App\Models\Auditoria; class AuditoriaSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { $batchSize = 1000; // Número de registros por lote $totalRecords = 70000; $data = []; for ($i = 0; $i < $totalRecords; $i++) { $data[] = [ 'campo_editado' => fake()->word(), 'valor_anterior' => fake()->sentence(), 'nuevo_valor' => fake()->sentence(), 'contacto_id' => \App\Models\Contacto::inRandomOrder()->first()->id ?? null, 'user_id' => \App\Models\User::inRandomOrder()->first()->id ?? null, 'created_at' => now(), 'updated_at' => now(), ]; // Cuando se llega al tamaño del lote, insertamos y limpiamos el array if (count($data) === $batchSize) { \DB::table('auditorias')->insert($data); $data = []; } } // Inserta los registros restantes si hay if (!empty($data)) { \DB::table('auditorias')->insert($data); } } } resources/views/adminGen/auditoria/index.blade.php 0 → 100644 +106 −0 Original line number Diff line number Diff line <x-layout.default> <script src="/assets/js/simple-datatables.js"></script> <link rel="stylesheet" href="{{ Vite::asset('resources/css/swiper-bundle.min.css') }}"> <script src="/assets/js/swiper-bundle.min.js"></script> <div x-data="auditoria"> <ul class="flex space-x-2 rtl:space-x-reverse"> <li> <a href="javascript:;" class="text-primary hover:underline">Dashboard</a> </li> <li class="before:content-['/'] before:mr-1 rtl:before:ml-1"> <span>Auditoria</span> </li> </ul> <div class="panel mt-6"> <div class="flex items-center flex-wrap mb-5"> <a href="{{ route('listas.create') }}" type="button" class="btn btn-success btn-sm m-1"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10.5 14L17 14" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 14H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 10.5H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 17.5H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M10.5 10.5H17" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M10.5 17.5H17" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M8 3.5C8 2.67157 8.67157 2 9.5 2H14.5C15.3284 2 16 2.67157 16 3.5V4.5C16 5.32843 15.3284 6 14.5 6H9.5C8.67157 6 8 5.32843 8 4.5V3.5Z" stroke="#1C274C" stroke-width="1.5"/> <path d="M21 16.0002C21 18.8286 21 20.2429 20.1213 21.1215C19.2426 22.0002 17.8284 22.0002 15 22.0002H9C6.17157 22.0002 4.75736 22.0002 3.87868 21.1215C3 20.2429 3 18.8286 3 16.0002V13.0002M16 4.00195C18.175 4.01406 19.3529 4.11051 20.1213 4.87889C21 5.75757 21 7.17179 21 10.0002V12.0002M8 4.00195C5.82497 4.01406 4.64706 4.11051 3.87868 4.87889C3.11032 5.64725 3.01385 6.82511 3.00174 9" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> </svg> Crear nueva lista </a> </div> <table id="myTable" class="whitespace-nowrap table-hover"> <thead></thead> <tbody></tbody> </table> </div> </div> <link rel="stylesheet" href="{{ Vite::asset('resources/css/highlight.min.css') }}"> <script src="/assets/js/highlight.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <link rel="stylesheet" href="/assets/css/jquery.toast.css"> <script src="/assets/js/jquery.toast.js"></script> <script> const datos = @json($datos); const data = datos.map(dato => [dato.contacto.nombre + ' ' + dato.contacto.ap_paterno + ' ' + dato.contacto.ap_materno, dato.user.name, dato.updated_at, dato.campo_editado, dato.valor_anterior, dato.nuevo_valor]) document.addEventListener('DOMContentLoaded', () => { const datatable = new simpleDatatables.DataTable('#myTable', { data: { headings: ['Contacto', 'Usuario', 'Fecha', 'Campo', 'Valor Anterior', 'Nuevo Valor'], data: data }, perPage: 30, perPageSelect: [10, 20, 30, 50, 100], columns: [{ select: 0, sort: 'asc' }, ], firstLast: true, firstText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M13 19L7 12L13 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path opacity="0.5" d="M16.9998 19L10.9998 12L16.9998 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', lastText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M11 19L17 12L11 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path opacity="0.5" d="M6.99976 19L12.9998 12L6.99976 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', prevText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M15 5L9 12L15 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', nextText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M9 5L15 12L9 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', labels: { placeholder: "Buscar...", perPage: "{select}", noRows: "No hay filas para mostrar", info: "Mostrando {start} a {end} de {rows} filas", }, }); }); function showToast(message, heading, icon) { $.toast({ heading: heading, text: message, showHideTransition: 'slide', icon: icon, position: 'top-right', loader: false, hideAfter: 10000, allowToastClose: true, textColor: '#676767', }); } document.addEventListener('DOMContentLoaded', function() { @if(session('success')) // Muestra el mensaje de éxito utilizando showMessage showToast("{{ session('success') }}", 'Exito.', 'success') @endif @if($errors->any()) @foreach($errors->all() as $error) showToast(`{{ $error }}`, 'Error.', 'error'); @endforeach @endif }); </script> </x-layout.default> No newline at end of file Loading
app/Http/Controllers/AuditoriaController.php +2 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ class AuditoriaController extends Controller */ public function index() { // $datos = Auditoria::with('contacto', 'user')->orderBy('id', 'desc')->get(); return view('adminGen.auditoria.index', compact('datos')); } /** Loading
app/Http/Controllers/ContactoController.php +48 −33 Original line number Diff line number Diff line Loading @@ -227,8 +227,8 @@ public function update(Request $request, string $id) } // Guardar auditoría de teléfonos $telefonosAnteriores = $contacto->telefonos->toArray(); $telefonos = collect($request->input('prefijo'))->map(function($prefijo, $index) use ($request) { $telefonosAnteriores = collect($contacto->telefonos); $telefonosNuevos = collect($request->input('prefijo'))->map(function($prefijo, $index) use ($request) { return [ 'prefijo' => $prefijo, 'lada' => $request->input('lada')[$index], Loading @@ -239,15 +239,22 @@ public function update(Request $request, string $id) 'id_radio' => $request->input('id_radio')[$index], 'observaciones' => $request->input('observaciones')[$index], ]; })->toArray(); }); foreach ($telefonosAnteriores as $index => $telefonoAnterior) { foreach ($telefonoAnterior as $key => $value) { if (isset($telefonos[$index][$key]) && $value != $telefonos[$index][$key]) { // Unificar comparación entre teléfonos anteriores y nuevos $telefonosNuevos->each(function ($telefonoNuevo, $index) use ($telefonosAnteriores, &$changes, $contacto, $user) { // Asegurarse de que $telefonosAnteriores sea accesible y no usar get(), ya que es un array simple $telefonoAnterior = $telefonosAnteriores[$index] ?? []; // Si no hay un teléfono anterior en ese índice, usa un array vacío foreach ($telefonoNuevo as $key => $nuevoValor) { $valorAnterior = $telefonoAnterior[$key] ?? null; // Usa null si no existe el valor anterior // Solo registrar cambios si hay una diferencia if (strval($valorAnterior) !== $nuevoValor) { $changes[] = [ 'campo_editado' => "telefono_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $telefonos[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -255,24 +262,28 @@ public function update(Request $request, string $id) ]; } } } }); // Guardar auditoría de redes sociales $redesAnteriores = $contacto->redes->toArray(); $redes = collect($request->input('red_social'))->map(function($url, $index) use ($request) { $redesAnteriores = collect($contacto->redes); $redesNuevos = collect($request->input('red_social'))->map(function($url, $index) use ($request) { return [ 'red_social' => $url, 'tipo_red_social' => $request->input('tipo_red_social')[$index], ]; })->toArray(); }); $redesNuevos->each(function ($redNuevo, $index) use ($redesAnteriores, &$changes, $contacto, $user){ $redAnterior = $redesAnteriores->get($index, []); foreach ($redNuevo as $key => $nuevoValor){ $valorAnterior = $redAnterior[$key] ?? null; foreach ($redesAnteriores as $index => $redAnterior) { foreach ($redAnterior as $key => $value) { if (isset($redes[$index][$key]) && $value != $redes[$index][$key]) { if(strval($valorAnterior) !== $nuevoValor){ $changes[] = [ 'campo_editado' => "red_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $redes[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -280,24 +291,28 @@ public function update(Request $request, string $id) ]; } } } }); // Guardar auditoría de correos $correosAnteriores = $contacto->correos->toArray(); $correos = collect($request->input('correo_electronico'))->map(function($email, $index) use ($request) { $correosAnteriores = collect($contacto->correos); $correosNuevos = collect($request->input('correo_electronico'))->map(function($email, $index) use ($request) { return [ 'correo_electronico' => $email, 'tipo_correo_electronico' => $request->input('tipo_correo_electronico')[$index], ]; })->toArray(); }); $correosNuevos->each(function ($correoNuevo, $index) use ($correosAnteriores, &$changes, $contacto, $user){ $redAnterior = $correosAnteriores->get($index, []); foreach ($correosAnteriores as $index => $correoAnterior) { foreach ($correoAnterior as $key => $value) { if (isset($correos[$index][$key]) && $value != $correos[$index][$key]) { foreach ($correoNuevo as $key => $nuevoValor){ $valorAnterior = $redAnterior[$key] ?? null; if(strval($valorAnterior) !== $nuevoValor){ $changes[] = [ 'campo_editado' => "correo_{$index}_{$key}", 'valor_anterior' => $value, 'nuevo_valor' => $correos[$index][$key], 'valor_anterior' => $valorAnterior, 'nuevo_valor' => $nuevoValor, 'contacto_id' => $contacto->id, 'user_id' => $user->id, 'created_at' => now(), Loading @@ -305,7 +320,7 @@ public function update(Request $request, string $id) ]; } } } }); if (!empty($changes)) { Auditoria::insert($changes); Loading Loading @@ -349,15 +364,15 @@ public function update(Request $request, string $id) // Guardar teléfonos $contacto->telefonos()->delete(); $contacto->telefonos()->createMany($telefonos); $contacto->telefonos()->createMany($telefonosNuevos->toArray()); // Guardar redes sociales $contacto->redes()->delete(); $contacto->redes()->createMany($redes); $contacto->redes()->createMany($redesNuevos->toArray()); // Guardar correos electrónicos $contacto->correos()->delete(); $contacto->correos()->createMany($correos); $contacto->correos()->createMany($correosNuevos->toArray()); return redirect()->route('contacto.get')->with('success', 'Contacto actualizado correctamente'); } Loading
database/factories/AuditoriaFactory.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use App\Models\Auditoria; use App\Models\Contacto; use App\Models\User; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Auditoria> */ class AuditoriaFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ protected $model = Auditoria::class; public function definition(): array { return [ 'campo_editado' => $this->faker->word(), 'valor_anterior' => $this->faker->sentence(), 'nuevo_valor' => $this->faker->sentence(), 'contacto_id' => Contacto::inRandomOrder()->first()->id ?? null, 'user_id' => User::inRandomOrder()->first()->id ?? null, ]; } }
database/seeders/AuditoriaSeeder.php 0 → 100644 +43 −0 Original line number Diff line number Diff line <?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use App\Models\Auditoria; class AuditoriaSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { $batchSize = 1000; // Número de registros por lote $totalRecords = 70000; $data = []; for ($i = 0; $i < $totalRecords; $i++) { $data[] = [ 'campo_editado' => fake()->word(), 'valor_anterior' => fake()->sentence(), 'nuevo_valor' => fake()->sentence(), 'contacto_id' => \App\Models\Contacto::inRandomOrder()->first()->id ?? null, 'user_id' => \App\Models\User::inRandomOrder()->first()->id ?? null, 'created_at' => now(), 'updated_at' => now(), ]; // Cuando se llega al tamaño del lote, insertamos y limpiamos el array if (count($data) === $batchSize) { \DB::table('auditorias')->insert($data); $data = []; } } // Inserta los registros restantes si hay if (!empty($data)) { \DB::table('auditorias')->insert($data); } } }
resources/views/adminGen/auditoria/index.blade.php 0 → 100644 +106 −0 Original line number Diff line number Diff line <x-layout.default> <script src="/assets/js/simple-datatables.js"></script> <link rel="stylesheet" href="{{ Vite::asset('resources/css/swiper-bundle.min.css') }}"> <script src="/assets/js/swiper-bundle.min.js"></script> <div x-data="auditoria"> <ul class="flex space-x-2 rtl:space-x-reverse"> <li> <a href="javascript:;" class="text-primary hover:underline">Dashboard</a> </li> <li class="before:content-['/'] before:mr-1 rtl:before:ml-1"> <span>Auditoria</span> </li> </ul> <div class="panel mt-6"> <div class="flex items-center flex-wrap mb-5"> <a href="{{ route('listas.create') }}" type="button" class="btn btn-success btn-sm m-1"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10.5 14L17 14" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 14H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 10.5H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M7 17.5H7.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M10.5 10.5H17" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M10.5 17.5H17" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> <path d="M8 3.5C8 2.67157 8.67157 2 9.5 2H14.5C15.3284 2 16 2.67157 16 3.5V4.5C16 5.32843 15.3284 6 14.5 6H9.5C8.67157 6 8 5.32843 8 4.5V3.5Z" stroke="#1C274C" stroke-width="1.5"/> <path d="M21 16.0002C21 18.8286 21 20.2429 20.1213 21.1215C19.2426 22.0002 17.8284 22.0002 15 22.0002H9C6.17157 22.0002 4.75736 22.0002 3.87868 21.1215C3 20.2429 3 18.8286 3 16.0002V13.0002M16 4.00195C18.175 4.01406 19.3529 4.11051 20.1213 4.87889C21 5.75757 21 7.17179 21 10.0002V12.0002M8 4.00195C5.82497 4.01406 4.64706 4.11051 3.87868 4.87889C3.11032 5.64725 3.01385 6.82511 3.00174 9" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/> </svg> Crear nueva lista </a> </div> <table id="myTable" class="whitespace-nowrap table-hover"> <thead></thead> <tbody></tbody> </table> </div> </div> <link rel="stylesheet" href="{{ Vite::asset('resources/css/highlight.min.css') }}"> <script src="/assets/js/highlight.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <link rel="stylesheet" href="/assets/css/jquery.toast.css"> <script src="/assets/js/jquery.toast.js"></script> <script> const datos = @json($datos); const data = datos.map(dato => [dato.contacto.nombre + ' ' + dato.contacto.ap_paterno + ' ' + dato.contacto.ap_materno, dato.user.name, dato.updated_at, dato.campo_editado, dato.valor_anterior, dato.nuevo_valor]) document.addEventListener('DOMContentLoaded', () => { const datatable = new simpleDatatables.DataTable('#myTable', { data: { headings: ['Contacto', 'Usuario', 'Fecha', 'Campo', 'Valor Anterior', 'Nuevo Valor'], data: data }, perPage: 30, perPageSelect: [10, 20, 30, 50, 100], columns: [{ select: 0, sort: 'asc' }, ], firstLast: true, firstText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M13 19L7 12L13 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path opacity="0.5" d="M16.9998 19L10.9998 12L16.9998 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', lastText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M11 19L17 12L11 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path opacity="0.5" d="M6.99976 19L12.9998 12L6.99976 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', prevText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M15 5L9 12L15 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', nextText: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4.5 h-4.5 rtl:rotate-180"><path d="M9 5L15 12L9 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>', labels: { placeholder: "Buscar...", perPage: "{select}", noRows: "No hay filas para mostrar", info: "Mostrando {start} a {end} de {rows} filas", }, }); }); function showToast(message, heading, icon) { $.toast({ heading: heading, text: message, showHideTransition: 'slide', icon: icon, position: 'top-right', loader: false, hideAfter: 10000, allowToastClose: true, textColor: '#676767', }); } document.addEventListener('DOMContentLoaded', function() { @if(session('success')) // Muestra el mensaje de éxito utilizando showMessage showToast("{{ session('success') }}", 'Exito.', 'success') @endif @if($errors->any()) @foreach($errors->all() as $error) showToast(`{{ $error }}`, 'Error.', 'error'); @endforeach @endif }); </script> </x-layout.default> No newline at end of file