From cfb9f224628135bd866a73b42155a340b1c4c052 Mon Sep 17 00:00:00 2001 From: "R. Aravindan" Date: Fri, 2 Feb 2024 18:06:43 +0530 Subject: [PATCH] Redirect after accept consents and events & notifications --- config/filament-user-consent.php | 23 +++ src/FilamentUserConsentServiceProvider.php | 3 + .../ForceRedirectToUnapprovedConsents.php | 17 ++- src/Listeners/LogConsentUpdated.php | 20 +++ src/Listeners/NotifyConsentsUpdated.php | 16 +++ src/Livewire/ConsentOptionRequset.php | 136 +++++++++--------- src/Mail/ConsentsUpdatedMail.php | 35 +++++ .../ConsentsUpdatedNotification.php | 60 ++++++++ src/Providers/EventServiceProvider.php | 26 ++++ 9 files changed, 267 insertions(+), 69 deletions(-) create mode 100644 src/Listeners/LogConsentUpdated.php create mode 100644 src/Listeners/NotifyConsentsUpdated.php create mode 100644 src/Mail/ConsentsUpdatedMail.php create mode 100644 src/Notifications/ConsentsUpdatedNotification.php create mode 100644 src/Providers/EventServiceProvider.php diff --git a/config/filament-user-consent.php b/config/filament-user-consent.php index 4b424d2..4f2d6c7 100644 --- a/config/filament-user-consent.php +++ b/config/filament-user-consent.php @@ -1,5 +1,9 @@ 'EndUser', ], + 'notify' => ['mail'], + 'routes' => [ 'prefix' => 'consent-options', ], @@ -23,4 +29,21 @@ 'sort' => 50, 'group' => 'Content', ], + + 'listeners' => [ + //Event triggered after a consent updated + ConsentUpdated::class => [ + // Default listeners for this event + // You may want to update mailchump if consent withdrawn for marketing + ], + //Event triggered after all consents updated + ConsentsUpdatedComplete::class => [ + NotifyConsentsUpdated::class + ], + ], + + //send user an email with a copy of the consent after saving. + 'notify' => ['mail'], + + 'email-template' => 'vendor.ekoukltd.laraconsent.layouts.email', ]; diff --git a/src/FilamentUserConsentServiceProvider.php b/src/FilamentUserConsentServiceProvider.php index 81086f8..774556f 100644 --- a/src/FilamentUserConsentServiceProvider.php +++ b/src/FilamentUserConsentServiceProvider.php @@ -14,6 +14,7 @@ use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; use Visualbuilder\FilamentUserConsent\Commands\FilamentUserConsentCommand; +use Visualbuilder\FilamentUserConsent\Providers\EventServiceProvider; use Visualbuilder\FilamentUserConsent\Testing\TestsFilamentUserConsent; class FilamentUserConsentServiceProvider extends PackageServiceProvider @@ -56,6 +57,8 @@ public function configurePackage(Package $package): void if (file_exists($package->basePath('/../resources/views'))) { $package->hasViews(static::$viewNamespace); } + + $this->app->register(EventServiceProvider::class); } public function packageRegistered(): void diff --git a/src/Http/Middleware/ForceRedirectToUnapprovedConsents.php b/src/Http/Middleware/ForceRedirectToUnapprovedConsents.php index f0d7bf8..9fc054b 100644 --- a/src/Http/Middleware/ForceRedirectToUnapprovedConsents.php +++ b/src/Http/Middleware/ForceRedirectToUnapprovedConsents.php @@ -10,22 +10,29 @@ class ForceRedirectToUnapprovedConsents { public function handle(Request $request, Closure $next) { - $isConsentRoute = str_contains($request->route()->getName(), 'consent-options'); + if (Auth::guard('admin')->check()) { + $guard = 'admin'; + } else if (Auth::guard('enduser')->check()) { + $guard = 'enduser'; + } else if (Auth::guard('practitioner')->check()) { + $guard = 'practitioner'; + } + $isConsentRoute = str_contains($request->route()->getName(), 'consent-options'); if ( //must be logged in - Auth::user() + Auth::guard($guard)->user() //have the trait installed - && method_exists(Auth::user(), 'hasRequiredConsents') + && method_exists(Auth::guard($guard)->user(), 'hasRequiredConsents') //Not be a consent route && ! $isConsentRoute //Not an ajax call && ! $request->ajax() //Not have required consents signed - && ! Auth::user()->hasRequiredConsents() + && ! Auth::guard($guard)->user()->hasRequiredConsents() ) { //Save current request URL - // $request->session()->put('url.saved', $request->fullUrl()); + $request->session()->put('url.saved', $request->fullUrl()); //Redirect user to ask for consent return redirect()->route('consent-option-request'); } diff --git a/src/Listeners/LogConsentUpdated.php b/src/Listeners/LogConsentUpdated.php new file mode 100644 index 0000000..87c97ac --- /dev/null +++ b/src/Listeners/LogConsentUpdated.php @@ -0,0 +1,20 @@ +consentOption->is_mandatory&&config('laraconsent.logging.mandatory')) + ||(!$event->consentOption->is_mandatory&&config('laraconsent.logging.optional')) + ){ + $status = $event->accepted?'accepted':'refused'; + Log::info("Consent: ".$event->consentOption->key." $status by ".Auth::user()->email); + } + } +} \ No newline at end of file diff --git a/src/Listeners/NotifyConsentsUpdated.php b/src/Listeners/NotifyConsentsUpdated.php new file mode 100644 index 0000000..a0bf0e9 --- /dev/null +++ b/src/Listeners/NotifyConsentsUpdated.php @@ -0,0 +1,16 @@ +user->notify(new ConsentsUpdatedNotification()); + } +} \ No newline at end of file diff --git a/src/Livewire/ConsentOptionRequset.php b/src/Livewire/ConsentOptionRequset.php index af98095..499f9cf 100644 --- a/src/Livewire/ConsentOptionRequset.php +++ b/src/Livewire/ConsentOptionRequset.php @@ -5,6 +5,7 @@ use Filament\Forms\Concerns\InteractsWithForms; use Filament\Infolists\Components\Actions; use Filament\Infolists\Components\Actions\Action; +use Filament\Infolists\Components\Fieldset; use Filament\Infolists\Components\Group; use Filament\Infolists\Components\RepeatableEntry; use Filament\Infolists\Components\Section; @@ -19,6 +20,9 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; use Visualbuilder\FilamentUserConsent\Models\ConsentOption; +use Illuminate\Support\Facades\Validator; +use Visualbuilder\FilamentUserConsent\Events\ConsentsUpdatedComplete; +use Visualbuilder\FilamentUserConsent\Events\ConsentUpdated; class ConsentOptionRequset extends SimplePage { @@ -41,7 +45,7 @@ public function mount(): void $this->user = Auth::guard('practitioner')->user(); } - if (! $this->user) { + if (!$this->user) { abort(403, 'Only authenticated users can set consent options'); } @@ -73,47 +77,51 @@ public function infolist(Infolist $infolist): Infolist return $infolist ->record($this->user) ->schema([ - Section::make('User Info') + Fieldset::make('User Info') ->schema([ TextEntry::make('fullName'), TextEntry::make('email'), ]) ->columns(2), - RepeatableEntry::make('collections') - ->label('Your Consent is required') - ->schema([ - Section::make(fn (ConsentOption $record) => "{$record->title} V{$record->version}") - ->description(function (ConsentOption $record) { - $suffix = $this->previousConsents($record->key); - $mandatory = $record->is_mandatory ? 'Mandatory' : 'Optional'; - if ($suffix) { - $mandatory .= " - ( $suffix )"; - } - - return $mandatory; + Fieldset::make('Your Consent is required')->schema([ + RepeatableEntry::make('collections') + ->label('') + ->schema([ + Section::make(fn (ConsentOption $record) => "{$record->title} V{$record->version}") + ->description(function (ConsentOption $record) { + $suffix = $this->previousConsents($record->key); + $mandatory = $record->is_mandatory ? 'Mandatory' : 'Optional'; + if ($suffix) { + $mandatory .= " - ( $suffix )"; + } + return $mandatory; + }) + ->icon(fn (ConsentOption $record) => $record->is_mandatory ? 'heroicon-o-check-badge' : 'heroicon-o-question-mark-circle') + ->iconColor(fn (ConsentOption $record) => $record->is_mandatory ? 'success' : 'info') + ->schema([ + TextEntry::make('text')->label('') + ->markdown(), + Group::make()->schema([ + ViewEntry::make('acceptConsent') + ->label('') + ->view('vendor.user-consent.infolists.components.consent-option-checkbox'), + TextEntry::make('updated_at')->label('Last Updated') + ])->columns(2) + ]), + ]) + ->columns(2) + ->columnSpanFull(), + Actions::make([ + Action::make('saveConsents') + ->icon('heroicon-o-check-circle') + ->color('success') + ->before(function (Action $action) { + $this->validateConsents($action); }) - ->icon(fn (ConsentOption $record) => $record->is_mandatory ? 'heroicon-o-check-badge' : 'heroicon-o-question-mark-circle') - ->iconColor(fn (ConsentOption $record) => $record->is_mandatory ? 'success' : 'info') - ->schema([ - TextEntry::make('text')->label('') - ->markdown(), - Group::make()->schema([ - ViewEntry::make('acceptConsent') - ->label('') - ->view('vendor.user-consent.infolists.components.consent-option-checkbox'), - TextEntry::make('updated_at')->label('Last Updated'), - ])->columns(2), - ]), - ]) - ->columns(2) - ->columnSpanFull(), - Actions::make([ - Action::make('saveConsents') - ->icon('heroicon-o-check-circle') - ->color('success') - ->action(function (array $data) { - $this->acceptConsent(); - }), + ->action(function (array $data) { + $this->acceptConsent(); + }) + ]), ]), ])->columns(3); } @@ -127,44 +135,44 @@ public function previousConsents($key) } } - public function acceptConsent() + public function validateConsents($action) { $validateMandatoryConsents = $this->user->requiredOutstandingConsentsValidate($this->acceptConsents); - if (! $validateMandatoryConsents) { + if (!$validateMandatoryConsents) { Notification::make() ->title('Please confirm.!') ->body('Please accept all required consent options.') ->icon('heroicon-o-check-circle') ->color('danger') ->send(); - } else { - - $outstandingConsents = $this->user->outstandingConsents(); - foreach ($outstandingConsents as $consentOption) { - $this->user->consents() - ->save( - $consentOption, - [ - 'accepted' => in_array($consentOption->id, $this->acceptConsents), - 'key' => $consentOption->key, - ] - ); - // event(new ConsentUpdated($consentOption, $request->consent_option[ $consentOption->id ])); - } - Notification::make() - ->title('Welcome.!') - ->body('Your submitted all consent options are saved.') - ->icon('heroicon-o-check-circle') - ->color('success') - ->send(); - - // event(new ConsentsUpdatedComplete($outstandingConsents, $user)); + $action->cancel(); + } + } - // return Redirect::intended( - // $request->session() - // ->get('url.saved') - // ); + public function acceptConsent() + { + $outstandingConsents = $this->user->outstandingConsents(); + foreach ($outstandingConsents as $consentOption) { + $this->user->consents() + ->save( + $consentOption, + [ + 'accepted' => in_array($consentOption->id, $this->acceptConsents), + 'key' => $consentOption->key + ] + ); + event(new ConsentUpdated($consentOption, in_array($consentOption->id, $this->acceptConsents))); } + Notification::make() + ->title('Welcome.!') + ->body('Your submitted all consent options are saved.') + ->icon('heroicon-o-check-circle') + ->color('success') + ->send(); + + event(new ConsentsUpdatedComplete($outstandingConsents, $this->user)); + + return redirect(request()->session()->get('url.saved')); } } diff --git a/src/Mail/ConsentsUpdatedMail.php b/src/Mail/ConsentsUpdatedMail.php new file mode 100644 index 0000000..ebc4f57 --- /dev/null +++ b/src/Mail/ConsentsUpdatedMail.php @@ -0,0 +1,35 @@ +user = $user; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + + } +} diff --git a/src/Notifications/ConsentsUpdatedNotification.php b/src/Notifications/ConsentsUpdatedNotification.php new file mode 100644 index 0000000..e48cfb4 --- /dev/null +++ b/src/Notifications/ConsentsUpdatedNotification.php @@ -0,0 +1,60 @@ + $listeners) { + foreach ($listeners as $listener) { + Event::listen($event, $listener); + } + } + } +} \ No newline at end of file