Update user table

This commit is contained in:
Julian Prieber 2024-12-16 18:30:35 +01:00
parent 591e3743f5
commit dd83134643
5 changed files with 10365 additions and 172 deletions

View File

@ -0,0 +1,138 @@
<?php
namespace App\Http\Livewire;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use App\Models\User;
use App\Models\Link;
class UsersTable extends DataTableComponent
{
protected $model = User::class;
protected $listeners = ['refresh' => '$refresh'];
public function configure(): void
{
$this->setPrimaryKey('id');
$this->setDefaultSort('created_at', 'asc');
$this->setPerPageAccepted([50, 100, 250, 500, 1000, -1]);
$this->setColumnSelectEnabled();
$this->setThAttributes(function(Column $column) {
return ['default' => true];
});
}
public function columns(): array
{
return [
Column::make(__('messages.ID'), "id")
->sortable()
->searchable(),
Column::make(__('messages.Name'), "name")
->sortable()
->searchable(),
Column::make(__('messages.E-Mail'), "email")
->sortable()
->searchable(),
Column::make(__('messages.Page'), "littlelink_name")
->sortable()
->searchable()
->format(function ($value, $row, Column $column) {
if (!$row->littlelink_name == NULL) {
return "<a href='" . url('') . "/@" . htmlspecialchars($row->littlelink_name) . "' target='_blank' class='text-info'><i class='bi bi-box-arrow-up-right'></i>&nbsp; " . htmlspecialchars($row->littlelink_name) . " </a>";
} else {
return 'N/A';
}
})
->html(),
Column::make(__('messages.Role'), "role")
->sortable()
->searchable(),
Column::make(__('messages.Links'), "id")
->format(function ($value, $row) {
$linkCount = Link::where('user_id', $row->id)->count();
return $linkCount;
}),
Column::make(__('messages.Clicks'), "id")
->format(function ($value, $row) {
$clicksSum = Link::where('user_id', $row->id)->sum('click_number');
return $clicksSum;
}),
Column::make(__('messages.E-Mail'), "email_verified_at")
->sortable()
->format(function ($value, $row, Column $column) {
if (env('REGISTER_AUTH') !== 'auth') {
if ($row->role == 'admin' && $row->email_verified_at != '') {
return '<div class="text-center">-</div>';
} else {
if($row->email_verified_at == ''){
$verifyLinkBool = 'true';
} else {
$verifyLinkBool = 'false';
}
$verifyLink = route('verifyUser', [
'verify' => $verifyLinkBool,
'id' => $row->id
]);
if ($row->email_verified_at == '') {
return '<div class="text-center"><a style="cursor:pointer" data-id="'.$verifyLink.'" class="user-email text-danger"><span class="badge bg-danger">' . __('messages.Pending') . '</span></a></div>';
} else {
return '<div class="text-center"><a style="cursor:pointer" data-id="'.$verifyLink.'" class="user-email text-danger"><span class="badge bg-success">' . __('messages.Verified') . '</span></a></div>';
}
}
} else {
return '<div class="text-center">-</div>';
}
return '';
})->html(),
Column::make(__('messages.Status'), "block")
->sortable()
->format(function ($value, $row, Column $column) {
if ($row->role === 'admin' && $row->id === 1) {
return '<div class="text-center">-</div>';
} else {
$route = route('blockUser', ['block' => $row->block, 'id' => $row->id]);
if ($row->block === 'yes') {
$badge = '<div class="text-center"><a style="cursor:pointer" data-id="'.$route.'" class="user-block text-danger"><span class="badge bg-danger">'.__('messages.Pending').'</span></a></div>';
} elseif ($row->block === 'no') {
$badge = '<div class="text-center"><a style="cursor:pointer" data-id="'.$route.'" class="user-block text-danger"><span class="badge bg-success">'.__('messages.Approved').'</span></a></div>';
}
return "<a href=\"$route\">$badge</a>";
}
})
->html(),
Column::make(__('messages.Created at'), "created_at")
->sortable()
->format(function ($value) {
if ($value) {
return $value->format('d/m/y');
} else {
return '';
}
}),
Column::make(__('messages.Last seen'), "updated_at")
->sortable()
->format(function ($value) {
$now = now();
$diff = $now->diff($value);
if ($diff->d < 1 && $diff->h < 1) {
return 'Now';
} elseif ($diff->d < 1 && $diff->h < 24) {
return $diff->h . ' hours ago';
} elseif ($diff->d < 365) {
return $diff->d . ' days ago';
} else {
return $diff->y . ' years ago';
}
}),
Column::make(__('messages.Action'), "id")
->format(function ($value, $row, Column $column) {
return view('components.table-components.action', ['user' => $row]);
}),
];
}
}

