'array', 'read_at' => 'datetime', ]; /** * Get the user who received this notification. */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * Check if the notification has been read */ public function isRead(): bool { return $this->read_at !== null; } /** * Check if the notification is unread */ public function isUnread(): bool { return $this->read_at === null; } /** * Mark the notification as read */ public function markAsRead(): void { $this->read_at = now(); $this->save(); } /** * Mark the notification as unread */ public function markAsUnread(): void { $this->read_at = null; $this->save(); } /** * Create a new notification */ public static function createForUser(User $user, string $type, array $data = []): self { return self::create([ 'user_id' => $user->id, 'type' => $type, 'data' => $data, ]); } /** * Send a system notification */ public static function sendSystem(User $user, string $message): self { return self::createForUser($user, 'system', [ 'message' => $message, ]); } /** * Send a crime success notification */ public static function sendCrimeSuccess(User $user, Crime $crime, int $reward): self { return self::createForUser($user, 'crime_success', [ 'crime_name' => $crime->name, 'reward' => $reward, ]); } /** * Send a crime failure notification */ public static function sendCrimeFailure(User $user, Crime $crime): self { return self::createForUser($user, 'crime_failure', [ 'crime_name' => $crime->name, ]); } /** * Get the notification message */ public function getMessageAttribute(): string { return match($this->type) { 'system' => $this->data['message'] ?? 'System notification', 'crime_success' => "Crime successful: {$this->data['crime_name']}! You earned \${$this->data['reward']}", 'crime_failure' => "Crime failed: {$this->data['crime_name']}.", default => $this->type, }; } /** * Get the notification icon */ public function getIconAttribute(): string { return match($this->type) { 'system' => 'information-circle', 'crime_success' => 'check-circle', 'crime_failure' => 'x-circle', 'money' => 'currency-dollar', 'level_up' => 'arrow-up-circle', default => 'bell', }; } /** * Get the notification color */ public function getColorAttribute(): string { return match($this->type) { 'system' => 'blue', 'crime_success' => 'green', 'crime_failure' => 'red', 'money' => 'yellow', 'level_up' => 'purple', default => 'gray', }; } }