Initial commit

This commit is contained in:
2025-11-20 23:21:05 +08:00
commit 13bc6db529
378 changed files with 54527 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Profile') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
<div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg">
<div class="max-w-xl">
@include('profile.partials.update-profile-information-form')
</div>
</div>
<div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg">
<div class="max-w-xl">
@include('profile.partials.update-password-form')
</div>
</div>
<div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg">
<div class="max-w-xl">
@include('profile.partials.delete-user-form')
</div>
</div>
</div>
</div>
</x-app-layout>

View File

@@ -0,0 +1,55 @@
<section class="space-y-6">
<header>
<h2 class="text-lg font-medium text-gray-900">
{{ __('Delete Account') }}
</h2>
<p class="mt-1 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.') }}
</p>
</header>
<x-danger-button
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.destroy') }}" class="p-6">
@csrf
@method('delete')
<h2 class="text-lg font-medium text-gray-900">
{{ __('Are you sure you want to delete your account?') }}
</h2>
<p class="mt-1 text-sm text-gray-600">
{{ __('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="ms-3">
{{ __('Delete Account') }}
</x-danger-button>
</div>
</form>
</x-modal>
</section>

View File

@@ -0,0 +1,48 @@
<section>
<header>
<h2 class="text-lg font-medium text-gray-900">
{{ __('Update Password') }}
</h2>
<p class="mt-1 text-sm text-gray-600">
{{ __('Ensure your account is using a long, random password to stay secure.') }}
</p>
</header>
<form method="post" action="{{ route('password.update') }}" class="mt-6 space-y-6">
@csrf
@method('put')
<div>
<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="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="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>
<div class="flex items-center gap-4">
<x-primary-button>{{ __('Save') }}</x-primary-button>
@if (session('status') === 'password-updated')
<p
x-data="{ show: true }"
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600"
>{{ __('Saved.') }}</p>
@endif
</div>
</form>
</section>

View File

@@ -0,0 +1,170 @@
<section>
<header>
<h2 class="text-lg font-medium text-gray-900">
{{ __('Profile Information') }}
</h2>
<p class="mt-1 text-sm text-gray-600">
{{ __("Update your account's profile information and email address.") }}
</p>
</header>
<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" enctype="multipart/form-data">
@if ($user->profilePhotoUrl())
<div class="flex items-center space-x-4">
<img src="{{ $user->profilePhotoUrl() }}" alt="{{ __('Profile photo for :name', ['name' => $user->name]) }}" class="h-16 w-16 rounded-full object-cover">
<p class="text-sm text-gray-600">{{ __('This is your current profile photo.') }}</p>
</div>
@endif
<div>
<x-input-label for="profile_photo" :value="__('Profile Photo')" />
<input
id="profile_photo"
name="profile_photo"
type="file"
class="mt-1 block w-full text-sm text-gray-900 file:mr-4 file:rounded-md file:border-0 file:bg-indigo-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-indigo-700 hover:file:bg-indigo-100"
accept="image/*"
/>
<x-input-error class="mt-2" :messages="$errors->get('profile_photo')" />
</div>
@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" />
<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)" required autocomplete="username" />
<x-input-error class="mt-2" :messages="$errors->get('email')" />
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
<div>
<p class="text-sm mt-2 text-gray-800">
{{ __('Your email address is unverified.') }}
<button form="send-verification" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
{{ __('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">
{{ __('A new verification link has been sent to your email address.') }}
</p>
@endif
</div>
@endif
</div>
<div>
<x-input-label for="phone" :value="__('Phone')" />
<x-text-input
id="phone"
name="phone"
type="text"
class="mt-1 block w-full"
:value="old('phone', optional($member)->phone)"
autocomplete="tel"
/>
<x-input-error class="mt-2" :messages="$errors->get('phone')" />
</div>
<div>
<x-input-label for="address_line_1" :value="__('Address Line 1')" />
<x-text-input
id="address_line_1"
name="address_line_1"
type="text"
class="mt-1 block w-full"
:value="old('address_line_1', optional($member)->address_line_1)"
/>
<x-input-error class="mt-2" :messages="$errors->get('address_line_1')" />
</div>
<div>
<x-input-label for="address_line_2" :value="__('Address Line 2')" />
<x-text-input
id="address_line_2"
name="address_line_2"
type="text"
class="mt-1 block w-full"
:value="old('address_line_2', optional($member)->address_line_2)"
/>
<x-input-error class="mt-2" :messages="$errors->get('address_line_2')" />
</div>
<div class="grid gap-4 sm:grid-cols-2">
<div>
<x-input-label for="city" :value="__('City')" />
<x-text-input
id="city"
name="city"
type="text"
class="mt-1 block w-full"
:value="old('city', optional($member)->city)"
/>
<x-input-error class="mt-2" :messages="$errors->get('city')" />
</div>
<div>
<x-input-label for="postal_code" :value="__('Postal Code')" />
<x-text-input
id="postal_code"
name="postal_code"
type="text"
class="mt-1 block w-full"
:value="old('postal_code', optional($member)->postal_code)"
/>
<x-input-error class="mt-2" :messages="$errors->get('postal_code')" />
</div>
</div>
<div>
<x-input-label for="emergency_contact_name" :value="__('Emergency Contact Name')" />
<x-text-input
id="emergency_contact_name"
name="emergency_contact_name"
type="text"
class="mt-1 block w-full"
:value="old('emergency_contact_name', optional($member)->emergency_contact_name)"
/>
<x-input-error class="mt-2" :messages="$errors->get('emergency_contact_name')" />
</div>
<div>
<x-input-label for="emergency_contact_phone" :value="__('Emergency Contact Phone')" />
<x-text-input
id="emergency_contact_phone"
name="emergency_contact_phone"
type="text"
class="mt-1 block w-full"
:value="old('emergency_contact_phone', optional($member)->emergency_contact_phone)"
/>
<x-input-error class="mt-2" :messages="$errors->get('emergency_contact_phone')" />
</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"
>{{ __('Saved.') }}</p>
@endif
</div>
</form>
</section>