From 08e8aa82d45cdca3fd63687101f7054140ec8db3 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 25 Jan 2026 16:46:17 +0000 Subject: [PATCH] adding testimonial --- core/__pycache__/admin.cpython-311.pyc | Bin 8372 -> 8864 bytes core/__pycache__/models.cpython-311.pyc | Bin 17498 -> 19991 bytes core/__pycache__/views.cpython-311.pyc | Bin 22715 -> 22875 bytes core/admin.py | 9 ++++- core/migrations/0015_testimonial.py | 34 ++++++++++++++++++ .../0015_testimonial.cpython-311.pyc | Bin 0 -> 2032 bytes core/models.py | 34 +++++++++++++++++- core/templates/core/index.html | 32 +++++++++++++++++ core/views.py | 9 +++-- 9 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 core/migrations/0015_testimonial.py create mode 100644 core/migrations/__pycache__/0015_testimonial.cpython-311.pyc diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 3418d8bde9f6dea3e36282559f27eafabcb540f5..b93269356986b47662b9dd37ee8ba503785ecd3e 100644 GIT binary patch delta 2089 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 delta 312 zcmbO}hw)YiBj0jfUM>b8IBipw`CD}&p9JHDjq2wa*-|)z88oFgD=}?QWYpYzS=pS4 zan@vRwdbtMfQqM1&gGJr%&(ruIBRpAIzJ=hlF5A<`HYJ;|I>)$6fG}($I zLF|Q-^UTD6vaM!@OpKQ&Z?|Y*Ts_&sGLZWuNcJ>{I5&BUrJ?kG5c2?#C}so_4nzEi*Nx z=s8GO7evT{2(WQ?L9DxzwH@BFftZ@oliR!wFwU9m?ybiLw(9QW25(ueFF-kvBZ}=d QFZVWMn!MYWn-y#d0Jd^lYXATM diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index e80985306caa48f94115db82e1e940148b5b000e..cb8f7bd4be5f3e3f5f727ce579d74753f639fb00 100644 GIT binary patch delta 4359 zcmbVPYitzP72dIT*EU`ozwz5%8{4dnv5oCDHZOzY2Q&eKA+%FqS?>(?keS`>omoFp zr<(^AZ60dqRVyXxi$sN3(5hk6G-^vx6tz*SswEK$XxgUvlSoZfiG)_FQdQ~s?)ZgG zAL35f<+zUB5Yh3hOJ2I)&?>L)VD)pajGLuG$Tq3y?uac>+ zGfL%Bqf9O{%H?vSLardbOUcqJjVifX&})dUk!u8+b8p7R5E#ZLTC%i|g zBOFxf35R%XT5;gN(9Do(MD#AL02 zO$4Tgpq7t#x31|SssgN^@u$7B14T903mb0~w!T%^`l|a{Ve6ZP+piaHf8^fxvh$y5 zx>m9AWTZ^J;0PBseI4Hy6%BCtI|jp-%2R{U5H>`bPPYbIi*&~j61 zILGiv_wyeX_yb@Fdxe&O#KK_o6AaC{m#M#pe^S7cW7vdYPKbqFZY*)TqXvGlY(NK~ z0MJEXd-X6f$_|5rV6X=O695=&XPAjdL^Vye87wEeOt=aM?TmyOP+3S*gjIHW%!)hd zg`>hxb`S>v_oucOHM;W=9a1}?#p5a?-%M_mPD@k#FQp?5u+GjISFKQtg(6HP;~d3q z7SmOh165sIF00-qOgJu7IdTfKu={zyEWyfnvs2gsOs8Hh%akNFb*21lnwNoX@iK+uhWHV66av>rD_b@1t-YQj*Q7g3Yz8C)%;147=O|qtQ5W^ply;MknWVw z6d2R|5B{Fy|LPAOs}uMcP(p+7ryfhV67YzEu(O1wXRr^u?KM$#Dr8z=D`A>=QPoSC$VtQ% zs?Pac_B8EY=GPl8%)9Wl#^LmJi#b>bzbJueemkH^+xW5OebjX>HCODuTN$lzu^Q$S zj3qQ(35CbZn4X}!6HH@Ow86qWtEIy$vQoqQTY5$RV`q4>r9|4uzuvO1GKlkeT2!+% zSRD_~po-YHiT&E;jTfkR_?7aq)N8GEX_eoEN(3R0=2VSiHn@}gleU?KEVO|mI?LUR zEy62~OsJ6uV+ku{QVY>yQ8tY;!q7TU!t=!}*cnq{7S*ET48aa~opdak5%uGCt~~*v#pKUP;xOqVPD(eo7y0a#V}*0l zd{Aw7G;FAI6k&d*yIBhI%iW#QKl%IJ!G4vF56wxKP$$(uCR>VgIqk4KfOx&=;4BHK zBv^>oMSe6`+58G|mg3UyjGSELWIRT5FN(I$u8`2*`SZc277Z5IL=yi}2$HWwF#PS&6&e!2gcQM!zZc-{{AT&{_&}%lGEX-H$FQEaD z%g^q3-?5ON-Fc)Jy_pU}*coM_S+9(WZ~h}FG^wdm?AIjh=l=c;G-USnzvq^EdHdiN zukbL$ql1B(Yf$$lz+r-V3vdx|mA^9B(7z4jcEAn-J9ps)RL6ETGi zLv#eN2e6k{4EepE0(pS%9@^lH=PD8_9Ha)g0r)TBhsfL9 zzkj`SoDc2akPZFpL4eL@_E#qFoS@5G7cEAF(txxGr3l-K3q@o_v_*)PWnNqj5Z{z5 zN?HW0)kTlw?%$Uzj+5fqL;1=NiM7o$(E9Ji$txlFoUp98=(UTS z1k+71gYBI8nHox18u6;3Y~dU!JIQLm$y-#<)J+BrizKThzEgmxJv(=5B5axAczj-w zAKP_+dcb-BD$sW0I1}AM6kiW^6u?1%`1p7n6h5!S2Z|W?VlIlYCg#*0F$CD_kU{5T zZvaH|z@rzH$lfJtj(Q;&sMe1&w;3@dp{qOCN3^77=`x?-ZHH(3^lPsF^H1uJhc`%T T^CkLE+#)olN{*b9+_?8&a&PXv delta 4236 zcmb7Hdu&tJ8TU;bJLKWSB;@HN&O1(mAt8hW0;Es^bOpi~uwDwr_}(O!-fKJOUI#+6 znN}&A)UIlEwzbpNN$WIF%G7rC#wHNcrmdP*X$*CJpxbTzYnrC18lH?& zTxnFvRYtX3ZPds$#CIvH^jaez*9p3S=z6(c(1m(~5tM_1F47x~Cb>z_#d@>RBDWCj zQG9x<(I&SEeu>_0bjTfoF4aRur`#!Mzn<=ryJ#c7-Ys|2qSg9ZBP@rFb@Do6y}aJ& zk$a3@xmPGG(>EA>a-XqL-bmx}S(n_etRdW_R1glRg-YeD>mqr08E%S?JV@NC72M6l zt#-Klf>e^OSs^h*616M1TZtQ3!QDpOx)t2*N|| zu%G|Y{gtj_5d;AWJ)zHF~vHG$+`$kHvxacv!!4I z5w+mF$V;xD?1S50q zCEE=1=gN3Gf=L)Ig6r5V41^Vqnzf(`0SE(IO<;S*G@Y!lJvv2%a&!NxrK3td!!9SMO;Rc`6=Ptw@4JoOC&g-7KN240X#+^FLSD4~f7Z6RI3Jg)z)d z1I`gF4?P>l3?P-+TazzIr+9d%I`c^F*&I(2QfgqG4Q8Rq39g9iB!)qN4hR93#uN^*G(gl89h$IfSv>7hgw9aoR%HHw zJw^*I(ATVx__pQ{-_>xNyz{qLXAT5!N>Y*soB9L7F%zmSf>5qgRw*#1IBVLJ{$HI# zdYw$10VOmD=bA8tUm>SL>{U*SKy@rShDNa5rQ&ETR;nhgh_isfnHTs#^Np+X4?Fiu zVSZm%ZOgrCWtr)9{CroHCjc`}@UM6EctmLH`P*HCb)x2Bp(L`3*8t$ptIfZFqWg{rz<3ez4@0lozYw>X>%Grjwu(NY5JkOu(sVjl)>+|%>$0Z(t}BP|!U?BpM9Xl(r^ zO)L?#eNkppgUwP7zdG2T79O!HShB($KXLz)JJ&J)0|L5rsTj%X ztKi(zzXJG|mHIJB{e!;d<1U`q{6sc&16ykPzJ>KG@|R@VR5UgnNhWkHHqCxQLU~jO z>=LAr_el3W7naiHXPA*#BCe2miMYvLrxp3!KZMkWhu)VOMVEO6dhi5bdkH9XOBg)7 z?J4JaC=z!*tALzXb`Vr6KnDElnQ(6E#aBe`;wyrxht8|%q$FF+KZ6E9AvtFLhKTd7 zTVCJnXP>Wl)5{09|0;V*+J=t~9-~<@66>8S3XBy|E6O&F$dsm@VQ-K~J-;&CL5{ya z{5!X_k-xrcz$2V~nCFg!8g4+zF98k{)J?z~;5z@rNbB$b$U(qn0^2vgMJh?JER}5q zvw&U)5ks{m5(?W1(fa|r03-a>kw(vMkPq^AM>?Fi);V#l1RHU+^G5bQxa-go*F>Oy zfqBt^M6|_4A>Kuw!o*>~5x`Nvrva-0;xs-4N;J2JLA3xVT{~RtI7rcD+CVMlD}OOx zqN?pxIP%VG5|1Ls=#%_MyBn&|j_e|pifo}%|C(4$nU8i`Ig~j6V0q^J19#m!McIhe z@6h}RQ=n)J@HXJTqyQps@hb;fq+|TO1099fgG~T5?i&rHM?s1$gsY40i)JM5%ts(1 z!YM+xY(o)UQA{FCOR|q;Zvj-mvPu_0>vHX*nRS>(VP;?-ASG(MgPrz}l3!xoFi zO}aJlg0F(0NG*D^?aK;MH?Wv?N;qK`W|TwJo16%;$VInSj=N^3;!;64x0Q6STAw{nfEkzuDCaMLYoui%!Ayn(m s8@o+oYCbM=mjC?lOkd=t>;L}Cq>pq+B|eFM!Yx2BbLHqaBsaGFC!@;8761SM diff --git a/core/admin.py b/core/admin.py index 29a95fc..2ba60ea 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User -from .models import Profile, Parcel, Country, Governate, City, PlatformProfile +from .models import Profile, Parcel, Country, Governate, City, PlatformProfile, Testimonial from django.utils.translation import gettext_lazy as _ from django.urls import path, reverse from django.shortcuts import render @@ -124,6 +124,12 @@ class PlatformProfileAdmin(admin.ModelAdmin): fieldsets += ((_('Tools'), {'fields': ('test_connection_link',)}),) return fieldsets +class TestimonialAdmin(admin.ModelAdmin): + list_display = ('name_en', 'role_en', 'is_active', 'created_at') + list_filter = ('is_active', 'created_at') + search_fields = ('name_en', 'name_ar', 'content_en', 'content_ar') + list_editable = ('is_active',) + admin.site.unregister(User) admin.site.register(User, CustomUserAdmin) admin.site.register(Parcel, ParcelAdmin) @@ -131,3 +137,4 @@ admin.site.register(Country) admin.site.register(Governate) admin.site.register(City) admin.site.register(PlatformProfile, PlatformProfileAdmin) +admin.site.register(Testimonial, TestimonialAdmin) \ No newline at end of file diff --git a/core/migrations/0015_testimonial.py b/core/migrations/0015_testimonial.py new file mode 100644 index 0000000..5fe46cf --- /dev/null +++ b/core/migrations/0015_testimonial.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.7 on 2026-01-25 16:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0014_alter_otpverification_purpose'), + ] + + operations = [ + migrations.CreateModel( + name='Testimonial', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name_en', models.CharField(max_length=100, verbose_name='Name (English)')), + ('name_ar', models.CharField(max_length=100, verbose_name='Name (Arabic)')), + ('role_en', models.CharField(max_length=100, verbose_name='Role (English)')), + ('role_ar', models.CharField(max_length=100, verbose_name='Role (Arabic)')), + ('content_en', models.TextField(verbose_name='Testimony (English)')), + ('content_ar', models.TextField(verbose_name='Testimony (Arabic)')), + ('image', models.ImageField(blank=True, null=True, upload_to='testimonials/', verbose_name='Image')), + ('is_active', models.BooleanField(default=True, verbose_name='Active')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Testimonial', + 'verbose_name_plural': 'Testimonials', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/core/migrations/__pycache__/0015_testimonial.cpython-311.pyc b/core/migrations/__pycache__/0015_testimonial.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a3b7fc0f72b6cf52c36bdac19e31d71dc68f577 GIT binary patch literal 2032 zcmb7EJ#5=X6eg+vKS%OUl&Z3rq;3*9sTCtlQxs_d+o_BMjf>iXTgU|twC*g^rbzZk zI<_Vc9oj8hJ#=-V@HoCfP-*TfiBIaAel1tjuib9c_}F#-|>C#y?gI_dcS2d zNr7E|F7Bx5s382qH^CJd2(KS9;THi4P}GE$SQlGTT@nRJSQMc2qX0ul+zJIohfI2L zva5$+ctt2jUUGF=qRE!p#EPvNx<#Wc10v081eW}r8*E z@K$gr78>#|(XCkE0EXEefzeLvFw73Y9{<{qVBAB-gD)@vlbzI|#8B)xL8XUKnF~-O zL#Rs^pt3`#+y$sn50wbc0LMDxhb;3K>^V8r#5V-|G~HD)GLD zOby&~WU(_jREd&@N}r-S^3b`i4q>jni)p49OV{BCO%YE08tQy_zBw4D8F+)W$4#1e z8uSHgl5oSoh+e;YclKkTXg0#Yu+1HW)eW`b^$su{Y#J7#sT#6uwPon4qEShOwJMb! zKPrc5T5)UxG%!+Z1Zm2|YD>X;U>ohxgvC55n%YJ*&77_?KR{Pnh{pH|kp2>~wA&*~ zY@zs#p~odCb4EqD0m;Mc<}j z-O)6fa7@imAg~SJcS5y*(y-MXM5A-wo249sXhU%{I|%RB6DW3B9F$l$o&g0ynsiLa zYwhdeUiq1hrh{X$l3VT6M*~VYEaZC~J4*sEH3u^;;|7L|CcRk>vGa0vq8lpGphaVb z>5Y%2@(7Isk2wHn5&$+$99DKf(*XS7D4NG6+d*U^9U{G4 z^t{@fV;xiFF=%38Q^5nVhIVaVOnPPX<@CJ4m{oLtmwCi8uc<9G02(G5%(&l$*UY`} zcA>Iqv{1!acXZpSpk35p!Eoi7fwwJFX`l-4_{!;Qtgzm{56;jyWA0%#o&|5=g7q^S z5&I{1KPn_1^h45kbpNYU_T%E68+ zSIFnfL|*C2E3UjkvbA3BjOH66FL&i-S6(LBm0s=&DcnA|;TCTHF?Ccs24owPg4Hcp zZo$u>NJ_H@8*XX#XzKVoQd;enR^8Gn$$slOy~o4d`)i!Y)vjE13gth&C|sNA-MrtMoId!v9}7>6^aZ}ipq3PJDy literal 0 HcmV?d00001 diff --git a/core/models.py b/core/models.py index 35f9189..fb8a8a6 100644 --- a/core/models.py +++ b/core/models.py @@ -208,4 +208,36 @@ class OTPVerification(models.Model): def is_valid(self): # OTP valid for 10 minutes - return self.created_at >= timezone.now() - timezone.timedelta(minutes=10) \ No newline at end of file + return self.created_at >= timezone.now() - timezone.timedelta(minutes=10) + +class Testimonial(models.Model): + name_en = models.CharField(_('Name (English)'), max_length=100) + name_ar = models.CharField(_('Name (Arabic)'), max_length=100) + role_en = models.CharField(_('Role (English)'), max_length=100) + role_ar = models.CharField(_('Role (Arabic)'), max_length=100) + content_en = models.TextField(_('Testimony (English)')) + content_ar = models.TextField(_('Testimony (Arabic)')) + image = models.ImageField(_('Image'), upload_to='testimonials/', blank=True, null=True) + is_active = models.BooleanField(_('Active'), default=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + @property + def name(self): + return self.name_ar if get_language() == 'ar' else self.name_en + + @property + def role(self): + return self.role_ar if get_language() == 'ar' else self.role_en + + @property + def content(self): + return self.content_ar if get_language() == 'ar' else self.content_en + + def __str__(self): + return self.name + + class Meta: + verbose_name = _('Testimonial') + verbose_name_plural = _('Testimonials') + ordering = ['-created_at'] diff --git a/core/templates/core/index.html b/core/templates/core/index.html index a82bcf4..cb52783 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -86,6 +86,38 @@ + +{% if testimonials %} +
+
+
+

{% trans "What Our Users Say" %}

+

{% trans "Real stories from our community" %}

+
+
+ {% for testimonial in testimonials %} +
+
+
+ {% if testimonial.image %} + {{ testimonial.name }} + {% else %} +
+ {{ testimonial.name|first|upper }} +
+ {% endif %} +
{{ testimonial.name }}
+

{{ testimonial.role }}

+

"{{ testimonial.content }}"

+
+
+
+ {% endfor %} +
+
+
+{% endif %} +
diff --git a/core/views.py b/core/views.py index cdb8c84..58d1cb2 100644 --- a/core/views.py +++ b/core/views.py @@ -3,7 +3,7 @@ from django.contrib.auth import login, authenticate, logout from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User -from .models import Parcel, Profile, Country, Governate, City, OTPVerification, PlatformProfile +from .models import Parcel, Profile, Country, Governate, City, OTPVerification, PlatformProfile, Testimonial from .forms import UserRegistrationForm, ParcelForm, ContactForm, UserProfileForm from django.utils.translation import gettext_lazy as _ from django.utils.translation import get_language @@ -34,10 +34,13 @@ def index(request): except Parcel.DoesNotExist: error = _("Parcel not found.") + testimonials = Testimonial.objects.filter(is_active=True) + return render(request, 'core/index.html', { 'parcel': parcel, 'error': error, - 'tracking_id': tracking_id + 'tracking_id': tracking_id, + 'testimonials': testimonials }) def register(request): @@ -391,4 +394,4 @@ def verify_otp_view(request): except OTPVerification.DoesNotExist: messages.error(request, _("Invalid code.")) - return render(request, 'core/verify_otp.html') + return render(request, 'core/verify_otp.html') \ No newline at end of file