Skip to content

Commit

Permalink
#161 - profile completeness progress bar (#196)
Browse files Browse the repository at this point in the history
Profile bar is loaded according to how many fields in profile is filled
  • Loading branch information
petrceska committed Sep 13, 2023
2 parents 3fbde08 + ff4f477 commit 5d61ec5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 25 deletions.
46 changes: 28 additions & 18 deletions fiesta/apps/accounts/forms/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ class UserProfileForm(BaseModelForm):
_FIELD_NAMES_TO_CONFIGURATION = {f.field.name: conf_field for f, conf_field in FIELDS_TO_CONFIGURATION.items()}

@classmethod
def for_user(
cls,
user: User,
) -> type[UserProfileForm]:
"""
Creates the profile form class for specific user.
Fields and configuration are constructed from all SectionsConfiguration from
all sections from all memberships of that specific user.
"""
def get_form_fields(cls, user: User):
confs = cls.get_user_configuration(user)
# TODO: what to do, when no specific configuration is found?

fields_to_include = tuple(
field_name
for field_name, conf_field in cls._FIELD_NAMES_TO_CONFIGURATION.items()
if any(conf_field.__get__(c) is not None for c in confs)
)
return cls.Meta.fields + fields_to_include

@classmethod
def get_user_configuration(cls, user: User):
# all related configurations
confs = SectionsConfiguration.objects.filter(
return SectionsConfiguration.objects.filter(
# from all user's memberships sections
plugins__section__memberships__in=user.memberships.filter(
# with waiting for confirmation or already active membership
Expand All @@ -43,23 +47,29 @@ def for_user(
)
)

# TODO: what to do, when no specific configuration is found?
@classmethod
def for_user(
cls,
user: User,
) -> type[UserProfileForm]:
"""
Creates the profile form class for specific user.
Fields and configuration are constructed from all SectionsConfiguration from
all sections from all memberships of that specific user.
"""
confs = cls.get_user_configuration(user)

def callback(f: Field, **kwargs) -> FormField:
# TODO: what to do, when no specific configuration is found?

if conf_field := cls._FIELD_NAMES_TO_CONFIGURATION.get(f.name):
return f.formfield(required=any(conf_field.__get__(c) for c in confs), **kwargs)
return f.formfield(**kwargs)

fields_to_include = tuple(
field_name
for field_name, conf_field in cls._FIELD_NAMES_TO_CONFIGURATION.items()
if any(conf_field.__get__(c) is not None for c in confs)
)

return modelform_factory(
model=UserProfile,
form=cls,
fields=cls.Meta.fields + fields_to_include,
fields=cls.get_form_fields(user),
formfield_callback=callback,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="Dashboard__tiles">
<div class="Dashboard__tile Dashboard__tile--dark shadow-2xl bg-gray-900 aspect-square">
<div class="Dashboard__tile__title text-white">{% blocktrans %}My Profile{% endblocktrans %}</div>
{% compute_profile_fullness user.profile as fullness %}
{% compute_profile_fullness user as fullness %}
{% interpolate_to_list fullness "text-red-400" "text-orange-400" "text-blue-400" "text-lime-400" as color %}
<div class="flex justify-center items-center my-4">
{# TODO: compute completness #}
Expand Down
15 changes: 10 additions & 5 deletions fiesta/apps/accounts/templatetags/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django import template

from apps.accounts.forms.profile import UserProfileForm
from apps.accounts.models import User, UserProfile

# from apps.plugins.middleware.plugin import HttpRequest
Expand All @@ -19,10 +20,14 @@ def get_user_picture(user: User | None):
return profile.picture


@register.simple_tag(takes_context=True)
def compute_profile_fullness(context: dict, profile: UserProfile) -> float:
# req: HttpRequest = context.get("request")
@register.simple_tag
def compute_profile_fullness(user: User) -> float:
fields = UserProfileForm.get_form_fields(user) # Get all field names of UserProfile
empty_fields = 0

# TODO: compute based on accounts conf and profile state
for field in fields:
field_value = getattr(user.profile, field, None)
if field_value is None or field_value == "": # So far it's not possible to have a field with False value
empty_fields += 1

return 0.77
return (len(fields) - empty_fields) / len(fields)
2 changes: 1 addition & 1 deletion fiesta/apps/utils/templatetags/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def map_attrgetter(iterable: Reversible, attr: str):

@register.simple_tag
def interpolate_to_list(value: float, *values: typing.Any):
return values[int(min(1, max(0, value)) * len(values))]
return values[int(min(1, max(0, value)) * len(values)) - 1]


@register.filter
Expand Down

0 comments on commit 5d61ec5

Please sign in to comment.