feat: admin panel enrichment
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from apps.pages.contact_uploads import validate_contact_attachments
|
||||
|
||||
from .models import ProjectBrief
|
||||
|
||||
WIZARD_STEPS = [
|
||||
{
|
||||
"id": "basics",
|
||||
"title": "Project basics",
|
||||
"subtitle": "Give your project a name and category.",
|
||||
"fields": ["title", "category"],
|
||||
},
|
||||
{
|
||||
"id": "scope",
|
||||
"title": "Description & goals",
|
||||
"subtitle": "Describe the project scope, context, and the outcomes you expect.",
|
||||
"fields": ["description"],
|
||||
},
|
||||
{
|
||||
"id": "timeline",
|
||||
"title": "Budget & timeline",
|
||||
"subtitle": "Share your budget range and target deadline.",
|
||||
"fields": ["budget_range", "desired_deadline"],
|
||||
},
|
||||
{
|
||||
"id": "references",
|
||||
"title": "References & files",
|
||||
"subtitle": "Add links and supporting files, then review your brief.",
|
||||
"fields": ["reference_links", "attachments"],
|
||||
},
|
||||
]
|
||||
|
||||
REQUIRED_FIELDS = ("title",)
|
||||
|
||||
|
||||
class ProjectBriefForm(forms.ModelForm):
|
||||
attachments = forms.Field(required=False)
|
||||
|
||||
class Meta:
|
||||
model = ProjectBrief
|
||||
fields = [
|
||||
"title",
|
||||
"category",
|
||||
"description",
|
||||
"budget_range",
|
||||
"desired_deadline",
|
||||
"reference_links",
|
||||
]
|
||||
widgets = {
|
||||
"title": forms.TextInput(attrs={"placeholder": "Project title"}),
|
||||
"category": forms.Select(),
|
||||
"description": forms.Textarea(
|
||||
attrs={
|
||||
"placeholder": "Describe the project scope, context, and goals",
|
||||
"rows": 7,
|
||||
}
|
||||
),
|
||||
"budget_range": forms.Select(),
|
||||
"desired_deadline": forms.DateInput(attrs={"type": "date"}),
|
||||
"reference_links": forms.Textarea(
|
||||
attrs={
|
||||
"placeholder": "Links to docs, mockups, repos (one per line)",
|
||||
"rows": 3,
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, *args, file_list=None, **kwargs):
|
||||
self.file_list = file_list
|
||||
super().__init__(*args, **kwargs)
|
||||
optional_choice_fields = {
|
||||
"category": "Select a category (optional)",
|
||||
"budget_range": "Select a budget range (optional)",
|
||||
}
|
||||
for field_name, empty_label in optional_choice_fields.items():
|
||||
field = self.fields[field_name]
|
||||
field.required = False
|
||||
field.choices = [("", empty_label)] + list(field.choices)
|
||||
for field_name in self.fields:
|
||||
self.fields[field_name].required = field_name in REQUIRED_FIELDS
|
||||
for field in self.fields.values():
|
||||
if isinstance(
|
||||
field.widget,
|
||||
(forms.TextInput, forms.Textarea, forms.Select, forms.DateInput),
|
||||
):
|
||||
field.widget.attrs.setdefault("class", "form-control")
|
||||
if self.instance and self.instance.pk:
|
||||
for field_name in self.fields:
|
||||
if self.instance.is_field_locked(field_name):
|
||||
self.fields[field_name].disabled = True
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
try:
|
||||
cleaned_data["attachments"] = validate_contact_attachments(self.file_list)
|
||||
except ValidationError as exc:
|
||||
self.add_error("attachments", exc)
|
||||
cleaned_data["attachments"] = []
|
||||
return cleaned_data
|
||||
|
||||
def first_error_step(self):
|
||||
for index, step in enumerate(WIZARD_STEPS, start=1):
|
||||
for field_name in step["fields"]:
|
||||
if field_name in self.errors:
|
||||
return index
|
||||
return 1
|
||||
|
||||
def step_for_field(self, field_name):
|
||||
for index, step in enumerate(WIZARD_STEPS, start=1):
|
||||
if field_name in step["fields"]:
|
||||
return index
|
||||
return 1
|
||||
Reference in New Issue
Block a user