diff --git a/app/Http/Controllers/Admin/AdminPageController.php b/app/Http/Controllers/Admin/AdminPageController.php index fc8e018b9..61743b620 100644 --- a/app/Http/Controllers/Admin/AdminPageController.php +++ b/app/Http/Controllers/Admin/AdminPageController.php @@ -129,6 +129,11 @@ class AdminPageController extends BasePageController return \App\Models\DnzbFailure::count(); }); + // Cache reported releases count for 5 minutes + $reportedCount = \Illuminate\Support\Facades\Cache::remember('admin_stats_reported_count', 300, function () { + return \App\Models\ReleaseReport::where('status', 'pending')->count(); + }); + // Today's counts can be cached for 1 minute since they change frequently $releasesToday = \Illuminate\Support\Facades\Cache::remember('admin_stats_releases_today_'.$today, 60, function () use ($today) { return \App\Models\Release::whereRaw('DATE(adddate) = ?', [$today])->count(); @@ -146,6 +151,7 @@ class AdminPageController extends BasePageController 'groups' => $groupsCount, 'active_groups' => $activeGroupsCount, 'failed' => $failedCount, + 'reported' => $reportedCount, 'disk_free' => $this->getDiskSpace(), ]; } diff --git a/app/Models/ReleaseReport.php b/app/Models/ReleaseReport.php index 3c5f103ed..9da6e49bd 100644 --- a/app/Models/ReleaseReport.php +++ b/app/Models/ReleaseReport.php @@ -3,11 +3,14 @@ namespace App\Models; use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class ReleaseReport extends Model { + use HasFactory; + /** * The table associated with the model. */ diff --git a/database/factories/ReleaseReportFactory.php b/database/factories/ReleaseReportFactory.php new file mode 100644 index 000000000..c9808cf94 --- /dev/null +++ b/database/factories/ReleaseReportFactory.php @@ -0,0 +1,85 @@ + + */ +class ReleaseReportFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var class-string<\App\Models\ReleaseReport> + */ + protected $model = ReleaseReport::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $reasons = array_keys(ReleaseReport::REASONS); + + return [ + 'releases_id' => Release::factory(), + 'users_id' => User::factory(), + 'reason' => fake()->randomElement($reasons), + 'description' => fake()->optional()->sentence(), + 'status' => 'pending', + ]; + } + + /** + * Indicate that the report is pending. + */ + public function pending(): static + { + return $this->state(fn (array $attributes) => [ + 'status' => 'pending', + ]); + } + + /** + * Indicate that the report has been reviewed. + */ + public function reviewed(): static + { + return $this->state(fn (array $attributes) => [ + 'status' => 'reviewed', + 'reviewed_by' => User::factory(), + 'reviewed_at' => now(), + ]); + } + + /** + * Indicate that the report has been resolved. + */ + public function resolved(): static + { + return $this->state(fn (array $attributes) => [ + 'status' => 'resolved', + 'reviewed_by' => User::factory(), + 'reviewed_at' => now(), + ]); + } + + /** + * Indicate that the report has been dismissed. + */ + public function dismissed(): static + { + return $this->state(fn (array $attributes) => [ + 'status' => 'dismissed', + 'reviewed_by' => User::factory(), + 'reviewed_at' => now(), + ]); + } +} diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index ce1b191d1..b648ca698 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -9,7 +9,7 @@ -
+
@@ -81,6 +81,24 @@
+ + +
+
+
+

Reported Releases

+

{{ number_format($stats['reported'] ?? 0) }}

+
+
+ +
+
+ +
diff --git a/tests/Feature/AdminDashboardReportedReleasesTest.php b/tests/Feature/AdminDashboardReportedReleasesTest.php new file mode 100644 index 000000000..97e4e385d --- /dev/null +++ b/tests/Feature/AdminDashboardReportedReleasesTest.php @@ -0,0 +1,43 @@ +assertFileExists($bladePath); + + $content = file_get_contents($bladePath); + + // Check that the blade file contains the reported releases widget + $this->assertStringContainsString('Reported Releases', $content); + $this->assertStringContainsString("stats['reported']", $content); + $this->assertStringContainsString('/admin/release-reports', $content); + $this->assertStringContainsString('View reports', $content); + } + + /** + * Test that the AdminPageController contains the reported count in stats. + */ + public function test_controller_stats_method_has_reported_key(): void + { + $controllerPath = app_path('Http/Controllers/Admin/AdminPageController.php'); + + $this->assertFileExists($controllerPath); + + $content = file_get_contents($controllerPath); + + // Check that the controller contains the reported releases count + $this->assertStringContainsString("'reported'", $content); + $this->assertStringContainsString('admin_stats_reported_count', $content); + $this->assertStringContainsString('ReleaseReport::where', $content); + } +}