]> _ Git - psq.git/commitdiff
added nova metrics
authorLouis Jeckel <louis.jeckel@outlook.cm>
Thu, 30 Apr 2020 00:36:33 +0000 (02:36 +0200)
committerLouis Jeckel <louis.jeckel@outlook.cm>
Thu, 30 Apr 2020 00:36:33 +0000 (02:36 +0200)
app/Nova/Actions/SendNotification.php [new file with mode: 0644]
app/Nova/Actions/StartTrial.php [new file with mode: 0644]
app/Nova/Actions/VerifyEmail.php [new file with mode: 0644]
app/Nova/Metrics/FileAccess.php [new file with mode: 0644]
app/Nova/Metrics/MailEvents.php [new file with mode: 0644]
app/Nova/Metrics/MailEventsPartition.php [new file with mode: 0644]
app/Nova/Metrics/TotalUsers.php [new file with mode: 0644]
app/Nova/Metrics/UsersPartition.php [new file with mode: 0644]
app/Nova/User.php
app/Providers/NovaServiceProvider.php
app/User.php

diff --git a/app/Nova/Actions/SendNotification.php b/app/Nova/Actions/SendNotification.php
new file mode 100644 (file)
index 0000000..404616d
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Nova\Actions;
+
+use App\User;
+use FontLib\Table\Type\name;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Support\Collection;
+use Laravel\Nova\Actions\Action;
+use Laravel\Nova\Fields\ActionFields;
+use Laravel\Nova\Fields\Select;
+use App\Notifications;
+
+class SendNotification extends Action
+{
+    use InteractsWithQueue, Queueable;
+
+    public $showOnTableRow = true;
+
+
+
+    public $name = "Envoyer une notificaion";
+
+    public $confirmButtonText = "Envoyer";
+
+    /**
+     * Perform the action on the given models.
+     *
+     * @param  \Laravel\Nova\Fields\ActionFields  $fields
+     * @param  \Illuminate\Support\Collection  $models
+     * @return mixed
+     */
+    public function handle(ActionFields $fields, Collection $models)
+    {
+        $models->map(fn(User $user) => $user->notify(new $fields->notification));
+        return Action::message(sprintf('%d messages envoyés', $models->count()));
+    }
+
+    /**
+     * Get the fields available on the action.
+     *
+     * @return array
+     */
+    public function fields()
+    {
+        return [
+            Select::make('Notification')->options([
+                Notifications\Welcome::class => 'Message de bienvenue',
+                Notifications\RegistrationPending::class => 'Rappel',
+            ])
+        ];
+    }
+}
diff --git a/app/Nova/Actions/StartTrial.php b/app/Nova/Actions/StartTrial.php
new file mode 100644 (file)
index 0000000..97f5c62
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Nova\Actions;
+
+use App\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Support\Collection;
+use Laravel\Nova\Actions\Action;
+use Laravel\Nova\Fields\ActionFields;
+
+class StartTrial extends Action
+{
+    use InteractsWithQueue, Queueable;
+
+    public $showOnTableRow = true;
+    public $confirmButtonText = "Appliquer";
+    public $name = "Démarrer période d'essai";
+
+    public function __construct()
+    {
+        $this->confirmText = sprintf("Etes vous sûr de vouloir activer une période d'essai de %d jours ?", User::trialDurationDays);
+
+    }
+
+
+
+
+    /**
+     * Perform the action on the given models.
+     *
+     * @param  \Laravel\Nova\Fields\ActionFields  $fields
+     * @param  \Illuminate\Support\Collection  $models
+     * @return mixed
+     */
+    public function handle(ActionFields $fields, Collection $models)
+    {
+        $models->map->startTrial();
+
+        return Action::message(sprintf("La période d'essai à bien été activée pour %d utilisteur(s)", $models->count()));
+    }
+
+    /**
+     * Get the fields available on the action.
+     *
+     * @return array
+     */
+    public function fields()
+    {
+        return [];
+    }
+}
diff --git a/app/Nova/Actions/VerifyEmail.php b/app/Nova/Actions/VerifyEmail.php
new file mode 100644 (file)
index 0000000..894c13a
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Nova\Actions;
+
+use App\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Support\Collection;
+use Laravel\Nova\Actions\Action;
+use Laravel\Nova\Fields\ActionFields;
+
+class VerifyEmail extends Action
+{
+    use InteractsWithQueue, Queueable;
+
+    public $showOnTableRow = true;
+
+    /**
+     * Perform the action on the given models.
+     *
+     * @param  \Laravel\Nova\Fields\ActionFields  $fields
+     * @param  \Illuminate\Support\Collection  $models
+     * @return mixed
+     */
+    public function handle(ActionFields $fields, Collection $models)
+    {
+        $models->map->markEmailAsVerified();
+    }
+
+    /**
+     * Get the fields available on the action.
+     *
+     * @return array
+     */
+    public function fields()
+    {
+        return [];
+    }
+}
diff --git a/app/Nova/Metrics/FileAccess.php b/app/Nova/Metrics/FileAccess.php
new file mode 100644 (file)
index 0000000..8486a40
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+namespace App\Nova\Metrics;
+
+use App\AccessLog;
+use Laravel\Nova\Http\Requests\NovaRequest;
+use Laravel\Nova\Metrics\Value;
+
+class FileAccess extends Value
+{
+
+    public $name = "Lectures";
+
+    /**
+     * Calculate the value of the metric.
+     *
+     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
+     * @return mixed
+     */
+    public function calculate(NovaRequest $request)
+    {
+        return $this->count($request, AccessLog::class);
+    }
+
+    /**
+     * Get the ranges available for the metric.
+     *
+     * @return array
+     */
+    public function ranges()
+    {
+        return [
+            30 => '30 jours',
+            'TODAY' => 'Today',
+            7 => '7 jours',
+            60 => '60 jours',
+            365 => '365 jours',
+            'MTD' => 'Month To Date',
+            'QTD' => 'Quarter To Date',
+            'YTD' => 'Year To Date',
+        ];
+    }
+
+    /**
+     * Determine for how many minutes the metric should be cached.
+     *
+     * @return  \DateTimeInterface|\DateInterval|float|int
+     */
+    public function cacheFor()
+    {
+        // return now()->addMinutes(5);
+    }
+
+    /**
+     * Get the URI key for the metric.
+     *
+     * @return string
+     */
+    public function uriKey()
+    {
+        return 'file-access';
+    }
+}
diff --git a/app/Nova/Metrics/MailEvents.php b/app/Nova/Metrics/MailEvents.php
new file mode 100644 (file)
index 0000000..f655936
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Nova\Metrics;
+
+use App\MailgunEvent;
+use Laravel\Nova\Http\Requests\NovaRequest;
+use Laravel\Nova\Metrics\Value;
+
+class MailEvents extends Value
+{
+    /**
+     * @var string
+     */
+    private string $event;
+
+
+    /**
+     * MailEvents constructor.
+     * @param string $event
+     * @param string $name
+     */
+    public function __construct(string $event, string $name)
+    {
+        parent::__construct();
+
+        $this->event = $event;
+        $this->name = $name;
+    }
+
+    /**
+     * Calculate the value of the metric.
+     *
+     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
+     * @return mixed
+     */
+    public function calculate(NovaRequest $request)
+    {
+        return $this->count($request, MailgunEvent::where('event', $this->event));
+    }
+
+    /**
+     * Get the ranges available for the metric.
+     *
+     * @return array
+     */
+    public function ranges()
+    {
+        return [
+            30 => '30 Days',
+            60 => '60 Days',
+            365 => '365 Days',
+            'TODAY' => 'Today',
+            'MTD' => 'Month To Date',
+            'QTD' => 'Quarter To Date',
+            'YTD' => 'Year To Date',
+        ];
+    }
+
+    /**
+     * Determine for how many minutes the metric should be cached.
+     *
+     * @return  \DateTimeInterface|\DateInterval|float|int
+     */
+    public function cacheFor()
+    {
+        // return now()->addMinutes(5);
+    }
+
+    /**
+     * Get the URI key for the metric.
+     *
+     * @return string
+     */
+    public function uriKey()
+    {
+        return 'mail-events';
+    }
+}
diff --git a/app/Nova/Metrics/MailEventsPartition.php b/app/Nova/Metrics/MailEventsPartition.php
new file mode 100644 (file)
index 0000000..482b238
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Nova\Metrics;
+
+use App\MailgunEvent;
+use Laravel\Nova\Http\Requests\NovaRequest;
+use Laravel\Nova\Metrics\Partition;
+
+class MailEventsPartition extends Partition
+{
+    /**
+     * Calculate the value of the metric.
+     *
+     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
+     * @return mixed
+     */
+    public function calculate(NovaRequest $request)
+    {
+        return $this->count($request, MailgunEvent::class, 'event');
+    }
+
+    /**
+     * Determine for how many minutes the metric should be cached.
+     *
+     * @return  \DateTimeInterface|\DateInterval|float|int
+     */
+    public function cacheFor()
+    {
+        // return now()->addMinutes(5);
+    }
+
+    /**
+     * Get the URI key for the metric.
+     *
+     * @return string
+     */
+    public function uriKey()
+    {
+        return 'mail-events-partition';
+    }
+}
diff --git a/app/Nova/Metrics/TotalUsers.php b/app/Nova/Metrics/TotalUsers.php
new file mode 100644 (file)
index 0000000..7b781c7
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Nova\Metrics;
+
+use App\User;
+use Laravel\Nova\Http\Requests\NovaRequest;
+use Laravel\Nova\Metrics\Value;
+
+class TotalUsers extends Value
+{
+
+    public $name = "Nombre d'utilisateurs inscrits";
+    /**
+     * Calculate the value of the metric.
+     *
+     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
+     * @return mixed
+     */
+    public function calculate(NovaRequest $request)
+    {
+        return $this->result(User::count());
+    }
+
+
+    /**
+     * Determine for how many minutes the metric should be cached.
+     *
+     * @return  \DateTimeInterface|\DateInterval|float|int
+     */
+    public function cacheFor()
+    {
+//         return now()->addMinutes(5);
+    }
+
+    /**
+     * Get the URI key for the metric.
+     *
+     * @return string
+     */
+    public function uriKey()
+    {
+        return 'total-users';
+    }
+}
diff --git a/app/Nova/Metrics/UsersPartition.php b/app/Nova/Metrics/UsersPartition.php
new file mode 100644 (file)
index 0000000..105daa5
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Nova\Metrics;
+
+use App\User;
+use Laravel\Nova\Http\Requests\NovaRequest;
+use Laravel\Nova\Metrics\Partition;
+
+class UsersPartition extends Partition
+{
+
+    public $name = "Utilisateurs abonnés";
+
+    /**
+     * Calculate the value of the metric.
+     *
+     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
+     * @return mixed
+     */
+    public function calculate(NovaRequest $request)
+    {
+        return $this->result([
+            'Abonnés' => $s = User::hasActiveSubscription()->count(),
+            "Période d'essai" => $t = User::isOnTrial()->count(),
+            "Reste" => User::count() - $s - $t
+        ]);
+    }
+
+    /**
+     * Determine for how many minutes the metric should be cached.
+     *
+     * @return  \DateTimeInterface|\DateInterval|float|int
+     */
+    public function cacheFor()
+    {
+        // return now()->addMinutes(5);
+    }
+
+    /**
+     * Get the URI key for the metric.
+     *
+     * @return string
+     */
+    public function uriKey()
+    {
+        return 'users-partition';
+    }
+}
index fed3cb13985e574e5117be47de6dad9af58fe699..28cf721aa388d2fce5a310646fcda6d19a090bf7 100644 (file)
@@ -3,7 +3,17 @@
 namespace App\Nova;
 
 use App\Nova\Actions\ImportUsers;
