user crud functionality added

This commit is contained in:
erishBRBS 2025-05-21 10:19:35 +08:00
parent eebdeb9074
commit b09ac700aa
9 changed files with 159 additions and 79 deletions

View File

@ -49,6 +49,7 @@ class CreateUser extends Component
$token = Session::get('user')['access_token'] ?? null; $token = Session::get('user')['access_token'] ?? null;
if (!$token) { if (!$token) {
$this->addError('users', 'No access token found.'); $this->addError('users', 'No access token found.');
return; return;
@ -64,6 +65,9 @@ class CreateUser extends Component
'password' => $this->default_password, 'password' => $this->default_password,
]); ]);
// dd($response->json());
//handle backend response //handle backend response
if ($response->status() === 422) { if ($response->status() === 422) {
$errors = $response->json('data'); $errors = $response->json('data');

View File

@ -45,6 +45,23 @@ class Table extends Component
public $showModal = false; public $showModal = false;
public $modalMode = 'view'; public $modalMode = 'view';
public $modalData = []; public $modalData = [];
public $confirmingDeleteId = null;
public function confirmDelete($id)
{
$this->confirmingDeleteId = $id;
}
public function deleteConfirmed()
{
if (!$this->confirmingDeleteId) return;
$this->deleteRow($this->confirmingDeleteId);
// Reset the confirmation state
$this->confirmingDeleteId = null;
}
public function mount($columns, $rows, $addRoute = null, $rowKey = 'id') public function mount($columns, $rows, $addRoute = null, $rowKey = 'id')
{ {
@ -74,30 +91,53 @@ class Table extends Component
$this->showModal = true; $this->showModal = true;
} }
public function saveRow() public function saveRow()
{ {
$token = Session::get('user')['access_token'] ?? null; $token = Session::get('user')['access_token'] ?? null;
$url = rtrim(config('services.backend_api.url'), '/') . '/' . $this->updateEndpoint . '/' . $this->modalData[$this->rowKey]; $url = rtrim(config('services.backend_api.url'), '/') . '/' . $this->updateEndpoint . '/' . $this->modalData[$this->rowKey];
try { try {
$response = Http::withToken($token)->put($url, $this->modalData); $response = Http::withToken($token)->put($url, $this->modalData);
if ($response->successful()) { if ($response->successful()) {
$this->closeModal(); $this->closeModal();
$this->fetchData(); $this->fetchData();
} else { } else {
$errors = $response->json('errors') ?? []; $errors = $response->json('errors') ?? [];
foreach ($errors as $field => $messages) { foreach ($errors as $field => $messages) {
$this->addError("modalData.$field", is_array($messages) ? $messages[0] : $messages); $this->addError("modalData.$field", is_array($messages) ? $messages[0] : $messages);
}
} }
} catch (\Exception $e) {
logger()->error('SaveRow error: ' . $e->getMessage());
$this->addError('modalData', 'Something went wrong. Please try again.');
}
}
public function deleteRow($id)
{
$token = Session::get('user')['access_token'] ?? null;
$url = rtrim(config('services.backend_api.url'), '/') . '/' . $this->deleteEndpoint . '/' . $id;
try {
$response = Http::withToken($token)->delete($url);
if ($response->successful()) {
$this->fetchData();
} else {
$errors = $response->json('errors') ?? [];
foreach ($errors as $field => $messages) {
$this->addError("modalData.$field", is_array($messages) ? $messages[0] : $messages);
}
}
} catch (\Exception $e) {
logger()->error('DeleteRow error: ' . $e->getMessage());
$this->addError('modalData', 'Something went wrong. Please try again.');
} }
} catch (\Exception $e) {
logger()->error('SaveRow error: ' . $e->getMessage());
$this->addError('modalData', 'Something went wrong. Please try again.');
} }
}

View File

@ -28,20 +28,21 @@ class UserManagement extends Component
$response = Http::withToken($token) $response = Http::withToken($token)
->get(config('services.backend_api.url') . '/api/cms/admin'); ->get(config('services.backend_api.url') . '/api/cms/admin');
// dd($response->json()); // dd($response->json());
if ($response->successful()) { if ($response->successful()) {
// Properly use collect to handle the response data // Properly use collect to handle the response data
$this->users = collect($response->json()['data'])->map(function ($user) { $this->users = collect($response->json()['data'])->map(function ($user) {
return [ return [
'admin_uuid' => $user['admin_uuid'], 'admin_uuid' => $user['admin_uuid'],
'username' => $user['username'], 'username' => $user['username'],
'firstname' => $user['firstname'], 'firstname' => $user['firstname'],
'lastname' => $user['lastname'], 'lastname' => $user['lastname'],
'email' => $user['email'], 'email' => $user['email'],
'role' => $user['role'], 'role' => $user['role'],
'status' => $user['status'], 'status' => $user['status'],
]; ];
}); });
} else { } else {
$this->addError('users', 'Failed to load users.'); $this->addError('users', 'Failed to load users.');
} }
@ -57,4 +58,3 @@ class UserManagement extends Component
]); ]);
} }
} }

