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