export csv added

This commit is contained in:
erishBRBS 2025-04-27 08:32:31 +08:00
parent 2a92dc2983
commit bc8f68a610
11 changed files with 301 additions and 119 deletions

View File

@ -2,6 +2,7 @@
namespace App\Livewire\Components; namespace App\Livewire\Components;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Livewire\Component; use Livewire\Component;
class Table extends Component class Table extends Component
@ -20,6 +21,12 @@ class Table extends Component
public $search = ''; // Search query for filtering rows public $search = ''; // Search query for filtering rows
public $sortField = null; // Column to sort by public $sortField = null; // Column to sort by
public $sortDirection = 'asc'; // Sorting direction (asc or desc) public $sortDirection = 'asc'; // Sorting direction (asc or desc)
public bool $hasSearch = true;
public $startDate;
public $endDate;
// Modal Configuration // Modal Configuration
public $showModal = false; // Whether the modal is visible public $showModal = false; // Whether the modal is visible
@ -114,6 +121,36 @@ class Table extends Component
}, SORT_REGULAR, $this->sortDirection === 'desc')->values()->all(); // Use all() to return plain array again }, SORT_REGULAR, $this->sortDirection === 'desc')->values()->all(); // Use all() to return plain array again
} }
/**
* Download the data from the tables
*/
public function export()
{
$filename = 'export.csv';
return response()->streamDownload(function () {
// Open output stream
$handle = fopen('php://output', 'w');
// Write the CSV header
fputcsv($handle, collect($this->columns)->pluck('label')->toArray());
// Write the rows
foreach ($this->rows as $row) {
fputcsv($handle, collect($this->columns)->map(function ($column) use ($row) {
return $row[$column['field']] ?? '';
})->toArray());
}
// Close the output stream
fclose($handle);
}, $filename, [
'Content-Type' => 'text/csv',
'Content-Disposition' => "attachment; filename={$filename}",
]);
}
/** /**
* Render the table view * Render the table view
*/ */

View File

@ -8,8 +8,22 @@ use Livewire\Attributes\Layout; // Required for layout declaration
#[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11 #[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11
class MobileUsageReport extends Component class MobileUsageReport extends Component
{ {
public $mobileUsageReport = [];
public function mount()
{
$this->loadMobileUsageReport(); // Load mobileUsageReport initially
}
public function loadMobileUsageReport()
{
$this->mobileUsageReport = collect(json_decode(file_get_contents(storage_path('app/mobile-usage.json')), true));
}
public function render() public function render()
{ {
return view('livewire.report.mobile-usage-report'); return view('livewire.report.mobile-usage-report', [
'mobileUsageReport' => $this->mobileUsageReport,
]);
} }
} }

View File

@ -8,8 +8,22 @@ use Livewire\Attributes\Layout; // Required for layout declaration
#[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11 #[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11
class RegistrationReport extends Component class RegistrationReport extends Component
{ {
public $registrationReport = [];
public function mount()
{
$this->loadRegistrationReport(); // Load registrationReport initially
}
public function loadRegistrationReport()
{
$this->registrationReport = collect(json_decode(file_get_contents(storage_path('app/registration-report.json')), true));
}
public function render() public function render()
{ {
return view('livewire.report.registration-report'); return view('livewire.report.registration-report', [
'registrationReport' => $this->registrationReport,
]);
} }
} }

View File

@ -8,8 +8,22 @@ use Livewire\Attributes\Layout; // Required for layout declaration
#[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11 #[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11
class StationRatingReport extends Component class StationRatingReport extends Component
{ {
public $stationRating = [];
public function mount()
{
$this->loadStationRating(); // Load stationRating initially
}
public function loadStationRating()
{
$this->stationRating = collect(json_decode(file_get_contents(storage_path('app/station-rating.json')), true));
}
public function render() public function render()
{ {
return view('livewire.report.station-rating-report'); return view('livewire.report.station-rating-report', [
'stationRating' => $this->stationRating,
]);
} }
} }

View File

@ -8,8 +8,27 @@ use Livewire\Attributes\Layout; // Required for layout declaration
#[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11 #[Layout('layouts.dashboard')] // Attribute syntax for Laravel 11
class TopUpUsageReport extends Component class TopUpUsageReport extends Component
{ {
public $topUpUsage = [];
public function mount()
{
$this->loadTopUpUsage(); // Load topUpUsage initially
}
public function loadTopUpUsage()
{
$this->topUpUsage = collect(json_decode(file_get_contents(storage_path('app/topup-usage-report.json')), true));
}
public function render() public function render()
{ {
return view('livewire.report.top-up-usage-report'); return view('livewire.report.top-up-usage-report', [
'topUpUsage' => $this->topUpUsage,
]);
} }
} }

View File

