*/ use HasApiTokens, HasFactory, HasUuids, Notifiable, SoftDeletes; /** * The primary key type. * * @var string */ protected $keyType = 'string'; /** * Indicates if the IDs are auto-incrementing. * * @var bool */ public $incrementing = false; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ 'username', 'email', 'password', 'role', 'xp', 'avatar_uri', 'participations', 'victories', 'level_id', ]; /** * The accessors to append to the model's array form. * * @var array */ protected $appends = [ 'next_level_xp', ]; /** * The attributes that should be hidden for serialization. * * @var list */ protected $hidden = [ 'password', 'remember_token', ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'role' => UserRole::class, ]; } public function participations() { return $this->belongsToMany(Hunts::class, 'hunt_participants', 'user_id', 'hunt_id') ->withPivot(['current_step_number', 'status']) ->withTimestamps(); } public function currentLevel(): BelongsTo { return $this->belongsTo(Level::class, 'level_id'); } public function updateLevel(): void { $level = Level::where('xpThreshold', '<=', $this->xp) ->orderBy('xpThreshold', 'desc') ->first(); if ($level && $this->level_id !== $level->id) { $this->level_id = $level->id; $this->save(); } } public function getNextLevelXpAttribute(): ?int { // Si l'XP est null, on ne peut pas comparer avec > // On retourne le premier niveau disponible if ($this->xp === null) { return Level::orderBy('xpThreshold', 'asc') ->value('xpThreshold'); } return Level::where('xpThreshold', '>', $this->xp) ->orderBy('xpThreshold', 'asc') ->value('xpThreshold'); } public function getFilamentName(): string { return $this->username; } public function canAccessPanel(Panel $panel): bool { return $this->role === UserRole::ADMIN || $this->role === UserRole::ORGA; } }