feat: contact form and more edits

This commit is contained in:
mohamad
2026-05-04 13:54:45 +03:30
parent 3c10f5c5ed
commit 744ef69942
49 changed files with 1073 additions and 179 deletions
+14 -1
View File
@@ -1,6 +1,19 @@
from django.contrib import admin
from .models import DownloadItem, FAQEntry
from .models import ContactSubmission, DownloadItem, FAQEntry
@admin.register(ContactSubmission)
class ContactSubmissionAdmin(admin.ModelAdmin):
list_display = ("name", "title", "email", "submitted_at", "is_read")
list_filter = ("is_read", "submitted_at")
search_fields = ("name", "title", "description", "email")
list_editable = ("is_read",)
readonly_fields = ("name", "title", "description", "email", "submitted_at")
fieldsets = (
(None, {"fields": ("name", "title", "email", "description")}),
("Meta", {"fields": ("submitted_at", "is_read")}),
)
@admin.register(FAQEntry)
+24
View File
@@ -0,0 +1,24 @@
from django import forms
from .models import ContactSubmission
class ContactForm(forms.ModelForm):
class Meta:
model = ContactSubmission
fields = ["name", "title", "description", "email"]
widgets = {
"name": forms.TextInput(
attrs={"placeholder": "Your full name", "autocomplete": "name"}
),
"title": forms.TextInput(attrs={"placeholder": "Subject / topic"}),
"description": forms.Textarea(
attrs={"placeholder": "Write your message here…", "rows": 5}
),
"email": forms.EmailInput(
attrs={
"placeholder": "your@email.com (optional)",
"autocomplete": "email",
}
),
}
@@ -0,0 +1,30 @@
# Generated by Django 5.0.2 on 2026-05-04 09:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pages', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ContactSubmission',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('title', models.CharField(max_length=300)),
('description', models.TextField()),
('email', models.EmailField(blank=True, max_length=254)),
('submitted_at', models.DateTimeField(auto_now_add=True)),
('is_read', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Contact Submission',
'verbose_name_plural': 'Contact Submissions',
'ordering': ['-submitted_at'],
},
),
]
+17
View File
@@ -1,6 +1,23 @@
from django.db import models
class ContactSubmission(models.Model):
name = models.CharField(max_length=200)
title = models.CharField(max_length=300)
description = models.TextField()
email = models.EmailField(blank=True)
submitted_at = models.DateTimeField(auto_now_add=True)
is_read = models.BooleanField(default=False)
class Meta:
ordering = ["-submitted_at"]
verbose_name = "Contact Submission"
verbose_name_plural = "Contact Submissions"
def __str__(self):
return f"{self.name}{self.title}"
class FAQEntry(models.Model):
question = models.CharField(max_length=500)
answer = models.TextField()
+2 -2
View File
@@ -27,14 +27,14 @@ class AboutViewTest(TestCase):
class DownloadsViewTest(TestCase):
def setUp(self):
DownloadItem.objects.create(
name="ViSERA Desktop",
name="Radiuma Desktop",
platform="windows",
version="1.0",
download_url="https://example.com/windows",
is_active=True,
)
DownloadItem.objects.create(
name="ViSERA Desktop",
name="Radiuma Desktop",
platform="macos",
version="Coming Soon",
download_url="#",
+46 -2
View File
@@ -1,6 +1,12 @@
import random
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django.views.generic import ListView, TemplateView
from .models import DownloadItem, FAQEntry
from .forms import ContactForm
from .models import ContactSubmission, DownloadItem, FAQEntry
class HomeView(TemplateView):
@@ -36,5 +42,43 @@ class FAQView(ListView):
queryset = FAQEntry.objects.filter(is_active=True)
class ContactView(TemplateView):
class ContactView(View):
template_name = "pages/contact.html"
def _new_captcha(self, request):
a, b = random.randint(1, 9), random.randint(1, 9)
request.session["captcha_answer"] = a + b
return f"{a} + {b}"
def get(self, request, *args, **kwargs):
return render(
request,
self.template_name,
{"form": ContactForm(), "captcha_question": self._new_captcha(request)},
)
def post(self, request, *args, **kwargs):
form = ContactForm(request.POST)
expected = request.session.get("captcha_answer")
captcha_question = self._new_captcha(request)
captcha_ok = False
try:
captcha_ok = int(request.POST.get("captcha_answer", "")) == expected
except (ValueError, TypeError):
pass
if form.is_valid() and captcha_ok:
form.save()
return JsonResponse({"success": True})
errors: dict = {}
if not captcha_ok:
errors["captcha"] = ["Incorrect answer — please try again."]
errors.update(
{field: [str(e) for e in errs] for field, errs in form.errors.items()}
)
return JsonResponse(
{"success": False, "errors": errors, "captcha_question": captcha_question},
status=400,
)