Repository navigation
[Core]: User pages in the Core Module #18
Copy link
Copy link
Closed
Milestone
Description
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
userstable viaUserService::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 touchcreated_at/updated_aton save.- Password update must go through
Hash::make()— never store plain text. - Avatar upload should reuse
Modules\Core\Models\Uploadand store to the configured disk.
Flag for manual deletion: Comments #3705247869 (nielsdrost7) and #3705247976 (coderabbitai) on this issue are stale and should be removed.
Metadata
Metadata
Assignees
Labels
No labels
Activity
[-]User[/-][+][Core] User pages in the Core Module[/+]nielsdrost7 commentedon Jan 2, 2026
@coderabbitai make pull-request with AAA test Scenario's: Arrange, Act, Assert. And also make sure you test edge cases
coderabbitai commentedon Jan 2, 2026
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.
[-][Core] User pages in the Core Module[/-][+][Core]: User pages in the Core Module[/+]nielsdrost7 commentedon Jun 14, 2026
Sprint 5 — Implementation Plan
The spec in this issue is complete. Here's the file-level checklist:
Files to create:
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)Modules/Core/Filament/Company/Pages/MyCompanies.php— Livewire page listingauth()->user()->companies()as a table with company name,search_code, role, and a "Switch" buttonRegistration: Add both pages to
CompanyPanelProviderinModules/Core/Providers/CompanyPanelProvider.php:->pages([ EditProfile::class, MyCompanies::class, ])Routes: Filament auto-generates:
/{tenant}/my-profile→EditProfile/{tenant}/my-companies→MyCompaniesService call:
EditProfilemust callUserService::updateProfile()on save. Add this method toModules/Core/Services/UserService.phpif missing — it shouldHash::make()password before saving, and respectUser::$timestamps = false.Key constraints:
User::$timestamps = false— never touchcreated_at/updated_atModules\Core\Models\Uploadand store to configured diskHash::make(), never plain textTests: All three PHPUnit test methods in the issue body are ready to copy into a new file:
Modules/Core/Tests/Feature/UserProfileTest.phpEffort: ~5 hours.
Generated by Claude Code
fix: address remaining CodeRabbit findings for Subscriptions module