From 192b5d74082d5cf296bb994f0f9081f4222752fe Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 25 Jan 2026 11:30:16 +0000 Subject: [PATCH] Autosave: 20260125-113016 --- core/__pycache__/forms.cpython-311.pyc | Bin 13217 -> 14567 bytes core/__pycache__/mail.cpython-311.pyc | Bin 0 -> 1603 bytes core/__pycache__/urls.cpython-311.pyc | Bin 2087 -> 2178 bytes core/__pycache__/views.cpython-311.pyc | Bin 12530 -> 13671 bytes core/forms.py | 6 + core/mail.py | 38 ++ core/templates/base.html | 18 +- core/templates/core/contact.html | 91 +++++ core/urls.py | 20 +- core/views.py | 24 +- locale/ar/LC_MESSAGES/django.mo | Bin 8613 -> 11813 bytes locale/ar/LC_MESSAGES/django.po | 467 ++++++++++++++++++------- media/platform_logos/masarxlogo2.jpg | Bin 0 -> 14236 bytes 13 files changed, 515 insertions(+), 149 deletions(-) create mode 100644 core/__pycache__/mail.cpython-311.pyc create mode 100644 core/mail.py create mode 100644 core/templates/core/contact.html create mode 100644 media/platform_logos/masarxlogo2.jpg diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index b0b499d930e578013955c04e56ddea396b3502ab..3a3aab8f54ee335c8a18d79136f5cec8658fdc45 100644 GIT binary patch delta 2814 zcmZ`*TTB#J7~Ywky|TM17XhQPphnjVO0Aa|D^g$u1-yWQv~fD_9AW9QyPTO7-CmX$ zV@=D0X8Os+CNqsO))9_$YGY@@je5$r4O-$4D|IRFkl+LiFx#4!XZqd(q2A9dM11`Pn zqDv1kY2^P{<$Ac+6^mT`F&7ff$@tHQlFRCrY74p~yO>9pZ%E{re$GQO_lS3Pq`L)2 zd7YzsuF1E(ugh-x79{8sp8T_(gdhJrn*wPBB``}V1q;k0k!sOk!5cCqO+V)u3<^)m z>{u@o;XCr~n%g`ATY)O!kXHxmV$xMz%p|~mAol*;%_-Eg9cUfacs$8cx-F@8ppTt1JJZ>mX)9@(gdG&I9lg_cv>t~1Y@bm|!4E@? zGtKsmI>}gfJUa_KLNNsRsAJev=@WDBld=_;cT6@lZSt$8T|Oc|hw!NU!f8l1C>;Z()U-*xpr9cNngS_9eGn3ojBujuNoeKe_Q#=> zQ%&^tPw%994JMdDzr?sOeLqgu6NyEeZT7a)iVQUX0nT|tys8L z3Qr!;kkiAG2w!UUoInUdA`l{|NQ4kU`za`1-Z;D83F^3tyQEukP?W4FUhBDglT>4^ zQffBvYA{jJagN)Oj)Q+J$M|`Js^8DqST4z#&TA}PdEntOVpy9z^^JT5_42`Zk{hNt zX8AyuR_gY|{5(o(UJqy>u&#P4H}JL8v%TVc8GH+LBFn81E8UFBb~kmatv@`fS7`QI zw;O7US#Og%XnHdnM#>+Tsr)qH5uOP z?L@c7`Z>JHi%|Ti^*r1l)fX!xn-yu$YALU;ISu&;;C%uE2QnIs@~u|ByhCcSekeaH zH5T_&_~ZgeG09eP2IDx)DQ1VV!pjEiLWLAW{$YKR}9##RjNEHNoFHA`2~ zc!ujd1rk0D{1_-zW<0l@TTJ?GL%N){^Qfud^)H#_F|&xt#2! z-5H&wT8A^q1QVB%s2wp8-V1Y)bQ$&N{-V`!@)w(eW#Rh)M*(R7(zC;=D(>k7OQlrx zrsT{7-{k$yB!W%g0>Z^#svk;Dku(*jYrjwud>P5}RsF-78KwI#dOnkj8Z50R(?iX4 z`PRX-0#FI40@=N-v59VTNNIyimd$&%HE!G1BqaGIy(VYO-1>GdnSvKyUi@ygUs@l9 z{aj^pe7N~r08y4=?KaWS`n_(&7QT*pw$J&N7`z#@*9+fSi3_9{DDI7p$fd$B-fmbQ zD7+1RE1(T<3GgW(4mbe#1aKM90q6pB13m*x62vM+2|BBdx>&eXeULe43ccfi6M#ZL z5Sz$91c>b$K<^}A5bzG*U4mG^Da!-|I)DMr0EPfKhPIbZshTVmDV9zY>8m-FmLtuV+bSu5#VD2V_wBfKnUo!E;WsW#HE5^ zPprcFyXkzJf`1~!XVDIbiWXy3n6O%~S1BdZ#rE+piGnyrRIm$Gx+q*jB)ZpFC@} zPqoj3XSjA)EtQGKL$>vR*sP{s%OpkY@BIR;_(sL4lT@KudqAiWfsBE!^7gEQ# z37rKN1dKSnA-=fkS_g#3#kI_a`1M1Fmgt)ZiU5lU=@l(89cmUS5gE`OEW87Bov2ZH zrMIzk4?qEU*xyzfq?=;uY63E~PGa}j^zewX!V1GbXHio_*)}fGQDM;(kOq(&*Yg#N zuAw_@`Qm`)XU=vmUOE2fM*QqLnwYOR)gqCh6nd0t&?Q*%$}t?L)`gn3g_<>UyNn3gxD9xf$tc zo!RmzA>Q;#vuc;B^>QbYzTf_7ETT+wRS$BamjNkGSt35_~e30a&+ymx1GD5bdSAfNbn5uvUOP@G7t>VCcSH z@4&GR6o9+H27tH8HSu)KYRPZ<|2<3*)au)?sF24R`(-8`M$g=Sm2LJdwy$2FRu{V3 z@vp|p_>~I6|D&coIDt*}>D*pi)*jP>kz_sd4{zvF;%h=wQgSl1t4+@%OXAP0X_H&@ V6R{JAyMF}O>HNFQS@2XG`8O&?PYwV8 diff --git a/core/__pycache__/mail.cpython-311.pyc b/core/__pycache__/mail.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd23f61b2128fda748683c19df82eb847eff7bcd GIT binary patch literal 1603 zcmZWp-D@LN6u*X zadJ{eKv&m+{c9SbKe#d^F%e#Dg76qw$PygX6!ryy%PA+-6!*ng7M=8dI)zC3NE%Ki z@)H4}r|{m;zG9`nLi?&ER#0C0iyQMosQJXTjHYQjpr}4!%yt|8c5RrNyD9K;{RM(x zkC6t;=%DY=_o*|{N^!{&I|A@@Ck0mdEY0|=gpNiFXibdSQ$vr2a3(RHBcYDi8ILgX z>`0dMi~Iyid^#!<%2z7rEyUE}e1w(|y?-XN7}y)@5AyBbTgg&8GOuGCC;{yuOFNUl zkS(c_NNu5wj>SFH7V^3|2_@+mr~=se*u*u@WoC`xx<{M1NqpaI5X?Nx4he2KCX4N+ z)wEr|5KoL*nKt}VEb&;b*(CVB&uG3B$0hU~KQ@j$2=CHMF0pmwGfbWYs=@+>Cca4G zvXN^n>=G7G_kYVc@I0r4t27|ku4C974EsT?1~t_K$2nQX8>ZtE>_KU?ZTlpSayq|F z+ITHNVJiWkPQ4~R{dms{@S*vLU`lGlencz)%mw%1x?;BzFQB+h4t$%DF*pmlz75Ef z@Tsb=a{xff=z5Z)q;KSe0Lsrg^JD<<(HW?2f zrr!g0j-t8Oq?y6=!=J3)^g|e3B}$2Ng#liQMEFJs*z-5;Mbc1-Wc2oOqzu*W#J@UP zc(XtMpf_Ln?YRHmZtvYnH~Xjh>L7P#ki(a=i~ZRLgFE@b!eW$>HT`b{>>tjem}Sva zuFI}2Gr0(*q?ucGsb;^K_7TXkKRYb;$4^Hw~*v literal 0 HcmV?d00001 diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index e99b8fdc913593e916c6c169d2a0422bdc5e4348..2b649dde12f5c9c3dd6a473575aed282948df4b5 100644 GIT binary patch delta 962 zcmZ|My>HV%6aesZe0IK?rfHHkZQ9ZgLI`PU6+~NgstB-ARYGOx5?S#nb#R=@aUf)> z5Cdb;Au%ANPHiQ+@E`CeIFb>SCj<+XIv}yZ!t*7zC=zF%?%nVCo$h?cBhM3?$FW!h zLHqQ(tv(hI`sPl&mL3E@zXlL`gA}B28ftJm9OuRXEzsb1FvL8>0>u2Q&C+dL4|?^7 zAusxSR6?iWBMzbW(ECk^&{;0M8YQ?M_Uu2kL#MHSYKPt0c%1Ncb`ZB-8DW+Hi+bxR zqs)?EL%yY$rNLspjWHVs8}=>3YyvFq+a$9r*obda%%;H-zRfVZ0ygT~EVDVVq;K=g z7Qj-zU1gR7^R5CZ*O=wO#{BQDyS7~b8~5$Tsd&W0UxwaqwZu+FDLzDn#d8-5oP+md za~DS8iAtWf&fWWPkRzzNLOO0*mm7o@`SsE-PJ($@Cmpl0C)bE0YRy`+ZFa*3si`fK z7?Kn6LfYluCgxOKHC5Rpr9JssgXkuGffuy2}5>0Z32f0cgx)Iqh)v89M zWjc)?(F=Sp*9}#hx+zyp$q5dk&BBBeRqC={Yc917t!41^fsn}<*xi0aZkxLmb{<0n zFoLurRFcM|n;aUf!1DC7@F1E8c8}c(1gIot=Wki)(tC!I*5#LK;tV|$SBqsUwcJZ> z*r|<=9Sd*u@Rp6Y&Twe|?#t`}d99zUTX?01S8TjOFGPjD3*OIuVd<%Zwmn|7Zr-tQ xxrfU(E<+jJ4KDHS_&q4)`^!uoY}@JliE81s9$vHY+K*f^9@vk%kCB62{{izf*N^}J delta 855 zcmZ|NF>KR76adh3>~ox?X_6*RLR$(6Z6Q({gODgAk&0kx7)TkiL{{&VI!c_#aiGl- z#KcH-14sx7mUbW#OpLHHI#LGYm8n}13la(Ucr7&xetr%h^b!$7geGbURY5=`K*VOCC00d<5yTS2_^7-Y6&pdXo+w8j z)vXZ44aK9kAusy-PQt^;v4GHf7}G}Pcxe<$C)?xrpHe)W|EDwtrLi~_8mnB$CZPxXv8lIcKV;Fm(Y2|ixr!I|xy64fE5ttF8q3K$kyS|fr*(e_>`-3H zCmnRIe?vE&^PPQ?SJ-+m&BpSUde2GS7^SwysqL?~9jP*sDr2d_ZUss9`QnS+v08Ah r-*KeUNGgq`(wU5Ki2V*0@iclByg!RJ6fJ(XnTZ9SM)+mrVMl)e2Lihg diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 91c102237cbb2cb0c7dfb1ddf2296ec15800b1ae..cd8e56a541155e16e959a99a1b118e4f62aa60d5 100644 GIT binary patch delta 3258 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 GKkr|aa~=Kw diff --git a/core/forms.py b/core/forms.py index f9b7273..f81aa07 100644 --- a/core/forms.py +++ b/core/forms.py @@ -4,6 +4,12 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import get_language from .models import Profile, Parcel, Country, Governate, City +class ContactForm(forms.Form): + name = forms.CharField(max_length=100, label=_("Name"), widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Your Name')})) + email = forms.EmailField(label=_("Email"), widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': _('Your Email')})) + subject = forms.CharField(max_length=200, label=_("Subject"), widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Subject')})) + message = forms.CharField(label=_("Message"), widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 5, 'placeholder': _('Your Message')})) + class UserRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput, label=_("Password")) password_confirm = forms.CharField(widget=forms.PasswordInput, label=_("Confirm Password")) diff --git a/core/mail.py b/core/mail.py new file mode 100644 index 0000000..b855004 --- /dev/null +++ b/core/mail.py @@ -0,0 +1,38 @@ +from django.core.mail import send_mail +from django.conf import settings +import logging + +logger = logging.getLogger(__name__) + +def send_contact_message(name, email, message): + """ + Sends a contact form message to the platform admins. + + Args: + name (str): Sender's name + email (str): Sender's email + message (str): The message content + + Returns: + bool: True if sent successfully, False otherwise + """ + try: + subject = f"New Contact Message from {name}" + full_message = f"You have received a new message from your website contact form.\n\n" \ + f"Name: {name}\n" \ + f"Email: {email}\n\n" \ + f"Message:\n{message}" + + recipient_list = settings.CONTACT_EMAIL_TO or [settings.DEFAULT_FROM_EMAIL] + + send_mail( + subject=subject, + message=full_message, + from_email=settings.DEFAULT_FROM_EMAIL, + recipient_list=recipient_list, + fail_silently=False, + ) + return True + except Exception as e: + logger.error(f"Failed to send contact message: {e}") + return False diff --git a/core/templates/base.html b/core/templates/base.html index 36cb331..63534f6 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -36,6 +36,15 @@ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Example font suitable for Arabic */ } + /* Fix alignment for form inputs in RTL */ + .form-control, .form-select { + text-align: right; + } + /* Ensure labels are also right-aligned */ + .form-label { + text-align: right; + width: 100%; + } {% endif %} @@ -54,6 +63,9 @@ + {% if user.is_authenticated %}
  • {% trans "VAT No:" %} {{ platform_profile.vat_number }}
  • {% endif %} - {% if not platform_profile.address and not platform_profile.phone_number %} -
  • {% trans "Contact information pending." %}
  • - {% endif %} +
  • + {% trans "Send us a message" %} +
  • diff --git a/core/templates/core/contact.html b/core/templates/core/contact.html new file mode 100644 index 0000000..0a8044c --- /dev/null +++ b/core/templates/core/contact.html @@ -0,0 +1,91 @@ +{% extends 'base.html' %} +{% load i18n static %} + +{% block title %}{% trans "Contact Us" %} | masarX{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    +
    +
    +

    {% trans "Contact Us" %}

    +

    {% trans "We'd love to hear from you. Please fill out the form below." %}

    +
    + +
    + {% csrf_token %} + + {% if form.non_field_errors %} +
    + {% for error in form.non_field_errors %} + {{ error }} + {% endfor %} +
    + {% endif %} + +
    +
    + + {{ form.name }} + {% if form.name.errors %} +
    {{ form.name.errors.0 }}
    + {% endif %} +
    +
    + + {{ form.email }} + {% if form.email.errors %} +
    {{ form.email.errors.0 }}
    + {% endif %} +
    +
    + +
    + + {{ form.subject }} + {% if form.subject.errors %} +
    {{ form.subject.errors.0 }}
    + {% endif %} +
    + +
    + + {{ form.message }} + {% if form.message.errors %} +
    {{ form.message.errors.0 }}
    + {% endif %} +
    + +
    + +
    +
    +
    +
    + + + {% if platform_profile %} +
    +
    {% trans "Or reach us at" %}
    +
    + {% if platform_profile.phone_number %} +
    {{ platform_profile.phone_number }}
    + {% endif %} + {% if platform_profile.email %} +
    {{ platform_profile.email }}
    + {% endif %} + {% if platform_profile.address %} +
    {{ platform_profile.address }}
    + {% endif %} +
    +
    + {% endif %} + +
    +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/core/urls.py b/core/urls.py index 3d76963..7803136 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,28 +1,24 @@ from django.urls import path -from . import views from django.contrib.auth import views as auth_views +from . import views urlpatterns = [ path('', views.index, name='index'), - path('register/', views.register, name='register'), path('login/', auth_views.LoginView.as_view(template_name='core/login.html'), name='login'), - path('logout/', auth_views.LogoutView.as_view(next_page='index'), name='logout'), + path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'), + path('register/', views.register, name='register'), path('dashboard/', views.dashboard, name='dashboard'), path('shipment-request/', views.shipment_request, name='shipment_request'), path('accept-parcel//', views.accept_parcel, name='accept_parcel'), path('update-status//', views.update_status, name='update_status'), - path('article/', views.article_detail, name='article_detail'), + path('initiate-payment//', views.initiate_payment, name='initiate_payment'), + path('payment-success/', views.payment_success, name='payment_success'), + path('payment-cancel/', views.payment_cancel, name='payment_cancel'), - # AJAX for locations + path('article/1/', views.article_detail, name='article_detail'), path('ajax/get-governates/', views.get_governates, name='get_governates'), path('ajax/get-cities/', views.get_cities, name='get_cities'), - - # Thawani Payment - path('payment/initiate//', views.initiate_payment, name='initiate_payment'), - path('payment/success/', views.payment_success, name='payment_success'), - path('payment/cancel/', views.payment_cancel, name='payment_cancel'), - - # Static pages path('privacy-policy/', views.privacy_policy, name='privacy_policy'), path('terms-conditions/', views.terms_conditions, name='terms_conditions'), + path('contact/', views.contact_view, name='contact'), ] \ No newline at end of file diff --git a/core/views.py b/core/views.py index 1670a0a..54fde5b 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 .models import Parcel, Profile, Country, Governate, City -from .forms import UserRegistrationForm, ParcelForm +from .forms import UserRegistrationForm, ParcelForm, ContactForm from django.utils.translation import gettext_lazy as _ from django.utils.translation import get_language from django.contrib import messages @@ -17,6 +17,7 @@ from .whatsapp_utils import ( notify_driver_assigned, notify_status_change ) +from .mail import send_contact_message def index(request): tracking_id = request.GET.get('tracking_id') @@ -187,4 +188,23 @@ def privacy_policy(request): return render(request, 'core/privacy_policy.html') def terms_conditions(request): - return render(request, 'core/terms_conditions.html') \ No newline at end of file + return render(request, 'core/terms_conditions.html') + +def contact_view(request): + if request.method == 'POST': + form = ContactForm(request.POST) + if form.is_valid(): + # Send email + sent = send_contact_message( + name=form.cleaned_data['name'], + email=form.cleaned_data['email'], + message=form.cleaned_data['message'] + ) + if sent: + messages.success(request, _("Your message has been sent successfully!")) + else: + messages.error(request, _("There was an error sending your message. Please try again later.")) + return redirect('contact') + else: + form = ContactForm() + return render(request, 'core/contact.html', {'form': form}) \ No newline at end of file diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo index 6c506629e18739e0d1391371c6dbdcac560223ce..39ac3dfb2c7e1fae2dbbcfc1a4b0ab51e8a369a0 100644 GIT binary patch literal 11813 zcmbW53vgW3dB=}a9>zS{PzXsW;W!0s2Wye6n1_sGWMmr$KNQR6)dqUKdnGMi?G^W~ ztcZkwAF_oY36wxyB@{of5jIBHV8j6JBz>gQNhgy|rn{60ZIfxBnWi+IcABIU`um@I z?(WKuH0{Noe)pc|_kHI(-#N?o&OPN(!?PFpZKUf|W8Q?NS^VL7>uh6I!nfhC!}fEG zIUQaPX=-kS=fRJ|_rqTJoA6$!_K(2dfV<%t@QCMYP~&_Po(8`SPl106)&32rasCCW z-3$hkN@u`!cplVvH$c^|gETd_LA5LT`ikdg;7rQLpvHd~ehBV@m}dUWm;a6D58%0! z{|7u1&ZN`(;CWE}FXxZ!zZP1!6t04Kcr|^I z2IapC310P^<9Q{N-i0gVejkJye-2c;c8H3m6XFW90m^^-3PTFr(h0# z2Wq|D*PR2K9J6L33PD|6;Ibf`E5De3?n!^ z!9Z1Q zo$r8(%L3H84nf&524&}?PMw*EccJHvP~!wp?aEMg-3JK) z^ChTto`h=my08Bslz-lZ((4=!5!GJ|W&eDrd9H%;&uS=t7hyZR2i^cD;Z^WwP;sz; z;E*2cpvEac`6YrZf!Pda!Y@FL|2S-choSoY1JpeK4)1`cU&3C4eNcKl31#1_kSWb~ zq1yi!)Ocr+#AVNipxU=X>9^K@?}YN>ZYX_T_53@iaefL}VsrLo={n7a8fOXAIKK-u z|07WSpMmo4UqbowCs6HYunDElMNsYAq1OFID8JkeHD3`be(!-6J^&RD2cX)$0_B&# zfEuR;rT@Qqp2_5jlS`rWxej)~+u=<3WvKSMpyKKk|NSGV@lKs*4FAkU{E>bup!B*8 zDjv#^rsh*nKk^XuIoIRnWa?S&HZm@l{% zEo&JO@62v?1FOJz7h} zwVo%Ck0Of8Pa!uWdIpitx;OGUyagFXKIY4Q-;=FvK8cJXUq!l+HAwd89Q`BYL1Y_p zC!%K$(vIAK+=OJ0;$F{sWT|^gWAhLF`|a=#kS`(E`!dp^d+y-xIsSd4r!bD(h-^Z> zf<%a(*~kF0P#-*BL{_=C^v}aU`|2v>*U}>Q_rv~u3A`IQ6Iq6wg6O#*h5M`hco*_D zBy=UldiRFB6ix%VO;Djh6S4sVjB&Y z!`PNXUPq!KJ6OzbO6<^}t@MX>Fo^SE$p+1 zI1rXArn69p!z6(N#j@!vm26z>>!%l`VZ1pk(4`cIL1D!92b)92wLv}~4V5cPOy}mH zSPC|l!uoKDSsLb}0h-yaxQNb;Z_PMJ!Sz8I{Yqhhx7e+YS|1WP0K)Rr$|??W~xtAnD&21t`=NmSiH9__vYz zi_P4c)no;BZcil+!^#y)hl-^_vD`PW(Z`ux?~v-$G-Ov;!QDxt{fda$%cx0Fl8=jn zm10yjT~T>X<@mKqm%}!+UpByKW?2~r*!6Lc--I%DWtW{B=K6AWVdsLSxm<3ZZ;<$K zv4vEL`F1!|n9O%^R!ALzQ`2Aylbl^ynUmPNhKNkp1iuq}>1>2-Y};B}^8EqxYW_;o z{FTTiVQA%ALb`x?NzN=sSNy!ZNK~(ift_WwMyOX>L?D)s<1C8nN>xqoax0oEYZ|{jqa9<6vVkKhG7}xy#CZrDD?0XEN`2WcCyF-o0uJA)|N{njg*t{>h`}?N@U7xV)`CEri=h+Pv6i?YG?RD#No zdZnKvMLumYv4gCrfg8=qy{Y$ zUj#ML+vqSHIH#m(kK%ORjJBIiGBjwq`=fGb*9;A8BonHPWWRx8U+a*i5nq~po*=8F z-K@(g*}KbfBU#@ppZMDPwlUpg#omb2>msWD)g4E@>_XEW7xTo}+STjk>3wsMAF;5>Jgm++c}W=Z+SF{!VS9H1sxyTDT?D>k2Gi>qu}(59wN#4aYi=0Dl8z{sA48H8_pbu!v&iW#^^%}BEOCCiaio#Y5*yt4 zXi~V_$p$WMMt{mW8E@)b?{WXZqDtMm zv26U3P-^svPm|M+Ob$PK4F{Krk5R>$MsF=K3w{6Z+>}E zE3q5H5T9$jX?xG4=d#VG7tzFN<4!zxB`rnypwxU;%Ei4w!X+stXXu`sUY9Dm?YL{R zzc_J}=hBme%Y9!oA5XJ5aWRUy2)mrAJ<+nV&~g*!D*@4AyF0JHv2(>Td(*OYJuBC) znYAt)jN(em>ZGq&XjwYcm$a;pI_#|OwJqzy%|-QT>EbHYVHdP6xU!|St!2SN+j><; zTl?j$JhOCfX(77G3AsOtJM4;(p94k8%Y8$f(k<)5V4%aM_lkOH2P->k^~%-D8hW+m zT4(7pj`Ld9j|?(lCH!RNiop`M?L}5Mz9g(H-mrdo%hio`nzuKMTb7mckv3e1y?SG@ zGON2Z6thK^a}*^Vwmj%Qlf_pqvgzyM^5VsF@4`)&1bZJgK1 z>eIG5p^AOA?bV6uLE3G#wb9y++D=>DuhQC9TJ2BEwz;zEVY+Om&UZUXgG079M*Bn6 zC)1%O8ESj=>71eaex}}@79XK_NA+prrki4xG2V8#&)O*C?om@yJ%9$|)v2_PbQ*J7 z(Rm9!UUK7ZuO7lIG&)GXeKILkcT07OnV(3fNax#Eop3`j#RNlbk=drUt+oR<(Df;F z+*fuRH$`CQjunb57#Q`?Ki|GA-_9 z$(hHk{O;H5|Z;YzcKomcS z#iKINM~WI&~tyi~h?o^eaz{D0hd&ak?Q z4TUCfnpOerj_t!}^4%6i-m!IVURkw8){j>Y%bC+7lVEH(#yce)rm@O&+RsubN}O4H z>9GwD5+Ybc0PbdapOtEp#9QW08tf-x=Az&;>c(!*e(g3o9A}u{gxax+!?Eh~>;!

    N3!VIPupj#w6;{cEnA&1PVs#x=Y6!>#j&P#Rn1Fz zYynd$a7bNMrc4vUcx{XJ(G&x0H`vkqjX^GdOy0u!O6}&Xii2cky6tI3ev-3C^;bUg zYrU80hypFFOQTq*aVXF?(`}WOJE||r9t8!PwLU9;soOcl$5ZrTo01YVQ#RrAQbKu{ zahjuv+~6mzZBwVi#vwEmiFov=V)+Fn2fx1cV^!gcHx>Hq8y17s$DM;TY78W! z{MkcCc1v^b>QQP5p}K0?ceSxp>BiZim0?FzNhQX4aEo=$@}Z^kNeAeZ@xj)pv^wTE zM$i~9AcvSi5y+e3UXh#bQC?Ka1Zk-()i_ysVy7%|;aLma#t?|k0{!i!Tv@xfhoYQKKJ7St^S-)dW&*oZe&T<&Bw}aipek9qF zckv@zx~7zy2AHpQQF~Z**fN=`PO+=g>+Iod$(|*9xD2AmJ9%AmtTy&JN2&{d7u2aH z>E_g^Y5GYu)Ow{$dW4GXz)1H}nZyw~~GSeu`_{0@p^h=+o~X&2`N_ zs`se*c=67ump6qJWu(3i26u0bi&yq(*~ItZAvLo#pV=EB=_{PWC)_?^Imipm$w*t9 zZ-T?+_tfn=GInV_sl+whV=^u4*WzQ!>mg#QO=qG;ZaNk?Hd#$H-7Y6`7eYZbL5HkL zDMGVnX`ZG!-Q<0*cDk1CcZel9HTHj#-4m!x81Vn4vYad@DdOCGZtzC%J56$VcgwJZ+t(Tq%<(;10ypD+GJ>rD>;}eyF*GTz$Iwpmgxpn`z~25T^Av*5_DB zmgd+J5*Ha5J$5%~o~q!}uXhgF)18OUr0wdtx#6I+*NN`iu7=ef&I z!{ey#k8;Cq{Y2o6_)op^|Ec|@yO?dHBti-y#92cQk!RfG?pBS>RV-!!<)GbEX>&el zn`1BwG7g4gjvU68pMIs^RPOGEuhYP)zYvu~@uBnv=3=g1!a-L{uY%05H9KY9&s&ur zWUaXjjuQZcyT2Oh?A}SmPDSEw^dtQc0>?+T6z~hKLswqVbfjK-Wg! za$MOo=8Jrcvz5llG+M?JRsAZ5q3)+TNBK>uBbd3lFDQ#l^E?IHwM5KBjiT;3-DLS0 zqQ$H2RLE21e%3U-@+)Z@-Wlbvs8`EN`p~^zJr1xI3Pw4OQOPhe+U1<|N8DDWb=~Cn zapW|}^2}_*0Jv%*t(6U|QPaNlhl+2Nj(O5ns3ngQ7U?8f-EGo@NN{o66qA@EPt~(r z)81=pg{AdOXBc{tDcFVCPYG4mfA&qgh3aR_NpHB$d29mI8+ZNX7yRgRQsc*>TPF5h njsLl%VAieBrE%KxAI{+?X6h|>|Jo_1ln9LMo#0n1hBLCaa#QrdE~2=oAztAJSKE>vy`)~BVEw$MH;N`NPFRMLP4 z14bm`K^jDkiX|LsBoGrZ93h0@R)Z+=f)_w-j0waL{r<|3sFVHgXLfdHcCLM%`o;AV zLqEr~-EBxUL?7Z}8)H7e^%0y%zjrVu3R|4v9gUg7bu4zpCD;wium^6!SlsLGH=ydD zL7FgEoIfJ32$|dNfxD=RkFX0ycQS^o@lX|qIJ2-l*W*wP=VE_cfRVV~mDf4TU-(q~jb%DjKNX{KC~9@bV@Ok(OC}CyBZn#Gq!-kndb%0azz*avyEu8cA2p(HUHKK~ zP1Jzyqh9nk>OB#RrZ+~RuG6|Q|9UWs0y=9ZBhQ+-?twzo3s$-NucFqn7PSO>ki+cb zr00&J+WQi<886^ayp8HeEH|}Td*eVH7RCIl!U9hHa3%7rsY7+-ebmSgqP~vL-Th1M z{tXPL{4Q$gno(2yC%%9YT&TU7sCEiaOIw5*z?u*lO+^iAWV+UaJ5eLrgIbDu)DnGx z>gah)#XFdUQB>9^oQZ40j5&loxlUrZatyA+d8l@-qUwe2knzZLrc@25BW;@L&H_{i z*Pu4jI#h?=L=X3(X69>mzX`RJ_mIQ<<;tV^<}{U5Bqy9# zQB!swd*MUui`{rQ5i@WY=Hm*i#Z}mhdVVn*K^<9(n(`f}0qjKWKl33O^{4^0S-wYA ze1MvXSZ?ZmGAA`O&Y6$8Uy8iTY(T1*-KfoV)Rq5$YzNbfda)YUOh#e`?>C8LaxouA z;yzTv*HL@n4(bP`8MPFVOpiJekLj3(`UPBwYIuXY{|@TK2av;@;-vPkx$DlXTZm4X zfn@Z83C?Ax5p8tW@1jO@9JPiwPz~Nib)-F&^?YB{Qe~q$l7rd{`KYg;(A}>>4RB)u z^RJ3;Q=pD~iX7$~r)TjO)QEet;JQBmwM1i4^~!J%Zbf}P4X78NLrwK{RL6fq)$hy> zSBFzjGdsE;^RE|7q(D8Ih6`~is-e@U5nV!kjy|g4+o%q-pr*cq_xQOqRK1a?%{dkI z!ZOsrHlu#3KX!f>B6E_0dl-guiT|e@3N*Uugf^IxdatDAP@44^lYz5|;e^(n6*41; zCuz=;3>Ffha#t_|H8M^65@IZ&5hzs?8bvlSo(K?{cBNH>WfMtHe?|+Y+5%hsA7&owdBMba`>Wn-r)j ztSng_EU75B*J38vGqLa4#%@J6F|NOz7nf_liL0|S<7+#Wl?1)Kz?$knRnTtlzAI+l z@{(Xld9hbiQR%HNDJ-pCZC~%Pzp%sn6KP`h-p4cBq$aw|PyrJh3ePGr!S4OcPr?|3K3g|EPbg zX`6r8M)vpY%KqnVUQ&#$NUF5Ah9osU7|=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: core/forms.py:7 -msgid "Password" -msgstr "كلمة المرور" +#: core/forms.py:8 +msgid "Name" +msgstr "الاسم" #: core/forms.py:8 -msgid "Confirm Password" -msgstr "تأكيد كلمة المرور" +msgid "Your Name" +msgstr "اسمك" -#: core/forms.py:9 -msgid "Register as" -msgstr "التسجيل كـ" - -#: core/forms.py:10 core/models.py:13 -msgid "Phone Number" -msgstr "رقم الهاتف" - -#: core/forms.py:16 -msgid "Username" -msgstr "اسم المستخدم" - -#: core/forms.py:17 +#: core/forms.py:9 core/forms.py:28 msgid "Email" msgstr "البريد الإلكتروني" -#: core/forms.py:18 +#: core/forms.py:9 +msgid "Your Email" +msgstr "بريدك الإلكتروني" + +#: core/forms.py:10 +msgid "Subject" +msgstr "الموضوع" + +#: core/forms.py:11 +msgid "Message" +msgstr "الرسالة" + +#: core/forms.py:11 +msgid "Your Message" +msgstr "رسالتك" + +#: core/forms.py:14 +msgid "Password" +msgstr "كلمة المرور" + +#: core/forms.py:15 +msgid "Confirm Password" +msgstr "تأكيد كلمة المرور" + +#: core/forms.py:16 +msgid "Register as" +msgstr "التسجيل كـ" + +#: core/forms.py:17 core/models.py:69 core/models.py:154 +msgid "Phone Number" +msgstr "رقم الهاتف" + +#: core/forms.py:19 core/models.py:23 core/models.py:27 core/models.py:71 +msgid "Country" +msgstr "الدولة" + +#: core/forms.py:20 core/models.py:41 core/models.py:45 core/models.py:72 +msgid "Governate" +msgstr "المحافظة" + +#: core/forms.py:21 core/models.py:59 core/models.py:73 +msgid "City" +msgstr "المدينة" + +#: core/forms.py:27 +msgid "Username" +msgstr "اسم المستخدم" + +#: core/forms.py:29 msgid "First Name" msgstr "الاسم الأول" -#: core/forms.py:19 +#: core/forms.py:30 msgid "Last Name" msgstr "اسم العائلة" -#: core/forms.py:26 +#: core/forms.py:69 msgid "Passwords don't match" msgstr "كلمات المرور غير متطابقة" -#: core/forms.py:46 +#: core/forms.py:97 msgid "What are you sending?" msgstr "ماذا سترسل؟" -#: core/forms.py:48 -msgid "123 Street, City" -msgstr "123 شارع، مدينة" +#: core/forms.py:104 core/forms.py:109 +msgid "Street/Building" +msgstr "الشارع/المبنى" -#: core/forms.py:49 -msgid "456 Avenue, City" -msgstr "456 جادة، مدينة" - -#: core/forms.py:54 +#: core/forms.py:115 msgid "Package Description" msgstr "وصف الطرد" -#: core/forms.py:55 core/models.py:36 +#: core/forms.py:116 core/models.py:112 msgid "Weight (kg)" msgstr "الوزن (كجم)" -#: core/forms.py:56 core/models.py:38 -msgid "Pickup Address" -msgstr "عنوان الاستلام" +#: core/forms.py:117 +msgid "Shipping Price (OMR)" +msgstr "سعر الشحن (ر.ع)" -#: core/forms.py:57 core/models.py:39 -msgid "Delivery Address" -msgstr "عنوان التوصيل" +#: core/forms.py:118 core/models.py:116 +msgid "Pickup Country" +msgstr "دولة الاستلام" -#: core/forms.py:58 core/models.py:41 +#: core/forms.py:119 core/models.py:117 +msgid "Pickup Governate" +msgstr "محافظة الاستلام" + +#: core/forms.py:120 core/models.py:118 +msgid "Pickup City" +msgstr "مدينة الاستلام" + +#: core/forms.py:121 +msgid "Pickup Address (Street/Building)" +msgstr "عنوان الاستلام (الشارع/المبنى)" + +#: core/forms.py:122 core/models.py:122 +msgid "Delivery Country" +msgstr "دولة التوصيل" + +#: core/forms.py:123 core/models.py:123 +msgid "Delivery Governate" +msgstr "محافظة التوصيل" + +#: core/forms.py:124 core/models.py:124 +msgid "Delivery City" +msgstr "مدينة التوصيل" + +#: core/forms.py:125 +msgid "Delivery Address (Street/Building)" +msgstr "عنوان التوصيل (الشارع/المبنى)" + +#: core/forms.py:126 core/models.py:127 msgid "Receiver Name" msgstr "اسم المستلم" -#: core/forms.py:59 core/models.py:42 +#: core/forms.py:127 core/models.py:128 msgid "Receiver Phone" msgstr "هاتف المستلم" -#: core/models.py:8 core/models.py:32 +#: core/models.py:10 core/models.py:28 core/models.py:46 +msgid "Name (English)" +msgstr "الاسم (إنجليزي)" + +#: core/models.py:11 core/models.py:29 core/models.py:47 +msgid "Name (Arabic)" +msgstr "الاسم (عربي)" + +#: core/models.py:24 +msgid "Countries" +msgstr "الدول" + +#: core/models.py:42 +msgid "Governates" +msgstr "المحافظات" + +#: core/models.py:60 +msgid "Cities" +msgstr "المدن" + +#: core/models.py:64 core/models.py:108 msgid "Shipper" msgstr "شاحن" -#: core/models.py:9 +#: core/models.py:65 msgid "Car Owner" msgstr "صاحب سيارة" -#: core/models.py:11 +#: core/models.py:67 msgid "User" msgstr "مستخدم" -#: core/models.py:12 +#: core/models.py:68 msgid "Role" msgstr "الدور" -#: core/models.py:19 +#: core/models.py:79 msgid "Profile" msgstr "الملف الشخصي" -#: core/models.py:20 +#: core/models.py:80 msgid "Profiles" msgstr "الملفات الشخصية" -#: core/models.py:24 +#: core/models.py:94 msgid "Pending Pickup" msgstr "في انتظار الاستلام" -#: core/models.py:25 +#: core/models.py:95 msgid "Picked Up" msgstr "تم الاستلام" -#: core/models.py:26 +#: core/models.py:96 msgid "In Transit" msgstr "في الطريق" -#: core/models.py:27 +#: core/models.py:97 msgid "Delivered" msgstr "تم التوصيل" -#: core/models.py:28 +#: core/models.py:98 msgid "Cancelled" msgstr "ملغي" -#: core/models.py:31 +#: core/models.py:102 +msgid "Pending" +msgstr "قيد الانتظار" + +#: core/models.py:103 +msgid "Paid" +msgstr "مدفوع" + +#: core/models.py:104 +msgid "Failed" +msgstr "فشل" + +#: core/models.py:107 msgid "Tracking Number" msgstr "رقم التتبع" -#: core/models.py:33 core/templates/core/shipper_dashboard.html:28 +#: core/models.py:109 core/templates/core/shipper_dashboard.html:42 msgid "Carrier" msgstr "الناقل" -#: core/models.py:35 +#: core/models.py:111 msgid "Description" msgstr "الوصف" -#: core/models.py:36 +#: core/models.py:112 msgid "Weight in kg" msgstr "الوزن بالكيلوجرام" -#: core/models.py:44 core/templates/core/index.html:30 +#: core/models.py:113 +msgid "Price (OMR)" +msgstr "السعر (ر.ع)" + +#: core/models.py:119 +msgid "Pickup Address" +msgstr "عنوان الاستلام" + +#: core/models.py:125 +msgid "Delivery Address" +msgstr "عنوان التوصيل" + +#: core/models.py:130 core/templates/core/index.html:30 msgid "Status" msgstr "الحالة" -#: core/models.py:45 +#: core/models.py:131 +msgid "Payment Status" +msgstr "حالة الدفع" + +#: core/models.py:132 +msgid "Thawani Session ID" +msgstr "معرف جلسة ثواني" + +#: core/models.py:134 msgid "Created At" msgstr "أنشئ في" -#: core/models.py:46 +#: core/models.py:135 msgid "Updated At" msgstr "حدث في" -#: core/models.py:57 +#: core/models.py:146 msgid "Parcel" msgstr "طرد" -#: core/models.py:58 +#: core/models.py:147 msgid "Parcels" msgstr "طرود" -#: core/templates/base.html:9 +#: core/models.py:150 +msgid "Platform Name" +msgstr "اسم المنصة" + +#: core/models.py:151 +msgid "Logo" +msgstr "الشعار" + +#: core/models.py:152 +msgid "Slogan" +msgstr "الشعار اللفظي" + +#: core/models.py:153 +msgid "Address" +msgstr "العنوان" + +#: core/models.py:155 +msgid "Registration Number" +msgstr "رقم السجل التجاري" + +#: core/models.py:156 +msgid "VAT Number" +msgstr "الرقم الضريبي" + +#: core/models.py:157 core/templates/base.html:177 +#: core/templates/core/privacy_policy.html:6 +msgid "Privacy Policy" +msgstr "سياسة الخصوصية" + +#: core/models.py:158 core/templates/core/terms_conditions.html:6 +msgid "Terms and Conditions" +msgstr "الشروط والأحكام" + +#: core/models.py:164 core/models.py:165 +msgid "Platform Profile" +msgstr "ملف تعريف المنصة" + +#: core/templates/base.html:9 core/templates/base.html:149 msgid "Small Shipments, Smart Delivery" msgstr "شحنات صغيرة، توصيل ذكي" -#: core/templates/base.html:62 +#: core/templates/base.html:55 msgid "How it Works" msgstr "كيف يعمل" -#: core/templates/base.html:66 +#: core/templates/base.html:58 +msgid "Contact" +msgstr "اتصل بنا" + +#: core/templates/base.html:62 msgid "Dashboard" msgstr "لوحة التحكم" -#: core/templates/base.html:69 +#: core/templates/base.html:66 +msgid "Admin" +msgstr "المسؤول" + +#: core/templates/base.html:70 msgid "Hello" msgstr "مرحباً" -#: core/templates/base.html:74 +#: core/templates/base.html:75 msgid "Logout" msgstr "تسجيل الخروج" -#: core/templates/base.html:79 core/templates/core/login.html:4 +#: core/templates/base.html:80 core/templates/core/login.html:4 #: core/templates/core/login.html:25 msgid "Login" msgstr "تسجيل الدخول" -#: core/templates/base.html:82 core/templates/core/register.html:4 +#: core/templates/base.html:83 core/templates/core/register.html:4 msgid "Register" msgstr "تسجيل" -#: core/templates/base.html:110 +#: core/templates/base.html:111 msgid "Find Loads" msgstr "البحث عن شحنات" -#: core/templates/base.html:112 core/templates/core/index.html:13 +#: core/templates/base.html:113 core/templates/core/index.html:13 msgid "Start Shipping" msgstr "ابدأ الشحن" -#: core/templates/base.html:137 +#: core/templates/base.html:154 core/templates/core/contact.html:4 +#: core/templates/core/contact.html:14 +msgid "Contact Us" +msgstr "اتصل بنا" + +#: core/templates/base.html:163 +msgid "Reg No:" +msgstr "رقم السجل:" + +#: core/templates/base.html:166 +msgid "VAT No:" +msgstr "الرقم الضريبي:" + +#: core/templates/base.html:169 +msgid "Send us a message" +msgstr "أرسل لنا رسالة" + +#: core/templates/base.html:175 +msgid "Legal" +msgstr "قانوني" + +#: core/templates/base.html:178 +msgid "Terms & Conditions" +msgstr "الشروط والأحكام" + +#: core/templates/base.html:186 msgid "All rights reserved." msgstr "جميع الحقوق محفوظة." +#: core/templates/core/contact.html:15 +msgid "We'd love to hear from you. Please fill out the form below." +msgstr "نود أن نسمع منك. يرجى ملء النموذج أدناه." + +#: core/templates/core/contact.html:63 +msgid "Send Message" +msgstr "إرسال الرسالة" + +#: core/templates/core/contact.html:72 +msgid "Or reach us at" +msgstr "أو تواصل معنا عبر" + #: core/templates/core/driver_dashboard.html:6 msgid "Driver Dashboard" msgstr "لوحة تحكم السائق" @@ -231,34 +425,34 @@ msgstr "الاستلام" msgid "Delivery" msgstr "التوصيل" -#: core/templates/core/driver_dashboard.html:29 +#: core/templates/core/driver_dashboard.html:30 msgid "Weight" msgstr "الوزن" -#: core/templates/core/driver_dashboard.html:32 +#: core/templates/core/driver_dashboard.html:35 msgid "Accept Shipment" msgstr "قبول الشحنة" -#: core/templates/core/driver_dashboard.html:40 +#: core/templates/core/driver_dashboard.html:43 msgid "No shipments available at the moment." msgstr "لا توجد شحنات متوفرة حالياً." -#: core/templates/core/driver_dashboard.html:57 +#: core/templates/core/driver_dashboard.html:60 #: core/templates/core/index.html:35 #: core/templates/core/shipper_dashboard.html:25 msgid "To" msgstr "إلى" -#: core/templates/core/driver_dashboard.html:58 -#: core/templates/core/shipper_dashboard.html:27 +#: core/templates/core/driver_dashboard.html:61 +#: core/templates/core/shipper_dashboard.html:41 msgid "Receiver" msgstr "المستلم" -#: core/templates/core/driver_dashboard.html:69 +#: core/templates/core/driver_dashboard.html:72 msgid "Update" msgstr "تحديث" -#: core/templates/core/driver_dashboard.html:77 +#: core/templates/core/driver_dashboard.html:80 msgid "You haven't accepted any shipments yet." msgstr "لم تقبل أي شحنات بعد." @@ -369,6 +563,10 @@ msgstr "ليس لديك حساب؟" msgid "Register here" msgstr "سجل هنا" +#: core/templates/core/privacy_policy.html:11 +msgid "Privacy Policy not available yet." +msgstr "سياسة الخصوصية غير متوفرة بعد." + #: core/templates/core/register.html:13 msgid "Join masarX" msgstr "انضم إلى مسارX" @@ -385,11 +583,34 @@ msgstr "لديك حساب بالفعل؟" msgid "Login here" msgstr "سجل دخولك هنا" +#: core/templates/core/register.html:48 +#: core/templates/core/shipment_request.html:143 +msgid "Select Governate" +msgstr "اختر المحافظة" + +#: core/templates/core/register.html:49 core/templates/core/register.html:67 +#: core/templates/core/shipment_request.html:144 +#: core/templates/core/shipment_request.html:162 +msgid "Select City" +msgstr "اختر المدينة" + #: core/templates/core/shipment_request.html:10 msgid "Request a Shipment" msgstr "طلب شحنة" -#: core/templates/core/shipment_request.html:24 +#: core/templates/core/shipment_request.html:39 +msgid "Pickup Details" +msgstr "تفاصيل الاستلام" + +#: core/templates/core/shipment_request.html:72 +msgid "Delivery Details" +msgstr "تفاصيل التوصيل" + +#: core/templates/core/shipment_request.html:105 +msgid "Receiver Details" +msgstr "تفاصيل المستلم" + +#: core/templates/core/shipment_request.html:123 msgid "Submit Request" msgstr "إرسال الطلب" @@ -401,88 +622,70 @@ msgstr "شحناتي" msgid "New Shipment" msgstr "شحنة جديدة" -#: core/templates/core/shipper_dashboard.html:28 +#: core/templates/core/shipper_dashboard.html:36 +msgid "Pay Now" +msgstr "ادفع الآن" + +#: core/templates/core/shipper_dashboard.html:42 msgid "Waiting for pickup" msgstr "في انتظار الاستلام" -#: core/templates/core/shipper_dashboard.html:36 +#: core/templates/core/shipper_dashboard.html:50 msgid "You haven't sent any shipments yet." msgstr "لم ترسل أي شحنات بعد." -#: core/templates/core/shipper_dashboard.html:37 +#: core/templates/core/shipper_dashboard.html:51 msgid "Send your first shipment" msgstr "أرسل أول شحنة لك" -#: core/views.py:18 +#: core/templates/core/terms_conditions.html:11 +msgid "Terms and Conditions not available yet." +msgstr "الشروط والأحكام غير متوفرة بعد." + +#: core/views.py:30 msgid "Parcel not found." msgstr "الطرد غير موجود." -#: core/views.py:55 +#: core/views.py:70 msgid "Only shippers can request shipments." msgstr "فقط الشاحنين يمكنهم طلب شحنات." -#: core/views.py:64 +#: core/views.py:83 msgid "Shipment requested successfully! Tracking ID: " msgstr "تم طلب الشحنة بنجاح! رقم التتبع: " -#: core/views.py:73 +#: core/views.py:93 msgid "Only car owners can accept shipments." msgstr "فقط أصحاب السيارات يمكنهم قبول الشحنات." -#: core/views.py:80 +#: core/views.py:104 msgid "You have accepted the shipment!" msgstr "لقد قبلت الشحنة!" -#: core/views.py:91 +#: core/views.py:119 msgid "Status updated successfully!" msgstr "تم تحديث الحالة بنجاح!" -#: core/templates/core/shipment_request.html:38 -msgid "Pickup Details" -msgstr "تفاصيل الاستلام" +#: core/views.py:138 +msgid "Could not initiate payment. Please try again later." +msgstr "تعذر بدء الدفع. يرجى المحاولة مرة أخرى لاحقاً." -#: core/templates/core/shipment_request.html:64 -msgid "Delivery Details" -msgstr "تفاصيل التوصيل" +#: core/views.py:157 +msgid "Payment successful! Your shipment is now active." +msgstr "تم الدفع بنجاح! شحنتك نشطة الآن." -#: core/templates/core/shipment_request.html:90 -msgid "Receiver Details" -msgstr "تفاصيل المستلم" +#: core/views.py:159 +msgid "Payment status is pending or failed. Please check your dashboard." +msgstr "حالة الدفع معلقة أو فشلت. يرجى التحقق من لوحة التحكم." -#: core/templates/core/shipment_request.html:113 -msgid "Select Governate" -msgstr "اختر المحافظة" +#: core/views.py:165 +msgid "Payment was cancelled." +msgstr "تم إلغاء الدفع." -#: core/templates/core/shipment_request.html:114 -msgid "Select City" -msgstr "اختر المدينة" +#: core/views.py:204 +msgid "Your message has been sent successfully!" +msgstr "تم إرسال رسالتك بنجاح!" -msgid "Shipping Price (OMR)" -msgstr "سعر الشحن (ر.ع)" - -msgid "Pickup Country" -msgstr "دولة الاستلام" - -msgid "Pickup Governate" -msgstr "محافظة الاستلام" - -msgid "Pickup City" -msgstr "مدينة الاستلام" - -msgid "Pickup Address (Street/Building)" -msgstr "عنوان الاستلام (الشارع/المبنى)" - -msgid "Delivery Country" -msgstr "دولة التوصيل" - -msgid "Delivery Governate" -msgstr "محافظة التوصيل" - -msgid "Delivery City" -msgstr "مدينة التوصيل" - -msgid "Delivery Address (Street/Building)" -msgstr "عنوان التوصيل (الشارع/المبنى)" - -msgid "Street/Building" -msgstr "الشارع/المبنى" \ No newline at end of file +#: core/views.py:206 +msgid "There was an error sending your message. Please try again later." +msgstr "حدث خطأ أثناء إرسال رسالتك. يرجى المحاولة مرة أخرى لاحقاً." \ No newline at end of file diff --git a/media/platform_logos/masarxlogo2.jpg b/media/platform_logos/masarxlogo2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b64665f0f710e3002bbc4e1388b177d14ef1250b GIT binary patch literal 14236 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 AO8@`> literal 0 HcmV?d00001