1st update

This commit is contained in:
Flatlogic Bot 2026-01-25 07:17:07 +00:00
parent 254e46f4b2
commit f69cb03bdb
29 changed files with 1526 additions and 224 deletions

View File

@ -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'

View File

@ -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.

View File

@ -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
View 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

View 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)),
],
),
]

View File

@ -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'),
),
]

View File

@ -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')

View File

@ -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">&copy; 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>

View File

@ -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 %}

View 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 %}

View 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 %}

View 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 %}

View File

@ -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'),
]

View File

@ -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 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})
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()
@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')
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)
def article_detail(request):
return render(request, 'core/article_detail.html')

Binary file not shown.

View 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 "الطرد غير موجود."

Binary file not shown.

View 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 ""

View File

@ -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; }

View File

@ -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; }