From 500b5b525e87e9900f477a8ceb05fb4aa2c5afd4 Mon Sep 17 00:00:00 2001 From: Nilanchala Date: Wed, 10 Jan 2024 14:12:31 +0000 Subject: [PATCH] Added account, feedback form, edit profile --- .pylintrc | 3 +- .vscode/settings.json | 5 +- bloggy/forms/change_password_form.py | 30 +++++ bloggy/forms/edit_profile_form.py | 3 + bloggy/forms/update_username_form.py | 31 +++++ .../send_account_activation_reminders.py | 2 +- bloggy/management/commands/send_card.py | 2 +- bloggy/management/commands/send_newsletter.py | 2 +- bloggy/models/user.py | 1 - bloggy/services/email_service.py | 57 +++----- bloggy/templates/.DS_Store | Bin 0 -> 6148 bytes bloggy/templates/auth/password_reset.html | 2 +- bloggy/templates/base-with-header-footer.html | 10 +- bloggy/templates/base-with-header.html | 10 +- bloggy/templates/pages/home.html | 12 +- bloggy/templates/pages/single/course.html | 27 ++-- .../templates/pages/single/post-standard.html | 2 +- .../pages/{user.html => user_profile.html} | 14 +- bloggy/templates/partials/dashboard_menu.html | 34 ++--- bloggy/templates/partials/header.html | 39 ++++-- .../user_profile_social_media_links.html | 20 +-- bloggy/templates/profile/account_view.html | 124 ++++++++++++++++++ bloggy/templates/profile/change_password.html | 44 +++++++ bloggy/templates/profile/edit_profile.html | 61 ++++++--- bloggy/templates/profile/update_username.html | 44 +++++++ bloggy/templates/profile/user_dashboard.html | 33 ----- bloggy/templates/widgets/feedback-form.html | 98 ++++++++++++++ bloggy/urls.py | 14 +- bloggy/views/__init__.py | 1 - bloggy/views/account_view.py | 22 ++++ bloggy/views/category_view.py | 1 - bloggy/views/change_password_view.py | 16 +++ bloggy/views/courses_view.py | 2 + bloggy/views/edit_profile_view.py | 12 +- bloggy/views/register.py | 22 +++- bloggy/views/update_username_view.py | 22 ++++ bloggy/views/user.py | 70 ++-------- bloggy_api/urls.py | 17 +-- bloggy_api/views/feedback_api.py | 33 +++++ bloggy_api/views/newsletter_api.py | 25 +++- bloggy_frontend/js/app/toast.js | 7 +- bloggy_frontend/js/vue/disqus/ContactForm.vue | 6 - bloggy_frontend/sass/_customVariables.scss | 2 +- bloggy_frontend/sass/_utils.scss | 40 ++++++ bloggy_frontend/sass/bootstrap.scss | 4 +- bloggy_frontend/sass/content/_darkMode.scss | 3 +- bloggy_frontend/sass/content/_feedback.scss | 61 +++++++++ .../sass/content/_update-profile.scss | 9 -- bloggy_frontend/sass/content/post.scss | 1 - bloggy_frontend/sass/style.scss | 2 +- bloggy_frontend/sass/vendor/_alert.scss | 2 +- bloggy_frontend/sass/vendor/_button.scss | 8 +- bloggy_frontend/sass/vendor/_card.scss | 4 + .../sass/vendor/_dark_mode_toggle.scss | 27 ++-- bloggy_frontend/sass/vendor/_navbar.scss | 4 +- bloggy_frontend/sass/vendor/_toast.scss | 3 +- 56 files changed, 848 insertions(+), 302 deletions(-) create mode 100644 bloggy/forms/change_password_form.py create mode 100644 bloggy/forms/update_username_form.py create mode 100644 bloggy/templates/.DS_Store rename bloggy/templates/pages/{user.html => user_profile.html} (77%) create mode 100644 bloggy/templates/profile/account_view.html create mode 100644 bloggy/templates/profile/change_password.html create mode 100644 bloggy/templates/profile/update_username.html delete mode 100644 bloggy/templates/profile/user_dashboard.html create mode 100644 bloggy/templates/widgets/feedback-form.html create mode 100644 bloggy/views/account_view.py create mode 100644 bloggy/views/change_password_view.py create mode 100644 bloggy/views/update_username_view.py create mode 100644 bloggy_api/views/feedback_api.py create mode 100644 bloggy_frontend/sass/content/_feedback.scss delete mode 100644 bloggy_frontend/sass/content/_update-profile.scss diff --git a/.pylintrc b/.pylintrc index 0111a6b..ff28161 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,2 +1,3 @@ [MASTER] -ignore=migrations \ No newline at end of file +ignore=migrations +disable=C0114, # missing-module-docstring \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d23c7f..8e5f771 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "editor.formatOnSave": false, "python.linting.enabled": true, "python.linting.lintOnSave": true, - // "editor.fontFamily": "Dank Mono, JetBrains Mono NL, Fira Code, Menlo, Monaco, 'Courier New', monospace", - // "editor.fontSize": 14, +// "editor.fontFamily": "Dank Mono, JetBrains Mono NL, Fira Code, Menlo, Monaco, 'Courier New', monospace", +// "editor.fontSize": 14, + "python.linting.pylintArgs": ["--disable=C0111"] } \ No newline at end of file diff --git a/bloggy/forms/change_password_form.py b/bloggy/forms/change_password_form.py new file mode 100644 index 0000000..d4482b2 --- /dev/null +++ b/bloggy/forms/change_password_form.py @@ -0,0 +1,30 @@ +from django import forms +from django.contrib.auth.forms import PasswordChangeForm + + +class ChangePasswordForm(PasswordChangeForm): + old_password = forms.CharField( + label="Old password", + strip=False, + widget=forms.PasswordInput( + attrs={"autocomplete": "current-password", "autofocus": True, 'class': 'form-control'} + ), + ) + + new_password1 = forms.CharField( + label="New Password", + help_text='Please use 8 or more characters with a mix of letters, numbers & symbols', + widget=forms.PasswordInput(attrs={'class': 'form-control'}, ) + ) + new_password2 = forms.CharField( + label="Confirm New Password", + widget=forms.PasswordInput(attrs={'class': 'form-control'}), + ) + + def clean_new_password2(self): + new_password1 = self.cleaned_data.get('new_password1') + new_password2 = self.cleaned_data.get('new_password2') + + if new_password1 and new_password2 and new_password1 != new_password2: + raise forms.ValidationError("Passwords do not match.") + return new_password2 diff --git a/bloggy/forms/edit_profile_form.py b/bloggy/forms/edit_profile_form.py index 68c789b..045a199 100644 --- a/bloggy/forms/edit_profile_form.py +++ b/bloggy/forms/edit_profile_form.py @@ -11,6 +11,9 @@ class NonClearableFileInput(ClearableFileInput): class EditProfileForm(forms.ModelForm): class Meta: model = User + help_texts={ + "bio": "This will be displayed publicly on your profile. Keep it short and crisp." + } fields = [ 'profile_photo', 'name', diff --git a/bloggy/forms/update_username_form.py b/bloggy/forms/update_username_form.py new file mode 100644 index 0000000..8bf2914 --- /dev/null +++ b/bloggy/forms/update_username_form.py @@ -0,0 +1,31 @@ +from django import forms +from django.contrib.auth import get_user_model + + +class UpdateUsernameForm(forms.ModelForm): + class Meta: + model = get_user_model() + fields = ['username'] + help_texts={ + 'username': 'Letters, digits and "_" only allowed.' + } + labels = { + "username": "New username", + } + + widgets = { + 'username': forms.TextInput(attrs={ + 'class': 'form-control', + 'placeholder': 'Username', + }), + } + + def clean_username(self): + new_username = self.cleaned_data['username'] + user_model = get_user_model() + + # Check if the new username is available + if user_model.objects.filter(username=new_username).exclude(pk=self.instance.pk).exists(): + raise forms.ValidationError('This username is already in use. Please choose a different one.') + + return new_username diff --git a/bloggy/management/commands/send_account_activation_reminders.py b/bloggy/management/commands/send_account_activation_reminders.py index e93e609..c68dce7 100644 --- a/bloggy/management/commands/send_account_activation_reminders.py +++ b/bloggy/management/commands/send_account_activation_reminders.py @@ -31,7 +31,7 @@ def handle(self, *args, **kwargs): } try: - email_service.send_custom_email( + email_service.send_html_email( subject, [user.email], "email/account_activation_reminder_email.html", diff --git a/bloggy/management/commands/send_card.py b/bloggy/management/commands/send_card.py index 04de31b..7c60d51 100644 --- a/bloggy/management/commands/send_card.py +++ b/bloggy/management/commands/send_card.py @@ -41,7 +41,7 @@ def handle(self, *args, **options): } try: - email_service.send_custom_email(subject, [user.email], "email/wish_card_email.html", args) + email_service.send_html_email(subject, [user.email], "email/wish_card_email.html", args) print('Success: Card sent to {}', user.email) except Exception as ex: print('Error sending card to {}: {}', user.email, ex) diff --git a/bloggy/management/commands/send_newsletter.py b/bloggy/management/commands/send_newsletter.py index 7d5389a..0e14144 100644 --- a/bloggy/management/commands/send_newsletter.py +++ b/bloggy/management/commands/send_newsletter.py @@ -37,7 +37,7 @@ def handle(self, *args, **options): } try: - email_service.send_custom_email(subject, [user.email], "email/wish_card_email.html", args) + email_service.send_html_email(subject, [user.email], "email/wish_card_email.html", args) print('Success: Card sent to {}', user.email) except Exception as ex: print('Error sending card to {}: {}', user.email, ex) diff --git a/bloggy/models/user.py b/bloggy/models/user.py index 9e96cd7..c225e1e 100644 --- a/bloggy/models/user.py +++ b/bloggy/models/user.py @@ -81,7 +81,6 @@ def get_bookmarks_count(self): def get_full_name_or_username(self): if self.name: return self.name - return self.username def __str__(self): diff --git a/bloggy/services/email_service.py b/bloggy/services/email_service.py index 28c324c..2531979 100644 --- a/bloggy/services/email_service.py +++ b/bloggy/services/email_service.py @@ -1,55 +1,36 @@ from django.core.mail import send_mail from django.template.loader import render_to_string -from django.urls import reverse from bloggy import settings -def send_custom_email(subject, recipients, template, args, from_email=settings.DEFAULT_FROM_EMAIL): +def send_html_email(subject, to_email, template, args, from_email=settings.DEFAULT_FROM_EMAIL): email_body = render_to_string(template, args) send_mail( subject, email_body, from_email, - recipients, + to_email, fail_silently=False, html_message=email_body ) -def send_newsletter_verification_token(request, email, uuid, token): - subject = f'Confirm to {settings.SITE_TITLE} newsletter' - - args = { - "email_subject": subject, - "app_name": settings.SITE_TITLE, - "verification_link": request.build_absolute_uri(reverse("newsletter_verification", args=[uuid, token])) - } - - send_custom_email(subject, [email], "email/newsletter_verification_token.html", args) - - -def email_verification_token(request, new_user, token): - subject = f"{settings.SITE_TITLE} confirmation code: {token.code}" - args = { - "email_subject": subject, - "verification_code": token.code, - "app_name": settings.SITE_TITLE, - "verification_link": request.build_absolute_uri(reverse("otp_verification", args=[token.uuid])) - } - send_custom_email(subject, [new_user.email], "email/login_code_email.html", args) - - -def send_account_activation_email(request, new_user, verification_token): - subject = f'Welcome to {settings.SITE_TITLE}!' - args = { - "email_subject": subject, - "user_name": new_user.name, - "app_name": settings.SITE_TITLE, - "verification_link": request.build_absolute_uri(reverse("activate_account", args=[ - verification_token.uuid, - verification_token.token - ])) - } +def send_plain_email(subject, to_email, message_content, from_email=settings.DEFAULT_FROM_EMAIL): + send_mail( + subject, + message_content, + from_email, + to_email, + fail_silently=False, + ) - send_custom_email(subject, [new_user.email], "email/account_activation_email.html", args) \ No newline at end of file +# def email_verification_token(request, new_user, token): +# subject = f"{settings.SITE_TITLE} confirmation code: {token.code}" +# args = { +# "email_subject": subject, +# "verification_code": token.code, +# "app_name": settings.SITE_TITLE, +# "verification_link": request.build_absolute_uri(reverse("otp_verification", args=[token.uuid])) +# } +# send_html_email(subject, [new_user.email], "email/login_code_email.html", args) diff --git a/bloggy/templates/.DS_Store b/bloggy/templates/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3ce9dd10aa59164d02db1068318f7fba98b7bd17 GIT binary patch literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n1@lf?^{oiq>0sE|2D$PqQp`S}1Q|@{-BCguG&B zM?`df+s;HLA~J#-%EN}P*}i$ldKpn59A{kbtIP3lI_^8U?*hgh%2_tDmtBi*J2Wal z1*iZOpaN9j(+XsT9gRPIFwdg`RN&_ouHg$K#o*^3bYmI$8uuze+hrn z|F=n8Q2{FOR|@E0v0BXWq^zx-$62i{@HO0Wo^UhFor1y3G0@8~7FLd@o)me-=Gd=^ UO`y{ecRG+i1Evd&3Vd6E7ypForgot password diff --git a/bloggy/templates/base-with-header-footer.html b/bloggy/templates/base-with-header-footer.html index 6cba4d8..7118fd0 100644 --- a/bloggy/templates/base-with-header-footer.html +++ b/bloggy/templates/base-with-header-footer.html @@ -32,15 +32,7 @@
- {% if messages %} -
- {% for message in messages %} -
- {{ message }} -
- {% endfor %} -
- {% endif %} + {% include 'widgets/feedback-form.html' %} {% block content %}{% endblock content %}