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 = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -134,6 +135,14 @@ AUTH_PASSWORD_VALIDATORS = [
# https://docs.djangoproject.com/en/5.2/topics/i18n/ # https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en-us'
LANGUAGES = [
('en', 'English'),
('ar', 'Arabic'),
]
LOCALE_PATHS = [
BASE_DIR / 'locale',
]
TIME_ZONE = 'UTC' 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.contrib import admin
from django.urls import include, path from django.urls import path, include
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.conf.urls.i18n import i18n_patterns
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls), path('i18n/', include('django.conf.urls.i18n')),
path("", include("core.urls")),
] ]
urlpatterns += i18n_patterns(
path('admin/', admin.site.urls),
path('', include('core.urls')),
prefix_default_language=False
)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets")
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.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 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.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> <!DOCTYPE html>
<html lang="en"> <html lang="{{ LANGUAGE_CODE }}" dir="{{ lang.direction }}">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Knowledge Base{% endblock %}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0">
{% if project_description %} <title>{% block title %}masarX | {% trans "Small Shipments, Smart Delivery" %}{% endblock %}</title>
<meta name="description" content="{{ project_description }}">
<meta property="og:description" content="{{ project_description }}"> {% if project_description %}
<meta property="twitter:description" content="{{ project_description }}"> <meta name="description" content="{{ project_description }}">
{% endif %} <meta property="og:description" content="{{ project_description }}">
{% if project_image_url %} <meta property="twitter:description" content="{{ project_description }}">
<meta property="og:image" content="{{ project_image_url }}"> {% endif %}
<meta property="twitter:image" content="{{ project_image_url }}"> {% if project_image_url %}
{% endif %} <meta property="og:image" content="{{ project_image_url }}">
{% load static %} <meta property="twitter:image" content="{{ project_image_url }}">
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}"> {% endif %}
{% block head %}{% endblock %}
<!-- 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> </head>
<body> <body>
{% block content %}{% endblock %} <!-- Navbar -->
</body> <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> </html>

View File

@ -1,145 +1,105 @@
{% extends "base.html" %} {% extends 'base.html' %}
{% load static i18n %}
{% 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 %}
{% block content %} {% block content %}
<main> <!-- Hero Section -->
<div class="card"> <section class="hero-section">
<h1>Analyzing your requirements and generating your app…</h1> <div class="container">
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes"> <div class="row align-items-center">
<span class="sr-only">Loading…</span> <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> </div>
<p class="hint">AppWizzy AI is collecting your requirements and applying the first changes.</p> </section>
<p class="hint">This page will refresh automatically as the plan is implemented.</p>
<p class="runtime"> <!-- Features Section -->
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code> <section id="how-it-works" class="py-5 bg-white">
— UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code> <div class="container py-5">
</p> <div class="text-center mb-5">
</div> <h2 class="display-5">{% trans "How masarX Works" %}</h2>
</main> <p class="text-muted">{% trans "Simple steps to get your shipment moving" %}</p>
<footer> </div>
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC) <div class="row g-4">
</footer> <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 %} {% 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 django.urls import path
from django.contrib.auth import views as auth_views
from .views import home from . import views
urlpatterns = [ 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 from django.shortcuts import render, redirect
import platform 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 def index(request):
from django.shortcuts import render tracking_id = request.GET.get('tracking_id')
from django.utils import timezone 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): @login_required
"""Render the landing screen with loader and environment details.""" def shipment_request(request):
host_name = request.get_host().lower() if request.method == 'POST':
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" # Logic for creating shipment will go here
now = timezone.now() pass
return render(request, 'core/shipment_request.html')
context = { def article_detail(request):
"project_name": "New Style", return render(request, 'core/article_detail.html')
"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)

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 */ /* masarX Custom Styles */
body { @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@600;700&display=swap');
font-family: system-ui, -apple-system, sans-serif;
: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 { :root {
--bg-color-start: #6a11cb; --primary-dark: #1A1A1D;
--bg-color-end: #2575fc; --accent-orange: #FF922B;
--text-color: #ffffff; --soft-cloud: #F8F9FA;
--card-bg-color: rgba(255, 255, 255, 0.01); --slate-blue: #4D96FF;
--card-border-color: rgba(255, 255, 255, 0.1); --glass-bg: rgba(255, 255, 255, 0.1);
} }
body { body {
margin: 0;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); background-color: var(--soft-cloud);
color: var(--text-color); color: var(--primary-dark);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
} }
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; }