--- /dev/null
+<?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',
+ ])
+ ];
+ }
+}
--- /dev/null
+<?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 [];
+ }
+}
--- /dev/null
+<?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 [];
+ }
+}
--- /dev/null
+<?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';
+ }
+}
--- /dev/null
+<?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';
+ }
+}
--- /dev/null
+<?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';
+ }
+}
--- /dev/null
+<?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';
+ }
+}
--- /dev/null
+<?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';
+ }
+}
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;
*
* @var string
*/
- public static $model = \App\User::class;
+ public static $model = AppUser::class;
/**
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')),
];
}
*/
public function cards(Request $request)
{
- return [];
+ return [
+ new TotalUsers,
+ new UsersPartition,
+ ];
}
/**
{
return [
new ImportUsers,
+ new SendNotification,
+ new StartTrial,
+ new VerifyEmail,
];
}
}
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;
protected function cards()
{
return [
+ new TotalUsers,
+ new UsersPartition,
+ new FileAccess,
+ new MailEvents('opened', 'Mails ouverts'),
+ new MailEventsPartition,
+
];
}
namespace App;
+use DemeterChain\B;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
'email_verified_at' => 'datetime',
'subscription_active' => 'bool',
'reg_complete' => 'bool',
- 'trial_until' => 'datetime',
+ 'trial_ends_at' => 'datetime',
'active_until' => 'datetime',
];
];
}
- public int $trialDurationDays = 14;
+ public const trialDurationDays = 14;
/**
* @return BelongsTo
*/
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'];
}
/**
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());
+ }
+
+
+
/**