converting react.js codes to laravel php

This commit is contained in:
armiejean 2025-04-14 11:44:57 +08:00
parent dd7c51c9a4
commit 67bcc53114
44 changed files with 2852 additions and 0 deletions

View File

@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class RestrictToRoleOne
{
public function handle(Request $request, Closure $next)
{
$user = auth()->user();
if ($user && $user->role == 1) { // Adjust 'role' based on your user model
return $next($request);
}
return redirect('/notifications')->with('error', 'Unauthorized access.');
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
class CardMemberList extends Component
{
use WithPagination;
public $filters = [
'status' => '',
];
public $members = [];
public function mount()
{
$this->fetchMembers();
}
public function fetchMembers()
{
$url = 'https://api.example.com/member' . ($this->filters['status'] ? '?status=' . ($this->filters['status'] === 'active' ? 'active' : 'inactive') : '');
$this->members = $this->fetchFromApi($url);
}
public function updatedFilters()
{
$this->resetPage();
$this->fetchMembers();
}
private function fetchFromApi($url)
{
try {
$response = \Http::get($url);
return $response->json()['data'] ?? [];
} catch (\Exception $e) {
session()->flash('error', 'Failed to load members: ' . $e->getMessage());
return [];
}
}
public function render()
{
return view('livewire.card-member-list');
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class CardMemberView extends Component
{
public $member;
public function mount($id)
{
try {
$this->member = $this->fetchFromApi("https://api.example.com/member/{$id}");
} catch (\Exception $e) {
session()->flash('error', 'Failed to load member details: ' . $e->getMessage());
return redirect()->route('card-members.list');
}
}
private function fetchFromApi($url)
{
$response = \Http::get($url);
return $response->json()['data'] ?? null;
}
public function render()
{
return view('livewire.card-member-view', ['member' => $this->member]);
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Livewire\MemberManagement;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class LockAccountList extends Component
{
use LivewireAlert;
public $accounts = [];
public function mount()
{
// Placeholder role check
// if (auth()->user()->role != 1) {
// $this->alert('error', 'Unauthorized access.');
// return redirect('/');
// }
$this->fetchAccounts();
}
public function fetchAccounts()
{
try {
$response = Http::get('https://api.example.com/member', [
'_locked' => 1,
'_sort_by' => 'card_number',
'_sort_order' => 'asc',
]);
if ($response->successful()) {
$this->accounts = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch locked accounts.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
public function render()
{
return view('livewire.member-management.lock-account-list')->layout('layouts.app', ['title' => 'Locked Accounts']);
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace App\Livewire\MemberManagement;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class LockAccountView extends Component
{
use LivewireAlert;
public $id;
public $userInfo = null;
public $loading = false;
public function mount($id)
{
$this->id = $id;
// Placeholder role check
// if (auth()->user()->role != 1) {
// $this->alert('error', 'Unauthorized access.');
// return redirect('/member-management/lock-account');
// }
$this->fetchAccount();
}
public function fetchAccount()
{
try {
$response = Http::get("https://api.example.com/member/{$this->id}");
if ($response->successful()) {
$this->userInfo = $response->json()['data'] ?? null;
} else {
$this->alert('error', 'Failed to fetch account data.');
return redirect('/member-management/lock-account');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
return redirect('/member-management/lock-account');
}
}
public function activateAccount()
{
$this->loading = true;
try {
$response = Http::post("https://api.example.com/memberActivate/{$this->id}");
if ($response->successful()) {
$this->alert('success', 'Record was successfully updated.');
return redirect('/member-management/lock-account');
} else {
$this->alert('error', 'Failed to activate account.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->loading = false;
}
}
public function render()
{
return view('livewire.member-management.lock-account-view')->layout('layouts.app', ['title' => 'Locked Account Details']);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Livewire\MyProfile;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class MyProfileView extends Component
{
use LivewireAlert;
public $userInfo = null;
public function mount()
{
$this->fetchProfile();
}
public function fetchProfile()
{
try {
$response = Http::post('https://api.example.com/adminProfile');
if ($response->successful()) {
$this->userInfo = $response->json()['data'] ?? null;
} else {
$this->alert('error', 'Failed to fetch profile data.', ['duration' => 20000]);
$this->userInfo = null;
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage(), ['duration' => 20000]);
$this->userInfo = null;
}
}
public function getRoleLabel($role)
{
if ($role == '1') {
return 'System Admin';
} elseif ($role == '3') {
return 'Super Admin';
}
return 'Marketing Personnel';
}
public function render()
{
return view('livewire.my-profile.my-profile-view')->layout('layouts.app', ['title' => 'My Profile']);
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Livewire\Notifications;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class NotificationList extends Component
{
use LivewireAlert;
public $notifications = [];
public $updating = false;
public function mount()
{
// Placeholder role check (replace with middleware or actual auth logic)
// if (auth()->user()->role != 1) {
// $this->alert('error', 'Unauthorized access.');
// return redirect('/'); // Adjust redirect as needed
// }
$this->fetchNotifications();
}
public function fetchNotifications()
{
try {
$this->updating = true;
$response = Http::get('https://api.example.com/notification');
if ($response->successful()) {
$this->notifications = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch notifications.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->updating = false;
}
}
public function render()
{
return view('livewire.notifications.notification-list')->layout('layouts.app', ['title' => 'Notifications']);
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace App\Livewire\Notifications;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class NotificationsCreate extends Component
{
use LivewireAlert;
public $subject = '';
public $content = '';
public $isScheduled = 'false';
public $schedule = '';
public $expiration = '';
public $loading = false;
protected $rules = [
'subject' => 'required|string|max:255',
'content' => 'required|string',
'isScheduled' => 'required|in:true,false',
'schedule' => 'required_if:isScheduled,true|nullable|date',
'expiration' => 'required_if:isScheduled,true|nullable|date|after_or_equal:schedule',
];
protected $messages = [
'subject.required' => 'Subject is required!',
'content.required' => 'Content is required!',
'isScheduled.required' => 'Schedule selection is required!',
'schedule.required_if' => 'Schedule date is required when scheduled!',
'expiration.required_if' => 'Expiration date is required when scheduled!',
'expiration.after_or_equal' => 'Expiration must be on or after the schedule date!',
];
public function mount()
{
// Placeholder role check
// if (auth()->user()->role != 1) {
// $this->alert('error', 'Unauthorized access.');
// return redirect('/notifications');
// }
}
public function save()
{
$this->validate();
$this->loading = true;
try {
$data = [
'subject' => $this->subject,
'content' => $this->content,
'isScheduled' => $this->isScheduled === 'true',
'schedule' => $this->isScheduled === 'true' ? $this->schedule : null,
'expiration' => $this->isScheduled === 'true' ? $this->expiration : null,
];
$response = Http::post('https://api.example.com/notification', $data);
if ($response->successful()) {
$this->alert('success', 'Notification created successfully!');
return redirect('/notifications');
} else {
$this->alert('error', 'Failed to create notification.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->loading = false;
}
}
public function cancel()
{
if (confirm('Are you sure you want to discard changes?')) {
return redirect('/notifications');
}
}
public function render()
{
return view('livewire.notifications.notifications-create')->layout('layouts.app', ['title' => 'Add Notification']);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Livewire\PhotoSlider;
use Livewire\Component;
class PhotoSlider extends Component
{
public function render()
{
return view('livewire.photo-slider.photo-slider');
}
}

View File

@ -0,0 +1,181 @@
<?php
namespace App\Http\Livewire\PhotoSlider;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;
class PhotoSliderCreate extends Component
{
use WithFileUploads;
public $loading = false;
public $promotionsOptions = [];
public $photoSliderLimit = false;
public $dateStartEnd = null;
public $form = [
'promotion_uuid' => '',
'title' => '',
'description' => '',
'image' => null,
'date_start' => '',
'date_end' => '',
'start_time' => '',
'end_time' => '',
];
public $errors = [];
public function mount()
{
$this->checkLimit();
$this->fetchPromotions();
}
public function checkLimit()
{
try {
$response = Http::get('https://api.example.com/photoSliderCount');
$this->photoSliderLimit = $response->json()['data'] >= 10;
} catch (\Exception $e) {
$this->photoSliderLimit = true;
session()->flash('error', 'Failed to check photo slider limit: ' . $e->getMessage());
}
}
public function fetchPromotions()
{
try {
$response = Http::get('https://api.example.com/getPromotions');
$promotions = $response->json()['data'] ?? [];
$this->promotionsOptions = array_map(function ($item) {
return [
'label' => $item['title'],
'value' => $item['promotion_uuid'],
'date' => [
'dateStart' => $item['date_start'],
'dateEnd' => $item['date_end'],
],
];
}, $promotions);
} catch (\Exception $e) {
session()->flash('error', 'Failed to load promotions: ' . $e->getMessage());
}
}
public function fetchDate($id)
{
foreach ($this->promotionsOptions as $option) {
if ($option['value'] == $id) {
$this->dateStartEnd = [
'date_start' => $option['date']['dateStart'],
'date_end' => $option['date']['dateEnd'],
];
break;
}
}
}
public function autoFillDetails($id)
{
try {
$response = Http::get("https://api.example.com/promotion/{$id}");
$data = $response->json()['data'] ?? [];
$this->form = array_merge($this->form, [
'title' => $data['title'] ?? '',
'description' => $data['description'] ?? '',
'image' => $data['image'] ?? '',
'date_start' => Carbon::parse($data['date_start'])->format('Y-m-d'),
'date_end' => Carbon::parse($data['date_end'])->format('Y-m-d'),
'start_time' => Carbon::parse($data['date_start'])->format('H:i'),
'end_time' => Carbon::parse($data['date_end'])->format('H:i'),
]);
} catch (\Exception $e) {
session()->flash('error', 'Failed to autofill details: ' . $e->getMessage());
}
}
public function submit()
{
$this->validateForm();
$this->loading = true;
try {
$formData = new \GuzzleHttp\Psr7\MultipartStream([
[
'name' => 'promotion_uuid',
'contents' => $this->form['promotion_uuid'] ?? '',
],
[
'name' => 'title',
'contents' => $this->form['title'] ?? '',
],
[
'name' => 'description',
'contents' => $this->form['description'] ?? '',
],
[
'name' => 'date_start',
'contents' => Carbon::parse($this->form['date_start'] . ' ' . $this->form['start_time'])->format('Y-m-d\TH:i:s'),
],
[
'name' => 'date_end',
'contents' => Carbon::parse($this->form['date_end'] . ' ' . $this->form['end_time'])->format('Y-m-d\TH:i:s'),
],
[
'name' => 'image',
'contents' => $this->form['image'] ? fopen($this->form['image']->getPathname(), 'r') : '',
'filename' => $this->form['image'] ? $this->form['image']->getClientOriginalName() : '',
],
]);
$response = Http::withHeaders(['Content-Type' => 'multipart/form-data; boundary=' . $formData->getBoundary()])
->withBody($formData)
->post('https://api.example.com/photoSlider');
if ($response->successful()) {
session()->flash('success', 'New record added.');
$this->redirect(route('photo-slider.index'));
}
} catch (\Exception $e) {
session()->flash('error', 'Failed to create record: ' . $e->getMessage());
}
$this->loading = false;
}
public function validateForm()
{
$rules = [
'title' => 'required|max:128',
'image' => 'required',
'date_start' => 'required|date',
'date_end' => 'required|date',
'start_time' => 'required',
'end_time' => 'required',
];
$messages = [
'title.required' => 'Title is required!',
'title.max' => 'Maximum character is 128.',
'image.required' => 'Upload Image is required!',
'date_start.required' => 'Start Appearance Date is required!',
'date_end.required' => 'End Appearance Date is required!',
'start_time.required' => 'Start Time is required!',
'end_time.required' => 'End Time is required!',
];
$this->errors = [];
try {
$this->validate($rules, $messages);
} catch (\Exception $e) {
$this->errors = collect($e->errors())->flatten()->toArray();
throw $e;
}
}
public function render()
{
return view('livewire.photo-slider.photo-slider-create');
}
}

View File

@ -0,0 +1,204 @@
<?php
namespace App\Http\Livewire\PhotoSlider;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;
class PhotoSliderEdit extends Component
{
use WithFileUploads;
public $loading = false;
public $slider;
public $promotionsOptions = [];
public $promotionsDefaultValue = [];
public $promotionsDefaultKeyValue = [];
public $dateStartEnd = null;
public $form = [
'promotion_uuid' => '',
'title' => '',
'description' => '',
'image' => null,
'date_start' => '',
'date_end' => '',
'start_time' => '',
'end_time' => '',
];
public $errors = [];
public function mount($id)
{
$this->fetchSlider($id);
$this->fetchPromotions();
}
public function fetchSlider($id)
{
try {
$response = Http::get("https://api.example.com/photoSlider/{$id}");
$this->slider = $response->json()['data'] ?? null;
if (!$this->slider) {
throw new \Exception('No data found');
}
$this->form = [
'promotion_uuid' => $this->slider['promotion'] ? $this->slider['promotion']['promotion_uuid'] : '',
'title' => $this->slider['title'] ?? '',
'description' => $this->slider['description'] ?? '',
'image' => $this->slider['image'] ?? null,
'date_start' => Carbon::parse($this->slider['date_start'])->format('Y-m-d'),
'date_end' => Carbon::parse($this->slider['date_end'])->format('Y-m-d'),
'start_time' => Carbon::parse($this->slider['date_start'])->format('H:i'),
'end_time' => Carbon::parse($this->slider['date_end'])->format('H:i'),
];
if ($this->slider['promotion']) {
$this->promotionsDefaultValue = [$this->slider['promotion']['title']];
$this->promotionsDefaultKeyValue = [$this->slider['promotion']['promotion_uuid']];
$this->dateStartEnd = [
'date_start' => $this->slider['promotion']['date_start'],
'date_end' => $this->slider['promotion']['date_end'],
];
}
} catch (\Exception $e) {
session()->flash('error', 'Failed to load photo slider details: ' . $e->getMessage());
$this->redirect(route('photo-slider.index'));
}
}
public function fetchPromotions()
{
try {
$response = Http::get('https://api.example.com/getPromotions');
$promotions = $response->json()['data'] ?? [];
$this->promotionsOptions = array_map(function ($item) {
return [
'label' => $item['title'],
'value' => $item['promotion_uuid'],
'date' => [
'dateStart' => $item['date_start'],
'dateEnd' => $item['date_end'],
],
];
}, $promotions);
} catch (\Exception $e) {
session()->flash('error', 'Failed to load promotions: ' . $e->getMessage());
}
}
public function fetchDate($id)
{
foreach ($this->promotionsOptions as $option) {
if ($option['value'] == $id) {
$this->dateStartEnd = [
'date_start' => $option['date']['dateStart'],
'date_end' => $option['date']['dateEnd'],
];
break;
}
}
}
public function autoFillDetails($id)
{
try {
$response = Http::get("https://api.example.com/promotion/{$id}");
$data = $response->json()['data'] ?? [];
$this->form = array_merge($this->form, [
'title' => $data['title'] ?? '',
'description' => $data['description'] ?? '',
'image' => $data['image'] ?? '',
'date_start' => Carbon::parse($data['date_start'])->format('Y-m-d'),
'date_end' => Carbon::parse($data['date_end'])->format('Y-m-d'),
'start_time' => Carbon::parse($data['date_start'])->format('H:i'),
'end_time' => Carbon::parse($data['date_end'])->format('H:i'),
]);
} catch (\Exception $e) {
session()->flash('error', 'Failed to autofill details: ' . $e->getMessage());
}
}
public function submit()
{
$this->validateForm();
$this->loading = true;
try {
$formData = new \GuzzleHttp\Psr7\MultipartStream([
[
'name' => 'promotion_uuid',
'contents' => $this->form['promotion_uuid'] ?? '',
],
[
'name' => 'title',
'contents' => $this->form['title'] ?? '',
],
[
'name' => 'description',
'contents' => $this->form['description'] ?? '',
],
[
'name' => 'date_start',
'contents' => Carbon::parse($this->form['date_start'] . ' ' . $this->form['start_time'])->format('Y-m-d\TH:i:s'),
],
[
'name' => 'date_end',
'contents' => Carbon::parse($this->form['date_end'] . ' ' . $this->form['end_time'])->format('Y-m-d\TH:i:s'),
],
[
'name' => 'image',
'contents' => $this->form['image'] instanceof \Livewire\TemporaryUploadedFile ? fopen($this->form['image']->getPathname(), 'r') : $this->form['image'],
'filename' => $this->form['image'] instanceof \Livewire\TemporaryUploadedFile ? $this->form['image']->getClientOriginalName() : '',
],
]);
$response = Http::withHeaders(['Content-Type' => 'multipart/form-data; boundary=' . $formData->getBoundary()])
->withBody($formData)
->post("https://api.example.com/updatePhotoSlider/{$this->slider['photoslider_uuid']}");
if ($response->successful()) {
session()->flash('success', 'Record was successfully updated.');
$this->redirect(route('photo-slider.index'));
}
} catch (\Exception $e) {
session()->flash('error', 'Failed to update record: ' . $e->getMessage());
}
$this->loading = false;
}
public function validateForm()
{
$rules = [
'title' => 'required|max:128',
'image' => 'required',
'date_start' => 'required|date',
'date_end' => 'required|date',
'start_time' => 'required',
'end_time' => 'required',
];
$messages = [
'title.required' => 'Title is required!',
'title.max' => 'Maximum character is 128.',
'image.required' => 'Upload Image is required!',
'date_start.required' => 'Start Appearance Date is required!',
'date_end.required' => 'End Appearance Date is required!',
'start_time.required' => 'Start Time is required!',
'end_time.required' => 'End Time is required!',
];
$this->errors = [];
try {
$this->validate($rules, $messages);
} catch (\Exception $e) {
$this->errors = collect($e->errors())->flatten()->toArray();
throw $e;
}
}
public function render()
{
return view('livewire.photo-slider.photo-slider-edit');
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace App\Http\Livewire\PhotoSlider;
use Livewire\Component;
class PhotoSliderList extends Component
{
public $sliders = [];
public $photoSliderLimit = false;
public function mount()
{
$this->fetchSliders();
$this->checkLimit();
}
public function fetchSliders()
{
try {
$this->sliders = $this->fetchFromApi('https://api.example.com/photoSlider?page=1&page_size=10&_sort_by=create_dt&_sort_order=desc');
} catch (\Exception $e) {
session()->flash('error', 'Failed to load photo sliders: ' . $e->getMessage());
}
}
public function checkLimit()
{
try {
$response = \Http::get('https://api.example.com/photoSliderCount');
$this->photoSliderLimit = $response->json()['data'] >= 10;
} catch (\Exception $e) {
$this->photoSliderLimit = true; // Default to true if API fails
}
}
private function fetchFromApi($url)
{
$response = \Http::get($url);
return $response->json()['data'] ?? [];
}
public function delete($uuid)
{
try {
$response = \Http::delete("https://api.example.com/photoSlider/{$uuid}");
if ($response->successful()) {
session()->flash('success', 'Record was successfully deleted.');
$this->fetchSliders();
$this->checkLimit();
}
} catch (\Exception $e) {
session()->flash('error', 'Failed to delete record: ' . $e->getMessage());
}
}
public function render()
{
return view('livewire.photo-slider.photo-slider-list');
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Http\Livewire\PhotoSlider;
use Livewire\Component;
class PhotoSliderView extends Component
{
public $slider;
public function mount($id)
{
try {
$this->slider = $this->fetchFromApi("https://api.example.com/photoSlider/{$id}");
} catch (\Exception $e) {
session()->flash('error', 'Failed to load photo slider details: ' . $e->getMessage());
return redirect()->route('photo-slider.index');
}
}
private function fetchFromApi($url)
{
$response = \Http::get($url);
return $response->json()['data'] ?? null;
}
public function delete($uuid)
{
try {
$response = \Http::delete("https://api.example.com/photoSlider/{$uuid}");
if ($response->successful()) {
session()->flash('success', 'Record was successfully deleted.');
return redirect()->route('photo-slider.index');
}
} catch (\Exception $e) {
session()->flash('error', 'Failed to delete record: ' . $e->getMessage());
}
}
public function render()
{
return view('livewire.photo-slider.photo-slider-view', ['slider' => $this->slider]);
}
}

View File

@ -0,0 +1,173 @@
<?php
namespace App\Livewire\Promotions;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class PromotionsCreate extends Component
{
use LivewireAlert, WithFileUploads;
public $title = '';
public $description = '';
public $image = null;
public $station_uuid = [];
public $date_start = '';
public $date_end = '';
public $start_time = '';
public $end_time = '';
public $is_toppromotion = 0;
public $is_gps = 0;
public $promo_type = '';
public $branches = [];
public $branchesOptionsTwo = [];
public $promoTypes = [];
public $is_toppromotion_disabled = false;
public $loading = false;
protected $rules = [
'title' => 'required|string|max:128',
'description' => 'required|string|max:32000',
'image' => 'required|image|mimes:jpg,png,gif|max:100', // 100KB
'station_uuid' => 'nullable|array',
'date_start' => 'required|date',
'date_end' => 'required|date|after_or_equal:date_start',
'start_time' => 'required',
'end_time' => 'required',
'is_toppromotion' => 'in:0,1',
'is_gps' => 'in:0,1',
'promo_type' => 'required|string',
];
protected $messages = [
'title.required' => 'Title is required!',
'title.max' => 'Maximum character is 128.',
'description.required' => 'Description is required!',
'description.max' => 'Maximum character is 32,000.',
'image.required' => 'Upload Image is required!',
'image.max' => 'Maximum file size is 100KB.',
'date_start.required' => 'Start Date is required!',
'date_end.required' => 'End Date is required!',
'date_end.after_or_equal' => 'End Date must be on or after Start Date!',
'start_time.required' => 'Start Time is required!',
'end_time.required' => 'End Time is required!',
'promo_type.required' => 'Promo Type is required!',
];
public function mount()
{
$this->fetchBranches();
$this->fetchPromoTypes();
$this->checkTopPromotion();
}
public function fetchBranches()
{
try {
$response = Http::get('https://api.example.com/getStations');
if ($response->successful()) {
$stations = $response->json()['data'] ?? [];
$this->branches = array_map(function ($station) {
return [
'value' => $station['station_uuid'],
'label' => $station['description'],
];
}, $stations);
$this->branchesOptionsTwo = array_column($stations, 'description');
} else {
$this->alert('error', 'Failed to fetch branches.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
public function fetchPromoTypes()
{
try {
$response = Http::get('https://api.example.com/promoTypes');
if ($response->successful()) {
$this->promoTypes = array_map(function ($key, $value) {
return [
'value' => $key,
'label' => $value,
];
}, array_keys($response->json()['data'] ?? []), $response->json()['data'] ?? []);
} else {
$this->alert('error', 'Failed to fetch promo types.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
public function checkTopPromotion()
{
try {
$response = Http::get('https://api.example.com/promotionDisableTopTwo');
if ($response->successful()) {
$this->is_toppromotion_disabled = !($response->json()['data']['is_toppromotion'] === 'disable');
}
} catch (\Exception $e) {
$this->alert('error', 'Failed to check top promotion status.');
}
}
public function save()
{
$this->validate();
$this->loading = true;
try {
$data = [
'title' => $this->title,
'description' => $this->description,
'station_uuid' => json_encode($this->station_uuid),
'date_start' => \Carbon\Carbon::parse($this->date_start . ' ' . $this->start_time)->format('Y-m-d\TH:i:s'),
'date_end' => \Carbon\Carbon::parse($this->date_end . ' ' . $this->end_time)->format('Y-m-d\TH:i:s'),
'is_toppromotion' => $this->is_toppromotion,
'is_gps' => $this->is_gps,
'promo_type' => $this->promo_type,
'created_by' => auth()->user()->name ?? 'user',
];
$response = Http::asMultipart();
if ($this->image) {
$response = $response->attach('image', file_get_contents($this->image->getRealPath()), $this->image->getClientOriginalName());
}
$response = $response->post('https://api.example.com/promotion', $data);
if ($response->successful()) {
$this->alert('success', 'New record added.');
return redirect('/promotions');
} else {
$this->alert('error', 'Failed to create promotion.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->loading = false;
}
}
public function cancel()
{
if (confirm('Are you sure you want to discard changes?')) {
return redirect('/promotions');
}
}
public function render()
{
return view('livewire.promotions.promotions-create', [
'branches' => $this->branches,
'branchesOptionsTwo' => $this->branchesOptionsTwo,
'promoTypes' => $this->promoTypes,
])->layout('layouts.app', ['title' => 'Add Promotion']);
}
}

View File

@ -0,0 +1,198 @@
<?php
namespace App\Livewire\Promotions;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class PromotionsEdit extends Component
{
use LivewireAlert, WithFileUploads;
public $id;
public $promotion = null;
public $title = '';
public $description = '';
public $image = null;
public $station_uuid = [];
public $date_start = '';
public $date_end = '';
public $start_time = '';
public $end_time = '';
public $is_toppromotion = 0;
public $is_gps = 0;
public $promo_type = '';
public $branches = [];
public $branchesOptionsTwo = [];
public $promoTypes = [];
public $is_toppromotion_disabled = false;
public $loading = false;
protected $rules = [
'title' => 'required|string|max:128',
'description' => 'required|string|max:32000',
'image' => 'nullable|image|mimes:jpg,png,gif|max:100', // 100KB
'station_uuid' => 'nullable|array',
'date_start' => 'required|date',
'date_end' => 'required|date|after_or_equal:date_start',
'start_time' => 'required',
'end_time' => 'required',
'is_toppromotion' => 'in:0,1',
'is_gps' => 'in:0,1',
'promo_type' => 'required|string',
];
protected $messages = [
'title.required' => 'Title is required!',
'title.max' => 'Maximum character is 128.',
'description.required' => 'Description is required!',
'description.max' => 'Maximum character is 32,000.',
'image.max' => 'Maximum file size is 100KB.',
'date_start.required' => 'Start Date is required!',
'date_end.required' => 'End Date is required!',
'date_end.after_or_equal' => 'End Date must be on or after Start Date!',
'start_time.required' => 'Start Time is required!',
'end_time.required' => 'End Time is required!',
'promo_type.required' => 'Promo Type is required!',
];
public function mount($id)
{
$this->id = $id;
$this->fetchPromotion();
$this->fetchBranches();
$this->fetchPromoTypes();
$this->checkTopPromotion();
}
public function fetchPromotion()
{
try {
$response = Http::get("https://api.example.com/promotion/{$this->id}");
if ($response->successful()) {
$this->promotion = $response->json()['data'];
$this->title = $this->promotion['title'] ?? '';
$this->description = $this->promotion['description'] ?? '';
$this->station_uuid = array_column($this->promotion['stations'] ?? [], 'station_uuid');
$this->date_start = \Carbon\Carbon::parse($this->promotion['date_start'])->format('Y-m-d');
$this->date_end = \Carbon\Carbon::parse($this->promotion['date_end'])->format('Y-m-d');
$this->start_time = \Carbon\Carbon::parse($this->promotion['date_start'])->format('H:i');
$this->end_time = \Carbon\Carbon::parse($this->promotion['date_end'])->format('H:i');
$this->is_toppromotion = $this->promotion['is_toppromotion'] ?? 0;
$this->is_gps = $this->promotion['is_gps'] ?? 0;
$this->promo_type = $this->promotion['promo_type']['id'] ?? '';
} else {
$this->alert('error', 'Failed to fetch promotion data.');
return redirect('/promotions');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
return redirect('/promotions');
}
}
public function fetchBranches()
{
try {
$response = Http::get('https://api.example.com/getStations');
if ($response->successful()) {
$stations = $response->json()['data'] ?? [];
$this->branches = array_map(function ($station) {
return [
'value' => $station['station_uuid'],
'label' => $station['description'],
];
}, $stations);
$this->branchesOptionsTwo = array_column($stations, 'description');
}
} catch (\Exception $e) {
$this->alert('error', 'Failed to fetch branches.');
}
}
public function fetchPromoTypes()
{
try {
$response = Http::get('https://api.example.com/promoTypes');
if ($response->successful()) {
$this->promoTypes = array_map(function ($key, $value) {
return [
'value' => $key,
'label' => $value,
];
}, array_keys($response->json()['data'] ?? []), $response->json()['data'] ?? []);
}
} catch (\Exception $e) {
$this->alert('error', 'Failed to fetch promo types.');
}
}
public function checkTopPromotion()
{
try {
$response = Http::get("https://api.example.com/promotionDisableTopTwo?promotion_uuid={$this->id}");
if ($response->successful()) {
$this->is_toppromotion_disabled = !($response->json()['data']['is_toppromotion'] === 'disable');
}
} catch (\Exception $e) {
$this->alert('error', 'Failed to check top promotion status.');
}
}
public function save()
{
$this->validate();
$this->loading = true;
try {
$data = [
'title' => $this->title,
'description' => $this->description,
'station_uuid' => json_encode($this->station_uuid),
'date_start' => \Carbon\Carbon::parse($this->date_start . ' ' . $this->start_time)->format('Y-m-d\TH:i:s'),
'date_end' => \Carbon\Carbon::parse($this->date_end . ' ' . $this->end_time)->format('Y-m-d\TH:i:s'),
'is_toppromotion' => $this->is_toppromotion,
'is_gps' => $this->is_gps,
'promo_type' => $this->promo_type,
'updated_by' => auth()->user()->name ?? 'user',
];
$response = Http::asMultipart();
if ($this->image) {
$response = $response->attach('image', file_get_contents($this->image->getRealPath()), $this->image->getClientOriginalName());
}
$response = $response->post("https://api.example.com/updatePromotion/{$this->id}", $data);
if ($response->successful()) {
$this->alert('success', 'Promotion updated successfully!');
return redirect('/promotions');
} else {
$this->alert('error', 'Failed to update promotion.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->loading = false;
}
}
public function cancel()
{
if (confirm('Are you sure you want to discard changes?')) {
return redirect('/promotions');
}
}
public function render()
{
return view('livewire.promotions.promotions-edit', [
'branches' => $this->branches,
'branchesOptionsTwo' => $this->branchesOptionsTwo,
'promoTypes' => $this->promoTypes,
])->layout('layouts.app', ['title' => 'Update Promotion']);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Livewire\Promotions;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class PromotionsList extends Component
{
use LivewireAlert;
public $promotions = [];
public function mount()
{
$this->fetchPromotions();
}
public function fetchPromotions()
{
try {
$response = Http::get('https://api.example.com/promotion');
if ($response->successful()) {
$this->promotions = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch promotions.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
public function delete($id)
{
if (confirm('Are you sure you want to delete this promotion?')) {
try {
$response = Http::delete("https://api.example.com/promotion/{$id}");
if ($response->successful()) {
$this->alert('success', 'Promotion deleted successfully!');
$this->fetchPromotions();
} else {
$this->alert('error', 'Failed to delete promotion.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
}
public function render()
{
return view('livewire.promotions.promotions-list')->layout('layouts.app', ['title' => 'Promotions']);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Livewire\Promotions;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class PromotionsView extends Component
{
use LivewireAlert;
public $id;
public $promotion = null;
public function mount($id)
{
$this->id = $id;
$this->fetchPromotion();
}
public function fetchPromotion()
{
try {
$response = Http::get("https://api.example.com/promotion/{$this->id}");
if ($response->successful()) {
$this->promotion = $response->json()['data'] ?? null;
} else {
$this->alert('error', 'Failed to fetch promotion data.');
return redirect('/promotions');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
return redirect('/promotions');
}
}
public function delete()
{
if (confirm('Are you sure you want to delete this promotion?')) {
try {
$response = Http::delete("https://api.example.com/promotion/{$this->id}");
if ($response->successful()) {
$this->alert('success', 'Promotion deleted successfully!');
return redirect('/promotions');
} else {
$this->alert('error', 'Failed to delete promotion.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
}
}
}
public function render()
{
return view('livewire.promotions.promotions-view')->layout('layouts.app', ['title' => 'Promotion Details']);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Livewire\Reports;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class MobileUsageList extends Component
{
use LivewireAlert;
public $data = [];
public $updating = false;
public function mount()
{
$this->fetchData();
}
public function fetchData()
{
try {
$this->updating = true;
$response = Http::get('https://api.example.com/reportMobileUsage');
if ($response->successful()) {
$this->data = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch mobile usage report data.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->updating = false;
}
}
public function render()
{
return view('livewire.reports.mobile-usage-list')->layout('layouts.app', ['title' => 'Mobile Usage Report']);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Livewire\Reports;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class RegistrationList extends Component
{
use LivewireAlert;
public $data = [];
public $updating = false;
public function mount()
{
$this->fetchData();
}
public function fetchData()
{
try {
$this->updating = true;
$response = Http::get('https://api.example.com/reportRegistration');
if ($response->successful()) {
$this->data = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch registration report data.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->updating = false;
}
}
public function render()
{
return view('livewire.reports.registration-list')->layout('layouts.app', ['title' => 'Registration Report']);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Livewire\Reports;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class StationRatingList extends Component
{
use LivewireAlert;
public $data = [];
public $updating = false;
public function mount()
{
$this->fetchData();
}
public function fetchData()
{
try {
$this->updating = true;
$response = Http::get('https://api.example.com/reportStationRatings');
if ($response->successful()) {
$this->data = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch station rating report data.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->updating = false;
}
}
public function render()
{
return view('livewire.reports.station-rating-list')->layout('layouts.app', ['title' => 'Station Rating Report']);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Livewire\Reports;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
class TopUpList extends Component
{
use LivewireAlert;
public $data = [];
public $updating = false;
public function mount()
{
$this->fetchData();
}
public function fetchData()
{
try {
$this->updating = true;
$response = Http::get('https://api.example.com/reportTopUp');
if ($response->successful()) {
$this->data = $response->json()['data'] ?? [];
} else {
$this->alert('error', 'Failed to fetch top-up report data.');
}
} catch (\Exception $e) {
$this->alert('error', 'An error occurred: ' . $e->getMessage());
} finally {
$this->updating = false;
}
}
public function render()
{
return view('livewire.reports.top-up-list')->layout('layouts.app', ['title' => 'Top-Up Usage Report']);
}
// In TopUpList.php
public function exportCsv()
{
$response = Http::get('https://api.example.com/reportTopUpExport');
if ($response->successful()) {
return response($response->body())
->header('Content-Type', 'text/csv')
->header('Content-Disposition', 'attachment; filename="TopUpUsageReport.csv"');
}
$this->alert('error', 'Failed to export CSV.');
}
}

View File

@ -0,0 +1,65 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5;">
<x-header-form title="Card Member" />
@if(session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
<div class="card">
<div class="card-body">
<div class="mb-3">
<select wire:model="filters.status" class="form-select" style="max-width: 200px;">
<option value="">All Status</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Card Number</th>
<th>First Name</th>
<th>Last Name</th>
<th>Birthday</th>
<th>Card Type</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach ($members as $member)
<tr>
<td>{{ $member['card_number'] }}</td>
<td>{{ $member['firstname'] }}</td>
<td>{{ $member['lastname'] }}</td>
<td>{{ \Carbon\Carbon::parse($member['birthdate'])->format('d-M-Y') }}</td>
<td>{{ $member['card_type'] }}</td>
<td>{{ $member['status'] === 'active' ? 'Active' : 'Inactive' }}</td>
<td>
<a href="{{ route('card-members.view', $member['id']) }}" class="btn btn-primary btn-sm">
<i class="fas fa-eye"></i> View
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="d-flex justify-content-center">
<nav>
<ul class="pagination">
<li class="page-item {{ $page > 1 ? '' : 'disabled' }}">
<a class="page-link" href="#" wire:click.prevent="previousPage">Previous</a>
</li>
<li class="page-item {{ $page < $lastPage ? '' : 'disabled' }}">
<a class="page-link" href="#" wire:click.prevent="nextPage">Next</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,53 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5; padding-bottom: 10px;">
<x-header-form title="Card Member Details" />
@if(session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
@if($member)
<div class="card">
<div class="card-body">
<div style="padding: 15px 30px 0px;">
<h2 style="margin: 0 0 20px;">Details</h2>
<h2 style="font-weight: bold; font-size: 20px;">Card Details</h2>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Card Number:</span></div>
<div class="col-9">{{ $member['card_number'] }}</div>
</div>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">First Name:</span></div>
<div class="col-9">{{ $member['firstname'] }}</div>
</div>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Last Name:</span></div>
<div class="col-9">{{ $member['lastname'] }}</div>
</div>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Birthday:</span></div>
<div class="col-9">{{ \Carbon\Carbon::parse($member['birthdate'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Card Type:</span></div>
<div class="col-9">{{ $member['card_type'] }}</div>
</div>
<h2 style="font-weight: bold; font-size: 20px; margin-top: 12px;">Account Details</h2>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Account Status:</span></div>
<div class="col-9">{{ $member['is_locked'] == 1 ? 'Locked' : 'Active' }}</div>
</div>
<div class="row mb-2">
<div class="col-3"><span style="font-weight: 600;">Unlocked By:</span></div>
<div class="col-9">{{ $member['unlocked_by'] }}</div>
</div>
</div>
</div>
</div>
@else
<p>No member data found.</p>
@endif
</div>

View File

@ -0,0 +1,45 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Locked Accounts</h4>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th style="width: 18%;">Card Number</th>
<th style="width: 15%;">First Name</th>
<th style="width: 15%;">Last Name</th>
<th style="width: 18%;">Birthday</th>
<th style="width: 18%;">Card Type</th>
<th style="width: 10%;">Status</th>
<th style="width: 6%;">Action</th>
</tr>
</thead>
<tbody>
@forelse ($accounts as $account)
<tr>
<td>{{ $account['card_number'] ?? 'N/A' }}</td>
<td>{{ $account['firstname'] ?? 'N/A' }}</td>
<td>{{ $account['lastname'] ?? 'N/A' }}</td>
<td>{{ $account['birthdate'] ? \Carbon\Carbon::parse($account['birthdate'])->format('d-M-Y') : 'N/A' }}</td>
<td>{{ $account['card_type'] ?? 'N/A' }}</td>
<td>{{ $account['status'] == 'locked' ? 'Locked' : 'Locked' }}</td>
<td>
<a href="{{ route('member-management.lock-account.view', $account['lcard_uuid']) }}" class="btn btn-sm btn-info">View</a>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="text-center">No locked accounts found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,60 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Locked Accounts</h4>
<button class="btn btn-primary" wire:click="activateAccount" wire:loading.attr="disabled" wire:target="activateAccount">
@if($loading) <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Activating... @else Activate Account @endif
</button>
</div>
<div class="card-body">
@if($userInfo)
<div class="p-4">
<div class="mb-4">
<h5 class="fw-bold fs-5">Card Details</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Card Number:</div>
<div class="col-9">{{ $userInfo['card_number'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">First Name:</div>
<div class="col-9">{{ $userInfo['firstname'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Last Name:</div>
<div class="col-9">{{ $userInfo['lastname'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Birthday:</div>
<div class="col-9">{{ $userInfo['birthdate'] ? \Carbon\Carbon::parse($userInfo['birthdate'])->format('d-M-Y') : 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Card Type:</div>
<div class="col-9">{{ $userInfo['card_type'] ?? 'N/A' }}</div>
</div>
</div>
<div>
<h5 class="fw-bold fs-5">Account Details</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Account Status:</div>
<div class="col-9">{{ $userInfo['is_locked'] == 1 ? 'Locked' : 'Active' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Lock Account Description:</div>
<div class="col-9">{{ $userInfo['reason'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Locked Date:</div>
<div class="col-9">{{ $userInfo['lock_dt'] ? \Carbon\Carbon::parse($userInfo['lock_dt'])->format('d-M-Y') : 'N/A' }}</div>
</div>
</div>
</div>
@else
<p>Loading account details...</p>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,49 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>My Profile</h4>
</div>
<div class="card-body">
@if($userInfo)
<div class="d-flex align-items-center p-4" style="background: #F3F3F6; border: 1px solid #E6ECF5;">
<div>
<img src="https://via.placeholder.com/80?text=User" alt="User Avatar" style="width: 80px; height: 80px; border-radius: 50%; background-color: #B8BBC9;">
</div>
<h1 class="m-0 ms-3" style="color: #5a5e76; font-size: 40px;">
{{ $userInfo['firstname'] ?? 'N/A' }} {{ $userInfo['lastname'] ?? 'N/A' }}
</h1>
</div>
<div class="p-4 border border-top-0 border-gray-200">
<div class="mb-4">
<h5 class="fw-bold fs-5">My Information</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Username:</div>
<div class="col-9">{{ $userInfo['username'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Email:</div>
<div class="col-9">
<a href="mailto:{{ $userInfo['email'] ?? '#' }}" style="color: #1890FF;">
{{ $userInfo['email'] ?? 'N/A' }}
</a>
</div>
</div>
</div>
<div>
<h5 class="fw-bold fs-5">Access Role</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Role:</div>
<div class="col-9">{{ $this->getRoleLabel($userInfo['role'] ?? null) }}</div>
</div>
</div>
</div>
@else
<p>Loading profile data...</p>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,47 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Notifications</h4>
<a href="{{ route('notifications.create') }}" class="btn btn-primary">Add Notification</a>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th style="width: 10%;">ID</th>
<th style="width: 10%;">Subject</th>
<th style="width: 30%;">Content</th>
<th style="width: 20%;">Is Scheduled</th>
<th style="width: 20%;">Schedule</th>
<th style="width: 20%;">Expiration</th>
</tr>
</thead>
<tbody>
@forelse ($notifications as $notification)
<tr>
<td>{{ $notification['id'] ?? 'N/A' }}</td>
<td>{{ $notification['subject'] ?? 'N/A' }}</td>
<td>{{ $notification['content'] ?? 'N/A' }}</td>
<td>{{ $notification['isScheduled'] ? 'Yes' : 'No' }}</td>
<td>{{ $notification['schedule'] ? \Carbon\Carbon::parse($notification['schedule'])->format('M d, Y H:i') : 'N/A' }}</td>
<td>{{ $notification['expiration'] ? \Carbon\Carbon::parse($notification['expiration'])->format('M d, Y H:i') : 'N/A' }}</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center">No notifications found.</td>
</tr>
@endforelse
</tbody>
</table>
@if ($updating)
<div class="text-center">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,70 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Add Notification</h4>
</div>
<div class="card-body">
<form wire:submit.prevent="save" novalidate>
@include('partials.header-form', [
'title' => $title,
'loading' => $loading,
'disabled' => false,
'actionBtnName' => 'Submit',
])
<div class="row mb-3">
<label for="subject" class="col-sm-5 col-form-label">Subject</label>
<div class="col-sm-7">
<input type="text" class="form-control @error('subject') is-invalid @enderror" id="subject" wire:model="subject" placeholder="Subject">
@error('subject') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="content" class="col-sm-5 col-form-label">Content</label>
<div class="col-sm-7">
<textarea class="form-control @error('content') is-invalid @enderror" id="content" wire:model="content" rows="6" placeholder="Content"></textarea>
@error('content') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label class="col-sm-5 col-form-label">Schedule</label>
<div class="col-sm-7">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="sched_no" wire:model="isScheduled" value="false">
<label class="form-check-label" for="sched_no">No</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="sched_yes" wire:model="isScheduled" value="true">
<label class="form-check-label" for="sched_yes">Yes</label>
</div>
@error('isScheduled') <div class="text-danger">{{ $message }}</div> @enderror
</div>
</div>
@if ($isScheduled === 'true')
<div class="row mb-3">
<label for="schedule" class="col-sm-5 col-form-label">Schedule</label>
<div class="col-sm-7">
<input type="datetime-local" class="form-control @error('schedule') is-invalid @enderror" id="schedule" wire:model="schedule">
@error('schedule') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="expiration" class="col-sm-5 col-form-label">Expiration</label>
<div class="col-sm-7">
<input type="datetime-local" class="form-control @error('expiration') is-invalid @enderror" id="expiration" wire:model="expiration">
@error('expiration') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
@endif
</form>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,101 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5; padding-bottom: 10px;">
<h2 style="margin: 25px 35px;">Photo Slider Content Details</h2>
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if(!empty($errors))
<div class="alert alert-danger">
<ul>
@foreach ($errors as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form wire:submit.prevent="submit">
@include('partials.header-form', [
'title' => 'Photo Slider',
'action' => '#',
'disabled' => $photoSliderLimit ? 'disabled' : '',
'actionBtnName' => 'Submit',
'cancelAction' => route('photo-slider.index'),
'cancelBtnName' => 'Cancel'
])
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Promotion Name</label>
<div class="col-sm-10">
<select wire:model="form.promotion_uuid" class="form-select" wire:change="fetchDate($event.target.value)" @disabled($photoSliderLimit)>
<option value="">Select Promotion</option>
@foreach ($promotionsOptions as $option)
<option value="{{ $option['value'] }}">{{ $option['label'] }}</option>
@endforeach
</select>
<button type="button" wire:click="autoFillDetails(form.promotion_uuid)" class="btn btn-secondary mt-2" @disabled(!$form['promotion_uuid'])>Auto Fill</button>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Title</label>
<div class="col-sm-10">
<input type="text" wire:model="form.title" class="form-control" placeholder="Title" @disabled($photoSliderLimit)>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Description</label>
<div class="col-sm-10">
<textarea wire:model="form.description" class="form-control" rows="6" placeholder="Description" @disabled($photoSliderLimit)></textarea>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Upload Image</label>
<div class="col-sm-10">
<input type="file" wire:model="form.image" class="form-control" accept=".jpg,.png,.gif" @disabled($photoSliderLimit)>
<small class="form-text text-muted">
Image Size: 1020 x 621<br>
Maximum File Size: 100KB
</small>
@if($form['image'] && is_string($form['image']))
<img src="{{ $form['image'] }}" alt="Preview" style="width: 294px; height: 170px; object-fit: fill; margin-top: 10px;">
@endif
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Start Appearance Date</label>
<div class="col-sm-10">
<input type="date" wire:model="form.date_start" class="form-control" @disabled($photoSliderLimit)>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">End Appearance Date</label>
<div class="col-sm-10">
<input type="date" wire:model="form.date_end" class="form-control" @disabled($photoSliderLimit)>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Start Time</label>
<div class="col-sm-10">
<input type="time" wire:model="form.start_time" class="form-control" @disabled($photoSliderLimit)>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">End Time</label>
<div class="col-sm-10">
<input type="time" wire:model="form.end_time" class="form-control" @disabled($photoSliderLimit)>
</div>
</div>
</form>
</div>

View File

@ -0,0 +1,104 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5; padding-bottom: 10px;">
<h2 style="margin: 25px 35px;">Photo Slider Content Details</h2>
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if(!empty($errors))
<div class="alert alert-danger">
<ul>
@foreach ($errors as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if($slider)
<form wire:submit.prevent="submit">
@include('partials.header-form', [
'title' => 'Update Photo Slider',
'action' => '#',
'actionBtnName' => 'Submit',
'cancelAction' => route('photo-slider.index'),
'cancelBtnName' => 'Cancel'
])
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Promotion Name</label>
<div class="col-sm-10">
<select wire:model="form.promotion_uuid" class="form-select" wire:change="fetchDate($event.target.value)">
<option value="">Select Promotion</option>
@foreach ($promotionsOptions as $option)
<option value="{{ $option['value'] }}" {{ in_array($option['value'], $promotionsDefaultKeyValue) ? 'selected' : '' }}>{{ $option['label'] }}</option>
@endforeach
</select>
<button type="button" wire:click="autoFillDetails(form.promotion_uuid)" class="btn btn-secondary mt-2" @disabled(!$form['promotion_uuid'])>Auto Fill</button>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Title</label>
<div class="col-sm-10">
<input type="text" wire:model="form.title" class="form-control" placeholder="Title">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Description</label>
<div class="col-sm-10">
<textarea wire:model="form.description" class="form-control" rows="6" placeholder="Description"></textarea>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Upload Image</label>
<div class="col-sm-10">
<input type="file" wire:model="form.image" class="form-control" accept=".jpg,.png,.gif">
<small class="form-text text-muted">
Image Size: 1020 x 621<br>
Maximum File Size: 100KB
</small>
@if($form['image'] && is_string($form['image']))
<img src="{{ $form['image'] }}" alt="Preview" style="width: 294px; height: 170px; object-fit: fill; margin-top: 10px;">
@endif
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Start Appearance Date</label>
<div class="col-sm-10">
<input type="date" wire:model="form.date_start" class="form-control">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">End Appearance Date</label>
<div class="col-sm-10">
<input type="date" wire:model="form.date_end" class="form-control">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Start Time</label>
<div class="col-sm-10">
<input type="time" wire:model="form.start_time" class="form-control">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">End Time</label>
<div class="col-sm-10">
<input type="time" wire:model="form.end_time" class="form-control">
</div>
</div>
</form>
@else
<p>No slider data found.</p>
@endif
</div>

View File

@ -0,0 +1,53 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5;">
@include('partials.header-form', [
'title' => 'Photo Slider',
'action' => route('photo-slider.create'),
'disabled' => $photoSliderLimit ? 'disabled' : '',
'actionBtnName' => 'Add Content'
])
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
<div class="card">
<div class="card-body">
<table class="table table-striped">
<thead>
<tr>
<th>Title</th>
<th>Type</th>
<th>Start Date</th>
<th>End Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach ($sliders as $slider)
<tr>
<td>{{ $slider['title'] }}</td>
<td>{{ $slider['type'] }}</td>
<td>{{ \Carbon\Carbon::parse($slider['date_start'])->format('d-M-Y') }}</td>
<td>{{ \Carbon\Carbon::parse($slider['date_end'])->format('d-M-Y') }}</td>
<td>
<a href="{{ route('photo-slider.edit', $slider['photoslider_uuid']) }}" class="btn btn-primary btn-sm me-2">
<i class="fas fa-edit"></i> Edit
</a>
<button wire:click="delete('{{ $slider['photoslider_uuid'] }}')" class="btn btn-danger btn-sm me-2">
<i class="fas fa-trash"></i> Delete
</button>
<a href="{{ route('photo-slider.view', $slider['photoslider_uuid']) }}" class="btn btn-info btn-sm">
<i class="fas fa-eye"></i> View
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,78 @@
<div class="container mt-4" style="border: 1px solid #E6ECF5; padding-bottom: 10px;">
@include('partials.header-form', [
'title' => 'Photo Slider',
'action' => route('photo-slider.edit', ['id' => $slider['photoslider_uuid'] ?? '']),
'styleBtn' => 'background: white; border-color: rgb(184, 187, 201); color: rgb(101, 105, 127)',
'actionBtnName' => 'Update',
'deleteAction' => "delete('{{ $slider['photoslider_uuid'] ?? '' }}')",
'deleteBtnName' => 'Delete'
])
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if($slider)
<div class="card">
<div class="card-body">
<div style="width: 100%; height: 160px;">
<img style="float: left; width: 313px; height: 164px; object-fit: fill;"
src="{{ $slider['image'] }}" alt="Slider Image"
onerror="this.src='https://via.placeholder.com/313x164?text=No+Image';"/>
</div>
<div style="padding: 15px 30px 0px; border-top: 0;">
<h2 style="margin: 0 0 20px;">Details</h2>
<h2 style="font-weight: bold; font-size: 15px;">CONTENT DETAILS</h2>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Title:</span></div>
<div class="col-7">{{ $slider['title'] }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Description:</span></div>
<div class="col-7">{{ $slider['description'] }}</div>
</div>
<h2 style="font-weight: bold; font-size: 15px; margin-top: 12px;">SCHEDULE DETAILS</h2>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Start Appearance Date:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['date_start'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">End Appearance Date:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['date_end'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Start Time:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['date_start'])->format('H:i:s') }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">End Time:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['date_end'])->format('H:i:s') }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Created By:</span></div>
<div class="col-7">{{ $slider['created_by'] }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Date Created:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['created_at'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Last Updated By:</span></div>
<div class="col-7">{{ $slider['updated_by'] }}</div>
</div>
<div class="row mb-2">
<div class="col-5"><span style="font-weight: 600;">Last Date Updated:</span></div>
<div class="col-7">{{ \Carbon\Carbon::parse($slider['updated_at'])->format('d-M-Y') }}</div>
</div>
</div>
</div>
</div>
@else
<p>No slider data found.</p>
@endif
</div>

View File

@ -0,0 +1,17 @@
<div class="container mt-4" style="position: relative; border: 1px solid #E6ECF5;">
@if(Request::is('home-page/photo-slider'))
<livewire:photo-slider.photo-slider-list />
@elseif(Request::is('home-page/photo-slider/create'))
<livewire:photo-slider.photo-slider-create />
@elseif(Request::is('home-page/photo-slider/edit/*'))
<livewire:photo-slider.photo-slider-edit />
@elseif(Request::is('home-page/photo-slider/view/*'))
<livewire:photo-slider.photo-slider-view />
@endif
@if(Request::is('/home-page/photo-slider'))
<script>
window.location.href = '{{ route('photo-slider.index') }}';
</script>
@endif
</div>

View File

@ -0,0 +1,20 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>{{ $title }}</h4>
</div>
<div class="card-body">
@include('partials.promotion-form', [
'branches' => $branches,
'branchesOptionsTwo' => $branchesOptionsTwo,
'promoTypes' => $promoTypes,
'title' => $title,
'loading' => $loading,
])
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,20 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>{{ $title }}</h4>
</div>
<div class="card-body">
@include('partials.promotion-form', [
'branches' => $branches,
'branchesOptionsTwo' => $branchesOptionsTwo,
'promoTypes' => $promoTypes,
'title' => $title,
'loading' => $loading,
])
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,46 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Promotions</h4>
<a href="{{ route('promotions.create') }}" class="btn btn-primary">Add Content</a>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Type</th>
<th>Start Date</th>
<th>End Date</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@forelse ($promotions as $promotion)
<tr>
<td>{{ $promotion['title'] ?? 'N/A' }}</td>
<td>{{ $promotion['promo_type']['name'] ?? 'N/A' }}</td>
<td>{{ \Carbon\Carbon::parse($promotion['date_start'])->format('d-M-Y') }}</td>
<td>{{ \Carbon\Carbon::parse($promotion['date_end'])->format('d-M-Y') }}</td>
<td>{{ $promotion['status'] ?? 'N/A' }}</td>
<td>
<a href="{{ route('promotions.edit', $promotion['promotion_uuid']) }}" class="btn btn-sm btn-warning">Edit</a>
<button class="btn btn-sm btn-danger" wire:click="delete('{{ $promotion['promotion_uuid'] }}')">Delete</button>
<a href="{{ route('promotions.view', $promotion['promotion_uuid']) }}" class="btn btn-sm btn-info">View</a>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center">No promotions found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,104 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Promotion Details</h4>
<div>
<a href="{{ route('promotions.edit', $id) }}" class="btn btn-warning">Update</a>
<button class="btn btn-danger" wire:click="delete">Delete</button>
</div>
</div>
<div class="card-body">
@if($promotion)
<div class="mb-3">
@if($promotion['image'])
<img src="{{ $promotion['image'] }}" alt="Promotion Image" style="width: 313px; height: 164px; object-fit: fill;">
@else
<p>No image available.</p>
@endif
</div>
<div class="mb-4">
<h5 class="fw-bold">Content Details</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Title:</div>
<div class="col-9">{{ $promotion['title'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Description:</div>
<div class="col-9">{{ $promotion['description'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Branch:</div>
<div class="col-9">
@if($promotion['stations'] && count($promotion['stations']) > 0)
@foreach($promotion['stations'] as $station)
{{ $station['description'] }}@if(!$loop->last), @endif
@endforeach
@else
All
@endif
</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Add in Top 2 Promos:</div>
<div class="col-9">{{ $promotion['is_toppromotion'] == 1 ? 'Yes' : 'No' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Add in GPS:</div>
<div class="col-9">{{ $promotion['is_gps'] == 1 ? 'Yes' : 'No' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Status:</div>
<div class="col-9">{{ $promotion['status'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Promo Type:</div>
<div class="col-9">{{ $promotion['promo_type']['name'] ?? 'N/A' }}</div>
</div>
</div>
<div>
<h5 class="fw-bold">Schedule Details</h5>
<div class="row mb-2">
<div class="col-3 fw-semibold">Start Appearance Date:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['date_start'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">End Appearance Date:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['date_end'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Start Time:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['date_start'])->format('H:i') }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">End Time:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['date_end'])->format('H:i') }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Created By:</div>
<div class="col-9">{{ $promotion['created_by'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Date Created:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['created_at'])->format('d-M-Y') }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Last Updated By:</div>
<div class="col-9">{{ $promotion['updated_by'] ?? 'N/A' }}</div>
</div>
<div class="row mb-2">
<div class="col-3 fw-semibold">Last Updated Date:</div>
<div class="col-9">{{ \Carbon\Carbon::parse($promotion['updated_at'])->format('d-M-Y') }}</div>
</div>
</div>
@else
<p>Loading promotion details...</p>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,42 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Mobile Usage Report</h4>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Date</th>
<th>Active Registered Users</th>
<th>Inactive Registered Users</th>
<th>Locked Registered Users</th>
</tr>
</thead>
<tbody>
@forelse ($data as $item)
<tr>
<td>{{ \Carbon\Carbon::parse($item['date'])->format('d-M-Y') }}</td>
<td>{{ $item['active'] ?? '0' }}</td>
<td>{{ $item['inactive'] ?? '0' }}</td>
<td>{{ $item['locked'] ?? '0' }}</td>
</tr>
@empty
<tr>
<td colspan="4" class="text-center">No data found.</td>
</tr>
@endforelse
</tbody>
</table>
@if ($updating)
<div class="text-center">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,40 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Registration Report</h4>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Date</th>
<th>No. of Activated Cards</th>
<th>No. of Registered Members</th>
</tr>
</thead>
<tbody>
@forelse ($data as $item)
<tr>
<td>{{ \Carbon\Carbon::parse($item['date'])->format('d-M-Y') }}</td>
<td>{{ $item['activated'] ?? '0' }}</td>
<td>{{ $item['registered'] ?? '0' }}</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center">No data found.</td>
</tr>
@endforelse
</tbody>
</table>
@if ($updating)
<div class="text-center">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,44 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Station Rating Report</h4>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Transaction Date & Time</th>
<th>Card Number</th>
<th>Sales Invoice</th>
<th>Station</th>
<th>Ratings</th>
</tr>
</thead>
<tbody>
@forelse ($data as $item)
<tr>
<td>{{ \Carbon\Carbon::parse($item['date'])->format('M d, Y H:i') }}</td>
<td>{{ $item['card_number'] ?? 'N/A' }}</td>
<td>{{ $item['invoice'] ?? 'N/A' }}</td>
<td>{{ $item['station'] ?? 'N/A' }}</td>
<td>{{ $item['rate'] ?? 'N/A' }}</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center">No data found.</td>
</tr>
@endforelse
</tbody>
</table>
@if ($updating)
<div class="text-center">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,44 @@
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h4>Top-Up Usage Report</h4>
</div>
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Top-Up Usage Report</h4>
<button class="btn btn-primary" wire:click="exportCsv">Export CSV</button>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Transaction Date & Time</th>
<th>Card Number</th>
<th>Top-up Amount</th>
</tr>
</thead>
<tbody>
@forelse ($data as $item)
<tr>
<td>{{ \Carbon\Carbon::parse($item['date'])->format('M d, Y H:i') }}</td>
<td>{{ $item['card_number'] ?? 'N/A' }}</td>
<td>{{ number_format($item['amount'], 2) }}</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center">No data found.</td>
</tr>
@endforelse
</tbody>
</table>
@if ($updating)
<div class="text-center">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,12 @@
@include('partials.header-form', ['title' => 'My Profile', 'loading' => false, 'disabled' => true, 'actionBtnName' => '', 'cancelBtnName' => ''])
<!-- resources/views/partials/header-form.blade.php -->
<div class="card-header">
<h1>{{ $title }}</h1>
@if(isset($action) && !$disabled)
<a href="{{ $action }}" class="btn" style="{{ $styleBtn ?? '' }}">{{ $actionBtnName }}</a>
@endif
@if(isset($deleteAction))
<button wire:click="{{ $deleteAction }}" class="btn btn-danger ms-2">{{ $deleteBtnName }}</button>
@endif
</div>

View File

@ -0,0 +1,115 @@
<form wire:submit.prevent="save" novalidate>
@include('partials.header-form', ['title' => $title, 'loading' => $loading, 'disabled' => false, 'actionBtnName' => 'Submit'])
<div class="row mb-3">
<label for="title" class="col-sm-5 col-form-label">Title</label>
<div class="col-sm-7">
<input type="text" class="form-control @error('title') is-invalid @enderror" id="title" wire:model="title" placeholder="Title">
@error('title') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="description" class="col-sm-5 col-form-label">Description</label>
<div class="col-sm-7">
<textarea class="form-control @error('description') is-invalid @enderror" id="description" wire:model="description" rows="6" placeholder="Description"></textarea>
@error('description') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="image" class="col-sm-5 col-form-label">Upload Image</label>
<div class="col-sm-7">
<input type="file" class="form-control @error('image') is-invalid @enderror" id="image" wire:model="image" accept=".jpg,.png,.gif">
<small>Image Size: 1020 x 621, Maximum File Size: 100KB</small>
@error('image') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="station_uuid" class="col-sm-5 col-form-label">Branch</label>
<div class="col-sm-7">
<select multiple class="form-control @error('station_uuid') is-invalid @enderror" id="station_uuid" wire:model="station_uuid">
@foreach ($branches as $branch)
<option value="{{ $branch['value'] }}">{{ $branch['label'] }}</option>
@endforeach
</select>
@error('station_uuid') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="date_start" class="col-sm-5 col-form-label">Start Date</label>
<div class="col-sm-7">
<input type="date" class="form-control @error('date_start') is-invalid @enderror" id="date_start" wire:model="date_start">
@error('date_start') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="date_end" class="col-sm-5 col-form-label">End Date</label>
<div class="col-sm-7">
<input type="date" class="form-control @error('date_end') is-invalid @enderror" id="date_end" wire:model="date_end">
@error('date_end') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="start_time" class="col-sm-5 col-form-label">Start Time</label>
<div class="col-sm-7">
<input type="time" class="form-control @error('start_time') is-invalid @enderror" id="start_time" wire:model="start_time">
@error('start_time') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="end_time" class="col-sm-5 col-form-label">End Time</label>
<div class="col-sm-7">
<input type="time" class="form-control @error('end_time') is-invalid @enderror" id="end_time" wire:model="end_time">
@error('end_time') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label class="col-sm-5 col-form-label">Add in Top 2 Promos</label>
<div class="col-sm-7">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="top_yes" wire:model="is_toppromotion" value="1" {{ $is_toppromotion_disabled ? 'disabled' : '' }}>
<label class="form-check-label" for="top_yes">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="top_no" wire:model="is_toppromotion" value="0">
<label class="form-check-label" for="top_no">No</label>
</div>
@error('is_toppromotion') <div class="text-danger">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label for="promo_type" class="col-sm-5 col-form-label">Promo Type</label>
<div class="col-sm-7">
<select class="form-control @error('promo_type') is-invalid @enderror" id="promo_type" wire:model="promo_type">
<option value="">Select Promo Type</option>
@foreach ($promoTypes as $type)
<option value="{{ $type['value'] }}">{{ $type['label'] }}</option>
@endforeach
</select>
@error('promo_type') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div>
</div>
<div class="row mb-3">
<label class="col-sm-5 col-form-label">Add in GPS</label>
<div class="col-sm-7">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="gps_yes" wire:model="is_gps" value="1">
<label class="form-check-label" for="gps_yes">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="gps_no" wire:model="is_gps" value="0">
<label class="form-check-label" for="gps_no">No</label>
</div>
@error('is_gps') <div class="text-danger">{{ $message }}</div> @enderror
</div>
</div>
</form>

View File

@ -59,6 +59,63 @@ use App\Livewire\StationLocator\BranchList;
use App\Livewire\StationLocator\CreateBranch;
use App\Livewire\StationLocator\EditBranch;
use App\Livewire\Reports\TopUpList;
use App\Livewire\Reports\StationRatingList;
use App\Livewire\Reports\MobileUsageList;
use App\Livewire\Reports\RegistrationList;
use App\Livewire\Promotions\PromotionsList;
use App\Livewire\Promotions\PromotionsCreate;
use App\Livewire\Promotions\PromotionsEdit;
use App\Livewire\Promotions\PromotionsView;
use App\Livewire\Notifications\NotificationList;
use App\Livewire\Notifications\NotificationsCreate;
use App\Livewire\MyProfile\MyProfileView;
use App\Livewire\MemberManagement\CardMemberList;
use App\Livewire\MemberManagement\CardMemberView;
use App\Livewire\MemberManagement\LockAccountList;
use App\Livewire\MemberManagement\LockAccountView;
use App\Http\Livewire\PhotoSlider\PhotoSlider;
use App\Http\Livewire\PhotoSlider\PhotoSliderView;
use App\Http\Livewire\PhotoSlider\PhotoSliderList;
use App\Http\Livewire\PhotoSlider\PhotoSliderCreate;
use App\Http\Livewire\PhotoSlider\PhotoSliderEdit;
// Route::get('/home-page/photo-slider', PhotoSlider::class)->name('photo-slider.index');
// Route::get('/home-page/photo-slider/create', PhotoSlider::class)->name('photo-slider.create');
// Route::get('/home-page/photo-slider/edit/{id}', PhotoSlider::class)->name('photo-slider.edit');
// Route::get('/home-page/photo-slider/view/{id}', PhotoSliderView::class)->name('photo-slider.view');
// Route::get('/member-management/card-member', CardMemberList::class)->name('member-management.card-member');
// Route::get('/member-management/card-member/view/{id}', CardMemberView::class)->name('member-management.card-member.view');
// Route::get('/member-management/lock-account', LockAccountList::class)->name('member-management.lock-account');
// Route::get('/member-management/lock-account/view/{id}', LockAccountView::class)->name('member-management.lock-account.view');
// Route::get('/my-profile', MyProfileView::class)->name('my-profile.view');
// Route::get('/notifications', NotificationList::class)->name('notifications.list');
// Route::get('/notifications/create', NotificationsCreate::class)->name('notifications.create');
// Route::get('/promotions', PromotionsList::class)->name('promotions.list');
// Route::get('/promotions/create', PromotionsCreate::class)->name('promotions.create');
// Route::get('/promotions/edit/{id}', PromotionsEdit::class)->name('promotions.edit');
// Route::get('/promotions/view/{id}', PromotionsView::class)->name('promotions.view');
// Route::get('/reports/top-up', TopUpList::class)->name('reports.top-up');
// Route::get('/reports/station-rating', StationRatingList::class)->name('reports.station-rating');
// Route::get('/reports/mobile-report', MobileUsageList::class)->name('reports.mobile-report');
// Route::get('/reports/registration-report', RegistrationList::class)->name('reports.registration-report');
// Route::get('/reports', function () {
// return redirect('/reports/top-up');
// });
// Route::get('/fuels', FuelList::class)->name('fuels.list');
// Route::get('/fuels/create', CreateFuel::class)->name('fuels.create');
// Route::get('/fuels/view/{id}', EditFuel::class)->name('fuels.edit');