Make sign in and registration screens scrollable

- Remove fixed height constraints from main pages
- Add responsive padding
- Add max-height and overflow handling to modals
- Make modal headers sticky
- Improve overall scrolling behavior
This commit is contained in:
pacnpal
2024-11-14 01:02:54 +00:00
parent 8d70bf8994
commit 30b786d51e
4 changed files with 216 additions and 213 deletions

View File

@@ -6,8 +6,8 @@
{% block title %}Login - ThrillWiki{% endblock %} {% block title %}Login - ThrillWiki{% endblock %}
{% block content %} {% block content %}
<div class="flex items-center justify-center min-h-[calc(100vh-16rem)]"> <div class="flex items-center justify-center py-8 md:py-12">
<div class="w-full max-w-lg"> <div class="w-full max-w-lg px-4">
<div class="auth-card"> <div class="auth-card">
<h1 class="auth-title">{% trans "Welcome Back" %}</h1> <h1 class="auth-title">{% trans "Welcome Back" %}</h1>

View File

@@ -4,11 +4,10 @@
<div <div
id="login-modal" id="login-modal"
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" class="fixed inset-0 z-50 flex items-center justify-center p-4 overflow-y-auto bg-black/50 backdrop-blur-sm"
@click.away="document.getElementById('login-modal').remove()"
> >
<div class="w-full max-w-lg p-6 mx-4 bg-white rounded-lg shadow-xl dark:bg-gray-800"> <div class="w-full max-w-lg my-auto bg-white rounded-lg shadow-xl dark:bg-gray-800 max-h-[90vh] overflow-y-auto">
<div class="flex justify-between mb-4"> <div class="sticky top-0 flex justify-between p-6 bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">{% trans "Welcome Back" %}</h2> <h2 class="text-2xl font-bold text-gray-900 dark:text-white">{% trans "Welcome Back" %}</h2>
<button <button
onclick="this.closest('#login-modal').remove()" onclick="this.closest('#login-modal').remove()"
@@ -18,53 +17,55 @@
</button> </button>
</div> </div>
{% get_providers as socialaccount_providers %} <div class="p-6">
{% if socialaccount_providers %} {% get_providers as socialaccount_providers %}
<div class="space-y-3"> {% if socialaccount_providers %}
{% for provider in socialaccount_providers %} <div class="space-y-3">
<a {% for provider in socialaccount_providers %}
href="{% provider_login_url provider.id process='login' %}"
class="btn-social {% if provider.id == 'discord' %}btn-discord{% elif provider.id == 'google' %}btn-google{% endif %}"
role="button"
tabindex="0"
onkeydown="if(event.key === 'Enter' || event.key === ' ') { this.click(); event.preventDefault(); }"
>
{% if provider.id == 'google' %}
<img
src="{% static 'images/google-icon.svg' %}"
alt="Google"
class="w-5 h-5 mr-3"
/>
<span>Continue with Google</span>
{% elif provider.id == 'discord' %}
<img
src="{% static 'images/discord-icon.svg' %}"
alt="Discord"
class="w-5 h-5 mr-3"
/>
<span>Continue with Discord</span>
{% endif %}
</a>
{% endfor %}
</div>
<div class="auth-divider">
<span>Or continue with email</span>
</div>
{% endif %}
{% include "account/partials/login_form.html" %}
<div class="mt-6 text-sm text-center">
<p class="text-gray-600 dark:text-gray-400">
{% trans "Don't have an account?" %}
<a <a
href="{% url 'account_signup' %}" href="{% provider_login_url provider.id process='login' %}"
class="ml-1 font-medium transition-colors text-primary hover:text-primary/80 focus:outline-none focus:underline" class="btn-social {% if provider.id == 'discord' %}btn-discord{% elif provider.id == 'google' %}btn-google{% endif %}"
role="button"
tabindex="0"
onkeydown="if(event.key === 'Enter' || event.key === ' ') { this.click(); event.preventDefault(); }"
> >
{% trans "Sign up" %} {% if provider.id == 'google' %}
<img
src="{% static 'images/google-icon.svg' %}"
alt="Google"
class="w-5 h-5 mr-3"
/>
<span>Continue with Google</span>
{% elif provider.id == 'discord' %}
<img
src="{% static 'images/discord-icon.svg' %}"
alt="Discord"
class="w-5 h-5 mr-3"
/>
<span>Continue with Discord</span>
{% endif %}
</a> </a>
</p> {% endfor %}
</div>
<div class="auth-divider">
<span>Or continue with email</span>
</div>
{% endif %}
{% include "account/partials/login_form.html" %}
<div class="mt-6 text-sm text-center">
<p class="text-gray-600 dark:text-gray-400">
{% trans "Don't have an account?" %}
<a
href="{% url 'account_signup' %}"
class="ml-1 font-medium transition-colors text-primary hover:text-primary/80 focus:outline-none focus:underline"
>
{% trans "Sign up" %}
</a>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -5,11 +5,11 @@
<div <div
id="signup-modal" id="signup-modal"
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" class="fixed inset-0 z-50 flex items-center justify-center p-4 overflow-y-auto bg-black/50 backdrop-blur-sm"
@click.away="document.getElementById('signup-modal').remove()" @click.away="document.getElementById('signup-modal').remove()"
> >
<div class="w-full max-w-lg p-6 mx-4 bg-white rounded-lg shadow-xl dark:bg-gray-800"> <div class="w-full max-w-lg my-auto bg-white rounded-lg shadow-xl dark:bg-gray-800 max-h-[90vh] overflow-y-auto">
<div class="flex justify-between mb-4"> <div class="sticky top-0 flex justify-between p-6 bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">{% trans "Create Account" %}</h2> <h2 class="text-2xl font-bold text-gray-900 dark:text-white">{% trans "Create Account" %}</h2>
<button <button
onclick="this.closest('#signup-modal').remove()" onclick="this.closest('#signup-modal').remove()"
@@ -19,178 +19,180 @@
</button> </button>
</div> </div>
{% get_providers as socialaccount_providers %} <div class="p-6">
{% if socialaccount_providers %} {% get_providers as socialaccount_providers %}
<div class="space-y-3"> {% if socialaccount_providers %}
{% for provider in socialaccount_providers %} <div class="space-y-3">
<a {% for provider in socialaccount_providers %}
href="{% provider_login_url provider.id process='signup' %}" <a
class="btn-social {% if provider.id == 'discord' %}btn-discord{% elif provider.id == 'google' %}btn-google{% endif %}" href="{% provider_login_url provider.id process='signup' %}"
role="button" class="btn-social {% if provider.id == 'discord' %}btn-discord{% elif provider.id == 'google' %}btn-google{% endif %}"
tabindex="0" role="button"
onkeydown="if(event.key === 'Enter' || event.key === ' ') { this.click(); event.preventDefault(); }" tabindex="0"
> onkeydown="if(event.key === 'Enter' || event.key === ' ') { this.click(); event.preventDefault(); }"
{% if provider.id == 'google' %} >
<img {% if provider.id == 'google' %}
src="{% static 'images/google-icon.svg' %}" <img
alt="Google" src="{% static 'images/google-icon.svg' %}"
class="w-5 h-5 mr-3" alt="Google"
/> class="w-5 h-5 mr-3"
<span>Continue with Google</span> />
{% elif provider.id == 'discord' %} <span>Continue with Google</span>
<img {% elif provider.id == 'discord' %}
src="{% static 'images/discord-icon.svg' %}" <img
alt="Discord" src="{% static 'images/discord-icon.svg' %}"
class="w-5 h-5 mr-3" alt="Discord"
/> class="w-5 h-5 mr-3"
<span>Continue with Discord</span> />
{% endif %} <span>Continue with Discord</span>
</a> {% endif %}
{% endfor %} </a>
</div> {% endfor %}
</div>
<div class="auth-divider"> <div class="auth-divider">
<span>Or continue with email</span> <span>Or continue with email</span>
</div>
{% endif %}
<form
class="space-y-6"
hx-post="{% url 'account_signup' %}"
hx-target="this"
hx-swap="outerHTML"
hx-indicator="#signup-indicator"
>
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-error">
<div class="text-sm">{{ form.non_field_errors }}</div>
</div> </div>
{% endif %} {% endif %}
<div> <form
<label for="id_username" class="form-label"> class="space-y-6"
{% trans "Username" %} hx-post="{% url 'account_signup' %}"
</label> hx-target="this"
<input hx-swap="outerHTML"
type="text" hx-indicator="#signup-indicator"
name="username" >
id="id_username" {% csrf_token %}
required {% if form.non_field_errors %}
autocomplete="username" <div class="alert alert-error">
class="form-input" <div class="text-sm">{{ form.non_field_errors }}</div>
/> </div>
{% if form.username.errors %}
<p class="form-error">{{ form.username.errors }}</p>
{% endif %} {% endif %}
</div>
<div> <div>
<label for="id_email" class="form-label">{% trans "Email" %}</label> <label for="id_username" class="form-label">
<input {% trans "Username" %}
type="email" </label>
name="email" <input
id="id_email" type="text"
required name="username"
autocomplete="email" id="id_username"
class="form-input" required
/> autocomplete="username"
{% if form.email.errors %} class="form-input"
<p class="form-error">{{ form.email.errors }}</p> />
{% endif %} {% if form.username.errors %}
</div> <p class="form-error">{{ form.username.errors }}</p>
{% endif %}
</div>
<div> <div>
<label for="id_password1" class="form-label"> <label for="id_email" class="form-label">{% trans "Email" %}</label>
{% trans "Password" %} <input
</label> type="email"
name="email"
id="id_email"
required
autocomplete="email"
class="form-input"
/>
{% if form.email.errors %}
<p class="form-error">{{ form.email.errors }}</p>
{% endif %}
</div>
<div>
<label for="id_password1" class="form-label">
{% trans "Password" %}
</label>
<input
type="password"
name="password1"
id="id_password1"
required
autocomplete="new-password"
class="form-input"
oninput="validatePassword(this.value)"
/>
{% if form.password1.errors %}
<p class="form-error">{{ form.password1.errors }}</p>
{% endif %}
<div class="mt-3 password-requirements">
<ul id="passwordRequirements">
<li class="invalid" id="req-length">
<i class="text-xs fas fa-circle"></i>
<span>Must be at least 8 characters long</span>
</li>
<li class="invalid" id="req-similar">
<i class="text-xs fas fa-circle"></i>
<span>Can't be too similar to your personal information</span>
</li>
<li class="invalid" id="req-common">
<i class="text-xs fas fa-circle"></i>
<span>Can't be a commonly used password</span>
</li>
<li class="invalid" id="req-numeric">
<i class="text-xs fas fa-circle"></i>
<span>Can't be entirely numeric</span>
</li>
</ul>
</div>
</div>
<div>
<label for="id_password2" class="form-label">
{% trans "Confirm Password" %}
</label>
<input
type="password"
name="password2"
id="id_password2"
required
autocomplete="new-password"
class="form-input"
oninput="validatePasswordMatch()"
/>
{% if form.password2.errors %}
<p class="form-error">{{ form.password2.errors }}</p>
{% endif %}
</div>
{% turnstile_widget %}
{% if redirect_field_value %}
<input <input
type="password" type="hidden"
name="password1" name="{{ redirect_field_name }}"
id="id_password1" value="{{ redirect_field_value }}"
required
autocomplete="new-password"
class="form-input"
oninput="validatePassword(this.value)"
/> />
{% if form.password1.errors %}
<p class="form-error">{{ form.password1.errors }}</p>
{% endif %} {% endif %}
<div class="mt-3 password-requirements">
<ul id="passwordRequirements"> <div>
<li class="invalid" id="req-length"> <button type="submit" class="w-full btn-primary">
<i class="text-xs fas fa-circle"></i> <i class="mr-2 fas fa-user-plus"></i>
<span>Must be at least 8 characters long</span> {% trans "Create Account" %}
</li> </button>
<li class="invalid" id="req-similar"> </div>
<i class="text-xs fas fa-circle"></i> </form>
<span>Can't be too similar to your personal information</span>
</li> <!-- Loading indicator -->
<li class="invalid" id="req-common"> <div id="signup-indicator" class="htmx-indicator">
<i class="text-xs fas fa-circle"></i> <div class="flex items-center justify-center w-full py-4">
<span>Can't be a commonly used password</span> <div class="w-8 h-8 border-4 rounded-full border-primary border-t-transparent animate-spin"></div>
</li>
<li class="invalid" id="req-numeric">
<i class="text-xs fas fa-circle"></i>
<span>Can't be entirely numeric</span>
</li>
</ul>
</div> </div>
</div> </div>
<div> <div class="mt-6 text-sm text-center">
<label for="id_password2" class="form-label"> <p class="text-gray-600 dark:text-gray-400">
{% trans "Confirm Password" %} {% trans "Already have an account?" %}
</label> <a
<input href="{% url 'account_login' %}"
type="password" class="ml-1 font-medium transition-colors text-primary hover:text-primary/80 focus:outline-none focus:underline"
name="password2" onkeydown="if(event.key === 'Enter') { this.click(); }"
id="id_password2" >
required {% trans "Sign in" %}
autocomplete="new-password" </a>
class="form-input" </p>
oninput="validatePasswordMatch()"
/>
{% if form.password2.errors %}
<p class="form-error">{{ form.password2.errors }}</p>
{% endif %}
</div> </div>
{% turnstile_widget %}
{% if redirect_field_value %}
<input
type="hidden"
name="{{ redirect_field_name }}"
value="{{ redirect_field_value }}"
/>
{% endif %}
<div>
<button type="submit" class="w-full btn-primary">
<i class="mr-2 fas fa-user-plus"></i>
{% trans "Create Account" %}
</button>
</div>
</form>
<!-- Loading indicator -->
<div id="signup-indicator" class="htmx-indicator">
<div class="flex items-center justify-center w-full py-4">
<div class="w-8 h-8 border-4 rounded-full border-primary border-t-transparent animate-spin"></div>
</div>
</div>
<div class="mt-6 text-sm text-center">
<p class="text-gray-600 dark:text-gray-400">
{% trans "Already have an account?" %}
<a
href="{% url 'account_login' %}"
class="ml-1 font-medium transition-colors text-primary hover:text-primary/80 focus:outline-none focus:underline"
onkeydown="if(event.key === 'Enter') { this.click(); }"
>
{% trans "Sign in" %}
</a>
</p>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,8 +7,8 @@
{% block title %}Register - ThrillWiki{% endblock %} {% block title %}Register - ThrillWiki{% endblock %}
{% block content %} {% block content %}
<div class="flex items-center justify-center min-h-[calc(100vh-16rem)]"> <div class="flex items-center justify-center py-8 md:py-12">
<div class="w-full max-w-lg"> <div class="w-full max-w-lg px-4">
<div class="auth-card"> <div class="auth-card">
<h1 class="auth-title">{% trans "Create Account" %}</h1> <h1 class="auth-title">{% trans "Create Account" %}</h1>