@ -1,23 +1,49 @@
<div class="mt-10"> <div class="mt-10">
<div class="p-4 bg-white shadow-md"> <div class="p-4 bg-white shadow-md">
<!-- Top Bar with Search & Add Button --> <div class="flex justify-between items-center mb-4">
<div class="mb-4 flex items-center justify-between"> @if ($hasSearch ?? true)
<!-- Search Input --> <!-- Search bar -->
<input type="text" wire:model.debounce.500ms="search" <input
class="w-80 p-2 border border-gray-300 rounded-md" type="text"
wire:model="search"
placeholder="Search..." placeholder="Search..."
> class="border rounded px-3 py-2"
/>
@else
<!-- Start Date and End Date filters -->
<div class="flex gap-2">
<input
type="date"
wire:model="startDate"
class="border rounded px-3 py-2"
/>
<!-- Add Button (if enabled and route exists) --> <input
@if ($hasAddButton && $addRoute) type="date"
<a href="{{ $addRoute }}" wire:navigate wire:model="endDate"
class="ml-4 px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600"> class="border rounded px-3 py-2"
/>
</div>
@endif
@if ($hasAddButton ?? true)
<!-- Add button -->
<a href="{{ $addRoute }}" class="bg-orange-600 text-white px-4 py-2 rounded">
+ Add + Add
</a> </a>
@else
<!-- Export button -->
<button
wire:click="export"
class="bg-orange-600 text-white px-4 py-2 rounded flex items-center gap-2"
>
Export CSV
</button>
@endif @endif
</div> </div>
<!-- Table Header --> <!-- Table Header -->
<table class="table-auto w-full"> <table class="table-auto w-full">
<thead class="bg-gray-100"> <thead class="bg-gray-100">

View File

@ -1,5 +1,19 @@
<div> <div>
{{-- Top Nav --}} {{-- Top Nav --}}
@include('livewire.report.top-nav.mobile-usage-report') @include('livewire.report.top-nav.mobile-usage-report')
<h1>This is card type page</h1> <livewire:components.table
:columns="[
['label' => 'Date', 'field' => 'date'],
['label' => 'Active Registered Users', 'field' => 'active_registered_users'],
['label' => 'Inactive Registered Users', 'field' => 'inactive_registered_users'],
['label' => 'Locked Registered Users', 'field' => 'locked_registered_users'],
]"
:rows="$mobileUsageReport"
:hasSearch="false"
:hasCheckbox="false"
:hasActions="false"
:hasDelete="false"
:hasAddButton="false"
:isViewPage="false"
/>
</div> </div>

View File

@ -1,5 +1,18 @@
<div> <div>
{{-- Top Nav --}} {{-- Top Nav --}}
@include('livewire.report.top-nav.registration-report') @include('livewire.report.top-nav.registration-report')
<h1>This is card type page</h1> <livewire:components.table
:columns="[
['label' => 'Date', 'field' => 'date'],
['label' => 'No. of Activated Cards', 'field' => 'number_activated_cards'],
['label' => 'No. of Registered Members', 'field' => 'number_registered_members'],
]"
:rows="$registrationReport"
:hasSearch="false"
:hasCheckbox="false"
:hasActions="false"
:hasDelete="false"
:hasAddButton="false"
:isViewPage="false"
/>
</div> </div>

View File

@ -1,5 +1,20 @@
<div> <div>
{{-- Top Nav --}} {{-- Top Nav --}}
@include('livewire.report.top-nav.station-rating-report') @include('livewire.report.top-nav.station-rating-report')
<h1>This is card type page</h1> <livewire:components.table
:columns="[
['label' => 'Transaction Date & Time', 'field' => 'transaction_date_time'],
['label' => 'Card Number', 'field' => 'card_number'],
['label' => 'Sales Invoice', 'field' => 'sales_invoice'],
['label' => 'Station', 'field' => 'station'],
['label' => 'Ratings', 'field' => 'rating'],
]"
:rows="$stationRating"
:hasSearch="false"
:hasCheckbox="false"
:hasActions="false"
:hasDelete="false"
:hasAddButton="false"
:isViewPage="false"
/>
</div> </div>

View File

@ -1,5 +1,19 @@
<div> <div>
{{-- Top Nav --}} {{-- Top Nav --}}
@include('livewire.report.top-nav.top-up-usage-report') @include('livewire.report.top-nav.top-up-usage-report')
<h1>This is card type page</h1>
<livewire:components.table
:columns="[
['label' => 'Transaction Date & Time', 'field' => 'transaction_date_time'],
['label' => 'Card Number', 'field' => 'card_number'],
['label' => 'Top-up Amount', 'field' => 'top_up_amount'],
]"
:rows="$topUpUsage"
:hasAddButton="false"
:hasSearch="false"
:hasCheckbox="false"
:hasActions="false"
:hasDelete="false"
:isViewPage="false"
/>
</div> </div>

View File

@ -17,4 +17,6 @@
<!-- Bottom border --> <!-- Bottom border -->
<div class="border-b border-gray-300 mt-5"></div> <div class="border-b border-gray-300 mt-5"></div>
</div> </div>