Skip to content

Commit

Permalink
Merge pull request #564 from HZ-HBO-ICT/feature/555-feedback-system
Browse files Browse the repository at this point in the history
Feature - Feedback system
  • Loading branch information
TimKardol authored Oct 28, 2024
2 parents db4ed68 + bfc130e commit 9bdee10
Show file tree
Hide file tree
Showing 23 changed files with 620 additions and 4 deletions.
41 changes: 41 additions & 0 deletions app/Http/Controllers/Crew/FeedbackController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Http\Controllers\Crew;

use App\Http\Controllers\Controller;
use App\Models\Feedback;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class FeedbackController extends Controller
{
/**
* Display a listing of the resource.
* @return View
*/
public function index() : View
{
if (Auth::user()->cannot('viewAny', Feedback::class)) {
abort(403);
}

$feedbackReports = Feedback::all();

return view('crew.feedback.index', compact('feedbackReports'));
}

/**
* Display the specified resource.
* @param Feedback $feedback
* @return View
*/
public function show(Feedback $feedback) : View
{
if (Auth::user()->cannot('view', $feedback)) {
abort(403);
}

return view('crew.feedback.show', compact('feedback'));
}
}
32 changes: 32 additions & 0 deletions app/Http/Controllers/Hub/ParticipantController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace App\Http\Controllers\Hub;

use App\Http\Controllers\Controller;
use App\Models\Feedback;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

Expand All @@ -19,4 +21,34 @@ public function programme(): View

return view('myhub.programme', compact('presentations'));
}

/**
* Show the form for creating a new resource.
*/
public function createFeedback()
{
if (Auth::user()->cannot('create', Feedback::class)) {
abort(403);
}

return view('myhub.feedback');
}

/**
* Store a newly created resource in storage.
*/
public function storeFeedback(Request $request)
{
if (Auth::user()->cannot('create', Feedback::class)) {
abort(403);
}

$validated = $request->validate(Feedback::$rules);
Feedback::create(array_merge(
$validated,
['reported_by_id' => Auth::user()->id]
));

return redirect(route('dashboard'))->banner('You successfully submitted your feedback!');
}
}
63 changes: 63 additions & 0 deletions app/Livewire/Crew/AddTeam.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace App\Livewire\Crew;

use App\Models\User;
use Illuminate\View\View;
use LivewireUI\Modal\ModalComponent;

class AddTeam extends ModalComponent
{
public User $user;
public $crew_team;

/**
* Initializes the component
* @param User $user
* @return void
*/
public function mount(User $user)
{
$this->user = $user;
$this->crew_team = $user->crew_team;
}

/**
* Saves the tag for the user
*/
public function save()
{
$validated = $this->validate([
'crew_team' => 'required|in:organization,website'
]);

$this->user->update([
'crew_team' => $this->crew_team
]);

return redirect()->to(route('moderator.crew.index'));
}

/**
* Removes the set team of the crew user
*
* @return \Illuminate\Http\RedirectResponse
*/
public function removeTeam()
{
$this->user->update([
'crew_team' => null
]);

return redirect()->to(route('moderator.crew.index'));
}

/**
* Renders the component
* @return View
*/
public function render(): View
{
return view('livewire.crew.add-team');
}
}
54 changes: 54 additions & 0 deletions app/Mail/FeedbackReceivedMailable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace App\Mail;

use App\Models\Feedback;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class FeedbackReceivedMailable extends Mailable
{
use Queueable, SerializesModels;

/**
* Create a new message instance.
*/
public function __construct(
public Feedback $feedback
) {
}

/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: "Feedback Received for team {$this->feedback->type}",
);
}

/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
markdown: 'emails.feedback-received',
);
}

/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
32 changes: 32 additions & 0 deletions app/Models/Feedback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Models;

use App\Observers\FeedbackObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

#[ObservedBy([FeedbackObserver::class])]
class Feedback extends Model
{
use HasFactory;

protected $fillable = ['type', 'title', 'content', 'reported_by_id'];

public static $rules = [
'type' => 'required|in:organization,website',
'title' => 'required|max:255|string',
'content' => 'required|max:1500|string',
];

/**
* Establishes connection to the user who gave the feedback
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function reportedBy()
{
return $this->belongsTo(User::class, 'reported_by_id');
}
}
14 changes: 12 additions & 2 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class User extends Authenticatable implements MustVerifyEmail
'email',
'password',
'company_id',
'institution'
'institution',
'crew_team'
];

/**
Expand Down Expand Up @@ -85,6 +86,15 @@ public function company(): BelongsTo
return $this->belongsTo(Company::class);
}

/**
* Establishes the relationship between the user and the feedback given by them
* @return HasMany
*/
public function feedback()
{
return $this->hasMany(Feedback::class);
}

/**
* Hides a many-to-many relationship with presentations
* and implements relationship with linking table UserPresentation
Expand Down Expand Up @@ -321,7 +331,7 @@ public function mainRoles()
* @param Builder $query
* @return void
*/
public function scopeSendEmailPreference(Builder $query) : void
public function scopeSendEmailPreference(Builder $query): void
{
$query->where('receive_emails', '=', 1);
}
Expand Down
22 changes: 22 additions & 0 deletions app/Observers/FeedbackObserver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Observers;

use App\Mail\FeedbackReceivedMailable;
use App\Models\Feedback;
use App\Models\User;
use Illuminate\Support\Facades\Mail;

class FeedbackObserver
{
/**
* Handle the Feedback "created" event.
*/
public function created(Feedback $feedback): void
{
$crew = User::where('crew_team', $feedback->type)->get();
foreach ($crew as $user) {
Mail::to($user->email)->send(new FeedbackReceivedMailable($feedback));
}
}
}
41 changes: 41 additions & 0 deletions app/Policies/FeedbackPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Policies;

use App\Models\Feedback;
use App\Models\User;

class FeedbackPolicy
{
/**
* Determines whether the user can create feedback
*
* @param User $user
* @return bool
*/
public function create(User $user)
{
return !$user->is_crew;
}

/**
* Determines whether the user can view any feedback
* @param User $user
* @return bool
*/
public function viewAny(User $user)
{
return $user->can('viewAny feedback');
}

/**
* Determines whether the user can view specific feedback
* @param User $user
* @param Feedback $feedback
* @return bool
*/
public function view(User $user, Feedback $feedback)
{
return $user->can('viewAny feedback');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?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::table('users', function (Blueprint $table) {
$table->enum('crew_team', ['organization', 'website'])->nullable();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('crew_team');
});
}
};
Loading

0 comments on commit 9bdee10

Please sign in to comment.