diff --git a/app/Livewire/Admin/Plans.php b/app/Livewire/Admin/Plans.php index a901e9c..4b64db3 100644 --- a/app/Livewire/Admin/Plans.php +++ b/app/Livewire/Admin/Plans.php @@ -7,29 +7,32 @@ use Illuminate\View\View; use Jantinnerezo\LivewireAlert\LivewireAlert; use Livewire\Attributes\Layout; +use Livewire\Attributes\Session; +use Livewire\Attributes\Url; use Livewire\Component; use Livewire\WithPagination; -use Spatie\Permission\Models\Permission; class Plans extends Component { use LivewireAlert; use WithPagination; + #[Session] public int $perPage = 25; public string $sortField = 'title'; public bool $sortAsc = true; + #[Url] public string $search = ''; public array $searchableFields = ['title', 'slug', 'stripe_id']; protected $listeners = [ - 'deletePermission' => 'destroy', - 'permissionCreated' => '$refresh', - 'permissionUpdated' => '$refresh', + 'deletePlan' => 'destroy', + 'planCreated' => '$refresh', + 'planUpdated' => '$refresh', ]; public function updatingSearch(): void @@ -52,19 +55,23 @@ public function sortBy($field): void public function render(): View { return view('livewire.admin.plans', [ - 'plans' => Plan::query()->search($this->searchableFields, $this->search) + 'plans' => Plan::query() + ->when($this->search, function ($query) { + $query->search($this->searchableFields, $this->search); + }) ->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc') ->paginate($this->perPage), ]); } - public function destroy($id): void + public function deletePlan(string $id): void { try { - Permission::query()->find($id)->delete(); - $this->alert('success', 'Permission deleted successfully!'); + Plan::query()->where('id', '=', $id)->delete(); + $this->alert('success', __('plans.plan_was_deleted')); + $this->dispatch('deletePlan'); } catch (Exception $e) { - $this->alert('error', 'Something went wrong!'); + $this->alert('error', __('plans.something_went_wrong')); } } } diff --git a/app/Livewire/Admin/Plans/CreatePlan.php b/app/Livewire/Admin/Plans/CreatePlan.php index 198fc2d..252c4b2 100644 --- a/app/Livewire/Admin/Plans/CreatePlan.php +++ b/app/Livewire/Admin/Plans/CreatePlan.php @@ -4,11 +4,14 @@ use App\Models\Plan; use Illuminate\Contracts\View\View; +use Jantinnerezo\LivewireAlert\LivewireAlert; use Livewire\Attributes\Rule; use LivewireUI\Modal\ModalComponent; class CreatePlan extends ModalComponent { + use LivewireAlert; + #[Rule(['required', 'max:255', 'unique:plans,title'])] public string $title = ''; @@ -29,6 +32,11 @@ public function create(): void ]); $this->dispatch('planCreated'); + + $this->alert('success', 'Plan was created'); + + $this->closeModal(); + } public function mount(): void diff --git a/app/Livewire/Admin/Plans/EditPlan.php b/app/Livewire/Admin/Plans/EditPlan.php new file mode 100644 index 0000000..9d45e12 --- /dev/null +++ b/app/Livewire/Admin/Plans/EditPlan.php @@ -0,0 +1,58 @@ +check(), 403); + abort_unless(auth()->user()->hasPermissionTo('edit plans'), 403); + + $this->plan = $plan; + $this->title = $plan->title ?? ''; + $this->slug = $plan->slug ?? ''; + $this->stripe_id = $plan->stripe_id ?? ''; + } + + public function save() + { + $this->validate(); + + $this->plan->update([ + 'title' => $this->title, + 'slug' => $this->slug, + 'stripe_id' => $this->stripe_id, + ]); + + $this->alert('success', __('plans.update_successful')); + + $this->dispatch('planUpdated'); + + $this->closeModal(); + } + + public function render(): View + { + return view('livewire.admin.plans.edit-plan'); + } +} diff --git a/lang/en/plans.php b/lang/en/plans.php new file mode 100644 index 0000000..cb79786 --- /dev/null +++ b/lang/en/plans.php @@ -0,0 +1,13 @@ + 'Edit plan', + 'delete_plan' => 'Delete plan', + 'confirm_deletion' => 'Are you sure you want to delete this plan?', + 'no_plans_found' => 'No plans was found', + 'plan_was_deleted' => 'The Plan was deleted', + 'something_went_wrong' => 'Something went wrong.', + 'update_successful' => 'Plan was updated', + 'save' => 'Save', + 'cancel' => 'Cancel', +]; diff --git a/resources/views/livewire/admin/plans.blade.php b/resources/views/livewire/admin/plans.blade.php index d8069d7..80ac97f 100644 --- a/resources/views/livewire/admin/plans.blade.php +++ b/resources/views/livewire/admin/plans.blade.php @@ -14,4 +14,64 @@ class="text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-pr +
+
+ +
+ +
+
+ + + + {{ __('ID') }} + {{ __('Title') }} + + {{ __('Stripe ID') }} + + {{ __('Actions') }} + + + + @forelse ($plans as $plan) + + + {{ $plan->id }} + + {{ $plan->title }} + {{ $plan->stripe_id }} + + @can('edit plans') + + @lang('plans.edit_plan') + + @endcan + @can('delete plans') + + @lang('plans.delete_plan') + + @endcan + + + @empty + + +
+ @lang('plans.no_plans_found') +
+
+
+ @endforelse +
+
+ +
+ diff --git a/resources/views/livewire/admin/plans/edit-plan.blade.php b/resources/views/livewire/admin/plans/edit-plan.blade.php new file mode 100644 index 0000000..8f229a0 --- /dev/null +++ b/resources/views/livewire/admin/plans/edit-plan.blade.php @@ -0,0 +1,46 @@ +
+ +

+ {{ __('Edit Plan') }} +

+ +
+ + + @error('title') {{ $message }}@enderror +
+ +
+ + + @error('slug') {{ $message }}@enderror +
+ +
+ + + @error('stripe_id') {{ $message }}@enderror +
+ +
+ + + {{ __('plans.cancel') }} + +
+ +
diff --git a/tests/Feature/Livewire/Admin/Plans/EditPlanTest.php b/tests/Feature/Livewire/Admin/Plans/EditPlanTest.php index b3d9bbc..cc666cf 100644 --- a/tests/Feature/Livewire/Admin/Plans/EditPlanTest.php +++ b/tests/Feature/Livewire/Admin/Plans/EditPlanTest.php @@ -1 +1,87 @@ assertForbidden(); + + $user = User::factory()->create(); + /** @var User $user */ + $user->givePermissionTo('edit plans'); + + Livewire::actingAs($user) + ->test(EditPlan::class) + ->assertOk(); +}); + +it('can fetch the plan from the provided plan id', function () { + Livewire::test(EditPlan::class) + ->assertForbidden(); + + $user = User::factory()->create(); + /** @var User $user */ + $user->givePermissionTo('edit plans'); + + $plan = Plan::factory()->create(); + + Livewire::actingAs($user) + ->test(EditPlan::class, ['plan' => $plan]) + ->assertOk() + ->assertSet('title', $plan->title) + ->assertSet('slug', $plan->slug) + ->assertSet('stripe_id', $plan->stripe_id); + +}); + +it('has wired properties and methods', function () { + $user = User::factory()->create(); + /** @var User $user */ + $user->givePermissionTo('edit plans'); + $plan = Plan::factory() + ->create(); + + Livewire::actingAs($user) + ->test(EditPlan::class, ['plan' => $plan]) + ->assertOk() + ->assertPropertyWired('title') + ->assertPropertyWired('slug') + ->assertPropertyWired('stripe_id') + ->assertMethodWired('save'); +}); + +it('can save a updated plan', function () { + + $user = User::factory()->create(); + /** @var User $user */ + $user->givePermissionTo('edit plans'); + $plan = Plan::factory() + ->create(); + + Livewire::actingAs($user) + ->test(EditPlan::class, ['plan' => $plan]) + ->assertOk() + ->set('title', 'New Plan Title') + ->set('slug', 'New-Plan-Slug') + ->set('stripe_id', 'New Stripe ID') + ->call('save') + ->assertHasNoErrors(); + + assertDatabaseMissing('plans', [ + 'title' => $plan->title, + 'slug' => $plan->slug, + 'stripe_id' => $plan->stripe_id, + ]); + + expect($plan->refresh()) + ->title->toBe('New Plan Title') + ->slug->toBe('New-Plan-Slug') + ->stripe_id->toBe('New Stripe ID'); + +});