+use App\Nova\Actions\SendNotification;
+use App\Nova\Actions\StartTrial;
+use App\Nova\Actions\VerifyEmail;
+use App\Nova\Metrics\SubscribedUsers;
+use App\Nova\Metrics\TotalUsers;
+use App\Nova\Metrics\TrialUsers;
+use App\Nova\Metrics\UsersPartition;
+use App\User as AppUser;
 use Illuminate\Http\Request;
+use Illuminate\Support\Arr;
+use Laravel\Nova\Fields\Badge;
 use Laravel\Nova\Fields\BelongsTo;
 use Laravel\Nova\Fields\Boolean;
 use Laravel\Nova\Fields\Country;
@@ -20,7 +30,7 @@ class User extends Resource
      *
      * @var string
      */
-    public static $model = \App\User::class;
+    public static $model = AppUser::class;
 
 
     /**
@@ -56,7 +66,9 @@ class User extends Resource
                 BelongsTo::make('Organisation', 'organization', Organization::class)->searchable(),
 
             ]),
-            Boolean::make('Abonnement actif', 'isSubscribed')->readonly()->onlyOnIndex(),
+            Boolean::make('Compte actif', 'reg_complete'),
+            Badge::make('Etat', fn() => AppUser::statuses[$this->status]['label'])
+                ->map(Arr::pluck(AppUser::statuses, 'badge', 'label')),
         ];
     }
 
@@ -86,7 +98,10 @@ class User extends Resource
      */
     public function cards(Request $request)
     {
-        return [];
+        return [
+            new TotalUsers,
+            new UsersPartition,
+        ];
     }
 
     /**
@@ -121,6 +136,9 @@ class User extends Resource
     {
         return [
             new ImportUsers,
+            new SendNotification,
+            new StartTrial,
+            new VerifyEmail,
         ];
     }
 }
index 05d973dc23e4678fbf13918b63303c3d0ef705e1..3b3052460076425f04ad610a5724f4d1117a28af 100644 (file)
@@ -4,6 +4,11 @@ namespace App\Providers;
 
 use A17\Twill\Models\User as TwillUser;
 use Anaseqal\NovaImport\NovaImport;
+use App\Nova\Metrics\FileAccess;
+use App\Nova\Metrics\MailEvents;
+use App\Nova\Metrics\MailEventsPartition;
+use App\Nova\Metrics\TotalUsers;
+use App\Nova\Metrics\UsersPartition;
 use Illuminate\Support\Facades\Gate;
 use Laravel\Nova\Cards\Help;
 use Laravel\Nova\Nova;
@@ -57,6 +62,12 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
     protected function cards()
     {
         return [
+            new TotalUsers,
+            new UsersPartition,
+            new FileAccess,
+            new MailEvents('opened', 'Mails ouverts'),
+            new MailEventsPartition,
+
         ];
     }
 
index 9b9b42038e794ea8c8f18338522c288928628339..cc895f7ca8e5d3986c414f62d2c10912834ac34b 100644 (file)
@@ -3,6 +3,7 @@
 namespace App;
 
 
+use DemeterChain\B;
 use Illuminate\Contracts\Auth\MustVerifyEmail;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -68,7 +69,7 @@ class User extends Authenticatable
         'email_verified_at' => 'datetime',
         'subscription_active' => 'bool',
         'reg_complete' => 'bool',
-        'trial_until' => 'datetime',
+        'trial_ends_at' => 'datetime',
         'active_until' => 'datetime',
     ];
 
@@ -83,7 +84,7 @@ class User extends Authenticatable
         ];
     }
 
-    public int $trialDurationDays = 14;
+    public const trialDurationDays = 14;
 
     /**
      * @return BelongsTo
@@ -98,11 +99,52 @@ class User extends Authenticatable
      */
     public function getIsSubscribedAttribute(): bool
     {
-        if($o = $this->organization){
-            return $o->isSubscribed();
-        }
+        return ($o = $this->organization) === null ?
+            false:
+            $o->isSubscribed();
+    }
+
+    /**
+     * Possible Statuses
+     */
+    public const statuses = [
+        'inactive' => [
+            'badge' => 'danger',
+            'label' => 'Aucun abonnement'
+        ],
+        'subscribed' => [
+            'badge' => 'success',
+            'label' => 'Abonnement actif (orga)'
+        ],
+        'trial' => [
+            'badge' => 'warning',
+            'label' => "Période d'essai"
+        ],
+    ];
+
+    /**
+     * @return string
+     */
+    public function getStatusAttribute(): string
+    {
+        $id = 'inactive';
+
+        if($this->isSubscribed)
+            $id = 'subscribed';
+        if($this->onTrial())
+            $id = 'trial';
+
+        return $id;
+
+    }
 
