Skip to content

181 featprofile add complete user profile display with demographic data#190

Merged
NorbertAguilera merged 13 commits into
devfrom
181-featprofile-add-complete-user-profile-display-with-demographic-data
Jun 11, 2026
Merged

181 featprofile add complete user profile display with demographic data#190
NorbertAguilera merged 13 commits into
devfrom
181-featprofile-add-complete-user-profile-display-with-demographic-data

Conversation

@gery25

@gery25 gery25 commented Jun 9, 2026

Copy link
Copy Markdown
Member

PR: Add demographic fields and views analytics dashboards

Summary

Added demographic profile fields (gender, age range, municipality) to user registration and profile editing, along with 5 analytics dashboards for Admin/Staff users with Chart.js. Also includes a province→municipality two-dropdown selector linked via JS with data for all Spanish provinces and municipalities.

Changes made

Models (web_app/models.py)

  • Gender: TextChoices with Male, Female, Non-binary, Other
  • AgeRange: TextChoices with <18, 18-30, 31-50, >50
  • Province: Model with ine_code (2 chars, unique) and name
  • Municipality: Model with ine_code (5 chars, unique), name, FK to Province
  • CustomUser: New fields gender (CharField), age_range (CharField), municipality (FK to Municipality)

Forms (web_app/forms.py)

  • CustomUserCreationForm: Added gender, age_range, province, municipality fields with validation ensuring the municipality belongs to the selected province. save() persists all three new fields.
  • CustomUserChangeForm: Added province field (ModelChoiceField). __init__ pre-selects the user's current province. Same validation as registration.

Admin (web_app/admin.py)

  • Registered ProvinceAdmin and MunicipalityAdmin with list display and filters

URLs

  • web_app/urls.py: New route api/municipalities/<int:province_id>/ for AJAX municipality loading
  • users/urls.py: 5 new routes for demographic dashboards under admin/dashboard/demographics/

API (web_app/views.py)

  • municipalities_by_province: View returning JSON with municipalities for a given province

Profile views (users/views.py)

  • user_profile: Now passes provinces, current_province_id, and current_municipality_id to the template context

Analytics services (users/services.py)

  • _base_view_filters: Reusable filters for date and platform
  • get_views_by_gender: Views grouped by gender
  • get_views_by_age_range: Views grouped by age range
  • get_views_by_province: Top 10 provinces + "Others"
  • get_views_by_gender_age: Gender × age cross-tabulation (for grouped bar chart)

Dashboard views (users/views.py)

  • admin_dashboard_demographics: Overview with 4 mini-charts (doughnut, bar, horizontal bar, grouped bar)
  • admin_dashboard_views_by_gender: Doughnut chart + data table
  • admin_dashboard_views_by_age: Bar chart + data table
  • admin_dashboard_views_by_province: Horizontal bar chart (Top 10 + Others) + data table
  • admin_dashboard_cross_tab: Grouped bar chart (Gender on X-axis, colored by Age Range) + data table

All dashboard views use @user_passes_test(is_admin_or_staff) (Admin/Staff only).

Middleware (users/middleware.py)

  • Added the 5 new demographic routes to the Admin block's exempt URL list to prevent unexpected redirects

Templates

  • register.html: 4 new <select> elements (gender, age_range, province, municipality) with JS that fetches municipalities on province change
  • user_profile.html: Same, with current province/municipality pre-selected and initial load via JS
  • user_client.html: 3 new glass-cards in the sidebar (Gender, Age range, Location)
  • user_admin.html: New "Demographics" tab in the navigation menu
  • dashboard_demographics.html: Overview with 4 charts and sub-navigation pills
  • dashboard_views_by_gender.html: Doughnut Chart.js + data table
  • dashboard_views_by_age.html: Bar Chart.js + data table
  • dashboard_views_by_province.html: Horizontal Bar Chart.js + data table
  • dashboard_cross_tab.html: Grouped Bar Chart.js (Gender × Age) + data table

CSS

  • register.css: Styles for .form-group select (dark theme, custom arrow, disabled state)
  • user_profile.css: Styles for select.form-control (custom arrow, dark background for options)

Data (data/municipalities_spain.json)

  • JSON file with all 52 provinces and ~1155 Spanish municipalities, each with its INE code

Management command (web_app/management/commands/load_municipalities.py)

  • python manage.py load_municipalities: Reads the JSON and runs update_or_create for provinces and municipalities. Accepts optional --source for an alternate file path.

Known bug (not fixed in this PR)

Infinite 302 loop for non-superuser Staff Admin: AdminRedirectMiddleware redirects all type == 'Staff Admin' users to staff_admin_panel, but the staff_admin_panel view (and all other staff views) have @user_passes_test(lambda u: u.is_superuser). When a non-superuser Staff Admin tries to access any page, the middleware redirects them to the panel, the decorator redirects them to login, the middleware catches it → infinite loop.

Pending fix: Add 'login' to the Staff Admin exempt list in the middleware, or change the decorators to type == 'Staff Admin'.

Run after merge

python manage.py makemigrations && python manage.py migrate
python manage.py load_municipalities

@gery25 gery25 added this to the sprint 3 milestone Jun 9, 2026
@gery25 gery25 self-assigned this Jun 9, 2026
@gery25 gery25 added scope: frontend UI components, styling (CSS/SCSS), client-side logic, and state management. scope: backend API development, business logic, server-side services, and integrations. scope: database Schema changes, migrations, query optimization, and data persistence. type: feature New functionality or requirement implementation. type: refractor Code changes that improve structure or readability without changing behavior. labels Jun 9, 2026
@gery25 gery25 added this to Sprint 3 Jun 9, 2026
@gery25 gery25 added the scope: ui/ux For tasks that focus on the visual design of the login/header. label Jun 9, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in Sprint 3 Jun 9, 2026
@gery25 gery25 linked an issue Jun 9, 2026 that may be closed by this pull request
@gery25 gery25 moved this from Backlog to In review in Sprint 3 Jun 9, 2026
@github-project-automation github-project-automation Bot moved this from In review to Done in Sprint 3 Jun 11, 2026
@Bogdan2005-19 Bogdan2005-19 reopened this Jun 11, 2026
@Bogdan2005-19 Bogdan2005-19 temporarily deployed to 181-featprofile-add-complete-user-profile-display-with-demographic-data - JoinProject-dev PR #190 June 11, 2026 13:02 — with Render Destroyed
@NorbertAguilera NorbertAguilera merged commit 7f2fd23 into dev Jun 11, 2026
12 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: backend API development, business logic, server-side services, and integrations. scope: database Schema changes, migrations, query optimization, and data persistence. scope: frontend UI components, styling (CSS/SCSS), client-side logic, and state management. scope: ui/ux For tasks that focus on the visual design of the login/header. type: feature New functionality or requirement implementation. type: refractor Code changes that improve structure or readability without changing behavior.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(profile): add complete user profile display with demographic data

3 participants