From 7ae8c16db2496b9410c8c116ab8e1f9b015d1c9b Mon Sep 17 00:00:00 2001 From: Faheed Date: Mon, 20 Oct 2025 17:30:08 +0300 Subject: [PATCH] password reset --- .../__pycache__/settings.cpython-312.pyc | Bin 8301 -> 8478 bytes NorahUniversity/settings.py | 33 ++-- recruitment/__pycache__/forms.cpython-312.pyc | Bin 26374 -> 26564 bytes .../__pycache__/models.cpython-312.pyc | Bin 58633 -> 60414 bytes recruitment/__pycache__/urls.cpython-312.pyc | Bin 11571 -> 11703 bytes recruitment/__pycache__/views.cpython-312.pyc | Bin 86075 -> 87400 bytes recruitment/forms.py | 4 + recruitment/models.py | 23 +++ recruitment/urls.py | 5 + recruitment/views.py | 79 ++++++--- templates/account/account_inactive.html | 155 ++++++++++++++++++ templates/account/email.html | 125 ++++++++++++++ .../email/password_reset_key_message.html | 39 +++++ templates/account/email_confirm.html | 71 ++++++++ templates/account/logout.html | 80 +++++++++ templates/account/password_change.html | 2 +- .../account/password_reset_from_key.html | 144 ++++------------ .../account/password_reset_from_key_done.html | 87 ++++++++++ templates/base.html | 6 +- templates/includes/easy_logs.html | 2 +- templates/jobs/job_list.html | 10 +- templates/user/admin_settings.html | 51 +++++- templates/user/profile.html | 56 ++++++- 23 files changed, 806 insertions(+), 166 deletions(-) create mode 100644 templates/account/account_inactive.html create mode 100644 templates/account/email.html create mode 100644 templates/account/email/password_reset_key_message.html create mode 100644 templates/account/email_confirm.html create mode 100644 templates/account/logout.html create mode 100644 templates/account/password_reset_from_key_done.html diff --git a/NorahUniversity/__pycache__/settings.cpython-312.pyc b/NorahUniversity/__pycache__/settings.cpython-312.pyc index ddf3afbc8f013b532a4807c1ff6aa286fef33ff7..9e1dff922b71352517ba92f971267004060c9fdf 100644 GIT binary patch delta 1200 zcmYLGT~HfU6yDv0lu*)1A*9XJP$(1#6euB-pVF290a75)B(!>4jS1hfSqMqkO{w5d z>QAc{t+hL&&KS!~W_%>_I6zxJE z{F1=VptqlOi*^LI4|5!)?!f@-r8H+r`f!f^vseC??qjgxE!rOH^wNQ!I#SHjWwU zVgg|{NfN?kHicO>jX5@hc@{7$dmBO;A0nyYekW8J1Z0c348CtTjS!A$IV`R&`Oov#`94k*_Z9t(r z9Mp2r2o%V5({yZ>d2v>p#jTQXpz#tlw1sWFj92g~@z+qqZM=>*N>;pyw{Qn{P5w6C z!MnI;aLGz*-zin$Jt}3K_e&P?+%H+!96n(4TY~RFGQe|OP30#`ZFR8?tI4dC>p`j~ zm0VsEvrv2TIkg}uqPmeu9&<*S`@KeGiB;Af8T)Op{?rH zfk40CXVYz=$aFXo(yfu;JmFF-6xFL2gR$7Ph3KSiomq&*b?f3nG_JH&PSpO$d-P)} z6;6ojNjZ~P&Sh6*Wj$GtbJ@zTj!y;czB6izQUN8d{p{>Mpq`@}e4?^*w1sb8GlDq- z@&=gZ1~FfgvT8cC@9P?zraNQU>jq@C-|MFNHEp!MtM%zyy}FP?ZcbJU|7TH@e{<~A z(>Ap~>I3ws)5QqyxQ6(&_Om%dJ#{~MJT;AwhRa7n2Fv=IS-G)y0XGX-jDT}w1 zN5;)v18!44!cruj2+aq>bBSo^%2GHQ(tbF8*HwQIiU#AM#9Vkj9FJA5dcGBE{-!## zd``VyX?w=Tx7Ko1NA~JQ_M9j7oX7WEO(t>w<~ZcE?OW^);kJF>uZ6ugYW6rI8 e?j3g0o5oKH`xfDt@R+OLcUGQw?+MnwDC<9_{c0xw delta 1024 zcmX|8OHfm16u$q>0|~?d!6=R(?+`HfAPOkTLqiN=T1%_-h)UqQUamqCZsLnRBG&q# z9bb3U&h(Cpj5}AIEW7TeE;^lVoUFQNcXbAJ-1q!f@cwhY^Zn<2?*DA$^^pIi-|tiS z`@8J@Y{f%=op}CBFf8&~IqDZH6a@{oY6z;wHZ&T7vB|+^2U`rGyQu-Kx}a^kg0_O7 zMtG?S?bHmFT9~&Yhz_pMh7h%*lY%TA@bc-hRSID{!n#VG=%z02xkL8kYE9d*lfs_eV4t(dUhJn{ z3{W2qP(KdRJ`B=+4AB6~0q%7W!!(Ey8p0tSV;F~Ngyj&TbQq%)MT|yqgkp$e3`a4J za$e*ZvvMTz_ynKgI6kvon84@w0w6PSJDxj#w5=0?JUkYdJ0KLPh-Z> zfad7)(52SB6vr$KUgJVR7<`yrbk>^VwdRrH7zODGeOW?mB)%>wVRPcZ`WSZY8S2Yjml4L7XhUt8NjaGt#L`n3dpM4Q8Q6b9&8C zDobC=K}+RIULz&-hcHOLCgHp_SrZd8*7KUK){nJH>vCzN$Bpc2xU6bkaB5obY7CLI z&eTRY=}|2)zOL;PQ&#)N2etQP$bANGo5>mJRMxy`{l0NP%voiD&cI{oabGsHE9Mg! z`BcKZ6$^BTl$8ne1*c?y$Cyv*TFH}3PS0u1CM93SOlLGRXK2}w%Urhp2=t2aV%esM zYE9JLEdE#bo9cVZx%}Ui>|pWNtzJ>zta#SH+R*)~YV%J6e^v$GcwAN96_>}aUN2wS XYW-V3X~i1)#fIX8hGo^g!ioO_$%QMM diff --git a/NorahUniversity/settings.py b/NorahUniversity/settings.py index c87beef..6be985e 100644 --- a/NorahUniversity/settings.py +++ b/NorahUniversity/settings.py @@ -132,23 +132,23 @@ WSGI_APPLICATION = 'NorahUniversity.wsgi.application' # Database # https://docs.djangoproject.com/en/5.2/ref/settings/#databases -# DATABASES = { -# 'default': { -# 'ENGINE': 'django.db.backends.postgresql_psycopg2', -# 'NAME': 'norahuniversity', -# 'USER': 'norahuniversity', -# 'PASSWORD': 'norahuniversity', -# 'HOST': '127.0.0.1', -# 'PORT': '5432', -# } -# } - DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'haikal_db', + 'USER': 'faheed', + 'PASSWORD': 'Faheed@215', + 'HOST': '127.0.0.1', + 'PORT': '5432', } -} +} + +# DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.sqlite3', +# 'NAME': BASE_DIR / 'db.sqlite3', +# } +# } # Password validation # https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators @@ -178,6 +178,7 @@ ACCOUNT_SIGNUP_FIELDS = ['email*', 'password1*', 'password2*'] ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_EMAIL_VERIFICATION = 'none' ACCOUNT_USER_MODEL_USERNAME_FIELD = None +ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True @@ -197,6 +198,10 @@ CRISPY_BS5 = { 'use_css_helpers': True, } +ACCOUNT_RATE_LIMITS = { + 'send_email_confirmation': None, # Disables the limit +} + # Internationalization # https://docs.djangoproject.com/en/5.2/topics/i18n/ diff --git a/recruitment/__pycache__/forms.cpython-312.pyc b/recruitment/__pycache__/forms.cpython-312.pyc index 3f269ca58dc20bc4ef1ad547e6d056f84ab7ab89..9725eb3dbdf5f2ae28daf02c5c52b51aac2fc152 100644 GIT binary patch delta 233 zcmZoW$9UvCBkyTmUM>b8Ftq%ZVKtFglJU((^~213ObqS}DJCrpDW<86SqYOHwS_0w zGjg!nR2piUZGOkx9`BV5(gg#IP{wB-AY(d1Dnk@w3PTiAC8H+OEy0ld^z@um$K>Sv z(!3J4{GwbxP39sapu!?!5MeU;psBEOB+!T=5V3=afuWccDAB@jgN38W4x|Jmu4%iu zJoz;vW8~zxR9UVJpa>8#6nAZIO)Y1X{=%TjDDowUk&%&e2J3vTnOt8PfK0G%0KBU< AhyVZp delta 78 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 H?Am_-SWwat delta 8148 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 diff --git a/recruitment/__pycache__/urls.cpython-312.pyc b/recruitment/__pycache__/urls.cpython-312.pyc index 66d82628c22c4fc8b78543fca2e095804a892c05..0baf2e898c605d8ffde1d5b9049dcc7058d40272 100644 GIT binary patch delta 1320 zcmZ{kUuauZ9LIB$Q!r~&r)xAZO)}G)`M2r{=94Jdd=!TBQWT?XgCfdj(!uvcG>3JQwgy}#og1id6*lHcd| z=X>rw=kDk46+Az9JO>=sWyXJ7eZ1%KOW)p&-|Rf%bd;r)TV-_VmJR=Xt$hCVQ(w76 zY){HhU%Rc|+5fJy{oqh&sZ^?NZ`Oe^=gl`HEfe)Rq)zaBCE z3Wbcvp+BY9_aBABF6UOx_#-m&;*K>#vc9!n-3|wLNs{!?(G8zN4;^8SbmMZ*^OA0S z&=VQdrKg=gA8@p}KMFOy%&!u^YIaa`oVNq%un2Z*rkC}NlfH3$c9Ehb?$M1$J-#8x zcos6cn`IVCkxUB}UGA|o5S1;>fR;f&2K^=~i!MX|IPGN0I8mM~b67Wc)SlK6v+Mg}F-zw_8=zl+ zJ^=a){PxG~oD66s9vlXb^OC*HV6%<+6yj5`c9NnDzaRlzupxFIz8(ECbth%spy(7Y zT0Opx#~YAvQ6$8$GR%}SL^*@ctx#0v6;Z$XKX^^xO9Dr*oM!SAk*DzNIz=0NUEnQ& z{mnEBBuOA?T906i*90_5iqCSQE8UiUsst^)rv#6Ks~e&aZu}(apTsj2idK0;RA!v8 zsI1^kuWmj?R*!vp8R)sLpeC=LB?4*lwpl*C6s?;;lj6YydcOtkic$^c~#<7pX>+$7XXHuZ4Ktrh)=`m35rhhqM(anWZXVg8KPwH zsXRpmz9i_fplU115?PYS;>l%-O1vcKrl4@DCWtnHUxS@g74(XrC+~aNNP&zL@Jq{Y sQ*@2LCGeKOBlpv6tVqU+_@cE}8@wjyj&U&goaZY1d9Qt|ZoPi~2LHygasU7T delta 1083 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 delta 17011 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 diff --git a/recruitment/forms.py b/recruitment/forms.py index ec2186b..1794f3f 100644 --- a/recruitment/forms.py +++ b/recruitment/forms.py @@ -693,3 +693,7 @@ class StaffUserCreationForm(UserCreationForm): +class ToggleAccountForm(forms.Form): + pass + + diff --git a/recruitment/models.py b/recruitment/models.py index 4ebd9d8..0939404 100644 --- a/recruitment/models.py +++ b/recruitment/models.py @@ -29,6 +29,9 @@ class Profile(models.Model): profile_image = models.ImageField(null=True, blank=True, upload_to="profile_pic/") user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile") + def __str__(self): + return f"image for user {self.user}" + class JobPosting(Base): # Basic Job Information JOB_TYPES = [ @@ -301,6 +304,26 @@ class JobPosting(Base): @property def offer_candidates(self): return self.all_candidates.filter(stage="Offer") + + + #counts + @property + def all_candidates_count(self): + return self.candidates.annotate(sortable_score=Cast('ai_analysis_data__match_score',output_field=CharField())).order_by('-sortable_score').count() + @property + def screening_candidates_count(self): + return self.all_candidates.filter(stage="Applied").count() + + @property + def exam_candidates_count(self): + return self.all_candidates.filter(stage="Exam").count() + @property + def interview_candidates_count(self): + return self.all_candidates.filter(stage="Interview").count() + + @property + def offer_candidates_count(self): + return self.all_candidates.filter(stage="Offer").count() class JobPostingImage(models.Model): job=models.OneToOneField('JobPosting',on_delete=models.CASCADE,related_name='post_images') diff --git a/recruitment/urls.py b/recruitment/urls.py index c755962..8d3a50f 100644 --- a/recruitment/urls.py +++ b/recruitment/urls.py @@ -108,6 +108,7 @@ urlpatterns = [ path('jobs//candidates//schedule-meeting-page/', views.schedule_meeting_for_candidate, name='schedule_meeting_for_candidate'), path('jobs//candidates//delete_meeting_for_candidate//', views.delete_meeting_for_candidate, name='delete_meeting_for_candidate'), + # users urls path('user/',views.user_detail,name='user_detail'), path('user/user_profile_image_update/',views.user_profile_image_update,name='user_profile_image_update'), @@ -115,6 +116,10 @@ urlpatterns = [ path('settings/',views.admin_settings,name='admin_settings'), path('staff/create',views.create_staff_user,name='create_staff_user'), path('set_staff_password//',views.set_staff_password,name='set_staff_password'), + path('account_toggle_status/',views.account_toggle_status,name='account_toggle_status'), + + + # Meeting Comments URLs path('meetings//comments/add/', views.add_meeting_comment, name='add_meeting_comment'), diff --git a/recruitment/views.py b/recruitment/views.py index bdfb538..dbede05 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -26,8 +26,10 @@ from .forms import ( BreakTimeFormSet, JobPostingImageForm, ProfileImageUploadForm, - StaffUserCreationForm - ,MeetingCommentForm + StaffUserCreationForm, + MeetingCommentForm, + ToggleAccountForm, + ) from easyaudit.models import CRUDEvent, LoginEvent, RequestEvent from rest_framework import viewsets @@ -1940,37 +1942,51 @@ def schedule_meeting_for_candidate(request, slug, candidate_pk): from django.core.exceptions import ObjectDoesNotExist def user_profile_image_update(request, pk): + user = get_object_or_404(User, pk=pk) + + # 2. Ensure Profile exists and get the instance try: - instance =user.profile - - except ObjectDoesNotExist as e: - Profile.objects.create(user=user) - + + profile_instance = user.profile + except ObjectDoesNotExist: + + profile_instance = Profile.objects.create(user=user) + if request.method == 'POST': - profile_form = ProfileImageUploadForm(request.POST, request.FILES, instance=user.profile) + + profile_form = ProfileImageUploadForm( + request.POST, + request.FILES, + instance=profile_instance # <--- USE profile_instance HERE + ) + if profile_form.is_valid(): profile_form.save() - messages.success(request, 'Image uploaded successfully') - return redirect('user_detail', pk=user.pk) + messages.success(request, 'Image uploaded successfully.') + return redirect('user_detail', pk=user.pk) else: - messages.error(request, 'An error occurred while uploading the image') + messages.error(request, 'An error occurred while uploading the image. Please check the errors below.') else: - profile_form = ProfileImageUploadForm(instance=user.profile) - + # + profile_form = ProfileImageUploadForm(instance=profile_instance) context = { 'profile_form': profile_form, 'user': user, } return render(request, 'user/profile.html', context) - - def user_detail(request, pk): user = get_object_or_404(User, pk=pk) + + + try: + profile_instance = user.profile + profile_form = ProfileImageUploadForm(instance=profile_instance) + except: + profile_form = ProfileImageUploadForm() - profile_form = ProfileImageUploadForm() if request.method == 'POST': first_name=request.POST.get('first_name') last_name=request.POST.get('last_name') @@ -2068,15 +2084,17 @@ def create_staff_user(request): @user_passes_test(is_superuser_check) def admin_settings(request): staffs=User.objects.filter(is_superuser=False) + form = ToggleAccountForm() context={ - 'staffs':staffs + 'staffs':staffs, + 'form':form } return render(request,'user/admin_settings.html',context) from django.contrib.auth.forms import SetPasswordForm - +@user_passes_test(is_superuser_check) def set_staff_password(request,pk): user=get_object_or_404(User,pk=pk) print(request.POST) @@ -2085,10 +2103,11 @@ def set_staff_password(request,pk): if form.is_valid(): form.save() messages.success(request,f'Password successfully changed') + return redirect('admin_settings') else: form=SetPasswordForm(user=user) messages.error(request,f'Password does not match please try again.') - return redirect('set_staff_password',user=user) + return redirect('admin_settings') else: form=SetPasswordForm(user=user) @@ -2096,6 +2115,28 @@ def set_staff_password(request,pk): +@user_passes_test(is_superuser_check) +def account_toggle_status(request,pk): + user=get_object_or_404(User,pk=pk) + if request.method=='POST': + print(user.is_active) + form=ToggleAccountForm(request.POST) + if form.is_valid(): + if user.is_active: + user.is_active=False + user.save() + messages.success(request,f'Staff with email: {user.email} deactivated successfully') + return redirect('admin_settings') + else: + user.is_active=True + user.save() + messages.success(request,f'Staff with email: {user.email} activated successfully') + return redirect('admin_settings') + else: + messages.error(f'Please correct the error below') + + + # @login_required # def user_detail(requests,pk): diff --git a/templates/account/account_inactive.html b/templates/account/account_inactive.html new file mode 100644 index 0000000..c64e2ad --- /dev/null +++ b/templates/account/account_inactive.html @@ -0,0 +1,155 @@ +{% load static i18n %} + + + + + + {% translate "Account Inactive" %} - KAAUH ATS + + + {# Include Font Awesome for icons #} + + + + + + +
+ +
+
+

+ +
+
{% translate "جامعة الأميرة نورة بنت عبدالرحمن الأكاديمية" %}
+
{% translate "ومستشفى الملك عبدالله بن عبدالعزيز التخصصي" %}
+
{% translate "Princess Nourah bint Abdulrahman University" %}
+
{% translate "King Abdullah bin Abdulaziz University Hospital" %}
+
+
+

+ Powered By TENHAL | تنحل +
+
+ +
+ +
+ + + +

{% translate "Account Inactive" %}

+ +
+

+ {% translate "Access denied. This account has been marked as inactive by an administrator." %} +

+

+ {% translate "If you believe this is an error, please contact the system administrator for assistance." %} +

+ + + +
+
+
+
+ + + + + \ No newline at end of file diff --git a/templates/account/email.html b/templates/account/email.html new file mode 100644 index 0000000..5e62859 --- /dev/null +++ b/templates/account/email.html @@ -0,0 +1,125 @@ +{% extends "base.html" %} +{% load i18n %} +{% load account %} +{% load crispy_forms_tags %} + +{% block title %}{% translate "Email Addresses" %}{% endblock %} + +{% block content %} +
+ +
+
+

{% translate "Account Settings" %}

+

{% translate "Manage your personal details and security." %}

+
+
+ +
+ + {# ------------------- LEFT COLUMN: ACCOUNT MENU (New Card Style) ------------------- #} +
+
+
+
+ {# Assuming a main 'Profile' or 'Personal Information' page exists #} + + {% translate "Personal Information" %} + + + {# Highlight the current page (Email) as active #} + + {% translate "Email Addresses" %} + + + {% translate "Change Password" %} + + + + {% translate "Sign Out" %} + +
+
+
+
+ + {# ------------------- RIGHT COLUMN: EMAIL MANAGEMENT ------------------- #} +
+
+
+ +
{% translate "Email Addresses" %}
+

{% translate "These email addresses are linked to your account. You can set the primary address, resend verification, or remove an address." %}

+ + {% if emailaddresses %} + {% for emailaddress in emailaddresses %} +
+ +

+ {{ emailaddress.email }} + + {# Status Badges: Using rounded-pill and appropriate colors #} + {% if emailaddress.primary %} + {% translate "Primary" %} + {% endif %} + {% if emailaddress.verified %} + {% translate "Verified" %} + {% else %} + {% translate "Unverified" %} + {% endif %} +

+ +
+ + {# 1. MAKE PRIMARY ACTION #} + {% if not emailaddress.primary %} +
+ {% csrf_token %} + + + +
+ {% endif %} + + {# 2. RESEND VERIFICATION ACTION #} + {% if not emailaddress.verified %} +
+ {% csrf_token %} + + + +
+ {% endif %} + + {# 3. REMOVE ACTION #} + {% if not emailaddress.primary %} +
+ {% csrf_token %} + + + +
+ {% endif %} +
+
+ {% endfor %} + {% else %} +

{% translate "No email addresses found." %}

+ {% endif %} + +
+ + {# ------------------- ADD EMAIL FORM ------------------- #} +
{% translate "Add Email Address" %}
+
+ {% csrf_token %} + {{ form|crispy }} + {# Teal/Dark Green button consistent with "Save Changes" #} + +
+
+
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/templates/account/email/password_reset_key_message.html b/templates/account/email/password_reset_key_message.html new file mode 100644 index 0000000..74b722d --- /dev/null +++ b/templates/account/email/password_reset_key_message.html @@ -0,0 +1,39 @@ +{% load i18n %} +{% load static %} +{% autoescape off %} + +
+ +
+

{% trans "Password Reset Request" %}

+
+ +
+

{% trans "Hello," %}

+ +

{% trans "You are receiving this email because you or someone else has requested a password reset for your account at" %} {{ current_site.name }}.

+ +

+ + {% trans "Click Here to Reset Your Password" %} + +

+ +

{% trans "This link is only valid for a limited time." %}

+ +

{% trans "If you did not request a password reset, please ignore this email. Your password will remain unchanged." %}

+ +

+ {% trans "Thank you," %}
+ {% trans "KAAUH ATS Team" %} +

+
+ +
+ {% trans "If the button above does not work, copy and paste the following link into your browser:" %}
+ {{ password_reset_url }} +
+
+ +{% endautoescape %} \ No newline at end of file diff --git a/templates/account/email_confirm.html b/templates/account/email_confirm.html new file mode 100644 index 0000000..3b802d6 --- /dev/null +++ b/templates/account/email_confirm.html @@ -0,0 +1,71 @@ +{% extends "base.html" %} +{% load i18n %} +{% load account %} + +{% block title %}{% translate "Confirm Email Address" %}{% endblock %} + +{% block content %} +
+ +
+
+

{% translate "Account Verification" %}

+

{% translate "Verify your email to secure your account and unlock full features." %}

+
+
+ +
+
+
+
+ + {% with emailaddress.email as email %} + + {% if confirmation %} + + {# ------------------- CONFIRMATION REQUEST (GET) ------------------- #} + {% user_display confirmation.email_address.user as user_display %} + + +

{% translate "Confirm Your Email Address" %}

+ +

+ {% blocktrans with email as email %}Please confirm that **{{ email }}** is an email address for user **{{ user_display }}**.{% endblocktrans %} +

+ + {# Confirmation Form #} +
+ {% csrf_token %} + + {# Teal/Dark Green button consistent with the UI theme #} + +
+ + {% else %} + + {# ------------------- CONFIRMATION FAILED (Error) ------------------- #} + +

{% translate "Invalid Link" %}

+ +

+ {% translate "The email confirmation link has expired or is invalid." %} +

+

+ {% translate "Please request a new verification email from your account settings page." %} +

+ + + {% translate "Go to Settings" %} + + + {% endif %} + + {% endwith %} +
+
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/templates/account/logout.html b/templates/account/logout.html new file mode 100644 index 0000000..4af2a35 --- /dev/null +++ b/templates/account/logout.html @@ -0,0 +1,80 @@ +{% extends "base.html" %} +{% load i18n %} +{% load account %} + +{% block title %}{% translate "Sign Out" %}{% endblock %} + +{% block content %} +
+ +
+
+

{% translate "Account Settings" %}

+

{% translate "Manage your personal details and security." %}

+
+
+ +
+ + {# ------------------- LEFT COLUMN: ACCOUNT MENU (New Card Style) ------------------- #} +
+
+
+
+ {# Assuming a main 'Profile' or 'Personal Information' page exists #} + + {% translate "Personal Information" %} + + + {% translate "Email Addresses" %} + + + {% translate "Change Password" %} + + + {# Highlight the current page (Sign Out) as active #} + + {% translate "Sign Out" %} + +
+
+
+
+ + {# ------------------- RIGHT COLUMN: LOGOUT CONFIRMATION ------------------- #} +
+
+
+ + +

{% translate "Confirm Sign Out" %}

+ +

{% translate "Are you sure you want to sign out of your account?" %}

+ +
+ {% csrf_token %} + + {% if redirect_field_value %} + + {% endif %} + +
+ {# Sign Out button in danger color #} + + + {# Cancel/Go Back button with outline #} + + {% translate "Cancel" %} + +
+
+
+
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/templates/account/password_change.html b/templates/account/password_change.html index b05d6df..2e5a12f 100644 --- a/templates/account/password_change.html +++ b/templates/account/password_change.html @@ -7,7 +7,7 @@ {% endblock %} {% block content %} -
+
diff --git a/templates/account/password_reset_from_key.html b/templates/account/password_reset_from_key.html index 2a208a9..a873279 100644 --- a/templates/account/password_reset_from_key.html +++ b/templates/account/password_reset_from_key.html @@ -7,120 +7,39 @@ {% trans "Set New Password" %} - KAAUH ATS + {% get_current_language as LANGUAGE_CODE %} @@ -153,14 +72,17 @@
{% if form %} +

+ {% trans 'Please enter your new password below.' %} +

- {% trans 'Please enter your new password below. You can then log in.' %} + {% trans 'You can then log in.' %}

-
+ {% csrf_token %} - {# Display any general form errors #} + {# Non-Field Errors (General errors like tokens or passwords not matching) #} {% if form.non_field_errors %}
- + +