Skip to content

Commit

Permalink
feat: Added default pagination section
Browse files Browse the repository at this point in the history
  • Loading branch information
lewislarsen committed Aug 1, 2024
1 parent c2dc212 commit 5f03090
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 101 deletions.
2 changes: 1 addition & 1 deletion app/Livewire/BackupDestinations/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function render(): View
{
$backupDestinations = BackupDestination::where('user_id', Auth::id())
->orderBy('created_at', 'desc')
->paginate(30, pageName: 'backup-destinations');
->paginate(Auth::user()?->getAttribute('pagination_count') ?? 15, pageName: 'backup-destinations');

return view('livewire.backup-destinations.index-table', ['backupDestinations' => $backupDestinations]);
}
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/BackupTasks/Tables/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function render(): View
->with(['remoteServer', 'backupDestination'])
->withAggregate('latestLog', 'created_at')
->orderBy('id', 'desc')
->paginate(10, pageName: 'backup-tasks');
->paginate(Auth::user()?->getAttribute('pagination_count') ?? 15, pageName: 'backup-tasks');

return view('livewire.backup-tasks.tables.index-table', ['backupTasks' => $backupTasks]);
}
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/NotificationStreams/Tables/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function render(): View
{
$notificationStreams = NotificationStream::where('user_id', Auth::id())
->orderBy('id', 'desc')
->paginate(10, pageName: 'notification-streams');
->paginate(Auth::user()?->getAttribute('pagination_count') ?? 15, pageName: 'notification-streams');

return view('livewire.notification-streams.tables.index-table', [
'notificationStreams' => $notificationStreams,
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/RemoteServers/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function render(): View
$remoteServers = RemoteServer::where('user_id', Auth::id())
->whereNull('marked_for_deletion_at')
->orderBy('created_at', 'desc')
->paginate(30, pageName: 'remote-servers');
->paginate(Auth::user()?->getAttribute('pagination_count') ?? 15, pageName: 'remote-servers');

return view('livewire.remote-servers.index-table', ['remoteServers' => $remoteServers]);
}
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Tags/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function render(): View
{
$tags = Tag::where('user_id', Auth::id())
->orderBy('created_at', 'desc')
->paginate(30, pageName: 'tags');
->paginate(Auth::user()?->getAttribute('pagination_count') ?? 15, pageName: 'tags');

return view('livewire.tags.index-table', ['tags' => $tags]);
}
Expand Down
1 change: 1 addition & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class User extends Authenticatable
'language',
'gravatar_email',
'weekly_summary_opt_in_at',
'pagination_count',
];

protected $hidden = [
Expand Down
1 change: 1 addition & 0 deletions database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function definition(): array
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
'timezone' => 'UTC',
'pagination_count' => '25',
'language' => 'en',
'weekly_summary_opt_in_at' => now(),
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->integer('pagination_count')->default(15);
});
}
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\Rule;
Expand All @@ -15,6 +16,8 @@
public ?int $preferred_backup_destination_id = null;
public string $language = 'en'; // Default language is english.
public ?bool $receiving_weekly_summary_email = false;
public int $pagination_count;
public Collection $pagination_options;
public function mount(): void
{
Expand All @@ -25,6 +28,8 @@ public function mount(): void
$this->preferred_backup_destination_id = Auth::user()->preferred_backup_destination_id ?? null;
$this->language = Auth::user()->language;
$this->receiving_weekly_summary_email = Auth::user()->isOptedInForWeeklySummary();
$this->pagination_count = Auth::user()->getAttribute('pagination_count');
$this->pagination_options = collect([15, 30, 50, 100])->mapWithKeys(fn($value) => [$value => "{$value} per page"]);
}
public function updateProfileInformation(): void
Expand All @@ -38,6 +43,7 @@ public function updateProfileInformation(): void
'timezone' => ['required', 'string', 'max:255', Rule::in(timezone_identifiers_list())],
'preferred_backup_destination_id' => ['nullable', 'integer', Rule::exists('backup_destinations', 'id')->where('user_id', $user->id)],
'receiving_weekly_summary_email' => ['required', 'boolean'],
'pagination_count' => ['required', 'integer', 'min:1', 'max:100', 'in:15,30,50,100'],
'language' => [
'required',
'string',
Expand Down Expand Up @@ -71,7 +77,9 @@ public function messages(): array
'email.email' => __('Please enter an email address.'),
'gravatar_email.email' => __('Please enter an email address.'),
'timezone.required' => __('Please specify a timezone.'),
'language.required' => __('Please specify a language for your account.')
'language.required' => __('Please specify a language for your account.'),
'pagination_count.required' => __('Please specify a valid pagination value for your account.'),
'pagination.count_integer' => __('The count must be an integer.')
];
}
Expand Down Expand Up @@ -102,117 +110,136 @@ public function sendVerification(): void
<x-slot name="icon">
heroicon-o-user
</x-slot>
<form wire:submit="updateProfileInformation" class="mt-6 space-y-6">
<div class="mt-4">
<form wire:submit="updateProfileInformation" class="mt-6 space-y-6">
<div class="mt-4">
<x-input-label for="avatar" :value="__('Avatar')"/>
<div class="flex items-center mt-2">
<div x-data="{ imageLoaded: false }" class="relative w-20 h-20">
<div
x-show="!imageLoaded"
class="absolute inset-0 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse"
></div>
<img
x-on:load="imageLoaded = true"
x-bind:class="{ 'opacity-0': !imageLoaded, 'opacity-100': imageLoaded }"
class="w-20 h-20 rounded-full transition-opacity duration-300"
src="{{ Auth::user()->gravatar('160') }}"
/>
<div class="mt-4">
<x-input-label for="avatar" :value="__('Avatar')"/>
<div class="flex items-center mt-2">
<div x-data="{ imageLoaded: false }" class="relative w-20 h-20">
<div
x-show="!imageLoaded"
class="absolute inset-0 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse"
></div>
<img
x-on:load="imageLoaded = true"
x-bind:class="{ 'opacity-0': !imageLoaded, 'opacity-100': imageLoaded }"
class="w-20 h-20 rounded-full transition-opacity duration-300"
src="{{ Auth::user()->gravatar('160') }}"
/>
</div>
<a href="https://gravatar.com" target="_blank"
class="ml-4 text-sm text-gray-600 dark:text-gray-400 underline hover:text-gray-900 dark:hover:text-gray-100 transition-colors ease-in-out">
{{ __('Update your avatar on Gravatar') }}
</a>
</div>
<a href="https://gravatar.com" target="_blank"
class="ml-4 text-sm text-gray-600 dark:text-gray-400 underline hover:text-gray-900 dark:hover:text-gray-100 transition-colors ease-in-out">
{{ __('Update your avatar on Gravatar') }}
</a>
</div>
</div>
</div>
<!-- Grid layout for form fields -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="name" :value="__('Name')"/>
<x-text-input wire:model="name" id="name" name="name" type="text" class="mt-1 block w-full" required autofocus autocomplete="name"/>
<x-input-error class="mt-2" :messages="$errors->get('name')"/>
</div>
<!-- Grid layout for form fields -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="name" :value="__('Name')"/>
<x-text-input wire:model="name" id="name" name="name" type="text" class="mt-1 block w-full" required
autofocus autocomplete="name"/>
<x-input-error class="mt-2" :messages="$errors->get('name')"/>
</div>

