From f0ffe83f835f0728abfefddc30117714974ad05c Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Wed, 21 Jan 2026 19:22:45 -0300 Subject: [PATCH] feat: improvements on deleting account. --- app/Concerns/ProfileValidationRules.php | 12 -- .../Settings/PasswordController.php | 3 + .../Settings/ProfileController.php | 65 ++++++- app/Http/Middleware/HandleInertiaRequests.php | 2 + database/seeders/LanguageSeeder.php | 4 +- resources/js/components/AppSidebar.vue | 40 +++- resources/js/components/Toast.vue | 110 +++-------- resources/js/layouts/app/AppSidebarLayout.vue | 2 + resources/js/pages/settings/Password.vue | 36 +--- resources/js/pages/settings/Profile.vue | 178 +++++++----------- routes/settings.php | 2 +- tests/Feature/Settings/ProfileUpdateTest.php | 95 +++++++++- 12 files changed, 313 insertions(+), 236 deletions(-) diff --git a/app/Concerns/ProfileValidationRules.php b/app/Concerns/ProfileValidationRules.php index 22ffcaab..92878f9c 100644 --- a/app/Concerns/ProfileValidationRules.php +++ b/app/Concerns/ProfileValidationRules.php @@ -2,7 +2,6 @@ namespace App\Concerns; -use App\Models\Language; use App\Models\User; use Illuminate\Validation\Rule; @@ -18,20 +17,9 @@ protected function profileRules(string|int|null $userId = null): array return [ 'name' => $this->nameRules(), 'email' => $this->emailRules($userId), - 'language_id' => $this->languageRules(), ]; } - /** - * Get the validation rules used to validate user language. - * - * @return array|string> - */ - protected function languageRules(): array - { - return ['required', Rule::exists(Language::class, 'id')]; - } - /** * Get the validation rules used to validate user names. * diff --git a/app/Http/Controllers/Settings/PasswordController.php b/app/Http/Controllers/Settings/PasswordController.php index d51afe4a..d5e4c485 100644 --- a/app/Http/Controllers/Settings/PasswordController.php +++ b/app/Http/Controllers/Settings/PasswordController.php @@ -27,6 +27,9 @@ public function update(PasswordUpdateRequest $request): RedirectResponse 'password' => $request->password, ]); + session()->flash('flash.banner', 'Password updated successfully!'); + session()->flash('flash.bannerStyle', 'success'); + return back(); } } diff --git a/app/Http/Controllers/Settings/ProfileController.php b/app/Http/Controllers/Settings/ProfileController.php index 42d23c3e..3c185525 100644 --- a/app/Http/Controllers/Settings/ProfileController.php +++ b/app/Http/Controllers/Settings/ProfileController.php @@ -2,14 +2,15 @@ namespace App\Http\Controllers\Settings; +use App\Enums\UserWorkspace\Role; use App\Http\Controllers\Controller; use App\Http\Requests\Settings\ProfileDeleteRequest; use App\Http\Requests\Settings\ProfileUpdateRequest; -use App\Models\Language; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; use Inertia\Inertia; use Inertia\Response; @@ -23,7 +24,6 @@ public function edit(Request $request): Response return Inertia::render('settings/Profile', [ 'mustVerifyEmail' => $request->user() instanceof MustVerifyEmail, 'status' => $request->session()->get('status'), - 'languages' => Language::all(), ]); } @@ -40,9 +40,31 @@ public function update(ProfileUpdateRequest $request): RedirectResponse $request->user()->save(); + session()->flash('flash.banner', 'Profile updated successfully!'); + session()->flash('flash.bannerStyle', 'success'); + return to_route('profile.edit'); } + /** + * Update the user's language. + */ + public function updateLanguage(Request $request): RedirectResponse + { + $request->validate([ + 'language_id' => ['required', 'exists:languages,id'], + ]); + + $request->user()->update([ + 'language_id' => $request->language_id, + ]); + + session()->flash('flash.banner', 'Language updated successfully!'); + session()->flash('flash.bannerStyle', 'success'); + + return back(); + } + /** * Delete the user's profile. */ @@ -50,6 +72,45 @@ public function destroy(ProfileDeleteRequest $request): RedirectResponse { $user = $request->user(); + DB::transaction(function () use ($user) { + // Cancel active Stripe subscription and delete subscription records + if ($user->subscribed('default')) { + $user->subscription('default')->cancelNow(); + } + $user->subscriptions()->delete(); + + // Clear current workspace reference + $user->update(['current_workspace_id' => null]); + + // Delete all workspaces owned by the user + $ownedWorkspaces = $user->workspaces()->wherePivot('role', Role::Owner->value)->get(); + + foreach ($ownedWorkspaces as $workspace) { + // Update members who have this as current_workspace_id + foreach ($workspace->members as $member) { + if ($member->id !== $user->id && $member->current_workspace_id === $workspace->id) { + // Find another workspace for this member + $otherWorkspace = $member->workspaces() + ->where('workspaces.id', '!=', $workspace->id) + ->first(); + + $member->update(['current_workspace_id' => $otherWorkspace?->id]); + } + } + + $workspace->posts()->delete(); + $workspace->socialAccounts()->delete(); + $workspace->hashtags()->delete(); + $workspace->labels()->delete(); + $workspace->invites()->delete(); + $workspace->members()->detach(); + $workspace->delete(); + } + + // Remove user from workspaces where they are a member + $user->workspaces()->detach(); + }); + Auth::logout(); $user->delete(); diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 0fcc690b..afd63c8f 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -2,6 +2,7 @@ namespace App\Http\Middleware; +use App\Models\Language; use Illuminate\Http\Request; use Inertia\Middleware; @@ -62,6 +63,7 @@ public function share(Request $request): array 'env' => config('app.env'), 'locale' => app()->getLocale(), 'selfHosted' => config('trypost.self_hosted'), + 'languages' => Language::all(), ]; } } diff --git a/database/seeders/LanguageSeeder.php b/database/seeders/LanguageSeeder.php index 0db7da70..2874999c 100644 --- a/database/seeders/LanguageSeeder.php +++ b/database/seeders/LanguageSeeder.php @@ -12,7 +12,7 @@ class LanguageSeeder extends Seeder */ public function run(): void { - Language::create(['name' => 'English', 'code' => 'en-US']); - Language::create(['name' => 'Português', 'code' => 'pt-BR']); + Language::create(['name' => 'English (US)', 'code' => 'en-US']); + Language::create(['name' => 'Português (BR)', 'code' => 'pt-BR']); } } diff --git a/resources/js/components/AppSidebar.vue b/resources/js/components/AppSidebar.vue index 34a1d58c..e5ab03c7 100644 --- a/resources/js/components/AppSidebar.vue +++ b/resources/js/components/AppSidebar.vue @@ -1,8 +1,9 @@