adding editing main page from admin panel
This commit is contained in:
parent
f1cec56a71
commit
081f578fb5
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,7 +4,7 @@ from django.shortcuts import render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner
|
||||
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection
|
||||
from .whatsapp import send_whatsapp_message
|
||||
|
||||
@admin.register(Country)
|
||||
@ -102,4 +102,11 @@ class AppSettingAdmin(admin.ModelAdmin):
|
||||
class BannerAdmin(admin.ModelAdmin):
|
||||
list_display = ('title', 'order', 'is_active', 'created_at')
|
||||
list_editable = ('order', 'is_active')
|
||||
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar')
|
||||
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar')
|
||||
|
||||
@admin.register(HomeSection)
|
||||
class HomeSectionAdmin(admin.ModelAdmin):
|
||||
list_display = ('title', 'section_type', 'order', 'is_active')
|
||||
list_editable = ('order', 'is_active')
|
||||
list_filter = ('section_type', 'is_active', 'background_color')
|
||||
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')
|
||||
|
||||
35
core/migrations/0016_homesection.py
Normal file
35
core/migrations/0016_homesection.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-24 03:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0015_banner'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='HomeSection',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=200, verbose_name='Title (EN)')),
|
||||
('title_ar', models.CharField(blank=True, max_length=200, verbose_name='Title (AR)')),
|
||||
('subtitle', models.CharField(blank=True, max_length=255, verbose_name='Subtitle (EN)')),
|
||||
('subtitle_ar', models.CharField(blank=True, max_length=255, verbose_name='Subtitle (AR)')),
|
||||
('content', models.TextField(blank=True, verbose_name='Content (EN)')),
|
||||
('content_ar', models.TextField(blank=True, verbose_name='Content (AR)')),
|
||||
('image', models.ImageField(blank=True, null=True, upload_to='home_sections/', verbose_name='Image')),
|
||||
('order', models.PositiveIntegerField(default=0, verbose_name='Order')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
|
||||
('section_type', models.CharField(choices=[('SIMPLE', 'Simple Text & Image'), ('FEATURES', 'Features List'), ('CTA', 'Call to Action')], default='SIMPLE', max_length=20)),
|
||||
('background_color', models.CharField(default='white', help_text='e.g. white, light, primary', max_length=50)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Home Section',
|
||||
'verbose_name_plural': 'Home Sections',
|
||||
'ordering': ['order'],
|
||||
},
|
||||
),
|
||||
]
|
||||
BIN
core/migrations/__pycache__/0016_homesection.cpython-311.pyc
Normal file
BIN
core/migrations/__pycache__/0016_homesection.cpython-311.pyc
Normal file
Binary file not shown.
@ -279,6 +279,50 @@ class Banner(models.Model):
|
||||
return self.subtitle_ar
|
||||
return self.subtitle
|
||||
|
||||
class HomeSection(models.Model):
|
||||
SECTION_TYPES = (
|
||||
('SIMPLE', _('Simple Text & Image')),
|
||||
('FEATURES', _('Features List')),
|
||||
('CTA', _('Call to Action')),
|
||||
)
|
||||
title = models.CharField(_('Title (EN)'), max_length=200)
|
||||
title_ar = models.CharField(_('Title (AR)'), max_length=200, blank=True)
|
||||
subtitle = models.CharField(_('Subtitle (EN)'), max_length=255, blank=True)
|
||||
subtitle_ar = models.CharField(_('Subtitle (AR)'), max_length=255, blank=True)
|
||||
content = models.TextField(_('Content (EN)'), blank=True)
|
||||
content_ar = models.TextField(_('Content (AR)'), blank=True)
|
||||
image = models.ImageField(_('Image'), upload_to='home_sections/', blank=True, null=True)
|
||||
order = models.PositiveIntegerField(_('Order'), default=0)
|
||||
is_active = models.BooleanField(_('Is Active'), default=True)
|
||||
section_type = models.CharField(max_length=20, choices=SECTION_TYPES, default='SIMPLE')
|
||||
background_color = models.CharField(max_length=50, default='white', help_text="e.g. white, light, primary")
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Home Section')
|
||||
verbose_name_plural = _('Home Sections')
|
||||
ordering = ['order']
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
@property
|
||||
def display_title(self):
|
||||
if get_language() == 'ar' and self.title_ar:
|
||||
return self.title_ar
|
||||
return self.title
|
||||
|
||||
@property
|
||||
def display_subtitle(self):
|
||||
if get_language() == 'ar' and self.subtitle_ar:
|
||||
return self.subtitle_ar
|
||||
return self.subtitle
|
||||
|
||||
@property
|
||||
def display_content(self):
|
||||
if get_language() == 'ar' and self.content_ar:
|
||||
return self.content_ar
|
||||
return self.content
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def create_user_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
@ -307,4 +351,4 @@ def sync_user_groups(sender, instance, **kwargs):
|
||||
instance.user.groups.remove(*other_groups)
|
||||
|
||||
# Add user to the correct group
|
||||
instance.user.groups.add(group)
|
||||
instance.user.groups.add(group)
|
||||
@ -50,7 +50,7 @@
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hero Section (Only show if no banners, or maybe as a secondary section?) -->
|
||||
<!-- Hero Section (Only show if no banners) -->
|
||||
{% if not banners %}
|
||||
<section class="hero-section py-5">
|
||||
<div class="container">
|
||||
@ -76,6 +76,51 @@
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<!-- Dynamic Home Sections -->
|
||||
{% for section in home_sections %}
|
||||
<section class="py-5 {% if section.background_color == 'light' %}bg-light{% elif section.background_color == 'primary' %}bg-primary text-white{% else %}bg-white{% endif %}">
|
||||
<div class="container py-5">
|
||||
{% if section.section_type == 'SIMPLE' %}
|
||||
<div class="row align-items-center {% if forloop.counter|divisibleby:2 %}flex-row-reverse{% endif %}">
|
||||
<div class="col-lg-6 mb-4 mb-lg-0">
|
||||
<h2 class="fw-bold mb-3">{{ section.display_title }}</h2>
|
||||
{% if section.display_subtitle %}
|
||||
<h5 class="{% if section.background_color == 'primary' %}text-white-50{% else %}text-muted{% endif %} mb-4">{{ section.display_subtitle }}</h5>
|
||||
{% endif %}
|
||||
<div class="content lead">
|
||||
{{ section.display_content|linebreaks }}
|
||||
</div>
|
||||
</div>
|
||||
{% if section.image %}
|
||||
<div class="col-lg-6">
|
||||
<img src="{{ section.image.url }}" alt="{{ section.display_title }}" class="img-fluid rounded-4 shadow">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% elif section.section_type == 'CTA' %}
|
||||
<div class="text-center">
|
||||
<h2 class="fw-bold mb-3">{{ section.display_title }}</h2>
|
||||
{% if section.display_subtitle %}
|
||||
<p class="lead mb-4 opacity-75">{{ section.display_subtitle }}</p>
|
||||
{% endif %}
|
||||
<div class="mb-4">
|
||||
{{ section.display_content|linebreaks }}
|
||||
</div>
|
||||
<a href="{% url 'register' %}" class="btn {% if section.background_color == 'primary' %}btn-light text-primary{% else %}btn-primary{% endif %} btn-lg px-5 rounded-pill fw-bold">{% trans "Get Started" %}</a>
|
||||
</div>
|
||||
{% elif section.section_type == 'FEATURES' %}
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="fw-bold mb-3">{{ section.display_title }}</h2>
|
||||
<p class="lead text-muted">{{ section.display_subtitle }}</p>
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
{{ section.display_content|safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Role Selection Section -->
|
||||
<section class="py-5 bg-light" id="how-it-works">
|
||||
<div class="container py-5">
|
||||
@ -189,4 +234,4 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@ -2,7 +2,7 @@ from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import login, authenticate, logout
|
||||
from django.utils import timezone
|
||||
from .models import Profile, Truck, Shipment, Bid, Message, OTPCode, Country, City, AppSetting, Banner
|
||||
from .models import Profile, Truck, Shipment, Bid, Message, OTPCode, Country, City, AppSetting, Banner, HomeSection
|
||||
from .forms import TruckForm, ShipmentForm, BidForm, UserRegistrationForm, OTPVerifyForm, ShipperOfferForm
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import gettext as _
|
||||
@ -14,9 +14,11 @@ from django.contrib.auth.forms import AuthenticationForm
|
||||
def home(request):
|
||||
"""Render the landing screen for MASAR CARGO."""
|
||||
banners = Banner.objects.filter(is_active=True)
|
||||
home_sections = HomeSection.objects.filter(is_active=True).order_by('order')
|
||||
context = {
|
||||
"deployment_timestamp": timezone.now().timestamp(),
|
||||
"banners": banners,
|
||||
"home_sections": home_sections,
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
@ -399,4 +401,4 @@ def terms_of_service(request):
|
||||
'content': app_settings.terms_of_service if app_settings else _("Terms of service are coming soon.")
|
||||
}
|
||||
}
|
||||
return render(request, 'core/article_detail.html', context)
|
||||
return render(request, 'core/article_detail.html', context)
|
||||
|
||||
BIN
media/app/ahlalalkhair_logo.jpg
Normal file
BIN
media/app/ahlalalkhair_logo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
BIN
media/app/masarlogo.jpg
Normal file
BIN
media/app/masarlogo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Loading…
x
Reference in New Issue
Block a user