Refonte de la vue des tickets avec système de suivi + Mail lors de la création d'un ticket
This commit is contained in:
parent
bb1b813ba8
commit
aba21f4f7c
18 changed files with 481 additions and 37 deletions
25
app/Events/TicketStatusChanged.php
Normal file
25
app/Events/TicketStatusChanged.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class TicketStatusChanged
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $ticket, $status;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($ticket, $status)
|
||||
{
|
||||
$this->ticket = $ticket;
|
||||
$this->status = $status;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Events\TicketStatusChanged;
|
||||
use App\Mail\NewTicket;
|
||||
use App\Models\Message;
|
||||
use App\Models\Project;
|
||||
use App\Models\Ticket;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TicketController extends Controller
|
||||
|
|
@ -22,6 +26,15 @@ class TicketController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
public function show($id) {
|
||||
$ticket = Ticket::find($id);
|
||||
$status = $this->status;
|
||||
$messages = $ticket->messages()->orderBy('created_at', 'DESC')->get();
|
||||
if (!$ticket)
|
||||
abort(404);
|
||||
return view('ticket.show', compact('ticket', 'status', 'messages'));
|
||||
}
|
||||
|
||||
public function create() {
|
||||
$projects = Project::all();
|
||||
return view('ticket.create', compact('projects'));
|
||||
|
|
@ -36,19 +49,31 @@ class TicketController extends Controller
|
|||
$type = $request->type;
|
||||
$text = $request->text;
|
||||
$fileTicket = $request->file_ticket;
|
||||
$fileTicket2 = $request->file_ticket2;
|
||||
|
||||
$request->validate([
|
||||
'text' => 'required|string',
|
||||
]);
|
||||
|
||||
$ticketId = Ticket::count() + 1;
|
||||
|
||||
if ($fileTicket !== null) {
|
||||
$request->validate([
|
||||
'file_ticket' => 'mimes:jpeg,jpg,png,pdf|max:2048',
|
||||
]);
|
||||
$projectSlug = Str::slug(Project::find($projectId)->name);
|
||||
$ticketId = Ticket::count() + 1;
|
||||
$fileName = Str::slug($projectSlug) . "-" . ($type === 0 ? "bug" : "evo") . "-" . $ticketId . "." . $fileTicket->extension();
|
||||
$fileName = $projectSlug . "-" . ($type === "0" ? "bug" : "evo") . "-" . $ticketId . "." . $fileTicket->extension();
|
||||
$fileTicket->move(public_path('fichiers/' . $projectSlug . "/" . $ticketId . "/"), $fileName);
|
||||
$filePath = 'fichiers/' . $projectSlug . "/" . $ticketId . "/" . $fileName;
|
||||
}
|
||||
if ($fileTicket2 !== null) {
|
||||
$request->validate([
|
||||
'file_ticket' => 'mimes:jpeg,jpg,png,pdf|max:2048',
|
||||
]);
|
||||
$projectSlug = Str::slug(Project::find($projectId)->name);
|
||||
$fileName2 = $projectSlug . "-" . ($type === "0" ? "bug" : "evo") . "-" . $ticketId . "-2." . $fileTicket2->extension();
|
||||
$fileTicket2->move(public_path('fichiers/' . $projectSlug . "/" . $ticketId . "/"), $fileName2);
|
||||
$filePath2 = 'fichiers/' . $projectSlug . "/" . $ticketId . "/" . $fileName2;
|
||||
}
|
||||
|
||||
$ticket = new Ticket();
|
||||
|
|
@ -56,10 +81,14 @@ class TicketController extends Controller
|
|||
$ticket->type = $type;
|
||||
$ticket->text = $text;
|
||||
if ($fileTicket !== null)
|
||||
$ticket->file = $fileName;
|
||||
$ticket->file = $filePath;
|
||||
if ($fileTicket2 !== null)
|
||||
$ticket->file2 = $filePath2;
|
||||
$ticket->created_by = Auth::user()->id;
|
||||
$ticket->save();
|
||||
|
||||
Mail::to(config('mail.MAIL_ADMIN'))->send(new NewTicket($ticket));
|
||||
|
||||
return redirect()->route('home')->with('success', 'Ticket enregistré !');
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +112,7 @@ class TicketController extends Controller
|
|||
$type = $request->type;
|
||||
$text = $request->text;
|
||||
$fileTicket = $request->file_ticket;
|
||||
$fileTicket2 = $request->file_ticket2;
|
||||
|
||||
$request->validate([
|
||||
'text' => 'required|string',
|
||||
|
|
@ -94,23 +124,88 @@ class TicketController extends Controller
|
|||
$request->validate([
|
||||
'file_ticket' => 'mimes:jpeg,jpg,png,pdf|max:2048',
|
||||
]);
|
||||
if (file_exists(public_path('fichiers/' . $ticket->project->name . '/' . $ticket->id . '/') . $ticket->file))
|
||||
unlink(public_path('fichiers/' . $ticket->project->name . '/' . $ticket->id . '/') . $ticket->file);
|
||||
if ($ticket->file !== null && file_exists(public_path() . $ticket->file))
|
||||
unlink(public_path() . $ticket->file);
|
||||
$projectSlug = Str::slug(Project::find($projectId)->name);
|
||||
$fileName = Str::slug($projectSlug) . "-" . ($type === 0 ? "bug" : "evo") . "-" . $ticket->id . "." . $fileTicket->extension();
|
||||
$fileName = $projectSlug . "-" . ($type === "0" ? "bug" : "evo") . "-" . $ticket->id . "." . $fileTicket->extension();
|
||||
$fileTicket->move(public_path('fichiers/' . $projectSlug . "/" . $ticket->id . "/"), $fileName);
|
||||
$filePath = 'fichiers/' . $projectSlug . "/" . $ticket->id . "/" . $fileName;
|
||||
}
|
||||
if ($fileTicket2 !== null) {
|
||||
$request->validate([
|
||||
'file_ticket2' => 'mimes:jpeg,jpg,png,pdf|max:2048',
|
||||
]);
|
||||
if ($ticket->file2 !== null && file_exists(public_path() . $ticket->file2))
|
||||
unlink(public_path() . $ticket->file2);
|
||||
$projectSlug = Str::slug(Project::find($projectId)->name);
|
||||
$fileName2 = $projectSlug . "-" . ($type === "0" ? "bug" : "evo") . "-" . $ticket->id . "." . $fileTicket2->extension();
|
||||
$fileTicket2->move(public_path('fichiers/' . $projectSlug . "/" . $ticket->id . "/"), $fileName2);
|
||||
$filePath2 = 'fichiers/' . $projectSlug . "/" . $ticket->id . "/" . $fileName2;
|
||||
}
|
||||
|
||||
$ticket->project_id = $projectId;
|
||||
$ticket->type = $type;
|
||||
$ticket->text = $text;
|
||||
if ($fileTicket !== null)
|
||||
$ticket->file = $fileName;
|
||||
if (Auth::user()->role === 1)
|
||||
$ticket->file = $filePath;
|
||||
if ($fileTicket2 !== null)
|
||||
$ticket->file2 = $filePath2;
|
||||
if (Auth::user()->role === 1) {
|
||||
$ticket->status = $status;
|
||||
event(new TicketStatusChanged($ticket, $this->status));
|
||||
}
|
||||
|
||||
$ticket->save();
|
||||
|
||||
return redirect()->route('edit-ticket', $ticket->id)->with('success', 'Modifications enregistrées !');
|
||||
}
|
||||
|
||||
public function changeStatus(Request $request, $id) {
|
||||
$ticket = Ticket::find($id);
|
||||
if (!$ticket)
|
||||
abort(404);
|
||||
$ticket->status = $request->status;
|
||||
$ticket->save();
|
||||
event(new TicketStatusChanged($ticket, $this->status));
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function createMessage(Request $request) {
|
||||
$request->validate([
|
||||
'message' => 'required',
|
||||
]);
|
||||
|
||||
if ($request->file_message !== null) {
|
||||
$request->validate([
|
||||
'file_message' => 'mimes:jpeg,jpg,png,pdf|max:2048',
|
||||
]);
|
||||
}
|
||||
|
||||
$ticketId = $request->ticket_id;
|
||||
$fileMessage = $request->file_message;
|
||||
|
||||
$ticket = Ticket::find($ticketId);
|
||||
|
||||
if (Auth::user()->role !== 1 && (!$ticket || Auth::user()->id !== $ticket->created_by))
|
||||
return back()->withErrors("Les données entrées sont incorrects.");
|
||||
|
||||
$message = new Message();
|
||||
$message->ticket_id = $ticketId;
|
||||
$message->user_id = Auth::user()->id;
|
||||
$message->message = $request->message;
|
||||
$message->save();
|
||||
|
||||
if ($request->file_message !== null) {
|
||||
$projectSlug = Str::slug($ticket->project->name);
|
||||
$fileMessage = $request->file_message;
|
||||
$fileName = $projectSlug . '-ticket-' . $ticket->id . '-message-' . $message->id . '.' . $fileMessage->extension();
|
||||
$fileMessage->move(public_path('fichiers/' . $projectSlug . '/' . $ticket->id . '/'), $fileName);
|
||||
$filePath = 'fichiers/' . $projectSlug . '/' . $ticket->id . '/' . $fileName;
|
||||
$message->file = $filePath;
|
||||
$message->save();
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
33
app/Listeners/AddStatusMessages.php
Normal file
33
app/Listeners/AddStatusMessages.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Events\TicketStatusChanged;
|
||||
use App\Models\Message;
|
||||
|
||||
class AddStatusMessages
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TicketStatusChanged $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(TicketStatusChanged $event)
|
||||
{
|
||||
$message = new Message();
|
||||
$message->ticket_id = $event->ticket->id;
|
||||
$message->message = "Le status est passé à : " . $event->status[$event->ticket->status];
|
||||
$message->save();
|
||||
}
|
||||
}
|
||||
36
app/Mail/NewTicket.php
Normal file
36
app/Mail/NewTicket.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class NewTicket extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $ticket;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($ticket)
|
||||
{
|
||||
$this->ticket = $ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$ticket = $this->ticket;
|
||||
return $this->subject("[SupportWeb] Nouveau ticket n°" . $ticket->id)->view('mails.new-ticket', compact('ticket'));
|
||||
}
|
||||
}
|
||||
19
app/Models/Message.php
Normal file
19
app/Models/Message.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Message extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public function ticket() {
|
||||
return $this->belongsTo('App\Models\Ticket', 'ticket_id');
|
||||
}
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo('App\Models\User', 'user_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -16,4 +16,8 @@ class Ticket extends Model
|
|||
public function user() {
|
||||
return $this->belongsTo('App\Models\User', 'created_by');
|
||||
}
|
||||
|
||||
public function messages() {
|
||||
return $this->hasMany('App\Models\Message', 'ticket_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,4 +44,8 @@ class User extends Authenticatable
|
|||
public function tickets() {
|
||||
return $this->hasMany("App\Models\Ticket", 'created_by');
|
||||
}
|
||||
|
||||
public function messages() {
|
||||
return $this->hasMany('App\Models\Messages', 'user_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ class EventServiceProvider extends ServiceProvider
|
|||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
'App\Events\TicketStatusChanged' => [
|
||||
'App\Listeners\AddStatusMessages',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ return [
|
|||
|
||||
'default' => env('MAIL_MAILER', 'smtp'),
|
||||
|
||||
// Mail admin
|
||||
'MAIL_ADMIN' => env('MAIL_ADMIN'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mailer Configurations
|
||||
|
|
|
|||
35
database/migrations/2020_11_25_104931_create_messages.php
Normal file
35
database/migrations/2020_11_25_104931_create_messages.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateMessages extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('messages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('ticket_id')->constrained('tickets');
|
||||
$table->foreignId('user_id')->nullable()->constrained('users');
|
||||
$table->text('message');
|
||||
$table->string('file')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('messages');
|
||||
}
|
||||
}
|
||||
32
database/migrations/2020_11_25_141438_alter_tickets.php
Normal file
32
database/migrations/2020_11_25_141438_alter_tickets.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AlterTickets extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('tickets', function(Blueprint $table) {
|
||||
$table->string('file2')->nullable()->after('file');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('tickets', function(Blueprint $table) {
|
||||
$table->dropColumn('file2');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
@section('tickets', 'active')
|
||||
|
||||
@section('content')
|
||||
<div class="container content">
|
||||
<div class="container">
|
||||
@auth
|
||||
<h2>Gestion des tickets<a href="{{ route('create-ticket') }}" class="float-right btn btn-sm btn-primary">Créer un ticket</a></h2>
|
||||
<table class="table table-hover">
|
||||
|
|
@ -11,11 +11,12 @@
|
|||
<th scope="col">#</th>
|
||||
<th scope="col">Projet</th>
|
||||
<th scope="col">Type</th>
|
||||
<th scope="col">Description</th>
|
||||
<th scope="col">Fichier</th>
|
||||
<th scope="col">Fichier 2</th>
|
||||
<th scope="col">Date de création</th>
|
||||
<th scope="col">Créer par</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Contenu</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -23,10 +24,36 @@
|
|||
@if (Auth::user()->project_id === $ticket->project->id || Auth::user()->role === 1)
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<a href="{{ route('show-ticket', $ticket->id) }}" class="btn btn-sm btn-outline-secondary">{{ $ticket->id }}</a>
|
||||
</th>
|
||||
<td>{{ $ticket->project->name }}</td>
|
||||
<td>
|
||||
@if ($ticket->type === 0)
|
||||
<span class="badge badge-danger">Bug</span>
|
||||
@else
|
||||
<span class="badge badge-success">Évolution</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($ticket->file !== null)
|
||||
<a href="{{ asset($ticket->file) }}"
|
||||
class="btn btn-sm btn-outline-secondary" target="_blank">Fichier</a>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($ticket->file2 !== null)
|
||||
<a href="{{ asset($ticket->file2) }}"
|
||||
class="btn btn-sm btn-outline-secondary" target="_blank">Fichier 2</a>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ Carbon\Carbon::parse($ticket->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
<td>{{ $ticket->user->name }}</td>
|
||||
<td>{{ $status[$ticket->status] }}</td>
|
||||
<td>
|
||||
{{-- Modal du ticket --}}
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" data-toggle="modal" data-target="#ticket{{ $ticket->id }}Modal">
|
||||
{{ $ticket->id }}
|
||||
Aperçu
|
||||
</button>
|
||||
|
||||
<!-- Modal -->
|
||||
|
|
@ -43,12 +70,6 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{!! nl2br(e($ticket->text)) !!}</p>
|
||||
@if ($ticket->file !== null)
|
||||
<hr>
|
||||
<img src="{{ asset('fichiers/' . Str::slug($ticket->project->name) . '/' . $ticket->id . '/' . $ticket->file) }}" style="max-width: 100%;">
|
||||
<br>
|
||||
<a href="{{ asset('fichiers/' . Str::slug($ticket->project->name) . '/' . $ticket->id . '/' . $ticket->file) }}" target="_blank">Ouvrir dans un nouvel onglet</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal">Fermer</button>
|
||||
|
|
@ -56,25 +77,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td>{{ $ticket->project->name }}</td>
|
||||
<td>
|
||||
@if ($ticket->type === 0)
|
||||
<span class="badge badge-danger">Bug</span>
|
||||
@else
|
||||
<span class="badge badge-success">Évolution</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ \Illuminate\Support\Str::limit($ticket->text, 40, '...') }}</td>
|
||||
<td>
|
||||
@if ($ticket->file !== null)
|
||||
<a href="{{ asset('fichiers/' . Str::slug($ticket->project->name) . '/' . $ticket->id . '/' . $ticket->file) }}"
|
||||
class="btn btn-sm btn-outline-secondary" target="_blank">Fichier</a>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ Carbon\Carbon::parse($ticket->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
<td>{{ $ticket->user->name }}</td>
|
||||
<td>{{ $status[$ticket->status] }}</td>
|
||||
<td>
|
||||
@if ($ticket->created_by === Auth::user()->id || Auth::user()->role === 1)
|
||||
<a href="{{ route('edit-ticket', $ticket->id) }}" class="btn btn-sm btn-outline-primary">Modifier</a>
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@yield('content')
|
||||
<div class="content">
|
||||
@yield('content')
|
||||
</div>
|
||||
<script src="{{ asset('js/app.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
12
resources/views/mails/new-ticket.blade.php
Normal file
12
resources/views/mails/new-ticket.blade.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<p>Bonjour,</p>
|
||||
<p>Un nouveau ticket (n°{{ $ticket->id }}) a été créer sur le support web :</p>
|
||||
<ul>
|
||||
<li>Projet : {{ $ticket->project->name }}</li>
|
||||
<li>Type : {{ $ticket->type === 0 ? "Bug" : "Évolution" }}</li>
|
||||
<li>Créer par : {{ $ticket->user->name }}</li>
|
||||
</ul>
|
||||
<p>
|
||||
Description :<br>
|
||||
{!! nl2br(e($ticket->text)) !!}
|
||||
</p>
|
||||
<p>Lien vers le ticket : <a href="{{ route('show-ticket', $ticket->id) }}" traget="_blank">Ouvrir dans un nouvel onglet</a></p>
|
||||
|
|
@ -52,6 +52,9 @@
|
|||
<div class="form-group">
|
||||
<input type="file" name="file_ticket" accept="image/png, image/jpeg, image/jpg, .pdf">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="file" name="file_ticket2" accept="image/png, image/jpeg, image/jpg, .pdf">
|
||||
</div>
|
||||
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" class="btn btn-primary" value="Enregistrer">
|
||||
|
|
|
|||
|
|
@ -70,7 +70,17 @@
|
|||
@if ($ticket->file !== null)
|
||||
<hr>
|
||||
<div class="text-center">
|
||||
<img src="{{ asset('fichiers/' . Str::slug($ticket->project->name) . '/' . $ticket->id . '/' . $ticket->file) }}" style="max-width: 100%;">
|
||||
<img src="{{ asset($ticket->file) }}" style="max-width: 100%;">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="file" name="file_ticket2" accept="image/png, image/jpeg, image/jpg, .pdf">
|
||||
@if ($ticket->file2 !== null)
|
||||
<hr>
|
||||
<div class="text-center">
|
||||
<img src="{{ asset($ticket->file2) }}" style="max-width: 100%;">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
|||
122
resources/views/ticket/show.blade.php
Normal file
122
resources/views/ticket/show.blade.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="form-row">
|
||||
<h2 class="col-md-10">
|
||||
<a href="{{ route('home') }}" class="text-decoration-none">←</a>
|
||||
Ticket n°{{ $ticket->id }} : {{ $ticket->project->name }} - {{ $ticket->type === 0 ? "Bug" : "Évolution" }}
|
||||
@if (Auth::user()->role !== 1)
|
||||
<span class="badge badge-secondary">{{ $status[$ticket->status] }}</span>
|
||||
@endif
|
||||
</h2>
|
||||
@if (Auth::user()->role === 1)
|
||||
<form action="{{ route('change-status-ticket', $ticket->id) }}" method="POST" id="form_status" class="col-md-2">
|
||||
@csrf
|
||||
<select class="custom-select" name="status" id="status" onchange="$('#form_status').submit();">
|
||||
@for ($i = 1; $i < count($status) + 1; $i++)
|
||||
<option value="{{ $i }}" @if ($ticket->status === $i) selected @endif>{{ $status[$i] }}</option>
|
||||
@endfor
|
||||
</select>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<h4>
|
||||
Suivi
|
||||
@if (Auth::user()->id === $ticket->created_by || Auth::user()->role === 1)
|
||||
<button type="button" class="btn btn-sm btn-primary float-right" data-toggle="modal" data-target="#messageModal">
|
||||
Répondre
|
||||
</button>
|
||||
|
||||
{{-- Modal --}}
|
||||
<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form action="{{ route('create-message') }}" method="POST" enctype="multipart/form-data">
|
||||
@method('PUT')
|
||||
@csrf
|
||||
<input type="hidden" name="ticket_id" value="{{ $ticket->id }}">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="messageModalLabel">
|
||||
Répondre au ticket n°{{ $ticket->id }}
|
||||
</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea name="message" class="form-control" rows="10"></textarea><br>
|
||||
<input type="file" name="file_message" accept="image/jpeg, image/png, image/jpg, .pdf">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-sm btn-danger" data-dismiss="modal">Fermer</button>
|
||||
<button type="submit" class="btn btn-sm btn-success">Envoyer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Fin modal --}}
|
||||
@endif
|
||||
</h4>
|
||||
@foreach ($messages as $message)
|
||||
@if ($message->user_id === null)
|
||||
<div class="offset-md-3 col-md-6 alert alert-secondary text-center">
|
||||
{!! nl2br(e($message->message)) !!} - Le {{ \Carbon\Carbon::parse($message->created_at)->format('d/m/Y à H:i')}} <small class="text-muted">(Message système)</small>
|
||||
</div>
|
||||
@elseif ($message->user_id === Auth::user()->id)
|
||||
<div class="offset-md-4 col-md-8 alert alert-primary text-right">
|
||||
{!! nl2br(e($message->message)) !!}<br>
|
||||
@if ($message->file !== null)
|
||||
<a href="{{ asset($message->file) }}" target="_blank">Ouvrir la pièce jointe dans un nouvel onglet</a><br>
|
||||
@endif
|
||||
<small class="text-muted">Le {{ \Carbon\Carbon::parse($message->created_at)->format('d/m/Y à H:i')}} par {{ $message->user->name }}</small>
|
||||
</div>
|
||||
@else
|
||||
<div class="col-md-8 alert alert-success text-left">
|
||||
{!! nl2br(e($message->message)) !!}<br>
|
||||
@if ($message->file !== null)
|
||||
<a href="{{ asset($message->file) }}" target="_blank">Ouvrir la pièce jointe dans un nouvel onglet</a><br>
|
||||
@endif
|
||||
<small class="text-muted">Le {{ \Carbon\Carbon::parse($message->created_at)->format('d/m/Y à H:i')}} par {{ $message->user->name }}</small>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
<h4>Description</h4>
|
||||
<p>{!! nl2br(e($ticket->text)) !!}</p>
|
||||
<small class="text-muted">Créer le {{ \Carbon\Carbon::parse($ticket->created_at)->format('d/m/Y à H:i') }}</small>
|
||||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
<h4>Pièces jointes</h4>
|
||||
<ul>
|
||||
@if ($ticket->file !== null)
|
||||
<li>
|
||||
Pièce jointe n°1 :
|
||||
<a href="{{ asset($ticket->file) }}" target="_blank">Ouvrir la pièce jointe</a>
|
||||
</li>
|
||||
@endif
|
||||
@if ($ticket->file2 !== null)
|
||||
<li>
|
||||
Pièce jointe n°2 :
|
||||
<a href="{{ asset($ticket->file2) }}" target="_blank">Ouvrir la pièce jointe</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -26,6 +26,9 @@ Route::middleware(['auth'])->group(function () {
|
|||
Route::put('/ticket/create', [TicketController::class, 'store'])->name('store-ticket');
|
||||
Route::get('/ticket/{id}/edit', [TicketController::class, 'edit'])->name('edit-ticket');
|
||||
Route::post('/ticket/{id}/edit', [TicketController::class, 'update'])->name('update-ticket');
|
||||
Route::get('/ticket/{id}', [TicketController::class, 'show'])->name('show-ticket');
|
||||
Route::post('/ticket/change-status/{id}', [TicketController::class, 'changeStatus'])->name('change-status-ticket');
|
||||
Route::put('/ticket/message/create', [TicketController::class, 'createMessage'])->name('create-message');
|
||||
// Projets (admin)
|
||||
Route::middleware(['is-admin'])->group(function () {
|
||||
Route::get('/projects', [ProjectController::class, 'index'])->name('projects');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue