diff --git a/app/Http/Controllers/Dashboard/AtencionController.php b/app/Http/Controllers/Dashboard/AtencionController.php index 090b263..2274323 100644 --- a/app/Http/Controllers/Dashboard/AtencionController.php +++ b/app/Http/Controllers/Dashboard/AtencionController.php @@ -1,4 +1,6 @@ -only(['start', 'end', 'type', 'action']); - $input = array_merge(['action' => 'index', 'type' => 'api'], $query); + public function Atencion(Request $request) + { + $query = $request->only(['start', 'end', 'type', 'action']); + $input = array_merge(['action' => 'index', 'type' => 'api'], $query); - $startDate = $input['start'] ?? date('Y-01-01'); - $endDate = $input['end'] ?? date('Y-12-31'); + $startDate = $input['start'] ?? date('Y-01-01'); + $endDate = $input['end'] ?? date('Y-12-31'); - $baseParams = [ - 'start_date' => $startDate, - 'end_date' => $endDate, - 'type' => $input['type'] ?? 'api', - 'action' => $input['action'] ?? 'index', - ]; + $baseParams = [ + 'start_date' => $startDate, + 'end_date' => $endDate, + 'type' => $input['type'] ?? 'api', + 'action' => $input['action'] ?? 'index', + ]; - $baseUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/stats-by-date-range'; - $countsUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/counts-by-date'; + $baseUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/stats-by-date-range'; + $countsUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/counts-by-date'; + $dashboardUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/dashboard/api'; + $dashboardUrl2 = 'https://apoyos.comalcalco.gob.mx/beneficiaries/dashboard/api?type=servicio'; - try{ - $response = Http::get($baseUrl, $baseParams); + try { + $response = Http::get($baseUrl, $baseParams); - if(!$response->successful()){ - return response()->json(['error' => 'Error del servicio'], $response->status()); - } + if (!$response->successful()) { + return response()->json(['error' => 'Error del servicio'], $response->status()); + } - $mainData = $response->json(); - $countsAc = []; - try{ - $countsResp = Http::get($countsUrl, [ - 'start_date' => $startDate, - 'end_date' => $endDate, - ]); + $mainData = $response->json(); + $countsAc = []; + try { + $countsResp = Http::get($countsUrl, [ + 'start_date' => $startDate, + 'end_date' => $endDate, + ]); - if($countsResp->successful()){ - $countsAc = $countsResp->json(); - } else { - Log::error('Error al obtener los conteos de atención', ['status' => $countsResp->status()]); - } - }catch (\Exception $e) { - Log::error('Error al obtener los conteos de atención', ['exception' => $e->getMessage()]); - } - - $combinedData = array_merge( - is_array($mainData) ? $mainData : [], - [ - 'counts' => $countsAc, - ] - ); - return response()->json($combinedData, 200) - ->header('Content-Type', 'application/json'); - }catch (\Exception $e) { - Log::error('Error en la consulta de atención', ['exception' => $e->getMessage()]); - return response()->json(['error' => 'Error en la consulta de atención'], 500); + if ($countsResp->successful()) { + $countsAc = $countsResp->json(); + } else { + Log::error('Error al obtener los conteos de atención', ['status' => $countsResp->status()]); } + } catch (\Exception $e) { + Log::error('Error al obtener los conteos de atención', ['exception' => $e->getMessage()]); + } + + $dashboardData = []; + try { + $dashboardResp = Http::get($dashboardUrl); + + if ($dashboardResp->successful()) { + $dashboardData = $dashboardResp->json(); + } else { + Log::error('Error al obtener datos del dashboard', ['status' => $dashboardResp->status()]); + } + } catch (\Exception $e) { + Log::error('Error al obtener datos del dashboard', ['exception' => $e->getMessage()]); + } + + $dashboardServicioData = []; + try { + $dashboardResp2 = Http::get($dashboardUrl2); + + if ($dashboardResp2->successful()) { + $dashboardServicioData = $dashboardResp2->json(); + } else { + Log::error('Error al obtener datos del dashboard servicio', ['status' => $dashboardResp2->status()]); + } + } catch (\Exception $e) { + Log::error('Error al obtener datos del dashboard servicio', ['exception' => $e->getMessage()]); + } + + // Combina todos los resultados + $combinedData = array_merge( + is_array($mainData) ? $mainData : [], + [ + 'counts' => $countsAc, + 'dashboard' => $dashboardData, + 'dashboard_servicio' => $dashboardServicioData, + ] + ); + return response()->json($combinedData, 200) + ->header('Content-Type', 'application/json'); + } catch (\Exception $e) { + Log::error('Error en la consulta de atención', ['exception' => $e->getMessage()]); + return response()->json(['error' => 'Error en la consulta de atención'], 500); } + } + + public function getSupportOptions(Request $request) + { + try { + $typeId = $request->query('type_id'); + + if (!$typeId) { + return response()->json(['error' => 'type_id es requerido'], 400); + } + + $url = 'https://apoyos.comalcalco.gob.mx/beneficiaries/export/support-options'; + + $response = Http::timeout(30)->get($url, [ + 'type_id' => $typeId + ]); + + if (!$response->successful()) { + Log::error('Error al obtener opciones de apoyo', [ + 'status' => $response->status(), + 'body' => $response->body(), + 'type_id' => $typeId + ]); + + return response()->json([ + 'error' => 'Error al obtener opciones de apoyo' + ], $response->status()); + } + + return response()->json($response->json()); + } catch (\Exception $e) { + Log::error('Error en getSupportOptions', [ + 'exception' => $e->getMessage(), + 'type_id' => $request->query('type_id') + ]); + + return response()->json([ + 'error' => 'Error interno del servidor' + ], 500); + } + } + + public function exportExcel(Request $request) + { + try { + // CAMBIO: Usar los parámetros correctos que espera la API + $params = $request->only([ + 'start_date', + 'end_date', + 'type_id', + 'support_id' + ]); + + // Validaciones básicas + if (!$params['start_date'] || !$params['end_date']) { + return response()->json([ + 'error' => 'Las fechas son requeridas' + ], 400); + } + + if (!$params['type_id']) { + return response()->json([ + 'error' => 'El type_id es requerido' + ], 400); + } + + $url = 'https://apoyos.comalcalco.gob.mx/beneficiaries/export/excel'; + + // Log de parámetros para debug + Log::info('Exportando Excel con parámetros:', $params); + + // IMPORTANTE: Hacer la petición sin timeout muy alto y con withoutVerifying para SSL + $response = Http::withoutVerifying() + ->timeout(60) + ->get($url, $params); + + if (!$response->successful()) { + Log::error('Error al exportar Excel', [ + 'status' => $response->status(), + 'body' => $response->body(), + 'params' => $params + ]); + + return response()->json([ + 'error' => 'Error al generar el archivo Excel: ' . $response->body() + ], $response->status()); + } + + // CORREGIR: Verificar que la respuesta sea realmente un Excel + $contentType = $response->header('Content-Type'); + + if (!str_contains($contentType, 'spreadsheet') && !str_contains($contentType, 'excel')) { + Log::error('Respuesta no es un archivo Excel', [ + 'content_type' => $contentType, + 'body_preview' => substr($response->body(), 0, 200) + ]); + + return response()->json([ + 'error' => 'El servidor no devolvió un archivo Excel válido' + ], 400); + } + + // Retornar el archivo Excel directamente con headers correctos + return response($response->body(), 200, [ + 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'Content-Disposition' => 'attachment; filename="beneficiarios_' . + $params['start_date'] . '_' . $params['end_date'] . '.xlsx"', + 'Content-Length' => strlen($response->body()), + 'Cache-Control' => 'no-cache, no-store, must-revalidate', + 'Pragma' => 'no-cache', + 'Expires' => '0' + ]); + } catch (\Exception $e) { + Log::error('Error en exportExcel', [ + 'exception' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + 'params' => $request->all() + ]); + + return response()->json([ + 'error' => 'Error interno del servidor: ' . $e->getMessage() + ], 500); + } + } } diff --git a/colors.json.example b/colors.json.example index fd28bbe..d36ba7d 100644 --- a/colors.json.example +++ b/colors.json.example @@ -23,4 +23,4 @@ "danger-dark":"#EF4444", "info":"#3B82F6", "info-dark":"#3B82F6" -} \ No newline at end of file +} diff --git a/resources/css/app.css b/resources/css/app.css index e609f68..b0a29ba 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -18,12 +18,12 @@ @font-face { src: url(./google-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2'); } -/* Scrollbar */ +/* Scrollbar */ ::-webkit-scrollbar { width: 8px; height: 8px; } - + ::-webkit-scrollbar-thumb { background: #777777; border-radius: 4px; @@ -61,7 +61,7 @@ .btn-icon-secondary { } .header-icon { - @apply hover:text-yellow-500 focus:text-yellow-600 hover:scale-105 hover:transition hover:duration-300; + @apply hover:text-primary focus:text-primary hover:scale-105 hover:transition hover:duration-300; } .input-primary { diff --git a/resources/js/Components/Dashboard/Footer.vue b/resources/js/Components/Dashboard/Footer.vue new file mode 100644 index 0000000..0219b96 --- /dev/null +++ b/resources/js/Components/Dashboard/Footer.vue @@ -0,0 +1,125 @@ + diff --git a/resources/js/Components/Dashboard/Modal/ExportModal.vue b/resources/js/Components/Dashboard/Modal/ExportModal.vue new file mode 100644 index 0000000..732991e --- /dev/null +++ b/resources/js/Components/Dashboard/Modal/ExportModal.vue @@ -0,0 +1,387 @@ + + + diff --git a/resources/js/Layouts/AppLayout.vue b/resources/js/Layouts/AppLayout.vue new file mode 100644 index 0000000..567b164 --- /dev/null +++ b/resources/js/Layouts/AppLayout.vue @@ -0,0 +1,95 @@ + + + diff --git a/resources/js/Pages/App/AccesoRapido.vue b/resources/js/Pages/App/AccesoRapido.vue new file mode 100644 index 0000000..e63b29c --- /dev/null +++ b/resources/js/Pages/App/AccesoRapido.vue @@ -0,0 +1,145 @@ + + + diff --git a/resources/js/Pages/App/AtencionCiudadana.vue b/resources/js/Pages/App/AtencionCiudadana.vue new file mode 100644 index 0000000..668b9b8 --- /dev/null +++ b/resources/js/Pages/App/AtencionCiudadana.vue @@ -0,0 +1,984 @@ + + + diff --git a/resources/js/Pages/App/Obras.vue b/resources/js/Pages/App/Obras.vue new file mode 100644 index 0000000..f8df742 --- /dev/null +++ b/resources/js/Pages/App/Obras.vue @@ -0,0 +1,1373 @@ + + diff --git a/resources/js/Pages/App/Tramites.vue b/resources/js/Pages/App/Tramites.vue new file mode 100644 index 0000000..af110fc --- /dev/null +++ b/resources/js/Pages/App/Tramites.vue @@ -0,0 +1,584 @@ + + + diff --git a/resources/js/Pages/Dashboard/AtencionCiudadana.vue b/resources/js/Pages/Dashboard/AtencionCiudadana.vue deleted file mode 100644 index 67879d4..0000000 --- a/resources/js/Pages/Dashboard/AtencionCiudadana.vue +++ /dev/null @@ -1,406 +0,0 @@ - - - diff --git a/resources/js/Pages/Dashboard/Index.vue b/resources/js/Pages/Dashboard/Index.vue index bfc6dbd..b92c07d 100644 --- a/resources/js/Pages/Dashboard/Index.vue +++ b/resources/js/Pages/Dashboard/Index.vue @@ -1,173 +1,12 @@ diff --git a/resources/js/Pages/Dashboard/Obras.vue b/resources/js/Pages/Dashboard/Obras.vue deleted file mode 100644 index 29f287c..0000000 --- a/resources/js/Pages/Dashboard/Obras.vue +++ /dev/null @@ -1,1373 +0,0 @@ - - diff --git a/resources/js/Pages/Dashboard/Tramites.vue b/resources/js/Pages/Dashboard/Tramites.vue deleted file mode 100644 index e9b30a5..0000000 --- a/resources/js/Pages/Dashboard/Tramites.vue +++ /dev/null @@ -1,573 +0,0 @@ - - - diff --git a/routes/web.php b/routes/web.php index 1d7370a..5f4d8f1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,20 +1,35 @@ name('app.')->middleware([ + 'auth:sanctum', + 'verified', + config('jetstream.auth_session') + ])->group(function () { + Route::inertia('/tramites', 'App/Tramites')->name('tramites'); + Route::inertia('/obras', 'App/Obras')->name('obras'); + Route::inertia('/atencion', 'App/AtencionCiudadana')->name('atencion'); + Route::get('/api/support-options', [AtencionController::class, 'getSupportOptions']); + Route::get('/api/export-excel', [AtencionController::class, 'exportExcel']); +}); /** * Rutas del Dashboard @@ -30,10 +45,6 @@ Route::inertia('/changelogs', 'Dashboard/Changelogs')->name('changelogs'); Route::inertia('/help', 'Dashboard/Help')->name('help'); - Route::inertia('/api-tramite', 'Dashboard/Tramites')->name('api-tramite'); - Route::inertia('/api-obra', 'Dashboard/Obras')->name('api-obra'); - Route::inertia('/api-atencion', 'Dashboard/AtencionCiudadana')->name('api-atencion'); - # Log de Acciones Route::resource('histories', HistoryLogController::class)->only([ 'index',