mirror of
https://codeberg.org/JasterV/spazio-solazzo.git
synced 2026-04-26 18:20:03 +00:00
This pull request makes phone numbers optional for both user registrations and bookings, and updates validation, database schema, and UI to reflect this change. The main focus is to ensure that users are no longer required to provide a phone number, and that the application gracefully handles cases where a phone number is absent. **Database & Resource Model Updates** * Made the `phone_number` attribute in the `users` table and the `customer_phone` attribute in the `bookings` table nullable, including migration and resource snapshot updates. [[1]](diffhunk://#diff-baa6aed3674c4d6cbbebeafb076662df02dc4c25231dbd9dc9c8f0534ed1a1bfR1-R29) [[2]](diffhunk://#diff-a401f66b2ae5bfb798eb1bc2221bfeeac943e258950c90d59570b0bae05d3664R1-R244) [[3]](diffhunk://#diff-0c1180d6f6abc19b5987c8703bdee9ef67905535202f950e8327c32bd5b89d8aR1-R82) * Updated Ash resource definitions in `user.ex` and `booking.ex` to allow `phone_number` and `customer_phone` to be `nil`. [[1]](diffhunk://#diff-9194b9d80dce091f6dcb56f784217272ae160e35454c4b4ccc8850ad5ee06e38L152-R152) [[2]](diffhunk://#diff-4b1ddd6d86899f2144c69d142883b8719c755e32c03dbda5da2188208a5ad503L55-R55) [[3]](diffhunk://#diff-4b1ddd6d86899f2144c69d142883b8719c755e32c03dbda5da2188208a5ad503L170-R170) **Validation & Parsing Logic** * Renamed and refactored user registration field validation to `ParseRegistrationFields`, allowing phone numbers to be omitted and trimming input values. Empty phone numbers are now treated as absent rather than as errors. [[1]](diffhunk://#diff-8ffdd76e260e3cda6f0816c8e585ae76b993a90d2519c38185a5fe22b4b49e47L1-R1) [[2]](diffhunk://#diff-8ffdd76e260e3cda6f0816c8e585ae76b993a90d2519c38185a5fe22b4b49e47R14-R60) * Updated the authentication callback logic to trim input values and omit the phone number parameter if it is blank. **User Interface Improvements** * Updated registration and booking forms to indicate that phone numbers are optional, removed the required attribute, and improved placeholder text. [[1]](diffhunk://#diff-f356eb84970d8c9ee6ff1992c297b0cae07bade37ff967c1e6e0de6f8b67081cL101-R115) [[2]](diffhunk://#diff-43c0e1f7a869ee5c43a911bc10dc80cbb265a8672340ef0fa7c1d3009c047f02L92-R92) * Updated email templates and confirmation screens to display "N/A" or "-" when phone numbers are missing. [[1]](diffhunk://#diff-48468ef2d1bb2c33b5ffb40457b77532815c7faf1830932661f665bff58b2177R6-R11) [[2]](diffhunk://#diff-3f33187b4021450b481ce53fe13166addea582c627f2cfbc99c75c7ce5c34857L10-R10) [[3]](diffhunk://#diff-43c0e1f7a869ee5c43a911bc10dc80cbb265a8672340ef0fa7c1d3009c047f02L92-R92) **Profile Management** * Improved profile update flow to ensure the form reflects the latest user data after saving changes. * Made the "Full Name" field explicitly required in the profile form UI.
161 lines
8.2 KiB
Text
161 lines
8.2 KiB
Text
<Layouts.app flash={@flash} current_user={@current_user}>
|
|
<div class="min-h-screen bg-gradient-to-br from-slate-50 via-sky-50 to-slate-100 dark:from-slate-950 dark:via-slate-900 dark:to-slate-950 flex items-center justify-center px-4">
|
|
<div class="w-full max-w-md">
|
|
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-2xl border border-slate-200 dark:border-slate-700 overflow-hidden">
|
|
<div class="p-8">
|
|
<%= if @existing_user? do %>
|
|
<%!-- Existing User Sign In --%>
|
|
<div class="text-center mb-6">
|
|
<div class="inline-flex items-center justify-center size-12 bg-sky-100 dark:bg-sky-900/30 rounded-full mb-4">
|
|
<.icon name="hero-check-circle" class="size-6 text-sky-600 dark:text-sky-400" />
|
|
</div>
|
|
<h2 class="text-2xl font-bold text-slate-900 dark:text-slate-100 mb-2">
|
|
Welcome Back!
|
|
</h2>
|
|
<p class="text-slate-600 dark:text-slate-400 text-sm">
|
|
We found your account. Click below to continue.
|
|
</p>
|
|
</div>
|
|
|
|
<form id="sign-in-form" phx-submit="sign_in" class="space-y-5">
|
|
<div class="flex items-center gap-3 p-4 bg-gradient-to-r from-slate-50 to-sky-50/50 dark:from-slate-900 dark:to-slate-800 rounded-xl border border-slate-200 dark:border-slate-700">
|
|
<div class="flex-shrink-0">
|
|
<.icon name="hero-envelope" class="size-5 text-sky-600 dark:text-sky-400" />
|
|
</div>
|
|
<span class="text-sm font-medium text-slate-700 dark:text-slate-300 truncate">
|
|
{@email}
|
|
</span>
|
|
</div>
|
|
|
|
<label class="flex items-start gap-3 cursor-pointer group p-3 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-900/50 transition-colors">
|
|
<input
|
|
type="checkbox"
|
|
name="remember_me"
|
|
id="remember_me"
|
|
class="mt-0.5 size-5 rounded border-slate-300 dark:border-slate-600 text-sky-600 focus:ring-2 focus:ring-sky-500 focus:ring-offset-0 dark:bg-slate-700 cursor-pointer"
|
|
/>
|
|
<span class="text-sm text-slate-700 dark:text-slate-300 leading-tight">
|
|
Remember me on this device for 30 days
|
|
</span>
|
|
</label>
|
|
|
|
<button
|
|
type="submit"
|
|
id="sign-in-button"
|
|
class="w-full px-6 py-3.5 bg-gradient-to-r from-sky-500 to-sky-600 hover:from-sky-600 hover:to-sky-700 text-white font-semibold rounded-xl transition-all shadow-lg shadow-sky-500/30 hover:shadow-xl hover:shadow-sky-500/40 hover:-translate-y-0.5 active:translate-y-0"
|
|
>
|
|
Sign In to Your Account
|
|
</button>
|
|
</form>
|
|
<% else %>
|
|
<%!-- New User Registration --%>
|
|
<div class="text-center mb-6">
|
|
<div class="inline-flex items-center justify-center size-12 bg-sky-100 dark:bg-sky-900/30 rounded-full mb-4">
|
|
<.icon name="hero-user-plus" class="size-6 text-sky-600 dark:text-sky-400" />
|
|
</div>
|
|
<h2 class="text-2xl font-bold text-slate-900 dark:text-slate-100 mb-2">
|
|
Complete Your Profile
|
|
</h2>
|
|
<p class="text-slate-600 dark:text-slate-400 text-sm">
|
|
Just a few details to get you started
|
|
</p>
|
|
</div>
|
|
|
|
<form id="registration-form" phx-submit="register" class="space-y-5">
|
|
<div class="flex items-center gap-3 p-4 bg-gradient-to-r from-slate-50 to-sky-50/50 dark:from-slate-900 dark:to-slate-800 rounded-xl border border-slate-200 dark:border-slate-700">
|
|
<div class="flex-shrink-0">
|
|
<.icon name="hero-envelope" class="size-5 text-sky-600 dark:text-sky-400" />
|
|
</div>
|
|
<span class="text-sm font-medium text-slate-700 dark:text-slate-300 truncate">
|
|
{@email}
|
|
</span>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
for="name"
|
|
class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"
|
|
>
|
|
Full Name <span class="text-rose-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<input
|
|
type="text"
|
|
name="name"
|
|
id="name"
|
|
required
|
|
class="w-full pl-11 pr-4 py-3 rounded-xl border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100 placeholder-slate-400 dark:placeholder-slate-500 focus:ring-2 focus:ring-sky-500 focus:border-transparent transition-shadow"
|
|
placeholder="John Doe"
|
|
/>
|
|
<div class="absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none">
|
|
<.icon name="hero-user" class="size-5 text-slate-400 dark:text-slate-500" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
for="phone_number"
|
|
class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"
|
|
>
|
|
Phone Number (Optional)
|
|
</label>
|
|
<div class="relative">
|
|
<input
|
|
type="tel"
|
|
name="phone_number"
|
|
id="phone_number"
|
|
class="w-full pl-11 pr-4 py-3 rounded-xl border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100 placeholder-slate-400 dark:placeholder-slate-500 focus:ring-2 focus:ring-sky-500 focus:border-transparent transition-shadow"
|
|
placeholder="+39 123456789"
|
|
/>
|
|
<div class="absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none">
|
|
<.icon name="hero-phone" class="size-5 text-slate-400 dark:text-slate-500" />
|
|
</div>
|
|
</div>
|
|
<p class="mt-2 text-xs text-slate-500 dark:text-slate-400">
|
|
Your number will only be used to contact you personally about booking issues, never for marketing.
|
|
</p>
|
|
</div>
|
|
|
|
<label class="flex items-start gap-3 cursor-pointer group p-3 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-900/50 transition-colors">
|
|
<input
|
|
type="checkbox"
|
|
name="remember_me"
|
|
id="remember_me"
|
|
class="mt-0.5 size-5 rounded border-slate-300 dark:border-slate-600 text-sky-600 focus:ring-2 focus:ring-sky-500 focus:ring-offset-0 dark:bg-slate-700 cursor-pointer"
|
|
/>
|
|
<span class="text-sm text-slate-700 dark:text-slate-300 leading-tight">
|
|
Remember me on this device for 30 days
|
|
</span>
|
|
</label>
|
|
|
|
<button
|
|
type="submit"
|
|
id="register-button"
|
|
class="w-full px-6 py-3.5 bg-gradient-to-r from-sky-500 to-sky-600 hover:from-sky-600 hover:to-sky-700 text-white font-semibold rounded-xl transition-all shadow-lg shadow-sky-500/30 hover:shadow-xl hover:shadow-sky-500/40 hover:-translate-y-0.5 active:translate-y-0"
|
|
>
|
|
Create Account
|
|
</button>
|
|
</form>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="px-8 py-4 bg-slate-50 dark:bg-slate-900/50 border-t border-slate-200 dark:border-slate-700">
|
|
<p class="text-xs text-center text-slate-500 dark:text-slate-400">
|
|
By continuing, you agree to our Terms of Service and Privacy Policy
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6 text-center">
|
|
<.link
|
|
navigate="/"
|
|
class="inline-flex items-center gap-2 text-sm text-slate-600 dark:text-slate-400 hover:text-sky-600 dark:hover:text-sky-400 transition-colors"
|
|
>
|
|
<.icon name="hero-arrow-left" class="size-4" />
|
|
<span>Back to home</span>
|
|
</.link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Layouts.app>
|