diff --git a/base/components/components.py b/base/components/components.py index 4370d2a0..4116fb45 100644 --- a/base/components/components.py +++ b/base/components/components.py @@ -1,7 +1,7 @@ from typing import Literal from django_components import Component, register -from pydantic import BaseModel +from pydantic import BaseModel, EmailStr from base.main import TAB_VAR, ObjectList from base.pagination import PAGE_VAR, Pagination @@ -107,3 +107,25 @@ def get_template_data(self, args, kwargs, slots, context): "tabs": self.create_all_tabs(object_list), "object_list": object_list, } + + +@register("contact_information_button") +class ContactInformationButton(Component): + MAINTAINER_EMAILS = [ + "antoliny0919@gmail.com", + "wedgemail@gmail.com", + ] + template_file = "contact_information_button.html" + + class Kwargs(BaseModel): + button_text: str + description: str + contact_emails: list[EmailStr] | None = None + + def get_template_data(self, args, kwargs, slots, context): + contact_emails = kwargs.contact_emails or self.MAINTAINER_EMAILS + return { + "button_text": kwargs.button_text, + "description": kwargs.description, + "contact_emails": contact_emails, + } diff --git a/base/components/contact_information_button.html b/base/components/contact_information_button.html new file mode 100644 index 00000000..a62a0efc --- /dev/null +++ b/base/components/contact_information_button.html @@ -0,0 +1,20 @@ +{% if contact_emails %} +
+ +
+ {{ description }} +
+ {% for email in contact_emails %} + {{ email }} + {% endfor %} +
+
+
+{% endif %} diff --git a/base/forms.py b/base/forms.py new file mode 100644 index 00000000..05064cc2 --- /dev/null +++ b/base/forms.py @@ -0,0 +1,9 @@ +from allauth.account.forms import LoginForm + + +class DjangoSnippetsLoginForm(LoginForm): + + def _setup_password_field(self): + super()._setup_password_field() + # Disable allauth's automatically set help_text + self.fields["password"].help_text = None diff --git a/djangosnippets/adapters.py b/djangosnippets/adapters.py index fea9376f..c05104b6 100644 --- a/djangosnippets/adapters.py +++ b/djangosnippets/adapters.py @@ -1,13 +1,6 @@ -from allauth.account.adapter import DefaultAccountAdapter from allauth.socialaccount.adapter import DefaultSocialAccountAdapter -class DjangoSnippetsAccountAdapter(DefaultAccountAdapter): - def is_open_for_signup(self, request): - """Disabling common signup completely""" - return False - - class DjangoSnippetsSocialAccountAdapter(DefaultSocialAccountAdapter): def is_open_for_signup(self, request, sociallogin): """ diff --git a/djangosnippets/settings/base.py b/djangosnippets/settings/base.py index b0a53696..6c738e48 100644 --- a/djangosnippets/settings/base.py +++ b/djangosnippets/settings/base.py @@ -3,6 +3,7 @@ import dj_database_url from django.contrib import messages +from django.forms.renderers import TemplatesSetting from django.urls import reverse from dotenv import load_dotenv @@ -58,6 +59,7 @@ def user_url(user): "django.contrib.sessions", "django.contrib.staticfiles", "django.contrib.sites", + "django.forms", "allauth", "allauth.account", "allauth.socialaccount", @@ -74,6 +76,7 @@ def user_url(user): "django_components", "rest_framework", "django_htmx", + "widget_tweaks", ] MIDDLEWARE = ( @@ -137,11 +140,14 @@ def user_url(user): MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage" ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 7 -ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"] +ACCOUNT_SIGNUP_FIELDS = ["username*", "email*", "password1*", "password2*"] ACCOUNT_EMAIL_VERIFICATION = "mandatory" ACCOUNT_LOGOUT_ON_GET = True ACCOUNT_USERNAME_MIN_LENGTH = 3 -ACCOUNT_ADAPTER = "djangosnippets.adapters.DjangoSnippetsAccountAdapter" +ACCOUNT_FORMS = { + "login": "base.forms.DjangoSnippetsLoginForm", +} +ACCOUNT_SESSION_REMEMBER = True SOCIALACCOUNT_ADAPTER = "djangosnippets.adapters.DjangoSnippetsSocialAccountAdapter" SOCIALACCOUNT_AUTO_SIGNUP = False SOCIALACCOUNT_LOGIN_ON_GET = True @@ -215,3 +221,10 @@ def user_url(user): } DEFAULT_AUTO_FIELD = "django.db.models.AutoField" + + +class CustomFormRenderer(TemplatesSetting): + form_template_name = "forms/form.html" + + +FORM_RENDERER = "djangosnippets.settings.base.CustomFormRenderer" diff --git a/djangosnippets/settings/testing.py b/djangosnippets/settings/testing.py index d82e102f..c81fdaa6 100644 --- a/djangosnippets/settings/testing.py +++ b/djangosnippets/settings/testing.py @@ -25,6 +25,7 @@ "django.contrib.sessions", "django.contrib.sites", "django.contrib.staticfiles", + "django.forms", "django_components", "allauth", "allauth.account", diff --git a/djangosnippets/static/img/email_verification_expired.png b/djangosnippets/static/img/email_verification_expired.png new file mode 100644 index 00000000..c4e0e494 Binary files /dev/null and b/djangosnippets/static/img/email_verification_expired.png differ diff --git a/djangosnippets/static/img/password_reset_done.gif b/djangosnippets/static/img/password_reset_done.gif new file mode 100644 index 00000000..afec0574 Binary files /dev/null and b/djangosnippets/static/img/password_reset_done.gif differ diff --git a/djangosnippets/static/img/problem.png b/djangosnippets/static/img/problem.png new file mode 100644 index 00000000..7b1ac520 Binary files /dev/null and b/djangosnippets/static/img/problem.png differ diff --git a/djangosnippets/static/img/verification_sent.png b/djangosnippets/static/img/verification_sent.png new file mode 100644 index 00000000..69587399 Binary files /dev/null and b/djangosnippets/static/img/verification_sent.png differ diff --git a/djangosnippets/templates/account/account_inactive.html b/djangosnippets/templates/account/account_inactive.html deleted file mode 100644 index 90cde431..00000000 --- a/djangosnippets/templates/account/account_inactive.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "account/base.html" %} - -{% load i18n %} - -{% block head_title %}{% trans "Account Inactive" %}{% endblock %} - -{% block content_header %}{% trans "Account Inactive" %}{% endblock %} - -{% block content %} -

{% trans "This account is inactive." %}

-{% endblock %} diff --git a/djangosnippets/templates/account/email/email_confirmation_message.txt b/djangosnippets/templates/account/email/email_confirmation_message.txt deleted file mode 100644 index 9e354f3b..00000000 --- a/djangosnippets/templates/account/email/email_confirmation_message.txt +++ /dev/null @@ -1,9 +0,0 @@ -Somebody with this e-mail address registered a user account at {{ current_site.domain }}. -To activate your account, please visit the following page: - -{{ activate_url }} - -If clicking the above link does not work, please copy and paste the link into your browser. - -------------------------------------------------------------------------------------- -If you didn't request it, you may safely delete this message; we won't bug you again. diff --git a/djangosnippets/templates/account/email/email_confirmation_signup_message.txt b/djangosnippets/templates/account/email/email_confirmation_signup_message.txt deleted file mode 100644 index 9996f7e5..00000000 --- a/djangosnippets/templates/account/email/email_confirmation_signup_message.txt +++ /dev/null @@ -1 +0,0 @@ -{% include "account/email/email_confirmation_message.txt" %} diff --git a/djangosnippets/templates/account/email/email_confirmation_signup_subject.txt b/djangosnippets/templates/account/email/email_confirmation_signup_subject.txt deleted file mode 100644 index 4c85ebb9..00000000 --- a/djangosnippets/templates/account/email/email_confirmation_signup_subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% include "account/email/email_confirmation_subject.txt" %} diff --git a/djangosnippets/templates/account/email/email_confirmation_subject.txt b/djangosnippets/templates/account/email/email_confirmation_subject.txt deleted file mode 100644 index 0603d4a0..00000000 --- a/djangosnippets/templates/account/email/email_confirmation_subject.txt +++ /dev/null @@ -1,4 +0,0 @@ -{% load i18n %} -{% autoescape off %} -{% blocktrans %}Confirm e-mail address{% endblocktrans %} -{% endautoescape %} diff --git a/djangosnippets/templates/account/email/password_reset_key_message.txt b/djangosnippets/templates/account/email/password_reset_key_message.txt deleted file mode 100644 index 57722b1e..00000000 --- a/djangosnippets/templates/account/email/password_reset_key_message.txt +++ /dev/null @@ -1,11 +0,0 @@ -You're receiving this e-mail because you you or someone else requested a password reset for your user account at {{ site.domain }}. Click the link below to reset your password. - -{{ password_reset_url }} - -{% if username %}In case you forgot, your username is {{ username }}.{% endif %} - -Thanks for using our site! - - - The {{ site.domain }} staff - -PS: If you did not request this e-mail you may safely delete it -- your password remains unchanged and secure. diff --git a/djangosnippets/templates/account/email/password_reset_key_subject.txt b/djangosnippets/templates/account/email/password_reset_key_subject.txt deleted file mode 100644 index 8be9a92d..00000000 --- a/djangosnippets/templates/account/email/password_reset_key_subject.txt +++ /dev/null @@ -1,4 +0,0 @@ -{% load i18n %} -{% autoescape off %} -{% blocktrans %}Password reset e-mail{% endblocktrans %} -{% endautoescape %} diff --git a/djangosnippets/templates/account/email_confirm.html b/djangosnippets/templates/account/email_confirm.html index 776776e9..6ee9d5f0 100644 --- a/djangosnippets/templates/account/email_confirm.html +++ b/djangosnippets/templates/account/email_confirm.html @@ -1,28 +1,33 @@ {% extends "account/base.html" %} -{% load i18n %} -{% load account %} +{% load account static %} -{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %} - -{% block content_header %}{% trans "Confirm E-mail Address" %}{% endblock %} +{% block head_title %}Confirm E-mail Address{% endblock %} +{% block header %}{% endblock %} {% block content %} -{% if confirmation %} -{% user_display confirmation.email_address.user as user_display %} -

{% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}

- -
-{% csrf_token %} - -
- -{% else %} - -{% url 'account_email' as email_url %} - -

{% blocktrans %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request.{% endblocktrans %}

- -{% endif %} +
+

Confirm E-mail Address

+ {% if confirmation %} + {% with email=confirmation.email_address.email %} + {% if can_confirm %} + {% user_display confirmation.email_address.user as user_display %} +

Please confirm that {{ email }} is an email address for user {{ user_display }}.

+
+ {% csrf_token %} + +
+ {% else %} + +

Unable to confirm {{ email }} because it is already confirmed by a different account.

+ {% endif %} + {% endwith %} + {% else %} + +

This email confirmation link expired or is invalid. Would you like to request a new email confirmation?

+ New Email Confirmation + {% endif %} +
{% endblock %} +{% block footer %}{% endblock %} \ No newline at end of file diff --git a/djangosnippets/templates/account/email_confirmed.html b/djangosnippets/templates/account/email_confirmed.html deleted file mode 100644 index 17561370..00000000 --- a/djangosnippets/templates/account/email_confirmed.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "account/base.html" %} - -{% load i18n %} -{% load account %} - -{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %} - -{% block content_header %}{% trans "Confirm E-mail Address" %}{% endblock %} - -{% block content %} -{% user_display email_address.user as user_display %} -

{% blocktrans with email_address.email as email %}You have confirmed that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}

- -{% endblock %} diff --git a/djangosnippets/templates/account/login.html b/djangosnippets/templates/account/login.html index 9491bff0..41d87c1c 100644 --- a/djangosnippets/templates/account/login.html +++ b/djangosnippets/templates/account/login.html @@ -1,48 +1,28 @@ -{% extends "account/base.html" %} +{% extends "base.html" %} -{% load i18n %} -{% load account %} -{% load socialaccount %} +{% load static %} -{% block head_title %}{% trans "Login" %}{% endblock %} - -{% block content_header %}{% trans "Login" %}{% endblock %} +{% block header%}{% endblock %} {% block content %} -

-Please log in with one of the following 3rd party systems or with your existing account. -

- - - -{% include "socialaccount/snippets/login_extra.html" %} -{% endblock %} - -{% block sidebar %} -
- {% csrf_token %} - {% for field in form %} - {% if field.name == 'remember' %} - {{ field }} - {{ field.label_tag }} - {% else %} - {{ field.label_tag }} - {{ field }} - {% endif %} - {% if field.errors %} - {{ field.errors }} - {% endif %} - {% endfor %} - {% if redirect_field_value %} - - {% endif %} -
-
- - Forgotten your password? +
+

Sign In

+

Don't have an account? Sign Up

+ {% include "socialaccount/snippets/login_extra.html" %} + + {% csrf_token %} + {{ form }} + + + Forgotten your password? +
+
+ OR +
-
- +
    + {% include "socialaccount/snippets/provider_list.html" with process="login" %} +
+
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/logout.html b/djangosnippets/templates/account/logout.html deleted file mode 100644 index 2d389992..00000000 --- a/djangosnippets/templates/account/logout.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "account/base.html" %} - -{% load i18n %} - -{% block head_title %}{% trans "Logout" %}{% endblock %} - -{% block content_header %}{% trans "Logout" %}{% endblock %} - - -{% block content %} -

{% trans 'Are you sure you want to log out?' %}

- -
- {% csrf_token %} - {% if redirect_field_value %} - - {% endif %} - or cancel -
-{% endblock %} diff --git a/djangosnippets/templates/account/messages/cannot_delete_primary_email.txt b/djangosnippets/templates/account/messages/cannot_delete_primary_email.txt deleted file mode 100644 index 57bca1a6..00000000 --- a/djangosnippets/templates/account/messages/cannot_delete_primary_email.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}You cannot remove your primary e-mail address ({{ email }}).{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/email_confirmation_sent.txt b/djangosnippets/templates/account/messages/email_confirmation_sent.txt deleted file mode 100644 index be049b7e..00000000 --- a/djangosnippets/templates/account/messages/email_confirmation_sent.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Confirmation e-mail sent to {{ email }}.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/email_confirmed.txt b/djangosnippets/templates/account/messages/email_confirmed.txt deleted file mode 100644 index d642d258..00000000 --- a/djangosnippets/templates/account/messages/email_confirmed.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}You have confirmed {{ email }}.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/email_deleted.txt b/djangosnippets/templates/account/messages/email_deleted.txt deleted file mode 100644 index 052b28a5..00000000 --- a/djangosnippets/templates/account/messages/email_deleted.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Removed e-mail address {{ email }}.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/logged_in.txt b/djangosnippets/templates/account/messages/logged_in.txt deleted file mode 100644 index 0f8335ce..00000000 --- a/djangosnippets/templates/account/messages/logged_in.txt +++ /dev/null @@ -1,4 +0,0 @@ -{% load account %} -{% load i18n %} -{% user_display user as name %} -{% blocktrans %}Successfully logged in as {{ name }}.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/logged_out.txt b/djangosnippets/templates/account/messages/logged_out.txt deleted file mode 100644 index f063abd9..00000000 --- a/djangosnippets/templates/account/messages/logged_out.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}You are now logged out.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/password_changed.txt b/djangosnippets/templates/account/messages/password_changed.txt deleted file mode 100644 index bd5801c4..00000000 --- a/djangosnippets/templates/account/messages/password_changed.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Password successfully changed.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/password_set.txt b/djangosnippets/templates/account/messages/password_set.txt deleted file mode 100644 index 9d224ee0..00000000 --- a/djangosnippets/templates/account/messages/password_set.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Password successfully set.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/primary_email_set.txt b/djangosnippets/templates/account/messages/primary_email_set.txt deleted file mode 100644 index f6f3e4e5..00000000 --- a/djangosnippets/templates/account/messages/primary_email_set.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Primary e-mail address successfully set.{% endblocktrans %} diff --git a/djangosnippets/templates/account/messages/unverified_primary_email.txt b/djangosnippets/templates/account/messages/unverified_primary_email.txt deleted file mode 100644 index 9c9d0d87..00000000 --- a/djangosnippets/templates/account/messages/unverified_primary_email.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}Your primary e-mail address must be verified.{% endblocktrans %} diff --git a/djangosnippets/templates/account/password_reset.html b/djangosnippets/templates/account/password_reset.html index 46503470..16d26e7b 100644 --- a/djangosnippets/templates/account/password_reset.html +++ b/djangosnippets/templates/account/password_reset.html @@ -1,27 +1,22 @@ {% extends "account/base.html" %} -{% load i18n %} -{% load account %} +{% block head_title %}Reset password{% endblock %} -{% block head_title %}{% trans "Reset password" %}{% endblock %} - -{% block content_header %}{% trans "Reset password" %}{% endblock %} +{% block header %}{% endblock %} {% block content %} {% if user.is_authenticated %} {% include "account/snippets/already_logged_in.html" %} {% endif %} -

{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}

- -
{% csrf_token %} - {{ form.as_p }} - -
-

{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}

-{% endblock %} - -{% block extra_scripts %} - +
+ {% include "socialaccount/snippets/login_extra.html" %} +

Forgotten your password?

+

Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it.

