Skip to content

Modernize profile page styles#112

Open
hendriebeats wants to merge 7 commits into
masterfrom
update-profile-page-styles
Open

Modernize profile page styles#112
hendriebeats wants to merge 7 commits into
masterfrom
update-profile-page-styles

Conversation

@hendriebeats

@hendriebeats hendriebeats commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

Redesigns the profile page with a card-based layout, an avatar header showing the user's name and email, and constrained-width content area. Save buttons are disabled until the user actually changes something.

Layout & scroll

  • html, body { overflow: hidden }: The scroll container is #profileScroll (not the body), so this prevents a double scrollbar — one from the browser and one from the inner div.
  • height: calc(100vh - 52px): The 52px accounts for the fixed nav height so the scroll area fills exactly the remaining viewport.
  • Footer moved inside #profileScroll: Keeps the footer at the bottom of the scroll container (margin-top: auto) rather than below it.

Dirty-tracking (Save button enabled state)

  • Buttons start disabled in the template: Guarantees they're inactive even before JS runs, avoiding a flash of an enabled button on load.
  • FormData snapshot as baseline: Captures text inputs and checkboxes uniformly without manually enumerating fields; works for both forms with a single approach.
  • window load (not DOMContentLoaded): inputs.js (also on load) resets input values from their HTML attributes to work around HTMX re-use quirks — our snapshot must run after that, and same-event listeners fire in registration order.
  • htmx:afterSwap re-init: After a successful save HTMX replaces the form's outerHTML; the new form's saved values become the new baseline so the button returns to disabled.
  • cursor: default on button.blue:disabled: The previous not-allowed cursor and red border were jarring for a "nothing has changed yet" state; the lighter blue background alone is sufficient to indicate the button is inactive.

Other

  • Label for fix: Both labels previously pointed to for="name" with no matching id; clicking "Email" would have focused the name input. Prefixed ids (profileName, profileEmail) avoid any collision with other forms on the page.
  • checkboxRow class: Replaced the ambient .profileCard form div selector (which would match any future div inside a card form) with an explicit opt-in class.
  • Feature label: Removed the raw enum name prefix (GroupStudy - …) from the feature toggle label; the description alone is sufficient now that it reads "Group Studies (Beta)".

hendriebeats and others added 2 commits February 19, 2026 01:08
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add id attributes to profile form inputs so label for= attributes
  actually work (clicking "Name"/"Email" now focuses the right input;
  both labels previously pointed to a non-existent id)
- Replace ambient .profileCard form div selector with .checkboxRow
  to avoid unintended matches on future divs inside card forms
- Apply checkboxRow class to feature checkbox wrapper elements
- Convert #12 hex-alpha shadow to rgba(0,0,0,0.07) for broader
  browser compatibility and consistency with the avatar shadow above it
Both profile forms (info and features) now start with their Save
button disabled. A FormData snapshot is taken after inputs.js
initialises values on page load; any input/change event re-enables
the button only when the current state differs from that baseline.
After a successful HTMX swap the swapped-in form re-initialises,
returning the button to disabled with the fresh server values as
the new baseline.
@hendriebeats hendriebeats added Size: Medium 101–400 lines: Multi-file change, needs focused review but still manageable. labels Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Size: Medium 101–400 lines: Multi-file change, needs focused review but still manageable.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant