dem1
This commit is contained in:
parent
d457a5b75d
commit
de92a4ccc0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -42,6 +42,7 @@ SESSION_COOKIE_SECURE = True
|
||||
CSRF_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_SAMESITE = "None"
|
||||
CSRF_COOKIE_SAMESITE = "None"
|
||||
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
|
||||
@ -61,6 +62,7 @@ INSTALLED_APPS = [
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
@ -133,7 +135,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
LANGUAGE_CODE = 'en'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
@ -180,3 +182,17 @@ if EMAIL_USE_SSL:
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
LANGUAGES = [
|
||||
('en', _('English')),
|
||||
('ar', _('Arabic')),
|
||||
]
|
||||
|
||||
LOCALE_PATHS = [
|
||||
BASE_DIR / 'locale',
|
||||
]
|
||||
|
||||
MEDIA_URL = 'media/'
|
||||
MEDIA_ROOT = BASE_DIR / 'media'
|
||||
|
||||
@ -1,25 +1,10 @@
|
||||
"""
|
||||
URL configuration for config project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
|
||||
urlpatterns = [
|
||||
path('i18n/', include('django.conf.urls.i18n')),
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include("core.urls")),
|
||||
]
|
||||
@ -27,3 +12,4 @@ urlpatterns = [
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets")
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,30 @@
|
||||
from django.contrib import admin
|
||||
from .models import Profile, Truck, Shipment, Bid, Message
|
||||
|
||||
# Register your models here.
|
||||
@admin.register(Profile)
|
||||
class ProfileAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'role', 'phone_number')
|
||||
list_filter = ('role',)
|
||||
search_fields = ('user__username', 'phone_number')
|
||||
|
||||
@admin.register(Truck)
|
||||
class TruckAdmin(admin.ModelAdmin):
|
||||
list_display = ('truck_type', 'model', 'plate_no', 'owner', 'load_capacity')
|
||||
search_fields = ('plate_no', 'owner__username', 'truck_type')
|
||||
|
||||
@admin.register(Shipment)
|
||||
class ShipmentAdmin(admin.ModelAdmin):
|
||||
list_display = ('origin', 'destination', 'shipper', 'status', 'delivery_date')
|
||||
list_filter = ('status', 'delivery_date')
|
||||
search_fields = ('origin', 'destination', 'shipper__username')
|
||||
|
||||
@admin.register(Bid)
|
||||
class BidAdmin(admin.ModelAdmin):
|
||||
list_display = ('shipment', 'truck_owner', 'amount', 'status')
|
||||
list_filter = ('status',)
|
||||
search_fields = ('shipment__origin', 'shipment__destination', 'truck_owner__username')
|
||||
|
||||
@admin.register(Message)
|
||||
class MessageAdmin(admin.ModelAdmin):
|
||||
list_display = ('shipment', 'sender', 'timestamp')
|
||||
search_fields = ('content', 'sender__username')
|
||||
|
||||
26
core/migrations/0001_initial.py
Normal file
26
core/migrations/0001_initial.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-23 07:18
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('role', models.CharField(choices=[('SHIPPER', 'Shipper (Need Goods Moved)'), ('TRUCK_OWNER', 'Truck Owner (Service Provider)'), ('ADMIN', 'Administrator')], default='SHIPPER', max_length=20)),
|
||||
('phone_number', models.CharField(blank=True, max_length=20)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,76 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-23 09:01
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Shipment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(verbose_name='Goods Description')),
|
||||
('weight', models.CharField(max_length=100, verbose_name='Weight/Volume')),
|
||||
('origin', models.CharField(max_length=255, verbose_name='Origin')),
|
||||
('destination', models.CharField(max_length=255, verbose_name='Destination')),
|
||||
('delivery_date', models.DateField(verbose_name='Requested Delivery Date')),
|
||||
('status', models.CharField(choices=[('OPEN', 'Open for Bids'), ('IN_PROGRESS', 'In Progress'), ('COMPLETED', 'Completed'), ('CANCELLED', 'Cancelled')], default='OPEN', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('shipper', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shipments', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Message',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('content', models.TextField()),
|
||||
('timestamp', models.DateTimeField(auto_now_add=True)),
|
||||
('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_messages', to=settings.AUTH_USER_MODEL)),
|
||||
('shipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='core.shipment')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Truck',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('truck_type', models.CharField(max_length=100, verbose_name='Truck Type')),
|
||||
('model', models.CharField(max_length=100, verbose_name='Model')),
|
||||
('year', models.PositiveIntegerField(verbose_name='Year')),
|
||||
('plate_no', models.CharField(max_length=50, verbose_name='Plate No')),
|
||||
('load_capacity', models.CharField(max_length=100, verbose_name='Load Capacity')),
|
||||
('color', models.CharField(max_length=50, verbose_name='Color')),
|
||||
('truck_picture', models.ImageField(blank=True, null=True, upload_to='trucks/', verbose_name='Truck Picture')),
|
||||
('registration_front', models.ImageField(blank=True, null=True, upload_to='docs/', verbose_name='Registration Front')),
|
||||
('registration_back', models.ImageField(blank=True, null=True, upload_to='docs/', verbose_name='Registration Back')),
|
||||
('driver_license', models.ImageField(blank=True, null=True, upload_to='docs/', verbose_name='Driver License')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trucks', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shipment',
|
||||
name='assigned_truck',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assigned_shipments', to='core.truck'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Bid',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('amount', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Offer Amount')),
|
||||
('comments', models.TextField(blank=True, verbose_name='Comments')),
|
||||
('status', models.CharField(choices=[('PENDING', 'Pending'), ('ACCEPTED', 'Accepted'), ('REJECTED', 'Rejected')], default='PENDING', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('truck_owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bids', to=settings.AUTH_USER_MODEL)),
|
||||
('shipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bids', to='core.shipment')),
|
||||
('truck', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.truck')),
|
||||
],
|
||||
),
|
||||
]
|
||||
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,99 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Create your models here.
|
||||
class Profile(models.Model):
|
||||
ROLE_CHOICES = (
|
||||
('SHIPPER', _('Shipper (Need Goods Moved)')),
|
||||
('TRUCK_OWNER', _('Truck Owner (Service Provider)')),
|
||||
('ADMIN', _('Administrator')),
|
||||
)
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='SHIPPER')
|
||||
phone_number = models.CharField(max_length=20, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username} - {self.role}"
|
||||
|
||||
class Truck(models.Model):
|
||||
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='trucks')
|
||||
truck_type = models.CharField(_('Truck Type'), max_length=100)
|
||||
model = models.CharField(_('Model'), max_length=100)
|
||||
year = models.PositiveIntegerField(_('Year'))
|
||||
plate_no = models.CharField(_('Plate No'), max_length=50)
|
||||
load_capacity = models.CharField(_('Load Capacity'), max_length=100)
|
||||
color = models.CharField(_('Color'), max_length=50)
|
||||
|
||||
# Pictures
|
||||
truck_picture = models.ImageField(_('Truck Picture'), upload_to='trucks/', blank=True, null=True)
|
||||
registration_front = models.ImageField(_('Registration Front'), upload_to='docs/', blank=True, null=True)
|
||||
registration_back = models.ImageField(_('Registration Back'), upload_to='docs/', blank=True, null=True)
|
||||
driver_license = models.ImageField(_('Driver License'), upload_to='docs/', blank=True, null=True)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.truck_type} - {self.plate_no}"
|
||||
|
||||
class Shipment(models.Model):
|
||||
STATUS_CHOICES = (
|
||||
('OPEN', _('Open for Bids')),
|
||||
('IN_PROGRESS', _('In Progress')),
|
||||
('COMPLETED', _('Completed')),
|
||||
('CANCELLED', _('Cancelled')),
|
||||
)
|
||||
shipper = models.ForeignKey(User, on_delete=models.CASCADE, related_name='shipments')
|
||||
description = models.TextField(_('Goods Description'))
|
||||
weight = models.CharField(_('Weight/Volume'), max_length=100)
|
||||
origin = models.CharField(_('Origin'), max_length=255)
|
||||
destination = models.CharField(_('Destination'), max_length=255)
|
||||
delivery_date = models.DateField(_('Requested Delivery Date'))
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='OPEN')
|
||||
|
||||
assigned_truck = models.ForeignKey(Truck, on_delete=models.SET_NULL, null=True, blank=True, related_name='assigned_shipments')
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.origin} to {self.destination} - {self.status}"
|
||||
|
||||
class Bid(models.Model):
|
||||
STATUS_CHOICES = (
|
||||
('PENDING', _('Pending')),
|
||||
('ACCEPTED', _('Accepted')),
|
||||
('REJECTED', _('Rejected')),
|
||||
)
|
||||
shipment = models.ForeignKey(Shipment, on_delete=models.CASCADE, related_name='bids')
|
||||
truck_owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bids')
|
||||
truck = models.ForeignKey(Truck, on_delete=models.CASCADE)
|
||||
amount = models.DecimalField(_('Offer Amount'), max_digits=10, decimal_places=2)
|
||||
comments = models.TextField(_('Comments'), blank=True)
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING')
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Bid by {self.truck_owner.username} for {self.shipment}"
|
||||
|
||||
class Message(models.Model):
|
||||
shipment = models.ForeignKey(Shipment, on_delete=models.CASCADE, related_name='messages')
|
||||
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_messages')
|
||||
content = models.TextField()
|
||||
timestamp = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"From {self.sender.username} at {self.timestamp}"
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def create_user_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
Profile.objects.create(user=instance)
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def save_user_profile(sender, instance, **kwargs):
|
||||
if hasattr(instance, 'profile'):
|
||||
instance.profile.save()
|
||||
else:
|
||||
Profile.objects.create(user=instance)
|
||||
|
||||
@ -1,25 +1,156 @@
|
||||
{% load static i18n %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="{{ request.LANGUAGE_CODE }}" {% if request.LANGUAGE_CODE == 'ar' %}dir="rtl"{% endif %}>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Knowledge Base{% endblock %}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}MASAR CARGO{% endblock %}</title>
|
||||
{% if project_description %}
|
||||
<meta name="description" content="{{ project_description }}">
|
||||
<meta property="og:description" content="{{ project_description }}">
|
||||
<meta property="twitter:description" content="{{ project_description }}">
|
||||
{% endif %}
|
||||
{% if project_image_url %}
|
||||
<meta property="og:image" content="{{ project_image_url }}">
|
||||
<meta property="twitter:image" content="{{ project_image_url }}">
|
||||
|
||||
<!-- Bootstrap 5 CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
{% if request.LANGUAGE_CODE == 'ar' %}
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.rtl.min.css">
|
||||
{% endif %}
|
||||
{% load static %}
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||
{% block head %}{% endblock %}
|
||||
<style>
|
||||
body { font-family: 'Outfit', sans-serif; background-color: #f8f9fa; }
|
||||
{% if request.LANGUAGE_CODE == 'ar' %}
|
||||
body { font-family: 'Cairo', sans-serif; }
|
||||
{% endif %}
|
||||
.navbar { background-color: #0A1D37; }
|
||||
.navbar-brand, .nav-link { color: #fff !important; }
|
||||
.btn-primary { background-color: #2196F3; border-color: #2196F3; }
|
||||
footer { background-color: #0A1D37; color: #fff; padding: 3rem 0; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
<nav class="navbar navbar-expand-lg sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">
|
||||
<i class="fa-solid fa-truck-fast me-2 text-info"></i> MASAR CARGO
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto align-items-center">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'dashboard' %}">{% trans "Dashboard" %}</a>
|
||||
</li>
|
||||
{% if user.profile.role == 'TRUCK_OWNER' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'marketplace' %}">{% trans "Marketplace" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item dropdown ms-lg-3">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="langDropdown" role="button" data-bs-toggle="dropdown">
|
||||
<i class="fa-solid fa-globe me-1"></i> {{ request.LANGUAGE_CODE|upper }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<form action="{% url 'set_language' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="{{ request.path }}">
|
||||
<input name="language" type="hidden" value="en">
|
||||
<button type="submit" class="dropdown-item">English</button>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
<form action="{% url 'set_language' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="{{ request.path }}">
|
||||
<input name="language" type="hidden" value="ar">
|
||||
<button type="submit" class="dropdown-item">العربية</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item dropdown ms-lg-3">
|
||||
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
|
||||
<i class="fa-solid fa-user-circle me-1"></i> {{ user.username }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<form action="{% url 'logout' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="dropdown-item">{% trans "Logout" %}</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item ms-lg-3">
|
||||
<a class="nav-link" href="{% url 'login' %}">{% trans "Login" %}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="btn btn-primary" href="{% url 'register' %}">{% trans "Get Started" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% if messages %}
|
||||
<div class="container mt-3">
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<h4 class="fw-bold">MASAR CARGO</h4>
|
||||
<p class="text-white-50">{% trans "Empowering logistics with smart technology. Locally and abroad." %}</p>
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<h5 class="fw-bold">{% trans "Quick Links" %}</h5>
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="#" class="text-white-50 text-decoration-none">{% trans "Privacy Policy" %}</a></li>
|
||||
<li><a href="#" class="text-white-50 text-decoration-none">{% trans "Terms of Service" %}</a></li>
|
||||
<li><a href="#" class="text-white-50 text-decoration-none">{% trans "Contact Us" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<h5 class="fw-bold">{% trans "Contact" %}</h5>
|
||||
<p class="text-white-50">
|
||||
<i class="fa-brands fa-whatsapp me-2"></i> +123 456 7890<br>
|
||||
<i class="fa-solid fa-envelope me-2"></i> info@masarcargo.com
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="bg-white-50">
|
||||
<p class="text-center text-white-50 mb-0">© 2026 MASAR CARGO. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Bootstrap 5 JS Bundle -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@ -1,145 +1,142 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ project_name }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><path d='M-10 10L110 10M10 -10L10 110' stroke-width='1' stroke='rgba(255,255,255,0.05)'/></svg>");
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@keyframes bg-pan {
|
||||
0% {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2.5rem 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2.2rem, 3vw + 1.2rem, 3.2rem);
|
||||
font-weight: 700;
|
||||
margin: 0 0 1.2rem;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
.loader {
|
||||
margin: 1.5rem auto;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: 4px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.runtime code {
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
padding: 0.15rem 0.45rem;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.75;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block content %}
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your app…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
<!-- Hero Section -->
|
||||
<section class="hero-section py-5">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-6 mb-5 mb-lg-0">
|
||||
<h1 class="hero-title display-4 fw-bold mb-4">
|
||||
{% trans "Smart Cargo Solutions" %}<br>
|
||||
<span class="text-primary">{% trans "Locally & Abroad" %}</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle lead text-muted mb-4">
|
||||
{% trans "The most reliable platform connecting shippers with truck owners across the region. Transparent, fast, and secure." %}
|
||||
</p>
|
||||
<div class="d-flex gap-3">
|
||||
<a href="{% url 'register' %}" class="btn btn-primary btn-lg px-4">{% trans "Start Shipping" %}</a>
|
||||
<a href="#how-it-works" class="btn btn-outline-primary btn-lg px-4">{% trans "Learn More" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<img src="https://img.freepik.com/free-vector/delivery-truck-with-packages-concept_23-2148464601.jpg" alt="Logistics" class="img-fluid rounded-4 shadow-lg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="hint">AppWizzy AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will refresh automatically as the plan is implemented.</p>
|
||||
<p class="runtime">
|
||||
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code>
|
||||
— UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC)
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<!-- Role Selection Section -->
|
||||
<section class="py-5 bg-light" id="how-it-works">
|
||||
<div class="container py-5">
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="fw-bold text-primary">{% trans "How would you like to use MASAR?" %}</h2>
|
||||
<p class="text-muted">{% trans "Choose your path to get started with our platform." %}</p>
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<!-- Shipper Role -->
|
||||
<div class="col-md-6">
|
||||
<div class="card h-100 border-0 shadow-sm p-4 text-center">
|
||||
<div class="mb-4">
|
||||
<i class="fa-solid fa-box-open fa-3x text-primary"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold">{% trans "I am a Shipper" %}</h3>
|
||||
<p class="text-muted">
|
||||
{% trans "I need to move goods locally or abroad. Post your shipment, receive offers from verified drivers, and track your cargo in real-time." %}
|
||||
</p>
|
||||
<ul class="list-unstyled text-start mb-4 mx-auto" style="max-width: 300px;">
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Post shipments easily" %}</li>
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Compare competitive bids" %}</li>
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Real-time tracking" %}</li>
|
||||
</ul>
|
||||
<a href="{% url 'register' %}" class="btn btn-primary w-100 py-3">{% trans "Find a Truck" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Truck Owner Role -->
|
||||
<div class="col-md-6">
|
||||
<div class="card h-100 border-0 shadow-sm p-4 text-center">
|
||||
<div class="mb-4">
|
||||
<i class="fa-solid fa-truck fa-3x text-primary"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold">{% trans "I am a Truck Owner" %}</h3>
|
||||
<p class="text-muted">
|
||||
{% trans "I have trucks and want to find cargo to transport. Register your fleet, bid on available jobs, and grow your business." %}
|
||||
</p>
|
||||
<ul class="list-unstyled text-start mb-4 mx-auto" style="max-width: 300px;">
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Access daily cargo leads" %}</li>
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Flexible bidding system" %}</li>
|
||||
<li><i class="fa-solid fa-check text-success me-2"></i> {% trans "Direct chat with shippers" %}</li>
|
||||
</ul>
|
||||
<a href="{% url 'register' %}" class="btn btn-primary w-100 py-3">{% trans "Register Your Truck" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section class="bg-white py-5" id="features">
|
||||
<div class="container py-5">
|
||||
<div class="row g-5 align-items-center">
|
||||
<div class="col-lg-5">
|
||||
<h2 class="fw-bold mb-4">{% trans "Everything you need for seamless logistics" %}</h2>
|
||||
<div class="d-flex mb-4">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="bg-light p-3 rounded-3 text-primary">
|
||||
<i class="fa-brands fa-whatsapp fa-2x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-4">
|
||||
<h5 class="fw-bold">{% trans "WhatsApp Integration" %}</h5>
|
||||
<p class="text-muted">{% trans "Receive instant updates and communicate easily via WhatsApp API." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex mb-4">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="bg-light p-3 rounded-3 text-primary">
|
||||
<i class="fa-solid fa-language fa-2x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-4">
|
||||
<h5 class="fw-bold">{% trans "Multilingual Support" %}</h5>
|
||||
<p class="text-muted">{% trans "Fully accessible in both Arabic and English for all users." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="bg-light p-3 rounded-3 text-primary">
|
||||
<i class="fa-solid fa-shield-halved fa-2x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-4">
|
||||
<h5 class="fw-bold">{% trans "Secure Documentation" %}</h5>
|
||||
<p class="text-muted">{% trans "Digital verification of truck registration and driver licenses." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-7">
|
||||
<div class="row g-4">
|
||||
<div class="col-6">
|
||||
<img src="https://img.freepik.com/free-photo/view-truck-with-cargo_23-2150821510.jpg" class="img-fluid rounded-4 shadow" alt="">
|
||||
</div>
|
||||
<div class="col-6 mt-5">
|
||||
<img src="https://img.freepik.com/free-photo/industrial-port-container-yard-with-cranes-logistic-import-export-business-logistics-background_35641-2693.jpg" class="img-fluid rounded-4 shadow" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Call to Action -->
|
||||
<section class="py-5">
|
||||
<div class="container">
|
||||
<div class="bg-primary text-white p-5 rounded-5 text-center shadow-lg">
|
||||
<h2 class="fw-bold mb-3">{% trans "Ready to move your cargo?" %}</h2>
|
||||
<p class="mb-4 opacity-75">{% trans "Join thousands of shippers and drivers on MASAR today." %}</p>
|
||||
<a href="{% url 'register' %}" class="btn btn-light btn-lg px-5 rounded-pill fw-bold text-primary">{% trans "Join Now" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
39
core/templates/core/marketplace.html
Normal file
39
core/templates/core/marketplace.html
Normal file
@ -0,0 +1,39 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<h2 class="mb-4">{% trans "Shipment Marketplace" %}</h2>
|
||||
<div class="row">
|
||||
{% for shipment in shipments %}
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm h-100 border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="badge bg-primary">{% trans "Open for Bids" %}</span>
|
||||
<small class="text-muted">{{ shipment.created_at|timesince }} {% trans "ago" %}</small>
|
||||
</div>
|
||||
<h5 class="card-title">{{ shipment.origin }} <i class="fa-solid fa-arrow-right mx-2"></i> {{ shipment.destination }}</h5>
|
||||
<p class="card-text text-muted">{{ shipment.description|truncatechars:100 }}</p>
|
||||
<div class="d-flex gap-4 mb-3">
|
||||
<div>
|
||||
<small class="text-muted d-block">{% trans "Weight" %}</small>
|
||||
<strong>{{ shipment.weight }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<small class="text-muted d-block">{% trans "Delivery Date" %}</small>
|
||||
<strong>{{ shipment.delivery_date }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{% url 'place_bid' shipment.id %}" class="btn btn-outline-primary w-100">{% trans "Place an Offer" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col-12 text-center py-5">
|
||||
<p class="lead text-muted">{% trans "No shipments available at the moment." %}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
51
core/templates/core/place_bid.html
Normal file
51
core/templates/core/place_bid.html
Normal file
@ -0,0 +1,51 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4">{% trans "Place an Offer" %}</h2>
|
||||
<div class="alert alert-info mb-4">
|
||||
<strong>{% trans "Shipment:" %}</strong> {{ shipment.origin }} to {{ shipment.destination }}<br>
|
||||
<strong>{% trans "Goods:" %}</strong> {{ shipment.description }}
|
||||
</div>
|
||||
|
||||
{% if trucks %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Select Truck" %}</label>
|
||||
<select name="truck" class="form-select" required>
|
||||
{% for truck in trucks %}
|
||||
<option value="{{ truck.id }}">{{ truck.truck_type }} - {{ truck.plate_no }} ({{ truck.load_capacity }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Your Offer Amount" %}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" name="amount" class="form-control" step="0.01" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Comments/Conditions" %}</label>
|
||||
<textarea name="comments" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3">{% trans "Submit Offer" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<p class="text-danger">{% trans "You must register a truck before placing a bid." %}</p>
|
||||
<a href="{% url 'truck_register' %}" class="btn btn-success">{% trans "Register Truck Now" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
42
core/templates/core/post_shipment.html
Normal file
42
core/templates/core/post_shipment.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4">{% trans "Post a New Shipment" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Goods Description" %}</label>
|
||||
<textarea name="description" class="form-control" rows="4" placeholder="{% trans 'What are you moving? (e.g. 500 boxes of food)' %}" required></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Weight/Volume" %}</label>
|
||||
<input type="text" name="weight" class="form-control" placeholder="e.g. 5 Tons" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Origin" %}</label>
|
||||
<input type="text" name="origin" class="form-control" placeholder="{% trans 'City, Country' %}" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Destination" %}</label>
|
||||
<input type="text" name="destination" class="form-control" placeholder="{% trans 'City, Country' %}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Requested Delivery Date" %}</label>
|
||||
<input type="date" name="delivery_date" class="form-control" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3 mt-4">{% trans "Post Shipment" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
101
core/templates/core/shipment_detail.html
Normal file
101
core/templates/core/shipment_detail.html
Normal file
@ -0,0 +1,101 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">{{ shipment.origin }} <i class="fa-solid fa-arrow-right mx-2"></i> {{ shipment.destination }}</h2>
|
||||
<span class="badge {% if shipment.status == 'OPEN' %}bg-primary{% elif shipment.status == 'IN_PROGRESS' %}bg-warning{% else %}bg-success{% endif %} fs-6">
|
||||
{{ shipment.get_status_display }}
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
||||
<h5>{% trans "Details" %}</h5>
|
||||
<p>{{ shipment.description }}</p>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<small class="text-muted d-block">{% trans "Weight" %}</small>
|
||||
<strong>{{ shipment.weight }}</strong>
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<small class="text-muted d-block">{% trans "Delivery Date" %}</small>
|
||||
<strong>{{ shipment.delivery_date }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user == shipment.shipper and shipment.status == 'OPEN' %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">{% trans "Received Bids" %}</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Truck Owner" %}</th>
|
||||
<th>{% trans "Truck" %}</th>
|
||||
<th>{% trans "Amount" %}</th>
|
||||
<th>{% trans "Action" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bid in bids %}
|
||||
<tr>
|
||||
<td>{{ bid.truck_owner.username }}</td>
|
||||
<td>{{ bid.truck.truck_type }}</td>
|
||||
<td>${{ bid.amount }}</td>
|
||||
<td>
|
||||
<a href="{% url 'accept_bid' bid.id %}" class="btn btn-sm btn-success">{% trans "Accept" %}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-4 text-muted">{% trans "No bids received yet." %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if shipment.status == 'IN_PROGRESS' %}
|
||||
<div class="alert alert-success d-flex align-items-center">
|
||||
<i class="fa-solid fa-truck-moving fa-2x me-3"></i>
|
||||
<div>
|
||||
<strong>{% trans "Shipment in progress!" %}</strong><br>
|
||||
{% trans "Assigned Truck:" %} {{ shipment.assigned_truck.truck_type }} ({{ shipment.assigned_truck.plate_no }})
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a href="https://wa.me/{{ shipment.assigned_truck.owner.profile.phone_number }}" class="btn btn-success btn-lg">
|
||||
<i class="fa-brands fa-whatsapp me-2"></i> {% trans "Contact Driver on WhatsApp" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5>{% trans "Contact Information" %}</h5>
|
||||
<p>
|
||||
<strong>{% trans "Shipper:" %}</strong> {{ shipment.shipper.username }}<br>
|
||||
{% if shipment.status == 'IN_PROGRESS' %}
|
||||
<strong>{% trans "Phone:" %}</strong> {{ shipment.shipper.profile.phone_number }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
61
core/templates/core/shipper_dashboard.html
Normal file
61
core/templates/core/shipper_dashboard.html
Normal file
@ -0,0 +1,61 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>{% trans "Shipper Dashboard" %}</h2>
|
||||
<a href="{% url 'post_shipment' %}" class="btn btn-success">
|
||||
<i class="fa-solid fa-plus me-2"></i> {% trans "Post New Shipment" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">{% trans "My Shipments" %}</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<th>{% trans "Route" %}</th>
|
||||
<th>{% trans "Delivery Date" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th>{% trans "Bids" %}</th>
|
||||
<th>{% trans "Action" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for shipment in shipments %}
|
||||
<tr>
|
||||
<td>{{ shipment.description|truncatechars:30 }}</td>
|
||||
<td>{{ shipment.origin }} <i class="fa-solid fa-arrow-right mx-1"></i> {{ shipment.destination }}</td>
|
||||
<td>{{ shipment.delivery_date }}</td>
|
||||
<td>
|
||||
<span class="badge {% if shipment.status == 'OPEN' %}bg-primary{% elif shipment.status == 'IN_PROGRESS' %}bg-warning{% else %}bg-success{% endif %}">
|
||||
{{ shipment.get_status_display }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ shipment.bids.count }}</td>
|
||||
<td>
|
||||
<a href="{% url 'shipment_detail' shipment.id %}" class="btn btn-sm btn-outline-primary">{% trans "View Details" %}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-4">{% trans "No shipments posted yet." %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
79
core/templates/core/truck_owner_dashboard.html
Normal file
79
core/templates/core/truck_owner_dashboard.html
Normal file
@ -0,0 +1,79 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>{% trans "Truck Owner Dashboard" %}</h2>
|
||||
<div>
|
||||
<a href="{% url 'marketplace' %}" class="btn btn-primary me-2">
|
||||
<i class="fa-solid fa-search me-2"></i> {% trans "Find Shipments" %}
|
||||
</a>
|
||||
<a href="{% url 'truck_register' %}" class="btn btn-success">
|
||||
<i class="fa-solid fa-plus me-2"></i> {% trans "Register Truck" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">{% trans "My Trucks" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if trucks %}
|
||||
<ul class="list-group list-group-flush">
|
||||
{% for truck in trucks %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ truck.truck_type }} - {{ truck.plate_no }}
|
||||
<span class="badge bg-secondary">{{ truck.load_capacity }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="text-center py-3">{% trans "No trucks registered." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">{% trans "My Active Bids" %}</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Shipment" %}</th>
|
||||
<th>{% trans "Amount" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bid in bids %}
|
||||
<tr>
|
||||
<td>{{ bid.shipment.origin }} - {{ bid.shipment.destination }}</td>
|
||||
<td>{{ bid.amount }}</td>
|
||||
<td>
|
||||
<span class="badge {% if bid.status == 'PENDING' %}bg-warning{% elif bid.status == 'ACCEPTED' %}bg-success{% else %}bg-danger{% endif %}">
|
||||
{{ bid.get_status_display }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center py-3">{% trans "No bids placed." %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
73
core/templates/core/truck_register.html
Normal file
73
core/templates/core/truck_register.html
Normal file
@ -0,0 +1,73 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4">{% trans "Register a Truck" %}</h2>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Truck Type" %}</label>
|
||||
<input type="text" name="truck_type" class="form-control" placeholder="e.g. Flatbed, Trailer" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Model" %}</label>
|
||||
<input type="text" name="model" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">{% trans "Year" %}</label>
|
||||
<input type="number" name="year" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">{% trans "Plate No" %}</label>
|
||||
<input type="text" name="plate_no" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">{% trans "Color" %}</label>
|
||||
<input type="text" name="color" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Load Capacity (e.g. 20 Tons)" %}</label>
|
||||
<input type="text" name="load_capacity" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
<h5>{% trans "Documents & Photos" %}</h5>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Truck Picture" %}</label>
|
||||
<input type="file" name="truck_picture" class="form-control" accept="image/*">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Driver License" %}</label>
|
||||
<input type="file" name="driver_license" class="form-control" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Registration (Front Face)" %}</label>
|
||||
<input type="file" name="registration_front" class="form-control" accept="image/*">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">{% trans "Registration (Back Face)" %}</label>
|
||||
<input type="file" name="registration_back" class="form-control" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100 py-3 mt-4">{% trans "Submit Registration" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
core/templates/registration/login.html
Normal file
33
core/templates/registration/login.html
Normal file
@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<section class="py-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-5">
|
||||
<div class="card shadow">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="text-center mb-4">{% trans "Login" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Username" %}</label>
|
||||
<input type="text" name="username" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Password" %}</label>
|
||||
<input type="password" name="password" class="form-control" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-2">{% trans "Login" %}</button>
|
||||
</form>
|
||||
<div class="text-center mt-3">
|
||||
<p>{% trans "Don't have an account?" %} <a href="{% url 'register' %}">{% trans "Register" %}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
40
core/templates/registration/register.html
Normal file
40
core/templates/registration/register.html
Normal file
@ -0,0 +1,40 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<section class="py-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="text-center mb-4">{% trans "Create your account" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "I am a:" %}</label>
|
||||
<select name="role" class="form-select" required>
|
||||
<option value="SHIPPER">{% trans "Shipper (Need Goods Moved)" %}</option>
|
||||
<option value="TRUCK_OWNER">{% trans "Truck Owner (Service Provider)" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{% trans "Phone Number" %}</label>
|
||||
<input type="text" name="phone_number" class="form-control" placeholder="+1234567890">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100 py-2">{% trans "Register" %}</button>
|
||||
</form>
|
||||
<div class="text-center mt-3">
|
||||
<p>{% trans "Already have an account?" %} <a href="{% url 'login' %}">{% trans "Login" %}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
18
core/urls.py
18
core/urls.py
@ -1,7 +1,17 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import home
|
||||
from django.contrib.auth import views as auth_views
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", home, name="home"),
|
||||
]
|
||||
path("", views.home, name="home"),
|
||||
path("register/", views.register, name="register"),
|
||||
path("login/", auth_views.LoginView.as_view(), name="login"),
|
||||
path("logout/", auth_views.LogoutView.as_view(), name="logout"),
|
||||
path("dashboard/", views.dashboard, name="dashboard"),
|
||||
path("truck/register/", views.truck_register, name="truck_register"),
|
||||
path("shipment/post/", views.post_shipment, name="post_shipment"),
|
||||
path("marketplace/", views.marketplace, name="marketplace"),
|
||||
path("shipment/<int:shipment_id>/", views.shipment_detail, name="shipment_detail"),
|
||||
path("shipment/<int:shipment_id>/bid/", views.place_bid, name="place_bid"),
|
||||
path("bid/<int:bid_id>/accept/", views.accept_bid, name="accept_bid"),
|
||||
]
|
||||
185
core/views.py
185
core/views.py
@ -1,25 +1,172 @@
|
||||
import os
|
||||
import platform
|
||||
|
||||
from django import get_version as django_version
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import login, authenticate
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import Profile, Truck, Shipment, Bid, Message
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import gettext as _
|
||||
from django.db.models import Q
|
||||
|
||||
def home(request):
|
||||
"""Render the landing screen with loader and environment details."""
|
||||
host_name = request.get_host().lower()
|
||||
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
|
||||
now = timezone.now()
|
||||
|
||||
"""Render the landing screen for MASAR CARGO."""
|
||||
if request.user.is_authenticated:
|
||||
return redirect('dashboard')
|
||||
context = {
|
||||
"project_name": "New Style",
|
||||
"agent_brand": agent_brand,
|
||||
"django_version": django_version(),
|
||||
"python_version": platform.python_version(),
|
||||
"current_time": now,
|
||||
"host_name": host_name,
|
||||
"project_description": os.getenv("PROJECT_DESCRIPTION", ""),
|
||||
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
|
||||
"deployment_timestamp": timezone.now().timestamp(),
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
def register(request):
|
||||
if request.method == 'POST':
|
||||
form = UserCreationForm(request.POST)
|
||||
role = request.POST.get('role')
|
||||
phone = request.POST.get('phone_number')
|
||||
if form.is_valid():
|
||||
user = form.save()
|
||||
profile = user.profile
|
||||
profile.role = role
|
||||
profile.phone_number = phone
|
||||
profile.save()
|
||||
login(request, user)
|
||||
return redirect('dashboard')
|
||||
else:
|
||||
form = UserCreationForm()
|
||||
return render(request, 'registration/register.html', {'form': form})
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
profile = request.user.profile
|
||||
if profile.role == 'SHIPPER':
|
||||
my_shipments = Shipment.objects.filter(shipper=request.user).order_by('-created_at')
|
||||
return render(request, 'core/shipper_dashboard.html', {'shipments': my_shipments})
|
||||
elif profile.role == 'TRUCK_OWNER':
|
||||
my_trucks = Truck.objects.filter(owner=request.user)
|
||||
my_bids = Bid.objects.filter(truck_owner=request.user).order_by('-created_at')
|
||||
return render(request, 'core/truck_owner_dashboard.html', {
|
||||
'trucks': my_trucks,
|
||||
'bids': my_bids
|
||||
})
|
||||
else:
|
||||
return redirect('/admin/')
|
||||
|
||||
@login_required
|
||||
def truck_register(request):
|
||||
if request.user.profile.role != 'TRUCK_OWNER':
|
||||
return redirect('dashboard')
|
||||
|
||||
if request.method == 'POST':
|
||||
truck_type = request.POST.get('truck_type')
|
||||
model = request.POST.get('model')
|
||||
year = request.POST.get('year')
|
||||
plate_no = request.POST.get('plate_no')
|
||||
load_capacity = request.POST.get('load_capacity')
|
||||
color = request.POST.get('color')
|
||||
|
||||
truck = Truck.objects.create(
|
||||
owner=request.user,
|
||||
truck_type=truck_type,
|
||||
model=model,
|
||||
year=year,
|
||||
plate_no=plate_no,
|
||||
load_capacity=load_capacity,
|
||||
color=color,
|
||||
truck_picture=request.FILES.get('truck_picture'),
|
||||
registration_front=request.FILES.get('registration_front'),
|
||||
registration_back=request.FILES.get('registration_back'),
|
||||
driver_license=request.FILES.get('driver_license')
|
||||
)
|
||||
messages.success(request, _("Truck registered successfully!"))
|
||||
return redirect('dashboard')
|
||||
|
||||
return render(request, 'core/truck_register.html')
|
||||
|
||||
@login_required
|
||||
def post_shipment(request):
|
||||
if request.user.profile.role != 'SHIPPER':
|
||||
return redirect('dashboard')
|
||||
|
||||
if request.method == 'POST':
|
||||
description = request.POST.get('description')
|
||||
weight = request.POST.get('weight')
|
||||
origin = request.POST.get('origin')
|
||||
destination = request.POST.get('destination')
|
||||
delivery_date = request.POST.get('delivery_date')
|
||||
|
||||
Shipment.objects.create(
|
||||
shipper=request.user,
|
||||
description=description,
|
||||
weight=weight,
|
||||
origin=origin,
|
||||
destination=destination,
|
||||
delivery_date=delivery_date
|
||||
)
|
||||
messages.success(request, _("Shipment posted successfully!"))
|
||||
return redirect('dashboard')
|
||||
|
||||
return render(request, 'core/post_shipment.html')
|
||||
|
||||
@login_required
|
||||
def marketplace(request):
|
||||
if request.user.profile.role != 'TRUCK_OWNER':
|
||||
return redirect('dashboard')
|
||||
|
||||
shipments = Shipment.objects.filter(status='OPEN').order_by('-created_at')
|
||||
return render(request, 'core/marketplace.html', {'shipments': shipments})
|
||||
|
||||
@login_required
|
||||
def place_bid(request, shipment_id):
|
||||
shipment = get_object_or_404(Shipment, id=shipment_id)
|
||||
if request.user.profile.role != 'TRUCK_OWNER':
|
||||
return redirect('dashboard')
|
||||
|
||||
my_trucks = Truck.objects.filter(owner=request.user)
|
||||
if request.method == 'POST':
|
||||
truck_id = request.POST.get('truck')
|
||||
amount = request.POST.get('amount')
|
||||
comments = request.POST.get('comments')
|
||||
|
||||
truck = get_object_or_404(Truck, id=truck_id, owner=request.user)
|
||||
Bid.objects.create(
|
||||
shipment=shipment,
|
||||
truck_owner=request.user,
|
||||
truck=truck,
|
||||
amount=amount,
|
||||
comments=comments
|
||||
)
|
||||
messages.success(request, _("Bid placed successfully!"))
|
||||
return redirect('marketplace')
|
||||
|
||||
return render(request, 'core/place_bid.html', {'shipment': shipment, 'trucks': my_trucks})
|
||||
|
||||
@login_required
|
||||
def shipment_detail(request, shipment_id):
|
||||
shipment = get_object_or_404(Shipment, id=shipment_id)
|
||||
# Security: check if user is shipper or a truck owner who bid
|
||||
if shipment.shipper != request.user and not Bid.objects.filter(shipment=shipment, truck_owner=request.user).exists():
|
||||
if request.user.profile.role != 'ADMIN':
|
||||
return redirect('dashboard')
|
||||
|
||||
bids = shipment.bids.all()
|
||||
return render(request, 'core/shipment_detail.html', {'shipment': shipment, 'bids': bids})
|
||||
|
||||
@login_required
|
||||
def accept_bid(request, bid_id):
|
||||
bid = get_object_or_404(Bid, id=bid_id)
|
||||
if bid.shipment.shipper != request.user:
|
||||
return redirect('dashboard')
|
||||
|
||||
# Accept this bid
|
||||
bid.status = 'ACCEPTED'
|
||||
bid.save()
|
||||
|
||||
# Reject others
|
||||
bid.shipment.bids.exclude(id=bid_id).update(status='REJECTED')
|
||||
|
||||
# Update shipment
|
||||
bid.shipment.status = 'IN_PROGRESS'
|
||||
bid.shipment.assigned_truck = bid.truck
|
||||
bid.shipment.save()
|
||||
|
||||
messages.success(request, _("Bid accepted! Shipment is now in progress."))
|
||||
return redirect('shipment_detail', shipment_id=bid.shipment.id)
|
||||
|
||||
BIN
locale/ar/LC_MESSAGES/django.mo
Normal file
BIN
locale/ar/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
619
locale/ar/LC_MESSAGES/django.po
Normal file
619
locale/ar/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,619 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-23 09:04+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: ar\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
|
||||
#: config/settings.py:188
|
||||
msgid "English"
|
||||
msgstr "الإنجليزية"
|
||||
|
||||
#: config/settings.py:189
|
||||
msgid "Arabic"
|
||||
msgstr "العربية"
|
||||
|
||||
#: core/models.py:9 core/templates/registration/register.html:19
|
||||
msgid "Shipper (Need Goods Moved)"
|
||||
msgstr "شاحن (بحاجة لنقل بضائع)"
|
||||
|
||||
#: core/models.py:10 core/templates/registration/register.html:20
|
||||
msgid "Truck Owner (Service Provider)"
|
||||
msgstr "صاحب شاحنة (مزود خدمة)"
|
||||
|
||||
#: core/models.py:11
|
||||
msgid "Administrator"
|
||||
msgstr "مدير النظام"
|
||||
|
||||
#: core/models.py:22 core/templates/core/truck_register.html:15
|
||||
msgid "Truck Type"
|
||||
msgstr "نوع الشاحنة"
|
||||
|
||||
#: core/models.py:23 core/templates/core/truck_register.html:19
|
||||
msgid "Model"
|
||||
msgstr "الموديل"
|
||||
|
||||
#: core/models.py:24 core/templates/core/truck_register.html:25
|
||||
msgid "Year"
|
||||
msgstr "السنة"
|
||||
|
||||
#: core/models.py:25 core/templates/core/truck_register.html:29
|
||||
msgid "Plate No"
|
||||
msgstr "رقم اللوحة"
|
||||
|
||||
#: core/models.py:26
|
||||
msgid "Load Capacity"
|
||||
msgstr "حمولة الشاحنة"
|
||||
|
||||
#: core/models.py:27 core/templates/core/truck_register.html:33
|
||||
msgid "Color"
|
||||
msgstr "اللون"
|
||||
|
||||
#: core/models.py:30 core/templates/core/truck_register.html:47
|
||||
msgid "Truck Picture"
|
||||
msgstr "صورة الشاحنة"
|
||||
|
||||
#: core/models.py:31
|
||||
msgid "Registration Front"
|
||||
msgstr "التسجيل (الوجه الأمامي)"
|
||||
|
||||
#: core/models.py:32
|
||||
#, fuzzy
|
||||
#| msgid "Register Your Truck"
|
||||
msgid "Registration Back"
|
||||
msgstr "سجل شاحنتك"
|
||||
|
||||
#: core/models.py:33 core/templates/core/truck_register.html:51
|
||||
msgid "Driver License"
|
||||
msgstr "رخصة القيادة"
|
||||
|
||||
#: core/models.py:42 core/templates/core/marketplace.html:13
|
||||
msgid "Open for Bids"
|
||||
msgstr "مفتوح للعروض"
|
||||
|
||||
#: core/models.py:43
|
||||
msgid "In Progress"
|
||||
msgstr "قيد التنفيذ"
|
||||
|
||||
#: core/models.py:44
|
||||
msgid "Completed"
|
||||
msgstr "مكتمل"
|
||||
|
||||
#: core/models.py:45
|
||||
msgid "Cancelled"
|
||||
msgstr "ملغي"
|
||||
|
||||
#: core/models.py:48 core/templates/core/post_shipment.html:14
|
||||
msgid "Goods Description"
|
||||
msgstr "وصف البضائع"
|
||||
|
||||
#: core/models.py:49 core/templates/core/post_shipment.html:18
|
||||
msgid "Weight/Volume"
|
||||
msgstr "الوزن/الحجم"
|
||||
|
||||
#: core/models.py:50 core/templates/core/post_shipment.html:23
|
||||
msgid "Origin"
|
||||
msgstr "المصدر"
|
||||
|
||||
#: core/models.py:51 core/templates/core/post_shipment.html:27
|
||||
msgid "Destination"
|
||||
msgstr "الوجهة"
|
||||
|
||||
#: core/models.py:52 core/templates/core/post_shipment.html:32
|
||||
msgid "Requested Delivery Date"
|
||||
msgstr "تاريخ التسليم المطلوب"
|
||||
|
||||
#: core/models.py:64
|
||||
msgid "Pending"
|
||||
msgstr "قيد الانتظار"
|
||||
|
||||
#: core/models.py:65
|
||||
msgid "Accepted"
|
||||
msgstr "مقبول"
|
||||
|
||||
#: core/models.py:66
|
||||
msgid "Rejected"
|
||||
msgstr "مرفوض"
|
||||
|
||||
#: core/models.py:71
|
||||
msgid "Offer Amount"
|
||||
msgstr "قيمة العرض"
|
||||
|
||||
#: core/models.py:72
|
||||
msgid "Comments"
|
||||
msgstr "تعليقات"
|
||||
|
||||
#: core/templates/base.html:49
|
||||
msgid "Dashboard"
|
||||
msgstr "لوحة التحكم"
|
||||
|
||||
#: core/templates/base.html:53
|
||||
msgid "Marketplace"
|
||||
msgstr "السوق"
|
||||
|
||||
#: core/templates/base.html:91
|
||||
msgid "Logout"
|
||||
msgstr "تسجيل الخروج"
|
||||
|
||||
#: core/templates/base.html:98 core/templates/registration/login.html:11
|
||||
#: core/templates/registration/login.html:22
|
||||
#: core/templates/registration/register.html:32
|
||||
msgid "Login"
|
||||
msgstr "تسجيل الدخول"
|
||||
|
||||
#: core/templates/base.html:101
|
||||
msgid "Get Started"
|
||||
msgstr "ابدأ الآن"
|
||||
|
||||
#: core/templates/base.html:129
|
||||
msgid "Empowering logistics with smart technology. Locally and abroad."
|
||||
msgstr "تمكين الخدمات اللوجستية بتقنيات ذكية. محلياً ودولياً."
|
||||
|
||||
#: core/templates/base.html:132
|
||||
msgid "Quick Links"
|
||||
msgstr "روابط سريعة"
|
||||
|
||||
#: core/templates/base.html:134
|
||||
msgid "Privacy Policy"
|
||||
msgstr "سياسة الخصوصية"
|
||||
|
||||
#: core/templates/base.html:135
|
||||
msgid "Terms of Service"
|
||||
msgstr "شروط الخدمة"
|
||||
|
||||
#: core/templates/base.html:136
|
||||
msgid "Contact Us"
|
||||
msgstr "اتصل بنا"
|
||||
|
||||
#: core/templates/base.html:140
|
||||
msgid "Contact"
|
||||
msgstr "اتصال"
|
||||
|
||||
#: core/templates/core/index.html:11
|
||||
msgid "Smart Cargo Solutions"
|
||||
msgstr "حلول شحن ذكية"
|
||||
|
||||
#: core/templates/core/index.html:12
|
||||
msgid "Locally & Abroad"
|
||||
msgstr "محلياً ودولياً"
|
||||
|
||||
#: core/templates/core/index.html:15
|
||||
msgid ""
|
||||
"The most reliable platform connecting shippers with truck owners across the "
|
||||
"region. Transparent, fast, and secure."
|
||||
msgstr ""
|
||||
"المنصة الأكثر موثوقية لربط الشاحنين مع أصحاب الشاحنات في جميع أنحاء المنطقة. "
|
||||
"شفافة، سريعة، وآمنة."
|
||||
|
||||
#: core/templates/core/index.html:18
|
||||
msgid "Start Shipping"
|
||||
msgstr "ابدأ الشحن"
|
||||
|
||||
#: core/templates/core/index.html:19
|
||||
msgid "Learn More"
|
||||
msgstr "تعلم المزيد"
|
||||
|
||||
#: core/templates/core/index.html:33
|
||||
msgid "How would you like to use MASAR?"
|
||||
msgstr "كيف تود استخدام مسار؟"
|
||||
|
||||
#: core/templates/core/index.html:34
|
||||
msgid "Choose your path to get started with our platform."
|
||||
msgstr "اختر مسارك للبدء مع منصتنا."
|
||||
|
||||
#: core/templates/core/index.html:43
|
||||
msgid "I am a Shipper"
|
||||
msgstr "أنا شاحن"
|
||||
|
||||
#: core/templates/core/index.html:45
|
||||
msgid ""
|
||||
"I need to move goods locally or abroad. Post your shipment, receive offers "
|
||||
"from verified drivers, and track your cargo in real-time."
|
||||
msgstr ""
|
||||
"أريد نقل بضائع محلياً أو دولياً. انشر شحنتك، واستقبل عروضاً من سائقين موثقين، "
|
||||
"وتتبع شحنتك في الوقت الفعلي."
|
||||
|
||||
#: core/templates/core/index.html:48
|
||||
msgid "Post shipments easily"
|
||||
msgstr "انشر الشحنات بسهولة"
|
||||
|
||||
#: core/templates/core/index.html:49
|
||||
msgid "Compare competitive bids"
|
||||
msgstr "قارن العروض التنافسية"
|
||||
|
||||
#: core/templates/core/index.html:50
|
||||
msgid "Real-time tracking"
|
||||
msgstr "تتبع في الوقت الفعلي"
|
||||
|
||||
#: core/templates/core/index.html:52
|
||||
msgid "Find a Truck"
|
||||
msgstr "ابحث عن شاحنة"
|
||||
|
||||
#: core/templates/core/index.html:61
|
||||
msgid "I am a Truck Owner"
|
||||
msgstr "أنا صاحب شاحنة"
|
||||
|
||||
#: core/templates/core/index.html:63
|
||||
msgid ""
|
||||
"I have trucks and want to find cargo to transport. Register your fleet, bid "
|
||||
"on available jobs, and grow your business."
|
||||
msgstr ""
|
||||
"لدي شاحنات وأريد العثور على بضائع لنقلها. سجل أسطولك، وقدم عروضك على الوظائف "
|
||||
"المتاحة، ونمِ عملك."
|
||||
|
||||
#: core/templates/core/index.html:66
|
||||
msgid "Access daily cargo leads"
|
||||
msgstr "الوصول إلى فرص شحن يومية"
|
||||
|
||||
#: core/templates/core/index.html:67
|
||||
msgid "Flexible bidding system"
|
||||
msgstr "نظام عروض مرن"
|
||||
|
||||
#: core/templates/core/index.html:68
|
||||
msgid "Direct chat with shippers"
|
||||
msgstr "دردشة مباشرة مع الشاحنين"
|
||||
|
||||
#: core/templates/core/index.html:70
|
||||
msgid "Register Your Truck"
|
||||
msgstr "سجل شاحنتك"
|
||||
|
||||
#: core/templates/core/index.html:82
|
||||
msgid "Everything you need for seamless logistics"
|
||||
msgstr "كل ما تحتاجه للوجستيات سلسة"
|
||||
|
||||
#: core/templates/core/index.html:90
|
||||
msgid "WhatsApp Integration"
|
||||
msgstr "تكامل واتساب"
|
||||
|
||||
#: core/templates/core/index.html:91
|
||||
msgid "Receive instant updates and communicate easily via WhatsApp API."
|
||||
msgstr "استقبل تحديثات فورية وتواصل بسهولة عبر واجهة برمجة تطبيقات واتساب."
|
||||
|
||||
#: core/templates/core/index.html:101
|
||||
msgid "Multilingual Support"
|
||||
msgstr "دعم متعدد اللغات"
|
||||
|
||||
#: core/templates/core/index.html:102
|
||||
msgid "Fully accessible in both Arabic and English for all users."
|
||||
msgstr "متاح بالكامل باللغتين العربية والإنجليزية لجميع المستخدمين."
|
||||
|
||||
#: core/templates/core/index.html:112
|
||||
msgid "Secure Documentation"
|
||||
msgstr "توثيق آمن"
|
||||
|
||||
#: core/templates/core/index.html:113
|
||||
msgid "Digital verification of truck registration and driver licenses."
|
||||
msgstr "التحقق الرقمي من تسجيل الشاحنات ورخص القيادة."
|
||||
|
||||
#: core/templates/core/index.html:135
|
||||
msgid "Ready to move your cargo?"
|
||||
msgstr "هل أنت مستعد لنقل شحنتك؟"
|
||||
|
||||
#: core/templates/core/index.html:136
|
||||
msgid "Join thousands of shippers and drivers on MASAR today."
|
||||
msgstr "انضم إلى آلاف الشاحنين والسائقين على مسار اليوم."
|
||||
|
||||
#: core/templates/core/index.html:137
|
||||
msgid "Join Now"
|
||||
msgstr "انضم الآن"
|
||||
|
||||
#: core/templates/core/marketplace.html:6
|
||||
msgid "Shipment Marketplace"
|
||||
msgstr "سوق الشحنات"
|
||||
|
||||
#: core/templates/core/marketplace.html:14
|
||||
msgid "ago"
|
||||
msgstr "منذ"
|
||||
|
||||
#: core/templates/core/marketplace.html:20
|
||||
#: core/templates/core/shipment_detail.html:21
|
||||
msgid "Weight"
|
||||
msgstr "الوزن"
|
||||
|
||||
#: core/templates/core/marketplace.html:24
|
||||
#: core/templates/core/shipment_detail.html:25
|
||||
#: core/templates/core/shipper_dashboard.html:26
|
||||
msgid "Delivery Date"
|
||||
msgstr "تاريخ التسليم"
|
||||
|
||||
#: core/templates/core/marketplace.html:28
|
||||
#: core/templates/core/place_bid.html:10
|
||||
msgid "Place an Offer"
|
||||
msgstr "قدم عرضاً"
|
||||
|
||||
#: core/templates/core/marketplace.html:34
|
||||
msgid "No shipments available at the moment."
|
||||
msgstr "لا توجد شحنات متاحة حالياً."
|
||||
|
||||
#: core/templates/core/place_bid.html:12
|
||||
msgid "Shipment:"
|
||||
msgstr "الشحنة:"
|
||||
|
||||
#: core/templates/core/place_bid.html:13
|
||||
msgid "Goods:"
|
||||
msgstr "البضائع:"
|
||||
|
||||
#: core/templates/core/place_bid.html:20
|
||||
msgid "Select Truck"
|
||||
msgstr "اختر الشاحنة"
|
||||
|
||||
#: core/templates/core/place_bid.html:28
|
||||
msgid "Your Offer Amount"
|
||||
msgstr "مبلغ عرضك"
|
||||
|
||||
#: core/templates/core/place_bid.html:35
|
||||
msgid "Comments/Conditions"
|
||||
msgstr "التعليقات/الشروط"
|
||||
|
||||
#: core/templates/core/place_bid.html:38
|
||||
msgid "Submit Offer"
|
||||
msgstr "تقديم العرض"
|
||||
|
||||
#: core/templates/core/place_bid.html:42
|
||||
msgid "You must register a truck before placing a bid."
|
||||
msgstr "يجب عليك تسجيل شاحنة قبل تقديم عرض."
|
||||
|
||||
#: core/templates/core/place_bid.html:43
|
||||
#, fuzzy
|
||||
#| msgid "Register Your Truck"
|
||||
msgid "Register Truck Now"
|
||||
msgstr "سجل شاحنتك"
|
||||
|
||||
#: core/templates/core/post_shipment.html:10
|
||||
#, fuzzy
|
||||
#| msgid "Post shipments easily"
|
||||
msgid "Post a New Shipment"
|
||||
msgstr "انشر الشحنات بسهولة"
|
||||
|
||||
#: core/templates/core/post_shipment.html:15
|
||||
msgid "What are you moving? (e.g. 500 boxes of food)"
|
||||
msgstr "ماذا ستنقل؟ (مثال: 500 صندوق مواد غذائية)"
|
||||
|
||||
#: core/templates/core/post_shipment.html:24
|
||||
#: core/templates/core/post_shipment.html:28
|
||||
msgid "City, Country"
|
||||
msgstr "المدينة، الدولة"
|
||||
|
||||
#: core/templates/core/post_shipment.html:35
|
||||
#, fuzzy
|
||||
#| msgid "Post shipments easily"
|
||||
msgid "Post Shipment"
|
||||
msgstr "انشر الشحنات بسهولة"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:17
|
||||
msgid "Details"
|
||||
msgstr "التفاصيل"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:35
|
||||
msgid "Received Bids"
|
||||
msgstr "العروض المستلمة"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:42
|
||||
#, fuzzy
|
||||
#| msgid "I am a Truck Owner"
|
||||
msgid "Truck Owner"
|
||||
msgstr "أنا صاحب شاحنة"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:43
|
||||
msgid "Truck"
|
||||
msgstr "الشاحنة"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:44
|
||||
#: core/templates/core/truck_owner_dashboard.html:51
|
||||
msgid "Amount"
|
||||
msgstr "المبلغ"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:45
|
||||
#: core/templates/core/shipper_dashboard.html:29
|
||||
msgid "Action"
|
||||
msgstr "الإجراء"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:55
|
||||
msgid "Accept"
|
||||
msgstr "قبول"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:60
|
||||
msgid "No bids received yet."
|
||||
msgstr "لم يتم استلام عروض بعد."
|
||||
|
||||
#: core/templates/core/shipment_detail.html:74
|
||||
msgid "Shipment in progress!"
|
||||
msgstr "الشحنة قيد التنفيذ!"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:75
|
||||
#, fuzzy
|
||||
#| msgid "Find a Truck"
|
||||
msgid "Assigned Truck:"
|
||||
msgstr "ابحث عن شاحنة"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:80
|
||||
msgid "Contact Driver on WhatsApp"
|
||||
msgstr "تواصل مع السائق عبر واتساب"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:89
|
||||
msgid "Contact Information"
|
||||
msgstr "معلومات الاتصال"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:91
|
||||
#, fuzzy
|
||||
#| msgid "I am a Shipper"
|
||||
msgid "Shipper:"
|
||||
msgstr "أنا شاحن"
|
||||
|
||||
#: core/templates/core/shipment_detail.html:93
|
||||
msgid "Phone:"
|
||||
msgstr "الهاتف:"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:7
|
||||
#, fuzzy
|
||||
#| msgid "Dashboard"
|
||||
msgid "Shipper Dashboard"
|
||||
msgstr "لوحة التحكم"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:9
|
||||
#, fuzzy
|
||||
#| msgid "Post shipments easily"
|
||||
msgid "Post New Shipment"
|
||||
msgstr "انشر الشحنات بسهولة"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:17
|
||||
msgid "My Shipments"
|
||||
msgstr "شحناتي"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:24
|
||||
msgid "Description"
|
||||
msgstr "الوصف"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:25
|
||||
msgid "Route"
|
||||
msgstr "المسار"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:27
|
||||
#: core/templates/core/truck_owner_dashboard.html:52
|
||||
msgid "Status"
|
||||
msgstr "الحالة"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:28
|
||||
msgid "Bids"
|
||||
msgstr "العروض"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:45
|
||||
msgid "View Details"
|
||||
msgstr "عرض التفاصيل"
|
||||
|
||||
#: core/templates/core/shipper_dashboard.html:50
|
||||
#, fuzzy
|
||||
#| msgid "Post shipments easily"
|
||||
msgid "No shipments posted yet."
|
||||
msgstr "انشر الشحنات بسهولة"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:7
|
||||
#, fuzzy
|
||||
#| msgid "Dashboard"
|
||||
msgid "Truck Owner Dashboard"
|
||||
msgstr "لوحة التحكم"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:10
|
||||
msgid "Find Shipments"
|
||||
msgstr "ابحث عن شحنات"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:13
|
||||
#, fuzzy
|
||||
#| msgid "Register Your Truck"
|
||||
msgid "Register Truck"
|
||||
msgstr "سجل شاحنتك"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:22
|
||||
msgid "My Trucks"
|
||||
msgstr "شاحناتي"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:35
|
||||
msgid "No trucks registered."
|
||||
msgstr "لا توجد شاحنات مسجلة."
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:43
|
||||
msgid "My Active Bids"
|
||||
msgstr "عروضي النشطة"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:50
|
||||
msgid "Shipment"
|
||||
msgstr "الشحنة"
|
||||
|
||||
#: core/templates/core/truck_owner_dashboard.html:68
|
||||
msgid "No bids placed."
|
||||
msgstr "لا توجد عروض مقدمة."
|
||||
|
||||
#: core/templates/core/truck_register.html:10
|
||||
#, fuzzy
|
||||
#| msgid "Register Your Truck"
|
||||
msgid "Register a Truck"
|
||||
msgstr "سجل شاحنتك"
|
||||
|
||||
#: core/templates/core/truck_register.html:38
|
||||
msgid "Load Capacity (e.g. 20 Tons)"
|
||||
msgstr "الحمولة (مثال: 20 طن)"
|
||||
|
||||
#: core/templates/core/truck_register.html:43
|
||||
msgid "Documents & Photos"
|
||||
msgstr "المستندات والصور"
|
||||
|
||||
#: core/templates/core/truck_register.html:57
|
||||
msgid "Registration (Front Face)"
|
||||
msgstr "التسجيل (الوجه الأمامي)"
|
||||
|
||||
#: core/templates/core/truck_register.html:61
|
||||
msgid "Registration (Back Face)"
|
||||
msgstr "التسجيل (الوجه الخلفي)"
|
||||
|
||||
#: core/templates/core/truck_register.html:66
|
||||
msgid "Submit Registration"
|
||||
msgstr "إرسال التسجيل"
|
||||
|
||||
#: core/templates/registration/login.html:15
|
||||
msgid "Username"
|
||||
msgstr "اسم المستخدم"
|
||||
|
||||
#: core/templates/registration/login.html:19
|
||||
msgid "Password"
|
||||
msgstr "كلمة المرور"
|
||||
|
||||
#: core/templates/registration/login.html:25
|
||||
msgid "Don't have an account?"
|
||||
msgstr "ليس لديك حساب؟"
|
||||
|
||||
#: core/templates/registration/login.html:25
|
||||
#: core/templates/registration/register.html:29
|
||||
msgid "Register"
|
||||
msgstr "تسجيل"
|
||||
|
||||
#: core/templates/registration/register.html:11
|
||||
msgid "Create your account"
|
||||
msgstr "أنشئ حسابك"
|
||||
|
||||
#: core/templates/registration/register.html:17
|
||||
msgid "I am a:"
|
||||
msgstr "أنا:"
|
||||
|
||||
#: core/templates/registration/register.html:25
|
||||
msgid "Phone Number"
|
||||
msgstr "رقم الهاتف"
|
||||
|
||||
#: core/templates/registration/register.html:32
|
||||
msgid "Already have an account?"
|
||||
msgstr "لديك حساب بالفعل؟"
|
||||
|
||||
#: core/views.py:79
|
||||
msgid "Truck registered successfully!"
|
||||
msgstr "تم تسجيل الشاحنة بنجاح!"
|
||||
|
||||
#: core/views.py:104
|
||||
msgid "Shipment posted successfully!"
|
||||
msgstr "تم نشر الشحنة بنجاح!"
|
||||
|
||||
#: core/views.py:137
|
||||
msgid "Bid placed successfully!"
|
||||
msgstr "تم تقديم العرض بنجاح!"
|
||||
|
||||
#: core/views.py:171
|
||||
msgid "Bid accepted! Shipment is now in progress."
|
||||
msgstr "تم قبول العرض! الشحنة قيد التنفيذ الآن."
|
||||
|
||||
#~ msgid "Features"
|
||||
#~ msgstr "المميزات"
|
||||
|
||||
#~ msgid "How it Works"
|
||||
#~ msgstr "كيف يعمل"
|
||||
BIN
media/trucks/red_truk.jfif
Normal file
BIN
media/trucks/red_truk.jfif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -1,4 +1,131 @@
|
||||
/* Custom styles for the application */
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&family=Outfit:wght@400;600;700&display=swap');
|
||||
|
||||
:root {
|
||||
--primary-color: #0A1D37;
|
||||
--secondary-color: #2196F3;
|
||||
--accent-color: #00BCD4;
|
||||
--bg-light: #F4F7F6;
|
||||
--white: #FFFFFF;
|
||||
--text-dark: #333333;
|
||||
--text-muted: #666666;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Outfit', 'Cairo', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
color: var(--text-dark);
|
||||
margin: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
[lang="ar"] body {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: var(--white);
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: var(--primary-color) !important;
|
||||
font-weight: 600;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--secondary-color);
|
||||
border: none;
|
||||
padding: 10px 25px;
|
||||
border-radius: 50px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(33, 150, 243, 0.3);
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
border: 2px solid var(--secondary-color);
|
||||
color: var(--secondary-color);
|
||||
padding: 10px 25px;
|
||||
border-radius: 50px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 100px 0;
|
||||
background: linear-gradient(135deg, var(--white) 0%, #E3F2FD 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.role-card {
|
||||
background: var(--white);
|
||||
padding: 40px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid transparent;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.role-card:hover {
|
||||
border-color: var(--secondary-color);
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
font-size: 3rem;
|
||||
color: var(--secondary-color);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.role-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.role-desc {
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--primary-color);
|
||||
color: var(--white);
|
||||
padding: 50px 0;
|
||||
}
|
||||
|
||||
/* RTL Adjustments */
|
||||
[lang="ar"] .ms-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
@ -1,21 +1,131 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&family=Outfit:wght@400;600;700&display=swap');
|
||||
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
--primary-color: #0A1D37;
|
||||
--secondary-color: #2196F3;
|
||||
--accent-color: #00BCD4;
|
||||
--bg-light: #F4F7F6;
|
||||
--white: #FFFFFF;
|
||||
--text-dark: #333333;
|
||||
--text-muted: #666666;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Outfit', 'Cairo', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
color: var(--text-dark);
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
[lang="ar"] body {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: var(--white);
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: var(--primary-color) !important;
|
||||
font-weight: 600;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--secondary-color);
|
||||
border: none;
|
||||
padding: 10px 25px;
|
||||
border-radius: 50px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(33, 150, 243, 0.3);
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
border: 2px solid var(--secondary-color);
|
||||
color: var(--secondary-color);
|
||||
padding: 10px 25px;
|
||||
border-radius: 50px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 100px 0;
|
||||
background: linear-gradient(135deg, var(--white) 0%, #E3F2FD 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.role-card {
|
||||
background: var(--white);
|
||||
padding: 40px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid transparent;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.role-card:hover {
|
||||
border-color: var(--secondary-color);
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
font-size: 3rem;
|
||||
color: var(--secondary-color);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.role-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.role-desc {
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--primary-color);
|
||||
color: var(--white);
|
||||
padding: 50px 0;
|
||||
}
|
||||
|
||||
/* RTL Adjustments */
|
||||
[lang="ar"] .ms-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user