'integer', ]; } public function category(): BelongsTo { return $this->belongsTo(FileCategory::class, 'file_category_id'); } public function uploader(): BelongsTo { return $this->belongsTo(User::class, 'uploaded_by')->withTrashed(); } public function events(): BelongsToMany { return $this->belongsToMany(Event::class, 'event_file')->withPivot('created_at'); } public function teams(): BelongsToMany { return $this->belongsToMany(Team::class, 'team_file')->withPivot('created_at'); } public function getStoragePath(): string { return 'files/' . $this->stored_name; } public function isImage(): bool { return str_starts_with($this->mime_type, 'image/'); } public function isPdf(): bool { return $this->mime_type === 'application/pdf'; } public function isHtml(): bool { return $this->mime_type === 'text/html'; } public function humanSize(): string { $bytes = $this->size; if ($bytes >= 1048576) { return round($bytes / 1048576, 1) . ' MB'; } return round($bytes / 1024) . ' KB'; } public function iconType(): string { return match (true) { str_contains($this->mime_type, 'pdf') => 'pdf', str_contains($this->mime_type, 'wordprocessingml') => 'word', str_contains($this->mime_type, 'spreadsheetml') => 'excel', $this->isImage() => 'image', $this->isHtml() => 'html', default => 'file', }; } public function extension(): string { return pathinfo($this->original_name, PATHINFO_EXTENSION); } public function previewData(): array { $hasPreview = $this->isImage() || $this->isPdf(); return [ 'name' => $this->original_name, 'category' => $this->category->name ?? '', 'size' => $this->humanSize(), 'downloadUrl' => route('files.download', $this), 'previewUrl' => $hasPreview ? route('files.preview', $this) : null, 'isImage' => $this->isImage(), 'isPdf' => $this->isPdf(), 'isHtml' => $this->isHtml(), 'iconBg' => match ($this->iconType()) { 'pdf' => 'bg-red-100 text-red-600', 'word' => 'bg-blue-100 text-blue-600', 'excel' => 'bg-green-100 text-green-600', 'image' => 'bg-purple-100 text-purple-600', 'html' => 'bg-orange-100 text-orange-600', default => 'bg-gray-100 text-gray-600', }, ]; } }