From a26ef551ee9ccc1475e8bd164c1e4934c8a062d6 Mon Sep 17 00:00:00 2001 From: sofordar Date: Mon, 24 Feb 2025 12:33:09 +0600 Subject: [PATCH] sighn_up_in_out --- misdghs/__pycache__/settings.cpython-311.pyc | Bin 2888 -> 3389 bytes misdghs/__pycache__/urls.cpython-311.pyc | Bin 1198 -> 1392 bytes misdghs/settings.py | 18 ++ misdghs/urls.py | 2 + resulation/__pycache__/forms.cpython-311.pyc | Bin 0 -> 883 bytes resulation/__pycache__/models.cpython-311.pyc | Bin 2154 -> 2972 bytes resulation/__pycache__/urls.cpython-311.pyc | Bin 1878 -> 2440 bytes resulation/__pycache__/views.cpython-311.pyc | Bin 10194 -> 18711 bytes resulation/forms.py | 8 + resulation/migrations/0010_verification.py | 39 ++++ .../0010_verification.cpython-311.pyc | Bin 0 -> 1540 bytes resulation/models.py | 11 +- resulation/urls.py | 7 + resulation/views.py | 152 +++++++++++- templates/base.html | 8 +- templates/registration/signin.html | 29 +++ templates/registration/signup.html | 220 ++++++++++++++++++ .../registration/verification_email.html | 14 ++ templates/resulation/home.html | 4 +- 19 files changed, 504 insertions(+), 8 deletions(-) create mode 100644 resulation/__pycache__/forms.cpython-311.pyc create mode 100644 resulation/forms.py create mode 100644 resulation/migrations/0010_verification.py create mode 100644 resulation/migrations/__pycache__/0010_verification.cpython-311.pyc create mode 100644 templates/registration/signin.html create mode 100644 templates/registration/signup.html create mode 100644 templates/registration/verification_email.html diff --git a/misdghs/__pycache__/settings.cpython-311.pyc b/misdghs/__pycache__/settings.cpython-311.pyc index 27bd9e5ea5bc89b3159eafa77eea24c181538ac9..bd32c1bf7a7e9adf08984efc26104432ea0e410e 100644 GIT binary patch delta 843 zcmZuvOHUI~6rS71&}o_JlTu0xr7f0<)`gh3@Kvx$4Jf2jVsfKt3TGImPASf`D&5ey z(WRst7Ay=4UASyq5%(@kqzQ{=690e;Q~!adtso@c$2sTw?m73nC%Iq!UxLC%p0_hN zz8!s*z3x3BKwj@9!cib#Q7vUFwGzg}NG6H>Kp5r|?!kCJv`1sRwo_O-izo+HY6q4& zUY%l_ToTCS< zLZ}AAg$Rty( zEV)ZuNn#9Z(hEt`rGi?l@3h{SewYc{l-OIW8*i#-o4?ta)_3+c*)^2dP|sxI^?xu3RPDJzR6yukevJ)w-mGtCv zQ?P~Hj=!2UP1Q9EzM_@1-5?tVmtM_h3#+*$(cm)=(+`#k^XY}f%%l5;eE_q|V*WH< zSUUnBp)^Bg7e{8eU?`od2rUF`KEP0h5Keosn0ivP-; zu{a-Hn}2lvkJy6FRTyl;gq3ORWD3<4u`Ah@T!X_NT+}jx0Z*#_igH4Isb|DK0_|B%&#fW>TOx1X|e4=A2zqOAF8O6JKL_wKYbJE6XF|^b2%s!yv)0sLGxq1DD V%bViF-7jz5DY5!7QrJ?NvcLv_lxA^HoFK*n7H0>NtSKB5yJV30oD;ibIhmt)Qdoi+G`TizSj-fn z$#jd;CqF$iFDx^){1z9GnO|B0Vpp*xrsQVk=~uB7CFkl_@fW2Qm*ymvWaj7Tl@{d` zS4pH~CFZ5)>m}#sl@w(r=_QtyWPoKfc_)`JJE=%wlP?1rTwKHkbZZeikeIxcIfF|W z$Y2EG;*FElS-d1}Fj!x}h9(!X=xW_y;b?H_5St)ALHvTG@kK$CD}p8$Sxm36n0{bq O;b&^#2EighplJX_vtFS9 delta 175 zcmeyswT@GLIWI340}$-`vpGGAnStRkhyw%cP{!w$iR!u{Obn?kDXghXSukOSERKl_ zq}kbk609lg6KBbAr87lwrmzGvXmV_Pv6xA*iY+lEH#1MailrzySHFtCD7CmWC$S_m zKTof;D5qGHYw~?&r^#+C>0AOpn;3z(xPJ0>7O%;YthxdpSef~m8n{8Qhz}?Q0R06h AHUIzs diff --git a/misdghs/settings.py b/misdghs/settings.py index a35aa1e..2144ead 100644 --- a/misdghs/settings.py +++ b/misdghs/settings.py @@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/5.1/ref/settings/ from pathlib import Path import os +from django.urls import reverse_lazy # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -141,3 +142,20 @@ MEDIA_ROOT = BASE_DIR / 'media' # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + + +AUTH_URLS = { + 'login': reverse_lazy('login'), + 'logout': reverse_lazy('logout'), + 'password_reset': reverse_lazy('password_reset'), + # ... other auth URLs +} + +#email Setup + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'smtp.gmail.com' # Or your SMTP host +EMAIL_PORT = 587 +EMAIL_USE_TLS = True +EMAIL_HOST_USER = 'dpmehealth@gmail.com' +EMAIL_HOST_PASSWORD = 'qxyt faeu uioy jbjs' \ No newline at end of file diff --git a/misdghs/urls.py b/misdghs/urls.py index d9d916a..cadcbe8 100644 --- a/misdghs/urls.py +++ b/misdghs/urls.py @@ -17,7 +17,9 @@ Including another URLconf from django.contrib import admin from django.urls import path, include import resulation +from django.contrib.auth.views import LoginView, LogoutView urlpatterns = [ path('admin/', admin.site.urls), path('rcm/', include('resulation.urls')), + path('rcm/', include('django.contrib.auth.urls')), ] diff --git a/resulation/__pycache__/forms.cpython-311.pyc b/resulation/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1e5f315f586e03d5cc70ef7abd1b229fbd0b756 GIT binary patch literal 883 zcmZuvJ#W-N5Z(3KzT=dGTu2cjke~rhNG>T*1VvD&xF$+tS+dOS#xe58v1=D}6cqUf z;THrUYHI$1OKV#yx{EH=Rm`mKh^*XxynQpXe!DZ?@5AAMKs)*UD_+3*2aR=eR%CGm z(YYLV7AR?oWW_f z9vmleUd>Rqqqp9<*zf2G=G&ZdE4F;6RaoA;QSjc2GSdADE|*7{(2mHWB%O?1-48?b zgrOdUVOH=eMZOh=pQ)6-c3~)Kn`lHS}hmwT(BEcR~aTo$X$TR*p^#p3=!_G-ExG??7EMvw+75Y9RS?u&n?S&HYc~?3Vqib0GJo8MR65oK{-xN1RRi?u2O}n>W_7B>B@>=eJ28F3+ n0CPquZOC5T9SwO|cSl2B)ZH<+8HJp0Lp^$Oh3@MOF_ZQ`-zC-{ literal 0 HcmV?d00001 diff --git a/resulation/__pycache__/models.cpython-311.pyc b/resulation/__pycache__/models.cpython-311.pyc index 6a0f5f10700c1a84b9919a0f8854633cc30d72af..1354397c0f0c71dc83a32acc652d7636bda4d01b 100644 GIT binary patch delta 1106 zcmZuvOH30%7@pZzOJ9q~qc#u=A>c;S00HzsAXr2%)C20FA*tK$P+GRTX1XOxOxgo6 zBp#HM#DgzRD1n0py?OOsk{+79dDK%4o;>-_7Md#lJM-=2`@etof9#L;S3QAue!mBS zUH$Soos+f#LAg`+GB>Mf7)OL*__ z89$59buy-d>4gPiskFQNO}G?v*gjxmN|5$2Nsz&Xa=$p(6JTn$Nz;jfk+E#iG9P48 zR4y-x<*xHg#sXZMcl<9@Vig_8h5~#W!zPCy3ANjI1qO+#K3M?+^b0&DDG?Y&Gy|RG_#yZsaD1` zAfq;9VM7Rtvh7YF-2mmIxcgaTwqQdW^F01}nnOHia)?zOOl$ z5*J&Shx6gJ)-Q6lP=FrTZia@MBeWfY^DH>*%!9I4u6MSk8A&Aa7EL6En6ew7glZk# z+e)=#up&>uDzcY*!fAU<@wZM6)Rd)c`)?cMjtMZIA-YB*jB`b27o)RtH|RK%g&D=K zl1H}hx@qb}H5{q!ZWKT?C$-iAv#1e(qJ#Z#$}aQPG3nmn+%R+R_dLrtSc@@Q2aE#0aMSe&e*v(Wg- z*ym$K#bvi?S=C6J5iQxMS6nb*u9W?FcId>HG7XDnk`c9FtweInpLZJJr2kK0zui-y zDClIGPQx8+K>4=-bsl3}L%o%jRledLxj&9@Un>dc8oFHhd({OALp5jN`Q-N0PsacH IkJBmj59HYYbpQYW delta 276 zcmbOu{z`yvIWI340}$-`vpHRebt0bxqs2sZ3s#n322IwDi{>#IXfod7%1x|@&q>Wo zFUinkF5&>HzQvl9lbDx%izTl#C+DRRP(+idh!aQ^aZN5@j$zc?e3sdfQBVjZA^=j) z;+tBMSR^u8o>fBvEGi8Y_0yCn5(Oy{0}5RFo1apelWJF_ Z2jnsWak1~@uUzhY4C0J>A3y}yJOFPnK3V_( diff --git a/resulation/__pycache__/urls.cpython-311.pyc b/resulation/__pycache__/urls.cpython-311.pyc index 303e6928f6bf15bd15f87b897b35957a92c31dd9..50bf90be5a9290aef59bf091def7302328fd42df 100644 GIT binary patch delta 1073 zcmb7?%WD%+6vppNZjv_1q0HaKHPz-#z!7VZJzzy{R`8 zWkWFD5g%&R>rnRwOl0^ff&Tt_uMT{$em>qJxM~%LefP$pi5jga%RvvSN^BATNQe8e|2?CnC~cGsxP& zd1gZB96}qDGW_g9lhR4kuPY`n*B$(aJ2cn5PNF{RY6kSAXCTh?4PwG`FGXga2}3j{>_1u0g|uQx_0D9z3hx+cw=;{}nl z{OphL!r_hMRf$fV+>+_UkWR^T>g_WLXNNc|UH?2XCZD;GWq=Y}{Zfx7!@bJz*Q}asVi}LeJG-W1Rum&>nPwrw>XXKf@iB)OxKi1I6rEE3aIzR_7 n0&(#h#>s!!<}!U?n|zf0E$0VeE`Fv4?hg`^wK$_#w15f#Tvt^C diff --git a/resulation/__pycache__/views.cpython-311.pyc b/resulation/__pycache__/views.cpython-311.pyc index d1f3530d8f8a8d4af872a901863290adab5100ac..27b38af7c5cd5575e31819b61ac22cda5e8ab719 100644 GIT binary patch literal 18711 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 delta 1801 zcma)+O;B4^6vyu+UqA>Yk0ODlZLDpQCk-J;v9uCE2tq9r6h>`9G2}fUOp-^>OQ?1O z3w7zJcNn+s95$^AIS%5(065Nt<%GxwMKaqhY2p#;G&uO`_B#(gXYWVfzR>sLMtOXwhU5>60;gp&kJ zg~4e;NbE*J+%LY1jKnRM4q$+)Snh&eS}`lcVwq#oFrCh$GgH>;Uro+PG zn=;<*Iy=7SXg>)X3fbP9U&`q>K{w0!3?&0oxORn%=(J7tyAl+u-9zp+9AzEiql?FP z?sf;bau&x{BknWuWw|dR{)l(Q5;zULgr^A2(rPL-HaW8JVmdtwUYhMgs7_EsswWzj zDf%#GeL*vB7V}0%gO|}@8k<=}Y_eZHUa{4)%G*9m+;zA~G6;yT`+7G*)D08P5S}1J z2JV8D69x%M!U#cScmzC)UDJm+ zQa!e`jwz!Iuj1NkWE4Zysc2&T!;Xy<&cHb0R(nm_>sSia)TvTbw;lK-nNwB3^8}fo z%;PE!kCc;#$_ahI>$vg`t)>yOj`ozZKPX-Im99@x;?IF$-nJ9Jq&qupJ<-U%$Tk0g zxSb6ChsO1`#_|cM*-73O30Xpj@F>XxHMwUEyyTf|=}>o=$9)mC3RjIIwlAAKi}ymeA&1Z07pDc$J}LhnHr-R!}UCp1Dj) z!35zUIhsh0gP>srZN9)}QUTd_`>WAGdAHS*!a0_7%Sw)miLt^J`6$abN4^R2Qp#$Q z(#p`J!)*riILOfds(+?nXyv?~gc~?V@4Wc}7pKO*+^D!Y@2#*Z+yi{D!m3#34nD^# stcFbuJdHCo42F4sg;g=loqQH8YS?m~U#_q!=F#gl>9xcDIZ7G$-&!<=asU7T diff --git a/resulation/forms.py b/resulation/forms.py new file mode 100644 index 0000000..9218616 --- /dev/null +++ b/resulation/forms.py @@ -0,0 +1,8 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.models import User + +class SignupForm(UserCreationForm): + class Meta: + model = User + fields = ['username', 'email'] \ No newline at end of file diff --git a/resulation/migrations/0010_verification.py b/resulation/migrations/0010_verification.py new file mode 100644 index 0000000..16b7a61 --- /dev/null +++ b/resulation/migrations/0010_verification.py @@ -0,0 +1,39 @@ +# Generated by Django 5.1.5 on 2025-02-20 03:07 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("resulation", "0009_alter_resulation_attendance_file_and_more"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Verification", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("key", models.CharField(max_length=50)), + ("verified", models.BooleanField(default=False)), + ( + "user", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/resulation/migrations/__pycache__/0010_verification.cpython-311.pyc b/resulation/migrations/__pycache__/0010_verification.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a91792642c65472b2bbed939347bc67b07dd1634 GIT binary patch literal 1540 zcmZuxy>Ht_6hD$8MauGr6gib^xK7-(me5pC(!u>g9a*;91aVT-AA=y^K z)z+Onbm*9^89Ekj3v1|9bnCw$0~~~#0(43z8upZ_??_WgkUa7p-+TAFckjJ>$KNI= zGYH83<*&{^DTMyzN<#9baQ-C-KO=&OV4{WqU(pmTsUZp6CYdQqZpfC>Py{5R&k;%e zh=@$(ZaQ&vEFp9PBc?{02-~QvJmu9sD` zMW2aF<@~0=W1>+!4Uq^UqEZ(!hzWLA68RXACop2_h>diFRTB#li3Ap{8&!f^NeUjB zD1-Ddcsv<)L{B$TSsW*$qdvx$F!}aw!F|T_4;O1X;!ILs~=(A^r?%Vo3ZZu z)F!&!qPT6C6zev@mg7>E-J`D2Hd^s&(I7jUOuV~ZPO+@s_Z{4FsqRz4CVH-6>Fy!^ znjSLEgGIV&`~d5}rS87tQEclLWfIIjy$u;aD`YJFdu&p>;~y{;P_PRnU{4d;*88T< zQhjg(;cJeKp*g5endm!UNJYLBz?;N-P`<)c9J$AsWiW(I`j7!;S&YBw>m~l^o3c8oBn$0q7gqFcO8U4C0w zcFpM2pah#d45rl&bT<~WYmQ@5-Hx@%hc?}DfW@jpy1LzQm`L`S8f69j&(ihUcD=T~ z!7@&dUfzj6&^c^_p6%5?Ztg-Qyog`xwVLZrt8Y=;_nMy5c3h&nP0R2|=fG<|KT%p>he#SKwbV_4N7-T)mos|LRl&( zNB6@l(iZvLTcg|}fM@4Mh2=+^L1B6HPI+{rG+N?9sL8We&k(Q+&O%wu<-Hyg4eAxO;G1 z`n4P^-42#M36|=k`L~1l4UOBqQANOXG zd|734@sU)>ekJ}3Rg!aY-vt<(xSVe}c02ABZM-6CtEeC1dcMc~M$X>{>6!Xz+>M{P zw?O4TCeH^JN`fFj*@WvubS-{IiSUA@G(@j?LuFA=Li8$olnG{Tobic^*UUyy{SPx` Bop%5L literal 0 HcmV?d00001 diff --git a/resulation/models.py b/resulation/models.py index 1811880..fa507f2 100644 --- a/resulation/models.py +++ b/resulation/models.py @@ -27,4 +27,13 @@ class resulation(models.Model): verbose_name_plural = "PDF Documents" - \ No newline at end of file +from django.db import models +from django.contrib.auth.models import User + +class Verification(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + key = models.CharField(max_length=50) + verified = models.BooleanField(default=False) + + def __str__(self): + return f"{self.user.username}'s verification" \ No newline at end of file diff --git a/resulation/urls.py b/resulation/urls.py index fca90b2..920c8c0 100644 --- a/resulation/urls.py +++ b/resulation/urls.py @@ -6,6 +6,9 @@ from django.conf.urls.static import static from django.urls import path, re_path from . import views from django.views.static import serve +from .views import SignupView +from django.contrib.auth.views import LoginView, LogoutView + urlpatterns = [ path('', resulation.views.Home, name='home'), @@ -17,6 +20,10 @@ urlpatterns = [ path('viewmou/', resulation.views.Viewmou, name='viewmou'), path('/', resulation.views.file_download, name='file-download'), path('rcm/', resulation.views.file_download, name='download_file'), + path('signup/', SignupView.as_view(), name='signup'), + path('verify//', resulation.views.Verify, name='verify'), + path('login/', resulation.views.signin, name='login'), + path('logout/', resulation.views.signout, name='logout'), ] if settings.DEBUG: diff --git a/resulation/views.py b/resulation/views.py index 968daec..289ffb9 100644 --- a/resulation/views.py +++ b/resulation/views.py @@ -7,11 +7,151 @@ from django.http import FileResponse, StreamingHttpResponse from urllib.parse import unquote from misdghs import settings from django.core.files.storage import default_storage +from django.shortcuts import render, redirect +from django.urls import reverse_lazy, reverse +from django.contrib.auth.views import LoginView +from django.contrib.auth.models import User +from django.contrib.messages.views import SuccessMessageMixin +from django.views.generic.edit import CreateView +from .models import Verification +from .forms import SignupForm +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.decorators import login_required +from django.contrib import messages + + +class SignupView(SuccessMessageMixin, CreateView): + form_class = SignupForm + template_name = 'registration/signup.html' + success_url = reverse_lazy('login') + success_message = "Registration successful! Please verify your email." + + def form_valid(self, form): + print("=== Checking form validity in SignupView ===") + + # Check if the username already exists + existing_username = User.objects.filter(username=form.cleaned_data['username']) + if existing_username.exists(): + print(f"Username '{form.cleaned_data['username']}' already exists.") + form.add_error('username', 'Username already taken.') + return super().form_invalid(form) + + # Check if the email already exists + existing_email = User.objects.filter(email=form.cleaned_data['email']) + if existing_email.exists(): + print(f"Email '{form.cleaned_data['email']}' already registered.") + form.add_error('email', 'Email already registered.') + return super().form_invalid(form) + + # Form is valid, proceed to create user + print("Form validation passed. Proceeding to create user...") + response = super().form_valid(form) + print(f"User created successfully. User object: {self.object}") + + # Verify that self.object exists and has the correct fields + if self.object: + print(f"New user details - Username: {self.object.username}, Email: {self.object.email}") + print("Proceeding to send verification email.") + self.send_verification_email() + else: + print("Error: User object is not created after form submission.") + + return response + + def send_verification_email(self): + print("\n=== Entering send_verification_email method ===") + try: + # Create a new Verification instance + verification = Verification.objects.create(user=self.object) + print(f"Verification object created with key: {verification.key}") + + # Generate the verification key (you can improve this by using a more secure method) + import uuid + key = str(uuid.uuid4()) + print(f"Generated verification key: {key}") + + # Prepare email content + subject = 'Verify your email' + body = ( + f'Please verify your account by clicking this link: ' + f'{self.request.build_absolute_uri(reverse("verify", kwargs={"key": key}))}' + ) + html_body = ( + f'' + 'Verify Email' + ) + + # Send email using Django's send_mail function + print(f"Attempting to send verification email to: {self.object.email}") + from django.core.mail import send_mail + send_mail( + subject, + body, + 'dpmehealth@gmail.com', + [self.object.email], + fail_silently=False + ) + print("Verification email sent successfully.") + + except Exception as e: + print(f"Error sending verification email: {str(e)}") + raise # Re-raise the exception to see it in logs or handle appropriately + + def generate_key(self): + import uuid + return str(uuid.uuid4()) + +def Verify(request, key): + try: + print(f"\n=== Verification view called with key: {key} ===") + verification = Verification.objects.get(key=key) + if not verification.verified: + print(f"Verification found and unverified. Proceeding to verify.") + verification.verified = True + verification.save() + user = verification.user + print(f"User associated with this verification: {user.username}") + user.is_active = True + user.save() + messages.success(request, 'Email verified successfully!') + return redirect('login') + else: + print("Verification link already used.") + messages.error(request, 'Already verified.') + except Verification.DoesNotExist: + print(f"Invalid verification key: {key}") + messages.error(request, 'Invalid verification link.') + return redirect('home') + + +def signin(request): + if request.method == "POST": + username = request.POST.get("username") + password = request.POST.get("password") + user = authenticate(request, username=username, password=password) + if user is not None: + login(request, user) + messages.success(request, "You have successfully logged in!") + return redirect("home") + messages.error(request, "Invalid username or password.") + else: + return render(request, "registration/signin.html") + +@login_required +def signout(request): + logout(request) + messages.info(request, "You have successfully logged out.") + return redirect("home") + + + # Create your views here. def Home(request): return render(request,'resulation/home.html') + +@login_required def Savepdf(request): if request.method == 'POST': try: @@ -71,12 +211,13 @@ def Savepdf(request): # Render the form template return render(request, 'resulation/resulation.html') +@login_required def Viewresulation(request): # Get all records from database pdf_records = resulation.objects.filter(pdftype='Meeting Minutes').order_by('-m_date') # Latest first return render(request, 'resulation/viewresulation.html', {'pdf_records': pdf_records}) - +@login_required def file_download(request, type, filename): # Construct the full path to the file if type== 'attendance': @@ -89,8 +230,7 @@ def file_download(request, type, filename): return FileResponse(open(file_path, 'rb'), content_type='application/pdf') - - +@login_required def Mou(request): if request.method == 'POST': try: @@ -131,6 +271,8 @@ def Mou(request): # Render the form template return render(request, 'resulation/mou.html') + +@login_required def Viewmou(request): # Get all records from database pdf_records = resulation.objects.filter(pdftype='MoU').order_by('-m_date') # Latest first @@ -138,7 +280,7 @@ def Viewmou(request): return render(request, 'resulation/viewmou.html', {'pdf_records': pdf_records}) - +@login_required def Contract(request): if request.method == 'POST': try: @@ -185,6 +327,8 @@ def Contract(request): # Render the form template return render(request, 'resulation/contract.html') + +@login_required def Viewcontract(request): # Get all records from database pdf_records = resulation.objects.filter(pdftype='Contract').order_by('-m_date') # Latest first diff --git a/templates/base.html b/templates/base.html index dfc48f4..de3a98a 100644 --- a/templates/base.html +++ b/templates/base.html @@ -19,9 +19,13 @@ diff --git a/templates/registration/signin.html b/templates/registration/signin.html new file mode 100644 index 0000000..383c69b --- /dev/null +++ b/templates/registration/signin.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} +
+

Login

+ {% if messages %} +
    + {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + +
+ +
+ + +
+
+ + +
+ {% csrf_token %} + +
+

Don't have an account? Register here

+
+{% endblock %} \ No newline at end of file diff --git a/templates/registration/signup.html b/templates/registration/signup.html new file mode 100644 index 0000000..131d809 --- /dev/null +++ b/templates/registration/signup.html @@ -0,0 +1,220 @@ +{% extends "base.html" %} +{% block content %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }}
+ {% endfor %} + +{% endif %} +
+

Sign Up

+
+ + + + + + + + + + + + + + + + + + {% csrf_token %} + + + + + + + +
Userneme:
Email:
Password:
Confirm Password:
Already have an account? Login here
+
+
+{% endblock content %} \ No newline at end of file diff --git a/templates/registration/verification_email.html b/templates/registration/verification_email.html new file mode 100644 index 0000000..b3e9814 --- /dev/null +++ b/templates/registration/verification_email.html @@ -0,0 +1,14 @@ + + + + + Email Verification + + +

Please verify your email

+

Click this link to verify your account:

+ Verify Now +
+

If you didn't request this, you can safely ignore this email.

+ + \ No newline at end of file diff --git a/templates/resulation/home.html b/templates/resulation/home.html index 26c2f9d..9aeae8b 100644 --- a/templates/resulation/home.html +++ b/templates/resulation/home.html @@ -1,7 +1,8 @@ {% extends "base.html" %} {% block content %} {% if message %} -
+
{{ message }}
{% endif %} @@ -86,6 +87,7 @@ list li::before { } +

Archiving and Timely Upload of Meeting Minutes, Deeds, and MoUs


To ensure seamless access and efficient management of critical documents within the Directorate General of Health Services (DGHS), it is essential to archive and upload Meeting Minutes, Deeds, and Memorandums of Understanding (MOUs) in a timely manner.