refactor: remove unused widgets from AdminPanelProvider to streamline widget management
This commit is contained in:
parent
6277d50cc0
commit
4426fe4d84
74
app/Filament/Widgets/MyAssignmentCompletionChart.php
Normal file
74
app/Filament/Widgets/MyAssignmentCompletionChart.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Assignment;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class MyAssignmentCompletionChart extends ChartWidget
|
||||
{
|
||||
protected static ?int $sort = 3;
|
||||
|
||||
protected ?string $heading = 'Status Penyelesaian Tugas';
|
||||
|
||||
protected ?string $maxHeight = '275px';
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()?->student !== null;
|
||||
}
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$studentId = auth()->user()?->student?->id;
|
||||
|
||||
$baseQuery = Assignment::query()
|
||||
->whereHas('assignmentTargets', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')->from('study_group_members')->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')->from('study_groups')->where('leader_id', $studentId);
|
||||
});
|
||||
});
|
||||
|
||||
$submittedCount = (clone $baseQuery)->whereHas('assignmentSubmissions', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')->from('study_group_members')->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')->from('study_groups')->where('leader_id', $studentId);
|
||||
});
|
||||
})->count();
|
||||
|
||||
$totalCount = $baseQuery->count();
|
||||
|
||||
$notSubmittedCount = $totalCount - $submittedCount;
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Tugas',
|
||||
'data' => [$submittedCount, $notSubmittedCount],
|
||||
'backgroundColor' => [
|
||||
'rgba(59, 130, 246, 0.8)', // Blue 500
|
||||
'rgba(245, 158, 11, 0.8)', // Amber 500
|
||||
],
|
||||
'borderColor' => [
|
||||
'rgba(59, 130, 246, 1)',
|
||||
'rgba(245, 158, 11, 1)',
|
||||
],
|
||||
],
|
||||
],
|
||||
'labels' => ['Sudah Dikerjakan', 'Belum Dikerjakan'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'doughnut';
|
||||
}
|
||||
}
|
||||
57
app/Filament/Widgets/MyAttendanceRatioChart.php
Normal file
57
app/Filament/Widgets/MyAttendanceRatioChart.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Attendance;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
|
||||
class MyAttendanceRatioChart extends ChartWidget
|
||||
{
|
||||
protected static ?int $sort = 2;
|
||||
|
||||
protected ?string $heading = 'Persentase Presensi';
|
||||
|
||||
protected ?string $maxHeight = '275px';
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()?->student !== null;
|
||||
}
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$studentId = auth()->user()?->student?->id;
|
||||
|
||||
$presentCount = Attendance::where('student_id', $studentId)
|
||||
->whereNotNull('attended_at')
|
||||
->count();
|
||||
|
||||
$absentCount = Attendance::where('student_id', $studentId)
|
||||
->whereNull('attended_at')
|
||||
->where('date', '<=', today())
|
||||
->count();
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Presensi',
|
||||
'data' => [$presentCount, $absentCount],
|
||||
'backgroundColor' => [
|
||||
'rgba(16, 185, 129, 0.8)', // Emerald 500
|
||||
'rgba(244, 63, 94, 0.8)', // Rose 500
|
||||
],
|
||||
'borderColor' => [
|
||||
'rgba(16, 185, 129, 1)',
|
||||
'rgba(244, 63, 94, 1)',
|
||||
],
|
||||
],
|
||||
],
|
||||
'labels' => ['Hadir', 'Tidak / Belum Hadir'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'doughnut';
|
||||
}
|
||||
}
|
||||
95
app/Filament/Widgets/MyPendingAssignmentsTable.php
Normal file
95
app/Filament/Widgets/MyPendingAssignmentsTable.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Assignment;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Widgets\TableWidget as BaseWidget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class MyPendingAssignmentsTable extends BaseWidget
|
||||
{
|
||||
protected static ?int $sort = 4;
|
||||
|
||||
protected int|string|array $columnSpan = 'full';
|
||||
|
||||
protected static ?string $heading = 'Tugas Mendatang yang Belum Selesai';
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()?->student !== null;
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
$studentId = auth()->user()?->student?->id;
|
||||
|
||||
return $table
|
||||
->query(
|
||||
Assignment::query()
|
||||
->whereHas('assignmentTargets', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')
|
||||
->from('study_group_members')
|
||||
->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')
|
||||
->from('study_groups')
|
||||
->where('leader_id', $studentId);
|
||||
});
|
||||
})
|
||||
->whereDoesntHave('assignmentSubmissions', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')
|
||||
->from('study_group_members')
|
||||
->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')
|
||||
->from('study_groups')
|
||||
->where('leader_id', $studentId);
|
||||
});
|
||||
})
|
||||
->where('due_date', '>=', now())
|
||||
->orderBy('due_date', 'asc')
|
||||
)
|
||||
->columns([
|
||||
TextColumn::make('title')
|
||||
->label('Judul Tugas')
|
||||
->searchable()
|
||||
->sortable()
|
||||
->wrap(),
|
||||
|
||||
TextColumn::make('course.name')
|
||||
->label('Mata Kuliah')
|
||||
->searchable()
|
||||
->sortable()
|
||||
->wrap(),
|
||||
|
||||
TextColumn::make('type')
|
||||
->label('Jenis')
|
||||
->badge(),
|
||||
|
||||
TextColumn::make('due_date')
|
||||
->label('Tenggat Waktu')
|
||||
->dateTime('d M Y H:i')
|
||||
->sortable()
|
||||
->color(fn (Assignment $record) => $record->due_date < now()->addDays(2) ? 'danger' : 'warning'),
|
||||
])
|
||||
->recordActions([
|
||||
Action::make('kerjakan')
|
||||
->label('Lihat Detail & Kerjakan')
|
||||
->url(fn (Assignment $record): string => '/admin/learning/assignments/'.$record->id.'/submit')
|
||||
->icon('heroicon-m-arrow-top-right-on-square')
|
||||
->button()
|
||||
->color('primary'),
|
||||
])
|
||||
->emptyStateHeading('Tidak Ada Tugas')
|
||||
->emptyStateDescription('Semua tugas telah diselesaikan atau tidak ada tugas mendatang.');
|
||||
}
|
||||
}
|
||||
84
app/Filament/Widgets/StatsOverview.php
Normal file
84
app/Filament/Widgets/StatsOverview.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Assignment;
|
||||
use App\Models\Attendance;
|
||||
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatsOverview extends BaseWidget
|
||||
{
|
||||
protected static ?int $sort = 1;
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()?->student !== null;
|
||||
}
|
||||
|
||||
protected function getStats(): array
|
||||
{
|
||||
$studentId = auth()->user()?->student?->id;
|
||||
|
||||
if (! $studentId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$presentCount = Attendance::where('student_id', $studentId)
|
||||
->whereNotNull('attended_at')
|
||||
->count();
|
||||
$totalSessions = Attendance::where('student_id', $studentId)->count();
|
||||
$attendanceRate = $totalSessions > 0 ? round(($presentCount / $totalSessions) * 100) : 0;
|
||||
|
||||
$baseAssignmentQuery = Assignment::query()
|
||||
->whereHas('assignmentTargets', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')->from('study_group_members')->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')->from('study_groups')->where('leader_id', $studentId);
|
||||
});
|
||||
});
|
||||
|
||||
$completedAssignments = (clone $baseAssignmentQuery)->whereHas('assignmentSubmissions', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')->from('study_group_members')->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')->from('study_groups')->where('leader_id', $studentId);
|
||||
});
|
||||
})->count();
|
||||
|
||||
$pendingAssignments = (clone $baseAssignmentQuery)->whereDoesntHave('assignmentSubmissions', function (Builder $query) use ($studentId) {
|
||||
$query->where('student_id', $studentId)
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('study_group_id')->from('study_group_members')->where('student_id', $studentId);
|
||||
})
|
||||
->orWhereIn('study_group_id', function ($q) use ($studentId) {
|
||||
$q->select('id')->from('study_groups')->where('leader_id', $studentId);
|
||||
});
|
||||
})
|
||||
->where('due_date', '>=', now())
|
||||
->count();
|
||||
|
||||
return [
|
||||
Stat::make('Kehadiran', $presentCount.' / '.$totalSessions.' Sesi')
|
||||
->description($attendanceRate.'% Tingkat Kehadiran')
|
||||
->descriptionIcon('heroicon-m-check-circle')
|
||||
->color($attendanceRate >= 75 ? 'success' : 'danger'),
|
||||
|
||||
Stat::make('Tugas Selesai', $completedAssignments.' Tugas')
|
||||
->description('Telah dikumpulkan')
|
||||
->descriptionIcon('heroicon-m-clipboard-document-check')
|
||||
->color('success'),
|
||||
|
||||
Stat::make('Tugas Mendatang', $pendingAssignments.' Tugas')
|
||||
->description('Belum dikerjakan')
|
||||
->descriptionIcon($pendingAssignments > 0 ? 'heroicon-m-exclamation-circle' : 'heroicon-m-face-smile')
|
||||
->color($pendingAssignments > 0 ? 'warning' : 'gray'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,6 @@
|
||||
use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets\AccountWidget;
|
||||
use Hammadzafar05\MobileBottomNav\MobileBottomNav;
|
||||
use Hammadzafar05\MobileBottomNav\MobileBottomNavItem;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
@ -27,7 +26,6 @@
|
||||
use Saade\Facehash\Enums\Variant;
|
||||
use Saade\FilamentFacehash\FacehashPlugin;
|
||||
use Saade\FilamentFacehash\FacehashProvider;
|
||||
use SalmanAlmajali\JokesWidget\JokesWidget;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
{
|
||||
@ -49,10 +47,7 @@ public function panel(Panel $panel): Panel
|
||||
Dashboard::class,
|
||||
])
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
JokesWidget::class,
|
||||
])
|
||||
->widgets([])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user