+
+ {% csrf_token %} + {{ form }} + +
+
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/password_reset_done.html b/djangosnippets/templates/account/password_reset_done.html index 20681c49..a65dee2f 100644 --- a/djangosnippets/templates/account/password_reset_done.html +++ b/djangosnippets/templates/account/password_reset_done.html @@ -1,16 +1,18 @@ {% extends "account/base.html" %} -{% load i18n %} -{% load account %} +{% load static widget_tweaks %} -{% block head_title %}{% trans "Password Reset" %}{% endblock %} +{% block head_title %}Verify Your E-mail Address{% endblock %} -{% block content_header %}{% trans "Password Reset" %}{% endblock %} +{% block header%}{% endblock %} {% block content %} - {% if user.is_authenticated %} - {% include "account/snippets/already_logged_in.html" %} - {% endif %} - -

{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}

+
+

Password Reset

+ +

We have sent an e-mail to you for verification 🚀

+

Follow the link provided to finalize the password reset process. If you do not see the verification email in your main inbox, check your spam folder.

+ {% component 'contact_information_button' button_text="Didn't receive the email ?" description="If you didn't receive the verification email, please contact us at:" / %} +
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/password_reset_from_key.html b/djangosnippets/templates/account/password_reset_from_key.html index 9d7816ce..9ed698e9 100644 --- a/djangosnippets/templates/account/password_reset_from_key.html +++ b/djangosnippets/templates/account/password_reset_from_key.html @@ -1,23 +1,26 @@ {% extends "account/base.html" %} -{% load i18n %} -{% block head_title %}{% trans "Change Password" %}{% endblock %} +{% load static %} -{% block content_header %}{% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}{% endblock %} +{% block head_title %}{% if token_fail %}Bad Token{% else %}Change Password{% endif %}{% endblock %} + +{% block header %}{% endblock %} {% block content %} -{% if token_fail %} - {% url 'account_reset_password' as passwd_reset_url %} -

{% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset.{% endblocktrans %}

-{% else %} - {% if form %} -
+
+

{% if token_fail %}Bad Token{% else %}Change Password{% endif %}

+ {% if token_fail %} + +

The password reset link was invalid, possibly because it has already been used. Would you like to request a new one?

+ New Password Reset + {% else %} +

Enter your new password.

+ {% csrf_token %} - {{ form.as_p }} - + {{ form }} + - {% else %} -

{% trans 'Your password is now changed.' %}

- {% endif %} -{% endif %} + {% endif %} +
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/password_reset_from_key_done.html b/djangosnippets/templates/account/password_reset_from_key_done.html index 01fd3cb8..877f059c 100644 --- a/djangosnippets/templates/account/password_reset_from_key_done.html +++ b/djangosnippets/templates/account/password_reset_from_key_done.html @@ -1,10 +1,16 @@ {% extends "account/base.html" %} -{% load i18n %} +{% load static %} -{% block head_title %}{% trans "Change Password" %}{% endblock %} +{% block head_title %}Change Password{% endblock %} -{% block content_header %}{% trans "Change Password" %}{% endblock %} +{% block header %}{% endblock %} {% block content %} -

{% trans 'Your password is now changed.' %}

+
+

Your password is now changed

+ +

Please login with your new password.

+ Continue Login +
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/signup.html b/djangosnippets/templates/account/signup.html index e508b44c..e06bffa7 100644 --- a/djangosnippets/templates/account/signup.html +++ b/djangosnippets/templates/account/signup.html @@ -1,20 +1,27 @@ {% extends "account/base.html" %} -{% load i18n %} +{% block head_title %}Signup{% endblock %} -{% block head_title %}{% trans "Signup" %}{% endblock %} - -{% block content_header %}{% trans "Signup" %}{% endblock %} +{% block header%}{% endblock %} {% block content %} -

{% blocktrans %}Already have an account? Then please log in.{% endblocktrans %}

- - +
+

Sign Up

+

Already have an account? Then please log in

+ {% include "socialaccount/snippets/login_extra.html" %} +
+ {% csrf_token %} + {{ form }} + +
+
+
+ OR +
+
+
    + {% include "socialaccount/snippets/provider_list.html" with process="login" %} +
+
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/signup_closed.html b/djangosnippets/templates/account/signup_closed.html deleted file mode 100644 index 23ceee85..00000000 --- a/djangosnippets/templates/account/signup_closed.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "account/base.html" %} - -{% load i18n %} - -{% block head_title %}{% trans "Sign Up closed" %}{% endblock %} - -{% block content_header %}{% trans "Sign Up closed" %}{% endblock %} - -{% block content %} -

{% trans "We are sorry, but the sign up is currently closed." %}

-{% endblock %} diff --git a/djangosnippets/templates/account/snippets/already_logged_in.html b/djangosnippets/templates/account/snippets/already_logged_in.html deleted file mode 100644 index 00799f00..00000000 --- a/djangosnippets/templates/account/snippets/already_logged_in.html +++ /dev/null @@ -1,5 +0,0 @@ -{% load i18n %} -{% load account %} - -{% user_display user as user_display %} -

{% trans "Note" %}: {% blocktrans %}you are already logged in as {{ user_display }}.{% endblocktrans %}

diff --git a/djangosnippets/templates/account/verification_sent.html b/djangosnippets/templates/account/verification_sent.html index 1ec0f442..7ae412b4 100644 --- a/djangosnippets/templates/account/verification_sent.html +++ b/djangosnippets/templates/account/verification_sent.html @@ -1,11 +1,18 @@ {% extends "account/base.html" %} -{% load i18n %} +{% load static widget_tweaks %} -{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} +{% block head_title %}Verify Your E-mail Address{% endblock %} -{% block content_header %}{% trans "Verify Your E-mail Address" %}{% endblock %} +{% block header%}{% endblock %} {% block content %} -

{% blocktrans %}We have sent an e-mail to you for verification. Follow the link provided to finalize the process. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}

+
+

Email Verification

+ +

We have sent an e-mail to you for verification 🚀

+

Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder.

+ {% component 'contact_information_button' button_text="Didn't receive the email ?" description="If you didn't receive the verification email, please contact us at:" / %} +
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/account/verified_email_required.html b/djangosnippets/templates/account/verified_email_required.html deleted file mode 100644 index 49f631d7..00000000 --- a/djangosnippets/templates/account/verified_email_required.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "account/base.html" %} - -{% load i18n %} - -{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} - -{% block content_header %}{% trans "Verify Your E-mail Address" %}{% endblock %} - -{% block content %} -{% url 'account_email' as email_url %} - -

{% blocktrans %}This part of the site requires us to verify that -you are who you claim to be. For this purpose, we require that you -verify ownership of your e-mail address. {% endblocktrans %}

- -

{% blocktrans %}We have sent an e-mail to you for -verification. Please click on the link inside this e-mail. Please -contact us if you do not receive it within a few minutes.{% endblocktrans %}

- -

{% blocktrans %}Note: you can still change your e-mail address.{% endblocktrans %}

- -{% endblock %} diff --git a/djangosnippets/templates/base.html b/djangosnippets/templates/base.html index d5bb0674..acac3447 100644 --- a/djangosnippets/templates/base.html +++ b/djangosnippets/templates/base.html @@ -15,6 +15,7 @@ {% tailwind_css %} + {% block header %}

{% url 'account_logout' as logout_url %} @@ -38,6 +39,7 @@

+ {% endblock %}
{% block secondary_nav %}
+ {% block footer %} + {% endblock %} {% block extra_body %}{% endblock %} diff --git a/djangosnippets/templates/forms/form.html b/djangosnippets/templates/forms/form.html new file mode 100644 index 00000000..b23d9321 --- /dev/null +++ b/djangosnippets/templates/forms/form.html @@ -0,0 +1,22 @@ +{% load widget_tweaks %} + +{% if form.non_field_errors %} + +{% endif %} +{% for field in form %} +
+
+ + +
+ {% if field.errors %} + {{ field|add_class:"h-12 text-lg rounded-lg border-red-600 border-2 my-2" }} + {% else %} + {{ field|add_class:"h-12 text-lg rounded-lg border-base-green-400 border-2 my-2" }} + {% endif %} + {% if field.help_text %}
{{ field.help_text|safe }}
{% endif %} + {% if field.errors %}
    {% for error in field.errors %}
  • {{ error }}
  • {% endfor %}
{% endif %} +
+{% endfor %} diff --git a/djangosnippets/templates/socialaccount/authentication_error.html b/djangosnippets/templates/socialaccount/authentication_error.html index 3a49a7dd..caa9b1d6 100644 --- a/djangosnippets/templates/socialaccount/authentication_error.html +++ b/djangosnippets/templates/socialaccount/authentication_error.html @@ -1,11 +1,17 @@ {% extends "socialaccount/base.html" %} -{% load i18n %} +{% load static %} -{% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %} +{% block head_title %}Social Network Login Failure{% endblock %} -{% block content_header %}{% trans "Social Network Login Failure" %}{% endblock %} +{% block header %}{% endblock %} {% block content %} -

