diff --git a/app/Http/Controllers/ResourceController.php b/app/Http/Controllers/ResourceController.php index 357e07c..80f4b2e 100644 --- a/app/Http/Controllers/ResourceController.php +++ b/app/Http/Controllers/ResourceController.php @@ -3,13 +3,12 @@ namespace App\Http\Controllers; use App\Models\Resource; +use App\Models\ResourceCompletion; use Illuminate\Support\Facades\Cache; use Inertia\Inertia; class ResourceController extends Controller { - // - public function show($id) { $data = Cache::rememberForever("resource_{$id}", function () use ($id) { @@ -32,6 +31,39 @@ public function show($id) ]; }); - return Inertia::render('Resource', $data); + $isCompleted = auth()->check() + ? ResourceCompletion::where('resource_id', $id)->where('user_id', auth()->id())->exists() + : false; + + $completionsCount = ResourceCompletion::where('resource_id', $id)->count(); + + $completers = ResourceCompletion::where('resource_id', $id) + ->with('user:id,name,image_path,institution') + ->latest() + ->take(10) + ->get() + ->pluck('user') + ->filter() + ->values(); + + return Inertia::render('Resource', array_merge($data, [ + 'isCompleted' => $isCompleted, + 'completionsCount' => $completionsCount, + 'completers' => $completers, + ])); + } + + public function toggleComplete(Resource $resource) + { + $user = auth()->user(); + $existing = $resource->completions()->where('user_id', $user->id)->first(); + + if ($existing) { + $existing->delete(); + } else { + $resource->completions()->create(['user_id' => $user->id]); + } + + return back(); } } diff --git a/app/Models/Resource.php b/app/Models/Resource.php index c5956d8..c3e4c12 100644 --- a/app/Models/Resource.php +++ b/app/Models/Resource.php @@ -47,4 +47,9 @@ public function user() { return $this->belongsTo(User::class); } + + public function completions() + { + return $this->hasMany(ResourceCompletion::class); + } } diff --git a/app/Models/ResourceCompletion.php b/app/Models/ResourceCompletion.php new file mode 100644 index 0000000..47d784c --- /dev/null +++ b/app/Models/ResourceCompletion.php @@ -0,0 +1,24 @@ +belongsTo(Resource::class); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 88a954c..206f211 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -82,4 +82,14 @@ public function blogs(): HasMany { return $this->hasmany(Blog::class); } + + public function resourceCompletions(): HasMany + { + return $this->hasMany(ResourceCompletion::class); + } + + public function completedResources() + { + return $this->belongsToMany(Resource::class, 'resource_completions'); + } } diff --git a/database/migrations/2026_08_26_114000_create_resource_completions_table.php b/database/migrations/2026_08_26_114000_create_resource_completions_table.php new file mode 100644 index 0000000..90053b1 --- /dev/null +++ b/database/migrations/2026_08_26_114000_create_resource_completions_table.php @@ -0,0 +1,31 @@ +id(); + $table->foreignId('resource_id')->constrained()->cascadeOnDelete(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->timestamps(); + + $table->unique(['resource_id', 'user_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('resource_completions'); + } +}; diff --git a/resources/js/pages/Resource.vue b/resources/js/pages/Resource.vue index df4e7bf..7654429 100644 --- a/resources/js/pages/Resource.vue +++ b/resources/js/pages/Resource.vue @@ -1,5 +1,5 @@