10114
assets/vendor/livewire/livewire.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,8 @@
"laravel/framework": "^10.42.0",
"laravel/socialite": "^5.5",
"laravel/tinker": "^2.5",
"livewire/livewire": "^2.12",
"rappasoft/laravel-livewire-tables": "^2.15",
"livewire/livewire": "^3.0",
"rappasoft/laravel-livewire-tables": "^3.0",
"simplesoftwareio/simple-qrcode": "~4",
"spatie/laravel-backup": "^8.1.5"
},

View File

@ -3,156 +3,158 @@
return [
/*
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
| Class Namespace
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
|
| This value sets the root namespace for Livewire component classes in
| your application. This value affects component auto-discovery and
| any Livewire file helper commands, like `artisan make:livewire`.
|
| After changing this item, run: `php artisan livewire:discover`.
| This value sets the root class namespace for Livewire component classes in
| your application. This value will change where component auto-discovery
| finds components. It's also referenced by the file creation commands.
|
*/
'class_namespace' => 'App\\Http\\Livewire',
/*
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
| View Path
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
|
| This value sets the path for Livewire component views. This affects
| file manipulation helper commands like `artisan make:livewire`.
| This value is used to specify where Livewire component Blade templates are
| stored when running file creation commands like `artisan make:livewire`.
| It is also used if you choose to omit a component's render() method.
|
*/
'view_path' => resource_path('views/livewire'),
/*
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
| Layout
|--------------------------------------------------------------------------
| The default layout view that will be used when rendering a component via
| Route::get('/some-endpoint', SomeComponent::class);. In this case the
| the view returned by SomeComponent will be wrapped in "layouts.app"
|---------------------------------------------------------------------------
| The view that will be used as the layout when rendering a single component
| as an entire page via `Route::get('/post/create', CreatePost::class);`.
| In this case, the view returned by CreatePost will render into $slot.
|
*/
'layout' => 'layouts.app',
'layout' => 'components.layouts.app',
/*
|--------------------------------------------------------------------------
| Livewire Assets URL
|--------------------------------------------------------------------------
|
| This value sets the path to Livewire JavaScript assets, for cases where
| your app's domain root is not the correct path. By default, Livewire
| will load its JavaScript assets from the app's "relative root".
|
| Examples: "/assets", "myurl.com/app".
|---------------------------------------------------------------------------
| Lazy Loading Placeholder
|---------------------------------------------------------------------------
| Livewire allows you to lazy load components that would otherwise slow down
| the initial page load. Every component can have a custom placeholder or
| you can define the default placeholder view for all components below.
|
*/
'asset_url' => null,
'lazy_placeholder' => null,
/*
|--------------------------------------------------------------------------
| Livewire App URL
|--------------------------------------------------------------------------
|
| This value should be used if livewire assets are served from CDN.
| Livewire will communicate with an app through this url.
|
| Examples: "https://my-app.com", "myurl.com/app".
|
*/
'app_url' => null,
/*
|--------------------------------------------------------------------------
| Livewire Endpoint Middleware Group
|--------------------------------------------------------------------------
|
| This value sets the middleware group that will be applied to the main
| Livewire "message" endpoint (the endpoint that gets hit everytime
| a Livewire component updates). It is set to "web" by default.
|
*/
'middleware_group' => 'web',
/*
|--------------------------------------------------------------------------
| Livewire Temporary File Uploads Endpoint Configuration
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
| Temporary File Uploads
|---------------------------------------------------------------------------
|
| Livewire handles file uploads by storing uploads in a temporary directory
| before the file is validated and stored permanently. All file uploads
| are directed to a global endpoint for temporary storage. The config
| items below are used for customizing the way the endpoint works.
| before the file is stored permanently. All file uploads are directed to
| a global endpoint for temporary storage. You may configure this below:
|
*/
'temporary_file_upload' => [
'disk' => null, // Example: 'local', 's3' Default: 'default'
'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB)
'directory' => null, // Example: 'tmp' Default 'livewire-tmp'
'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1'
'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs.
'disk' => null, // Example: 'local', 's3' | Default: 'default'
'rules' => null, // Example: ['file', 'mimes:png,jpg'] | Default: ['required', 'file', 'max:12288'] (12MB)
'directory' => null, // Example: 'tmp' | Default: 'livewire-tmp'
'middleware' => null, // Example: 'throttle:5,1' | Default: 'throttle:60,1'
'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs...
'png', 'gif', 'bmp', 'svg', 'wav', 'mp4',
'mov', 'avi', 'wmv', 'mp3', 'm4a',
'jpg', 'jpeg', 'mpga', 'webp', 'wma',
],
'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated.
'max_upload_time' => 5, // Max duration (in minutes) before an upload is invalidated...
'cleanup' => true, // Should cleanup temporary uploads older than 24 hrs...
],
/*
|--------------------------------------------------------------------------
| Manifest File Path
|--------------------------------------------------------------------------
|
| This value sets the path to the Livewire manifest file.
| The default should work for most cases (which is
| "<app_root>/bootstrap/cache/livewire-components.php"), but for specific
| cases like when hosting on Laravel Vapor, it could be set to a different value.
|
| Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php".
|
*/
'manifest_path' => null,
/*
|--------------------------------------------------------------------------
| Back Button Cache
|--------------------------------------------------------------------------
|
| This value determines whether the back button cache will be used on pages
| that contain Livewire. By disabling back button cache, it ensures that
| the back button shows the correct state of components, instead of
| potentially stale, cached data.
|
| Setting it to "false" (default) will disable back button cache.
|
*/
'back_button_cache' => false,
/*
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
| Render On Redirect
|--------------------------------------------------------------------------
|---------------------------------------------------------------------------
|
| This value determines whether Livewire will render before it's redirected
| or not. Setting it to "false" (default) will mean the render method is
| skipped when redirecting. And "true" will mean the render method is
| run before redirecting. Browsers bfcache can store a potentially
| stale view if render is skipped on redirect.
| This value determines if Livewire will run a component's `render()` method
| after a redirect has been triggered using something like `redirect(...)`
| Setting this to true will render the view once more before redirecting
|
*/
'render_on_redirect' => false,
/*
|---------------------------------------------------------------------------
| Eloquent Model Binding
|---------------------------------------------------------------------------
|
| Previous versions of Livewire supported binding directly to eloquent model
| properties using wire:model by default. However, this behavior has been
| deemed too "magical" and has therefore been put under a feature flag.
|
*/
'legacy_model_binding' => false,
/*
|---------------------------------------------------------------------------
| Auto-inject Frontend Assets
|---------------------------------------------------------------------------
|
| By default, Livewire automatically injects its JavaScript and CSS into the
| <head> and <body> of pages containing Livewire components. By disabling
| this behavior, you need to use @livewireStyles and @livewireScripts.
|
*/
'inject_assets' => true,
/*
|---------------------------------------------------------------------------
| Navigate (SPA mode)
|---------------------------------------------------------------------------
|
| By adding `wire:navigate` to links in your Livewire application, Livewire
| will prevent the default link handling and instead request those pages
| via AJAX, creating an SPA-like effect. Configure this behavior here.
|
*/
'navigate' => [
'show_progress_bar' => true,
'progress_bar_color' => '#2299dd',
],
/*
|---------------------------------------------------------------------------
| HTML Morph Markers
|---------------------------------------------------------------------------
|
| Livewire intelligently "morphs" existing HTML into the newly rendered HTML
| after each update. To make this process more reliable, Livewire injects
| "markers" into the rendered Blade surrounding @if, @class & @foreach.
|
*/
'inject_morph_markers' => true,
/*
|---------------------------------------------------------------------------
| Pagination Theme
|---------------------------------------------------------------------------
|
| When enabling Livewire's pagination feature by using the `WithPagination`
| trait, Livewire will use Tailwind templates to render pagination views
| on the page. If you want Bootstrap CSS, you can specify: "bootstrap"
|
*/
'pagination_theme' => 'bootstrap',
];

