Build M6 Edit personal info for the mobile app
The last of the seven Member-mode screens. A real editable form for the
fields Member actually has (first/last name, date of birth, email,
phone, emergency phone) -- the design mock's national-register-number,
address, allergies/notes and consent-toggle rows have no backing field
and are omitted rather than added as new schema for a screen-building
pass. Two mock rows do have real data and are shown read-only instead:
every guardian via Member.guardians ("Emergency contact"), and any open
onboarding requirement for the person's current-season membership (via
club.services.onboarding.checklist_for) as a banner -- no upload/complete
action, that stays staff-only elsewhere in the platform.
Authorization: the target Member (from the URL) must be one of the
signed-in account's managed_people, checked on both GET and POST -- an
unmanaged id 404s, same as another club's Event/News already does
elsewhere in this app.
This completes M1-M7 (Home, Event detail, Calendar, News article, Me &
my people, Edit personal info, Notifications). Coach mode (C1-C6) is a
separate, later phase per the design doc and is intentionally not
started here.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
39
mobile/forms.py
Normal file
39
mobile/forms.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from django import forms
|
||||
|
||||
from members.models import Member
|
||||
|
||||
#: Shared by every text-ish field below -- mobile has no equivalent of
|
||||
#: management/controlpanel's templatetags/field.html (which builds widget
|
||||
#: classes at render time for their daisyUI-shaped inputs), so this app's one
|
||||
#: form so far just bakes its own classes straight into the widget.
|
||||
_INPUT_CLASSES = "h-11 w-full rounded-lg border border-stroke bg-paper px-3 text-[15px] text-ink placeholder:text-dim focus:border-ink focus:outline-none"
|
||||
|
||||
|
||||
class MemberProfileForm(forms.ModelForm):
|
||||
"""M6 -- "Edit personal info" (design_handoff_rosterchief_platform/README.md).
|
||||
|
||||
Covers exactly the fields ``members.models.Member`` actually has. The
|
||||
design mock also shows a "National register no.", an "Address", an
|
||||
"Allergies / notes" field and two "Consent" toggles -- none of those have
|
||||
a backing field on ``Member`` (see EditProfileView's own docstring), so
|
||||
they're simply not part of this form rather than being invented here.
|
||||
|
||||
Same field list and date widget as ``management.forms.MemberForm`` (the
|
||||
staff-side equivalent editing the same model) -- diverging widget
|
||||
conventions across the platform for identical fields would be its own bug.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Member
|
||||
fields = ["first_name", "last_name", "date_of_birth", "email", "phone", "emergency_phone"]
|
||||
# Same date widget as management.forms.MemberForm. phone/emergency_phone
|
||||
# deliberately keep django-phonenumber-field's own RegionalPhoneNumberWidget
|
||||
# (national-format display, region-aware parsing) rather than being
|
||||
# swapped for a plain TextInput here -- __init__ below only adds a CSS
|
||||
# class to whatever widget each field already has, never replaces it.
|
||||
widgets = {"date_of_birth": forms.DateInput(attrs={"type": "date"})}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
for field in self.fields.values():
|
||||
field.widget.attrs["class"] = _INPUT_CLASSES
|
||||
Reference in New Issue
Block a user