View File

@ -20,7 +20,7 @@ services:
timeout: 10s timeout: 10s
retries: 10 retries: 10
networks: networks:
- app_network - unioil-network
db_mysql: db_mysql:
@ -40,14 +40,14 @@ services:
timeout: 10s timeout: 10s
retries: 5 retries: 5
networks: networks:
- app_network - unioil-network
nginx: nginx:
image: nginx:alpine image: nginx:alpine
container_name: unioil-nginx container_name: unioil-nginx
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8000:80" - "8000:81"
volumes: volumes:
- .:/var/www/html - .:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
@ -55,7 +55,7 @@ services:
app: app:
condition: service_healthy condition: service_healthy
networks: networks:
- app_network - unioil-network
volumes: volumes:
mysql-data: mysql-data:
@ -63,5 +63,5 @@ volumes:
driver: local driver: local
networks: networks:
app_network: unioil-network:
driver: bridge driver: bridge

View File

@ -1,5 +1,5 @@
server { server {
listen 80; listen 81;
server_name localhost; server_name localhost;
root /var/www/html/public; root /var/www/html/public;

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{ {
"name": "unioil-cms-fe", "name": "html",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -31,19 +31,19 @@
@endif @endif
@if ($hasAddButton ?? true) @if ($hasAddButton ?? true)
<!-- Add button --> <!-- Add button -->
<a href="{{ $addRoute }}" class="bg-orange-600 text-white px-4 py-2 rounded"> <a href="{{ $addRoute }}" class="bg-orange-600 text-white px-4 py-2 rounded hover:bg-orange-700">
+ Add + Add
</a> </a>
@elseif ($hasExportButton ?? false) @elseif ($hasExportButton ?? false)
<!-- Export button --> <!-- Export button -->
<button wire:click="export" class="bg-orange-600 text-white px-4 py-2 rounded flex items-center gap-2"> <button wire:click="export" class="bg-orange-600 text-white px-4 py-2 rounded flex items-center gap-2">
Export Export
</button> </button>
@else @else
@endif @endif
</div> </div>
<!-- Table Header --> <!-- Table Header -->
@ -115,7 +115,7 @@
<button wire:click="viewRow('{{ $row[$rowKey] ?? $index }}')" class="text-gray-500 hover:text-gray-700"> <button wire:click="viewRow('{{ $row[$rowKey] ?? $index }}')" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-eye"></i> <i class="fas fa-eye"></i>
</button> </button>
<button wire:click="deleteRow('{{ $row[$rowKey] ?? $index }}')" class="text-red-500 hover:text-red-700"> <button wire:click="confirmDelete('{{ $row[$rowKey] ?? $index }}')" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> <i class="fas fa-trash-alt"></i>
</button> </button>
@endif @endif
@ -196,9 +196,18 @@
<label class="block text-sm font-medium text-gray-700"> <label class="block text-sm font-medium text-gray-700">
{{ $column['label'] }} {{ $column['label'] }}
</label> </label>
@if ($modalMode === 'edit') @if ($modalMode === 'edit')
<input type="text" wire:model.defer="modalData.{{ $column['field'] }}" @if ($column['type'] === 'select')
<select wire:model.defer="modalData.{{ $column['field'] }}" class="mt-1 p-2 border border-gray-300 rounded w-full">
@foreach ($column['options'] as $key => $label)
<option value="{{ $key }}">{{ $label }}</option>
@endforeach
</select>
@else
<input type="{{ $column['type'] }}" wire:model.defer="modalData.{{ $column['field'] }}"
class="mt-1 p-2 border border-gray-300 rounded w-full"> class="mt-1 p-2 border border-gray-300 rounded w-full">
@endif
@else @else
<div class="mt-1 p-2 bg-gray-100 rounded"> <div class="mt-1 p-2 bg-gray-100 rounded">
{{ $modalData[$column['field']] ?? '' }} {{ $modalData[$column['field']] ?? '' }}
@ -211,7 +220,7 @@
<!-- Modal Footer with Save Button (if in edit mode) --> <!-- Modal Footer with Save Button (if in edit mode) -->
@if ($modalMode === 'edit') @if ($modalMode === 'edit')
<div class="mt-6 flex justify-end"> <div class="mt-6 flex justify-end">
<button wire:click="saveRow" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"> <button wire:click="saveRow" class="px-4 py-2 bg-orange-600 text-white rounded hover:bg-orange-700">
Save Save
</button> </button>
</div> </div>
@ -219,5 +228,26 @@
</div> </div>
</div> </div>
@endif @endif
<!-- Confirmation Modal for Deletion -->
@if ($confirmingDeleteId)
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div class="bg-white rounded-lg shadow-lg p-6 w-full max-w-md">
<h2 class="text-lg font-bold mb-4">Confirm Delete</h2>
<p class="mb-6">Are you sure you want to delete this item? This action cannot be undone.</p>
<div class="flex justify-end space-x-2">
<button wire:click="$set('confirmingDeleteId', null)" class="px-4 py-2 bg-gray-300 text-gray-800 rounded-md hover:bg-gray-400">
Cancel
</button>
<button wire:click="deleteConfirmed" class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 cursor-pointer">
Yes, Delete
</button>
</div>
</div>
</div>
@endif
</div> </div>
</div> </div>

View File

@ -1,29 +1,34 @@
<div> <div>
@include('livewire.user-management.top-nav.user-management') @include('livewire.user-management.top-nav.user-management')
@if (session()->has('success')) @if (session()->has('success'))
<div <div
x-data="{ show: true }" x-data="{ show: true }"
x-init="setTimeout(() => show = false, 3000)" x-init="setTimeout(() => show = false, 3000)"
x-show="show" x-show="show"
x-transition x-transition
class="text-2xl text-green-700 px-4 py-2 rounded mb-4" class="text-2xl text-green-700 px-4 py-2 rounded mb-4">
>
{{ session('success') }} {{ session('success') }}
</div> </div>
@endif @endif
<livewire:components.table <livewire:components.table
:columns="[ :columns="[
['label' => 'Username', 'field' => 'username'], ['label' => 'Username', 'field' => 'username', 'type' => 'text'],
['label' => 'First Name', 'field' => 'firstname'], ['label' => 'First Name', 'field' => 'firstname', 'type' => 'text'],
['label' => 'Last Name', 'field' => 'lastname'], ['label' => 'Last Name', 'field' => 'lastname', 'type' => 'text'],
['label' => 'Email', 'field' => 'email'], ['label' => 'Email', 'field' => 'email', 'type' => 'text'],
['label' => 'Role', 'field' => 'role'], ['label' => 'Role', 'field' => 'role', 'type' => 'select', 'options' => [
['label' => 'Status', 'field' => 'status'], 1 => 'Admin',
]" 0 => 'Marketing Personnel'
]],
['label' => 'Status', 'field' => 'status', 'type' => 'select', 'options' =>[
'active' => 'Active',
'inactive' => 'Inactive'
]],
]"
:rows="$users" :rows="$users"
:addRoute="route('user-create')" :addRoute="route('user-create')"
:hasAddButton="true" :hasAddButton="true"
@ -32,5 +37,6 @@
:isViewPage="false" :isViewPage="false"
:rowKey="'admin_uuid'" :rowKey="'admin_uuid'"
:updateEndpoint="'api/cms/admin'" :updateEndpoint="'api/cms/admin'"
/> :deleteEndpoint="'api/cms/admin'"
/>
</div> </div>

View File

@ -24,13 +24,13 @@ use Illuminate\Support\Facades\Route;
//laravel page //laravel page
// Route::get('/', function () { Route::get('/', function () {
// return redirect()->route('login'); return redirect()->route('login');
// }); });
// Route::get('/login', function () { Route::get('/login', function () {
// return view('auth.log-in'); return view('auth.log-in');
// })->name('login'); })->name('login');
Route::get('/login', LoginForm::class)->name('login'); // Route::get('/login', LoginForm::class)->name('login');
// // Route::get('/login', LoginForm::class)->name('layouts.app'); // // Route::get('/login', LoginForm::class)->name('layouts.app');