add report student
This commit is contained in:
parent
edf02bc09a
commit
dee2805504
223
app/Filament/Pages/StudentReport.php
Normal file
223
app/Filament/Pages/StudentReport.php
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\Assessment;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\ClassSubject;
|
||||||
|
use App\Models\Student;
|
||||||
|
use App\Models\Subject;
|
||||||
|
use App\Models\TeacherSubject;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
|
||||||
|
class StudentReport extends Page
|
||||||
|
{
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static string $view = 'filament.pages.student-report';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Academic Management';
|
||||||
|
|
||||||
|
public $class_id;
|
||||||
|
public $academic_year;
|
||||||
|
public $semester;
|
||||||
|
public ?array $data;
|
||||||
|
|
||||||
|
public $list;
|
||||||
|
|
||||||
|
public static function canAccess(): bool
|
||||||
|
{
|
||||||
|
return auth()->user()->hasAnyRole(['super_admin']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function shouldRegisterNavigation(): bool
|
||||||
|
{
|
||||||
|
return auth()->user()->hasAnyRole(['super_admin']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->class = null;
|
||||||
|
$this->academicYear = null;
|
||||||
|
$this->semester = null;
|
||||||
|
$this->data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form->schema([
|
||||||
|
Select::make('class_id')
|
||||||
|
->label('Class')
|
||||||
|
->required()
|
||||||
|
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->reactive()
|
||||||
|
->afterStateUpdated(function ($state) {
|
||||||
|
$this->class_id = $state;
|
||||||
|
$this->data['class_id'] = $state; // Update data array
|
||||||
|
$this->loadData();
|
||||||
|
}),
|
||||||
|
|
||||||
|
Select::make('academic_year')
|
||||||
|
->label('Academic Year')
|
||||||
|
->required()
|
||||||
|
->options(AcademicYear::pluck('name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->reactive()
|
||||||
|
->afterStateUpdated(function ($state) {
|
||||||
|
$this->academic_year = $state;
|
||||||
|
$this->data['academic_year'] = $state; // Update data array
|
||||||
|
$this->loadData();
|
||||||
|
}),
|
||||||
|
|
||||||
|
Select::make('semester')
|
||||||
|
->label('Semester')
|
||||||
|
->required()
|
||||||
|
->options([
|
||||||
|
'first' => 'First Semester',
|
||||||
|
'second' => 'Second Semester'
|
||||||
|
])
|
||||||
|
->reactive()
|
||||||
|
->afterStateUpdated(function ($state) {
|
||||||
|
$this->semester = $state;
|
||||||
|
$this->data['semester'] = $state;
|
||||||
|
$this->loadData();
|
||||||
|
}),
|
||||||
|
])->columns(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadData(): void
|
||||||
|
{
|
||||||
|
if (count($this->data) < 3) {
|
||||||
|
$this->list = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedAssessment = [];
|
||||||
|
|
||||||
|
$assessments = Assessment::where('semester', $this->semester)
|
||||||
|
->whereHas('teacherSubject', function($query) {
|
||||||
|
$query->where('academic_year_id', $this->academic_year)
|
||||||
|
->where('class_id', $this->class_id);
|
||||||
|
})
|
||||||
|
->with('teacherSubject', 'student')
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$classSubjects = ClassSubject::with(['subject', 'class', 'academicYear'])
|
||||||
|
->where('class_room_id', $this->class_id)
|
||||||
|
->where('academic_year_id', $this->academic_year)
|
||||||
|
->get()
|
||||||
|
->sortByDesc(function ($item) {
|
||||||
|
return $item->subject->name;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$header = [];
|
||||||
|
|
||||||
|
foreach ($classSubjects as $classSubject) {
|
||||||
|
$category = strtolower($classSubject['subject']['category']);
|
||||||
|
$subjectName = $classSubject['subject']['name'];
|
||||||
|
$subjectId = $classSubject['subject']['id'];
|
||||||
|
$header[$category][$subjectId] = $subjectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$students = ClassStudent::with(['class', 'academicYear', 'student'])
|
||||||
|
->where('class_room_id', $this->class_id)
|
||||||
|
->where('academic_year_id', $this->academic_year)
|
||||||
|
->get()
|
||||||
|
->map(function($student) {
|
||||||
|
return $student['student'];
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$finals = [];
|
||||||
|
foreach ($students as $student) {
|
||||||
|
$studentData = [
|
||||||
|
'student_id' => $student['id'],
|
||||||
|
'name' => $student['full_name'],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($header as $category => $subjects) {
|
||||||
|
foreach ($subjects as $subjectId => $subjectName) {
|
||||||
|
$matchingAssessment = collect($assessments)->first(function ($a) use ($student, $subjectId) {
|
||||||
|
return $a['student_id'] == $student['id'] && $a['teacher_subject']['subject_id'] == $subjectId;
|
||||||
|
});
|
||||||
|
|
||||||
|
$studentData[$category][$subjectId] = $matchingAssessment['score'] ?? '-'; // atau null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$finals[] = $studentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($finals as $final => $fnl) {
|
||||||
|
$existStudent = Student::where('id', $fnl['student_id'])->firstOrFail();
|
||||||
|
|
||||||
|
$studentData = [
|
||||||
|
'name' => $fnl['name'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$mapel = $fnl['umum'] ?? null;
|
||||||
|
|
||||||
|
if ($mapel) {
|
||||||
|
foreach ($mapel as $key => $value) {
|
||||||
|
$existSubject = Subject::where('id', $key)->firstOrFail();
|
||||||
|
|
||||||
|
if ($existSubject->is_religious) {
|
||||||
|
$studentReligion = strtolower($existStudent->religion); // contoh: "islam"
|
||||||
|
$subjectName = strtolower($existSubject->name); // contoh: "pendidikan agama islam"
|
||||||
|
|
||||||
|
if (str_contains($subjectName, $studentReligion)) {
|
||||||
|
// Hanya mapel agama yang sesuai dengan agama siswa dimasukkan ke umum[0]
|
||||||
|
$studentData['umum'][0] = $value;
|
||||||
|
}
|
||||||
|
// Mapel agama lain tidak dimasukkan sama sekali
|
||||||
|
} else {
|
||||||
|
$studentData['umum'][$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$studentData['muatan lokal'] = $fnl['muatan lokal'] ?? null;
|
||||||
|
|
||||||
|
$result[] = $studentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedAssessment["data"] = $result;
|
||||||
|
|
||||||
|
$groupedSubjectsHeader = [];
|
||||||
|
|
||||||
|
$groupedSubjectsHeader['name'] = "Nama";
|
||||||
|
|
||||||
|
$religionAdded = false;
|
||||||
|
|
||||||
|
foreach ($classSubjects as $classSubject) {
|
||||||
|
$category = strtolower($classSubject['subject']['category']);
|
||||||
|
$subjectName = $classSubject['subject']['name'];
|
||||||
|
$isReligion = $classSubject['subject']['is_religious'];
|
||||||
|
$subjectId = $classSubject['subject']['id'];
|
||||||
|
|
||||||
|
if ($isReligion) {
|
||||||
|
if (!$religionAdded) {
|
||||||
|
$groupedSubjectsHeader['umum'][0] = 'Pendidikan Agama';
|
||||||
|
$religionAdded = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedSubjectsHeader[$category][$subjectId] = $subjectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedAssessment["header"] = $groupedSubjectsHeader;
|
||||||
|
|
||||||
|
$this->list = $groupedAssessment;
|
||||||
|
}
|
||||||
|
}
|
||||||
105
app/Filament/Resources/AcademicYearResource.php
Normal file
105
app/Filament/Resources/AcademicYearResource.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\AcademicYearResource\Pages;
|
||||||
|
use App\Filament\Resources\AcademicYearResource\RelationManagers;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class AcademicYearResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = AcademicYear::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Forms\Components\TextInput::make('name')
|
||||||
|
->required()
|
||||||
|
->placeholder("ex: 2024/2025")
|
||||||
|
->maxLength(255),
|
||||||
|
Forms\Components\Toggle::make('is_active')
|
||||||
|
->required(),
|
||||||
|
Forms\Components\DatePicker::make('start_date'),
|
||||||
|
Forms\Components\DatePicker::make('end_date'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
Tables\Columns\TextColumn::make('name')
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\IconColumn::make('is_active')
|
||||||
|
->boolean(),
|
||||||
|
Tables\Columns\TextColumn::make('start_date')
|
||||||
|
->date()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('end_date')
|
||||||
|
->date()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('updated_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('deleted_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
Tables\Filters\TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
Tables\Actions\ForceDeleteBulkAction::make(),
|
||||||
|
Tables\Actions\RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListAcademicYears::route('/'),
|
||||||
|
'create' => Pages\CreateAcademicYear::route('/create'),
|
||||||
|
'edit' => Pages\EditAcademicYear::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\AcademicYearResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\AcademicYearResource;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateAcademicYear extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = AcademicYearResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$exists = AcademicYear::where('name', $data['name'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\AcademicYearResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\AcademicYearResource;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditAcademicYear extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = AcademicYearResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
$exists = AcademicYear::where('name', $data['name'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
Actions\ForceDeleteAction::make(),
|
||||||
|
Actions\RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\AcademicYearResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\AcademicYearResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListAcademicYears extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = AcademicYearResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ use App\Filament\Resources\AssessmentResource\Pages;
|
|||||||
use App\Filament\Resources\AssessmentResource\RelationManagers;
|
use App\Filament\Resources\AssessmentResource\RelationManagers;
|
||||||
use App\Models\Assessment;
|
use App\Models\Assessment;
|
||||||
use App\Models\AssessmentComponent;
|
use App\Models\AssessmentComponent;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
@ -33,15 +34,14 @@ class AssessmentResource extends Resource
|
|||||||
->required()
|
->required()
|
||||||
->relationship('teacherSubject', 'id')
|
->relationship('teacherSubject', 'id')
|
||||||
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
||||||
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academic_year)
|
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academicYear->name)
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->preload()
|
||||||
->afterStateUpdated(function (callable $set, $state) {
|
->afterStateUpdated(function (callable $set, $state) {
|
||||||
// Filter siswa berdasarkan kelas yang dipilih dalam teacher_subject_id
|
|
||||||
if ($state) {
|
if ($state) {
|
||||||
$teacherSubject = TeacherSubject::find($state);
|
$teacherSubject = TeacherSubject::find($state);
|
||||||
if ($teacherSubject) {
|
if ($teacherSubject) {
|
||||||
$set('student_id', null); // Reset student_id jika teacher_subject_id berubah
|
$set('student_id', null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -51,14 +51,15 @@ class AssessmentResource extends Resource
|
|||||||
->label('Student')
|
->label('Student')
|
||||||
->required()
|
->required()
|
||||||
->searchable()
|
->searchable()
|
||||||
// Filter opsi siswa berdasarkan kelas yang terkait dengan teacher_subject_id
|
|
||||||
->options(function ($get) {
|
->options(function ($get) {
|
||||||
$teacherSubjectId = $get('teacher_subject_id');
|
$teacherSubjectId = $get('teacher_subject_id');
|
||||||
if ($teacherSubjectId) {
|
if ($teacherSubjectId) {
|
||||||
$teacherSubject = TeacherSubject::find($teacherSubjectId);
|
$teacherSubject = TeacherSubject::find($teacherSubjectId);
|
||||||
// Ambil siswa yang memiliki kelas yang sesuai dengan teacher_subject_id
|
$students = ClassStudent::where('class_room_id', $teacherSubject->class_id)
|
||||||
$students = Student::where('class_id', $teacherSubject->class_id)
|
->where('academic_year_id', $teacherSubject->academic_year_id)
|
||||||
->pluck('full_name', 'id')
|
->with('student')
|
||||||
|
->get()
|
||||||
|
->pluck('student.full_name', 'id')
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
return $students;
|
return $students;
|
||||||
@ -68,8 +69,15 @@ class AssessmentResource extends Resource
|
|||||||
->getOptionLabelUsing(function ($value) {
|
->getOptionLabelUsing(function ($value) {
|
||||||
$student = Student::find($value);
|
$student = Student::find($value);
|
||||||
return $student ? $student->full_name . ' (' . $student->nis . ')' : null;
|
return $student ? $student->full_name . ' (' . $student->nis . ')' : null;
|
||||||
})
|
}),
|
||||||
->required(),
|
|
||||||
|
Forms\Components\Select::make('semester')
|
||||||
|
->label('Semester')
|
||||||
|
->required()
|
||||||
|
->options([
|
||||||
|
'first' => 'First Semester',
|
||||||
|
'second' => 'Second Semester'
|
||||||
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('score')
|
Forms\Components\TextInput::make('score')
|
||||||
->label('Score')
|
->label('Score')
|
||||||
@ -122,6 +130,9 @@ class AssessmentResource extends Resource
|
|||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class ListAssessments extends ListRecords
|
|||||||
return [
|
return [
|
||||||
Actions\CreateAction::make(),
|
Actions\CreateAction::make(),
|
||||||
Actions\Action::make('multiple')
|
Actions\Action::make('multiple')
|
||||||
->label('Multiple Attendance')
|
->label('Multiple Assessments')
|
||||||
->url('assessments/multiple')
|
->url('assessments/multiple')
|
||||||
->icon('heroicon-o-user-group'),
|
->icon('heroicon-o-user-group'),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -5,13 +5,16 @@ namespace App\Filament\Resources\AssessmentResource\Pages;
|
|||||||
use App\Filament\Resources\AssessmentResource;
|
use App\Filament\Resources\AssessmentResource;
|
||||||
use App\Models\Assessment;
|
use App\Models\Assessment;
|
||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Resources\Pages\page;
|
use Filament\Resources\Pages\page;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use function Symfony\Component\Translation\t;
|
||||||
|
|
||||||
class MultipleAssessments extends page
|
class MultipleAssessments extends page
|
||||||
{
|
{
|
||||||
@ -21,10 +24,15 @@ class MultipleAssessments extends page
|
|||||||
|
|
||||||
use Forms\Concerns\InteractsWithForms;
|
use Forms\Concerns\InteractsWithForms;
|
||||||
|
|
||||||
|
public ?array $data = [];
|
||||||
public ?int $teacherSubjectId = null;
|
public ?int $teacherSubjectId = null;
|
||||||
|
|
||||||
|
public $teacherSubject;
|
||||||
|
|
||||||
public array $students = [];
|
public array $students = [];
|
||||||
|
|
||||||
|
public $semester = 'first';
|
||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
{
|
{
|
||||||
$this->form->fill();
|
$this->form->fill();
|
||||||
@ -33,18 +41,38 @@ class MultipleAssessments extends page
|
|||||||
protected function getFormSchema(): array
|
protected function getFormSchema(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
Forms\Components\Grid::make(2)
|
||||||
|
->schema([
|
||||||
Forms\Components\Select::make('teacherSubjectId')
|
Forms\Components\Select::make('teacherSubjectId')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->options(
|
->options(
|
||||||
TeacherSubject::with(['teacher', 'subject', 'class'])->get()->mapWithKeys(function ($item) {
|
TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear'])->get()->mapWithKeys(function ($item) {
|
||||||
return [
|
return [
|
||||||
$item->id => "{$item->teacher->name} - {$item->subject->name} - {$item->class->class_name}"
|
$item->id => "{$item->teacher->name} - {$item->subject->name} - {$item->class->class_name} - {$item->academicYear->name}"
|
||||||
];
|
];
|
||||||
})->toArray()
|
})->toArray()
|
||||||
)
|
)
|
||||||
->searchable()
|
->searchable()
|
||||||
->reactive()
|
->reactive()
|
||||||
->afterStateUpdated(fn ($state) => $this->loadStudents()),
|
->afterStateUpdated(function ($state) {
|
||||||
|
$this->teacherSubjectId = $state;
|
||||||
|
$this->loadStudents();
|
||||||
|
}),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('semester')
|
||||||
|
->label('Semester')
|
||||||
|
->required()
|
||||||
|
->default('first')
|
||||||
|
->options([
|
||||||
|
'first' => 'First Semester',
|
||||||
|
'second' => 'Second Semester'
|
||||||
|
])
|
||||||
|
->live()
|
||||||
|
->afterStateUpdated(function ($state) {
|
||||||
|
$this->semester = $state;
|
||||||
|
$this->loadStudents();
|
||||||
|
}),
|
||||||
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,34 +83,47 @@ class MultipleAssessments extends page
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$teacherSubject = TeacherSubject::find($this->teacherSubjectId);
|
$this->teacherSubject = TeacherSubject::with(['subject','class','academicYear','teacher'])
|
||||||
|
->where('id', $this->teacherSubjectId)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
if (!$teacherSubject) {
|
$classStudents = ClassStudent::where('class_room_id', $this->teacherSubject->class_id)
|
||||||
$this->students = [];
|
->where('academic_year_id', $this->teacherSubject->academic_year_id)
|
||||||
|
->with('student')
|
||||||
|
->get();
|
||||||
|
|
||||||
Notification::make()
|
$isSubjectReligion = $this->teacherSubject->subject->is_religious;
|
||||||
->title('Not Found')
|
$subjectName = strtolower($this->teacherSubject->subject->name);
|
||||||
->body('Selected teacher subject not found.')
|
|
||||||
->danger()
|
|
||||||
->send();
|
|
||||||
|
|
||||||
return;
|
$result = [];
|
||||||
}
|
|
||||||
|
foreach ($classStudents as $classStudent) {
|
||||||
|
$student = $classStudent->student;
|
||||||
|
|
||||||
|
if (!$student) continue; // Jaga-jaga kalau relasi student-nya null
|
||||||
|
|
||||||
$this->students = Student::where('class_id', $teacherSubject->class_id)
|
|
||||||
->get()
|
|
||||||
->map(function ($student) {
|
|
||||||
$existingAssessment = Assessment::where('student_id', $student->id)
|
$existingAssessment = Assessment::where('student_id', $student->id)
|
||||||
->where('teacher_subject_id', $this->teacherSubjectId)
|
->where('teacher_subject_id', $this->teacherSubjectId)
|
||||||
|
->where('semester', $this->semester)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
return [
|
if ($isSubjectReligion) {
|
||||||
|
$studentReligion = strtolower($student->religion);
|
||||||
|
|
||||||
|
if (!str_contains($subjectName, $studentReligion)) {
|
||||||
|
continue; // Skip kalau agama tidak cocok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = [
|
||||||
'id' => $student->id,
|
'id' => $student->id,
|
||||||
'name' => $student->full_name,
|
'name' => $student->full_name,
|
||||||
'nis' => $student->nis,
|
'nis' => $student->nis,
|
||||||
'score' => $existingAssessment ? $existingAssessment->score : null,
|
'score' => $existingAssessment ? $existingAssessment->score : null,
|
||||||
];
|
];
|
||||||
})->toArray();
|
}
|
||||||
|
|
||||||
|
$this->students = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function submit(): void
|
public function submit(): void
|
||||||
@ -106,6 +147,7 @@ class MultipleAssessments extends page
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'score' => $student['score'],
|
'score' => $student['score'],
|
||||||
|
'semester' => $this->semester,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
|||||||
use App\Filament\Resources\AttendancesResource\Pages;
|
use App\Filament\Resources\AttendancesResource\Pages;
|
||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
@ -26,22 +27,21 @@ class AttendancesResource extends Resource
|
|||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Section::make('Informasi Absensi')
|
Forms\Components\Section::make('Data Absensi')
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Select::make('teacher_subject_id')
|
Forms\Components\Select::make('teacher_subject_id')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->required()
|
->required()
|
||||||
->relationship('teacherSubject', 'id')
|
->relationship('teacherSubject', 'id')
|
||||||
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
||||||
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academic_year)
|
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academicYear->name)
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->preload()
|
||||||
->afterStateUpdated(function (callable $set, $state) {
|
->afterStateUpdated(function (callable $set, $state) {
|
||||||
// Filter siswa berdasarkan kelas yang dipilih dalam teacher_subject_id
|
|
||||||
if ($state) {
|
if ($state) {
|
||||||
$teacherSubject = TeacherSubject::find($state);
|
$teacherSubject = TeacherSubject::find($state);
|
||||||
if ($teacherSubject) {
|
if ($teacherSubject) {
|
||||||
$set('student_id', null); // Reset student_id jika teacher_subject_id berubah
|
$set('student_id', null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -51,20 +51,21 @@ class AttendancesResource extends Resource
|
|||||||
->label('Date')
|
->label('Date')
|
||||||
->required()
|
->required()
|
||||||
->default(now())
|
->default(now())
|
||||||
->maxDate(now()),
|
->live(),
|
||||||
|
|
||||||
Forms\Components\Select::make('student_id')
|
Forms\Components\Select::make('student_id')
|
||||||
->label('Student')
|
->label('Student')
|
||||||
->required()
|
->required()
|
||||||
->searchable()
|
->searchable()
|
||||||
// Filter opsi siswa berdasarkan kelas yang terkait dengan teacher_subject_id
|
|
||||||
->options(function ($get) {
|
->options(function ($get) {
|
||||||
$teacherSubjectId = $get('teacher_subject_id');
|
$teacherSubjectId = $get('teacher_subject_id');
|
||||||
if ($teacherSubjectId) {
|
if ($teacherSubjectId) {
|
||||||
$teacherSubject = TeacherSubject::find($teacherSubjectId);
|
$teacherSubject = TeacherSubject::find($teacherSubjectId);
|
||||||
// Ambil siswa yang memiliki kelas yang sesuai dengan teacher_subject_id
|
$students = ClassStudent::where('class_room_id', $teacherSubject->class_id)
|
||||||
$students = Student::where('class_id', $teacherSubject->class_id)
|
->where('academic_year_id', $teacherSubject->academic_year_id)
|
||||||
->pluck('full_name', 'id')
|
->with('student')
|
||||||
|
->get()
|
||||||
|
->pluck('student.full_name', 'id')
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
return $students;
|
return $students;
|
||||||
@ -153,7 +154,7 @@ class AttendancesResource extends Resource
|
|||||||
'second' => 'Second Semester'
|
'second' => 'Second Semester'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('teacherSubject.academic_year')
|
Tables\Columns\TextColumn::make('teacherSubject.academicYear.name')
|
||||||
->label('Academic Year')
|
->label('Academic Year')
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,36 @@
|
|||||||
namespace App\Filament\Resources\AttendancesResource\Pages;
|
namespace App\Filament\Resources\AttendancesResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\AttendancesResource;
|
use App\Filament\Resources\AttendancesResource;
|
||||||
|
use App\Models\Assessment;
|
||||||
|
use App\Models\Attendances;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Pages\EditRecord;
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
class EditAttendances extends EditRecord
|
class EditAttendances extends EditRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = AttendancesResource::class;
|
protected static string $resource = AttendancesResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
$exists = Attendances::where('teacher_subject_id', $data['teacher_subject_id'])
|
||||||
|
->where('student_id', $data['student_id'])
|
||||||
|
->where('id', '!=', $this->record->id) // ignore current record
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('An assessment for this teacher, subject, and student combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@ -3,8 +3,10 @@
|
|||||||
namespace App\Filament\Resources\AttendancesResource\Pages;
|
namespace App\Filament\Resources\AttendancesResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\AttendancesResource;
|
use App\Filament\Resources\AttendancesResource;
|
||||||
|
use App\Models\Assessment;
|
||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
@ -26,7 +28,8 @@ class MultipleAttendances extends Page
|
|||||||
|
|
||||||
public $teacherSubject;
|
public $teacherSubject;
|
||||||
public $attendanceDate;
|
public $attendanceDate;
|
||||||
public $semester = 'first'; // Default semester
|
public $semester = 'first';
|
||||||
|
|
||||||
public $students = [];
|
public $students = [];
|
||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
@ -48,7 +51,7 @@ class MultipleAttendances extends Page
|
|||||||
->options(TeacherSubject::with(['teacher', 'subject', 'class'])
|
->options(TeacherSubject::with(['teacher', 'subject', 'class'])
|
||||||
->get()
|
->get()
|
||||||
->mapWithKeys(fn ($item) => [
|
->mapWithKeys(fn ($item) => [
|
||||||
$item->id => $item->teacher->name . ' - ' . $item->subject->name . ' - ' . $item->class->class_name
|
$item->id => $item->teacher->name . ' - ' . $item->subject->name . ' - ' . $item->class->class_name . ' - ' . $item->academicYear->name
|
||||||
]))
|
]))
|
||||||
->searchable()
|
->searchable()
|
||||||
->live()
|
->live()
|
||||||
@ -61,7 +64,6 @@ class MultipleAttendances extends Page
|
|||||||
->label('Attendance Date')
|
->label('Attendance Date')
|
||||||
->required()
|
->required()
|
||||||
->default(now())
|
->default(now())
|
||||||
->maxDate(now())
|
|
||||||
->live()
|
->live()
|
||||||
->afterStateUpdated(function ($state) {
|
->afterStateUpdated(function ($state) {
|
||||||
$this->attendanceDate = $state;
|
$this->attendanceDate = $state;
|
||||||
@ -81,7 +83,8 @@ class MultipleAttendances extends Page
|
|||||||
$this->loadStudents();
|
$this->loadStudents();
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
->statePath('data');
|
->statePath('data')
|
||||||
|
->columns(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadStudents(): void
|
protected function loadStudents(): void
|
||||||
@ -93,25 +96,67 @@ class MultipleAttendances extends Page
|
|||||||
|
|
||||||
$this->teacherSubject = TeacherSubject::where('id', $this->teacherSubjectId)->firstOrFail();
|
$this->teacherSubject = TeacherSubject::where('id', $this->teacherSubjectId)->firstOrFail();
|
||||||
|
|
||||||
$this->students = Student::where('class_id', $this->teacherSubject->class_id)
|
$classStudents = ClassStudent::where('class_room_id', $this->teacherSubject->class_id)
|
||||||
->orderBy('full_name')
|
->where('academic_year_id', $this->teacherSubject->academic_year_id)
|
||||||
->get()
|
->with('student')
|
||||||
->map(function ($student) {
|
->get();
|
||||||
|
|
||||||
|
$isSubjectReligion = $this->teacherSubject->subject->is_religious;
|
||||||
|
$subjectName = strtolower($this->teacherSubject->subject->name);
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($classStudents as $classStudent) {
|
||||||
|
$student = $classStudent->student;
|
||||||
|
|
||||||
|
if (!$student) continue;
|
||||||
|
|
||||||
|
if ($isSubjectReligion) {
|
||||||
|
$studentReligion = strtolower($student->religion ?? '');
|
||||||
|
|
||||||
|
if (!str_contains($subjectName, $studentReligion)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$existingAttendance = Attendances::where('student_id', $student->id)
|
$existingAttendance = Attendances::where('student_id', $student->id)
|
||||||
->where('teacher_subject_id', $this->teacherSubjectId)
|
->where('teacher_subject_id', $this->teacherSubjectId)
|
||||||
->whereDate('date', $this->attendanceDate)
|
->whereDate('date', $this->attendanceDate)
|
||||||
->where('semester', $this->semester)
|
->where('semester', $this->semester)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
return [
|
$result[] = [
|
||||||
'id' => $student->id,
|
'id' => $student->id,
|
||||||
'name' => $student->full_name,
|
'name' => $student->full_name,
|
||||||
'nis' => $student->nis,
|
'nis' => $student->nis,
|
||||||
'status' => $existingAttendance ? $existingAttendance->status : null,
|
'status' => $existingAttendance ? $existingAttendance->status : null,
|
||||||
'attendance_id' => $existingAttendance ? $existingAttendance->id : null,
|
'attendance_id' => $existingAttendance ? $existingAttendance->id : null,
|
||||||
];
|
];
|
||||||
})
|
}
|
||||||
->toArray();
|
|
||||||
|
$this->students = $result;
|
||||||
|
|
||||||
|
// $this->students = ClassStudent::where('class_room_id', $this->teacherSubjectId)
|
||||||
|
// ->where('academic_year_id', $this->teacherSubject->academic_year_id)
|
||||||
|
// ->with('student')
|
||||||
|
// ->get()
|
||||||
|
// ->map(function ($student) {
|
||||||
|
// $existingAttendance = Attendances::where('student_id', $student->student_id)
|
||||||
|
// ->where('teacher_subject_id', $this->teacherSubjectId)
|
||||||
|
// ->whereDate('date', $this->attendanceDate)
|
||||||
|
// ->where('semester', $this->semester)
|
||||||
|
// ->first();
|
||||||
|
//
|
||||||
|
// return [
|
||||||
|
// 'id' => $student->student->id,
|
||||||
|
// 'name' => $student->student->full_name,
|
||||||
|
// 'nis' => $student->student->nis,
|
||||||
|
// 'status' => $existingAttendance ? $existingAttendance->status : null,
|
||||||
|
// 'attendance_id' => $existingAttendance ? $existingAttendance->id : null,
|
||||||
|
// ];
|
||||||
|
// })
|
||||||
|
// ->values()
|
||||||
|
// ->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function markAll($status): void
|
public function markAll($status): void
|
||||||
|
|||||||
@ -43,24 +43,6 @@ class ClassRoomResource extends Resource
|
|||||||
'5' => 'Class 5',
|
'5' => 'Class 5',
|
||||||
'6' => 'Class 6',
|
'6' => 'Class 6',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Select::make('homeroom_teacher_id')
|
|
||||||
->label('Homeroom Teacher')
|
|
||||||
->relationship(
|
|
||||||
name: 'homeroomTeacher',
|
|
||||||
titleAttribute: 'name',
|
|
||||||
modifyQueryUsing: fn ($query) => $query->whereHas('roles', function ($q) {
|
|
||||||
$q->where('name', 'teacher');
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
->searchable()
|
|
||||||
->preload()
|
|
||||||
->required(),
|
|
||||||
Forms\Components\TextInput::make('academic_year')
|
|
||||||
->label('Academic Year')
|
|
||||||
->required()
|
|
||||||
->placeholder('Example: 2023/2024')
|
|
||||||
->maxLength(9),
|
|
||||||
])->columns(2)
|
])->columns(2)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -73,10 +55,6 @@ class ClassRoomResource extends Resource
|
|||||||
->searchable(),
|
->searchable(),
|
||||||
Tables\Columns\TextColumn::make('class_level')
|
Tables\Columns\TextColumn::make('class_level')
|
||||||
->searchable(),
|
->searchable(),
|
||||||
Tables\Columns\TextColumn::make('homeroomTeacher.name')
|
|
||||||
->label('Homeroom Teacher'),
|
|
||||||
Tables\Columns\TextColumn::make('academic_year')
|
|
||||||
->searchable(),
|
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
@ -87,16 +65,28 @@ class ClassRoomResource extends Resource
|
|||||||
->toggleable(isToggledHiddenByDefault: true),
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
Tables\Filters\TrashedFilter::make(),
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
Tables\Actions\DeleteAction::make(),
|
Tables\Actions\DeleteAction::make(),
|
||||||
|
Tables\Actions\RestoreAction::make(),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
app/Filament/Resources/ClassStudentResource.php
Normal file
112
app/Filament/Resources/ClassStudentResource.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassStudentResource\Pages;
|
||||||
|
use App\Filament\Resources\ClassStudentResource\RelationManagers;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\Student;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class ClassStudentResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = ClassStudent::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Select::make('class_room_id')
|
||||||
|
->label('Class Room')
|
||||||
|
->required()
|
||||||
|
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('student_id')
|
||||||
|
->label('Student')
|
||||||
|
->required()
|
||||||
|
->options(Student::pluck('full_name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('academic_year_id')
|
||||||
|
->label('Academic Year')
|
||||||
|
->required()
|
||||||
|
->options(AcademicYear::pluck('name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
Tables\Columns\TextColumn::make('class.class_name')
|
||||||
|
->label('Class Room')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('student.full_name')
|
||||||
|
->label('Student')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('academicYear.name')
|
||||||
|
->label('Academic Year')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('updated_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('deleted_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListClassStudents::route('/'),
|
||||||
|
'create' => Pages\CreateClassStudent::route('/create'),
|
||||||
|
'edit' => Pages\EditClassStudent::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassStudentResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassStudentResource;
|
||||||
|
use App\Models\Assessment;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateClassStudent extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassStudentResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$exists = ClassStudent::where('class_room_id', $data['class_room_id'])
|
||||||
|
->where('student_id', $data['student_id'])
|
||||||
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record for this class room, student, and academic year combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassStudentResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassStudentResource;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditClassStudent extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassStudentResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
$exists = ClassStudent::where('class_room_id', $data['class_room_id'])
|
||||||
|
->where('student_id', $data['student_id'])
|
||||||
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record for this class room, student, and academic year combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassStudentResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassStudentResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListClassStudents extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassStudentResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
83
app/Filament/Resources/ClassSubjectResource.php
Normal file
83
app/Filament/Resources/ClassSubjectResource.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassSubjectResource\Pages;
|
||||||
|
use App\Filament\Resources\ClassSubjectResource\RelationManagers;
|
||||||
|
use App\Models\ClassSubject;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
|
||||||
|
class ClassSubjectResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = ClassSubject::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Select::make('class_room_id')
|
||||||
|
->label('Kelas')
|
||||||
|
->relationship('class', 'class_name')
|
||||||
|
->required(),
|
||||||
|
|
||||||
|
Select::make('subject_id')
|
||||||
|
->label('Mata Pelajaran')
|
||||||
|
->relationship('subject', 'name')
|
||||||
|
->required(),
|
||||||
|
|
||||||
|
Select::make('academic_year_id')
|
||||||
|
->label('Tahun Ajaran')
|
||||||
|
->relationship('academicYear', 'name') // ganti "name" jika kolomnya berbeda
|
||||||
|
->required(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('class.class_name')->label('Kelas')->sortable()->searchable(),
|
||||||
|
TextColumn::make('subject.name')->label('Mata Pelajaran')->sortable()->searchable(),
|
||||||
|
TextColumn::make('academicYear.name')->label('Tahun Ajaran')->sortable(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListClassSubjects::route('/'),
|
||||||
|
'create' => Pages\CreateClassSubject::route('/create'),
|
||||||
|
'edit' => Pages\EditClassSubject::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassSubjectResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassSubjectResource;
|
||||||
|
use App\Models\ClassSubject;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateClassSubject extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassSubjectResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$exists = ClassSubject::where('class_room_id', $data['class_room_id'])
|
||||||
|
->where('subject_id', $data['subject_id'])
|
||||||
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record for this class, subject, and academic year combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassSubjectResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassSubjectResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditClassSubject extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassSubjectResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ClassSubjectResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ClassSubjectResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListClassSubjects extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = ClassSubjectResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources;
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
use App\Filament\Resources\SubjectScopeResource\Pages;
|
use App\Filament\Resources\CompetencyAchievementResource\Pages;
|
||||||
use App\Filament\Resources\SubjectScopeResource\RelationManagers;
|
use App\Filament\Resources\CompetencyAchievementResource\RelationManagers;
|
||||||
use App\Models\SubjectScope;
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\Subject;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
@ -13,12 +15,10 @@ use Filament\Tables\Table;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
class SubjectScopeResource extends Resource
|
class CompetencyAchievementResource extends Resource
|
||||||
{
|
{
|
||||||
protected static ?string $model = SubjectScope::class;
|
protected static ?string $model = CompetencyAchievement::class;
|
||||||
|
|
||||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
protected static ?string $navigationGroup = 'Academic Management';
|
protected static ?string $navigationGroup = 'Academic Management';
|
||||||
|
|
||||||
public static function form(Form $form): Form
|
public static function form(Form $form): Form
|
||||||
@ -27,17 +27,27 @@ class SubjectScopeResource extends Resource
|
|||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Select::make('subject_id')
|
Forms\Components\Select::make('subject_id')
|
||||||
->label('Subject')
|
->label('Subject')
|
||||||
->options(
|
|
||||||
fn () => \App\Models\Subject::pluck('name', 'id')->toArray()
|
|
||||||
)
|
|
||||||
->searchable()
|
|
||||||
->required(),
|
|
||||||
Forms\Components\TextInput::make('religion')
|
|
||||||
->maxLength(255),
|
|
||||||
Forms\Components\TextInput::make('learning_goal')
|
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->options(Subject::pluck('name', 'id')->toArray())
|
||||||
Forms\Components\Textarea::make('scope')
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('class_room_id')
|
||||||
|
->label('Class')
|
||||||
|
->required()
|
||||||
|
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('min_score')
|
||||||
|
->required()
|
||||||
|
->numeric()
|
||||||
|
->default(0),
|
||||||
|
Forms\Components\TextInput::make('max_score')
|
||||||
|
->required()
|
||||||
|
->numeric()
|
||||||
|
->default(0),
|
||||||
|
Forms\Components\Textarea::make('description')
|
||||||
->required()
|
->required()
|
||||||
->columnSpanFull(),
|
->columnSpanFull(),
|
||||||
]);
|
]);
|
||||||
@ -50,10 +60,15 @@ class SubjectScopeResource extends Resource
|
|||||||
Tables\Columns\TextColumn::make('subject.name')
|
Tables\Columns\TextColumn::make('subject.name')
|
||||||
->numeric()
|
->numeric()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
Tables\Columns\TextColumn::make('religion')
|
Tables\Columns\TextColumn::make('classRoom.class_name')
|
||||||
->searchable(),
|
->numeric()
|
||||||
Tables\Columns\TextColumn::make('learning_goal')
|
->sortable(),
|
||||||
->searchable(),
|
Tables\Columns\TextColumn::make('min_score')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('max_score')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
@ -68,11 +83,15 @@ class SubjectScopeResource extends Resource
|
|||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
|
Tables\Actions\ViewAction::make(),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +105,9 @@ class SubjectScopeResource extends Resource
|
|||||||
public static function getPages(): array
|
public static function getPages(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'index' => Pages\ListSubjectScopes::route('/'),
|
'index' => Pages\ListCompetencyAchievements::route('/'),
|
||||||
'create' => Pages\CreateSubjectScope::route('/create'),
|
'create' => Pages\CreateCompetencyAchievement::route('/create'),
|
||||||
'edit' => Pages\EditSubjectScope::route('/{record}/edit'),
|
'edit' => Pages\EditCompetencyAchievement::route('/{record}/edit'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CompetencyAchievementResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CompetencyAchievementResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateCompetencyAchievement extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = CompetencyAchievementResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CompetencyAchievementResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CompetencyAchievementResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditCompetencyAchievement extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = CompetencyAchievementResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CompetencyAchievementResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CompetencyAchievementResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListCompetencyAchievements extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = CompetencyAchievementResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -56,18 +56,21 @@ class ExtracurricularResource extends Resource
|
|||||||
// Tambahkan filter jika perlu
|
// Tambahkan filter jika perlu
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make()->label('Edit'),
|
Tables\Actions\EditAction::make(),
|
||||||
Tables\Actions\DeleteAction::make()->label('Hapus'),
|
Tables\Actions\DeleteAction::make(),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\DeleteBulkAction::make()->label('Hapus Massal'),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getRelations(): array
|
public static function getRelations(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
// Tambahkan RelationManager jika ada
|
//
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
app/Filament/Resources/HomeRoomTeacherResource.php
Normal file
109
app/Filament/Resources/HomeRoomTeacherResource.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\HomeRoomTeacherResource\Pages;
|
||||||
|
use App\Filament\Resources\HomeRoomTeacherResource\RelationManagers;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use App\Models\User;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class HomeRoomTeacherResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = HomeRoomTeacher::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Select::make('class_room_id')
|
||||||
|
->label('Class Room')
|
||||||
|
->required()
|
||||||
|
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('teacher_id')
|
||||||
|
->label('Teacher')
|
||||||
|
->required()
|
||||||
|
->options(User::role('teacher')->pluck('name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('academic_year_id')
|
||||||
|
->label('Academic Year')
|
||||||
|
->required()
|
||||||
|
->options(AcademicYear::pluck('name', 'id')->toArray())
|
||||||
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
Tables\Columns\TextColumn::make('classRoom.class_name')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('teacher.name')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('academicYear.name')
|
||||||
|
->numeric()
|
||||||
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('updated_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
Tables\Columns\TextColumn::make('deleted_at')
|
||||||
|
->dateTime()
|
||||||
|
->sortable()
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListHomeRoomTeachers::route('/'),
|
||||||
|
'create' => Pages\CreateHomeRoomTeacher::route('/create'),
|
||||||
|
'edit' => Pages\EditHomeRoomTeacher::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\HomeRoomTeacherResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\HomeRoomTeacherResource;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateHomeRoomTeacher extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = HomeRoomTeacherResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$exists = HomeRoomTeacher::where('class_room_id', $data['class_room_id'])
|
||||||
|
->where('teacher_id', $data['teacher_id'])
|
||||||
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record for this class room, teacher, and academic year combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\HomeRoomTeacherResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\HomeRoomTeacherResource;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditHomeRoomTeacher extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = HomeRoomTeacherResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
$exists = HomeRoomTeacher::where('class_room_id', $data['class_room_id'])
|
||||||
|
->where('teacher_id', $data['teacher_id'])
|
||||||
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save')
|
||||||
|
->body('A record for this class room, teacher, and academic year combination already exists.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->halt(); // Stop the save process
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\HomeRoomTeacherResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\HomeRoomTeacherResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListHomeRoomTeachers extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = HomeRoomTeacherResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,14 +18,18 @@ class StudentResource extends Resource
|
|||||||
|
|
||||||
protected static ?string $navigationIcon = 'heroicon-o-users';
|
protected static ?string $navigationIcon = 'heroicon-o-users';
|
||||||
|
|
||||||
protected static ?string $navigationGroup = 'Academic Management';
|
protected static ?string $navigationGroup = 'Data Master';
|
||||||
|
|
||||||
public static function form(Form $form): Form
|
public static function form(Form $form): Form
|
||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Section::make('Informasi Siswa')
|
Forms\Components\Section::make('Data Siswa')
|
||||||
->schema([
|
->schema([
|
||||||
|
Forms\Components\TextInput::make('nisn')
|
||||||
|
->label('NISN')
|
||||||
|
->maxLength(20),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('nis')
|
Forms\Components\TextInput::make('nis')
|
||||||
->label('NIS')
|
->label('NIS')
|
||||||
->required()
|
->required()
|
||||||
@ -62,14 +66,6 @@ class StudentResource extends Resource
|
|||||||
->email()
|
->email()
|
||||||
->maxLength(100),
|
->maxLength(100),
|
||||||
|
|
||||||
Forms\Components\Select::make('class_id')
|
|
||||||
->label('Class')
|
|
||||||
->options(
|
|
||||||
fn () => \App\Models\ClassRoom::pluck('class_name', 'id')->toArray()
|
|
||||||
)
|
|
||||||
->searchable()
|
|
||||||
->required(),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('parent_name')
|
Forms\Components\TextInput::make('parent_name')
|
||||||
->label("Parent's Name")
|
->label("Parent's Name")
|
||||||
->required()
|
->required()
|
||||||
@ -79,9 +75,19 @@ class StudentResource extends Resource
|
|||||||
->label("Parent's Phone")
|
->label("Parent's Phone")
|
||||||
->maxLength(15),
|
->maxLength(15),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('religion')
|
||||||
|
->label('Religion')
|
||||||
|
->options([
|
||||||
|
'islam' => 'Islam',
|
||||||
|
'hindu' => 'Hindu',
|
||||||
|
'katolik' => 'Katolik',
|
||||||
|
'kristen' => 'Kristen',
|
||||||
|
'buddha' => 'Buddha',
|
||||||
|
]),
|
||||||
|
|
||||||
Forms\Components\Textarea::make('address')
|
Forms\Components\Textarea::make('address')
|
||||||
->label('Address')
|
->label('Address')
|
||||||
->rows(3),
|
->rows(1),
|
||||||
|
|
||||||
])
|
])
|
||||||
->columns(2),
|
->columns(2),
|
||||||
@ -107,12 +113,12 @@ class StudentResource extends Resource
|
|||||||
Tables\Columns\TextColumn::make('birth_date')
|
Tables\Columns\TextColumn::make('birth_date')
|
||||||
->label('Birth Date')
|
->label('Birth Date')
|
||||||
->date(),
|
->date(),
|
||||||
Tables\Columns\TextColumn::make('classRoom.class_name')
|
|
||||||
->label('Class')
|
|
||||||
->sortable()
|
|
||||||
->searchable(),
|
|
||||||
Tables\Columns\TextColumn::make('parent_name')
|
Tables\Columns\TextColumn::make('parent_name')
|
||||||
->label("Parent's Name"),
|
->label("Parent's Name"),
|
||||||
|
Tables\Columns\TextColumn::make('religion')
|
||||||
|
->label("Religion")
|
||||||
|
->formatStateUsing(fn (string $state): string => strtoupper($state))
|
||||||
|
->badge(),
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
@ -129,6 +135,9 @@ class StudentResource extends Resource
|
|||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,18 @@ class SubjectResource extends Resource
|
|||||||
Forms\Components\TextInput::make('name')
|
Forms\Components\TextInput::make('name')
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
|
|
||||||
Forms\Components\Toggle::make('is_religious')
|
Forms\Components\Toggle::make('is_religious')
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('category')
|
||||||
|
->options([
|
||||||
|
'umum' => 'Umum',
|
||||||
|
'muatan lokal' => 'Muatan Lokal',
|
||||||
|
'seni' => 'Seni',
|
||||||
|
])
|
||||||
|
->required(),
|
||||||
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,9 +48,14 @@ class SubjectResource extends Resource
|
|||||||
return $table
|
return $table
|
||||||
->columns([
|
->columns([
|
||||||
Tables\Columns\TextColumn::make('name')
|
Tables\Columns\TextColumn::make('name')
|
||||||
|
->label("Name")
|
||||||
->searchable(),
|
->searchable(),
|
||||||
Tables\Columns\IconColumn::make('is_religious')
|
Tables\Columns\IconColumn::make('is_religious')
|
||||||
|
->label("Is Religious")
|
||||||
->boolean(),
|
->boolean(),
|
||||||
|
Tables\Columns\TextColumn::make('category')
|
||||||
|
->label("Category")
|
||||||
|
->sortable(),
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
@ -60,6 +75,9 @@ class SubjectResource extends Resource
|
|||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Filament\Resources\SubjectScopeResource\Pages;
|
|
||||||
|
|
||||||
use App\Filament\Resources\SubjectScopeResource;
|
|
||||||
use Filament\Actions;
|
|
||||||
use Filament\Resources\Pages\CreateRecord;
|
|
||||||
|
|
||||||
class CreateSubjectScope extends CreateRecord
|
|
||||||
{
|
|
||||||
protected static string $resource = SubjectScopeResource::class;
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Filament\Resources\SubjectScopeResource\Pages;
|
|
||||||
|
|
||||||
use App\Filament\Resources\SubjectScopeResource;
|
|
||||||
use Filament\Actions;
|
|
||||||
use Filament\Resources\Pages\EditRecord;
|
|
||||||
|
|
||||||
class EditSubjectScope extends EditRecord
|
|
||||||
{
|
|
||||||
protected static string $resource = SubjectScopeResource::class;
|
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Actions\DeleteAction::make(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Filament\Resources\SubjectScopeResource\Pages;
|
|
||||||
|
|
||||||
use App\Filament\Resources\SubjectScopeResource;
|
|
||||||
use Filament\Actions;
|
|
||||||
use Filament\Resources\Pages\ListRecords;
|
|
||||||
|
|
||||||
class ListSubjectScopes extends ListRecords
|
|
||||||
{
|
|
||||||
protected static string $resource = SubjectScopeResource::class;
|
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Actions\CreateAction::make(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Filament\Resources;
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
use App\Filament\Resources\TeacherSubjectResource\Pages;
|
use App\Filament\Resources\TeacherSubjectResource\Pages;
|
||||||
|
use App\Models\AcademicYear;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
@ -50,11 +51,12 @@ class TeacherSubjectResource extends Resource
|
|||||||
->searchable()
|
->searchable()
|
||||||
->native(false),
|
->native(false),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('academic_year')
|
Forms\Components\Select::make('academic_year_id')
|
||||||
->label('Academic Year')
|
->label('Academic Year')
|
||||||
->required()
|
->required()
|
||||||
->placeholder('e.g. 2023/2024')
|
->options(AcademicYear::pluck('name', 'id')->toArray())
|
||||||
->maxLength(9),
|
->searchable()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
])
|
])
|
||||||
->columns(2),
|
->columns(2),
|
||||||
@ -80,7 +82,7 @@ class TeacherSubjectResource extends Resource
|
|||||||
->searchable()
|
->searchable()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('academic_year')
|
Tables\Columns\TextColumn::make('academicYear.name')
|
||||||
->label('Academic Year')
|
->label('Academic Year')
|
||||||
->searchable()
|
->searchable()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class CreateTeacherSubject extends CreateRecord
|
|||||||
$exists = TeacherSubject::where('teacher_id', $data['teacher_id'])
|
$exists = TeacherSubject::where('teacher_id', $data['teacher_id'])
|
||||||
->where('subject_id', $data['subject_id'])
|
->where('subject_id', $data['subject_id'])
|
||||||
->where('class_id', $data['class_id'])
|
->where('class_id', $data['class_id'])
|
||||||
->where('academic_year', $data['academic_year'])
|
->where('academic_year_id', $data['academic_year_id'])
|
||||||
->exists();
|
->exists();
|
||||||
|
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
|
|||||||
@ -73,8 +73,11 @@ class UserResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
// Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
app/Models/AcademicYear.php
Normal file
34
app/Models/AcademicYear.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class AcademicYear extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = ['name', 'is_active', 'start_date', 'end_date'];
|
||||||
|
|
||||||
|
public function homeRoomTeahcer(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(HomeRoomTeacher::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function teacherSubject(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(TeacherSubject::class, 'academic_year_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function classStudents()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ClassStudent::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function classSubjects()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ClassStudent::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ class Assessment extends Model
|
|||||||
'teacher_subject_id',
|
'teacher_subject_id',
|
||||||
'student_id',
|
'student_id',
|
||||||
'score',
|
'score',
|
||||||
|
'semester'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function teacherSubject()
|
public function teacherSubject()
|
||||||
|
|||||||
@ -4,28 +4,44 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class ClassRoom extends Model
|
class ClassRoom extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'class_name',
|
'class_name',
|
||||||
'class_level',
|
'class_level',
|
||||||
'homeroom_teacher_id',
|
|
||||||
'academic_year'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public function homeroomTeacher()
|
public function homeroomTeacher()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'homeroom_teacher_id');
|
return $this->hasMany(HomeRoomTeacher::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function students()
|
public function students()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Student::class, 'class_id');
|
return $this->hasMany(Student::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function teacherAssignments(): HasMany
|
public function teacherAssignments(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(TeacherSubject::class, 'class_id');
|
return $this->hasMany(TeacherSubject::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function competencyAchievements()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CompetencyAchievement::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function classStudents()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ClassStudent::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function classSubjects(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(ClassSubject::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/Models/ClassStudent.php
Normal file
28
app/Models/ClassStudent.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class ClassStudent extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = ['class_room_id', 'student_id', 'academic_year_id'];
|
||||||
|
|
||||||
|
public function class()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ClassRoom::class, 'class_room_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function student()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Student::class, 'student_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function academicYear()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AcademicYear::class, 'academic_year_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
27
app/Models/ClassSubject.php
Normal file
27
app/Models/ClassSubject.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
|
class ClassSubject extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = ['class_room_id', 'subject_id', 'academic_year_id'];
|
||||||
|
|
||||||
|
public function subject(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Subject::class, 'subject_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function class(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ClassRoom::class, 'class_room_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function academicYear(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AcademicYear::class, 'academic_year_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/Models/CompetencyAchievement.php
Normal file
31
app/Models/CompetencyAchievement.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class CompetencyAchievement extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'subject_id',
|
||||||
|
'class_room_id',
|
||||||
|
'min_score',
|
||||||
|
'max_score',
|
||||||
|
'description',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Relasi ke Subject
|
||||||
|
public function subject()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Subject::class, 'subject_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relasi ke ClassRoom
|
||||||
|
public function classRoom()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ClassRoom::class, 'class_room_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/Models/HomeRoomTeacher.php
Normal file
28
app/Models/HomeRoomTeacher.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class HomeRoomTeacher extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = ['class_room_id', 'teacher_id', 'academic_year_id'];
|
||||||
|
|
||||||
|
public function classRoom()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ClassRoom::class, 'class_room_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function teacher()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'teacher_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function academicYear()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AcademicYear::class, 'academic_year_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,18 +17,17 @@ class Student extends Model
|
|||||||
'religion',
|
'religion',
|
||||||
'phone',
|
'phone',
|
||||||
'email',
|
'email',
|
||||||
'class_id',
|
|
||||||
'parent_name',
|
'parent_name',
|
||||||
'parent_phone',
|
'parent_phone',
|
||||||
|
'is_active',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'birth_date' => 'date',
|
'birth_date' => 'date',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Relasi dengan kelas
|
public function classStudents()
|
||||||
public function classRoom()
|
|
||||||
{
|
{
|
||||||
return $this->belongsTo(ClassRoom::class, 'class_id');
|
return $this->hasMany(ClassStudent::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
|
|
||||||
class Subject extends Model
|
class Subject extends Model
|
||||||
{
|
{
|
||||||
protected $fillable = ['name', 'is_religious'];
|
protected $fillable = ['name', 'is_religious', 'category'];
|
||||||
|
|
||||||
public function scopes()
|
public function scopes()
|
||||||
{
|
{
|
||||||
@ -16,12 +16,16 @@ class Subject extends Model
|
|||||||
|
|
||||||
public function teacherAssignments(): HasMany
|
public function teacherAssignments(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(TeacherSubject::class, 'subject_id');
|
return $this->hasMany(TeacherSubject::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function competencyAchievements()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CompetencyAchievement::class);
|
||||||
|
}
|
||||||
|
|
||||||
// public function grades()
|
public function classSubjects(): HasMany
|
||||||
// {
|
{
|
||||||
// return $this->hasMany(Grade::class);
|
return $this->hasMany(ClassSubject::class);
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class SubjectScope extends Model
|
|
||||||
{
|
|
||||||
protected $fillable = ['subject_id', 'religion', 'learning_goal', 'scope'];
|
|
||||||
|
|
||||||
public function subject()
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Subject::class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,53 +4,34 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
class TeacherSubject extends Model
|
class TeacherSubject extends Model
|
||||||
{
|
{
|
||||||
protected $fillable = ['teacher_id', 'subject_id', 'class_id', 'academic_year'];
|
protected $fillable = ['teacher_id', 'subject_id', 'class_id', 'academic_year_id'];
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the teacher associated with this assignment
|
|
||||||
*/
|
|
||||||
public function teacher(): BelongsTo
|
public function teacher(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'teacher_id');
|
return $this->belongsTo(User::class, 'teacher_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the subject associated with this assignment
|
|
||||||
*/
|
|
||||||
public function subject(): BelongsTo
|
public function subject(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Subject::class, 'subject_id');
|
return $this->belongsTo(Subject::class, 'subject_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the class associated with this assignment
|
|
||||||
*/
|
|
||||||
public function class(): BelongsTo
|
public function class(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(ClassRoom::class, 'class_id');
|
return $this->belongsTo(ClassRoom::class, 'class_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Scope for current academic year
|
|
||||||
*/
|
|
||||||
public function scopeCurrentYear($query)
|
|
||||||
{
|
|
||||||
return $query->where('academic_year', now()->format('Y'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scope for specific academic year
|
|
||||||
*/
|
|
||||||
public function scopeForYear($query, $year)
|
|
||||||
{
|
|
||||||
return $query->where('academic_year', $year);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attendances()
|
public function attendances()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Attendances::class);
|
return $this->hasMany(Attendances::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function academicYear() : BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AcademicYear::class, 'academic_year_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,4 +57,9 @@ class User extends Authenticatable
|
|||||||
{
|
{
|
||||||
return $this->hasMany(TeacherSubject::class, 'teacher_id');
|
return $this->hasMany(TeacherSubject::class, 'teacher_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function homeRoomTeacher(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(HomeRoomTeacher::class, 'teacher_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function viewAny(User $user): bool
|
public function viewAny(User $user): bool
|
||||||
{
|
{
|
||||||
return $user->can('view_any_subject_scope');
|
return $user->can('view_any_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function view(User $user, SubjectScope $subjectScope): bool
|
public function view(User $user, SubjectScope $subjectScope): bool
|
||||||
{
|
{
|
||||||
return $user->can('view_subject_scope');
|
return $user->can('view_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +28,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function create(User $user): bool
|
public function create(User $user): bool
|
||||||
{
|
{
|
||||||
return $user->can('create_subject_scope');
|
return $user->can('create_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function update(User $user, SubjectScope $subjectScope): bool
|
public function update(User $user, SubjectScope $subjectScope): bool
|
||||||
{
|
{
|
||||||
return $user->can('update_subject_scope');
|
return $user->can('update_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function delete(User $user, SubjectScope $subjectScope): bool
|
public function delete(User $user, SubjectScope $subjectScope): bool
|
||||||
{
|
{
|
||||||
return $user->can('delete_subject_scope');
|
return $user->can('delete_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +52,7 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function restore(User $user, SubjectScope $subjectScope): bool
|
public function restore(User $user, SubjectScope $subjectScope): bool
|
||||||
{
|
{
|
||||||
return $user->can('restore_subject_scope');
|
return $user->can('restore_subject::scope');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +60,6 @@ class SubjectScopePolicy
|
|||||||
*/
|
*/
|
||||||
public function forceDelete(User $user, SubjectScope $subjectScope): bool
|
public function forceDelete(User $user, SubjectScope $subjectScope): bool
|
||||||
{
|
{
|
||||||
return $user->can('force_delete_subject_scope');
|
return $user->can('force_delete_subject::scope');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function viewAny(User $user): bool
|
public function viewAny(User $user): bool
|
||||||
{
|
{
|
||||||
return $user->can('view_any_teacher_subject');
|
return $user->can('view_any_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function view(User $user, TeacherSubject $teacherSubject): bool
|
public function view(User $user, TeacherSubject $teacherSubject): bool
|
||||||
{
|
{
|
||||||
return $user->can('view_teacher_subject');
|
return $user->can('view_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +28,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function create(User $user): bool
|
public function create(User $user): bool
|
||||||
{
|
{
|
||||||
return $user->can('create_teacher_subject');
|
return $user->can('create_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function update(User $user, TeacherSubject $teacherSubject): bool
|
public function update(User $user, TeacherSubject $teacherSubject): bool
|
||||||
{
|
{
|
||||||
return $user->can('update_teacher_subject');
|
return $user->can('update_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function delete(User $user, TeacherSubject $teacherSubject): bool
|
public function delete(User $user, TeacherSubject $teacherSubject): bool
|
||||||
{
|
{
|
||||||
return $user->can('delete_teacher_subject');
|
return $user->can('delete_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +52,7 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function restore(User $user, TeacherSubject $teacherSubject): bool
|
public function restore(User $user, TeacherSubject $teacherSubject): bool
|
||||||
{
|
{
|
||||||
return $user->can('restore_teacher_subject');
|
return $user->can('restore_teacher::subject');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +60,6 @@ class TeacherSubjectPolicy
|
|||||||
*/
|
*/
|
||||||
public function forceDelete(User $user, TeacherSubject $teacherSubject): bool
|
public function forceDelete(User $user, TeacherSubject $teacherSubject): bool
|
||||||
{
|
{
|
||||||
return $user->can('force_delete_teacher_subject');
|
return $user->can('force_delete_teacher::subject');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,9 +15,10 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->string('class_name');
|
$table->string('class_name');
|
||||||
$table->string('class_level');
|
$table->string('class_level');
|
||||||
$table->foreignId('homeroom_teacher_id')->nullable()->constrained('users');
|
|
||||||
$table->string('academic_year');
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unique(['class_name', 'class_level']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,10 +23,13 @@ return new class extends Migration
|
|||||||
$table->text('religion')->nullable();
|
$table->text('religion')->nullable();
|
||||||
$table->string('phone')->nullable();
|
$table->string('phone')->nullable();
|
||||||
$table->string('email')->nullable();
|
$table->string('email')->nullable();
|
||||||
$table->foreignId('class_id')->nullable()->constrained('class_rooms');
|
|
||||||
$table->string('parent_name')->nullable();
|
$table->string('parent_name')->nullable();
|
||||||
$table->string('parent_phone')->nullable();
|
$table->string('parent_phone')->nullable();
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unique(['nis', 'nisn']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,16 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('subject_scopes', function (Blueprint $table) {
|
Schema::create('academic_years', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('subject_id')->constrained()->onDelete('cascade');
|
$table->string('name'); // contoh: 2024/2025
|
||||||
$table->string('religion')->nullable(); // null jika bukan mapel agama
|
$table->boolean('is_active')->default(false);
|
||||||
$table->string('learning_goal');
|
$table->date('start_date')->nullable();
|
||||||
$table->text('scope');
|
$table->date('end_date')->nullable();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unique(['name']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +29,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('subject_scopes');
|
Schema::dropIfExists('academic_years');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -15,7 +15,10 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->boolean('is_religious')->default(false);
|
$table->boolean('is_religious')->default(false);
|
||||||
|
$table->enum('category', ['umum', 'muatan lokal', 'seni']);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->unique(['name', 'is_religious', 'category']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,10 +16,10 @@ return new class extends Migration
|
|||||||
$table->foreignId('teacher_id')->constrained('users');
|
$table->foreignId('teacher_id')->constrained('users');
|
||||||
$table->foreignId('subject_id')->constrained('subjects');
|
$table->foreignId('subject_id')->constrained('subjects');
|
||||||
$table->foreignId('class_id')->constrained('class_rooms');
|
$table->foreignId('class_id')->constrained('class_rooms');
|
||||||
$table->string('academic_year');
|
$table->foreignId('academic_year_id')->constrained('academic_years');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
$table->unique(['teacher_id', 'subject_id', 'class_id', 'academic_year']);
|
$table->unique(['teacher_id', 'subject_id', 'class_id', 'academic_year_id']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,9 +16,10 @@ return new class extends Migration
|
|||||||
$table->foreignId('teacher_subject_id')->constrained('teacher_subjects');
|
$table->foreignId('teacher_subject_id')->constrained('teacher_subjects');
|
||||||
$table->foreignId('student_id')->constrained('students');
|
$table->foreignId('student_id')->constrained('students');
|
||||||
$table->float('score');
|
$table->float('score');
|
||||||
|
$table->string('semester');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
$table->unique(['teacher_subject_id', 'student_id']);
|
$table->unique(['teacher_subject_id', 'student_id', 'semester']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('competency_achievements', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('subject_id')->constrained('subjects');
|
||||||
|
$table->foreignId('class_room_id')->constrained('class_rooms');
|
||||||
|
$table->float("min_score")->default(0);
|
||||||
|
$table->float("max_score")->default(0);
|
||||||
|
$table->text("description");
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('competency_achievements');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('home_room_teachers', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('class_room_id')->constrained('class_rooms');
|
||||||
|
$table->foreignId('teacher_id')->constrained('users');
|
||||||
|
$table->foreignId('academic_year_id')->constrained('academic_years');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->unique(['class_room_id', 'teacher_id', 'academic_year_id']);
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('home_room_teachers');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('class_students', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('class_room_id')->constrained('class_rooms');
|
||||||
|
$table->foreignId('student_id')->constrained('students');
|
||||||
|
$table->foreignId('academic_year_id')->constrained('academic_years');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->unique(['class_room_id', 'student_id', 'academic_year_id']);
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('class_students');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('class_subjects', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('class_room_id')->constrained('class_rooms');
|
||||||
|
$table->foreignId('subject_id')->constrained('subjects');
|
||||||
|
$table->foreignId('academic_year_id')->constrained('academic_years');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unique(['class_room_id', 'subject_id', 'academic_year_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('class_subjects');
|
||||||
|
}
|
||||||
|
};
|
||||||
36
database/seeders/AcademicYearSeeder.php
Normal file
36
database/seeders/AcademicYearSeeder.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class AcademicYearSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
DB::table('academic_years')->insert([
|
||||||
|
[
|
||||||
|
'name' => '2023/2024',
|
||||||
|
'is_active' => false,
|
||||||
|
'start_date' => Carbon::create(2023, 7, 1),
|
||||||
|
'end_date' => Carbon::create(2024, 6, 30),
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => '2024/2025',
|
||||||
|
'is_active' => true,
|
||||||
|
'start_date' => Carbon::create(2024, 7, 1),
|
||||||
|
'end_date' => Carbon::create(2025, 6, 30),
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
|
|
||||||
class AttendanceSeeder extends Seeder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the database seeds.
|
|
||||||
*/
|
|
||||||
public function run(): void
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -18,14 +18,13 @@ class ClassRoomSeeder extends Seeder
|
|||||||
$teachers = User::role('teacher')->get();
|
$teachers = User::role('teacher')->get();
|
||||||
|
|
||||||
$classes = [
|
$classes = [
|
||||||
['class_name' => '1 A', 'class_level' => '1', 'academic_year' => '2024/2025'],
|
['class_name' => '1 A', 'class_level' => '1'],
|
||||||
['class_name' => '1 B', 'class_level' => '1', 'academic_year' => '2024/2025'],
|
['class_name' => '1 B', 'class_level' => '1'],
|
||||||
['class_name' => '2 A', 'class_level' => '2', 'academic_year' => '2024/2025'],
|
['class_name' => '2 A', 'class_level' => '2'],
|
||||||
['class_name' => '2 B', 'class_level' => '2', 'academic_year' => '2024/2025'],
|
['class_name' => '2 B', 'class_level' => '2'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($classes as $index => $class) {
|
foreach ($classes as $index => $class) {
|
||||||
$class['homeroom_teacher_id'] = $teachers[$index % count($teachers)]->id;
|
|
||||||
ClassRoom::create($class);
|
ClassRoom::create($class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
database/seeders/ClassStudentSeeder.php
Normal file
40
database/seeders/ClassStudentSeeder.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\Student;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class ClassStudentSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
// Pastikan data ClassRoom, Student, dan AcademicYear sudah ada
|
||||||
|
$classRooms = ClassRoom::all();
|
||||||
|
$students = Student::all();
|
||||||
|
$academicYears = AcademicYear::all();
|
||||||
|
|
||||||
|
// Hanya melanjutkan jika data tersedia
|
||||||
|
if ($classRooms->isNotEmpty() && $students->isNotEmpty() && $academicYears->isNotEmpty()) {
|
||||||
|
foreach ($classRooms as $classRoom) {
|
||||||
|
foreach ($students as $student) {
|
||||||
|
foreach ($academicYears as $academicYear) {
|
||||||
|
// Buat ClassStudent baru untuk setiap kombinasi
|
||||||
|
ClassStudent::create([
|
||||||
|
'class_room_id' => $classRoom->id,
|
||||||
|
'student_id' => $student->id,
|
||||||
|
'academic_year_id' => $academicYear->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
database/seeders/ClassSubjectSeeder.php
Normal file
41
database/seeders/ClassSubjectSeeder.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\ClassSubject;
|
||||||
|
use App\Models\Subject;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class ClassSubjectSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$classRooms = ClassRoom::all();
|
||||||
|
$subjects = Subject::all();
|
||||||
|
$academicYear = AcademicYear::where('is_active', true)->first();
|
||||||
|
|
||||||
|
if (!$academicYear) {
|
||||||
|
$this->command->error('Tahun ajaran aktif tidak ditemukan.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($classRooms as $classRoom) {
|
||||||
|
// Contoh: ambil 3 sampai 5 mapel random untuk tiap kelas
|
||||||
|
$assignedSubjects = $subjects->random(rand(3, 5));
|
||||||
|
|
||||||
|
foreach ($assignedSubjects as $subject) {
|
||||||
|
ClassSubject::firstOrCreate([
|
||||||
|
'class_room_id' => $classRoom->id,
|
||||||
|
'subject_id' => $subject->id,
|
||||||
|
'academic_year_id' => $academicYear->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\ClassRoom;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Spatie\Permission\Models\Permission;
|
|
||||||
use Spatie\Permission\Models\Role;
|
|
||||||
|
|
||||||
class DatabaseSeeder extends Seeder
|
class DatabaseSeeder extends Seeder
|
||||||
{
|
{
|
||||||
@ -19,9 +15,12 @@ class DatabaseSeeder extends Seeder
|
|||||||
UserSeeder::class,
|
UserSeeder::class,
|
||||||
SubjectSeeder::class,
|
SubjectSeeder::class,
|
||||||
ClassRoomSeeder::class,
|
ClassRoomSeeder::class,
|
||||||
|
AcademicYearSeeder::class,
|
||||||
StudentSeeder::class,
|
StudentSeeder::class,
|
||||||
ExtracurricularSeeder::class,
|
ExtracurricularSeeder::class,
|
||||||
AttendanceSeeder::class,
|
ClassSubjectSeeder::class,
|
||||||
|
ClassStudentSeeder::class,
|
||||||
|
HomeRoomTeacherSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,14 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class SubjectScopeSeeder extends Seeder
|
class HomeRoomTeacherSeeder extends Seeder
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Run the database seeds.
|
* Run the database seeds.
|
||||||
@ -14,4 +18,5 @@ class SubjectScopeSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ namespace Database\Seeders;
|
|||||||
|
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
@ -14,31 +15,29 @@ class StudentSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$classrooms = ClassRoom::all();
|
|
||||||
$religions = ['islam', 'kristen', 'katolik', 'hindu', 'buddha'];
|
$religions = ['islam', 'kristen', 'katolik', 'hindu', 'buddha'];
|
||||||
|
|
||||||
foreach ($classrooms as $classroom) {
|
|
||||||
for ($i = 1; $i <= 20; $i++) {
|
for ($i = 1; $i <= 20; $i++) {
|
||||||
$gender = $i % 2 == 0 ? 'L' : 'P';
|
$gender = $i % 2 == 0 ? 'L' : 'P';
|
||||||
$religion = $religions[array_rand($religions)];
|
$religion = $religions[array_rand($religions)];
|
||||||
$nis = $classroom->class_level . str_pad($i, 3, '0', STR_PAD_LEFT);
|
$nis = '24' . str_pad($i, 4, '0', STR_PAD_LEFT); // NIS unik, misal 240001
|
||||||
|
|
||||||
Student::firstOrCreate(
|
Student::firstOrCreate(
|
||||||
['nis' => $nis], // Cek berdasarkan NIS
|
['nis' => $nis], // Cek berdasarkan NIS
|
||||||
[
|
[
|
||||||
'full_name' => 'Siswa ' . $classroom->class_name . ' ' . $i,
|
'full_name' => 'Siswa ' . $i,
|
||||||
'gender' => $gender,
|
'gender' => $gender,
|
||||||
'birth_date' => now()->subYears(rand(15, 18))->subMonths(rand(1, 12)),
|
'birth_date' => Carbon::now()->subYears(rand(15, 18))->subMonths(rand(1, 12)),
|
||||||
'birth_place' => 'Kota ' . chr(65 + rand(0, 25)),
|
'birth_place' => 'Kota ' . chr(65 + rand(0, 25)),
|
||||||
'address' => 'Jl. Contoh No.' . $i,
|
'address' => 'Jl. Contoh No.' . $i,
|
||||||
'phone' => '0812' . rand(1000000, 9999999),
|
'phone' => '0812' . rand(1000000, 9999999),
|
||||||
'class_id' => $classroom->id,
|
|
||||||
'parent_name' => 'Orang Tua Siswa ' . $i,
|
'parent_name' => 'Orang Tua Siswa ' . $i,
|
||||||
'religion' => $religion,
|
'religion' => $religion,
|
||||||
'parent_phone' => '0813' . rand(1000000, 9999999),
|
'parent_phone' => '0813' . rand(1000000, 9999999),
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use App\Models\SubjectScope;
|
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
@ -15,16 +14,21 @@ class SubjectSeeder extends Seeder
|
|||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$subjects = [
|
$subjects = [
|
||||||
['name' => 'Matematika', 'is_religious' => false],
|
['name' => 'Matematika', 'is_religious' => false, 'category' => 'umum'],
|
||||||
['name' => 'Bahasa Indonesia', 'is_religious' => false],
|
['name' => 'Bahasa Indonesia', 'is_religious' => false, 'category' => 'umum'],
|
||||||
['name' => 'Bahasa Inggris', 'is_religious' => false],
|
['name' => 'Bahasa Inggris', 'is_religious' => false, 'category' => 'umum'],
|
||||||
['name' => 'IPA', 'is_religious' => false],
|
['name' => 'IPA', 'is_religious' => false, 'category' => 'umum'],
|
||||||
['name' => 'IPS', 'is_religious' => false],
|
['name' => 'IPS', 'is_religious' => false, 'category' => 'umum'],
|
||||||
['name' => 'Pendidikan Agama Islam', 'is_religious' => true],
|
['name' => 'Seni Rupa', 'is_religious' => false, 'category' => 'seni'],
|
||||||
['name' => 'Pendidikan Agama Kristen', 'is_religious' => true],
|
['name' => 'Seni Musik', 'is_religious' => false, 'category' => 'seni'],
|
||||||
['name' => 'Pendidikan Agama Katolik', 'is_religious' => true],
|
['name' => 'Seni Tari', 'is_religious' => false, 'category' => 'seni'],
|
||||||
['name' => 'Pendidikan Agama Hindu', 'is_religious' => true],
|
['name' => 'Seni Teater', 'is_religious' => false, 'category' => 'seni'],
|
||||||
['name' => 'Pendidikan Agama Buddha', 'is_religious' => true],
|
['name' => 'Bahasa Sunda', 'is_religious' => false, 'category' => 'muatan lokal'],
|
||||||
|
['name' => 'Pendidikan Agama Islam', 'is_religious' => true, 'category' => 'umum'],
|
||||||
|
['name' => 'Pendidikan Agama Kristen', 'is_religious' => true, 'category' => 'umum'],
|
||||||
|
['name' => 'Pendidikan Agama Katolik', 'is_religious' => true, 'category' => 'umum'],
|
||||||
|
['name' => 'Pendidikan Agama Hindu', 'is_religious' => true, 'category' => 'umum'],
|
||||||
|
['name' => 'Pendidikan Agama Buddha', 'is_religious' => true, 'category' => 'umum'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($subjects as $subject) {
|
foreach ($subjects as $subject) {
|
||||||
@ -40,15 +44,6 @@ class SubjectSeeder extends Seeder
|
|||||||
str_contains($createdSubject->name, 'Buddha') => 'buddha',
|
str_contains($createdSubject->name, 'Buddha') => 'buddha',
|
||||||
default => null
|
default => null
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($religion) {
|
|
||||||
SubjectScope::create([
|
|
||||||
'subject_id' => $createdSubject->id,
|
|
||||||
'religion' => $religion,
|
|
||||||
'learning_goal' => 'Memahami prinsip dasar agama ' . $religion,
|
|
||||||
'scope' => 'Tingkat dasar'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
resources/views/filament/pages/student-report.blade.php
Normal file
77
resources/views/filament/pages/student-report.blade.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->form }}
|
||||||
|
|
||||||
|
@if(!empty($this->list))
|
||||||
|
<div class="fi-ta-ctn overflow-hidden rounded-lg bg-white shadow-sm ring-1 ring-gray-200 dark:bg-gray-900 dark:ring-gray-800">
|
||||||
|
<div class="fi-ta-content overflow-x-auto">
|
||||||
|
<table class="fi-ta-table w-full border-collapse">
|
||||||
|
<thead class="bg-gray-50 dark:bg-gray-800">
|
||||||
|
<!-- Baris Judul Kelompok -->
|
||||||
|
<tr>
|
||||||
|
<th rowspan="2" class="fi-ta-header-cell px-4 py-3 text-left border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ $this->list['header']['name'] }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
@foreach(['umum', 'muatan lokal'] as $category)
|
||||||
|
@if(!empty($this->list['header'][$category]))
|
||||||
|
<th colspan="{{ count($this->list['header'][$category]) }}" class="fi-ta-header-cell px-4 py-3 text-center border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ ucfirst($category) }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Baris Mata Pelajaran -->
|
||||||
|
<tr>
|
||||||
|
@foreach(['umum', 'muatan lokal'] as $category)
|
||||||
|
@if(!empty($this->list['header'][$category]))
|
||||||
|
@foreach($this->list['header'][$category] as $subjectName)
|
||||||
|
<th class="fi-ta-header-cell px-4 py-3 text-center border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ $subjectName }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
|
@foreach($this->list['data'] as $student)
|
||||||
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50">
|
||||||
|
<!-- Kolom Nama -->
|
||||||
|
<td class="fi-ta-cell px-4 py-3 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<span class="text-sm text-gray-900 dark:text-white">
|
||||||
|
{{ $student['name'] }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- Nilai Mata Pelajaran -->
|
||||||
|
@foreach(['umum', 'muatan lokal'] as $category)
|
||||||
|
@if(!empty($this->list['header'][$category]))
|
||||||
|
@foreach($this->list['header'][$category] as $subjectId => $subjectName)
|
||||||
|
<td class="fi-ta-cell px-4 py-3 text-center border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<span class="text-sm text-gray-900 dark:text-white">
|
||||||
|
{{ $student[$category][$subjectId] ?? '-' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="mt-6 p-4 bg-gray-100 rounded-lg text-gray-600 dark:bg-gray-800 dark:text-gray-300">
|
||||||
|
Pilih Kelas, Tahun Akademik, dan Semester untuk melihat laporan siswa.
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</x-filament-panels::page>
|
||||||
@ -10,8 +10,8 @@
|
|||||||
@foreach($this->students as $index => $student)
|
@foreach($this->students as $index => $student)
|
||||||
<div class="flex items-center p-3 border rounded-lg">
|
<div class="flex items-center p-3 border rounded-lg">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<p class="font-medium">{{ $student['name'] }}</p>
|
<p class="font-medium">{{ $student['name'] ?? "" }}</p>
|
||||||
<p class="text-sm text-gray-500">{{ $student['nis'] }}</p>
|
<p class="text-sm text-gray-500">{{ $student['nis'] ?? "" }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-32">
|
<div class="w-32">
|
||||||
<x-filament::input
|
<x-filament::input
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user