<div>
<x-input-label for="email" :value="__('Email')"/>
<x-text-input wire:model="email" id="email" name="email" type="email" class="mt-1 block w-full" required autocomplete="username"/>
<x-input-error class="mt-2" :messages="$errors->get('email')"/>
@if (auth()->user() instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! auth()->user()->hasVerifiedEmail())
<!-- Email verification section -->
@endif
</div>
<div>
<x-input-label for="email" :value="__('Email')"/>
<x-text-input wire:model="email" id="email" name="email" type="email" class="mt-1 block w-full" required
autocomplete="username"/>
<x-input-error class="mt-2" :messages="$errors->get('email')"/>
@if (auth()->user() instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! auth()->user()->hasVerifiedEmail())
<!-- Email verification section -->
@endif
</div>

<div>
<x-input-label for="gravatar_email" :value="__('Gravatar Email')"/>
<x-text-input wire:model="gravatar_email" id="gravatar_email" name="gravatar_email" type="email" class="mt-1 block w-full" autofocus autocomplete="gravatar_email"/>
<x-input-explain>
{{ __('Enter an alternative email address to use for your Gravatar picture. If left blank, your primary email will be used.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('gravatar_email')"/>
</div>
<div>
<x-input-label for="gravatar_email" :value="__('Gravatar Email')"/>
<x-text-input wire:model="gravatar_email" id="gravatar_email" name="gravatar_email" type="email"
class="mt-1 block w-full" autofocus autocomplete="gravatar_email"/>
<x-input-explain>
{{ __('Enter an alternative email address to use for your Gravatar picture. If left blank, your primary email will be used.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('gravatar_email')"/>
</div>

<div>
<x-input-label for="timezone" :value="__('Timezone')"/>
<x-select wire:model="timezone" id="timezone" name="timezone" class="mt-1 block w-full">
@foreach (formatTimezones() as $identifier => $timezone)
<option value="{{ $identifier }}">{{ $timezone }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('Your timezone is used to display dates and times to you in your local time.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('timezone')"/>
</div>
<div>
<x-input-label for="timezone" :value="__('Timezone')"/>
<x-select wire:model="timezone" id="timezone" name="timezone" class="mt-1 block w-full">
@foreach (formatTimezones() as $identifier => $timezone)
<option value="{{ $identifier }}">{{ $timezone }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('Your timezone is used to display dates and times to you in your local time.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('timezone')"/>
</div>

<div>
<x-input-label for="language" :value="__('Language')"/>
<x-select wire:model.live="language" id="language" name="language" class="mt-1 block w-full">
@foreach (config('app.available_languages') as $code => $language)
<option value="{{ $code }}">{{ $language }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('Please select your preferred language from the dropdown list. This will change the language used throughout the application.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('language')"/>
</div>
<div>
<x-input-label for="language" :value="__('Language')"/>
<x-select wire:model.live="language" id="language" name="language" class="mt-1 block w-full">
@foreach (config('app.available_languages') as $code => $language)
<option value="{{ $code }}">{{ $language }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('Please select your preferred language from the dropdown list. This will change the language used throughout the application.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('language')"/>
</div>

@if (!Auth::user()->backupDestinations->isEmpty())
<div>
<x-input-label for="preferred_backup_destination_id" :value="__('Default Backup Destination')"/>
<x-select wire:model="preferred_backup_destination_id" id="preferred_backup_destination_id"
name="preferred_backup_destination_id" class="mt-1 block w-full">
<option value="">{{ __('None') }}</option>
@foreach (Auth::user()->backupDestinations as $backupDestination)
<option value="{{ $backupDestination->id }}">{{ $backupDestination->label }}
- {{ $backupDestination->type() }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('The backup destination you select here will be set as the default location for storing new backup tasks.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('preferred_backup_destination_id')"/>
</div>
@endif

@if (!Auth::user()->backupDestinations->isEmpty())
<div>
<x-input-label for="preferred_backup_destination_id" :value="__('Default Backup Destination')"/>
<x-select wire:model="preferred_backup_destination_id" id="preferred_backup_destination_id" name="preferred_backup_destination_id" class="mt-1 block w-full">
<option value="">{{ __('None') }}</option>
@foreach (Auth::user()->backupDestinations as $backupDestination)
<option value="{{ $backupDestination->id }}">{{ $backupDestination->label }} - {{ $backupDestination->type() }}</option>
<x-input-label for="weekly_summary_opt_in" :value="__('Weekly Backup Summary Emails')"/>
<x-toggle
name="receiving_weekly_summary_email"
model="receiving_weekly_summary_email"
/>
<x-input-explain>
{{ __('Get a summary of your weekly backup tasks every Monday morning.') }}
</x-input-explain>
</div>

<div>
<x-input-label for="pagination_count" :value="__('Items per Page')" />
<x-select wire:model="pagination_count" id="pagination_count" name="pagination_count" class="mt-1 block w-full">
@foreach ($pagination_options as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</x-select>
<x-input-explain>
{{ __('The backup destination you select here will be set as the default location for storing new backup tasks.') }}
{{ __('Select the number of items you want to see per page in lists throughout the application. This setting affects how many backup tasks, servers, and other items are displayed at once.') }}
</x-input-explain>
<x-input-error class="mt-2" :messages="$errors->get('preferred_backup_destination_id')"/>
<x-input-error class="mt-2" :messages="$errors->get('pagination_count')" />
</div>
@endif

<div>
<x-input-label for="weekly_summary_opt_in" :value="__('Weekly Backup Summary Emails')"/>
<x-toggle
name="receiving_weekly_summary_email"
model="receiving_weekly_summary_email"
/>
<x-input-explain>
{{ __('Get a summary of your weekly backup tasks every Monday morning.') }}
</x-input-explain>

</div>
</div>
<div class="mt-6 pb-4 max-w-3xl mx-auto">
<div class="flex justify-center">
<div class="w-full sm:w-4/6">
<x-primary-button type="submit" class="w-full justify-center" centered action="submit">
{{ __('Save') }}
</x-primary-button>
<div class="mt-6 pb-4 max-w-3xl mx-auto">
<div class="flex justify-center">
<div class="w-full sm:w-4/6">
<x-primary-button type="submit" class="w-full justify-center" centered action="submit">
{{ __('Save') }}
</x-primary-button>
</div>
</div>
</div>
</div>
</form>
</form>
</x-form-wrapper>
Loading

0 comments on commit 5f03090

Please sign in to comment.