-        return false;
+    /**
+     * @return string
+     * Returns current status
+     */
+    public function getStatusLabelAttribute(): string
+    {
+        return self::statuses[$this->status]['label'];
     }
 
     /**
@@ -126,23 +168,38 @@ class User extends Authenticatable
         return route($route, array_merge($params, $token), $absolute);
     }
 
+
     /**
-     * @param Builder $builder
+     * Starts trial period
      */
+    public function startTrial(): void
+    {
+        $this->trial_ends_at = now()->addDays(self::trialDurationDays);
+        $this->save();
+    }
+
+
+
+
+
+
     public function scopeRecievesEmails(Builder $builder): void
     {
-        $builder->whereHas('organization', fn($builder) => $builder->subscribed())
-            ->orWhereDate('trial_ends_at', '>', now());
+        $builder->hasActiveSubscription()->orWhere->isOnTrial();
     }
 
-    /**
-     * Starts trial period
-     */
-    public function startTrial(): void
+    public function scopeIsOnTrial(Builder $builder): void
     {
-        $this->trial_ends_at = now()->addDays($this->trialDurationDays);
+        $builder->whereDate('trial_ends_at', '>', now());
     }
 
+    public function scopeHasActiveSubscription(Builder $builder): void
+    {
+        $builder->whereHas('organization', fn($builder) => $builder->subscribed());
+    }
+
+
+
 
 
     /**