1st update
This commit is contained in:
parent
254e46f4b2
commit
f69cb03bdb
Binary file not shown.
Binary file not shown.
@ -61,6 +61,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',
|
||||
@ -134,6 +135,14 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
LANGUAGES = [
|
||||
('en', 'English'),
|
||||
('ar', 'Arabic'),
|
||||
]
|
||||
|
||||
LOCALE_PATHS = [
|
||||
BASE_DIR / 'locale',
|
||||
]
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
|
||||
@ -1,29 +1,19 @@
|
||||
"""
|
||||
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.urls import path, include
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include("core.urls")),
|
||||
path('i18n/', include('django.conf.urls.i18n')),
|
||||
]
|
||||
|
||||
urlpatterns += i18n_patterns(
|
||||
path('admin/', admin.site.urls),
|
||||
path('', include('core.urls')),
|
||||
prefix_default_language=False
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets")
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets")
|
||||
Binary file not shown.
BIN
core/__pycache__/forms.cpython-311.pyc
Normal file
BIN
core/__pycache__/forms.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,15 @@
|
||||
from django.contrib import admin
|
||||
from .models import Profile, Parcel
|
||||
|
||||
# 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(Parcel)
|
||||
class ParcelAdmin(admin.ModelAdmin):
|
||||
list_display = ('tracking_number', 'shipper', 'carrier', 'status', 'created_at')
|
||||
list_filter = ('status', 'created_at')
|
||||
search_fields = ('tracking_number', 'receiver_name', 'receiver_phone')
|
||||
readonly_fields = ('tracking_number',)
|
||||
39
core/forms.py
Normal file
39
core/forms.py
Normal file
@ -0,0 +1,39 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from .models import Profile
|
||||
|
||||
class UserRegistrationForm(forms.ModelForm):
|
||||
password = forms.CharField(widget=forms.PasswordInput, label=_("Password"))
|
||||
password_confirm = forms.CharField(widget=forms.PasswordInput, label=_("Confirm Password"))
|
||||
role = forms.ChoiceField(choices=Profile.ROLE_CHOICES, label=_("Register as"))
|
||||
phone_number = forms.CharField(max_length=20, label=_("Phone Number"))
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username', 'email', 'first_name', 'last_name']
|
||||
labels = {
|
||||
'username': _('Username'),
|
||||
'email': _('Email'),
|
||||
'first_name': _('First Name'),
|
||||
'last_name': _('Last Name'),
|
||||
}
|
||||
|
||||
def clean_password_confirm(self):
|
||||
password = self.cleaned_data.get('password')
|
||||
password_confirm = self.cleaned_data.get('password_confirm')
|
||||
if password and password_confirm and password != password_confirm:
|
||||
raise forms.ValidationError(_("Passwords don't match"))
|
||||
return password_confirm
|
||||
|
||||
def save(self, commit=True):
|
||||
user = super().save(commit=False)
|
||||
user.set_password(self.cleaned_data['password'])
|
||||
if commit:
|
||||
user.save()
|
||||
Profile.objects.create(
|
||||
user=user,
|
||||
role=self.cleaned_data['role'],
|
||||
phone_number=self.cleaned_data['phone_number']
|
||||
)
|
||||
return user
|
||||
44
core/migrations/0001_initial.py
Normal file
44
core/migrations/0001_initial.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-25 07:04
|
||||
|
||||
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='Parcel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('tracking_number', models.CharField(blank=True, max_length=20, unique=True)),
|
||||
('description', models.TextField()),
|
||||
('weight', models.DecimalField(decimal_places=2, help_text='Weight in kg', max_digits=5)),
|
||||
('pickup_address', models.CharField(max_length=255)),
|
||||
('delivery_address', models.CharField(max_length=255)),
|
||||
('receiver_name', models.CharField(max_length=100)),
|
||||
('receiver_phone', models.CharField(max_length=20)),
|
||||
('status', models.CharField(choices=[('pending', 'Pending Pickup'), ('picked_up', 'Picked Up'), ('in_transit', 'In Transit'), ('delivered', 'Delivered'), ('cancelled', 'Cancelled')], default='pending', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('carrier', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='carried_parcels', to=settings.AUTH_USER_MODEL)),
|
||||
('shipper', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_parcels', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
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'), ('car_owner', 'Car Owner')], 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,99 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-25 07:14
|
||||
|
||||
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.AlterModelOptions(
|
||||
name='parcel',
|
||||
options={'verbose_name': 'Parcel', 'verbose_name_plural': 'Parcels'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='profile',
|
||||
options={'verbose_name': 'Profile', 'verbose_name_plural': 'Profiles'},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='carrier',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='carried_parcels', to=settings.AUTH_USER_MODEL, verbose_name='Carrier'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Created At'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='delivery_address',
|
||||
field=models.CharField(max_length=255, verbose_name='Delivery Address'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='description',
|
||||
field=models.TextField(verbose_name='Description'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='pickup_address',
|
||||
field=models.CharField(max_length=255, verbose_name='Pickup Address'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='receiver_name',
|
||||
field=models.CharField(max_length=100, verbose_name='Receiver Name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='receiver_phone',
|
||||
field=models.CharField(max_length=20, verbose_name='Receiver Phone'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='shipper',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_parcels', to=settings.AUTH_USER_MODEL, verbose_name='Shipper'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('pending', 'Pending Pickup'), ('picked_up', 'Picked Up'), ('in_transit', 'In Transit'), ('delivered', 'Delivered'), ('cancelled', 'Cancelled')], default='pending', max_length=20, verbose_name='Status'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='tracking_number',
|
||||
field=models.CharField(blank=True, max_length=20, unique=True, verbose_name='Tracking Number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='updated_at',
|
||||
field=models.DateTimeField(auto_now=True, verbose_name='Updated At'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='weight',
|
||||
field=models.DecimalField(decimal_places=2, help_text='Weight in kg', max_digits=5, verbose_name='Weight (kg)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='phone_number',
|
||||
field=models.CharField(blank=True, max_length=20, verbose_name='Phone Number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='role',
|
||||
field=models.CharField(choices=[('shipper', 'Shipper'), ('car_owner', 'Car Owner')], default='shipper', max_length=20, verbose_name='Role'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
|
||||
),
|
||||
]
|
||||
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.
@ -1,3 +1,58 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
import uuid
|
||||
|
||||
# Create your models here.
|
||||
class Profile(models.Model):
|
||||
ROLE_CHOICES = (
|
||||
('shipper', _('Shipper')),
|
||||
('car_owner', _('Car Owner')),
|
||||
)
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name=_('User'))
|
||||
role = models.CharField(_('Role'), max_length=20, choices=ROLE_CHOICES, default='shipper')
|
||||
phone_number = models.CharField(_('Phone Number'), max_length=20, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username} - {self.get_role_display()}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Profile')
|
||||
verbose_name_plural = _('Profiles')
|
||||
|
||||
class Parcel(models.Model):
|
||||
STATUS_CHOICES = (
|
||||
('pending', _('Pending Pickup')),
|
||||
('picked_up', _('Picked Up')),
|
||||
('in_transit', _('In Transit')),
|
||||
('delivered', _('Delivered')),
|
||||
('cancelled', _('Cancelled')),
|
||||
)
|
||||
|
||||
tracking_number = models.CharField(_('Tracking Number'), max_length=20, unique=True, blank=True)
|
||||
shipper = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_parcels', verbose_name=_('Shipper'))
|
||||
carrier = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='carried_parcels', verbose_name=_('Carrier'))
|
||||
|
||||
description = models.TextField(_('Description'))
|
||||
weight = models.DecimalField(_('Weight (kg)'), max_digits=5, decimal_places=2, help_text=_("Weight in kg"))
|
||||
|
||||
pickup_address = models.CharField(_('Pickup Address'), max_length=255)
|
||||
delivery_address = models.CharField(_('Delivery Address'), max_length=255)
|
||||
|
||||
receiver_name = models.CharField(_('Receiver Name'), max_length=100)
|
||||
receiver_phone = models.CharField(_('Receiver Phone'), max_length=20)
|
||||
|
||||
status = models.CharField(_('Status'), max_length=20, choices=STATUS_CHOICES, default='pending')
|
||||
created_at = models.DateTimeField(_('Created At'), auto_now_add=True)
|
||||
updated_at = models.DateTimeField(_('Updated At'), auto_now=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.tracking_number:
|
||||
self.tracking_number = str(uuid.uuid4().hex[:10]).upper()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return f"Parcel {self.tracking_number} - {self.status}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Parcel')
|
||||
verbose_name_plural = _('Parcels')
|
||||
@ -1,25 +1,121 @@
|
||||
{% load i18n static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
{% get_language_info for LANGUAGE_CODE as lang %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<html lang="{{ LANGUAGE_CODE }}" dir="{{ lang.direction }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Knowledge Base{% 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 }}">
|
||||
{% endif %}
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||
{% block head %}{% endblock %}
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}masarX | {% trans "Small Shipments, Smart Delivery" %}{% 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 }}">
|
||||
{% endif %}
|
||||
|
||||
<!-- Bootstrap 5 -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
|
||||
<!-- Custom Styles -->
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||
|
||||
{% if lang.direction == 'rtl' %}
|
||||
<style>
|
||||
body {
|
||||
text-align: right;
|
||||
}
|
||||
.ms-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.me-auto {
|
||||
margin-left: auto !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark w-100" style="z-index: 1000;">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold fs-3" href="{% url 'index' %}" style="font-family: 'Outfit', sans-serif;">masar<span style="color: var(--accent-orange)">X</span></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">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3" href="{% url 'index' %}#how-it-works">{% trans "How it Works" %}</a>
|
||||
</li>
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<span class="nav-link text-white-50">{% trans "Hello" %}, {{ user.username }}</span>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<form action="{% url 'logout' %}" method="post" class="d-inline">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-link nav-link">{% trans "Logout" %}</button>
|
||||
</form>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3" href="{% url 'login' %}">{% trans "Login" %}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3" href="{% url 'register' %}">{% trans "Register" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="langDropdown" role="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-globe"></i> {{ lang.name_local }}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
{% get_available_languages as LANGUAGES %}
|
||||
{% for lang_code, lang_name in LANGUAGES %}
|
||||
<li>
|
||||
<form action="{% url 'set_language' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="{{ request.path }}">
|
||||
<input name="language" type="hidden" value="{{ lang_code }}">
|
||||
<button type="submit" class="dropdown-item {% if LANGUAGE_CODE == lang_code %}active{% endif %}">
|
||||
{{ lang_name }}
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item ms-lg-3">
|
||||
<a href="{% url 'shipment_request' %}" class="btn btn-masarx-primary btn-sm">{% trans "Start Shipping" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer class="py-5 bg-white border-top">
|
||||
<div class="container text-center">
|
||||
<p class="text-muted mb-0">© 2026 masarX. {% trans "All rights reserved." %}</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Bootstrap Bundle with Popper -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,145 +1,105 @@
|
||||
{% 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 static i18n %}
|
||||
|
||||
{% 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">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-6 mb-5 mb-lg-0">
|
||||
<h1 class="display-3 mb-4">{% trans "Small Shipments," %}<br><span style="color: var(--accent-orange)">{% trans "Smart Delivery." %}</span></h1>
|
||||
<p class="lead mb-5 opacity-75">{% trans "masarX connects shippers with local car owners for fast, reliable, and trackable deliveries. Your cargo, our priority." %}</p>
|
||||
<div class="d-flex gap-3">
|
||||
<a href="{% url 'shipment_request' %}" class="btn btn-masarx-primary">{% trans "Start Shipping" %}</a>
|
||||
<a href="#how-it-works" class="btn btn-outline-light border-2 px-4 py-2" style="border-radius: 12px;">{% trans "Learn More" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5 offset-lg-1">
|
||||
<div class="glass-card">
|
||||
<h3 class="mb-4">{% trans "Track your Parcel" %}</h3>
|
||||
<form method="GET" action="{% url 'index' %}">
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" name="tracking_id" class="form-control tracking-input" placeholder="{% trans 'Enter Tracking ID (e.g. 5A2B...)' %}" value="{{ tracking_id|default:'' }}">
|
||||
<button class="btn btn-masarx-primary px-4" type="submit">{% trans "Track" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% if parcel %}
|
||||
<div class="mt-4 p-3 bg-white bg-opacity-10 rounded-3 text-start" dir="ltr">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<span class="text-uppercase small opacity-75">{% trans "Status" %}</span>
|
||||
<span class="parcel-status-badge status-{{ parcel.status }}">{{ parcel.get_status_display }}</span>
|
||||
</div>
|
||||
<h5 class="mb-1">{{ parcel.description|truncatechars:30 }}</h5>
|
||||
<p class="small mb-0 opacity-75">{% trans "From" %}: {{ parcel.pickup_address }}</p>
|
||||
<p class="small mb-0 opacity-75">{% trans "To" %}: {{ parcel.delivery_address }}</p>
|
||||
</div>
|
||||
{% elif error %}
|
||||
<div class="mt-3 text-danger small">
|
||||
<i class="bi bi-exclamation-circle me-1"></i> {{ error }}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="small opacity-50 mt-3 mb-0">{% trans "Enter your 10-character tracking ID to see live updates." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section id="how-it-works" class="py-5 bg-white">
|
||||
<div class="container py-5">
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="display-5">{% trans "How masarX Works" %}</h2>
|
||||
<p class="text-muted">{% trans "Simple steps to get your shipment moving" %}</p>
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-4">
|
||||
<div class="p-4 border-0 card h-100 bg-transparent">
|
||||
<div class="feature-icon">
|
||||
<i class="bi bi-box-seam"></i>
|
||||
</div>
|
||||
<h4>1. {% trans "List your Parcel" %}</h4>
|
||||
<p class="text-muted">{% trans "Enter shipment details, weight, and delivery addresses. It's quick and easy." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="p-4 border-0 card h-100 bg-transparent">
|
||||
<div class="feature-icon">
|
||||
<i class="bi bi-truck"></i>
|
||||
</div>
|
||||
<h4>2. {% trans "Connect with Driver" %}</h4>
|
||||
<p class="text-muted">{% trans "A verified car owner near you picks up the parcel and starts the journey." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="p-4 border-0 card h-100 bg-transparent">
|
||||
<div class="feature-icon">
|
||||
<i class="bi bi-shield-check"></i>
|
||||
</div>
|
||||
<h4>3. {% trans "Secure Delivery" %}</h4>
|
||||
<p class="text-muted">{% trans "Track your parcel in real-time until it reaches its destination safely." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="py-5" style="background-color: var(--primary-dark); color: white;">
|
||||
<div class="container py-4 text-center">
|
||||
<h2 class="mb-4">{% trans "Ready to join the movement?" %}</h2>
|
||||
<div class="row justify-content-center gap-4">
|
||||
<div class="col-md-5 text-center">
|
||||
<p class="mb-3">{% trans "I want to send a parcel" %}</p>
|
||||
<a href="{% url 'register' %}" class="btn btn-masarx-primary">{% trans "Become a Shipper" %}</a>
|
||||
</div>
|
||||
<div class="col-md-5 text-center">
|
||||
<p class="mb-3">{% trans "I have a car and want to earn" %}</p>
|
||||
<a href="{% url 'register' %}" class="btn btn-outline-light border-2 px-4 py-2" style="border-radius: 12px;">{% trans "Become a Driver" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
50
core/templates/core/login.html
Normal file
50
core/templates/core/login.html
Normal file
@ -0,0 +1,50 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Login" %} | masarX{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="py-5 bg-light" style="min-height: 80vh;">
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-5">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="fw-bold mb-4 text-center">{% trans "Login to masarX" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}
|
||||
<div class="text-danger small">{{ field.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button type="submit" class="btn btn-masarx-primary w-100 py-2 mt-3">{% trans "Login" %}</button>
|
||||
</form>
|
||||
<div class="text-center mt-4">
|
||||
<p class="mb-0 text-muted">{% trans "Don't have an account?" %} <a href="{% url 'register' %}" class="text-masarx-orange">{% trans "Register here" %}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.form-control {
|
||||
border-radius: 8px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.btn-masarx-primary {
|
||||
background-color: var(--accent-orange);
|
||||
border-color: var(--accent-orange);
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
64
core/templates/core/register.html
Normal file
64
core/templates/core/register.html
Normal file
@ -0,0 +1,64 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Register" %} | masarX{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="py-5 bg-light" style="min-height: 80vh;">
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="fw-bold mb-4 text-center">{% trans "Join masarX" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-semibold">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.help_text %}
|
||||
<div class="form-text small">{{ field.help_text }}</div>
|
||||
{% endif %}
|
||||
{% if field.errors %}
|
||||
<div class="text-danger small">{{ field.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button type="submit" class="btn btn-masarx-primary w-100 py-2 mt-3">{% trans "Create Account" %}</button>
|
||||
</form>
|
||||
<div class="text-center mt-4">
|
||||
<p class="mb-0 text-muted">{% trans "Already have an account?" %} <a href="{% url 'login' %}" class="text-masarx-orange">{% trans "Login here" %}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
input, select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ced4da;
|
||||
appearance: none;
|
||||
border-radius: 8px;
|
||||
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
}
|
||||
.btn-masarx-primary {
|
||||
background-color: var(--accent-orange);
|
||||
border-color: var(--accent-orange);
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
42
core/templates/core/shipment_request.html
Normal file
42
core/templates/core/shipment_request.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card border-0 shadow-sm p-4" style="border-radius: 20px;">
|
||||
<h2 class="mb-4">Request a Shipment</h2>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pickup Address</label>
|
||||
<input type="text" class="form-control" placeholder="123 Street, City" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Delivery Address</label>
|
||||
<input type="text" class="form-control" placeholder="456 Avenue, City" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Package Description</label>
|
||||
<textarea class="form-control" rows="3" placeholder="What are you sending?"></textarea>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Weight (kg)</label>
|
||||
<input type="number" step="0.1" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">Receiver Name</label>
|
||||
<input type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-masarx-primary w-100">Submit Request</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
11
core/urls.py
11
core/urls.py
@ -1,7 +1,12 @@
|
||||
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.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('shipment-request/', views.shipment_request, name='shipment_request'),
|
||||
path('article-detail/', views.article_detail, name='article_detail'),
|
||||
]
|
||||
|
||||
@ -1,25 +1,44 @@
|
||||
import os
|
||||
import platform
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth import login, authenticate
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from .models import Parcel, Profile
|
||||
from .forms import UserRegistrationForm
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django import get_version as django_version
|
||||
from django.shortcuts import render
|
||||
from django.utils import timezone
|
||||
def index(request):
|
||||
tracking_id = request.GET.get('tracking_id')
|
||||
parcel = None
|
||||
error = None
|
||||
if tracking_id:
|
||||
try:
|
||||
parcel = Parcel.objects.get(tracking_number=tracking_id)
|
||||
except Parcel.DoesNotExist:
|
||||
error = _("Parcel not found.")
|
||||
|
||||
return render(request, 'core/index.html', {
|
||||
'parcel': parcel,
|
||||
'error': error,
|
||||
'tracking_id': tracking_id
|
||||
})
|
||||
|
||||
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()
|
||||
def register(request):
|
||||
if request.method == 'POST':
|
||||
form = UserRegistrationForm(request.POST)
|
||||
if form.is_valid():
|
||||
user = form.save()
|
||||
login(request, user)
|
||||
return redirect('index')
|
||||
else:
|
||||
form = UserRegistrationForm()
|
||||
return render(request, 'core/register.html', {'form': form})
|
||||
|
||||
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", ""),
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
@login_required
|
||||
def shipment_request(request):
|
||||
if request.method == 'POST':
|
||||
# Logic for creating shipment will go here
|
||||
pass
|
||||
return render(request, 'core/shipment_request.html')
|
||||
|
||||
def article_detail(request):
|
||||
return render(request, 'core/article_detail.html')
|
||||
|
||||
BIN
locale/ar/LC_MESSAGES/django.mo
Normal file
BIN
locale/ar/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
316
locale/ar/LC_MESSAGES/django.po
Normal file
316
locale/ar/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,316 @@
|
||||
# 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.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-25 07:13+0000\n"
|
||||
"PO-Revision-Date: 2026-01-25 07:13+0000\n"
|
||||
"Last-Translator: Gemini\n"
|
||||
"Language-Team: Arabic\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"
|
||||
|
||||
#: core/forms.py:7
|
||||
msgid "Password"
|
||||
msgstr "كلمة المرور"
|
||||
|
||||
#: core/forms.py:8
|
||||
msgid "Confirm Password"
|
||||
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
|
||||
msgid "Email"
|
||||
msgstr "البريد الإلكتروني"
|
||||
|
||||
#: core/forms.py:18
|
||||
msgid "First Name"
|
||||
msgstr "الاسم الأول"
|
||||
|
||||
#: core/forms.py:19
|
||||
msgid "Last Name"
|
||||
msgstr "اسم العائلة"
|
||||
|
||||
#: core/forms.py:26
|
||||
msgid "Passwords don't match"
|
||||
msgstr "كلمات المرور غير متطابقة"
|
||||
|
||||
#: core/models.py:8 core/models.py:32
|
||||
msgid "Shipper"
|
||||
msgstr "شاحن"
|
||||
|
||||
#: core/models.py:9
|
||||
msgid "Car Owner"
|
||||
msgstr "صاحب سيارة"
|
||||
|
||||
#: core/models.py:11
|
||||
msgid "User"
|
||||
msgstr "مستخدم"
|
||||
|
||||
#: core/models.py:12
|
||||
msgid "Role"
|
||||
msgstr "الدور"
|
||||
|
||||
#: core/models.py:19
|
||||
msgid "Profile"
|
||||
msgstr "الملف الشخصي"
|
||||
|
||||
#: core/models.py:20
|
||||
msgid "Profiles"
|
||||
msgstr "الملفات الشخصية"
|
||||
|
||||
#: core/models.py:24
|
||||
msgid "Pending Pickup"
|
||||
msgstr "في انتظار الاستلام"
|
||||
|
||||
#: core/models.py:25
|
||||
msgid "Picked Up"
|
||||
msgstr "تم الاستلام"
|
||||
|
||||
#: core/models.py:26
|
||||
msgid "In Transit"
|
||||
msgstr "في الطريق"
|
||||
|
||||
#: core/models.py:27
|
||||
msgid "Delivered"
|
||||
msgstr "تم التوصيل"
|
||||
|
||||
#: core/models.py:28
|
||||
msgid "Cancelled"
|
||||
msgstr "ملغي"
|
||||
|
||||
#: core/models.py:31
|
||||
msgid "Tracking Number"
|
||||
msgstr "رقم التتبع"
|
||||
|
||||
#: core/models.py:33
|
||||
msgid "Carrier"
|
||||
msgstr "الناقل"
|
||||
|
||||
#: core/models.py:35
|
||||
msgid "Description"
|
||||
msgstr "الوصف"
|
||||
|
||||
#: core/models.py:36
|
||||
msgid "Weight (kg)"
|
||||
msgstr "الوزن (كجم)"
|
||||
|
||||
#: core/models.py:36
|
||||
msgid "Weight in kg"
|
||||
msgstr "الوزن بالكيلوجرام"
|
||||
|
||||
#: core/models.py:38
|
||||
msgid "Pickup Address"
|
||||
msgstr "عنوان الاستلام"
|
||||
|
||||
#: core/models.py:39
|
||||
msgid "Delivery Address"
|
||||
msgstr "عنوان التوصيل"
|
||||
|
||||
#: core/models.py:41
|
||||
msgid "Receiver Name"
|
||||
msgstr "اسم المستلم"
|
||||
|
||||
#: core/models.py:42
|
||||
msgid "Receiver Phone"
|
||||
msgstr "هاتف المستلم"
|
||||
|
||||
#: core/models.py:44 core/templates/core/index.html:30
|
||||
msgid "Status"
|
||||
msgstr "الحالة"
|
||||
|
||||
#: core/models.py:45
|
||||
msgid "Created At"
|
||||
msgstr "أنشئ في"
|
||||
|
||||
#: core/models.py:46
|
||||
msgid "Updated At"
|
||||
msgstr "حدث في"
|
||||
|
||||
#: core/models.py:57
|
||||
msgid "Parcel"
|
||||
msgstr "طرد"
|
||||
|
||||
#: core/models.py:58
|
||||
msgid "Parcels"
|
||||
msgstr "طرود"
|
||||
|
||||
#: core/templates/base.html:9
|
||||
msgid "Small Shipments, Smart Delivery"
|
||||
msgstr "شحنات صغيرة، توصيل ذكي"
|
||||
|
||||
#: core/templates/base.html:58
|
||||
msgid "How it Works"
|
||||
msgstr "كيف يعمل"
|
||||
|
||||
#: core/templates/base.html:62
|
||||
msgid "Hello"
|
||||
msgstr "مرحباً"
|
||||
|
||||
#: core/templates/base.html:67
|
||||
msgid "Logout"
|
||||
msgstr "تسجيل الخروج"
|
||||
|
||||
#: core/templates/base.html:72 core/templates/core/login.html:4
|
||||
#: core/templates/core/login.html:25
|
||||
msgid "Login"
|
||||
msgstr "تسجيل الدخول"
|
||||
|
||||
#: core/templates/base.html:75 core/templates/core/register.html:4
|
||||
msgid "Register"
|
||||
msgstr "تسجيل"
|
||||
|
||||
#: core/templates/base.html:101 core/templates/core/index.html:13
|
||||
msgid "Start Shipping"
|
||||
msgstr "ابدأ الشحن"
|
||||
|
||||
#: core/templates/base.html:114
|
||||
msgid "All rights reserved."
|
||||
msgstr "جميع الحقوق محفوظة."
|
||||
|
||||
#: core/templates/core/index.html:10
|
||||
msgid "Small Shipments,"
|
||||
msgstr "شحنات صغيرة،"
|
||||
|
||||
#: core/templates/core/index.html:10
|
||||
msgid "Smart Delivery."
|
||||
msgstr "توصيل ذكي."
|
||||
|
||||
#: core/templates/core/index.html:11
|
||||
msgid ""
|
||||
"masarX connects shippers with local car owners for fast, reliable, and "
|
||||
"trackable deliveries. Your cargo, our priority."
|
||||
msgstr "يربط مسارX بين الشاحنين وأصحاب السيارات المحليين لتوصيل سريع وموثوق وقابل للتتبع. شحنتك هي أولويتنا."
|
||||
|
||||
#: core/templates/core/index.html:14
|
||||
msgid "Learn More"
|
||||
msgstr "تعلم المزيد"
|
||||
|
||||
#: core/templates/core/index.html:19
|
||||
msgid "Track your Parcel"
|
||||
msgstr "تتبع طردك"
|
||||
|
||||
#: core/templates/core/index.html:22
|
||||
msgid "Enter Tracking ID (e.g. 5A2B...)"
|
||||
msgstr "أدخل رقم التتبع (مثال: 5A2B...)"
|
||||
|
||||
#: core/templates/core/index.html:23
|
||||
msgid "Track"
|
||||
msgstr "تتبع"
|
||||
|
||||
#: core/templates/core/index.html:34
|
||||
msgid "From"
|
||||
msgstr "من"
|
||||
|
||||
#: core/templates/core/index.html:35
|
||||
msgid "To"
|
||||
msgstr "إلى"
|
||||
|
||||
#: core/templates/core/index.html:42
|
||||
msgid "Enter your 10-character tracking ID to see live updates."
|
||||
msgstr "أدخل رقم التتبع المكون من 10 أرقام لرؤية التحديثات المباشرة."
|
||||
|
||||
#: core/templates/core/index.html:54
|
||||
msgid "How masarX Works"
|
||||
msgstr "كيف يعمل مسارX"
|
||||
|
||||
#: core/templates/core/index.html:55
|
||||
msgid "Simple steps to get your shipment moving"
|
||||
msgstr "خطوات بسيطة لبدء شحن طردك"
|
||||
|
||||
#: core/templates/core/index.html:63
|
||||
msgid "List your Parcel"
|
||||
msgstr "أدرج طردك"
|
||||
|
||||
#: core/templates/core/index.html:64
|
||||
msgid ""
|
||||
"Enter shipment details, weight, and delivery addresses. It's quick and easy."
|
||||
msgstr "أدخل تفاصيل الشحنة والوزن وعناوين التوصيل. إنه سريع وسهل."
|
||||
|
||||
#: core/templates/core/index.html:72
|
||||
msgid "Connect with Driver"
|
||||
msgstr "تواصل مع السائق"
|
||||
|
||||
#: core/templates/core/index.html:73
|
||||
msgid ""
|
||||
"A verified car owner near you picks up the parcel and starts the journey."
|
||||
msgstr "يقوم صاحب سيارة تم التحقق منه بالقرب منك باستلام الطرد وبدء الرحلة."
|
||||
|
||||
#: core/templates/core/index.html:81
|
||||
msgid "Secure Delivery"
|
||||
msgstr "توصيل آمن"
|
||||
|
||||
#: core/templates/core/index.html:82
|
||||
msgid "Track your parcel in real-time until it reaches its destination safely."
|
||||
msgstr "تتبع طردك في الوقت الفعلي حتى يصل إلى وجهته بأمان."
|
||||
|
||||
#: core/templates/core/index.html:92
|
||||
msgid "Ready to join the movement?"
|
||||
msgstr "مستعد للانضمام إلينا؟"
|
||||
|
||||
#: core/templates/core/index.html:95
|
||||
msgid "I want to send a parcel"
|
||||
msgstr "أريد إرسال طرد"
|
||||
|
||||
#: core/templates/core/index.html:96
|
||||
msgid "Become a Shipper"
|
||||
msgstr "كن شاحناً"
|
||||
|
||||
#: core/templates/core/index.html:99
|
||||
msgid "I have a car and want to earn"
|
||||
msgstr "لدي سيارة وأريد كسب المال"
|
||||
|
||||
#: core/templates/core/index.html:100
|
||||
msgid "Become a Driver"
|
||||
msgstr "كن سائقاً"
|
||||
|
||||
#: core/templates/core/login.html:13
|
||||
msgid "Login to masarX"
|
||||
msgstr "تسجيل الدخول إلى مسارX"
|
||||
|
||||
#: core/templates/core/login.html:28
|
||||
msgid "Don't have an account?"
|
||||
msgstr "ليس لديك حساب؟"
|
||||
|
||||
#: core/templates/core/login.html:28
|
||||
msgid "Register here"
|
||||
msgstr "سجل هنا"
|
||||
|
||||
#: core/templates/core/register.html:13
|
||||
msgid "Join masarX"
|
||||
msgstr "انضم إلى مسارX"
|
||||
|
||||
#: core/templates/core/register.html:28
|
||||
msgid "Create Account"
|
||||
msgstr "إنشاء حساب"
|
||||
|
||||
#: core/templates/core/register.html:31
|
||||
msgid "Already have an account?"
|
||||
msgstr "لديك حساب بالفعل؟"
|
||||
|
||||
#: core/templates/core/register.html:31
|
||||
msgid "Login here"
|
||||
msgstr "سجل دخولك هنا"
|
||||
|
||||
#: core/views.py:17
|
||||
msgid "Parcel not found."
|
||||
msgstr "الطرد غير موجود."
|
||||
BIN
locale/en/LC_MESSAGES/django.mo
Normal file
BIN
locale/en/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
315
locale/en/LC_MESSAGES/django.po
Normal file
315
locale/en/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,315 @@
|
||||
# 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-25 07:13+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: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
#: core/forms.py:7
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: core/forms.py:8
|
||||
msgid "Confirm Password"
|
||||
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
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: core/forms.py:18
|
||||
msgid "First Name"
|
||||
msgstr ""
|
||||
|
||||
#: core/forms.py:19
|
||||
msgid "Last Name"
|
||||
msgstr ""
|
||||
|
||||
#: core/forms.py:26
|
||||
msgid "Passwords don't match"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:8 core/models.py:32
|
||||
msgid "Shipper"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:9
|
||||
msgid "Car Owner"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:11
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:12
|
||||
msgid "Role"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:19
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:20
|
||||
msgid "Profiles"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:24
|
||||
msgid "Pending Pickup"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:25
|
||||
msgid "Picked Up"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:26
|
||||
msgid "In Transit"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:27
|
||||
msgid "Delivered"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:28
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:31
|
||||
msgid "Tracking Number"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:33
|
||||
msgid "Carrier"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:35
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:36
|
||||
msgid "Weight (kg)"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:36
|
||||
msgid "Weight in kg"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:38
|
||||
msgid "Pickup Address"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:39
|
||||
msgid "Delivery Address"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:41
|
||||
msgid "Receiver Name"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:42
|
||||
msgid "Receiver Phone"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:44 core/templates/core/index.html:30
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:45
|
||||
msgid "Created At"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:46
|
||||
msgid "Updated At"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:57
|
||||
msgid "Parcel"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:58
|
||||
msgid "Parcels"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:9
|
||||
msgid "Small Shipments, Smart Delivery"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:58
|
||||
msgid "How it Works"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:62
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:67
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:72 core/templates/core/login.html:4
|
||||
#: core/templates/core/login.html:25
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:75 core/templates/core/register.html:4
|
||||
msgid "Register"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:101 core/templates/core/index.html:13
|
||||
msgid "Start Shipping"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/base.html:114
|
||||
msgid "All rights reserved."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:10
|
||||
msgid "Small Shipments,"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:10
|
||||
msgid "Smart Delivery."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:11
|
||||
msgid ""
|
||||
"masarX connects shippers with local car owners for fast, reliable, and "
|
||||
"trackable deliveries. Your cargo, our priority."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:14
|
||||
msgid "Learn More"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:19
|
||||
msgid "Track your Parcel"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:22
|
||||
msgid "Enter Tracking ID (e.g. 5A2B...)"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:23
|
||||
msgid "Track"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:34
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:35
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:42
|
||||
msgid "Enter your 10-character tracking ID to see live updates."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:54
|
||||
msgid "How masarX Works"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:55
|
||||
msgid "Simple steps to get your shipment moving"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:63
|
||||
msgid "List your Parcel"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:64
|
||||
msgid ""
|
||||
"Enter shipment details, weight, and delivery addresses. It's quick and easy."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:72
|
||||
msgid "Connect with Driver"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:73
|
||||
msgid ""
|
||||
"A verified car owner near you picks up the parcel and starts the journey."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:81
|
||||
msgid "Secure Delivery"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:82
|
||||
msgid "Track your parcel in real-time until it reaches its destination safely."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:92
|
||||
msgid "Ready to join the movement?"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:95
|
||||
msgid "I want to send a parcel"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:96
|
||||
msgid "Become a Shipper"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:99
|
||||
msgid "I have a car and want to earn"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/index.html:100
|
||||
msgid "Become a Driver"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/login.html:13
|
||||
msgid "Login to masarX"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/login.html:28
|
||||
msgid "Don't have an account?"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/login.html:28
|
||||
msgid "Register here"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/register.html:13
|
||||
msgid "Join masarX"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/register.html:28
|
||||
msgid "Create Account"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/register.html:31
|
||||
msgid "Already have an account?"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/register.html:31
|
||||
msgid "Login here"
|
||||
msgstr ""
|
||||
|
||||
#: core/views.py:17
|
||||
msgid "Parcel not found."
|
||||
msgstr ""
|
||||
@ -1,4 +1,106 @@
|
||||
/* Custom styles for the application */
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
/* masarX Custom Styles */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@600;700&display=swap');
|
||||
|
||||
:root {
|
||||
--primary-dark: #1A1A1D;
|
||||
--accent-orange: #FF922B;
|
||||
--soft-cloud: #F8F9FA;
|
||||
--slate-blue: #4D96FF;
|
||||
--glass-bg: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background-color: var(--soft-cloud);
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2D2D30 100%);
|
||||
padding: 100px 0;
|
||||
color: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
right: -50px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: var(--accent-orange);
|
||||
filter: blur(80px);
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.btn-masarx-primary {
|
||||
background-color: var(--accent-orange);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 30px;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-masarx-primary:hover {
|
||||
background-color: #E87E1B;
|
||||
transform: translateY(-2px);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tracking-input {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border-radius: 12px 0 0 12px;
|
||||
padding: 15px 20px;
|
||||
}
|
||||
|
||||
.tracking-input:focus {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-color: var(--accent-orange);
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--accent-orange);
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.parcel-status-badge {
|
||||
padding: 8px 16px;
|
||||
border-radius: 50px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-pending { background: #FFE8CC; color: #D9480F; }
|
||||
.status-picked_up { background: #E3FAFC; color: #0B7285; }
|
||||
.status-in_transit { background: #E7F5FF; color: #1864AB; }
|
||||
.status-delivered { background: #EBFBEE; color: #2B8A3E; }
|
||||
@ -1,21 +1,106 @@
|
||||
/* masarX Custom Styles */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@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-dark: #1A1A1D;
|
||||
--accent-orange: #FF922B;
|
||||
--soft-cloud: #F8F9FA;
|
||||
--slate-blue: #4D96FF;
|
||||
--glass-bg: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
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;
|
||||
background-color: var(--soft-cloud);
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2D2D30 100%);
|
||||
padding: 100px 0;
|
||||
color: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
right: -50px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: var(--accent-orange);
|
||||
filter: blur(80px);
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.btn-masarx-primary {
|
||||
background-color: var(--accent-orange);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 30px;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-masarx-primary:hover {
|
||||
background-color: #E87E1B;
|
||||
transform: translateY(-2px);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tracking-input {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border-radius: 12px 0 0 12px;
|
||||
padding: 15px 20px;
|
||||
}
|
||||
|
||||
.tracking-input:focus {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-color: var(--accent-orange);
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--accent-orange);
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.parcel-status-badge {
|
||||
padding: 8px 16px;
|
||||
border-radius: 50px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-pending { background: #FFE8CC; color: #D9480F; }
|
||||
.status-picked_up { background: #E3FAFC; color: #0B7285; }
|
||||
.status-in_transit { background: #E7F5FF; color: #1864AB; }
|
||||
.status-delivered { background: #EBFBEE; color: #2B8A3E; }
|
||||
Loading…
x
Reference in New Issue
Block a user