station data fetch successfully
This commit is contained in:
parent
9e5a466a5b
commit
9809ef792a
|
@ -4,11 +4,75 @@ namespace App\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class ReportsController extends Controller
|
||||
{
|
||||
protected $apiBaseUrl = 'http://192.168.100.6:8081/api/';
|
||||
protected $apiBaseUrl;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiBaseUrl = env('EXTERNAL_API_URL', 'http://localhost:8081/api/');
|
||||
}
|
||||
|
||||
private function makeApiRequest($endpoint, $params)
|
||||
{
|
||||
try {
|
||||
$user = Session::get('user');
|
||||
$accessToken = $user['access_token'] ?? null;
|
||||
|
||||
if (!$accessToken) {
|
||||
Log::info("No access token found, redirecting to login from {$endpoint}");
|
||||
return redirect()->route('login')->with('error', 'Please log in to view reports.');
|
||||
}
|
||||
|
||||
// Ensure proper URL formation
|
||||
$baseUrl = rtrim($this->apiBaseUrl, '/');
|
||||
$endpoint = ltrim($endpoint, '/');
|
||||
$fullUrl = "{$baseUrl}/{$endpoint}";
|
||||
|
||||
Log::info("Making API request to: {$fullUrl}", ['params' => $params]);
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
])->timeout(30)->get($fullUrl, $params);
|
||||
|
||||
Log::info("API response status: {$response->status()}", [
|
||||
'endpoint' => $endpoint,
|
||||
'response_body' => $response->body(),
|
||||
'headers' => $response->headers()
|
||||
]);
|
||||
|
||||
if ($response->status() === 401 || $response->status() === 403) {
|
||||
Log::warning("Unauthorized or Forbidden API response for {$endpoint}", ['response' => $response->json()]);
|
||||
return redirect()->route('login')->with('error', 'Your session has expired. Please log in again.');
|
||||
}
|
||||
|
||||
if (!$response->successful()) {
|
||||
Log::error("API request failed for {$endpoint}", [
|
||||
'status' => $response->status(),
|
||||
'response' => $response->body(),
|
||||
'headers' => $response->headers()
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response->json();
|
||||
} catch (\Illuminate\Http\Client\ConnectionException $e) {
|
||||
Log::error("Connection error during API request to {$endpoint}", [
|
||||
'error' => $e->getMessage(),
|
||||
'params' => $params
|
||||
]);
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Unexpected error during API request to {$endpoint}", [
|
||||
'error' => $e->getMessage(),
|
||||
'params' => $params
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public function mobileUsage(Request $request)
|
||||
{
|
||||
$params = [
|
||||
|
@ -17,17 +81,22 @@ class ReportsController extends Controller
|
|||
'date_start' => $request->input('date_start'),
|
||||
'date_end' => $request->input('date_end'),
|
||||
'sorting' => $request->input('sort', 'date|desc'),
|
||||
'_search' => $request->input('_search'),
|
||||
];
|
||||
|
||||
$response = Http::get($this->apiBaseUrl . 'cms/reportMobileUsage', $params);
|
||||
$data = $response->json();
|
||||
$data = $this->makeApiRequest('cms/reportMobileUsage', $params);
|
||||
|
||||
if (is_a($data, '\Illuminate\Http\RedirectResponse')) {
|
||||
return $data; // Redirect to login if unauthorized
|
||||
}
|
||||
|
||||
$mobileUsageData = [];
|
||||
$currentPage = $params['page'];
|
||||
$lastPage = 1;
|
||||
$total = 0;
|
||||
$errorMessage = null;
|
||||
|
||||
if ($response->successful() && isset($data['data'])) {
|
||||
if ($data && isset($data['data'])) {
|
||||
$mobileUsageData = array_map(function ($item) {
|
||||
return [
|
||||
'id' => $item['id'] ?? uniqid(),
|
||||
|
@ -40,9 +109,15 @@ class ReportsController extends Controller
|
|||
$currentPage = $data['meta']['current_page'] ?? 1;
|
||||
$lastPage = $data['meta']['last_page'] ?? 1;
|
||||
$total = $data['meta']['total'] ?? count($mobileUsageData);
|
||||
} elseif ($data && isset($data['message'])) {
|
||||
Log::info("API returned message for mobileUsage", ['message' => $data['message']]);
|
||||
$errorMessage = $data['message'];
|
||||
} else {
|
||||
Log::warning("No data returned or invalid response structure for mobileUsage", ['data' => $data]);
|
||||
$errorMessage = 'Failed to fetch mobile usage data.';
|
||||
}
|
||||
|
||||
return view('pages.reports.mobile-usage-report', compact('mobileUsageData', 'currentPage', 'lastPage', 'total'));
|
||||
return view('pages.reports.mobile-usage-report', compact('mobileUsageData', 'currentPage', 'lastPage', 'total', 'errorMessage'));
|
||||
}
|
||||
|
||||
public function registration(Request $request)
|
||||
|
@ -53,17 +128,22 @@ class ReportsController extends Controller
|
|||
'date_start' => $request->input('date_start'),
|
||||
'date_end' => $request->input('date_end'),
|
||||
'sorting' => $request->input('sort', 'date|desc'),
|
||||
'_search' => $request->input('_search'),
|
||||
];
|
||||
|
||||
$response = Http::get($this->apiBaseUrl . 'cms/reportRegistration', $params);
|
||||
$data = $response->json();
|
||||
$data = $this->makeApiRequest('cms/reportRegistration', $params);
|
||||
|
||||
if (is_a($data, '\Illuminate\Http\RedirectResponse')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$registrationData = [];
|
||||
$currentPage = $params['page'];
|
||||
$lastPage = 1;
|
||||
$total = 0;
|
||||
$errorMessage = null;
|
||||
|
||||
if ($response->successful() && isset($data['data'])) {
|
||||
if ($data && isset($data['data'])) {
|
||||
$registrationData = array_map(function ($item) {
|
||||
return [
|
||||
'id' => $item['id'] ?? uniqid(),
|
||||
|
@ -75,9 +155,15 @@ class ReportsController extends Controller
|
|||
$currentPage = $data['meta']['current_page'] ?? 1;
|
||||
$lastPage = $data['meta']['last_page'] ?? 1;
|
||||
$total = $data['meta']['total'] ?? count($registrationData);
|
||||
} elseif ($data && isset($data['message'])) {
|
||||
Log::info("API returned message for registration", ['message' => $data['message']]);
|
||||
$errorMessage = $data['message'];
|
||||
} else {
|
||||
Log::warning("No data returned or invalid response structure for registration", ['data' => $data]);
|
||||
$errorMessage = 'Failed to fetch registration data.';
|
||||
}
|
||||
|
||||
return view('pages.reports.registration-report', compact('registrationData', 'currentPage', 'lastPage', 'total'));
|
||||
return view('pages.reports.registration-report', compact('registrationData', 'currentPage', 'lastPage', 'total', 'errorMessage'));
|
||||
}
|
||||
|
||||
public function stationRating(Request $request)
|
||||
|
@ -87,36 +173,46 @@ class ReportsController extends Controller
|
|||
'page_size' => 5,
|
||||
'date_start' => $request->input('date_start'),
|
||||
'date_end' => $request->input('date_end'),
|
||||
'sorting' => $request->input('sort', 'transaction_date_time|desc'),
|
||||
'sorting' => $request->input('sort', 'date|desc'),
|
||||
'_search' => $request->input('_search'),
|
||||
];
|
||||
|
||||
$response = Http::get($this->apiBaseUrl . 'cms/reportStationRatings', $params);
|
||||
$data = $response->json();
|
||||
$data = $this->makeApiRequest('cms/reportStationRatings', $params);
|
||||
|
||||
if (is_a($data, '\Illuminate\Http\RedirectResponse')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$stationRatingData = [];
|
||||
$currentPage = $params['page'];
|
||||
$lastPage = 1;
|
||||
$total = 0;
|
||||
$errorMessage = null;
|
||||
|
||||
if ($response->successful() && isset($data['data'])) {
|
||||
if ($data && isset($data['data'])) {
|
||||
$stationRatingData = array_map(function ($item) {
|
||||
return [
|
||||
'id' => $item['id'] ?? uniqid(),
|
||||
'transactionDateTime' => $item['transaction_date_time'],
|
||||
'transactionDateTime' => $item['date'],
|
||||
'cardNumber' => $item['card_number'],
|
||||
'salesInvoice' => $item['sales_invoice'],
|
||||
'salesInvoice' => $item['invoice'],
|
||||
'station' => $item['station'],
|
||||
'ratings' => $item['ratings'],
|
||||
'ratings' => $item['rate'],
|
||||
];
|
||||
}, $data['data']);
|
||||
$currentPage = $data['meta']['current_page'] ?? 1;
|
||||
$lastPage = $data['meta']['last_page'] ?? 1;
|
||||
$total = $data['meta']['total'] ?? count($stationRatingData);
|
||||
} elseif ($data && isset($data['message'])) {
|
||||
Log::info("API returned message for stationRating", ['message' => $data['message']]);
|
||||
$errorMessage = $data['message'];
|
||||
} else {
|
||||
Log::warning("No data returned or invalid response structure for stationRating", ['data' => $data]);
|
||||
$errorMessage = 'Failed to fetch station rating data.';
|
||||
}
|
||||
|
||||
return view('pages.reports.station-rating-report', compact('stationRatingData', 'currentPage', 'lastPage', 'total'));
|
||||
return view('pages.reports.station-rating-report', compact('stationRatingData', 'currentPage', 'lastPage', 'total', 'errorMessage'));
|
||||
}
|
||||
|
||||
public function topUp(Request $request)
|
||||
{
|
||||
$params = [
|
||||
|
@ -125,17 +221,22 @@ class ReportsController extends Controller
|
|||
'date_start' => $request->input('date_start'),
|
||||
'date_end' => $request->input('date_end'),
|
||||
'sorting' => $request->input('sort', 'transaction_date_time|desc'),
|
||||
'_search' => $request->input('_search'),
|
||||
];
|
||||
|
||||
$response = Http::get($this->apiBaseUrl . 'cms/reportTopUp', $params);
|
||||
$data = $response->json();
|
||||
$data = $this->makeApiRequest('cms/reportTopUp', $params);
|
||||
|
||||
if (is_a($data, '\Illuminate\Http\RedirectResponse')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$topUpData = [];
|
||||
$currentPage = $params['page'];
|
||||
$lastPage = 1;
|
||||
$total = 0;
|
||||
$errorMessage = null;
|
||||
|
||||
if ($response->successful() && isset($data['data'])) {
|
||||
if ($data && isset($data['data'])) {
|
||||
$topUpData = array_map(function ($item) {
|
||||
return [
|
||||
'id' => $item['id'] ?? uniqid(),
|
||||
|
@ -147,8 +248,14 @@ class ReportsController extends Controller
|
|||
$currentPage = $data['meta']['current_page'] ?? 1;
|
||||
$lastPage = $data['meta']['last_page'] ?? 1;
|
||||
$total = $data['meta']['total'] ?? count($topUpData);
|
||||
} elseif ($data && isset($data['message'])) {
|
||||
Log::info("API returned message for topUp", ['message' => $data['message']]);
|
||||
$errorMessage = $data['message'];
|
||||
} else {
|
||||
Log::warning("No data returned or invalid response structure for topUp", ['data' => $data]);
|
||||
$errorMessage = 'Failed to fetch top-up data.';
|
||||
}
|
||||
|
||||
return view('pages.reports.top-up-usage-report', compact('topUpData', 'currentPage', 'lastPage', 'total'));
|
||||
return view('pages.reports.top-up-usage-report', compact('topUpData', 'currentPage', 'lastPage', 'total', 'errorMessage'));
|
||||
}
|
||||
}
|
|
@ -22,6 +22,8 @@ class StationController extends Controller
|
|||
$response = Http::get($this->apiBaseUrl . 'cms/getStations', $params);
|
||||
$data = $response->json();
|
||||
|
||||
\Log::info('Stations API Response:', ['status' => $response->status(), 'data' => $data]);
|
||||
|
||||
$stations = [];
|
||||
$currentPage = $params['page'];
|
||||
$lastPage = 1;
|
||||
|
@ -33,20 +35,18 @@ class StationController extends Controller
|
|||
'id' => $item['station_uuid'],
|
||||
'station_code' => $item['code'],
|
||||
'station_name' => $item['description'],
|
||||
'branch_name' => 'N/A', // Mocked; replace with actual API field if available
|
||||
'date_created' => 'N/A', // Mocked
|
||||
'created_by' => 'N/A', // Mocked
|
||||
'modified_by' => 'N/A', // Mocked
|
||||
'date_modified' => 'N/A', // Mocked
|
||||
'branch_name' => 'N/A',
|
||||
'date_created' => 'N/A',
|
||||
'created_by' => 'N/A',
|
||||
'modified_by' => 'N/A',
|
||||
'date_modified' => 'N/A',
|
||||
];
|
||||
}, $data['data']);
|
||||
|
||||
// Mock pagination since API may not support it
|
||||
$total = count($data['data']);
|
||||
$lastPage = ceil($total / $params['page_size']);
|
||||
$currentPage = min($currentPage, $lastPage);
|
||||
|
||||
// Handle search client-side if API doesn't support _search
|
||||
if ($params['_search']) {
|
||||
$searchTerm = strtolower($params['_search']);
|
||||
$stations = array_filter($stations, function ($station) use ($searchTerm) {
|
||||
|
@ -59,7 +59,6 @@ class StationController extends Controller
|
|||
$lastPage = ceil($total / $params['page_size']);
|
||||
}
|
||||
|
||||
// Handle sorting client-side if API doesn't support sort
|
||||
if ($params['sort']) {
|
||||
[$sortField, $sortDir] = explode('|', $params['sort']);
|
||||
usort($stations, function ($a, $b) use ($sortField, $sortDir) {
|
||||
|
@ -69,7 +68,6 @@ class StationController extends Controller
|
|||
});
|
||||
}
|
||||
|
||||
// Paginate manually
|
||||
$start = ($currentPage - 1) * $params['page_size'];
|
||||
$stations = array_slice($stations, $start, $params['page_size']);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
'total' => 0,
|
||||
])
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
<!-- Filters -->
|
||||
<div class="d-flex justify-content-between mb-3 flex-wrap gap-2">
|
||||
|
@ -26,23 +25,10 @@
|
|||
<span class="input-group-text bg-light border-end-0">
|
||||
<i class="fa-solid fa-magnifying-glass text-muted"></i>
|
||||
</span>
|
||||
<input type="text" class="form-control border-start-0" placeholder="Search..." id="searchInput" data-search-param="_search">
|
||||
<input type="text" class="form-control border-start-0" placeholder="Search..." id="searchInput" data-search-param="_search" value="{{ request('_search') }}">
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
{{-- <div class="d-flex flex-column">
|
||||
<label for="startDate" class="form-label mb-1">Start Date</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-calendar-alt"></i></span>
|
||||
<input type="date" class="form-control" id="startDate">
|
||||
</div>
|
||||
</div> --}}
|
||||
{{-- <div class="d-flex flex-column">
|
||||
<label for="endDate" class="form-label mb-1">End Date</label>
|
||||
<div class="input-group">
|
||||
<input type="date" class="form-control" id="endDate">
|
||||
</div>
|
||||
</div> --}}
|
||||
</div>
|
||||
<div class="d-flex gap-2 align-items-end">
|
||||
<button class="btn btn-outline-secondary btn-sm" id="clearFilters">
|
||||
|
@ -51,6 +37,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Data Message -->
|
||||
@if (empty($data))
|
||||
<div class="alert alert-info" id="no-data-message">No data available.</div>
|
||||
@endif
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-container">
|
||||
<table class="table table-hover align-middle">
|
||||
|
@ -127,6 +118,8 @@
|
|||
exportEndpoint: '{{ route( Str::kebab(str_replace(" ", "-", strtolower($pageTitle)))) }}Export',
|
||||
};
|
||||
|
||||
console.log('Table Config:', tableConfig); // Log initial config
|
||||
|
||||
const rowsPerPage = 5;
|
||||
let currentPage = tableConfig.currentPage;
|
||||
let filteredRows = [...tableConfig.data];
|
||||
|
@ -154,14 +147,23 @@
|
|||
}
|
||||
|
||||
function renderTable() {
|
||||
console.log('Rendering table with filteredRows:', filteredRows); // Log data
|
||||
const tableBody = document.getElementById('tableBody');
|
||||
if (!tableBody) return;
|
||||
if (!tableBody) {
|
||||
console.error('Table body not found');
|
||||
return;
|
||||
}
|
||||
tableBody.innerHTML = '';
|
||||
|
||||
if (filteredRows.length === 0) {
|
||||
tableBody.innerHTML = `<tr><td colspan="${tableConfig.columns.length}">No data to display</td></tr>`;
|
||||
console.log('No data to render');
|
||||
return;
|
||||
}
|
||||
|
||||
filteredRows.forEach(row => {
|
||||
const tr = document.createElement('tr');
|
||||
let rowHtml = '';
|
||||
|
||||
tableConfig.columns.forEach(col => {
|
||||
let value = row[col.key] || '';
|
||||
if (col.format === 'date' || col.key.includes('DateTime')) {
|
||||
|
@ -169,17 +171,18 @@
|
|||
}
|
||||
rowHtml += `<td>${value}</td>`;
|
||||
});
|
||||
|
||||
tr.innerHTML = rowHtml;
|
||||
tableBody.appendChild(tr);
|
||||
});
|
||||
|
||||
updateNoDataMessage();
|
||||
}
|
||||
|
||||
function renderPagination() {
|
||||
console.log('Rendering pagination:', { currentPage, lastPage: tableConfig.lastPage }); // Log pagination
|
||||
const pagination = document.getElementById('pagination');
|
||||
if (!pagination) return;
|
||||
if (!pagination) {
|
||||
console.error('Pagination element not found');
|
||||
return;
|
||||
}
|
||||
pagination.innerHTML = '';
|
||||
|
||||
const routeBase = tableConfig.pageTitle.toLowerCase().replace(/\s+/g, '-');
|
||||
|
@ -222,6 +225,7 @@
|
|||
}
|
||||
|
||||
function updateUrl(page, search, startDate, endDate) {
|
||||
console.log('Updating URL:', { page, search, startDate, endDate, sortColumn, sortDirection }); // Log URL update
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.set('page', page);
|
||||
if (search) url.searchParams.set('_search', search);
|
||||
|
@ -238,17 +242,11 @@
|
|||
window.location.href = url.toString();
|
||||
}
|
||||
|
||||
function updateNoDataMessage() {
|
||||
const noDataMessage = document.getElementById('no-data-message');
|
||||
if (noDataMessage) {
|
||||
noDataMessage.style.display = filteredRows.length === 0 ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function attachEventListeners() {
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener('input', function() {
|
||||
console.log('Search input changed:', this.value); // Log search
|
||||
const url = new URL(window.location);
|
||||
const searchTerm = this.value;
|
||||
if (searchTerm) {
|
||||
|
@ -266,6 +264,7 @@
|
|||
const columnKey = this.getAttribute('data-key');
|
||||
sortDirection = sortColumn === columnKey && sortDirection === 'asc' ? 'desc' : 'asc';
|
||||
sortColumn = columnKey;
|
||||
console.log('Sorting:', { columnKey, sortDirection }); // Log sorting
|
||||
|
||||
document.querySelectorAll('.sortable i').forEach(icon => {
|
||||
icon.classList.remove('fa-sort-up', 'fa-sort-down');
|
||||
|
@ -286,13 +285,20 @@
|
|||
const startDateInput = document.getElementById('startDate');
|
||||
const endDateInput = document.getElementById('endDate');
|
||||
if (startDateInput && endDateInput) {
|
||||
startDateInput.addEventListener('change', () => updateUrl(1, document.getElementById('searchInput')?.value || '', startDateInput.value, endDateInput.value));
|
||||
endDateInput.addEventListener('change', () => updateUrl(1, document.getElementById('searchInput')?.value || '', startDateInput.value, endDateInput.value));
|
||||
startDateInput.addEventListener('change', () => {
|
||||
console.log('Start date changed:', startDateInput.value); // Log date
|
||||
updateUrl(1, document.getElementById('searchInput')?.value || '', startDateInput.value, endDateInput.value);
|
||||
});
|
||||
endDateInput.addEventListener('change', () => {
|
||||
console.log('End date changed:', endDateInput.value); // Log date
|
||||
updateUrl(1, document.getElementById('searchInput')?.value || '', startDateInput.value, endDateInput.value);
|
||||
});
|
||||
}
|
||||
|
||||
const clearFilters = document.getElementById('clearFilters');
|
||||
if (clearFilters) {
|
||||
clearFilters.addEventListener('click', function() {
|
||||
console.log('Clearing filters'); // Log filter clear
|
||||
if (searchInput) searchInput.value = '';
|
||||
if (startDateInput) startDateInput.value = '';
|
||||
if (endDateInput) endDateInput.value = '';
|
||||
|
@ -309,6 +315,7 @@
|
|||
const exportCsvBtn = document.getElementById('exportCsv');
|
||||
if (exportCsvBtn) {
|
||||
exportCsvBtn.addEventListener('click', () => {
|
||||
console.log('Exporting CSV'); // Log export
|
||||
const url = new URL(tableConfig.exportEndpoint, window.location.origin);
|
||||
const searchTerm = document.getElementById('searchInput')?.value || '';
|
||||
const startDate = document.getElementById('startDate')?.value || '';
|
||||
|
@ -319,6 +326,7 @@
|
|||
if (sortColumn && sortDirection) {
|
||||
url.searchParams.set('sort', `${sortColumn}|${sortDirection}`);
|
||||
}
|
||||
console.log('Export URL:', url.toString()); // Log export URL
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="card-body p-3">
|
||||
<!-- Error Message -->
|
||||
@if ($errorMessage)
|
||||
<div class="alert alert-danger">{{ $errorMessage }}</div>
|
||||
@endif
|
||||
|
||||
<!-- Filters -->
|
||||
<div class="d-flex justify-content-between mb-3 flex-wrap gap-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
|
@ -15,13 +20,13 @@
|
|||
<label for="startDate" class="form-label mb-1">Start Date</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-calendar-alt"></i></span>
|
||||
<input type="date" class="form-control" id="startDate">
|
||||
<input type="date" class="form-control" id="startDate" value="{{ request('date_start') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<label for="endDate" class="form-label mb-1">End Date</label>
|
||||
<div class="input-group">
|
||||
<input type="date" class="form-control" id="endDate">
|
||||
<input type="date" class="form-control" id="endDate" value="{{ request('date_end') }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,7 +51,7 @@
|
|||
'showAddButton' => false,
|
||||
'showCheckboxes' => false,
|
||||
'showBatchDelete' => false,
|
||||
'showSearch' => false,
|
||||
'showSearch' => true,
|
||||
'currentPage' => $currentPage ?? 1,
|
||||
'lastPage' => $lastPage ?? 1,
|
||||
'total' => $total ?? 0,
|
||||
|
@ -55,20 +60,6 @@
|
|||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
border-radius: 5px;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
.form-control {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.btn-outline-secondary {
|
||||
border-color: #6c757d;
|
||||
color: #6c757d;
|
||||
}
|
||||
.btn-outline-secondary:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.btn-export-csv {
|
||||
background-color: #ff6200;
|
||||
color: white;
|
||||
|
@ -77,64 +68,22 @@
|
|||
.btn-export-csv:hover {
|
||||
background-color: #e65a00;
|
||||
}
|
||||
.input-group-text {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let originalData = [...tableConfig.data];
|
||||
const startDateInput = document.getElementById('startDate');
|
||||
const endDateInput = document.getElementById('endDate');
|
||||
const exportCsvBtn = document.getElementById('exportCsv');
|
||||
|
||||
function filterData() {
|
||||
const startDate = startDateInput.value ? new Date(startDateInput.value) : null;
|
||||
const endDate = endDateInput.value ? new Date(endDateInput.value) : null;
|
||||
|
||||
tableConfig.data = originalData.filter(item => {
|
||||
const itemDate = new Date(item.transactionDateTime);
|
||||
if (startDate && itemDate < startDate) return false;
|
||||
if (endDate) {
|
||||
const endDateAdjusted = new Date(endDate);
|
||||
endDateAdjusted.setHours(23, 59, 59, 999);
|
||||
if (itemDate > endDateAdjusted) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
currentPage = 1;
|
||||
renderTable();
|
||||
renderPagination();
|
||||
}
|
||||
|
||||
startDateInput.addEventListener('change', filterData);
|
||||
endDateInput.addEventListener('change', filterData);
|
||||
|
||||
exportCsvBtn.addEventListener('click', () => {
|
||||
const headers = tableConfig.columns.map(col => col.name).join(',');
|
||||
const rows = tableConfig.data.map(item => {
|
||||
return [
|
||||
item.transactionDateTime,
|
||||
item.cardNumber,
|
||||
item.salesInvoice,
|
||||
item.station,
|
||||
item.ratings
|
||||
].join(',');
|
||||
const url = new URL(tableConfig.exportEndpoint, window.location.origin);
|
||||
const searchTerm = document.getElementById('searchInput')?.value || '';
|
||||
const startDate = document.getElementById('startDate')?.value || '';
|
||||
const endDate = document.getElementById('endDate')?.value || '';
|
||||
if (searchTerm) url.searchParams.set('_search', searchTerm);
|
||||
if (startDate) url.searchParams.set('date_start', startDate);
|
||||
if (endDate) url.searchParams.set('date_end', endDate);
|
||||
if (sortColumn && sortDirection) {
|
||||
url.searchParams.set('sort', `${sortColumn}|${sortDirection}`);
|
||||
}
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
const csvContent = [headers, ...rows].join('\n');
|
||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
||||
const link = document.createElement('a');
|
||||
const url = URL.createObjectURL(blob);
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', 'station-rating-report.csv');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
});
|
||||
|
||||
// Initial render
|
||||
renderTable();
|
||||
renderPagination();
|
||||
</script>
|
||||
@endsection
|
|
@ -3,7 +3,7 @@
|
|||
@section('page_title', 'Station Management')
|
||||
|
||||
@section('content')
|
||||
@include('components.station-component', [
|
||||
@include('components.table-component', [
|
||||
'pageTitle' => 'Station Management',
|
||||
'data' => $stations ?? [],
|
||||
'columns' => [
|
||||
|
|
Loading…
Reference in New Issue