Compare commits
No commits in common. "dev" and "master" have entirely different histories.
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Actions\Fortify;
|
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
use Laravel\Fortify\Fortify;
|
|
||||||
|
|
||||||
class AuthenticateUser
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Resolve the user attempting to log in, rejecting inactive accounts.
|
|
||||||
*/
|
|
||||||
public function __invoke(Request $request): ?User
|
|
||||||
{
|
|
||||||
$user = User::where(Fortify::username(), $request->input(Fortify::username()))->first();
|
|
||||||
|
|
||||||
if (! $user || ! Hash::check($request->password, $user->password)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $user->is_active) {
|
|
||||||
throw ValidationException::withMessages([
|
|
||||||
Fortify::username() => 'Akun Anda tidak aktif. Silakan hubungi administrator.',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -12,6 +12,11 @@ class CreateNewUser implements CreatesNewUsers
|
|||||||
{
|
{
|
||||||
use PasswordValidationRules, ProfileValidationRules;
|
use PasswordValidationRules, ProfileValidationRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and create a newly registered user.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*/
|
||||||
public function create(array $input): User
|
public function create(array $input): User
|
||||||
{
|
{
|
||||||
Validator::make($input, [
|
Validator::make($input, [
|
||||||
@ -20,7 +25,7 @@ public function create(array $input): User
|
|||||||
])->validate();
|
])->validate();
|
||||||
|
|
||||||
return User::create([
|
return User::create([
|
||||||
'username' => $input['username'],
|
'name' => $input['name'],
|
||||||
'email' => $input['email'],
|
'email' => $input['email'],
|
||||||
'password' => $input['password'],
|
'password' => $input['password'],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -2,40 +2,40 @@
|
|||||||
|
|
||||||
namespace App\Concerns;
|
namespace App\Concerns;
|
||||||
|
|
||||||
use App\Enums\Gender;
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
trait ProfileValidationRules
|
trait ProfileValidationRules
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules used to validate user profiles.
|
||||||
|
*
|
||||||
|
* @return array<string, array<int, ValidationRule|array<mixed>|string>>
|
||||||
|
*/
|
||||||
protected function profileRules(?int $userId = null): array
|
protected function profileRules(?int $userId = null): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'username' => $this->usernameRules($userId),
|
'name' => $this->nameRules(),
|
||||||
'email' => $this->emailRules($userId),
|
'email' => $this->emailRules($userId),
|
||||||
'full_name' => ['required', 'string', 'max:150'],
|
|
||||||
'phone_number' => ['required', 'string', 'max:20'],
|
|
||||||
'address' => ['required', 'string'],
|
|
||||||
'gender' => ['required', 'string', Rule::in(Gender::values())],
|
|
||||||
'birth_date' => ['required', 'date'],
|
|
||||||
'birth_place' => ['required', 'string', 'max:100'],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function usernameRules(?int $userId = null): array
|
/**
|
||||||
|
* Get the validation rules used to validate user names.
|
||||||
|
*
|
||||||
|
* @return array<int, ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
protected function nameRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return ['required', 'string', 'max:255'];
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
'min:3',
|
|
||||||
'alpha_dash',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique(User::class)
|
|
||||||
: Rule::unique(User::class)->ignore($userId),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules used to validate user emails.
|
||||||
|
*
|
||||||
|
* @return array<int, ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
protected function emailRules(?int $userId = null): array
|
protected function emailRules(?int $userId = null): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum AttendanceStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Present = 'present';
|
|
||||||
case Absent = 'absent';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Present => 'Hadir',
|
|
||||||
self::Absent => 'Tidak Hadir',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum ClassMethod: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Online = 'online';
|
|
||||||
case Offline = 'offline';
|
|
||||||
case Hybrid = 'hybrid';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Online => 'Daring',
|
|
||||||
self::Offline => 'Luring',
|
|
||||||
self::Hybrid => 'Hybrid',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums\Concerns;
|
|
||||||
|
|
||||||
trait HasValues
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return array<int, string>
|
|
||||||
*/
|
|
||||||
public static function values(): array
|
|
||||||
{
|
|
||||||
return array_column(self::cases(), 'value');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<int, array{value: string, label: string}>
|
|
||||||
*/
|
|
||||||
public static function options(): array
|
|
||||||
{
|
|
||||||
return array_map(fn (self $case) => [
|
|
||||||
'value' => $case->value,
|
|
||||||
'label' => $case->label(),
|
|
||||||
], self::cases());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum FeedbackStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Submitted = 'submitted';
|
|
||||||
case InReview = 'in_review';
|
|
||||||
case Resolved = 'resolved';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Submitted => 'Terkirim',
|
|
||||||
self::InReview => 'Ditinjau',
|
|
||||||
self::Resolved => 'Selesai',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum FeedbackType: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Kritik = 'kritik';
|
|
||||||
case Saran = 'saran';
|
|
||||||
case Aduan = 'aduan';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Kritik => 'Kritik',
|
|
||||||
self::Saran => 'Saran',
|
|
||||||
self::Aduan => 'Aduan',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum Gender: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Male = 'male';
|
|
||||||
case Female = 'female';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Male => 'Laki-laki',
|
|
||||||
self::Female => 'Perempuan',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum LetterStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Submitted = 'submitted';
|
|
||||||
case InProcess = 'in_process';
|
|
||||||
case Completed = 'completed';
|
|
||||||
case Rejected = 'rejected';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Submitted => 'Diajukan',
|
|
||||||
self::InProcess => 'Diproses',
|
|
||||||
self::Completed => 'Selesai',
|
|
||||||
self::Rejected => 'Ditolak',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum PaymentMethod: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Transfer = 'transfer';
|
|
||||||
case Cash = 'cash';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Transfer => 'Transfer',
|
|
||||||
self::Cash => 'Tunai',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum PaymentStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Unpaid = 'unpaid';
|
|
||||||
case Partial = 'partial';
|
|
||||||
case Paid = 'paid';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Unpaid => 'Belum Bayar',
|
|
||||||
self::Partial => 'Sebagian',
|
|
||||||
self::Paid => 'Lunas',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum RegistrationStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Submitted = 'submitted';
|
|
||||||
case Approved = 'approved';
|
|
||||||
case Rejected = 'rejected';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Submitted => 'Diajukan',
|
|
||||||
self::Approved => 'Disetujui',
|
|
||||||
self::Rejected => 'Ditolak',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum Semester: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case odd = 'odd';
|
|
||||||
case even = 'even';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::odd => 'Ganjil',
|
|
||||||
self::even => 'Genap',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum StudentStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case Active = 'active';
|
|
||||||
case OnLeave = 'on_leave';
|
|
||||||
case Graduated = 'graduated';
|
|
||||||
case DroppedOut = 'dropped_out';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::Active => 'Aktif',
|
|
||||||
self::OnLeave => 'Cuti',
|
|
||||||
self::Graduated => 'Lulus',
|
|
||||||
self::DroppedOut => 'Drop Out',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Enums\Concerns\HasValues;
|
|
||||||
|
|
||||||
enum SubmissionStatus: string
|
|
||||||
{
|
|
||||||
use HasValues;
|
|
||||||
|
|
||||||
case NotSubmitted = 'not_submitted';
|
|
||||||
case Submitted = 'submitted';
|
|
||||||
|
|
||||||
public function label(): string
|
|
||||||
{
|
|
||||||
return match ($this) {
|
|
||||||
self::NotSubmitted => 'Belum Mengumpulkan',
|
|
||||||
self::Submitted => 'Sudah Mengumpulkan',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exports\Concerns;
|
|
||||||
|
|
||||||
use Maatwebsite\Excel\Events\AfterSheet;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|
||||||
|
|
||||||
trait StyledHeadingRow
|
|
||||||
{
|
|
||||||
abstract public function title(): string;
|
|
||||||
|
|
||||||
public function styles(Worksheet $sheet): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
1 => [
|
|
||||||
'font' => ['bold' => true, 'color' => ['rgb' => '733E0A']],
|
|
||||||
'fill' => [
|
|
||||||
'fillType' => Fill::FILL_SOLID,
|
|
||||||
'startColor' => ['rgb' => 'FDC700'],
|
|
||||||
],
|
|
||||||
'alignment' => [
|
|
||||||
'horizontal' => Alignment::HORIZONTAL_LEFT,
|
|
||||||
'vertical' => Alignment::VERTICAL_CENTER,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerEvents(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
AfterSheet::class => function (AfterSheet $event) {
|
|
||||||
$sheet = $event->sheet->getDelegate();
|
|
||||||
$lastColumn = $sheet->getHighestColumn();
|
|
||||||
|
|
||||||
$sheet->insertNewRowBefore(1, 1);
|
|
||||||
$sheet->mergeCells("A1:{$lastColumn}1");
|
|
||||||
$sheet->setCellValue('A1', $this->title().' '.config('app.name'));
|
|
||||||
$sheet->getRowDimension(1)->setRowHeight(24);
|
|
||||||
|
|
||||||
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
|
|
||||||
$sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
|
||||||
$sheet->getStyle('A1')->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exports;
|
|
||||||
|
|
||||||
use App\Exports\Concerns\StyledHeadingRow;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Services\Admin\Users\LecturerService;
|
|
||||||
use Illuminate\Support\Enumerable;
|
|
||||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
||||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
|
||||||
|
|
||||||
class LecturersExport implements FromCollection, ShouldAutoSize, WithEvents, WithHeadings, WithMapping, WithStyles
|
|
||||||
{
|
|
||||||
use StyledHeadingRow;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
private readonly string $search = '',
|
|
||||||
private readonly ?string $gender = null,
|
|
||||||
private readonly ?int $departmentId = null,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function title(): string
|
|
||||||
{
|
|
||||||
return 'Data Dosen';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function collection(): Enumerable
|
|
||||||
{
|
|
||||||
return app(LecturerService::class)->forExport($this->search, $this->gender, $this->departmentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function headings(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'NIDN',
|
|
||||||
'Nama Lengkap',
|
|
||||||
'Username',
|
|
||||||
'Email',
|
|
||||||
'Nomor Telepon',
|
|
||||||
'Jurusan',
|
|
||||||
'Jenis Kelamin',
|
|
||||||
'Tempat Lahir',
|
|
||||||
'Tanggal Lahir',
|
|
||||||
'Alamat',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function map($user): array
|
|
||||||
{
|
|
||||||
/** @var User $user */
|
|
||||||
return [
|
|
||||||
$user->lecturer?->lecturer_number ?? '-',
|
|
||||||
$user->profile?->full_name ?? '-',
|
|
||||||
$user->username,
|
|
||||||
$user->email,
|
|
||||||
$user->profile?->phone_number ?? '-',
|
|
||||||
$user->lecturer?->departments->pluck('name')->join(', ') ?: '-',
|
|
||||||
$user->profile?->gender?->label() ?? '-',
|
|
||||||
$user->profile?->birth_place ?? '-',
|
|
||||||
$user->profile?->birth_date?->format('d M Y') ?? '-',
|
|
||||||
$user->profile?->address ?? '-',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exports;
|
|
||||||
|
|
||||||
use App\Exports\Concerns\StyledHeadingRow;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Services\Admin\Users\StudentService;
|
|
||||||
use Illuminate\Support\Enumerable;
|
|
||||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
||||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
|
||||||
|
|
||||||
class StudentsExport implements FromCollection, ShouldAutoSize, WithEvents, WithHeadings, WithMapping, WithStyles
|
|
||||||
{
|
|
||||||
use StyledHeadingRow;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
private readonly string $search = '',
|
|
||||||
private readonly ?string $gender = null,
|
|
||||||
private readonly ?int $departmentId = null,
|
|
||||||
private readonly ?string $status = null,
|
|
||||||
private readonly ?int $enrollmentYear = null,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function title(): string
|
|
||||||
{
|
|
||||||
return 'Data Mahasiswa';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function collection(): Enumerable
|
|
||||||
{
|
|
||||||
return app(StudentService::class)->forExport($this->search, $this->gender, $this->departmentId, $this->status, $this->enrollmentYear);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function headings(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'NIM',
|
|
||||||
'Nama Lengkap',
|
|
||||||
'Username',
|
|
||||||
'Email',
|
|
||||||
'Nomor Telepon',
|
|
||||||
'Jurusan',
|
|
||||||
'Angkatan',
|
|
||||||
'Status',
|
|
||||||
'Jenis Kelamin',
|
|
||||||
'Tempat Lahir',
|
|
||||||
'Tanggal Lahir',
|
|
||||||
'Alamat',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function map($user): array
|
|
||||||
{
|
|
||||||
/** @var User $user */
|
|
||||||
return [
|
|
||||||
$user->student?->student_number ?? '-',
|
|
||||||
$user->profile?->full_name ?? '-',
|
|
||||||
$user->username,
|
|
||||||
$user->email,
|
|
||||||
$user->profile?->phone_number ?? '-',
|
|
||||||
$user->student?->department?->name ?? '-',
|
|
||||||
$user->student?->enrollment_year ?? '-',
|
|
||||||
$user->student?->status?->label() ?? '-',
|
|
||||||
$user->profile?->gender?->label() ?? '-',
|
|
||||||
$user->profile?->birth_place ?? '-',
|
|
||||||
$user->profile?->birth_date?->format('d M Y') ?? '-',
|
|
||||||
$user->profile?->address ?? '-',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\AcademicClasses\AssignmentRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Assignment;
|
|
||||||
use App\Services\Admin\AcademicClasses\AssignmentService;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class AssignmentController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AssignmentService $service,
|
|
||||||
private readonly CourseClassService $courseClassService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/academic-classes/assignments/index', [
|
|
||||||
'assignments' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
courseClassId: $request->validated('course_class_id'),
|
|
||||||
),
|
|
||||||
'courseClasses' => $this->courseClassService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['course_class_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AssignmentRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated(), $request->file('attachment'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tugas berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.assignments.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(AssignmentRequest $request, Assignment $assignment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($assignment, $request->validated(), $request->file('attachment'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tugas berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.assignments.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Assignment $assignment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($assignment);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Tugas berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\AcademicClasses\AttendanceStoreRequest;
|
|
||||||
use App\Models\CourseClass;
|
|
||||||
use App\Services\Admin\AcademicClasses\AttendanceService;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class AttendanceController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AttendanceService $service,
|
|
||||||
private readonly CourseClassService $courseClassService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/academic-classes/attendances/index', [
|
|
||||||
'sessions' => $this->service->sessions(),
|
|
||||||
'courseClasses' => $this->courseClassService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function session(CourseClass $courseClass, int $meetingNumber): Response
|
|
||||||
{
|
|
||||||
$courseClass->load('course');
|
|
||||||
$data = $this->service->session($courseClass, $meetingNumber);
|
|
||||||
|
|
||||||
return Inertia::render('admin/academic-classes/attendances/session', [
|
|
||||||
'courseClass' => $courseClass,
|
|
||||||
'meetingNumber' => $meetingNumber,
|
|
||||||
'roster' => $data['roster'],
|
|
||||||
'date' => $data['date'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AttendanceStoreRequest $request, CourseClass $courseClass, int $meetingNumber): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->saveSession($courseClass->id, $meetingNumber, $request->validated('date'), $request->validated('records'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kehadiran berhasil disimpan.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.attendances.session', [$courseClass->id, $meetingNumber]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(CourseClass $courseClass, int $meetingNumber): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->deleteSession($courseClass->id, $meetingNumber);
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Sesi kehadiran berhasil dihapus.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.attendances.index');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\AcademicClasses\MaterialRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Material;
|
|
||||||
use App\Services\Admin\AcademicClasses\MaterialService;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class MaterialController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly MaterialService $service,
|
|
||||||
private readonly CourseClassService $courseClassService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/academic-classes/materials/index', [
|
|
||||||
'materials' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
courseClassId: $request->validated('course_class_id'),
|
|
||||||
),
|
|
||||||
'courseClasses' => $this->courseClassService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['course_class_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(MaterialRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated(), $request->file('file'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Materi berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.materials.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(MaterialRequest $request, Material $material): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($material, $request->validated(), $request->file('file'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Materi berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.materials.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Material $material): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($material);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Materi berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\AcademicClasses\ScheduleRequest;
|
|
||||||
use App\Models\Schedule;
|
|
||||||
use App\Services\Admin\AcademicClasses\ScheduleService;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class ScheduleController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly ScheduleService $service,
|
|
||||||
private readonly CourseClassService $courseClassService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/academic-classes/schedules/index', [
|
|
||||||
'schedules' => $this->service->all(),
|
|
||||||
'courseClasses' => $this->courseClassService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(ScheduleRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Jadwal berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.schedules.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(ScheduleRequest $request, Schedule $schedule): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($schedule, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Jadwal berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.academic-classes.schedules.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Schedule $schedule): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($schedule);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Jadwal berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\AcademicClasses\SubmissionRequest;
|
|
||||||
use App\Models\Assignment;
|
|
||||||
use App\Models\Submission;
|
|
||||||
use App\Services\Admin\AcademicClasses\SubmissionService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class SubmissionController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly SubmissionService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(Assignment $assignment): Response
|
|
||||||
{
|
|
||||||
$assignment->load(['courseClass.course', 'courseClass.lecturer.user.profile', 'courseClass.academicTerm']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/academic-classes/assignments/submissions', [
|
|
||||||
'assignment' => $assignment,
|
|
||||||
'submissions' => $this->service->forAssignment($assignment),
|
|
||||||
'availableStudents' => $this->service->availableStudents($assignment),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(SubmissionRequest $request, Assignment $assignment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($assignment, $request->validated(), $request->file('file'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumpulan berhasil ditambahkan.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(SubmissionRequest $request, Assignment $assignment, Submission $submission): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($submission, $request->validated(), $request->file('file'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumpulan berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Assignment $assignment, Submission $submission): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($submission);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumpulan berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Developer;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Services\Admin\Developer\LogViewerService;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class LogController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly LogViewerService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
$files = $this->service->availableFiles();
|
|
||||||
$file = $request->validated('file') ?: $files->first()['name'] ?? null;
|
|
||||||
|
|
||||||
return Inertia::render('admin/developer/logs/index', [
|
|
||||||
'entries' => $file
|
|
||||||
? $this->service->paginated(
|
|
||||||
$file,
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
level: $request->validated('level'),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
'files' => $files,
|
|
||||||
'selectedFile' => $file,
|
|
||||||
'filters' => $request->only(['file', 'level']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function download(PaginatedRequest $request): BinaryFileResponse
|
|
||||||
{
|
|
||||||
$file = $request->validated('file');
|
|
||||||
|
|
||||||
abort_unless($file, 404);
|
|
||||||
|
|
||||||
$files = $this->service->availableFiles();
|
|
||||||
|
|
||||||
abort_unless($files->pluck('name')->contains($file), 404);
|
|
||||||
|
|
||||||
return response()->download(storage_path('logs/'.$file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Developer;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Developer\UpdateRolePermissionsRequest;
|
|
||||||
use App\Services\Admin\Developer\RolePermissionService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
use Spatie\Permission\Models\Role;
|
|
||||||
|
|
||||||
class RolePermissionController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly RolePermissionService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/developer/roles/index', [
|
|
||||||
'roles' => $this->service->roles(),
|
|
||||||
'permissionGroups' => $this->service->groupedPermissions(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(UpdateRolePermissionsRequest $request, Role $role): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updatePermissions($role, $request->validated('permissions'));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Permission role berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.developer.roles.index');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
|
||||||
|
|
||||||
use App\Enums\FeedbackStatus;
|
|
||||||
use App\Enums\FeedbackType;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Feedback\FeedbackRequest;
|
|
||||||
use App\Http\Requests\Admin\Feedback\UpdateFeedbackStatusRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Feedback;
|
|
||||||
use App\Services\Admin\FeedbackService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class FeedbackController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly FeedbackService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/feedback/index', [
|
|
||||||
'feedbacks' => $this->service->paginated(
|
|
||||||
$request->user(),
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
type: $request->validated('type'),
|
|
||||||
status: $request->validated('status'),
|
|
||||||
),
|
|
||||||
'types' => FeedbackType::options(),
|
|
||||||
'statuses' => FeedbackStatus::options(),
|
|
||||||
'filters' => $request->only(['type', 'status']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/feedback/create', [
|
|
||||||
'types' => FeedbackType::options(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(FeedbackRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->user(), $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Masukan berhasil dikirim.']);
|
|
||||||
|
|
||||||
return to_route('admin.feedback.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(Request $request, Feedback $feedback): Response
|
|
||||||
{
|
|
||||||
abort_unless($feedback->user_id === $request->user()->id, 403);
|
|
||||||
|
|
||||||
return Inertia::render('admin/feedback/edit', [
|
|
||||||
'feedback' => $feedback,
|
|
||||||
'types' => FeedbackType::options(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(FeedbackRequest $request, Feedback $feedback): RedirectResponse
|
|
||||||
{
|
|
||||||
abort_unless($feedback->user_id === $request->user()->id, 403);
|
|
||||||
|
|
||||||
$this->service->update($feedback, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Masukan berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.feedback.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateStatus(UpdateFeedbackStatusRequest $request, Feedback $feedback): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateStatus($feedback, $request->validated('status'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status masukan berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Request $request, Feedback $feedback): RedirectResponse
|
|
||||||
{
|
|
||||||
abort_unless($feedback->user_id === $request->user()->id, 403);
|
|
||||||
|
|
||||||
$this->service->delete($feedback);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Masukan berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Finances;
|
|
||||||
|
|
||||||
use App\Enums\StudentStatus;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Finances\TuitionInvoiceRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\TuitionInvoice;
|
|
||||||
use App\Services\Admin\Finances\TuitionInvoiceService;
|
|
||||||
use App\Services\Admin\Master\AcademicTermService;
|
|
||||||
use App\Services\Admin\Users\StudentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class TuitionInvoiceController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly TuitionInvoiceService $service,
|
|
||||||
private readonly StudentService $studentService,
|
|
||||||
private readonly AcademicTermService $academicTermService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
$students = $this->studentService->getAllForSelect(status: StudentStatus::Active->value);
|
|
||||||
|
|
||||||
$invoicedTermIdsByStudent = $this->service->getInvoicedTermIdsByStudent($students->pluck('id')->all());
|
|
||||||
|
|
||||||
$students->each(function ($student) use ($invoicedTermIdsByStudent) {
|
|
||||||
$student->invoiced_term_ids = $invoicedTermIdsByStudent->get($student->id, []);
|
|
||||||
});
|
|
||||||
|
|
||||||
$academicTerms = $this->academicTermService->getAllForSelect();
|
|
||||||
|
|
||||||
$requestedTermId = $request->validated('academic_term_id');
|
|
||||||
$summaryTermId = $requestedTermId ?? $this->academicTermService->getActive()?->id;
|
|
||||||
|
|
||||||
return Inertia::render('admin/finances/tuition-invoices/index', [
|
|
||||||
'invoices' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
academicTermId: $requestedTermId,
|
|
||||||
status: $request->validated('status'),
|
|
||||||
paymentMethod: $request->validated('payment_method'),
|
|
||||||
),
|
|
||||||
'summary' => $this->service->summary(
|
|
||||||
search: $request->validated('search') ?? '',
|
|
||||||
academicTermId: $summaryTermId,
|
|
||||||
),
|
|
||||||
'summaryAcademicTerm' => $academicTerms->firstWhere('id', $summaryTermId),
|
|
||||||
'students' => $students,
|
|
||||||
'academicTerms' => $academicTerms,
|
|
||||||
'filters' => $request->only(['academic_term_id', 'status', 'payment_method']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(TuitionInvoiceRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->createMany($request->validated('student_ids'), $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tagihan berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.finances.tuition-invoices.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(TuitionInvoiceRequest $request, TuitionInvoice $tuitionInvoice): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($tuitionInvoice, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tagihan berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.finances.tuition-invoices.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(TuitionInvoice $tuitionInvoice): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($tuitionInvoice);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Tagihan berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Finances;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Finances\TuitionPaymentRequest;
|
|
||||||
use App\Models\TuitionInvoice;
|
|
||||||
use App\Models\TuitionPayment;
|
|
||||||
use App\Services\Admin\Finances\TuitionPaymentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class TuitionPaymentController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly TuitionPaymentService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(TuitionInvoice $tuitionInvoice): Response
|
|
||||||
{
|
|
||||||
$tuitionInvoice->load(['student.user.profile', 'student.department', 'academicTerm']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/finances/tuition-invoices/payments', [
|
|
||||||
'invoice' => $tuitionInvoice,
|
|
||||||
'payments' => $this->service->forInvoice($tuitionInvoice),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(TuitionPaymentRequest $request, TuitionInvoice $tuitionInvoice): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($tuitionInvoice, $request->validated(), $request->file('proof'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pembayaran berhasil ditambahkan.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(TuitionPaymentRequest $request, TuitionInvoice $tuitionInvoice, TuitionPayment $payment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($payment, $request->validated(), $request->file('proof'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pembayaran berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(TuitionInvoice $tuitionInvoice, TuitionPayment $payment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($payment);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pembayaran berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Manage\AnnouncementRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Announcement;
|
|
||||||
use App\Services\Admin\Manage\AnnouncementService;
|
|
||||||
use App\Services\Admin\Master\DepartmentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class AnnouncementController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AnnouncementService $service,
|
|
||||||
private readonly DepartmentService $departmentService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/manage/announcements/index', [
|
|
||||||
'announcements' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
),
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['department_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AnnouncementRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumuman berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.manage.announcements.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(AnnouncementRequest $request, Announcement $announcement): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($announcement, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumuman berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.manage.announcements.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Announcement $announcement): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($announcement);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengumuman berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Manage\ClassEnrollmentRequest;
|
|
||||||
use App\Models\ClassEnrollment;
|
|
||||||
use App\Models\CourseClass;
|
|
||||||
use App\Services\Admin\Manage\ClassEnrollmentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class ClassEnrollmentController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly ClassEnrollmentService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(CourseClass $courseClass): Response
|
|
||||||
{
|
|
||||||
$courseClass->load(['course', 'lecturer.user.profile', 'academicTerm']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/manage/course-classes/enrollments', [
|
|
||||||
'courseClass' => $courseClass,
|
|
||||||
'enrollments' => $this->service->forClass($courseClass),
|
|
||||||
'availableStudents' => $this->service->availableStudents($courseClass),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(ClassEnrollmentRequest $request, CourseClass $courseClass): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->enrollMany($courseClass, $request->validated('student_ids'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Mahasiswa berhasil ditambahkan ke kelas.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(CourseClass $courseClass, ClassEnrollment $enrollment): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->unenroll($enrollment);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Mahasiswa berhasil dikeluarkan dari kelas.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Manage\CourseClassRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\CourseClass;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use App\Services\Admin\Master\AcademicTermService;
|
|
||||||
use App\Services\Admin\Master\CourseService;
|
|
||||||
use App\Services\Admin\Users\LecturerService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class CourseClassController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly CourseClassService $service,
|
|
||||||
private readonly CourseService $courseService,
|
|
||||||
private readonly LecturerService $lecturerService,
|
|
||||||
private readonly AcademicTermService $academicTermService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/manage/course-classes/index', [
|
|
||||||
'courseClasses' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
academicTermId: $request->validated('academic_term_id'),
|
|
||||||
method: $request->validated('method'),
|
|
||||||
),
|
|
||||||
'courses' => $this->courseService->getAllForSelect(),
|
|
||||||
'lecturers' => $this->lecturerService->getAllForSelect(),
|
|
||||||
'academicTerms' => $this->academicTermService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['academic_term_id', 'method']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(CourseClassRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kelas mata kuliah berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.manage.course-classes.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(CourseClassRequest $request, CourseClass $courseClass): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($courseClass, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kelas mata kuliah berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.manage.course-classes.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(CourseClass $courseClass): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($courseClass);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kelas mata kuliah berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,147 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Manage\CourseRegistrationRequest;
|
|
||||||
use App\Http\Requests\Admin\Manage\RejectCourseRegistrationRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\CourseRegistrationSubmission;
|
|
||||||
use App\Models\Student;
|
|
||||||
use App\Services\Admin\Manage\CourseClassService;
|
|
||||||
use App\Services\Admin\Manage\CourseRegistrationService;
|
|
||||||
use App\Services\Admin\Master\AcademicTermService;
|
|
||||||
use App\Services\Admin\Users\StudentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class CourseRegistrationController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly CourseRegistrationService $service,
|
|
||||||
private readonly StudentService $studentService,
|
|
||||||
private readonly AcademicTermService $academicTermService,
|
|
||||||
private readonly CourseClassService $courseClassService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/manage/course-registrations/index', [
|
|
||||||
'registrations' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
status: $request->validated('status'),
|
|
||||||
academicTermId: $request->validated('academic_term_id'),
|
|
||||||
),
|
|
||||||
'students' => $this->studentService->getAllForSelect(),
|
|
||||||
'academicTerms' => $this->academicTermService->getAllForSelect(),
|
|
||||||
'courseClasses' => $this->courseClassService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['status', 'academic_term_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function mine(Request $request): Response
|
|
||||||
{
|
|
||||||
$student = $this->currentStudent($request);
|
|
||||||
|
|
||||||
$term = $this->academicTermService->getActive();
|
|
||||||
$payment = $term ? $this->service->paymentStatus($student, $term) : null;
|
|
||||||
$activeSubmission = $term ? $this->service->currentSubmission($student, $term) : null;
|
|
||||||
|
|
||||||
return Inertia::render('student/course-registrations/index', [
|
|
||||||
'academicTerm' => $term,
|
|
||||||
'payment' => $payment,
|
|
||||||
'canSubmit' => $this->service->canSubmit($activeSubmission),
|
|
||||||
'activeSubmission' => $activeSubmission,
|
|
||||||
'submissions' => $this->service->submissionsFor($student),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(Request $request): Response|RedirectResponse
|
|
||||||
{
|
|
||||||
$student = $this->currentStudent($request);
|
|
||||||
|
|
||||||
$student->load(['user.profile', 'department', 'academicAdvisor.user.profile']);
|
|
||||||
|
|
||||||
$term = $this->academicTermService->getActive();
|
|
||||||
$payment = $term ? $this->service->paymentStatus($student, $term) : null;
|
|
||||||
$submission = $term ? $this->service->currentSubmission($student, $term) : null;
|
|
||||||
|
|
||||||
if (! $term || ! $payment['is_paid'] || ! $this->service->canSubmit($submission)) {
|
|
||||||
return to_route('student.course-registrations.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inertia::render('student/course-registrations/create', [
|
|
||||||
'student' => $student,
|
|
||||||
'academicTerm' => $term,
|
|
||||||
'submission' => $submission,
|
|
||||||
'availableCourses' => $this->service->availableCourseClasses($student, $term),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show(Request $request, CourseRegistrationSubmission $submission): Response
|
|
||||||
{
|
|
||||||
if ($request->routeIs('student.*')) {
|
|
||||||
$student = $this->currentStudent($request);
|
|
||||||
|
|
||||||
abort_if($submission->student_id !== $student->id, 403);
|
|
||||||
|
|
||||||
return Inertia::render('student/course-registrations/show', [
|
|
||||||
'submission' => $this->service->withDetails($submission),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inertia::render('admin/manage/course-registrations/show', [
|
|
||||||
'submission' => $this->service->withDetails($submission),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(CourseRegistrationRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
if ($request->routeIs('student.*')) {
|
|
||||||
$student = $this->currentStudent($request);
|
|
||||||
$term = $this->academicTermService->getActive();
|
|
||||||
|
|
||||||
$submission = $this->service->sign(
|
|
||||||
$student,
|
|
||||||
$term,
|
|
||||||
$request->validated('course_class_ids'),
|
|
||||||
$request->file('signature'),
|
|
||||||
);
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil ditandatangani.']);
|
|
||||||
|
|
||||||
return to_route('student.course-registrations.show', $submission);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Registrasi KRS berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.manage.course-registrations.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function approve(CourseRegistrationSubmission $submission): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->approve($submission);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disetujui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reject(RejectCourseRegistrationRequest $request, CourseRegistrationSubmission $submission): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->reject($submission, $request->validated('reason'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil ditolak.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function currentStudent(Request $request): Student
|
|
||||||
{
|
|
||||||
$student = $request->user()->student;
|
|
||||||
|
|
||||||
abort_if(! $student, 403);
|
|
||||||
|
|
||||||
return $student;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Master;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Master\AcademicTermRequest;
|
|
||||||
use App\Http\Requests\Admin\UpdateStatusRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\AcademicTerm;
|
|
||||||
use App\Services\Admin\Master\AcademicTermService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class AcademicTermController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AcademicTermService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/master/academic-terms/index', [
|
|
||||||
'academicTerms' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
semester: $request->validated('semester'),
|
|
||||||
isActive: $request->filled('is_active') ? filter_var($request->validated('is_active'), FILTER_VALIDATE_BOOLEAN) : null,
|
|
||||||
),
|
|
||||||
'filters' => $request->only(['semester', 'is_active']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AcademicTermRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Periode akademik berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.academic-terms.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(AcademicTermRequest $request, AcademicTerm $academicTerm): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($academicTerm, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Periode akademik berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.academic-terms.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(AcademicTerm $academicTerm): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($academicTerm);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Periode akademik berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateStatus(UpdateStatusRequest $request, AcademicTerm $academicTerm): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateActiveStatus($academicTerm, $request->boolean('is_active'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status periode akademik berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Master;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Master\CourseRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Services\Admin\Master\CourseService;
|
|
||||||
use App\Services\Admin\Master\DepartmentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class CourseController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly CourseService $service,
|
|
||||||
private readonly DepartmentService $departmentService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/master/courses/index', [
|
|
||||||
'courses' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
semesterNumber: $request->validated('semester_number'),
|
|
||||||
),
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'semesterNumbers' => $this->service->getSemesterNumbers(),
|
|
||||||
'filters' => $request->only(['department_id', 'semester_number']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(CourseRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mata kuliah berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.courses.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(CourseRequest $request, Course $course): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($course, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mata kuliah berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.courses.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Course $course): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($course);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Mata kuliah berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Master;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Master\DepartmentRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\Department;
|
|
||||||
use App\Services\Admin\Master\DepartmentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class DepartmentController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly DepartmentService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/master/departments/index', [
|
|
||||||
'departments' => $this->service->paginated(...$request->validatedWithDefaults()),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(DepartmentRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Jurusan berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.departments.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(DepartmentRequest $request, Department $department): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($department, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Jurusan berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.master.departments.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Department $department): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($department);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Jurusan berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Services;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Services\AcademicAdvisingLogRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\AcademicAdvisingLog;
|
|
||||||
use App\Services\Admin\Services\AcademicAdvisingLogService;
|
|
||||||
use App\Services\Admin\Users\LecturerService;
|
|
||||||
use App\Services\Admin\Users\StudentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class AcademicAdvisingLogController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AcademicAdvisingLogService $service,
|
|
||||||
private readonly StudentService $studentService,
|
|
||||||
private readonly LecturerService $lecturerService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/services/academic-advising-logs/index', [
|
|
||||||
'logs' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
lecturerId: $request->validated('lecturer_id'),
|
|
||||||
),
|
|
||||||
'students' => $this->studentService->getAllForSelect(),
|
|
||||||
'lecturers' => $this->lecturerService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['lecturer_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AcademicAdvisingLogRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Bimbingan akademik berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.services.academic-advising-logs.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(AcademicAdvisingLogRequest $request, AcademicAdvisingLog $academicAdvisingLog): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($academicAdvisingLog, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Bimbingan akademik berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.services.academic-advising-logs.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(AcademicAdvisingLog $academicAdvisingLog): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($academicAdvisingLog);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Bimbingan akademik berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Services;
|
|
||||||
|
|
||||||
use App\Enums\LetterStatus;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Services\LetterRequest\LetterRequestRequest;
|
|
||||||
use App\Http\Requests\Admin\Services\LetterRequest\LetterRequestStatusRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\LetterRequest;
|
|
||||||
use App\Services\Admin\Services\LetterRequestService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class LetterRequestController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly LetterRequestService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/services/letter-requests/index', [
|
|
||||||
'letterRequests' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
status: $request->validated('status'),
|
|
||||||
),
|
|
||||||
'filters' => $request->only(['status']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(LetterRequestRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create([
|
|
||||||
'user_id' => auth()->id(),
|
|
||||||
...$request->validated(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Surat permohonan berhasil diajukan.']);
|
|
||||||
|
|
||||||
return to_route('admin.services.letter-requests.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(LetterRequestRequest $request, LetterRequest $letterRequest): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($letterRequest, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Surat permohonan berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.services.letter-requests.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(LetterRequest $letterRequest): RedirectResponse
|
|
||||||
{
|
|
||||||
abort_if($letterRequest->status !== LetterStatus::Submitted->value, 403);
|
|
||||||
|
|
||||||
$this->service->delete($letterRequest);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Surat permohonan berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateStatus(LetterRequestStatusRequest $request, LetterRequest $letterRequest): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateStatus($letterRequest, $request->validated('status'), $request->file('result'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status surat permohonan berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Settings;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Settings\ProfileDeleteRequest;
|
|
||||||
use App\Http\Requests\Admin\Settings\ProfileUpdateRequest;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class ProfileController extends Controller
|
|
||||||
{
|
|
||||||
public function edit(Request $request): Response
|
|
||||||
{
|
|
||||||
$user = $request->user();
|
|
||||||
|
|
||||||
[$role, $roleData] = match (true) {
|
|
||||||
$user->hasRole('mahasiswa') => $this->studentRoleData($user),
|
|
||||||
$user->hasRole('dosen') => $this->lecturerRoleData($user),
|
|
||||||
default => $this->administratorRoleData($user),
|
|
||||||
};
|
|
||||||
|
|
||||||
return Inertia::render('admin/settings/profile', [
|
|
||||||
'mustVerifyEmail' => $user instanceof MustVerifyEmail,
|
|
||||||
'status' => $request->session()->get('status'),
|
|
||||||
'profile' => $user->profile,
|
|
||||||
'role' => $role,
|
|
||||||
'roleData' => $roleData,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(ProfileUpdateRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$user = $request->user();
|
|
||||||
|
|
||||||
$user->fill($request->safe()->only(['username', 'email']));
|
|
||||||
|
|
||||||
if ($user->isDirty('email')) {
|
|
||||||
$user->email_verified_at = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->save();
|
|
||||||
|
|
||||||
$user->profile()->updateOrCreate([], $request->safe()->only([
|
|
||||||
'full_name', 'phone_number', 'address', 'gender', 'birth_date', 'birth_place',
|
|
||||||
]));
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Profil berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.settings.profile.edit');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(ProfileDeleteRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$user = $request->user();
|
|
||||||
|
|
||||||
Auth::logout();
|
|
||||||
|
|
||||||
$user->delete();
|
|
||||||
|
|
||||||
$request->session()->invalidate();
|
|
||||||
$request->session()->regenerateToken();
|
|
||||||
|
|
||||||
return redirect('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function studentRoleData(User $user): array
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'student.department', 'student.academicAdvisor.user.profile']);
|
|
||||||
|
|
||||||
return ['mahasiswa', $user->student ? [
|
|
||||||
'student_number' => $user->student->student_number,
|
|
||||||
'department' => $user->student->department?->name,
|
|
||||||
'enrollment_year' => $user->student->enrollment_year,
|
|
||||||
'academic_advisor' => $user->student->academicAdvisor?->user?->profile?->full_name,
|
|
||||||
] : null];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function lecturerRoleData(User $user): array
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'lecturer.departments']);
|
|
||||||
|
|
||||||
return ['dosen', $user->lecturer ? [
|
|
||||||
'lecturer_number' => $user->lecturer->lecturer_number,
|
|
||||||
'department' => $user->lecturer->departments->pluck('name')->join(', ') ?: null,
|
|
||||||
] : null];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function administratorRoleData(User $user): array
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'roles']);
|
|
||||||
|
|
||||||
return ['admin', [
|
|
||||||
'roles' => $user->roles->pluck('name')->all(),
|
|
||||||
]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Settings;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\Settings\PasswordUpdateRequest;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Validation\Rules\Password;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
|
|
||||||
class SecurityController extends Controller
|
|
||||||
{
|
|
||||||
public function edit(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/settings/security', [
|
|
||||||
'passwordRules' => Password::defaults()->toPasswordRulesString(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(PasswordUpdateRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$request->user()->update([
|
|
||||||
'password' => $request->password,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Users;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\UpdateStatusRequest;
|
|
||||||
use App\Http\Requests\Admin\Users\AdministratorRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Services\Admin\Users\AdministratorService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
use Spatie\Permission\Models\Role;
|
|
||||||
|
|
||||||
class AdministratorController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly AdministratorService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/administrators/index', [
|
|
||||||
'administrators' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
gender: $request->validated('gender'),
|
|
||||||
),
|
|
||||||
'filters' => $request->only(['gender']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/administrators/create', [
|
|
||||||
'roles' => Role::whereIn('name', ['staff-admin', 'staff-keuangan'])->get(['id', 'name']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(AdministratorRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Administrator berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.administrators.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(User $user): Response
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'roles']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/users/administrators/edit', [
|
|
||||||
'user' => $user,
|
|
||||||
'roles' => Role::whereIn('name', ['staff-admin', 'staff-keuangan'])->get(['id', 'name']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(AdministratorRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($user, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Administrator berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.administrators.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Administrator berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetPassword(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->resetPassword($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil direset.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateUserStatus(UpdateStatusRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateUserStatus($user, $request->boolean('is_active'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status akun berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Users;
|
|
||||||
|
|
||||||
use App\Exports\LecturersExport;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\UpdateStatusRequest;
|
|
||||||
use App\Http\Requests\Admin\Users\LecturerRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Services\Admin\Master\DepartmentService;
|
|
||||||
use App\Services\Admin\Users\LecturerService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class LecturerController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly LecturerService $service,
|
|
||||||
private readonly DepartmentService $departmentService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/lecturers/index', [
|
|
||||||
'lecturers' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
gender: $request->validated('gender'),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
),
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'filters' => $request->only(['gender', 'department_id']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/lecturers/create', [
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(LecturerRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Dosen berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.lecturers.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(User $user): Response
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'lecturer.departments']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/users/lecturers/edit', [
|
|
||||||
'user' => $user,
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(LecturerRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($user, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Dosen berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.lecturers.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Dosen berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetPassword(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->resetPassword($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil direset.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateUserStatus(UpdateStatusRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateUserStatus($user, $request->boolean('is_active'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status akun berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function export(PaginatedRequest $request): BinaryFileResponse
|
|
||||||
{
|
|
||||||
return Excel::download(new LecturersExport(
|
|
||||||
search: $request->validated('search') ?? '',
|
|
||||||
gender: $request->validated('gender'),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
), 'dosen.xlsx');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,122 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Users;
|
|
||||||
|
|
||||||
use App\Enums\StudentStatus;
|
|
||||||
use App\Exports\StudentsExport;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Admin\UpdateStatusRequest;
|
|
||||||
use App\Http\Requests\Admin\Users\Student\StudentRequest;
|
|
||||||
use App\Http\Requests\Admin\Users\Student\StudentStatusRequest;
|
|
||||||
use App\Http\Requests\PaginatedRequest;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Services\Admin\Master\DepartmentService;
|
|
||||||
use App\Services\Admin\Users\LecturerService;
|
|
||||||
use App\Services\Admin\Users\StudentService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Response;
|
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class StudentController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly StudentService $service,
|
|
||||||
private readonly DepartmentService $departmentService,
|
|
||||||
private readonly LecturerService $lecturerService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function index(PaginatedRequest $request): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/students/index', [
|
|
||||||
'students' => $this->service->paginated(
|
|
||||||
...$request->validatedWithDefaults(),
|
|
||||||
gender: $request->validated('gender'),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
status: $request->validated('status'),
|
|
||||||
enrollmentYear: $request->validated('enrollment_year'),
|
|
||||||
),
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'statuses' => StudentStatus::options(),
|
|
||||||
'enrollmentYears' => $this->service->getEnrollmentYears(),
|
|
||||||
'filters' => $request->only(['gender', 'department_id', 'status', 'enrollment_year']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): Response
|
|
||||||
{
|
|
||||||
return Inertia::render('admin/users/students/create', [
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'lecturers' => $this->lecturerService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(StudentRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->create($request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mahasiswa berhasil ditambahkan.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.students.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(User $user): Response
|
|
||||||
{
|
|
||||||
$user->load(['profile', 'student.department', 'student.academicAdvisor.user.profile']);
|
|
||||||
|
|
||||||
return Inertia::render('admin/users/students/edit', [
|
|
||||||
'user' => $user,
|
|
||||||
'departments' => $this->departmentService->getAllForSelect(),
|
|
||||||
'lecturers' => $this->lecturerService->getAllForSelect(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(StudentRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->update($user, $request->validated());
|
|
||||||
|
|
||||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mahasiswa berhasil diperbarui.']);
|
|
||||||
|
|
||||||
return to_route('admin.users.students.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->delete($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Mahasiswa berhasil dihapus.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetPassword(User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->resetPassword($user);
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil direset.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateStatus(StudentStatusRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateStatus($user, $request->validated('status'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status mahasiswa berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateUserStatus(UpdateStatusRequest $request, User $user): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->updateUserStatus($user, $request->boolean('is_active'));
|
|
||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status akun berhasil diperbarui.'])->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function export(PaginatedRequest $request): BinaryFileResponse
|
|
||||||
{
|
|
||||||
return Excel::download(new StudentsExport(
|
|
||||||
search: $request->validated('search') ?? '',
|
|
||||||
gender: $request->validated('gender'),
|
|
||||||
departmentId: $request->validated('department_id'),
|
|
||||||
status: $request->validated('status'),
|
|
||||||
enrollmentYear: $request->validated('enrollment_year'),
|
|
||||||
), 'mahasiswa.xlsx');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Requests\MediaUploadRequest;
|
|
||||||
use App\Services\MediaUploadService;
|
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
|
|
||||||
class MediaUploadController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly MediaUploadService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function store(MediaUploadRequest $request): JsonResponse
|
|
||||||
{
|
|
||||||
$media = $this->service->store(
|
|
||||||
$request->user(),
|
|
||||||
$request->file('file'),
|
|
||||||
$request->validated('collection') ?? 'content',
|
|
||||||
);
|
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'id' => $media->id,
|
|
||||||
'name' => $media->name,
|
|
||||||
'file_name' => $media->file_name,
|
|
||||||
'mime_type' => $media->mime_type,
|
|
||||||
'size' => $media->size,
|
|
||||||
'url' => $media->getUrl(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Models\Notification;
|
|
||||||
use App\Services\NotificationService;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class NotificationController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly NotificationService $service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function markAllRead(Request $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->markAllAsRead($request->user());
|
|
||||||
|
|
||||||
return back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroyAll(Request $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->service->deleteAll($request->user());
|
|
||||||
|
|
||||||
return back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function markRead(Request $request, Notification $notification): RedirectResponse
|
|
||||||
{
|
|
||||||
abort_unless($notification->user_id === $request->user()->id, 403);
|
|
||||||
|
|
||||||
$this->service->markAsRead($notification);
|
|
||||||
|
|
||||||
return back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Request $request, Notification $notification): RedirectResponse
|
|
||||||
{
|
|
||||||
abort_unless($notification->user_id === $request->user()->id, 403);
|
|
||||||
|
|
||||||
$this->service->delete($notification);
|
|
||||||
|
|
||||||
return back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
62
app/Http/Controllers/Settings/ProfileController.php
Normal file
62
app/Http/Controllers/Settings/ProfileController.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Settings;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Settings\ProfileDeleteRequest;
|
||||||
|
use App\Http\Requests\Settings\ProfileUpdateRequest;
|
||||||
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
use Inertia\Response;
|
||||||
|
|
||||||
|
class ProfileController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show the user's profile settings page.
|
||||||
|
*/
|
||||||
|
public function edit(Request $request): Response
|
||||||
|
{
|
||||||
|
return Inertia::render('settings/profile', [
|
||||||
|
'mustVerifyEmail' => $request->user() instanceof MustVerifyEmail,
|
||||||
|
'status' => $request->session()->get('status'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the user's profile information.
|
||||||
|
*/
|
||||||
|
public function update(ProfileUpdateRequest $request): RedirectResponse
|
||||||
|
{
|
||||||
|
$request->user()->fill($request->validated());
|
||||||
|
|
||||||
|
if ($request->user()->isDirty('email')) {
|
||||||
|
$request->user()->email_verified_at = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->user()->save();
|
||||||
|
|
||||||
|
Inertia::flash('toast', ['type' => 'success', 'message' => __('Profile updated.')]);
|
||||||
|
|
||||||
|
return to_route('profile.edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the user's profile.
|
||||||
|
*/
|
||||||
|
public function destroy(ProfileDeleteRequest $request): RedirectResponse
|
||||||
|
{
|
||||||
|
$user = $request->user();
|
||||||
|
|
||||||
|
Auth::logout();
|
||||||
|
|
||||||
|
$user->delete();
|
||||||
|
|
||||||
|
$request->session()->invalidate();
|
||||||
|
$request->session()->regenerateToken();
|
||||||
|
|
||||||
|
return redirect('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Http/Controllers/Settings/SecurityController.php
Normal file
66
app/Http/Controllers/Settings/SecurityController.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Settings;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Settings\PasswordUpdateRequest;
|
||||||
|
use App\Http\Requests\Settings\TwoFactorAuthenticationRequest;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
use Inertia\Response;
|
||||||
|
use Laravel\Fortify\Features;
|
||||||
|
|
||||||
|
class SecurityController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show the user's security settings page.
|
||||||
|
*/
|
||||||
|
public function edit(TwoFactorAuthenticationRequest $request): Response
|
||||||
|
{
|
||||||
|
$props = [
|
||||||
|
'canManageTwoFactor' => Features::canManageTwoFactorAuthentication(),
|
||||||
|
'canManagePasskeys' => Features::canManagePasskeys(),
|
||||||
|
'passkeys' => Features::canManagePasskeys()
|
||||||
|
? $request->user()
|
||||||
|
->passkeys()
|
||||||
|
->select(['id', 'name', 'credential', 'created_at', 'last_used_at'])
|
||||||
|
->latest()
|
||||||
|
->get()
|
||||||
|
->map(fn ($passkey) => [
|
||||||
|
'id' => $passkey->id,
|
||||||
|
'name' => $passkey->name,
|
||||||
|
'authenticator' => $passkey->authenticator,
|
||||||
|
'created_at_diff' => $passkey->created_at->diffForHumans(),
|
||||||
|
'last_used_at_diff' => $passkey->last_used_at?->diffForHumans(),
|
||||||
|
])
|
||||||
|
->values()
|
||||||
|
->all()
|
||||||
|
: [],
|
||||||
|
'passwordRules' => Password::defaults()->toPasswordRulesString(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (Features::canManageTwoFactorAuthentication()) {
|
||||||
|
$request->ensureStateIsValid();
|
||||||
|
|
||||||
|
$props['twoFactorEnabled'] = $request->user()->hasEnabledTwoFactorAuthentication();
|
||||||
|
$props['requiresConfirmation'] = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inertia::render('settings/security', $props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the user's password.
|
||||||
|
*/
|
||||||
|
public function update(PasswordUpdateRequest $request): RedirectResponse
|
||||||
|
{
|
||||||
|
$request->user()->update([
|
||||||
|
'password' => $request->password,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Inertia::flash('toast', ['type' => 'success', 'message' => __('Password updated.')]);
|
||||||
|
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Services\Admin\FeedbackService;
|
|
||||||
use App\Services\NotificationService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Inertia;
|
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
|
|
||||||
class HandleInertiaRequests extends Middleware
|
class HandleInertiaRequests extends Middleware
|
||||||
@ -42,19 +39,9 @@ public function share(Request $request): array
|
|||||||
...parent::share($request),
|
...parent::share($request),
|
||||||
'name' => config('app.name'),
|
'name' => config('app.name'),
|
||||||
'auth' => [
|
'auth' => [
|
||||||
'user' => $request->user()?->load('roles:id,name'),
|
'user' => $request->user(),
|
||||||
'permissions' => $request->user()?->getAllPermissions()->pluck('name')->values() ?? [],
|
|
||||||
],
|
],
|
||||||
'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
|
'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
|
||||||
'unreadNotificationsCount' => fn () => $request->user()
|
|
||||||
? app(NotificationService::class)->unreadCount($request->user())
|
|
||||||
: 0,
|
|
||||||
'pendingFeedbackCount' => fn () => $request->user()
|
|
||||||
? app(FeedbackService::class)->pendingCount($request->user())
|
|
||||||
: 0,
|
|
||||||
'notifications' => Inertia::merge(fn () => $request->user()
|
|
||||||
? app(NotificationService::class)->paginated($request->user())
|
|
||||||
: null)->append('data', 'id'),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AssignmentRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-assignments' : 'update-assignments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'course_class_id' => ['required', 'integer', Rule::exists('course_classes', 'id')],
|
|
||||||
'title' => ['required', 'string', 'max:150'],
|
|
||||||
'description' => ['nullable', 'string'],
|
|
||||||
'deadline' => ['required', 'date'],
|
|
||||||
'attachment' => ['nullable', 'file', 'max:10240', 'mimes:pdf,doc,docx,ppt,pptx,xls,xlsx,jpg,jpeg,png,mp4,zip'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Enums\AttendanceStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AttendanceStoreRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('create-attendances');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'date' => ['required', 'date'],
|
|
||||||
'records' => ['required', 'array', 'min:1'],
|
|
||||||
'records.*.student_id' => ['required', 'integer', Rule::exists('students', 'id')],
|
|
||||||
'records.*.status' => ['required', Rule::enum(AttendanceStatus::class)],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class MaterialRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-materials' : 'update-materials');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'course_class_id' => ['required', 'integer', Rule::exists('course_classes', 'id')],
|
|
||||||
'title' => ['required', 'string', 'max:150'],
|
|
||||||
'description' => ['nullable', 'string'],
|
|
||||||
'meeting_number' => ['nullable', 'integer', 'min:1'],
|
|
||||||
'file' => [
|
|
||||||
'nullable',
|
|
||||||
'file',
|
|
||||||
'max:10240',
|
|
||||||
'mimes:pdf,doc,docx,ppt,pptx,xls,xlsx,jpg,jpeg,png,mp4,zip',
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class ScheduleRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-schedules' : 'update-schedules');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'course_class_id' => ['required', 'integer', Rule::exists('course_classes', 'id')],
|
|
||||||
'day_of_week' => ['nullable', 'string', 'max:15'],
|
|
||||||
'start_time' => ['nullable', 'date_format:H:i'],
|
|
||||||
'end_time' => ['nullable', 'date_format:H:i', 'after:start_time'],
|
|
||||||
'room' => ['nullable', 'string', 'max:20'],
|
|
||||||
'online_link' => ['nullable', 'string', 'max:255', 'url'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\AcademicClasses;
|
|
||||||
|
|
||||||
use App\Enums\SubmissionStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class SubmissionRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-assignment-submissions' : 'update-assignment-submissions');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$assignment = $this->route('assignment');
|
|
||||||
$submission = $this->route('submission');
|
|
||||||
|
|
||||||
$rules = [
|
|
||||||
'notes' => ['nullable', 'string'],
|
|
||||||
'status' => ['required', Rule::enum(SubmissionStatus::class)],
|
|
||||||
'submitted_at' => ['nullable', 'date'],
|
|
||||||
'score' => ['nullable', 'numeric', 'min:0', 'max:100'],
|
|
||||||
'lecturer_feedback' => ['nullable', 'string'],
|
|
||||||
'file' => ['nullable', 'file', 'max:10240', 'mimes:pdf,doc,docx,ppt,pptx,xls,xlsx,jpg,jpeg,png,mp4,zip'],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (! $submission) {
|
|
||||||
$rules['student_id'] = [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
Rule::exists('class_enrollments', 'student_id')->where('course_class_id', $assignment->course_class_id),
|
|
||||||
Rule::unique('submissions', 'student_id')->where('assignment_id', $assignment->id),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Developer;
|
|
||||||
|
|
||||||
use App\Support\PermissionCatalog;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class UpdateRolePermissionsRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('update-roles');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'permissions' => ['present', 'array'],
|
|
||||||
'permissions.*' => ['string', Rule::in(PermissionCatalog::all())],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Feedback;
|
|
||||||
|
|
||||||
use App\Enums\FeedbackType;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class FeedbackRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-feedback' : 'update-feedback');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'type' => ['required', 'string', Rule::in(FeedbackType::values())],
|
|
||||||
'subject' => ['required', 'string', 'max:150'],
|
|
||||||
'message' => ['required', 'string'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Feedback;
|
|
||||||
|
|
||||||
use App\Enums\FeedbackStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class UpdateFeedbackStatusRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('update-feedback-status');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => ['required', Rule::enum(FeedbackStatus::class)],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Finances;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class TuitionInvoiceRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-tuition-invoices' : 'update-tuition-invoices');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$rules = [
|
|
||||||
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
|
|
||||||
'amount_due' => ['required', 'numeric', 'min:0'],
|
|
||||||
'due_date' => ['required', 'date'],
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($this->isMethod('post')) {
|
|
||||||
$rules['student_ids'] = ['required', 'array', 'min:1'];
|
|
||||||
$rules['student_ids.*'] = [
|
|
||||||
'integer',
|
|
||||||
Rule::exists('students', 'id'),
|
|
||||||
Rule::unique('tuition_invoices', 'student_id')
|
|
||||||
->where('academic_term_id', $this->input('academic_term_id')),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$invoice = $this->route('tuition_invoice');
|
|
||||||
|
|
||||||
$rules['student_id'] = [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
Rule::exists('students', 'id'),
|
|
||||||
Rule::unique('tuition_invoices', 'student_id')
|
|
||||||
->where('academic_term_id', $this->input('academic_term_id'))
|
|
||||||
->ignore($invoice?->id),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function messages(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'student_ids.*.unique' => 'Salah satu mahasiswa yang dipilih sudah memiliki tagihan untuk periode akademik tersebut.',
|
|
||||||
'student_id.unique' => 'Mahasiswa ini sudah memiliki tagihan untuk periode akademik tersebut.',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Finances;
|
|
||||||
|
|
||||||
use App\Enums\PaymentMethod;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class TuitionPaymentRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-tuition-payments' : 'update-tuition-payments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$invoice = $this->route('tuition_invoice');
|
|
||||||
$payment = $this->route('payment');
|
|
||||||
|
|
||||||
$otherPaidTotal = $invoice->payments()
|
|
||||||
->when($payment, fn ($query) => $query->where('id', '!=', $payment->id))
|
|
||||||
->sum('amount_paid');
|
|
||||||
|
|
||||||
$remaining = max(0, round($invoice->amount_due - $otherPaidTotal, 2));
|
|
||||||
|
|
||||||
return [
|
|
||||||
'amount_paid' => ['required', 'numeric', 'min:0.01', "max:{$remaining}"],
|
|
||||||
'paid_at' => ['required', 'date', 'before_or_equal:now'],
|
|
||||||
'payment_method' => ['required', Rule::enum(PaymentMethod::class)],
|
|
||||||
'notes' => ['nullable', 'string'],
|
|
||||||
'proof' => ['nullable', 'file', 'max:10240', 'mimes:pdf,jpg,jpeg,png'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function messages(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'amount_paid.max' => 'Jumlah dibayar tidak boleh melebihi sisa tagihan.',
|
|
||||||
'paid_at.before_or_equal' => 'Tanggal & waktu bayar tidak boleh melebihi waktu saat ini.',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Manage;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AnnouncementRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-announcements' : 'update-announcements');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'title' => ['required', 'string', 'max:200'],
|
|
||||||
'content' => ['required', 'string'],
|
|
||||||
'department_id' => ['nullable', 'integer', Rule::exists('departments', 'id')],
|
|
||||||
'enrollment_year' => ['nullable', 'integer', 'digits:4'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Manage;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class ClassEnrollmentRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('create-course-class-enrollments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$courseClass = $this->route('course_class');
|
|
||||||
$departmentId = $courseClass->course->department_id;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'student_ids' => ['required', 'array', 'min:1'],
|
|
||||||
'student_ids.*' => [
|
|
||||||
'integer',
|
|
||||||
Rule::exists('students', 'id')->where('department_id', $departmentId),
|
|
||||||
Rule::unique('class_enrollments', 'student_id')->where('course_class_id', $courseClass->id),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Enums\ClassMethod;
|
|
||||||
use App\Models\Course;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class CourseClassRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-course-classes' : 'update-course-classes');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$departmentId = Course::find($this->input('course_id'))?->department_id;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'course_id' => ['required', 'integer', Rule::exists('courses', 'id')],
|
|
||||||
'lecturer_id' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
Rule::exists('lecturer_department', 'lecturer_id')->where('department_id', $departmentId),
|
|
||||||
],
|
|
||||||
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
|
|
||||||
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Manage;
|
|
||||||
|
|
||||||
use App\Services\Admin\Manage\CourseRegistrationService;
|
|
||||||
use App\Services\Admin\Master\AcademicTermService;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class CourseRegistrationRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
if (! $this->routeIs('student.*')) {
|
|
||||||
return $this->user()->can('create-course-registrations');
|
|
||||||
}
|
|
||||||
|
|
||||||
$student = $this->user()->student;
|
|
||||||
|
|
||||||
if (! $student) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$term = app(AcademicTermService::class)->getActive();
|
|
||||||
|
|
||||||
if (! $term) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$service = app(CourseRegistrationService::class);
|
|
||||||
$submission = $service->currentSubmission($student, $term);
|
|
||||||
|
|
||||||
if (! $service->canSubmit($submission)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $service->paymentStatus($student, $term)['is_paid'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
if ($this->routeIs('student.*')) {
|
|
||||||
$student = $this->user()->student;
|
|
||||||
$term = app(AcademicTermService::class)->getActive();
|
|
||||||
$allowedIds = $student && $term
|
|
||||||
? app(CourseRegistrationService::class)->allowedCourseClassIds($student, $term)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
return [
|
|
||||||
'course_class_ids' => ['required', 'array', 'min:1'],
|
|
||||||
'course_class_ids.*' => ['integer', Rule::in($allowedIds)],
|
|
||||||
'signature' => ['required', 'image', 'max:2048'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'student_id' => ['required', 'integer', Rule::exists('students', 'id')],
|
|
||||||
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
|
|
||||||
'course_class_ids' => ['required', 'array', 'min:1'],
|
|
||||||
'course_class_ids.*' => [
|
|
||||||
'integer',
|
|
||||||
Rule::exists('course_classes', 'id'),
|
|
||||||
Rule::unique('course_registrations', 'course_class_id')
|
|
||||||
->where('student_id', $this->input('student_id')),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attributes(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'course_class_ids' => 'mata kuliah',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Manage;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class RejectCourseRegistrationRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('reject-course-registrations');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'reason' => ['required', 'string', 'max:1000'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function messages(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'reason.required' => 'Alasan penolakan wajib diisi.',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Master;
|
|
||||||
|
|
||||||
use App\Enums\Semester;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AcademicTermRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-academic-terms' : 'update-academic-terms');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
function ($attribute, $value, $fail) {
|
|
||||||
if (! preg_match('/^(\d{4})\/(\d{4})$/', $value, $matches)) {
|
|
||||||
$fail('Format name harus YYYY/YYYY, contoh: 2025/2026.');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$startYear = (int) $matches[1];
|
|
||||||
$endYear = (int) $matches[2];
|
|
||||||
|
|
||||||
if ($endYear !== $startYear + 1) {
|
|
||||||
$fail('Tahun kedua harus selisih 1 tahun dari tahun pertama. Contoh: 2025/2026, 2026/2027.');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'semester' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
Rule::in(Semester::values()),
|
|
||||||
Rule::unique('academic_terms')->where(function ($query) {
|
|
||||||
return $query->where('name', $this->input('name'));
|
|
||||||
})->ignore($this->route('academic_term')),
|
|
||||||
],
|
|
||||||
'start_date' => [
|
|
||||||
'required',
|
|
||||||
'date',
|
|
||||||
function ($attribute, $value, $fail) {
|
|
||||||
$name = $this->input('name');
|
|
||||||
$semester = $this->input('semester');
|
|
||||||
if ($name && preg_match('/^(\d{4})\/(\d{4})$/', $name, $matches)) {
|
|
||||||
$startYear = (int) $matches[1];
|
|
||||||
$endYear = (int) $matches[2];
|
|
||||||
$dateYear = (int) date('Y', strtotime($value));
|
|
||||||
$expectedYear = $semester === 'even' ? $endYear : $startYear;
|
|
||||||
if ($dateYear !== $expectedYear) {
|
|
||||||
$fail('Start date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'end_date' => [
|
|
||||||
'required',
|
|
||||||
'date',
|
|
||||||
'after_or_equal:start_date',
|
|
||||||
function ($attribute, $value, $fail) {
|
|
||||||
$name = $this->input('name');
|
|
||||||
$semester = $this->input('semester');
|
|
||||||
if ($name && preg_match('/^(\d{4})\/(\d{4})$/', $name, $matches)) {
|
|
||||||
$startYear = (int) $matches[1];
|
|
||||||
$endYear = (int) $matches[2];
|
|
||||||
$dateYear = (int) date('Y', strtotime($value));
|
|
||||||
$expectedYear = $semester === 'even' ? $endYear : $startYear;
|
|
||||||
if ($dateYear !== $expectedYear) {
|
|
||||||
$fail('End date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'is_active' => ['boolean'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Master;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class CourseRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-courses' : 'update-courses');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'code' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
Rule::unique('courses')->ignore($this->route('course')),
|
|
||||||
],
|
|
||||||
'name' => ['required', 'string', 'max:150'],
|
|
||||||
'credits' => ['required', 'integer', 'min:1', 'max:10'],
|
|
||||||
'department_id' => ['required', 'integer', Rule::exists('departments', 'id')],
|
|
||||||
'semester_number' => ['nullable', 'integer', 'min:1', 'max:14'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Master;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class DepartmentRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-departments' : 'update-departments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'code' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:10',
|
|
||||||
Rule::unique('departments')->ignore($this->route('department')),
|
|
||||||
],
|
|
||||||
'name' => ['required', 'string', 'max:100'],
|
|
||||||
'degree_level' => ['nullable', 'string', Rule::in(['D3', 'D4', 'S1', 'S2', 'S3'])],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Services;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AcademicAdvisingLogRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-academic-advising-logs' : 'update-academic-advising-logs');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'student_ids' => ['required', 'array', 'min:1'],
|
|
||||||
'student_ids.*' => ['integer', Rule::exists('students', 'id')],
|
|
||||||
'lecturer_id' => ['required', 'integer', Rule::exists('lecturers', 'id')],
|
|
||||||
'topic' => ['required', 'string', 'max:150'],
|
|
||||||
'notes' => ['nullable', 'string'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Services\LetterRequest;
|
|
||||||
|
|
||||||
use App\Enums\LetterStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class LetterRequestRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
if ($this->isMethod('post')) {
|
|
||||||
return $this->user()->can('create-letter-requests');
|
|
||||||
}
|
|
||||||
|
|
||||||
$letterRequest = $this->route('letter_request');
|
|
||||||
|
|
||||||
return $this->user()->can('update-letter-requests')
|
|
||||||
&& $letterRequest->user_id === $this->user()->id
|
|
||||||
&& $letterRequest->status === LetterStatus::Submitted->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'letter_type' => ['required', 'string', 'max:100'],
|
|
||||||
'purpose' => ['nullable', 'string'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Services\LetterRequest;
|
|
||||||
|
|
||||||
use App\Enums\LetterStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class LetterRequestStatusRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('update-letter-requests-status');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => ['nullable', 'required_without:result', Rule::enum(LetterStatus::class)],
|
|
||||||
'result' => ['nullable', 'file', 'max:10240', 'mimes:pdf,jpg,jpeg,png,doc,docx'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class UpdateStatusRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
$permission = match ($this->route()?->getName()) {
|
|
||||||
'admin.master.academic-terms.update_status' => 'update-academic-terms-status',
|
|
||||||
'admin.users.lecturers.update_user_status' => 'update-lecturers-status',
|
|
||||||
'admin.users.students.update_user_status' => 'update-students-account-status',
|
|
||||||
'admin.users.administrators.update_user_status' => 'update-administrators-status',
|
|
||||||
default => null,
|
|
||||||
};
|
|
||||||
|
|
||||||
return $permission !== null && $this->user()->can($permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'is_active' => ['required', 'boolean'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Users;
|
|
||||||
|
|
||||||
use App\Enums\Gender;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class AdministratorRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-administrators' : 'update-administrators');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$userId = $this->route('user')?->id;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'username' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
'min:5',
|
|
||||||
'alpha_dash',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
'email' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'email',
|
|
||||||
'max:255',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
'role' => ['required', 'string', Rule::in(['staff-admin', 'staff-keuangan'])],
|
|
||||||
|
|
||||||
// Profile
|
|
||||||
'full_name' => ['required', 'string', 'max:150'],
|
|
||||||
'phone_number' => ['required', 'string', 'max:20'],
|
|
||||||
'address' => ['required', 'string'],
|
|
||||||
'gender' => ['required', 'string', Rule::in(Gender::values())],
|
|
||||||
'birth_date' => ['required', 'date'],
|
|
||||||
'birth_place' => ['required', 'string', 'max:100'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Users;
|
|
||||||
|
|
||||||
use App\Enums\Gender;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class LecturerRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-lecturers' : 'update-lecturers');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$userId = $this->route('user')?->id;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'username' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
'min:5',
|
|
||||||
'alpha_dash',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
'email' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'email',
|
|
||||||
'max:255',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
|
|
||||||
// Profile
|
|
||||||
'full_name' => ['required', 'string', 'max:150'],
|
|
||||||
'phone_number' => ['required', 'string', 'max:20'],
|
|
||||||
'address' => ['required', 'string'],
|
|
||||||
'gender' => ['required', 'string', Rule::in(Gender::values())],
|
|
||||||
'birth_date' => ['required', 'date'],
|
|
||||||
'birth_place' => ['required', 'string', 'max:100'],
|
|
||||||
|
|
||||||
// Lecturer fields
|
|
||||||
'lecturer_number' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
Rule::unique('lecturers')->ignore($userId, 'user_id'),
|
|
||||||
],
|
|
||||||
'department_ids' => ['required', 'array', 'min:1'],
|
|
||||||
'department_ids.*' => ['integer', Rule::exists('departments', 'id')],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Users\Student;
|
|
||||||
|
|
||||||
use App\Enums\Gender;
|
|
||||||
use App\Enums\StudentStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class StudentRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can($this->isMethod('post') ? 'create-students' : 'update-students');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$userId = $this->route('user')?->id;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'username' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:20',
|
|
||||||
'min:5',
|
|
||||||
'alpha_dash',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
'email' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'email',
|
|
||||||
'max:255',
|
|
||||||
$userId === null
|
|
||||||
? Rule::unique('users')
|
|
||||||
: Rule::unique('users')->ignore($userId),
|
|
||||||
],
|
|
||||||
|
|
||||||
// Profile
|
|
||||||
'full_name' => ['required', 'string', 'max:150'],
|
|
||||||
'phone_number' => ['required', 'string', 'max:20'],
|
|
||||||
'address' => ['required', 'string'],
|
|
||||||
'gender' => ['required', 'string', Rule::in(Gender::values())],
|
|
||||||
'birth_date' => ['required', 'date'],
|
|
||||||
'birth_place' => ['required', 'string', 'max:100'],
|
|
||||||
|
|
||||||
// Student fields
|
|
||||||
'student_number' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'max:10',
|
|
||||||
Rule::unique('students')->ignore($userId, 'user_id'),
|
|
||||||
],
|
|
||||||
'department_id' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
Rule::exists('departments', 'id'),
|
|
||||||
],
|
|
||||||
'enrollment_year' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
'digits:4',
|
|
||||||
],
|
|
||||||
'current_semester' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
'min:1',
|
|
||||||
'max:14',
|
|
||||||
],
|
|
||||||
'academic_advisor_id' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
Rule::exists('lecturers', 'id'),
|
|
||||||
],
|
|
||||||
'status' => [
|
|
||||||
'nullable',
|
|
||||||
'string',
|
|
||||||
Rule::in(StudentStatus::values()),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Users\Student;
|
|
||||||
|
|
||||||
use App\Enums\StudentStatus;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class StudentStatusRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return $this->user()->can('update-students-academic-status');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => ['required', 'string', Rule::in(StudentStatus::values())],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class MediaUploadRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'file' => ['required', 'image', 'max:10240', 'mimes:jpg,jpeg,png,gif,webp'],
|
|
||||||
'collection' => ['nullable', 'string', 'max:50'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests;
|
|
||||||
|
|
||||||
use App\Enums\ClassMethod;
|
|
||||||
use App\Enums\Gender;
|
|
||||||
use App\Enums\PaymentMethod;
|
|
||||||
use App\Enums\Semester;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class PaginatedRequest extends FormRequest
|
|
||||||
{
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'per_page' => ['nullable', 'integer', 'in:25,50,100,999999'],
|
|
||||||
'search' => ['nullable', 'string', 'max:255'],
|
|
||||||
'highlight' => ['nullable', 'integer'],
|
|
||||||
'gender' => ['nullable', 'string', Rule::in(Gender::values())],
|
|
||||||
'department_id' => ['nullable', 'integer'],
|
|
||||||
'status' => ['nullable', 'string'],
|
|
||||||
'enrollment_year' => ['nullable', 'integer'],
|
|
||||||
'semester_number' => ['nullable', 'integer'],
|
|
||||||
'semester' => ['nullable', 'string', Rule::in(Semester::values())],
|
|
||||||
'is_active' => ['nullable', Rule::in(['true', 'false'])],
|
|
||||||
'academic_term_id' => ['nullable', 'integer'],
|
|
||||||
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())],
|
|
||||||
'course_class_id' => ['nullable', 'integer'],
|
|
||||||
'lecturer_id' => ['nullable', 'integer'],
|
|
||||||
'type' => ['nullable', 'string'],
|
|
||||||
'payment_method' => ['nullable', 'string', Rule::in(PaymentMethod::values())],
|
|
||||||
'file' => ['nullable', 'string'],
|
|
||||||
'level' => ['nullable', 'string'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validatedWithDefaults(): array
|
|
||||||
{
|
|
||||||
$validated = $this->validated();
|
|
||||||
|
|
||||||
return [
|
|
||||||
'perPage' => $validated['per_page'] ?? 25,
|
|
||||||
'search' => $validated['search'] ?? '',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Settings;
|
namespace App\Http\Requests\Settings;
|
||||||
|
|
||||||
use App\Concerns\PasswordValidationRules;
|
use App\Concerns\PasswordValidationRules;
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Settings;
|
namespace App\Http\Requests\Settings;
|
||||||
|
|
||||||
use App\Concerns\PasswordValidationRules;
|
use App\Concerns\PasswordValidationRules;
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Settings;
|
namespace App\Http\Requests\Settings;
|
||||||
|
|
||||||
use App\Concerns\ProfileValidationRules;
|
use App\Concerns\ProfileValidationRules;
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Settings;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Laravel\Fortify\InteractsWithTwoFactorState;
|
||||||
|
|
||||||
|
class TwoFactorAuthenticationRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use InteractsWithTwoFactorState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class AcademicAdvisingLog extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public function students(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Student::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lecturer(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Lecturer::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\Semester;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['formatted_start_date', 'formatted_end_date'])]
|
|
||||||
class AcademicTerm extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public function tuitionInvoices(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(TuitionInvoice::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'semester' => Semester::class,
|
|
||||||
'start_date' => 'date',
|
|
||||||
'end_date' => 'date',
|
|
||||||
'is_active' => 'boolean',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formattedStartDate(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->start_date->format('d M Y'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formattedEndDate(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->end_date->format('d M Y'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Announcement extends Model
|
|
||||||
{
|
|
||||||
use HasFactory, SoftDeletes;
|
|
||||||
|
|
||||||
public function department(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Department::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function creator(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'created_by');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['attachment_url', 'attachment_name'])]
|
|
||||||
class Assignment extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use HasFactory, InteractsWithMedia, SoftDeletes;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'deadline' => 'datetime',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerMediaCollections(): void
|
|
||||||
{
|
|
||||||
$this->addMediaCollection('assignment_attachment')->singleFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseClass(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseClass::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function submissions(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Submission::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function attachmentUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('assignment_attachment') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function attachmentName(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMedia('assignment_attachment')?->file_name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\AttendanceStatus;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Attendance extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'date' => 'date',
|
|
||||||
'status' => AttendanceStatus::class,
|
|
||||||
'recorded_at' => 'datetime',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseClass(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseClass::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Student::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class ClassEnrollment extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'enrolled_at' => 'datetime',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseClass(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseClass::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Student::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Course extends Model
|
|
||||||
{
|
|
||||||
use HasFactory, SoftDeletes;
|
|
||||||
|
|
||||||
public function department(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Department::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function classes(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(CourseClass::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\ClassMethod;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class CourseClass extends Model
|
|
||||||
{
|
|
||||||
use HasFactory, SoftDeletes;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'method' => ClassMethod::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function course(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Course::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lecturer(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Lecturer::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function academicTerm(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(AcademicTerm::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enrollments(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(ClassEnrollment::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function materials(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Material::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function assignments(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Assignment::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function schedules(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Schedule::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attendances(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Attendance::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registrations(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(CourseRegistration::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class CourseRegistration extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public function student(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Student::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function academicTerm(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(AcademicTerm::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseClass(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseClass::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function submission(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\RegistrationStatus;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['signature_url'])]
|
|
||||||
class CourseRegistrationSubmission extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use InteractsWithMedia;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => RegistrationStatus::class,
|
|
||||||
'signed_at' => 'datetime',
|
|
||||||
'reviewed_at' => 'datetime',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerMediaCollections(): void
|
|
||||||
{
|
|
||||||
$this->addMediaCollection('signature')->singleFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Student::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function academicTerm(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(AcademicTerm::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reviewer(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'reviewed_by');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseRegistrations(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(CourseRegistration::class, 'submission_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logs(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(CourseRegistrationSubmissionLog::class, 'submission_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function signatureUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('signature') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\RegistrationStatus;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class CourseRegistrationSubmissionLog extends Model
|
|
||||||
{
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => RegistrationStatus::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function submission(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actor(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'actor_id');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Department extends Model
|
|
||||||
{
|
|
||||||
use HasFactory, SoftDeletes;
|
|
||||||
|
|
||||||
public function lecturers(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Lecturer::class, 'lecturer_department');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function students(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Student::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function leaderships(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(DepartmentLeadership::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function currentLeader(): HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(DepartmentLeadership::class)->whereNull('ended_at');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class DepartmentLeadership extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'started_at' => 'date',
|
|
||||||
'ended_at' => 'date',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function department(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Department::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lecturer(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Lecturer::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class EditorUpload extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use InteractsWithMedia;
|
|
||||||
|
|
||||||
public function uploader(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'uploaded_by');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\FeedbackStatus;
|
|
||||||
use App\Enums\FeedbackType;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Feedback extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected $table = 'feedbacks';
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'type' => FeedbackType::class,
|
|
||||||
'status' => FeedbackStatus::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function user(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handler(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'handled_by');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
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\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Lecturer extends Model
|
|
||||||
{
|
|
||||||
use HasFactory, SoftDeletes;
|
|
||||||
|
|
||||||
public function user(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function departments(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Department::class, 'lecturer_department');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function advisees(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Student::class, 'academic_advisor_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function leaderships(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(DepartmentLeadership::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function academicAdvisingLogs(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(AcademicAdvisingLog::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\LetterStatus;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['result_url', 'result_name'])]
|
|
||||||
class LetterRequest extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use HasFactory, InteractsWithMedia;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'status' => LetterStatus::class,
|
|
||||||
'submitted_at' => 'datetime',
|
|
||||||
'completed_at' => 'datetime',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerMediaCollections(): void
|
|
||||||
{
|
|
||||||
$this->addMediaCollection('letter_result')->singleFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function user(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processor(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'processed_by');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function resultUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('letter_result') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function resultName(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMedia('letter_result')?->file_name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class Mahasiswa extends Model
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['file_url', 'file_name'])]
|
|
||||||
class Material extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use HasFactory, InteractsWithMedia, SoftDeletes;
|
|
||||||
|
|
||||||
public function registerMediaCollections(): void
|
|
||||||
{
|
|
||||||
$this->addMediaCollection('materials')->singleFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function courseClass(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(CourseClass::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function fileUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('materials') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function fileName(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMedia('materials')?->file_name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
class Notification extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'is_read' => 'boolean',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function user(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function creator(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(User::class, 'created_by');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user