adding contact form

This commit is contained in:
Flatlogic Bot 2026-01-24 08:44:46 +00:00
parent d8b540ccd4
commit 7c076b687a
14 changed files with 204 additions and 10 deletions

View File

@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.utils.html import format_html
import os
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection, ContactMessage
from .whatsapp import send_whatsapp_message
@admin.register(Country)
@ -189,4 +189,12 @@ 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')
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')
@admin.register(ContactMessage)
class ContactMessageAdmin(admin.ModelAdmin):
list_display = ('subject', 'name', 'email', 'created_at', 'is_read')
list_filter = ('is_read', 'created_at')
search_fields = ('subject', 'name', 'email', 'message')
readonly_fields = ('created_at',)
list_editable = ('is_read',)

View File

@ -1,5 +1,5 @@
from django import forms
from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City, TruckType, AppSetting
from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City, TruckType, AppSetting, ContactMessage
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
@ -187,4 +187,15 @@ class AppSettingForm(forms.ModelForm):
'shipper_annual_fee': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'truck_owner_monthly_fee': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'truck_owner_annual_fee': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
}
}
class ContactForm(forms.ModelForm):
class Meta:
model = ContactMessage
fields = ['name', 'email', 'subject', 'message']
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Your Name')}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': _('Your Email')}),
'subject': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Subject')}),
'message': forms.Textarea(attrs={'class': 'form-control', 'rows': 5, 'placeholder': _('Your Message')}),
}

View File

@ -0,0 +1,30 @@
# Generated by Django 5.2.7 on 2026-01-24 08:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0022_alter_truck_driver_license_back_and_more'),
]
operations = [
migrations.CreateModel(
name='ContactMessage',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, verbose_name='Name')),
('email', models.EmailField(max_length=254, verbose_name='Email')),
('subject', models.CharField(max_length=200, verbose_name='Subject')),
('message', models.TextField(verbose_name='Message')),
('created_at', models.DateTimeField(auto_now_add=True)),
('is_read', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Contact Message',
'verbose_name_plural': 'Contact Messages',
'ordering': ['-created_at'],
},
),
]

View File

@ -474,4 +474,20 @@ class Transaction(models.Model):
super().save(*args, **kwargs)
def __str__(self):
return f"{self.receipt_number} - {self.user.username} ({self.amount})"
return f"{self.receipt_number} - {self.user.username} ({self.amount})"
class ContactMessage(models.Model):
name = models.CharField(_('Name'), max_length=100)
email = models.EmailField(_('Email'))
subject = models.CharField(_('Subject'), max_length=200)
message = models.TextField(_('Message'))
created_at = models.DateTimeField(auto_now_add=True)
is_read = models.BooleanField(default=False)
class Meta:
verbose_name = _('Contact Message')
verbose_name_plural = _('Contact Messages')
ordering = ['-created_at']
def __str__(self):
return f"{self.subject} - {self.name}"

View File

@ -66,6 +66,9 @@
</li>
{% endif %}
{% endif %}
<li class="nav-item">
<a class="nav-link" href="{% url 'contact' %}">{% trans "Contact" %}</a>
</li>
<li class="nav-item dropdown ms-lg-3">
<a class="nav-link dropdown-toggle" href="#" id="langDropdown" role="button" data-bs-toggle="dropdown">
@ -156,7 +159,7 @@
<ul class="list-unstyled">
<li><a href="{% url 'privacy_policy' %}" class="text-white-50 text-decoration-none">{% trans "Privacy Policy" %}</a></li>
<li><a href="{% url 'terms_of_service' %}" class="text-white-50 text-decoration-none">{% trans "Terms of Service" %}</a></li>
<li><a href="#" class="text-white-50 text-decoration-none">{% trans "Contact Us" %}</a></li>
<li><a href="{% url 'contact' %}" class="text-white-50 text-decoration-none">{% trans "Contact Us" %}</a></li>
</ul>
</div>
<div class="col-md-4 mb-4">
@ -186,4 +189,4 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</html>

View File