View File

@ -34,7 +34,7 @@
</button>
</div>
<livewire:user-table />
<livewire:users-table />
<a href="{{ url('') }}/admin/new-user">+ {{__('messages.Add new user')}}</a>
@ -91,72 +91,13 @@
// Function to refresh the Livewire table
var refreshLivewireTable = function() {
Livewire.components.getComponentsByName('user-table')[0].$wire.$refresh()
Livewire.dispatch('refresh');
};
attachClickEventListeners('confirmation', confirmIt);
attachClickEventListeners('user-email', handleUserClick);
attachClickEventListeners('user-block', handleUserClick);
</script>
{{-- <script type="text/javascript">
// Get the delete button div
var deleteButtonDiv = document.getElementById('select-active');
// Get all checkboxes
var checkboxes = document.querySelectorAll('.form-check-input');
// Function to check if at least one checkbox is selected
var isAnyCheckboxSelected = function() {
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
return true;
}
}
return false;
};
// Function to show or hide the delete button div
var showOrHideDeleteButton = function() {
if (isAnyCheckboxSelected()) {
deleteButtonDiv.classList.remove('d-none');
} else {
setTimeout(function() {
deleteButtonDiv.classList.add('d-none');
});
}
};
// Add event listener to checkboxes
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('change', showOrHideDeleteButton);
}
// Get the delete button
var deleteButton = deleteButtonDiv.querySelector('button');
// Function to delete selected users
var deleteSelectedUsers = function() {
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked && checkboxes[i].getAttribute('data-id') !== null) {
var userId = checkboxes[i].getAttribute('data-id');
// Find the corresponding <a> element
var deleteButton = document.querySelector('a[data-id="' + userId + '"]');
// If the <a> element exists, add loading spinner to it
if (deleteButton) {
deleteButton.innerHTML = '<div class="d-flex justify-content-center"><div class="spinner-border spinner-border-sm text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';
}
deleteUserData(userId);
}
}
};
// Add event listener to delete button
deleteButton.addEventListener('click', deleteSelectedUsers);
</script> --}}
</div>
</section>
@ -171,13 +112,11 @@ deleteButton.addEventListener('click', deleteSelectedUsers);
</div>
@push('sidebar-stylesheets')
<script defer src="{{url('assets/js/cdn.min.js')}}"></script>
<script src="{{url('vendor/livewire/livewire/dist/livewire.js')}}"></script>
@livewireStyles
@endpush
@push('sidebar-scripts')
<livewire:scripts />
<script src="{{url('assets/js/livewire-sortable.js')}}"></script>
<script src="{{url('/assets/vendor/livewire/livewire.js')}}" data-update-uri="/livewire/update" data-navigate-once="true"></script>
@endpush
@endsection