new fiture export reports to pdf
This commit is contained in:
parent
24c4212b2f
commit
bcfecf4b79
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class ExportReportController extends Controller
|
||||||
|
{
|
||||||
|
public function exportPdf(Request $request)
|
||||||
|
{
|
||||||
|
// Validasi request
|
||||||
|
$request->validate([
|
||||||
|
'startDate' => 'required|date',
|
||||||
|
'endDate' => 'required|date|after_or_equal:startDate',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Ambil parameter
|
||||||
|
$startDate = $request->startDate;
|
||||||
|
$endDate = $request->endDate;
|
||||||
|
|
||||||
|
Log::info('Export PDF with date range', [
|
||||||
|
'startDate' => $startDate,
|
||||||
|
'endDate' => $endDate
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Tambahkan 1 hari ke endDate untuk query "sampai dengan" yang benar
|
||||||
|
// Ensure the end date is included by adding one day
|
||||||
|
$endDateForQuery = Carbon::parse($endDate)->addDay()->format('Y-m-d');
|
||||||
|
|
||||||
|
Log::info('Actual date range for query', [
|
||||||
|
'startDate' => $startDate,
|
||||||
|
'endDateForQuery' => $endDateForQuery
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Ambil data report dari file JSON
|
||||||
|
$jsonPath = storage_path('app/reports.json');
|
||||||
|
$reports = [];
|
||||||
|
|
||||||
|
if (File::exists($jsonPath)) {
|
||||||
|
Log::info('JSON file exists: ' . $jsonPath);
|
||||||
|
$jsonContent = File::get($jsonPath);
|
||||||
|
$jsonData = json_decode($jsonContent, true);
|
||||||
|
|
||||||
|
if ($jsonData) {
|
||||||
|
Log::info('JSON data loaded successfully, count: ' . count($jsonData));
|
||||||
|
|
||||||
|
// Debug: Show a few timestamps from the data
|
||||||
|
$sampleTimestamps = array_slice(array_column($jsonData, 'timestamp'), 0, 5);
|
||||||
|
Log::info('Sample timestamps', ['samples' => $sampleTimestamps]);
|
||||||
|
|
||||||
|
// Debug: Check for reports on the specific date (24th)
|
||||||
|
$date24th = substr($endDate, 0, 8) . '24'; // Assuming format YYYY-MM-DD
|
||||||
|
$reportsOn24th = array_filter($jsonData, function($report) use ($date24th) {
|
||||||
|
return isset($report['timestamp']) && substr($report['timestamp'], 0, 10) === $date24th;
|
||||||
|
});
|
||||||
|
Log::info('Reports on the 24th', [
|
||||||
|
'date24th' => $date24th,
|
||||||
|
'count' => count($reportsOn24th),
|
||||||
|
'samples' => array_slice(array_column($reportsOn24th, 'timestamp'), 0, 3)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Filter berdasarkan range tanggal
|
||||||
|
$filteredReports = array_filter($jsonData, function($report) use ($startDate, $endDateForQuery, $endDate) {
|
||||||
|
if (!isset($report['timestamp'])) {
|
||||||
|
Log::warning('Report missing timestamp', ['report' => json_encode($report)]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reportTimestamp = $report['timestamp'];
|
||||||
|
$reportDate = substr($reportTimestamp, 0, 10); // Ambil bagian YYYY-MM-DD saja
|
||||||
|
|
||||||
|
// Log date comparison for debugging
|
||||||
|
Log::info('Date comparison', [
|
||||||
|
'reportTimestamp' => $reportTimestamp,
|
||||||
|
'reportDate' => $reportDate,
|
||||||
|
'startDate' => $startDate,
|
||||||
|
'endDateForQuery' => $endDateForQuery,
|
||||||
|
'isAfterStart' => $reportDate >= $startDate,
|
||||||
|
'isBeforeEnd' => $reportDate <= $endDate // Compare with original endDate for inclusive
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Use inclusive comparison for the end date (≤ instead of <)
|
||||||
|
// With endDateForQuery being endDate + 1 day, proper check is: reportDate < endDateForQuery
|
||||||
|
$isInRange = $reportDate >= $startDate && $reportDate < $endDateForQuery;
|
||||||
|
|
||||||
|
// Explicitly check for the end date to make sure it's included
|
||||||
|
if (substr($endDate, 0, 10) === $reportDate) {
|
||||||
|
Log::info('Found report on end date', ['timestamp' => $reportTimestamp]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $isInRange;
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::info('Filtered reports count: ' . count($filteredReports));
|
||||||
|
|
||||||
|
// Urutkan data berdasarkan timestamp (terbaru dulu)
|
||||||
|
usort($filteredReports, function($a, $b) {
|
||||||
|
$timeA = strtotime($a['timestamp']);
|
||||||
|
$timeB = strtotime($b['timestamp']);
|
||||||
|
return $timeB - $timeA; // Descending order
|
||||||
|
});
|
||||||
|
|
||||||
|
$reports = array_values($filteredReports); // Reset array keys
|
||||||
|
Log::info('Final reports count: ' . count($reports));
|
||||||
|
} else {
|
||||||
|
Log::error('Failed to decode JSON data', [
|
||||||
|
'fileSize' => strlen($jsonContent),
|
||||||
|
'jsonError' => json_last_error_msg()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log::error('JSON file not found: ' . $jsonPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preparation data untuk PDF
|
||||||
|
$data = [
|
||||||
|
'title' => 'Laporan Keamanan dan Monitoring',
|
||||||
|
'date' => date('d/m/Y'),
|
||||||
|
'startDate' => Carbon::parse($startDate)->format('d/m/Y'),
|
||||||
|
'endDate' => Carbon::parse($endDate)->format('d/m/Y'),
|
||||||
|
'reports' => $reports,
|
||||||
|
'totalReports' => count($reports),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Generate PDF
|
||||||
|
$pdf = Pdf::loadView('export.reports-pdf', $data);
|
||||||
|
|
||||||
|
// Set paper dan orientasi
|
||||||
|
$pdf->setPaper('a4', 'landscape');
|
||||||
|
|
||||||
|
// Download PDF dengan nama file yang berisi range tanggal
|
||||||
|
return $pdf->download('laporan_' . $startDate . '_sampai_' . $endDate . '.pdf');
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
|
"barryvdh/laravel-dompdf": "^3.1",
|
||||||
"google/cloud-firestore": "^1.48",
|
"google/cloud-firestore": "^1.48",
|
||||||
"guzzlehttp/guzzle": "^7.2",
|
"guzzlehttp/guzzle": "^7.2",
|
||||||
"kreait/firebase-php": "^7.16",
|
"kreait/firebase-php": "^7.16",
|
||||||
|
|
|
@ -4,8 +4,85 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "89ca0d9e8053ae1653b307f8756de6a9",
|
"content-hash": "160c4326c82eeb41dedfb2730b633aa5",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "barryvdh/laravel-dompdf",
|
||||||
|
"version": "v3.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/barryvdh/laravel-dompdf.git",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/dompdf": "^3.0",
|
||||||
|
"illuminate/support": "^9|^10|^11|^12",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"larastan/larastan": "^2.7|^3.0",
|
||||||
|
"orchestra/testbench": "^7|^8|^9|^10",
|
||||||
|
"phpro/grumphp": "^2.5",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"PDF": "Barryvdh\\DomPDF\\Facade\\Pdf",
|
||||||
|
"Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Barryvdh\\DomPDF\\ServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Barryvdh\\DomPDF\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Barry vd. Heuvel",
|
||||||
|
"email": "barryvdh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A DOMPDF Wrapper for Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"dompdf",
|
||||||
|
"laravel",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/barryvdh/laravel-dompdf/issues",
|
||||||
|
"source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.1.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://fruitcake.nl",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/barryvdh",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-13T15:07:54+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "beste/clock",
|
"name": "beste/clock",
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
@ -580,6 +657,161 @@
|
||||||
],
|
],
|
||||||
"time": "2024-02-05T11:56:58+00:00"
|
"time": "2024-02-05T11:56:58+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/dompdf",
|
||||||
|
"version": "v3.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/dompdf.git",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/php-font-lib": "^1.0.0",
|
||||||
|
"dompdf/php-svg-lib": "^1.0.0",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"masterminds/html5": "^2.0",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"mockery/mockery": "^1.3",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
|
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-gd": "Needed to process images",
|
||||||
|
"ext-gmagick": "Improves image processing performance",
|
||||||
|
"ext-imagick": "Improves image processing performance",
|
||||||
|
"ext-zlib": "Needed for pdf stream compression"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Dompdf\\": "src/"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"lib/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The Dompdf Community",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||||
|
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-01-15T14:09:04+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-font-lib",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"FontLib\\": "src/FontLib"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The FontLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
|
||||||
|
},
|
||||||
|
"time": "2024-12-02T14:37:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-svg-lib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0",
|
||||||
|
"sabberworm/php-css-parser": "^8.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Svg\\": "src/Svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The SvgLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse and export to PDF SVG files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
|
||||||
|
},
|
||||||
|
"time": "2024-04-29T13:26:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dragonmantank/cron-expression",
|
"name": "dragonmantank/cron-expression",
|
||||||
"version": "v3.4.0",
|
"version": "v3.4.0",
|
||||||
|
@ -3068,6 +3300,73 @@
|
||||||
],
|
],
|
||||||
"time": "2024-09-21T08:32:55+00:00"
|
"time": "2024-09-21T08:32:55+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "masterminds/html5",
|
||||||
|
"version": "2.9.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Masterminds/html5-php.git",
|
||||||
|
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
|
||||||
|
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-dom": "*",
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.7-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Masterminds\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Matt Butcher",
|
||||||
|
"email": "technosophos@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Matt Farina",
|
||||||
|
"email": "matt@mattfarina.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Asmir Mustafic",
|
||||||
|
"email": "goetas@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "An HTML5 parser and serializer.",
|
||||||
|
"homepage": "http://masterminds.github.io/html5-php",
|
||||||
|
"keywords": [
|
||||||
|
"HTML5",
|
||||||
|
"dom",
|
||||||
|
"html",
|
||||||
|
"parser",
|
||||||
|
"querypath",
|
||||||
|
"serializer",
|
||||||
|
"xml"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||||
|
"source": "https://github.com/Masterminds/html5-php/tree/2.9.0"
|
||||||
|
},
|
||||||
|
"time": "2024-03-31T07:05:07+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.8.1",
|
"version": "3.8.1",
|
||||||
|
@ -4539,6 +4838,71 @@
|
||||||
],
|
],
|
||||||
"time": "2024-11-27T12:13:42+00:00"
|
"time": "2024-11-27T12:13:42+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "sabberworm/php-css-parser",
|
||||||
|
"version": "v8.8.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||||
|
"reference": "3de493bdddfd1f051249af725c7e0d2c38fed740"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/3de493bdddfd1f051249af725c7e0d2c38fed740",
|
||||||
|
"reference": "3de493bdddfd1f051249af725c7e0d2c38fed740",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "9.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Sabberworm\\CSS\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Raphael Schweikert"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Oliver Klee",
|
||||||
|
"email": "github@oliverklee.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jake Hotson",
|
||||||
|
"email": "jake.github@qzdesign.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Parser for CSS Files written in PHP",
|
||||||
|
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||||
|
"keywords": [
|
||||||
|
"css",
|
||||||
|
"parser",
|
||||||
|
"stylesheet"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||||
|
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.8.0"
|
||||||
|
},
|
||||||
|
"time": "2025-03-23T17:59:05+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/cache",
|
"name": "symfony/cache",
|
||||||
"version": "v7.2.3",
|
"version": "v7.2.3",
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>{{ $title }}</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.date-range {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
.page-number {
|
||||||
|
text-align: right;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 9px;
|
||||||
|
margin-right: 3px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.badge-motion { background-color: #fef9c3; }
|
||||||
|
.badge-status { background-color: #fee2e2; }
|
||||||
|
.badge-fan { background-color: #dcfce7; }
|
||||||
|
.badge-servo-status { background-color: #cffafe; }
|
||||||
|
.badge-last-access { background-color: #ede9fe; }
|
||||||
|
.badge-restart-esp { background-color: #ffedd5; }
|
||||||
|
.badge-restart-wemos { background-color: #fef3c7; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">{{ $title }}</div>
|
||||||
|
<div class="subtitle">Laporan Keamanan dan Monitoring System</div>
|
||||||
|
<div class="date-range">Periode: {{ $startDate }} - {{ $endDate }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="3%">No</th>
|
||||||
|
<th width="15%">Tanggal</th>
|
||||||
|
<th width="20%">Perubahan</th>
|
||||||
|
<th width="32%">Status Keamanan</th>
|
||||||
|
<th width="30%">Status Perangkat</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if(count($reports) > 0)
|
||||||
|
@foreach($reports as $index => $report)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $index + 1 }}</td>
|
||||||
|
<td>{{ date('d/m/Y H:i', strtotime($report['timestamp'])) }}</td>
|
||||||
|
<td>
|
||||||
|
@php
|
||||||
|
$changes = [];
|
||||||
|
// Detect changes based on your logic
|
||||||
|
// This is a simplified example
|
||||||
|
if(isset($report['security']['motion'])) {
|
||||||
|
$changes[] = ['type' => 'Motion', 'badge' => 'badge-motion'];
|
||||||
|
}
|
||||||
|
if(isset($report['security']['status'])) {
|
||||||
|
$changes[] = ['type' => 'Status', 'badge' => 'badge-status'];
|
||||||
|
}
|
||||||
|
if(isset($report['security']['fan'])) {
|
||||||
|
$changes[] = ['type' => 'Fan', 'badge' => 'badge-fan'];
|
||||||
|
}
|
||||||
|
if(isset($report['smartcab']['servo_status'])) {
|
||||||
|
$changes[] = ['type' => 'Servo', 'badge' => 'badge-servo-status'];
|
||||||
|
}
|
||||||
|
// Add more change types as needed
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@foreach($changes as $change)
|
||||||
|
<span class="badge {{ $change['badge'] }}">{{ $change['type'] }}</span>
|
||||||
|
@endforeach
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@if(isset($report['security']))
|
||||||
|
<div>Gerakan: {{ ucfirst($report['security']['motion'] ?? 'N/A') }}</div>
|
||||||
|
<div>Status: {{ ucfirst($report['security']['status'] ?? 'N/A') }}</div>
|
||||||
|
<div>Fan: {{ $report['security']['fan'] ?? 'N/A' }}</div>
|
||||||
|
@else
|
||||||
|
N/A
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@if(isset($report['smartcab']))
|
||||||
|
<div>Servo: {{ $report['smartcab']['servo_status'] ?? 'N/A' }}</div>
|
||||||
|
<div>Last Access: {{ $report['smartcab']['last_access'] ?? 'N/A' }}</div>
|
||||||
|
@endif
|
||||||
|
@if(isset($report['dht11']))
|
||||||
|
<div>Suhu: {{ $report['dht11']['temperature'] ?? 'N/A' }}°C</div>
|
||||||
|
<div>Kelembaban: {{ $report['dht11']['humidity'] ?? 'N/A' }}%</div>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" style="text-align: center">Tidak ada data laporan untuk periode yang dipilih</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p>Total laporan: {{ $totalReports }}</p>
|
||||||
|
<p>Dicetak pada: {{ date('d/m/Y H:i:s') }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/php">
|
||||||
|
if (isset($pdf)) {
|
||||||
|
$text = "Halaman {PAGE_NUM} dari {PAGE_COUNT}";
|
||||||
|
$size = 10;
|
||||||
|
$font = $fontMetrics->getFont("Arial");
|
||||||
|
$width = $fontMetrics->get_text_width($text, $font, $size) / 2;
|
||||||
|
$x = ($pdf->get_width() - $width) / 2;
|
||||||
|
$y = $pdf->get_height() - 35;
|
||||||
|
$pdf->page_text($x, $y, $text, $font, $size);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -57,12 +57,20 @@
|
||||||
<div class="container mx-auto px-4 py-8">
|
<div class="container mx-auto px-4 py-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h2 class="text-2xl font-bold text-gray-800">Laporan Keamanan dan Monitoring</h2>
|
<h2 class="text-2xl font-bold text-gray-800">Laporan Keamanan dan Monitoring</h2>
|
||||||
<a href="{{route('welcome')}}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300">
|
<div class="flex gap-2">
|
||||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<button id="exportBtn" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700 focus:ring-4 focus:outline-none focus:ring-green-300">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
</svg>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
|
||||||
Kembali ke Dashboard
|
</svg>
|
||||||
</a>
|
Export Laporan
|
||||||
|
</button>
|
||||||
|
<a href="{{route('welcome')}}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300">
|
||||||
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
|
||||||
|
</svg>
|
||||||
|
Kembali ke Dashboard
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dashboard Overview - Single Comprehensive Chart -->
|
<!-- Dashboard Overview - Single Comprehensive Chart -->
|
||||||
|
@ -308,6 +316,61 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal Export Laporan -->
|
||||||
|
<div id="exportModal" tabindex="-1" aria-hidden="true" class="fixed top-0 left-0 right-0 z-50 hidden w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] max-h-full">
|
||||||
|
<div class="relative w-full max-w-md max-h-full">
|
||||||
|
<div class="relative bg-white rounded-lg shadow">
|
||||||
|
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t">
|
||||||
|
<h3 class="text-xl font-medium text-gray-900">
|
||||||
|
Export Laporan ke PDF
|
||||||
|
</h3>
|
||||||
|
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center" data-modal-hide="exportModal">
|
||||||
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Close modal</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="p-4 md:p-5 space-y-4">
|
||||||
|
<form id="exportForm" action="/export-reports" method="get">
|
||||||
|
@csrf
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="startDate" class="block mb-2 text-sm font-medium text-gray-700">Tanggal Mulai</label>
|
||||||
|
<div class="relative">
|
||||||
|
<div class="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
|
||||||
|
<svg class="w-4 h-4 text-gray-500" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M20 4a2 2 0 0 0-2-2h-2V1a1 1 0 0 0-2 0v1h-3V1a1 1 0 0 0-2 0v1H6V1a1 1 0 0 0-2 0v1H2a2 2 0 0 0-2 2v2.586a1 1 0 0 0 .293.707l-6.414 6.414a1 1 0 0 1-.293.707V17l-4 4v-6.586a1 1 0 0 1-.293-.707L3.293 7.293A1 1 0 0 0 3 6.586V4z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<input type="date" id="startDate" name="startDate" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="endDate" class="block mb-2 text-sm font-medium text-gray-700">Tanggal Akhir</label>
|
||||||
|
<div class="relative">
|
||||||
|
<div class="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
|
||||||
|
<svg class="w-4 h-4 text-gray-500" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M20 4a2 2 0 0 0-2-2h-2V1a1 1 0 0 0-2 0v1h-3V1a1 1 0 0 0-2 0v1H6V1a1 1 0 0 0-2 0v1H2a2 2 0 0 0-2 2v2.586a1 1 0 0 0 .293.707l-6.414 6.414a1 1 0 0 1-.293.707V17l-4 4v-6.586a1 1 0 0 1-.293-.707L3.293 7.293A1 1 0 0 0 3 6.586V4z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<input type="date" id="endDate" name="endDate" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end space-x-2 pt-4 border-t">
|
||||||
|
<button type="button" data-modal-hide="exportModal" class="py-2.5 px-5 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200">
|
||||||
|
Batal
|
||||||
|
</button>
|
||||||
|
<button type="submit" id="startExport" class="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5">
|
||||||
|
Export PDF
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Template untuk tabel reports -->
|
<!-- Template untuk tabel reports -->
|
||||||
<template id="reports-template">
|
<template id="reports-template">
|
||||||
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
|
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
|
||||||
|
@ -1473,6 +1536,70 @@ function updateChartFilterStatus() {
|
||||||
chartFilterBadge.classList.add('hidden');
|
chartFilterBadge.classList.add('hidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup untuk export button
|
||||||
|
document.getElementById('exportBtn').addEventListener('click', function() {
|
||||||
|
// Set tanggal default untuk export (7 hari terakhir)
|
||||||
|
const today = new Date();
|
||||||
|
const weekAgo = new Date();
|
||||||
|
weekAgo.setDate(weekAgo.getDate() - 7);
|
||||||
|
|
||||||
|
document.getElementById('endDate').value = today.toISOString().split('T')[0];
|
||||||
|
document.getElementById('startDate').value = weekAgo.toISOString().split('T')[0];
|
||||||
|
|
||||||
|
// Buka modal export
|
||||||
|
const modalElement = document.getElementById('exportModal');
|
||||||
|
const modalOptions = {
|
||||||
|
placement: 'center',
|
||||||
|
backdrop: 'dynamic',
|
||||||
|
backdropClasses: 'bg-gray-900/50 fixed inset-0 z-40',
|
||||||
|
closable: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const modal = new Modal(modalElement, modalOptions);
|
||||||
|
modal.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle export form submission
|
||||||
|
document.getElementById('exportForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const startDate = document.getElementById('startDate').value;
|
||||||
|
const endDate = document.getElementById('endDate').value;
|
||||||
|
|
||||||
|
// Validasi tanggal
|
||||||
|
if (new Date(startDate) > new Date(endDate)) {
|
||||||
|
alert('Tanggal mulai tidak boleh lebih besar dari tanggal akhir');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buat URL untuk export
|
||||||
|
let exportUrl = `/export-reports?startDate=${startDate}&endDate=${endDate}`;
|
||||||
|
|
||||||
|
// Tambahkan loading indicator
|
||||||
|
const submitBtn = document.getElementById('startExport');
|
||||||
|
const originalText = submitBtn.innerHTML;
|
||||||
|
submitBtn.innerHTML = `
|
||||||
|
<svg class="inline w-4 h-4 me-2 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||||
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||||
|
</svg>
|
||||||
|
Memproses...
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Mulai proses export dengan mengakses URL dalam window baru
|
||||||
|
window.open(exportUrl, '_blank');
|
||||||
|
|
||||||
|
// Kembalikan tombol ke kondisi semula setelah 1.5 detik
|
||||||
|
setTimeout(() => {
|
||||||
|
submitBtn.innerHTML = originalText;
|
||||||
|
|
||||||
|
// Tutup modal
|
||||||
|
const modalElement = document.getElementById('exportModal');
|
||||||
|
const modal = Modal.getInstance(modalElement);
|
||||||
|
modal.hide();
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use App\Http\Controllers\Auth\FirebaseAuthController;
|
use App\Http\Controllers\Auth\FirebaseAuthController;
|
||||||
use App\Http\Controllers\AIChatController;
|
use App\Http\Controllers\AIChatController;
|
||||||
|
use App\Http\Controllers\ExportReportController;
|
||||||
use App\Http\Controllers\WelcomeController;
|
use App\Http\Controllers\WelcomeController;
|
||||||
use App\Http\Controllers\ProfileController;
|
use App\Http\Controllers\ProfileController;
|
||||||
use App\Http\Controllers\ReportController;
|
use App\Http\Controllers\ReportController;
|
||||||
|
use App\Http\Controllers\ReportExportController;
|
||||||
|
|
||||||
Route::get('/login', [FirebaseAuthController::class, 'showLogin'])
|
Route::get('/login', [FirebaseAuthController::class, 'showLogin'])
|
||||||
->name('login')
|
->name('login')
|
||||||
|
@ -35,4 +37,5 @@
|
||||||
|
|
||||||
Route::get('/profile', [ProfileController::class, 'index'])->name('profile');
|
Route::get('/profile', [ProfileController::class, 'index'])->name('profile');
|
||||||
Route::post('/profile/update', [ProfileController::class, 'update'])->name('profile.update');
|
Route::post('/profile/update', [ProfileController::class, 'update'])->name('profile.update');
|
||||||
Route::get('/reports', [ReportController::class, 'index'])->name('reports');
|
Route::get('/reports', [ReportController::class, 'index'])->name('reports');
|
||||||
|
Route::get('/export-reports', [ExportReportController::class, 'exportPdf']);
|
Loading…
Reference in New Issue