@ -0,0 +1,101 @@
{% extends 'base.html' %}
{% load i18n %}
{% block content %}
<section class="py-5 bg-light">
<div class="container py-5">
<div class="row g-5">
<!-- Contact Info -->
<div class="col-lg-5">
<div class="mb-5">
<h1 class="fw-bold mb-3">{% trans "Get in Touch" %}</h1>
<p class="text-muted lead">
{% trans "Have questions about our services or need assistance? Fill out the form and our team will get back to you shortly." %}
</p>
</div>
<div class="d-flex mb-4">
<div class="flex-shrink-0">
<div class="bg-primary text-white p-3 rounded-3" style="width: 50px; height: 50px; display: flex; align-items: center; justify-content: center;">
<i class="fa-solid fa-phone"></i>
</div>
</div>
<div class="ms-4">
<h5 class="fw-bold">{% trans "Phone" %}</h5>
<p class="text-muted">{{ app_settings.contact_phone|default:"+966 XXX XXX XXX" }}</p>
</div>
</div>
<div class="d-flex mb-4">
<div class="flex-shrink-0">
<div class="bg-primary text-white p-3 rounded-3" style="width: 50px; height: 50px; display: flex; align-items: center; justify-content: center;">
<i class="fa-solid fa-envelope"></i>
</div>
</div>
<div class="ms-4">
<h5 class="fw-bold">{% trans "Email" %}</h5>
<p class="text-muted">{{ app_settings.contact_email|default:"info@masarcargo.com" }}</p>
</div>
</div>
<div class="d-flex mb-4">
<div class="flex-shrink-0">
<div class="bg-primary text-white p-3 rounded-3" style="width: 50px; height: 50px; display: flex; align-items: center; justify-content: center;">
<i class="fa-solid fa-location-dot"></i>
</div>
</div>
<div class="ms-4">
<h5 class="fw-bold">{% trans "Address" %}</h5>
<p class="text-muted">{{ app_settings.contact_address|default:"Muscat, Oman"|linebreaksbr }}</p>
</div>
</div>
</div>
<!-- Contact Form -->
<div class="col-lg-7">
<div class="card border-0 shadow-sm rounded-4 p-4 p-md-5">
<h2 class="fw-bold mb-4">{% trans "Send us a Message" %}</h2>
<form method="post" novalidate>
{% csrf_token %}
<div class="row g-3">
<div class="col-md-6">
<label class="form-label fw-bold small text-uppercase">{% trans "Your Name" %}</label>
{{ form.name }}
{% if form.name.errors %}
<div class="text-danger small mt-1">{{ form.name.errors }}</div>
{% endif %}
</div>
<div class="col-md-6">
<label class="form-label fw-bold small text-uppercase">{% trans "Email Address" %}</label>
{{ form.email }}
{% if form.email.errors %}
<div class="text-danger small mt-1">{{ form.email.errors }}</div>
{% endif %}
</div>
<div class="col-12">
<label class="form-label fw-bold small text-uppercase">{% trans "Subject" %}</label>
{{ form.subject }}
{% if form.subject.errors %}
<div class="text-danger small mt-1">{{ form.subject.errors }}</div>
{% endif %}
</div>
<div class="col-12">
<label class="form-label fw-bold small text-uppercase">{% trans "Message" %}</label>
{{ form.message }}
{% if form.message.errors %}
<div class="text-danger small mt-1">{{ form.message.errors }}</div>
{% endif %}
</div>
<div class="col-12 mt-4">
<button type="submit" class="btn btn-primary btn-lg px-5 rounded-pill w-100">
{% trans "Send Message" %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
{% endblock %}

View File

@ -22,6 +22,7 @@ urlpatterns = [
path("bid/<int:bid_id>/reject/", views.reject_bid, name="reject_bid"),
path("privacy-policy/", views.privacy_policy, name="privacy_policy"),
path("terms-of-service/", views.terms_of_service, name="terms_of_service"),
path("contact/", views.contact, name="contact"),
path("subscription-expired/", views.subscription_expired, name="subscription_expired"),
path("subscription-renew/", views.renew_subscription, name="renew_subscription"),
path("payment/success/", views.thawani_success, name="thawani_success"),

View File

@ -5,10 +5,11 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate, logout
from django.utils import timezone
from django.urls import reverse
from .models import Profile, Truck, Shipment, Bid, Message, OTPCode, Country, City, AppSetting, Banner, HomeSection, Transaction
from .models import Profile, Truck, Shipment, Bid, Message, OTPCode, Country, City, AppSetting, Banner, HomeSection, Transaction, ContactMessage
from .forms import (
TruckForm, ShipmentForm, BidForm, UserRegistrationForm,
OTPVerifyForm, ShipperOfferForm, RenewSubscriptionForm, AppSettingForm
OTPVerifyForm, ShipperOfferForm, RenewSubscriptionForm, AppSettingForm,
ContactForm
)
from django.contrib import messages
from django.utils.translation import gettext as _
@ -23,6 +24,7 @@ from django.http import HttpResponse
from django.contrib.sites.shortcuts import get_current_site
import json
import logging
import os
logger = logging.getLogger(__name__)
@ -731,4 +733,26 @@ def admin_app_settings(request):
else:
form = AppSettingForm(instance=settings_obj)
return render(request, 'core/app_settings.html', {'form': form})
return render(request, 'core/app_settings.html', {'form': form})
def contact(request):
app_settings = AppSetting.objects.first()
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, _("Your message has been sent successfully! We will get back to you soon."))
return redirect('contact')
else:
messages.error(request, _("There was an error in your form. Please check the fields below."))
else:
form = ContactForm()
if request.user.is_authenticated:
# Pre-fill name and email if user is logged in
form.fields['name'].initial = request.user.get_full_name() or request.user.username
form.fields['email'].initial = request.user.email
return render(request, 'core/contact.html', {
'form': form,
'app_settings': app_settings
})