Jetstream dashboard

This commit is contained in:
2020-09-16 05:01:27 +05:00
parent adc02dc83b
commit bdb60e74fa
89 changed files with 4011 additions and 103 deletions

View File

@@ -0,0 +1,51 @@
<x-jet-action-section>
<x-slot name="title">
{{ __('Delete Account') }}
</x-slot>
<x-slot name="description">
{{ __('Permanently delete your account.') }}
</x-slot>
<x-slot name="content">
<div class="max-w-xl text-sm text-gray-600">
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
</div>
<div class="mt-5">
<x-jet-danger-button wire:click="confirmUserDeletion" wire:loading.attr="disabled">
{{ __('Delete Account') }}
</x-jet-danger-button>
</div>
<!-- Delete User Confirmation Modal -->
<x-jet-dialog-modal wire:model="confirmingUserDeletion">
<x-slot name="title">
{{ __('Delete Account') }}
</x-slot>
<x-slot name="content">
{{ __('Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
<div class="mt-4" x-data="{}" x-on:confirming-delete-user.window="setTimeout(() => $refs.password.focus(), 250)">
<x-jet-input type="password" class="mt-1 block w-3/4" placeholder="Password"
x-ref="password"
wire:model.defer="password"
wire:keydown.enter="deleteUser" />
<x-jet-input-error for="password" class="mt-2" />
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button wire:click="$toggle('confirmingUserDeletion')" wire:loading.attr="disabled">
{{ __('Nevermind') }}
</x-jet-secondary-button>
<x-jet-danger-button class="ml-2" wire:click="deleteUser" wire:loading.attr="disabled">
{{ __('Delete Account') }}
</x-jet-danger-button>
</x-slot>
</x-jet-dialog-modal>
</x-slot>
</x-jet-action-section>

View File

@@ -0,0 +1,94 @@
<x-jet-action-section>
<x-slot name="title">
{{ __('Browser Sessions') }}
</x-slot>
<x-slot name="description">
{{ __('Manage and logout your active sessions on other browsers and devices.') }}
</x-slot>
<x-slot name="content">
<div class="max-w-xl text-sm text-gray-600">
{{ __('If necessary, you may logout of all of your other browser sessions across all of your devices. If you feel your account has been compromised, you should also update your password.') }}
</div>
@if (count($this->sessions) > 0)
<div class="mt-5 space-y-6">
<!-- Other Browser Sessions -->
@foreach ($this->sessions as $session)
<div class="flex items-center">
<div>
@if ($session->agent->isDesktop())
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor" class="w-8 h-8 text-gray-500">
<path d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
@else
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" class="w-8 h-8 text-gray-500">
<path d="M0 0h24v24H0z" stroke="none"></path><rect x="7" y="4" width="10" height="16" rx="1"></rect><path d="M11 5h2M12 17v.01"></path>
</svg>
@endif
</div>
<div class="ml-3">
<div class="text-sm text-gray-600">
{{ $session->agent->platform() }} - {{ $session->agent->browser() }}
</div>
<div>
<div class="text-xs text-gray-500">
{{ $session->ip_address }},
@if ($session->is_current_device)
<span class="text-green-500 font-semibold">{{ __('This device') }}</span>
@else
{{ __('Last active') }} {{ $session->last_active }}
@endif
</div>
</div>
</div>
</div>
@endforeach
</div>
@endif
<div class="flex items-center mt-5">
<x-jet-button wire:click="confirmLogout" wire:loading.attr="disabled">
{{ __('Logout Other Browser Sessions') }}
</x-jet-button>
<x-jet-action-message class="ml-3" on="loggedOut">
{{ __('Done.') }}
</x-jet-action-message>
</div>
<!-- Logout Other Devices Confirmation Modal -->
<x-jet-dialog-modal wire:model="confirmingLogout">
<x-slot name="title">
{{ __('Logout Other Browser Sessions') }}
</x-slot>
<x-slot name="content">
{{ __('Please enter your password to confirm you would like to logout of your other browser sessions across all of your devices.') }}
<div class="mt-4" x-data="{}" x-on:confirming-logout-other-browser-sessions.window="setTimeout(() => $refs.password.focus(), 250)">
<x-jet-input type="password" class="mt-1 block w-3/4" placeholder="Password"
x-ref="password"
wire:model.defer="password"
wire:keydown.enter="logoutOtherBrowserSessions" />
<x-jet-input-error for="password" class="mt-2" />
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button wire:click="$toggle('confirmingLogout')" wire:loading.attr="disabled">
{{ __('Nevermind') }}
</x-jet-secondary-button>
<x-jet-button class="ml-2" wire:click="logoutOtherBrowserSessions" wire:loading.attr="disabled">
{{ __('Logout Other Browser Sessions') }}
</x-jet-button>
</x-slot>
</x-jet-dialog-modal>
</x-slot>
</x-jet-action-section>

View File

@@ -0,0 +1,41 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Profile') }}
</h2>
</x-slot>
<div>
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
@livewire('profile.update-profile-information-form')
@if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()))
<x-jet-section-border />
<div class="mt-10 sm:mt-0">
@livewire('profile.update-password-form')
</div>
@endif
@if (Laravel\Fortify\Features::canManageTwoFactorAuthentication())
<x-jet-section-border />
<div class="mt-10 sm:mt-0">
@livewire('profile.two-factor-authentication-form')
</div>
@endif
<x-jet-section-border />
<div class="mt-10 sm:mt-0">
@livewire('profile.logout-other-browser-sessions-form')
</div>
<x-jet-section-border />
<div class="mt-10 sm:mt-0">
@livewire('profile.delete-user-form')
</div>
</div>
</div>
</x-app-layout>

View File

@@ -0,0 +1,83 @@
<x-jet-action-section>
<x-slot name="title">
{{ __('Two Factor Authentication') }}
</x-slot>
<x-slot name="description">
{{ __('Add additional security to your account using two factor authentication.') }}
</x-slot>
<x-slot name="content">
<h3 class="text-lg font-medium text-gray-900">
@if ($this->enabled)
{{ __('You have enabled two factor authentication.') }}
@else
{{ __('You have not enabled two factor authentication.') }}
@endif
</h3>
<div class="mt-3 max-w-xl text-sm text-gray-600">
<p>
{{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.') }}
</p>
</div>
@if ($this->enabled)
@if ($showingQrCode)
<div class="mt-4 max-w-xl text-sm text-gray-600">
<p class="font-semibold">
{{ __('Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application.') }}
</p>
</div>
<div class="mt-4">
{!! $this->user->twoFactorQrCodeSvg() !!}
</div>
@endif
@if ($showingRecoveryCodes)
<div class="mt-4 max-w-xl text-sm text-gray-600">
<p class="font-semibold">
{{ __('Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.') }}
</p>
</div>
<div class="grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-gray-100 rounded-lg">
@foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as $code)
<div>{{ $code }}</div>
@endforeach
</div>
@endif
@endif
<div class="mt-5">
@if (! $this->enabled)
<x-jet-confirms-password wire:then="enableTwoFactorAuthentication">
<x-jet-button type="button" wire:loading.attr="disabled">
{{ __('Enable') }}
</x-jet-button>
</x-jet-confirms-password>
@else
@if ($showingRecoveryCodes)
<x-jet-confirms-password wire:then="regenerateRecoveryCodes">
<x-jet-secondary-button class="mr-3">
{{ __('Regenerate Recovery Codes') }}
</x-jet-secondary-button>
</x-jet-confirms-password>
@else
<x-jet-confirms-password wire:then="showRecoveryCodes">
<x-jet-secondary-button class="mr-3">
{{ __('Show Recovery Codes') }}
</x-jet-secondary-button>
</x-jet-confirms-password>
@endif
<x-jet-confirms-password wire:then="disableTwoFactorAuthentication">
<x-jet-danger-button wire:loading.attr="disabled">
{{ __('Disable') }}
</x-jet-danger-button>
</x-jet-confirms-password>
@endif
</div>
</x-slot>
</x-jet-action-section>

View File

@@ -0,0 +1,39 @@
<x-jet-form-section submit="updatePassword">
<x-slot name="title">
{{ __('Update Password') }}
</x-slot>
<x-slot name="description">
{{ __('Ensure your account is using a long, random password to stay secure.') }}
</x-slot>
<x-slot name="form">
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="current_password" value="{{ __('Current Password') }}" />
<x-jet-input id="current_password" type="password" class="mt-1 block w-full" wire:model.defer="state.current_password" autocomplete="current-password" />
<x-jet-input-error for="current_password" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="password" value="{{ __('New Password') }}" />
<x-jet-input id="password" type="password" class="mt-1 block w-full" wire:model.defer="state.password" autocomplete="new-password" />
<x-jet-input-error for="password" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="password_confirmation" value="{{ __('Confirm Password') }}" />
<x-jet-input id="password_confirmation" type="password" class="mt-1 block w-full" wire:model.defer="state.password_confirmation" autocomplete="new-password" />
<x-jet-input-error for="password_confirmation" class="mt-2" />
</div>
</x-slot>
<x-slot name="actions">
<x-jet-action-message class="mr-3" on="saved">
{{ __('Saved.') }}
</x-jet-action-message>
<x-jet-button>
{{ __('Save') }}
</x-jet-button>
</x-slot>
</x-jet-form-section>

View File

@@ -0,0 +1,79 @@
<x-jet-form-section submit="updateProfileInformation">
<x-slot name="title">
{{ __('Profile Information') }}
</x-slot>
<x-slot name="description">
{{ __('Update your account\'s profile information and email address.') }}
</x-slot>
<x-slot name="form">
<!-- Profile Photo -->
@if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
<div x-data="{photoName: null, photoPreview: null}" class="col-span-6 sm:col-span-4">
<!-- Profile Photo File Input -->
<input type="file" class="hidden"
wire:model="photo"
x-ref="photo"
x-on:change="
photoName = $refs.photo.files[0].name;
const reader = new FileReader();
reader.onload = (e) => {
photoPreview = e.target.result;
};
reader.readAsDataURL($refs.photo.files[0]);
" />
<x-jet-label for="photo" value="{{ __('Photo') }}" />
<!-- Current Profile Photo -->
<div class="mt-2" x-show="! photoPreview">
<img src="{{ $this->user->profile_photo_url }}" alt="{{ $this->user->name }}" class="rounded-full h-20 w-20 object-cover">
</div>
<!-- New Profile Photo Preview -->
<div class="mt-2" x-show="photoPreview">
<span class="block rounded-full w-20 h-20"
x-bind:style="'background-size: cover; background-repeat: no-repeat; background-position: center center; background-image: url(\'' + photoPreview + '\');'">
</span>
</div>
<x-jet-secondary-button class="mt-2 mr-2" type="button" x-on:click.prevent="$refs.photo.click()">
{{ __('Select A New Photo') }}
</x-jet-secondary-button>
@if ($this->user->profile_photo_path)
<x-jet-secondary-button type="button" class="mt-2" wire:click="deleteProfilePhoto">
{{ __('Remove Photo') }}
</x-jet-secondary-button>
@endif
<x-jet-input-error for="photo" class="mt-2" />
</div>
@endif
<!-- Name -->
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="name" value="{{ __('Name') }}" />
<x-jet-input id="name" type="text" class="mt-1 block w-full" wire:model.defer="state.name" autocomplete="name" />
<x-jet-input-error for="name" class="mt-2" />
</div>
<!-- Email -->
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="email" value="Email" />
<x-jet-input id="email" type="email" class="mt-1 block w-full" wire:model.defer="state.email" />
<x-jet-input-error for="email" class="mt-2" />
</div>
</x-slot>
<x-slot name="actions">
<x-jet-action-message class="mr-3" on="saved">
{{ __('Saved.') }}
</x-jet-action-message>
<x-jet-button>
{{ __('Save') }}
</x-jet-button>
</x-slot>
</x-jet-form-section>