Add Auth System (Breeze)

This commit is contained in:
2026-01-07 16:04:23 +01:00
parent e972f8db41
commit 256af435ad
44 changed files with 1314 additions and 203 deletions

View File

@@ -1,78 +0,0 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('Profile') }}
</h2>
</x-slot>
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
<div class="flex flex-row gap-4 flex-wrap">
<!-- Profile Image -->
<div class="p-2 bg-white dark:bg-neutral-800 shadow rounded-lg flex-none">
@if($user->discord_avatar)
<img class="w-28 h-28 rounded-lg m-2" src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $user->discord_id }}/{{ $user->discord_avatar }}.webp" alt="{{ $user->discord_name ?? $user->name }} Avatar">
@else
<img class="w-24 h-24 rounded-lg m-2" src="/images/default-avatar.webp" alt="{{ $user->discord_name ?? $user->name }} Avatar">
@endif
</div>
<!-- Joined -->
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow rounded-lg content-center text-center grow">
<div class="inline-block rounded-md text-sky-500">
<i class="fa-solid fa-clock text-3xl"></i>
</div>
<h5 class="font-medium dark:text-neutral-300">
Joined {{ $user->created_at->format('Y-m') }}
</h5>
</div>
<!-- View Count -->
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow rounded-lg content-center text-center grow">
<a href="{{ route('user.watched') }}">
<div class="inline-block rounded-md text-sky-500">
<i class="fa-solid fa-eye text-3xl"></i>
</div>
<h5 class="font-medium dark:text-neutral-300">
{{ number_format($user->watched->count()) }} views
</h5>
</a>
</div>
<!-- Comment Count -->
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow rounded-lg content-center text-center grow">
<a href="{{ route('profile.comments') }}">
<div class="inline-block rounded-md text-sky-500">
<i class="fa-solid fa-comment text-3xl"></i>
</div>
<h5 class="font-medium dark:text-neutral-300">
{{ number_format($user->commentCount()) }} comments
</h5>
</a>
</div>
<!-- Likes -->
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow rounded-lg content-center text-center grow">
<a href="{{ route('profile.likes') }}">
<div class="inline-block rounded-md text-sky-500">
<i class="fa-solid fa-heart text-3xl"></i>
</div>
<h5 class="font-medium dark:text-neutral-300">
{{ number_format($user->likes()) }} likes
</h5>
</a>
</div>
<!-- Playlists -->
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow rounded-lg content-center text-center grow">
<a href="{{ route('profile.playlists') }}">
<div class="inline-block rounded-md text-sky-500">
<i class="fa-solid fa-rectangle-list text-3xl"></i>
</div>
<h5 class="font-medium dark:text-neutral-300">
{{ number_format($user->playlists->count()) }} playlists
</h5>
</a>
</div>
</div>
</div>
</x-app-layout>

View File

