From 0d6aa5ad02cdf3b42be526ae392e3c6ff6495964 Mon Sep 17 00:00:00 2001 From: Gokuldevx Date: Mon, 25 Aug 2025 12:26:58 +0530 Subject: [PATCH] major update --- .../core/__pycache__/forms.cpython-313.pyc | Bin 2960 -> 3510 bytes .../core/__pycache__/models.cpython-313.pyc | Bin 5002 -> 7171 bytes .../core/__pycache__/urls.cpython-313.pyc | Bin 996 -> 1587 bytes .../core/__pycache__/views.cpython-313.pyc | Bin 8068 -> 12508 bytes civicfix/core/migrations/0003_comment.py | 29 ++ .../0004_department_alter_comment_user.py | 32 ++ .../core/migrations/0005_department_users.py | 19 ++ .../__pycache__/0003_comment.cpython-313.pyc | Bin 0 -> 1858 bytes ...artment_alter_comment_user.cpython-313.pyc | Bin 0 -> 1616 bytes .../0005_department_users.cpython-313.pyc | Bin 0 -> 910 bytes civicfix/core/models.py | 18 + civicfix/core/templates/core/base.html | 322 +++++++++--------- .../templates/core/department_detail.html | 45 +++ .../templates/core/manage_departments.html | 48 +++ .../templates/core/superadmin_dashboard.html | 35 ++ civicfix/core/urls.py | 3 + civicfix/core/views.py | 73 +++- 17 files changed, 445 insertions(+), 179 deletions(-) create mode 100644 civicfix/core/migrations/0003_comment.py create mode 100644 civicfix/core/migrations/0004_department_alter_comment_user.py create mode 100644 civicfix/core/migrations/0005_department_users.py create mode 100644 civicfix/core/migrations/__pycache__/0003_comment.cpython-313.pyc create mode 100644 civicfix/core/migrations/__pycache__/0004_department_alter_comment_user.cpython-313.pyc create mode 100644 civicfix/core/migrations/__pycache__/0005_department_users.cpython-313.pyc create mode 100644 civicfix/core/templates/core/department_detail.html create mode 100644 civicfix/core/templates/core/manage_departments.html create mode 100644 civicfix/core/templates/core/superadmin_dashboard.html diff --git a/civicfix/core/__pycache__/forms.cpython-313.pyc b/civicfix/core/__pycache__/forms.cpython-313.pyc index f9aea4a9ac6021ae37c3bdc50fee8e5ecff4535a..c1b4e14f6656d344fd38a37b42cfd3b941979f1e 100644 GIT binary patch delta 1341 zcmZuwO=}ZD7~a{glgpjPJux(^EMd+c5 z2Pp{BI0sLPc#&L05Cp+LAbPO3vQj^exhbu9b)MN;q-J3s=6&9G-j8Qy7GrM`4Xcre zDeGL|(EvZ#%mojQx%4m~HkAg5sqK07gx~#$3;3OGosys|I znj+BTRA`-2LpQ^zNabZRrg(ud*QTC&&UI&PPwy{HPunwP_Dp@s?vXT!uyO4aljXN0 z&fdvKttMVM$p6(ahx^iUw0S}Gww!yQ(cS2&gDqKt? z;n@M$320+K11%R&%M11wb97+Jb_z5GR|lXI&<=NGy-ePAoNTsA=poL!ghSddhl8Ld zyQ~gqqNd57sLx|yYsfcBF+6SHFhCo*KOq&SX{-LJ#OJh@Vpy#OuUcD>Lo zCzrR2C8uE1D)H1@xlG-ZLN6frB47|8rb>nX6COStU;%cq@4-|YLW>QXXFtRCnCA=r zW%(O3T-E9(6=K!P)Q6n_TpriIioa!DHP<8#e#t%-HU^WS^$R^vqSG~qm*@Y+r>(D6 z2iYyHC7hAF3Dq+4q&^a5pAGBIK|+HWotig|RM3n5ld5aTF6U}E15eMFX3G4@)MReW zMNbzBR?f=%�@bi(cY19Rc|Ih3bxKAix6b0w{p7JHT;3JrRUDliZ6oTquF}7+X-6 zn-YtO1?^k7WpVcL{G<6-mp`4ISn9mC6ubUIk++%;bYCHnKr}_Kpa_=#9M=TYr4yWl zZW}7AP?>`t3HNX+%$CjcxR?R2#0w6U3bq5y#VLs-o6>v6iRn^d*0E300^fqy=isgP3d08Zj3;9(Px|e@T2PI`{(~A`A!s delta 933 zcmZvZ&ubGw6vt)I3?y*21%4ln}xq(i<7-je=KSqvA{Sc<-~W>JJS&*84i0 z4Ef3(?lNCp;(Wt(da1PdsqTnfTBdRFTDv0VL%TF5_CptFN|eGmt%#W>L^ASGq?M$W zMsq}*R*Hq-2)1vuc+F{bTU+kqzTzv~^&YTkv9641<0vnQH_Fzwd?*KYpRV>zHj0rG zh?9sh1UBXyH`?` znM|*vR2MsH#gH|iebD&J3>rT&fK?Vloe8M01dO75Erl^z=P?Xn?NydPJTm#1%pfa5 zwG>aHVlcK(+f!)Uh%*4L04&RT78ED@I18=<3eF)0gJS2=oJGt7{_hE#SUOuk;57&K zU|}Ly!ivqje-)jhcWwB5*4gBK?1@)*+-ApXxXh-$TJLrlx5I218YOJof@k6$4#939Jbao<>e6pZ6gQ?<3BkIFd?d+93PMBo^C9Pont4MkMrHvt4G zFw={nygCz diff --git a/civicfix/core/__pycache__/models.cpython-313.pyc b/civicfix/core/__pycache__/models.cpython-313.pyc index 64d04bc7e5264457914cde2ef62f7a60bf2f30f2..df7f7df79d0a388e0c5202077c17ee92386e227a 100644 GIT binary patch delta 2976 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 OmY<)gk-JD1=qvzO;nbG^ delta 281 zcmdnY^MqaFGcPX}0}y=LusoxJiGkrUhyw$>P{!v7#)%qJ#aV)cU@{0gNOZClqck^9 zFqB+u~`W*TkMf~Zanqrd! zm~r&)-oyi1)|p#4KFGh?%=t|;`%|5lb@-Py9ne| E03-P_DgXcg diff --git a/civicfix/core/__pycache__/views.cpython-313.pyc b/civicfix/core/__pycache__/views.cpython-313.pyc index 5c2470b75c5cf15f5d35a54c913c20a253b887d1..5e3d968b2265b2ebc480c625d0ab040910223a5b 100644 GIT binary patch delta 5456 zcmaJ_eQZjY{Fmm4~<3mF}KwP*3!2 zOo$2bqlTc77-?NQS{F1C6Rqn;g`k<3gBD_;ZT+Y5Ji%tt9P|=z&_{f9To}!^1Y1dKu#L0@+etfgnmr8Z znAC+V9;Ux6Dd~i^wWjTdwymbUEo6sTT_Fe1?UTAmcgVRhT3w|ZW_d&P9_B1t?F(c> zZkW^q0}VJp0-;7|?|?=09n9p8epZzs)byAIcW&YGJceu67Ov(RE_3CKz0m%3adKDtt=Gh=hGQ6BF#^|LQdgKY66smgn(?a1J1FYPly*H(PUCR zzCe9A_>e{g6g-q_I+#nq;OT(rC(CS&PYv27|E zJGZk~rGnJ9S?2YDn~B#%f-u|-AJ)}W@k zKQ+IE6U$(R8mvDrSu^R`2n{?$guY9%v*{B!!` zK&WvrDjQ-!G1C}BA~7NYz*N-f;$l*Sh5!sCA@_Ox$0@L%!#1w3@MwKSuTF}S8SG<4 zNe^EtZw2#p6eTL+2@EdF*S%j)$50oQf@j3`!!ZEDFPI6SYMJ0FwJ;lE2e_0b%pr2I zM8V=UoTz15!W?ow%Z8W~AC@2J>V**Zz?uny+tO}=bHr6;6SMfO8% z9>2*F1UkjZ2ssK>MNr*3E@q;MBpAku;|?TlB*&3>kW{gyA|7>LHW37P2=5g60lkW# zEN-J1)e(pp)Kug=&Oy+Exzzh%tC>vEcsx=bC9eVR4fsh}APdYFg73O`gUbs$7LMK< z82Z%Qa{a=Mflti+AM*<%pXn_>z5M#+x7`JO>sr?8dHXx>4!$#3uy!x- zkhYiWFT;^qi)3KgQ*fPG%6f!=m6}f`FS=uCBJQp=T<=U~HVKiMdW4~(+<>;moR?rR zdYfg{2+FILqIjUjLg|_fHf|lR17;RUSPZf(uJkd#kMcy2WD(vD7^x-~qDDV1^_85pHs0$E^6HD0!Q?ESIdj1~P)!{3^%{k?5B zhVr)Ei`s0->R!IIbg5`<&0AYnbp`8o@Ign@wVf+Fi;j-GqhocT;MldOzo)m{+kfQe z4cA&%T8nmn-tNC)%;EQmk4`P>)(qBV>you-XvrH|R>QX%?sz}&esm#+?Ux_pnbl~G zN5%$qO%H?M%KDj`>^P>Zko8IPb0WdS0a6##r-aPq%*aLuqw!hDreiZ=>>POm2LFa! zxGX5ZWG$M!d6PHCdsR?Z_l0pDe&ua9MT9H^KF;=+qXM9S8^72>y|`w-cvPC1N=Hdt z^=4M}Qk7{apxLQ|3=d;#cjNol@glm;stj;WiH-3Nvm$1X8 zw1l*kt^CYH)tNv|x{yB1_OUgg&@is>spzao9Y-<6MJYxSbNGmXkhch{ktHCCV>X(K zPK%Lv^~oV!^in0yX19z`9phS+=ZO@kBY117DJf0yY1)4r`-YLwOl1LU2!%~i^k>*n zmE@5q`X<9<83L5a!B2Vz2(^#XS9JLE4u8?nop*E>96d$H-n?V)t&xJ`;KFF_efC&~ za{I0&SCU0{SKi&V`lEuof6;W$WL*>7MWH1xv=oJHd12d)eL4KjJhSF(&UyO^&OJF{ z&lhTZ9w-^=ul{gd!wu>lGMu1aXE?3?|J-s6z<1Lv_wARQOI~mrbdV-(#?YM#hPDQ3 zYfYf8L6xs3r3>?bBwC_)Iq0e_$fh0*%d8XAqjo;5-3Y#6T?J`~tpPrzFJH$0)w{f5 zePs~9*;L+#2^qrNNe`kw3rQRR6s`!h06>jlF02XFZMv;Zf?XF5p!UcD63jmo4dh!Yo~N!{+3&9dX)SDN)MWHP(v=xMog`=C$?(|$6Tp27nJM+%Y z>}s&!+`VWh*&411D?-uMmbbO7HWX}uMQy2;vCQ|S$@y!;nzKP&p)2p~DmAs2+|6rE zU8}Dan)*sjzI7wx+P=@x>S z?zWQM{XnZZ2u`Cxr_q$1hWr@L8rUsg^?jcsdihIVYZkSmG{?_IQ`6~QyyQt@sy7P% zhUuMwSPynnZD1>N#HV^^)9~Pt2qyHzgtJZMv6)O}j=qAF3b!-^Px#n;Mt$+CHpHYr z@s_8YmtShB&)Tp{S6&zI2K9d!6bqQ2sChmDN70^v{|QOz0~cLEP5k?@HiYB^l1U`^ zW~GllLa>H;x|%G$fi=8}XuJa)gc;^0LxYO?uLr{*h%%oP50iI+3-3;;8|b=*W!bw- z=Y3}HeP;A7bKox1f1lZPm+{|cp2{;%(dIKn=9&A+ue}=fCH9*-15{ls>svR#$iG>8&e2g|J0EZ?dkC5R>I@#5k8%jCzLo=; S>)y?4xZSlZ4|r(OWBw2P8NL(% delta 1778 zcmZ`(O>7%Q6y90eYsbHdli0EA{5EN_ZsUYDsS+s)32jWfZV8fu5Fx_a*h6CKc+BMrm z=+wK!9j1>mH(Ikcs`V1^tBoq~iq72lV#C?wb*EZ3ovKyOTd*aT)sd{~YQXCi4sHM^ z;^eY}v%{^-($mYum0uW^*S+GlI;85V_*ESiuZ0qOk9j^+SxnsZWmt#!$5*%zqGJER|u>)ugv>x}wIq{Zu$~S?&@ZM+Im+Bx5 zkrVRUw!q;4X>>q_AVH86x7t?Os0al!(_wPN2!;rT2~H3kCuk=aA?PBIgf%!R)`Hn% z)JHf=Fpgkr2u(_m6Ym9+zBzP^h);r_vdO(0p>eh2G|eS$u9v!$*Tu(?F*YZDisW}k zDKl`R2w-$4!^Wz)SePG*v}!4zFBcQ`UTRx9{c(zU3L44uEMBTi}$2x8J$5E zKh3t{aZz0A=^ODGc2;~I&*uK`XCO{l5BuCkW=!;T_U+P+Hv4|qa@X_Z(u(WZ;Lc&+ zX{l(#=1|(P9A2^;>sR42Wy)Eu0Hb|f{Vty0D3#pP6zO$eTv+Fd}09%=IMQ}B?78!p$l zS?85f#dJ(4QqW7_Blr(LsVYg*cSIS@)o8k;ONmm)EtQlTcFeK1O7en$7clyY7)^hJ zD)}q@6^qHeCUNCgbPp_v?=smZWJhQ*J$&S7Np7S7H-dXwvY=E3ZelB_gsW9}jiW*L zFszI7y~7uzcrTJo^<6LRIo<&>sRAbX7`Le(lJ5gu2co2Zp*^8ZIBWqNxGp{Y}0YJC85LF_9mW~a>HpJFbIpEb3?lk z%F$X?SSLGm7!-zrlF%Cz`?q8j?$+szi4 Gtobiji-xWM diff --git a/civicfix/core/migrations/0003_comment.py b/civicfix/core/migrations/0003_comment.py new file mode 100644 index 0000000..bae5ef4 --- /dev/null +++ b/civicfix/core/migrations/0003_comment.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.5 on 2025-08-22 00:55 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_vote'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('issue', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='core.issue')), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='replies', to='core.comment')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['created_at'], + }, + ), + ] diff --git a/civicfix/core/migrations/0004_department_alter_comment_user.py b/civicfix/core/migrations/0004_department_alter_comment_user.py new file mode 100644 index 0000000..1d8bf39 --- /dev/null +++ b/civicfix/core/migrations/0004_department_alter_comment_user.py @@ -0,0 +1,32 @@ +# Generated by Django 5.2.5 on 2025-08-25 06:21 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_comment'), + ] + + operations = [ + migrations.CreateModel( + name='Department', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, unique=True)), + ('description', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.AlterField( + model_name='comment', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/civicfix/core/migrations/0005_department_users.py b/civicfix/core/migrations/0005_department_users.py new file mode 100644 index 0000000..e0c4aac --- /dev/null +++ b/civicfix/core/migrations/0005_department_users.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.5 on 2025-08-25 06:43 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_department_alter_comment_user'), + ] + + operations = [ + migrations.AddField( + model_name='department', + name='users', + field=models.ManyToManyField(blank=True, related_name='departments', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/civicfix/core/migrations/__pycache__/0003_comment.cpython-313.pyc b/civicfix/core/migrations/__pycache__/0003_comment.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b8916c448606830fcf3de1781b91dce0bf5c3ff GIT binary patch literal 1858 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 - - - - - Civixfix - {% block title %}Community Issue Reporting Platform{% endblock %} - - - - - - - - - - - {% block extra_css %}{% endblock %} - - - - - - -
{% block content %}{% endblock %}
- - -
-
-
-
-
Civixfix
-

- Empowering communities through transparent issue reporting and - resolution. -

-
-
-
Quick Links
- -
-
-
Contact
-
    -
  • - gokuldevse2001@gmail.com -
  • -
  • +91 8129329073
  • -
-
-
-
-
- © {% now "Y" %} Civixfix. All rights reserved. -
+
+
+ © {% now "Y" %} Civixfix. All rights reserved.
-
+ + + + + + + + {% block extra_js %}{% endblock %} + - - - - - {% block extra_js %}{% endblock %} - \ No newline at end of file diff --git a/civicfix/core/templates/core/department_detail.html b/civicfix/core/templates/core/department_detail.html new file mode 100644 index 0000000..22fe796 --- /dev/null +++ b/civicfix/core/templates/core/department_detail.html @@ -0,0 +1,45 @@ +{% extends "core/base.html" %} +{% block content %} +
+
+
+

{{ department.name }} Department

+ ⬅ Back +
+
+ +
Department Users
+ {% if users %} +
    + {% for user in users %} +
  • + {{ user.username }} — {{ user.email }} +
  • + {% endfor %} +
+ {% else %} +

No users registered in this department yet.

+ {% endif %} + +
+
Register New User for {{ department.name }}
+
+ {% csrf_token %} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+{% endblock %} diff --git a/civicfix/core/templates/core/manage_departments.html b/civicfix/core/templates/core/manage_departments.html new file mode 100644 index 0000000..9a38529 --- /dev/null +++ b/civicfix/core/templates/core/manage_departments.html @@ -0,0 +1,48 @@ + +{% extends "core/base.html" %} + +{% block content %} +
+
+
+

Manage Departments

+ Back to Dashboard +
+
+ + {% if departments %} + + {% else %} +

No departments added yet.

+ {% endif %} + + +
+ {% csrf_token %} +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+{% endblock %} diff --git a/civicfix/core/templates/core/superadmin_dashboard.html b/civicfix/core/templates/core/superadmin_dashboard.html new file mode 100644 index 0000000..ef052f1 --- /dev/null +++ b/civicfix/core/templates/core/superadmin_dashboard.html @@ -0,0 +1,35 @@ + +{% extends "core/base.html" %} + +{% block content %} +
+
+
+

Super Admin Dashboard

+
+
+

Welcome, {{ request.user.username }} 👑

+ + +
+
+
+{% endblock %} diff --git a/civicfix/core/urls.py b/civicfix/core/urls.py index 00abffb..af20d7b 100644 --- a/civicfix/core/urls.py +++ b/civicfix/core/urls.py @@ -4,6 +4,9 @@ from . import views urlpatterns = [ path('', views.home, name='home'), + path("superadmin/", views.superadmin_dashboard, name="superadmin_dashboard"), + path("superadmin/departments/", views.manage_departments, name="manage_departments"), + path("superadmin/departments//", views.department_detail, name="department_detail"), path('register/', views.register, name='register'), path('login/', views.custom_login, name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), diff --git a/civicfix/core/views.py b/civicfix/core/views.py index aaa7714..f505441 100644 --- a/civicfix/core/views.py +++ b/civicfix/core/views.py @@ -1,12 +1,13 @@ from django.contrib import messages from django.contrib.auth import authenticate, login -from django.contrib.auth.decorators import login_required +from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.hashers import make_password from django.db.models import Exists, OuterRef from django.http import JsonResponse from django.shortcuts import render, redirect, get_object_or_404 from django.views.decorators.http import require_POST -from .models import Issue, IssueCategory, User, Vote, Comment +from .models import Issue, IssueCategory, User, Vote, Comment, Department from .forms import CitizenRegistrationForm, IssueForm, CommentForm def home(request): @@ -165,11 +166,9 @@ def vote_issue(request, issue_id): return JsonResponse({'success': False, 'error': str(e)}) @login_required -def add_comment(request, issue_id, parent_id=None): - issue = get_object_or_404(Issue, id=issue_id) - parent = None - if parent_id: - parent = get_object_or_404(Comment, id=parent_id) +def add_comment(request, pk, parent_id=None): + issue = get_object_or_404(Issue, pk=pk) + parent = get_object_or_404(Comment, pk=parent_id) if parent_id else None if request.method == "POST": form = CommentForm(request.POST) @@ -179,11 +178,7 @@ def add_comment(request, issue_id, parent_id=None): comment.user = request.user comment.parent = parent comment.save() - return redirect("issue_detail", issue_id=issue.id) - else: - form = CommentForm() - - return render(request, "comments/add_comment.html", {"form": form, "issue": issue}) + return redirect("issue_detail", pk=pk) def issue_detail(request, pk): issue = get_object_or_404(Issue, pk=pk) @@ -198,4 +193,56 @@ def add_comment(request, pk, parent_id=None): if content: parent = Comment.objects.get(pk=parent_id) if parent_id else None Comment.objects.create(issue=issue, user=request.user, content=content, parent=parent) - return redirect("issue_detail", pk=pk) \ No newline at end of file + return redirect("issue_detail", pk=pk) + +def superadmin_check(user): + return user.is_superuser + + +@login_required +@user_passes_test(superadmin_check) +def superadmin_dashboard(request): + return render(request, "core/superadmin_dashboard.html") + + +@login_required +@user_passes_test(superadmin_check) +def manage_departments(request): + departments = Department.objects.all().order_by("name") + + if request.method == "POST": + name = request.POST.get("name") + description = request.POST.get("description") + if name: + Department.objects.create(name=name, description=description) + return redirect("manage_departments") + + return render(request, "core/manage_departments.html", { + "departments": departments + }) + +@login_required +@user_passes_test(superadmin_check) +def department_detail(request, pk): + department = get_object_or_404(Department, pk=pk) + users = department.users.all() + + if request.method == "POST": + username = request.POST.get("username") + email = request.POST.get("email") + password = request.POST.get("password") + + if username and password: + user = User.objects.create( + username=username, + email=email, + password=make_password(password), # hash the password + is_staff=True # mark as staff + ) + department.users.add(user) + return redirect("department_detail", pk=department.id) + + return render(request, "core/department_detail.html", { + "department": department, + "users": users, + }) \ No newline at end of file