{% trans "An error occurred while attempting to login via your social network account." %}

+
+

Social Network Login Failure

+ +

An error occurred while attempting to login via your third-party account.

+
{% endblock %} + +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/socialaccount/login_cancelled.html b/djangosnippets/templates/socialaccount/login_cancelled.html index 77999649..5a016705 100644 --- a/djangosnippets/templates/socialaccount/login_cancelled.html +++ b/djangosnippets/templates/socialaccount/login_cancelled.html @@ -1,14 +1,19 @@ {% extends "socialaccount/base.html" %} -{% load i18n %} +{% load static %} -{% block head_title %}{% trans "Login Cancelled" %}{% endblock %} +{% block head_title %}Login Cancelled{% endblock %} -{% block content_header %}{% trans "Login Cancelled" %}{% endblock %} +{% block header %}{% endblock %} {% block content %} -{% url 'account_login' as login_url %} - -

{% blocktrans %}You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in.{% endblocktrans %}

+
+

Login Cancelled

+ +

You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in.

+ Sign In +
{% endblock %} + +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/socialaccount/messages/account_connected.txt b/djangosnippets/templates/socialaccount/messages/account_connected.txt deleted file mode 100644 index be6aa60f..00000000 --- a/djangosnippets/templates/socialaccount/messages/account_connected.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}The social account has been connected.{% endblocktrans %} diff --git a/djangosnippets/templates/socialaccount/messages/account_connected_other.txt b/djangosnippets/templates/socialaccount/messages/account_connected_other.txt deleted file mode 100644 index e90f6ccc..00000000 --- a/djangosnippets/templates/socialaccount/messages/account_connected_other.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}The social account is already connected to a different account.{% endblocktrans %} diff --git a/djangosnippets/templates/socialaccount/messages/account_disconnected.txt b/djangosnippets/templates/socialaccount/messages/account_disconnected.txt deleted file mode 100644 index fd43f30e..00000000 --- a/djangosnippets/templates/socialaccount/messages/account_disconnected.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans %}The social account has been disconnected.{% endblocktrans %} diff --git a/djangosnippets/templates/socialaccount/signup.html b/djangosnippets/templates/socialaccount/signup.html index ab806d31..19968781 100644 --- a/djangosnippets/templates/socialaccount/signup.html +++ b/djangosnippets/templates/socialaccount/signup.html @@ -1,20 +1,19 @@ {% extends "socialaccount/base.html" %} -{% load i18n %} -{% block head_title %}{% trans "Signup" %}{% endblock %} +{% block head_title %}Signup{% endblock %} -{% block content_header %}{% trans "Signup" %}{% endblock %} +{% block header %}{% endblock %} {% block content %} -

{% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are about to use your {{ provider_name }} account to login to -{{ site_name }}. As a final step, please complete the following form:{% endblocktrans %}

+
+

Signup

+

You are about to use your {{ account.get_provider.name }} account to login to {{ site.name }}. As a final step, please complete the following form:

- + +
{% endblock %} +{% block footer %}{% endblock %} diff --git a/djangosnippets/templates/socialaccount/snippets/login_extra.html b/djangosnippets/templates/socialaccount/snippets/login_extra.html deleted file mode 100644 index 307def40..00000000 --- a/djangosnippets/templates/socialaccount/snippets/login_extra.html +++ /dev/null @@ -1,3 +0,0 @@ -{% load socialaccount %} - -{% providers_media_js %} diff --git a/djangosnippets/templates/socialaccount/snippets/provider_list.html b/djangosnippets/templates/socialaccount/snippets/provider_list.html index e058913e..6a8a68af 100644 --- a/djangosnippets/templates/socialaccount/snippets/provider_list.html +++ b/djangosnippets/templates/socialaccount/snippets/provider_list.html @@ -3,7 +3,7 @@ {% get_providers as socialaccount_providers %} {% for provider in socialaccount_providers %} -
  • - {{ provider.name }} +
  • + Continue with {{ provider.name }}
  • {% endfor %} diff --git a/pyproject.toml b/pyproject.toml index c2d8144d..9df1422f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ dependencies = [ "markdown", "pillow", "psycopg2-binary", - "pydantic", + "pydantic[email]", "pygments", "python-akismet", "python-dotenv", @@ -37,6 +37,7 @@ dependencies = [ "sentry-sdk", "gevent", "greenlet", + "django-widget-tweaks>=1.5.0", ] [project.optional-dependencies] diff --git a/theme/static_src/src/styles.css b/theme/static_src/src/styles.css index 3e94d371..a8810a17 100644 --- a/theme/static_src/src/styles.css +++ b/theme/static_src/src/styles.css @@ -6,13 +6,22 @@ --color-base-black: #0a0a0a; --color-base-gray-400: #7a7a7a; --color-base-green-400: #256918; + --color-base-green-600: #1E4F15; --color-base-green-800: #12330c; + --shadow-sign-content: rgba(0, 0, 0, 0.24) 0px 3px 8px; --font-header: "Libertinus Sans", sans-serif; --font-title: "Playfair Display", sans-serif; --font-text: "Nunito", sans-serif; --font-common: "Raleway", sans-serif; } +/* Additional default styles to be applied when SCSS is completely removed */ +@layer base { + a { + text-underline-offset: 4px ; + } +} + @layer components { .arrow-left::before { @apply content-[''] w-4 h-4 bg-current mr-2; @@ -25,6 +34,10 @@ } } +.button { + @apply border-2 px-4 py-2 my-2 bg-base-green-600 border-base-green-800 hover:bg-base-green-400 rounded-lg; +} + /** * A catch-all path to Django template files, JavaScript, and Python files * that contain Tailwind CSS classes and will be scanned by Tailwind to generate the final CSS file. diff --git a/uv.lock b/uv.lock index 027557fe..cc942a8c 100644 --- a/uv.lock +++ b/uv.lock @@ -343,6 +343,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cd/8f/7a651007ab9bf552221ae8adc9305c7d21113a9814eb38153b5fdb4ef5eb/django_tailwind-4.0.1-py3-none-any.whl", hash = "sha256:33e5dd5aadd5aa6facf4bddab9144a40cb501e486d4970b93e2853dbdbef4f67", size = 16714, upload-time = "2025-04-02T20:04:03.038Z" }, ] +[[package]] +name = "django-widget-tweaks" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/fe/26eb92fba83844e71bbec0ced7fc2e843e5990020e3cc676925204031654/django-widget-tweaks-1.5.0.tar.gz", hash = "sha256:1c2180681ebb994e922c754804c7ffebbe1245014777ac47897a81f57cc629c7", size = 14767, upload-time = "2023-08-25T15:29:12.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/6a/6cb6deb5c38b785c77c3ba66f53051eada49205979c407323eb666930915/django_widget_tweaks-1.5.0-py3-none-any.whl", hash = "sha256:a41b7b2f05bd44d673d11ebd6c09a96f1d013ee98121cb98c384fe84e33b881e", size = 8960, upload-time = "2023-08-25T15:29:05.644Z" }, +] + [[package]] name = "djangorestframework" version = "3.15.2" @@ -374,6 +383,7 @@ dependencies = [ { name = "django-redis-cache" }, { name = "django-taggit" }, { name = "django-tailwind" }, + { name = "django-widget-tweaks" }, { name = "djangorestframework" }, { name = "gevent" }, { name = "greenlet" }, @@ -381,7 +391,7 @@ dependencies = [ { name = "markdown" }, { name = "pillow" }, { name = "psycopg2-binary" }, - { name = "pydantic" }, + { name = "pydantic", extra = ["email"] }, { name = "pygments" }, { name = "python-akismet" }, { name = "python-dotenv" }, @@ -421,6 +431,7 @@ requires-dist = [ { name = "django-redis-cache" }, { name = "django-taggit" }, { name = "django-tailwind" }, + { name = "django-widget-tweaks", specifier = ">=1.5.0" }, { name = "djangorestframework" }, { name = "gevent" }, { name = "greenlet" }, @@ -430,7 +441,7 @@ requires-dist = [ { name = "pillow" }, { name = "pre-commit", marker = "extra == 'dev'" }, { name = "psycopg2-binary" }, - { name = "pydantic" }, + { name = "pydantic", extras = ["email"] }, { name = "pygments" }, { name = "python-akismet" }, { name = "python-dotenv" }, @@ -518,6 +529,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f2/fd/1f3ca2777adef393c135c9bd45260147a2ee72328cf4804f69ad392bebd5/djc_core_html_parser-1.0.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1c2e86c819e6dc49b8c4c81ed4e7a326d877f0aa884e6c6d3e19ce8d292d2dd3", size = 1221302, upload-time = "2025-10-21T21:04:17.876Z" }, ] +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + [[package]] name = "filelock" version = "3.20.0" @@ -1031,6 +1064,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + [[package]] name = "pydantic-core" version = "2.33.2"