tenant admin startseite schicker gestaltet und super-admin und tenant admin (filament) aufgesplittet.

Es gibt nun task collections und vordefinierte tasks für alle. Onboarding verfeinert und webseite-carousel gefixt (logging später entfernen!)
This commit is contained in:
Codex Agent
2025-10-14 15:17:52 +02:00
parent 64a5411fb9
commit 1a4bdb1fe1
92 changed files with 6027 additions and 515 deletions

View File

@@ -4,7 +4,10 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
class TaskCollection extends Model
{
@@ -14,10 +17,40 @@ class TaskCollection extends Model
protected $fillable = [
'tenant_id',
'name',
'description',
'slug',
'name_translations',
'description_translations',
'event_type_id',
'source_collection_id',
'is_default',
'position',
];
protected $casts = [
'name_translations' => 'array',
'description_translations' => 'array',
];
public function eventType(): BelongsTo
{
return $this->belongsTo(EventType::class);
}
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
public function sourceCollection(): BelongsTo
{
return $this->belongsTo(TaskCollection::class, 'source_collection_id');
}
public function derivedCollections(): HasMany
{
return $this->hasMany(TaskCollection::class, 'source_collection_id');
}
public function tasks(): BelongsToMany
{
return $this->belongsToMany(
@@ -25,7 +58,7 @@ class TaskCollection extends Model
'task_collection_task',
'task_collection_id',
'task_id'
);
)->withPivot(['sort_order']);
}
public function events(): BelongsToMany
@@ -35,7 +68,49 @@ class TaskCollection extends Model
'event_task_collection',
'task_collection_id',
'event_id'
);
)->withPivot(['sort_order'])->withTimestamps();
}
public function scopeGlobal($query)
{
return $query->whereNull('tenant_id');
}
public function scopeForTenant($query, ?int $tenantId)
{
return $query->where(function ($inner) use ($tenantId) {
$inner->whereNull('tenant_id');
if ($tenantId) {
$inner->orWhere('tenant_id', $tenantId);
}
});
}
public function getNameAttribute(): string
{
return $this->resolveTranslation('name_translations');
}
public function getDescriptionAttribute(): ?string
{
$value = $this->resolveTranslation('description_translations');
return $value ?: null;
}
protected function resolveTranslation(string $attribute, ?string $locale = null): string
{
$translations = $this->{$attribute} ?? [];
if (is_string($translations)) {
$translations = json_decode($translations, true) ?: [];
}
$locale = $locale ?? app()->getLocale();
return $translations[$locale]
?? Arr::first($translations)
?? '';
}
}