@@ -10,29 +10,43 @@
</header>
<x-danger-button
x-data=""
x-on:click.prevent="$dispatch('open-modal', 'confirm-user-deletion')"
x-data=""
x-on:click.prevent="$dispatch('open-modal', 'confirm-user-deletion')"
>{{ __('Delete Account') }}</x-danger-button>
<x-modal name="confirm-user-deletion" :show="$errors->userDeletion->isNotEmpty()" focusable>
<form method="POST" action="{{ route('profile.delete') }}" class="p-6">
@csrf
@method('delete')
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
{{ __('Are you sure you want to delete your account?') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted.') }}
{{ __('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.') }}
</p>
{{-- <div class="mt-6">
<x-input-label for="password" value="{{ __('Password') }}" class="sr-only" />
<x-text-input
id="password"
name="password"
type="password"
class="mt-1 block w-3/4"
placeholder="{{ __('Password') }}"
/>
<x-input-error :messages="$errors->userDeletion->get('password')" class="mt-2" />
</div> --}}
<div class="mt-6 flex justify-end">
<x-secondary-button x-on:click="$dispatch('close')">
{{ __('Cancel') }}
</x-secondary-button>
<x-danger-button class="ml-3">
<x-danger-button class="ms-3">
{{ __('Delete Account') }}
</x-danger-button>
</div>

View File

@@ -14,20 +14,20 @@
@method('put')
<div>
<x-input-label for="current_password" :value="__('Current Password')" />
<x-text-input id="current_password" name="current_password" type="password" class="mt-1 block w-full" autocomplete="current-password" />
<x-input-label for="update_password_current_password" :value="__('Current Password')" />
<x-text-input id="update_password_current_password" name="current_password" type="password" class="mt-1 block w-full" autocomplete="current-password" />
<x-input-error :messages="$errors->updatePassword->get('current_password')" class="mt-2" />
</div>
<div>
<x-input-label for="password" :value="__('New Password')" />
<x-text-input id="password" name="password" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-label for="update_password_password" :value="__('New Password')" />
<x-text-input id="update_password_password" name="password" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password')" class="mt-2" />
</div>
<div>
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
<x-text-input id="password_confirmation" name="password_confirmation" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-label for="update_password_password_confirmation" :value="__('Confirm Password')" />
<x-text-input id="update_password_password_confirmation" name="password_confirmation" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password_confirmation')" class="mt-2" />
</div>

View File

@@ -1,36 +1,72 @@
<section>
<header>
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<i class="fa-brands fa-discord"></i> {{ __('Profile Information') }}
{{ __('Profile Information') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ __("Update your account's profile information and email address.") }}
</p>
</header>
<div class="mt-6 space-y-6">
<form id="send-verification" method="post" action="{{ route('verification.send') }}">
@csrf
</form>
<form method="post" action="{{ route('profile.update') }}" class="mt-6 space-y-6">
@csrf
@method('patch')
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autofocus autocomplete="name" disabled />
<x-input-error class="mt-2" :messages="$errors->get('name')" />
</div>
@if (Auth::user()->discord_name)
<div>
<x-input-label for="discord_name" :value="__('Display Name')" />
<x-input-label for="discord_name" :value="__('Discord Name')" />
<x-text-input id="discord_name" name="discord_name" type="text" class="mt-1 block w-full" :value="old('discord_name', $user->discord_name)" required autocomplete="discord_name" disabled />
<x-input-error class="mt-2" :messages="$errors->get('discord_name')" />
</div>
@endif
<div>
<x-input-label for="name" :value="__('Username')" />
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autocomplete="name" disabled />
<x-input-error class="mt-2" :messages="$errors->get('name')" />
</div>
<div>
<x-input-label for="email" :value="__('Email')" />
<x-text-input id="email" name="email" type="email" class="mt-1 block w-full" :value="old('email', $user->email ?? __('Unknown'))" required autocomplete="email" disabled />
<x-text-input id="email" name="email" type="email" class="mt-1 block w-full" :value="old('email', $user->email)" required autocomplete="email" disabled />
<x-input-error class="mt-2" :messages="$errors->get('email')" />
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->verified)
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
<div>
<p class="text-sm mt-2 text-gray-800 dark:text-gray-200">
{{ __('Your email address is unverified.') }}
<button form="send-verification" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">
{{ __('Click here to re-send the verification email.') }}
</button>
</p>
@if (session('status') === 'verification-link-sent')
<p class="mt-2 font-medium text-sm text-green-600 dark:text-green-400">
{{ __('A new verification link has been sent to your email address.') }}
</p>
@endif
</div>
@endif
</div>
</div>
{{-- <div class="flex items-center gap-4">
<x-primary-button>{{ __('Save') }}</x-primary-button>
@if (session('status') === 'profile-updated')
<p
x-data="{ show: true }"
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600 dark:text-gray-400"
>{{ __('Saved.') }}</p>
@endif
</div> --}}
</form>
</section>