From d1b88898128a3e99be569cb49fc4f1f106702f6f Mon Sep 17 00:00:00 2001 From: Gokuldevx Date: Tue, 26 Aug 2025 13:59:33 +0530 Subject: [PATCH] minor update --- .../core/__pycache__/models.cpython-313.pyc | Bin 7794 -> 8916 bytes .../core/__pycache__/urls.cpython-313.pyc | Bin 2014 -> 2402 bytes .../core/__pycache__/views.cpython-313.pyc | Bin 16972 -> 18879 bytes .../0002_user_banned_until_user_is_banned.py | 23 +++++++ ...anned_until_user_is_banned.cpython-313.pyc | Bin 0 -> 915 bytes civicfix/core/models.py | 20 ++++++ .../core/templates/core/manage_users.html | 60 ++++++++++++++++++ .../dashboard/superadmin_dashboard.html | 2 +- .../core/templates/issues/manage_issues.html | 35 ++++++---- civicfix/core/urls.py | 4 ++ civicfix/core/views.py | 34 ++++++++++ 11 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 civicfix/core/migrations/0002_user_banned_until_user_is_banned.py create mode 100644 civicfix/core/migrations/__pycache__/0002_user_banned_until_user_is_banned.cpython-313.pyc create mode 100644 civicfix/core/templates/core/manage_users.html diff --git a/civicfix/core/__pycache__/models.cpython-313.pyc b/civicfix/core/__pycache__/models.cpython-313.pyc index a6af577562f6a5c92069c82063fcf8c6b04ebabe..ca9962d3ab5a013334117cfb3c2c2e9a0ca25986 100644 GIT binary patch delta 3355 zcmai0U2q#$72cIr^6JkkS(Yuyjw{E;j!5h@2~O(7ICcCp#BrRAB{MM2R4CHg*;JOy z*;T+{7<-sbn)HV_+_peX8v+l+1BEFbpbr!nUU=XoE}eI(zq=bI(1$-|lC99}d?(2n4(mUXkKEm+BgB)kYm&`PRNK^rfVf>x??;0Z&50 zwfl^B)CazV6qWW$shYTyQZG1roU~Jtz%RHSuOeeWvIQNOti3fW08Zdlq(hLbwDuHn5v6Qmt_d0!f^@eQuRo~sR-21 zG$f;3nKX6SRGH~`P1cy|TOOTi`uIR-?K09wF z_T}~IY`I`1j)~`FcN(*zkZ3&V<{rb$T+9}WdLC4?%bms2H-LQPew&>s7cHZ}6*GH9 zPdf0f7p9>J6-@Fsk>H(!%uqTOxD)lcO1bF9RV!(H9?7EgkJz5;$}6=WHMid$dvk1g z{1;z+Z)mM+V6A!Jy7HkKTUY%zJvThB`W~RRl#_{WU37xT*R!~IGG8gm#g4WzDNVRU zGNcv9_(;+T&A10zh&+X4MTP|4OxlnD@{YU8MRM6ITo&t2(ugBjl-6S{||pz)s?sl$1%2cX-0+)+?7;zc}r!0 zJw${%yBrQl)>?&yh$!3BkV`cqjC-VoAZJkVoxiPDd95@ z3}r1njWaf4=!Lw!5yO>W9}zmAM=}}H%34M)leH``E|x9b%w$$1ahRwD5X1;V(VKr_ zx0P4Fcu%SSG$@4{?+4pH2)5lFUJD*xJiQ){-4Azu5bnI2ey@Hl+`l;XP*GgQ;7hge)n=?5qxbxEx<`LpPZ?NaSfEbTC&-kk`Q| z&cF%ck?P}+xk9GkOUNX1CLz)_X}vza^vuhut#%e!*lO(Enq#3+Tvs#%`*%&^)M?u3 zM}jrh!Z+t{%->U^_GaN&GE&VkAY6f?L`K%)HmHU9nime+mms~W9*U77#CUBK%XlC*)~kGteYziprC=Wo#t+v ziBlk$JJ>12TZOaB6=U!Fj~yah6$s0{SF!~opS4P0Zq_3g$6lOQle<(ha=HnW8#u*2 z7nm4dz~xn6*RCK%ir@^XRMrMW%zy&gv{RbarIS0QVQY7ND;RC*vinaWHIpFcN|9v*`0?5B0TXCL?3 z6|yivB!z@~M@pa@GsQFdJh+KFN!*&jfz;r@&@flG+6CB=v+t>*IS;$PO#heanF96lwKh65|L^xJVgQ`W2=7-KQG%oJjISgK90VDTzqqg zwxm?UG?FwnR9C~`!ZHaRBF)?-TG&Q|WOX#qY~;yUr5PRT2vvO%j^9SZWZb0uAtuE4 zzpPat0V?g7+b}D_RprL zgqWEdvUT%zprlyZ)8{ delta 2342 zcma)7|8G-O6o0R4U*GzD-&nT}*3D7(1g7HV1~gD`n^VJF*5XgZm#)2Z58A$Q-z#Cv zSWp8_T-b7n28ZFYp(MUlQ_U3E?M~U?7Y{6HWA-``Q6o5}WkXd(S!d z+;h+8oYS91?!^P^e!oY6&kqw{PR}+i1;UPd!cuR4Pgv*{lCE|kDIFFE>d-7N8gRAPNzOq=q zEwE4Ox3lZwx1nSM4dfb?Cd+xqAaqS)e>pCSezsJ%=oH44Ap6SwyeP5X+=mB)aM}u$ zz)GDVw4fP=rWXyXMO6(mZE6`cZJJb@Dw)JkRoV*H>v$jA<5EIYh7|`17RCbmMqcpz z=xnB2xt!hUXj}QXeuvn-8TM;gfRy5(KKQkyQc*izBCz$NZGheOJRvpX($8AFF)v>R z?ERT7yV+@PLwP42bQaSE!s8fUmS`9)+7Q|iB4{D&G)t&f%+Vf{VaRqsG1NK_5;INF z6@Cp&-dW*#bNk}ZdD%7_1W`r=sD5w_q_U7N*4z*4WzljPB!9#}MU=+ai@xZA0azRO zw9~@%VAF-!`Ppl7*mj5!j4Lg*f~A-^8b#=5%f3jr`laNJq51NvI`}lbT@~kdZy8D*zY{fG8HpFU^WrVy>29aPo4?tq9am`UExr zw>2NJ9o;k_o?>roitR@3zy{Uy1i-lRWUV@~g2~kW)S;w0IWqC;WNKuXme`F=yS6e8#ZT0fX8Nt2Drds#B?nGPH%(M5Ypgm<&Q_m4|n$Vi@@ZcA~F*-Ng05A~Rx1A6EcO0%1TgtQhaLu5Qmz?i4-Q1|S_t>wIon_vSyue|E)|g=SPW@$iQ|zH>hULp0v#-00%o2b~-2EN;7iu4?8o z_<|i{wShlmpLfQfoxbmkM|Qy}MYN=uG=*0@a-PMao#o4TX9K`#;U>)Ix%s&(J=cP< zYjW&=4r$H@uU*auXMxkhnZeGo+!?)S;_X*pM-vEDiux<%AkR=8{%6fu`YEbw^~VRO zKv-aZL@)VxwcvJK39v7^Hj8!ayRMEh?@Vv@Xu6ow`{3Rqyp65;iX=N_R}n^Nxen@C zlDGdB_zQSd@OzLgI|2OPQH~e%Y$;Fn(yO2l;cH9*+^rKuaaDM3RoJyEL|285`+jGO UD7_oMFTl_JKK6e1uoDCQ2Wn;g&j0`b diff --git a/civicfix/core/__pycache__/urls.cpython-313.pyc b/civicfix/core/__pycache__/urls.cpython-313.pyc index 864507a7ced6259d09c77aa4d7dbc5ef6e546054..b6bde5bd993e921320d56d0e9c4890bfbc44b6b0 100644 GIT binary patch delta 492 zcmcb||42yVGcPX}0}u%2ugx%GXJB{?;=q73l=0bwd85V(rurC0C5B*)80H`YmZk2daVjfsV-zGD!#0n%BpP6E(e~SYs z0ajBbS(=AS5f@krqD(2XxVSX67-9~X4K_$AB{e6tBsD%QF*{ZNmLL)@9<0buQ+9F| z>uSLwNuc|Sq(B5HV2flX3$b}}sRNmeKwP|gb1GXdW7tg=jt==5s@J7-E=uWau)E0O z1QfZzskFd#x!*#+9a0xrT)+Y<3sSGEnO#&f+Yxh-#S1K?yQ1{EzS~88w+p@r7g-WN P=!)|*HF6iJ0!;@1^#XoW delta 104 zcmaDPbdO)-GcPX}0}yQYT$}Ngm4V?ghyw%SP{!vqOdB;;FmdP$6-lIPXliawVD4vP q_S2M{Jb`WXWPf%yE@hxfMj$RO+&rH>myzd#sxUuOBX^M^Pz(UTI~IHZ diff --git a/civicfix/core/__pycache__/views.cpython-313.pyc b/civicfix/core/__pycache__/views.cpython-313.pyc index 0f287f7d3fffb47957d2a2d0aea960a6ef7585d9..a59bdfcd475d1705667ccd74fa90c1c9d52010a2 100644 GIT binary patch delta 1797 zcma)-e@t6d6vy9v@Ae1u$AeL}S+TqpHmGq7T7In1A!_C@l@G>8=uuU&~r6%xsw}1O)Lh3)XE2)9P!FE zvD4xH(%c_LuEcTu z%C#$Nq9-GImZF;I(M1267|e*lM*}NjDBZbXDV?j)p7%c(`?gkV>RPdcG#nz0kUz}! z*&bHT2%Z4Ht$B{xf)!@CrV!_Qd3wj`D3%2o2av?|8R@xT1@>?kc>2ugNZC2r;OCpR z3qjnrU5}HE`PWg+c}?M-dpuDfrbGJG1fCaVaWrySO;$*w5mg#el(;k$i32t1odl6u zBo?gGZ|pS@k>!?w$qFDM?4ViGR4PK^vG@oXU{O1mdqNK5ydKX(W@;%9)C~Fht014k z@-YUp6C53;D1C&N4n6A0*k4VbUdNW%uIaA1bLp-OKD2?YYuNE4cFeuG=5ENi8#KwM z)%(Jl>&z-XyJ0Dt3$IwJG+eb0?GD+6{bZ@;GUI|=g@56ScX2g@d&m+TK3TTIa5A2w zSOA?tkLmD82-0@Ak^3-J|KXH^S+-bL=TLnP3v6HYHE;@}>YnbNIa835@08|xeHEYn ze~=!+4pa;_;fS{exWiLgiYjZ6q zOXiHVA$@9HbX>oB?P|Jn9T&}prb9DffIJ(1KRnlRJGNwAs|{qt+JIKmsKH|-%?ge$`3aS32RtjN>KV_YZnPzEd^IyAo0!cvi}z|U(xZ6^OgF9nsj%-= U7|;>6gDqbK=D(NFKVJ#|4b*d&UjP6A delta 298 zcmdl#nej{uBj0CUUM>b8$Vgh7aZhg|p9G`JMs*QJN#$TsDTXXYQ;-}G6lnyDNih^@ z1}jevVLT)dEC=Km#IVJ%D=`GiOEFB&Vv^N0gz^=o7)%)<+JcpUYzPxh7a66CXsT@H zV2&`GEa#vz`J}xD>oTAkwaMS?Lm8J&_HmG7T?OQ8ZO(U?#K^i1$kd$7<}^cPDUemP z0!S2tOjjr}0`WmA!Gs}DuxRz>Lr#ks8P`otb6Lu|87O5iS-^EEqw(f#t{sfpAft*v tqAMASOh9aq3AZ?Ga`RJ4b5iY!4gk3zql-5(ZmxCDU}X9vGr7>y4*+#-Lreew diff --git a/civicfix/core/migrations/0002_user_banned_until_user_is_banned.py b/civicfix/core/migrations/0002_user_banned_until_user_is_banned.py new file mode 100644 index 0000000..3696ffd --- /dev/null +++ b/civicfix/core/migrations/0002_user_banned_until_user_is_banned.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.5 on 2025-08-26 08:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='banned_until', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='user', + name='is_banned', + field=models.BooleanField(default=False), + ), + ] diff --git a/civicfix/core/migrations/__pycache__/0002_user_banned_until_user_is_banned.cpython-313.pyc b/civicfix/core/migrations/__pycache__/0002_user_banned_until_user_is_banned.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d811db35fc344b9e4e6e17cb2fc89e6708438a1 GIT binary patch literal 915 zcmaJT3iRk=$N3Sr~yM}L`DdKCw>Cr9^bDFYD zSiLkRNfw=J0ITTp~L8V^TxPzwnRM+(z!hSlb(VT{fFp7+D z;kHA@NQ?`X(_~+!n(ZWHFNML1B=L3Wi}C`qut(&Yie`tBBo;Q!aHZYxp{T{A6BbGS z8SMG4sN+(Av2ZY!2NVgB*v0r&5hm&o$u42sp*+hI$_PuG}fRV#lSSUY^nmD6QVAj2|z07DDd zi$h(zY`uFjbbviGsL!3$=T5I)Kb>AU^=1d&>WQ~{y#Lkcd-uQB4BPoPYrf1{Iq_DG zN#EP7avD>f^?sM%nB2JM8^VqcLe@>!;&y3WX;}3pRdtoSAd#rws~WP+7bS&qX7e%( bbqL`v3qb#eH4Uwg&Y-#6Z!Z4?l9cM-sg~v@ literal 0 HcmV?d00001 diff --git a/civicfix/core/models.py b/civicfix/core/models.py index 318a41c..fe643a5 100644 --- a/civicfix/core/models.py +++ b/civicfix/core/models.py @@ -1,7 +1,9 @@ +from datetime import timedelta from django.contrib.auth.models import AbstractUser from django.core.validators import FileExtensionValidator from django.conf import settings from django.db import models +from django.utils import timezone class User(AbstractUser): is_citizen = models.BooleanField(default=False) @@ -25,6 +27,24 @@ class User(AbstractUser): related_name='core_user_permissions', related_query_name='core_user', ) + is_banned = models.BooleanField(default=False) + banned_until = models.DateTimeField(null=True, blank=True) + + def ban(self, days=1): + """Ban user for given days (default 7 days).""" + self.is_banned = True + self.banned_until = timezone.now() + timedelta(days=days) + self.save() + + def unban(self): + self.is_banned = False + self.banned_until = None + self.save() + + def is_currently_banned(self): + if self.is_banned and self.banned_until: + return timezone.now() < self.banned_until + return False class Department(models.Model): name = models.CharField(max_length=100, unique=True) diff --git a/civicfix/core/templates/core/manage_users.html b/civicfix/core/templates/core/manage_users.html new file mode 100644 index 0000000..80ad9e9 --- /dev/null +++ b/civicfix/core/templates/core/manage_users.html @@ -0,0 +1,60 @@ +{% extends "core/base.html" %} + +{% block content %} +
+
+
+

Manage Citizens

+
+
+ {% if citizens %} + + + + + + + + + + + + + + {% for citizen in citizens %} + + + + + + + + + + {% endfor %} + +
No.UsernameEmailPhone No.Date JoinedStatusAction
{{ forloop.counter }}{{ citizen.username }}{{ citizen.email }}{{ citizen.phone }}{{ citizen.date_joined|date:"M d, Y" }} + {% if citizen.is_currently_banned %} + Banned until {{ citizen.banned_until|date:"M d, Y" }} + {% else %} + Active + {% endif %} + + {% if citizen.is_currently_banned %} + + Unban + + {% else %} + + Ban + + {% endif %} +
+ + {% else %} +

No citizen users found.

+ {% endif %} +
+
+
+{% endblock %} diff --git a/civicfix/core/templates/dashboard/superadmin_dashboard.html b/civicfix/core/templates/dashboard/superadmin_dashboard.html index e80d7fa..f4edbb2 100644 --- a/civicfix/core/templates/dashboard/superadmin_dashboard.html +++ b/civicfix/core/templates/dashboard/superadmin_dashboard.html @@ -12,7 +12,7 @@
  • - Manage Users + Manage Users
  • diff --git a/civicfix/core/templates/issues/manage_issues.html b/civicfix/core/templates/issues/manage_issues.html index 6608880..a1b6a49 100644 --- a/civicfix/core/templates/issues/manage_issues.html +++ b/civicfix/core/templates/issues/manage_issues.html @@ -16,7 +16,7 @@ Reported By Status Created At - Assign Department + Actions @@ -41,22 +41,29 @@ {{ issue.created_at|date:"M d, Y H:i" }} {% if issue.department %} - {{ issue.department.name }} + {{ issue.department.name }} {% else %} -
    - {% csrf_token %} - - - -
    + +
    + {% csrf_token %} + + + +
    + + + + Report Fake + {% endif %} - {% endfor %} diff --git a/civicfix/core/urls.py b/civicfix/core/urls.py index 6f8d3dd..5cabe27 100644 --- a/civicfix/core/urls.py +++ b/civicfix/core/urls.py @@ -21,4 +21,8 @@ urlpatterns = [ path('vote//', views.vote_issue, name='vote_issue'), path("department/", views.department_dashboard, name="department_dashboard"), path("update-issue-status//", views.update_issue_status, name="update_issue_status"), + path('manage-users/', views.manage_users, name='manage_users'), + path('ban-user//', views.ban_user, name='ban_user'), + path('unban-user//', views.unban_user, name='unban_user'), + path('issues//delete_fake/', views.delete_fake_issue, name='delete_fake_issue'), ] \ No newline at end of file diff --git a/civicfix/core/views.py b/civicfix/core/views.py index ba4709c..eb10de2 100644 --- a/civicfix/core/views.py +++ b/civicfix/core/views.py @@ -291,6 +291,40 @@ def assign_department(request, issue_id): return redirect("manage_issues") +@login_required +@user_passes_test(superadmin_check) +def manage_users(request): + citizens = User.objects.filter(is_citizen=True).order_by('-date_joined') + return render(request, 'core/manage_users.html', {'citizens': citizens}) + + +@login_required +@user_passes_test(superadmin_check) +def ban_user(request, user_id): + citizen = get_object_or_404(User, id=user_id, is_citizen=True) + citizen.ban(days=7) # default ban 7 days + messages.warning(request, f"{citizen.username} has been banned for 7 days.") + return redirect('manage_users') + +@login_required +@user_passes_test(superadmin_check) +def unban_user(request, user_id): + citizen = get_object_or_404(User, id=user_id, is_citizen=True) + citizen.unban() + messages.success(request, f"{citizen.username} has been unbanned.") + return redirect('manage_users') + +# core/views.py +@login_required +@user_passes_test(superadmin_check) +def delete_fake_issue(request, issue_id): + issue = get_object_or_404(Issue, id=issue_id) + reporter = issue.reporter + issue.delete() + messages.error(request, f"Issue by {reporter.username} was reported fake and deleted.") + return redirect('manage_issues') + + def resolver_check(user): return user.is_resolver