diff --git a/app/Models/Assignment.php b/app/Models/Assignment.php index 9e887c2..586e9cc 100644 --- a/app/Models/Assignment.php +++ b/app/Models/Assignment.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\AssignmentType; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,10 +15,16 @@ class Assignment extends Model implements HasMedia { + // --- Traits --- + use HasFactory, InteractsWithMedia, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ @@ -26,6 +33,25 @@ protected function casts(): array ]; } + // --- Accessors & Mutators --- + + protected function formattedDueDate(): Attribute + { + return Attribute::get(fn () => $this->due_date?->translatedFormat('l, d M Y H:i')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignmentPins(): HasMany { return $this->hasMany(AssignmentPin::class); diff --git a/app/Models/AssignmentPin.php b/app/Models/AssignmentPin.php index 884e27b..248fd6a 100644 --- a/app/Models/AssignmentPin.php +++ b/app/Models/AssignmentPin.php @@ -2,13 +2,30 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class AssignmentPin extends Model { + // --- Properties --- + protected $guarded = ['id']; + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignment(): BelongsTo { return $this->belongsTo(Assignment::class); diff --git a/app/Models/AssignmentSubmission.php b/app/Models/AssignmentSubmission.php index d927fb9..4183b03 100644 --- a/app/Models/AssignmentSubmission.php +++ b/app/Models/AssignmentSubmission.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -10,10 +11,16 @@ class AssignmentSubmission extends Model implements HasMedia { + // --- Traits --- + use HasFactory, InteractsWithMedia; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ @@ -21,6 +28,25 @@ protected function casts(): array ]; } + // --- Accessors & Mutators --- + + protected function formattedSubmittedAt(): Attribute + { + return Attribute::get(fn () => $this->submitted_at?->translatedFormat('l, d M Y H:i')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignment(): BelongsTo { return $this->belongsTo(Assignment::class); diff --git a/app/Models/AssignmentTarget.php b/app/Models/AssignmentTarget.php index e4f5cac..4d9d21d 100644 --- a/app/Models/AssignmentTarget.php +++ b/app/Models/AssignmentTarget.php @@ -2,16 +2,35 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class AssignmentTarget extends Model { + // --- Traits --- + use HasFactory; + // --- Properties --- + protected $guarded = ['id']; + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignment(): BelongsTo { return $this->belongsTo(Assignment::class); diff --git a/app/Models/Attendance.php b/app/Models/Attendance.php index e6d8486..282dc67 100644 --- a/app/Models/Attendance.php +++ b/app/Models/Attendance.php @@ -2,16 +2,23 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Attendance extends Model { + // --- Traits --- + use HasFactory; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ @@ -20,6 +27,30 @@ protected function casts(): array ]; } + // --- Accessors & Mutators --- + + protected function formattedDate(): Attribute + { + return Attribute::get(fn () => $this->date?->translatedFormat('l, d M Y')); + } + + protected function formattedAttendedAt(): Attribute + { + return Attribute::get(fn () => $this->attended_at?->translatedFormat('l, d M Y H:i')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function classSession(): BelongsTo { return $this->belongsTo(ClassSession::class); diff --git a/app/Models/Changelog.php b/app/Models/Changelog.php index f775886..63d56a7 100644 --- a/app/Models/Changelog.php +++ b/app/Models/Changelog.php @@ -10,8 +10,12 @@ class Changelog extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $fillable = [ 'version', 'release_date', @@ -21,24 +25,33 @@ class Changelog extends Model 'description', ]; - /** - * The attributes that should be cast. - * - * @var array - */ + // --- Casts --- + protected $casts = [ - 'release_date' => 'date', 'changes' => 'array', + 'release_date' => 'date', 'type' => ChangelogType::class, ]; - public function formattedVersion(): Attribute + // --- Accessors & Mutators --- + + protected function formattedVersion(): Attribute { return Attribute::get(fn () => strtoupper($this->version)); } - public function formattedReleaseDate(): Attribute + protected function formattedReleaseDate(): Attribute { return Attribute::get(fn () => $this->release_date->translatedFormat('l, d M Y')); } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } } diff --git a/app/Models/ClassSession.php b/app/Models/ClassSession.php index d07740a..88af5fe 100644 --- a/app/Models/ClassSession.php +++ b/app/Models/ClassSession.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -10,20 +11,55 @@ class ClassSession extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ 'date' => 'date', + 'end_time' => 'datetime', 'session_number' => 'integer', 'start_time' => 'datetime', - 'end_time' => 'datetime', ]; } + // --- Accessors & Mutators --- + + protected function formattedDate(): Attribute + { + return Attribute::get(fn () => $this->date?->translatedFormat('l, d M Y')); + } + + protected function formattedStartTime(): Attribute + { + return Attribute::get(fn () => $this->start_time?->translatedFormat('H:i')); + } + + protected function formattedEndTime(): Attribute + { + return Attribute::get(fn () => $this->end_time?->translatedFormat('H:i')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignments(): HasMany { return $this->hasMany(Assignment::class); diff --git a/app/Models/Course.php b/app/Models/Course.php index 0f77e40..08c1186 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -10,10 +11,28 @@ class Course extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignments(): HasMany { return $this->hasMany(Assignment::class); diff --git a/app/Models/CourseSchedule.php b/app/Models/CourseSchedule.php index dcf7a61..182b275 100644 --- a/app/Models/CourseSchedule.php +++ b/app/Models/CourseSchedule.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -10,10 +11,16 @@ class CourseSchedule extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ @@ -22,13 +29,37 @@ protected function casts(): array ]; } - public function course(): BelongsTo + // --- Accessors & Mutators --- + + protected function formattedStartTime(): Attribute { - return $this->belongsTo(Course::class); + return Attribute::get(fn () => $this->start_time?->translatedFormat('H:i')); } + protected function formattedEndTime(): Attribute + { + return Attribute::get(fn () => $this->end_time?->translatedFormat('H:i')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function attendances(): HasMany { return $this->hasMany(Attendance::class); } + + public function course(): BelongsTo + { + return $this->belongsTo(Course::class); + } } diff --git a/app/Models/Material.php b/app/Models/Material.php index 15e0638..63d2d44 100644 --- a/app/Models/Material.php +++ b/app/Models/Material.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -11,17 +12,35 @@ class Material extends Model implements HasMedia { + // --- Traits --- + use HasFactory, InteractsWithMedia, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; - public function course(): BelongsTo + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute { - return $this->belongsTo(Course::class); + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); } + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function classSession(): BelongsTo { return $this->belongsTo(ClassSession::class); } + + public function course(): BelongsTo + { + return $this->belongsTo(Course::class); + } } diff --git a/app/Models/Student.php b/app/Models/Student.php index bee66a6..94e816e 100644 --- a/app/Models/Student.php +++ b/app/Models/Student.php @@ -5,6 +5,7 @@ use App\Enums\Sex; use Illuminate\Database\Eloquent\Attributes\Scope; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,10 +15,16 @@ class Student extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; + // --- Casts --- + protected function casts(): array { return [ @@ -26,6 +33,8 @@ protected function casts(): array ]; } + // --- Scopes --- + #[Scope] protected function male(Builder $query): void { @@ -38,6 +47,25 @@ protected function female(Builder $query): void $query->where('sex', Sex::Female); } + // --- Accessors & Mutators --- + + protected function formattedDateOfBirth(): Attribute + { + return Attribute::get(fn () => $this->date_of_birth?->translatedFormat('l, d M Y')); + } + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignmentPins(): HasMany { return $this->hasMany(AssignmentPin::class); diff --git a/app/Models/StudyGroup.php b/app/Models/StudyGroup.php index d829094..d0632e5 100644 --- a/app/Models/StudyGroup.php +++ b/app/Models/StudyGroup.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -11,15 +12,28 @@ class StudyGroup extends Model { + // --- Traits --- + use HasFactory, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; - public function isLeader(Student $student): bool + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute { - return $this->leader_id === $student->id; + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); } + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function assignmentSubmissions(): HasMany { return $this->hasMany(AssignmentSubmission::class); @@ -60,6 +74,13 @@ public function students(): BelongsToMany return $this->belongsToMany(Student::class, 'study_group_members'); } + // --- Methods --- + + public function isLeader(Student $student): bool + { + return $this->leader_id === $student->id; + } + public static function getBusyStudentIdsForCourses(array $courseIds, ?int $excludeGroupId = null): array { $busyMemberIds = StudyGroupMember::whereHas( diff --git a/app/Models/StudyGroupMember.php b/app/Models/StudyGroupMember.php index f88e759..47d655f 100644 --- a/app/Models/StudyGroupMember.php +++ b/app/Models/StudyGroupMember.php @@ -2,16 +2,35 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class StudyGroupMember extends Model { + // --- Traits --- + use HasFactory; + // --- Properties --- + protected $guarded = ['id']; + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function student(): BelongsTo { return $this->belongsTo(Student::class); diff --git a/app/Models/User.php b/app/Models/User.php index 2867982..bceb993 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -20,15 +20,21 @@ class User extends Authenticatable implements FilamentUser { + // --- Traits --- + /** @use HasFactory */ use HasFacehashAvatar, HasFactory, HasRoles, Notifiable, SoftDeletes; + // --- Properties --- + protected $guarded = ['id']; protected $hidden = [ 'password', ]; + // --- Casts --- + protected function casts(): array { return [ @@ -37,6 +43,8 @@ protected function casts(): array ]; } + // --- Scopes --- + #[Scope] protected function active(Builder $query): void { @@ -49,10 +57,7 @@ protected function inactive(Builder $query): void $query->where('is_active', IsActive::Inactive); } - public function canAccessPanel(Panel $panel): bool - { - return $this->is_active === IsActive::Active; - } + // --- Accessors & Mutators --- protected function name(): Attribute { @@ -61,20 +66,39 @@ protected function name(): Attribute ); } - public function student(): HasOne + protected function formattedCreatedAt(): Attribute { - return $this->hasOne(Student::class); + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); } + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + public function settings(): HasOne { return $this->hasOne(UserSetting::class)->withDefault([ 'notif_style' => NotifStyle::Cheerful, - 'primary_color' => 'amber', // Cheerful yellow + 'primary_color' => 'amber', 'font' => 'Inter', 'content_width' => 'full', 'border_radius' => 'lg', 'top_navigation' => false, ]); } + + public function student(): HasOne + { + return $this->hasOne(Student::class); + } + + // --- Methods --- + + public function canAccessPanel(Panel $panel): bool + { + return $this->is_active === IsActive::Active; + } } diff --git a/app/Models/UserSetting.php b/app/Models/UserSetting.php index cc7cb93..afe19b6 100644 --- a/app/Models/UserSetting.php +++ b/app/Models/UserSetting.php @@ -3,17 +3,17 @@ namespace App\Models; use App\Enums\NotifStyle; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class UserSetting extends Model { + // --- Properties --- + protected $guarded = ['id']; - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } + // --- Casts --- protected function casts(): array { @@ -22,4 +22,23 @@ protected function casts(): array 'top_navigation' => 'boolean', ]; } + + // --- Accessors & Mutators --- + + protected function formattedCreatedAt(): Attribute + { + return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i')); + } + + protected function formattedUpdatedAt(): Attribute + { + return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i')); + } + + // --- Relations --- + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } }