Skip to content

[Core]: User pages in the Core Module #18

Closed

Description

@naui95

Story: User Profile & Company Membership Pages

As a logged-in user, I want a dedicated "My Profile" page where I can update my personal data (name, email, password, avatar, locale) and a "My Companies" page where I can view and manage my company memberships, so that I can keep my account details accurate without needing admin intervention.


Scope

Page Panel Path
User data form Company panel /{tenant}/my-profile
User company form Company panel /{tenant}/my-companies

Acceptance Criteria

User Data Form

  • Fields: first name, last name, email (with re-verification flow), password (with confirmation), locale/timezone, avatar upload.
  • Validation mirrors Laravel's built-in password rules; email change triggers a re-verification email.
  • Form saves to users table via UserService::updateProfile().
  • Success shows a Filament notification "Profile updated".

User Company Form

  • Lists all companies the authenticated user belongs to via $user->companies().
  • Each row shows company name, search_code, and the user's role in that company.
  • A "Switch" button calls Filament::setTenant($company) and redirects to that company's dashboard.
  • No ability to leave a company from this page (admin-only operation).

Test Scenarios (PHPUnit + Livewire)

// User data form saves
/* Arrange */ $this->testLivewire(EditProfile::class)
/* Act */     ->fillForm(['first_name' => 'Jane', 'last_name' => 'Doe'])
              ->call('save')
/* Assert */  ->assertHasNoFormErrors();
              $this->assertDatabaseHas('users', ['first_name' => 'Jane']);
// Company list renders
/* Arrange */ $this->testLivewire(MyCompanies::class)
/* Act */     ->assertSuccessful()
/* Assert */  ->assertSee($this->company->name);
// Password change requires confirmation
/* Arrange */ $this->testLivewire(EditProfile::class)
/* Act */     ->fillForm(['password' => 'NewSecure!1', 'password_confirmation' => 'wrong'])
              ->call('save')
/* Assert */  ->assertHasFormErrors(['password']);

Notes

  • User::$timestamps = false — do not touch created_at/updated_at on save.
  • Password update must go through Hash::make() — never store plain text.
  • Avatar upload should reuse Modules\Core\Models\Upload and store to the configured disk.

Flag for manual deletion: Comments #3705247869 (nielsdrost7) and #3705247976 (coderabbitai) on this issue are stale and should be removed.

Activity

  1. added this to the v2.0.0-alpha milestone on Jun 16, 2024
  2. transferred this issue fromon Jan 6, 2025
  3. changed the title [-]User[/-] [+][Core] User pages in the Core Module[/+] on Jul 14, 2025
  4. nielsdrost7 commented on Jan 2, 2026

    @nielsdrost7
    Collaborator

    @coderabbitai make pull-request with AAA test Scenario's: Arrange, Act, Assert. And also make sure you test edge cases

  5. coderabbitai commented on Jan 2, 2026

    @coderabbitai
    Contributor

    Rate Limit Exceeded

    @nielsdrost7 have exceeded the limit for the number of chat messages per hour. Please wait 1 minutes and 52 seconds before sending another message.

  6. changed the title [-][Core] User pages in the Core Module[/-] [+][Core]: User pages in the Core Module[/+] on Jun 13, 2026
  7. nielsdrost7 commented on Jun 14, 2026

    @nielsdrost7
    Collaborator

    Sprint 5 — Implementation Plan

    The spec in this issue is complete. Here's the file-level checklist:

    Files to create:

    1. Modules/Core/Filament/Company/Pages/Auth/EditProfile.php — Livewire page with a Filament form containing: first_name, last_name, email, password, password_confirmation, language/timezone, avatar (FileUpload)
    2. Modules/Core/Filament/Company/Pages/MyCompanies.php — Livewire page listing auth()->user()->companies() as a table with company name, search_code, role, and a "Switch" button

    Registration: Add both pages to CompanyPanelProvider in Modules/Core/Providers/CompanyPanelProvider.php:

    ->pages([
        EditProfile::class,
        MyCompanies::class,
    ])

    Routes: Filament auto-generates:

    • /{tenant}/my-profile → EditProfile
    • /{tenant}/my-companies → MyCompanies

    Service call: EditProfile must call UserService::updateProfile() on save. Add this method to Modules/Core/Services/UserService.php if missing — it should Hash::make() password before saving, and respect User::$timestamps = false.

    Key constraints:

    • User::$timestamps = false — never touch created_at/updated_at
    • Avatar → use Modules\Core\Models\Upload and store to configured disk
    • Password → always Hash::make(), never plain text

    Tests: All three PHPUnit test methods in the issue body are ready to copy into a new file: Modules/Core/Tests/Feature/UserProfileTest.php

    Effort: ~5 hours.


    Generated by Claude Code

  8. removed their assignment
    on Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions