소스 검색

Ticket System

SahrulGnwn 2 년 전
부모
커밋
94bbea2690
27개의 변경된 파일1391개의 추가작업 그리고 2개의 파일을 삭제
  1. 62 0
      app/Http/Controllers/Mod/TicketsController.php
  2. 84 0
      app/Http/Controllers/TicketsController.php
  3. 2 0
      app/Http/Kernel.php
  4. 27 0
      app/Http/Middleware/isMod.php
  5. 21 0
      app/Models/Ticket.php
  6. 13 0
      app/Models/TicketCategory.php
  7. 21 0
      app/Models/TicketComment.php
  8. 71 0
      app/Notifications/Ticket/Admin/AdminCreateNotification.php
  9. 78 0
      app/Notifications/Ticket/Admin/AdminReplyNotification.php
  10. 68 0
      app/Notifications/Ticket/User/CreateNotification.php
  11. 78 0
      app/Notifications/Ticket/User/ReplyNotification.php
  12. 39 0
      database/migrations/2022_08_01_170819_create_tickets_table.php
  13. 59 0
      database/migrations/2022_08_01_171633_create_ticketcategories_table.php
  14. 34 0
      database/migrations/2022_08_01_181607_create_ticketcomments_table.php
  15. 3 0
      resources/views/admin/users/edit.blade.php
  16. 1 1
      resources/views/admin/users/show.blade.php
  17. 17 0
      resources/views/layouts/main.blade.php
  18. 25 0
      resources/views/mail/ticket/admin/create.blade.php
  19. 25 0
      resources/views/mail/ticket/admin/reply.blade.php
  20. 13 0
      resources/views/mail/ticket/user/create.blade.php
  21. 18 0
      resources/views/mail/ticket/user/reply.blade.php
  22. 104 0
      resources/views/mod/ticket/index.blade.php
  23. 141 0
      resources/views/mod/ticket/show.blade.php
  24. 127 0
      resources/views/ticket/create.blade.php
  25. 100 0
      resources/views/ticket/index.blade.php
  26. 141 0
      resources/views/ticket/show.blade.php
  27. 19 1
      routes/web.php

+ 62 - 0
app/Http/Controllers/Mod/TicketsController.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Http\Controllers\Mod;
+
+use App\Models\User;
+use App\Models\Ticket;
+use App\Models\Server;
+use App\Models\TicketCategory;
+use App\Models\TicketComment;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use App\Notifications\Ticket\User\ReplyNotification;
+
+class TicketsController extends Controller
+{
+    public function index() {
+        $tickets = Ticket::paginate(10);
+        $ticketcategories = TicketCategory::all();
+        return view("admin.ticket.index", compact("tickets", "ticketcategories"));
+    }
+    public function show($ticket_id) {
+        $ticket = Ticket::where("ticket_id", $ticket_id)->firstOrFail();
+        $ticketcomments = $ticket->ticketcomments;
+        $ticketcategory = $ticket->ticketcategory;
+        $server = Server::where('id', $ticket->server)->first();
+        return view("admin.ticket.show", compact("ticket", "ticketcategory", "ticketcomments", "server"));
+    }
+
+    public function close($ticket_id) {
+        $ticket = Ticket::where("ticket_id", $ticket_id)->firstOrFail();
+        $ticket->status = "Closed";
+        $ticket->save();
+        $ticketOwner = $ticket->user;
+        return redirect()->back()->with('success', __('A ticket has been closed, ID: #') . $ticket->ticket_id);
+    }
+
+    public function delete($ticket_id){
+        $ticket = Ticket::where("ticket_id", $ticket_id)->firstOrFail();
+        TicketComment::where("ticket_id", $ticket->id)->delete();
+        $ticket->delete();
+        return redirect()->back()->with('success', __('A ticket has been deleted, ID: #') . $ticket_id);
+        
+    }
+    public function reply(Request $request) {
+        $this->validate($request, array("ticketcomment" => "required"));
+        $ticket = Ticket::where('id', $request->input("ticket_id"))->firstOrFail();
+        $ticket->status = "Answered";
+        $ticket->update();
+        $ticketcomment = TicketComment::create(array(
+        	"ticket_id" => $request->input("ticket_id"), 
+        	"user_id" => Auth::user()->id, 
+        	"ticketcomment" => $request->input("ticketcomment"), 
+        ));
+        $user = User::where('id', $ticket->user_id)->firstOrFail();
+        $newmessage = $request->input("ticketcomment");
+        $user->notify(new ReplyNotification($ticket, $user, $newmessage)); 
+        return redirect()->back()->with('success', __('Your comment has been submitted'));
+    }
+}

+ 84 - 0
app/Http/Controllers/TicketsController.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\User;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Session;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Str;
+use Illuminate\Support\Facades\Notification;
+
+use App\Models\Ticket;
+use App\Models\Server;
+use App\Models\TicketComment;
+use App\Models\TicketCategory;
+use App\Notifications\Ticket\User\CreateNotification;
+use App\Notifications\Ticket\Admin\AdminCreateNotification;
+use App\Notifications\Ticket\Admin\AdminReplyNotification;
+
+
+class TicketsController extends Controller
+{
+    public function index()
+    {
+        $tickets = Ticket::where("user_id", Auth::user()->id)->paginate(10); 
+        $ticketcategories = TicketCategory::all();
+        
+        return view("ticket.index", compact("tickets", "ticketcategories"));
+    }
+    public function create() {
+        $ticketcategories = TicketCategory::all();
+        $servers = Auth::user()->servers;
+        return view("ticket.create", compact("ticketcategories", "servers"));
+    }
+    public function store(Request $request) {
+        $this->validate($request, array(
+        	"title" => "required", 
+        	"ticketcategory" => "required", 
+        	"priority" => "required", 
+        	"message" => "required")
+    	);
+        $ticket = new Ticket(array(
+        	"title" => $request->input("title"), 
+        	"user_id" => Auth::user()->id, 
+        	"ticket_id" => strtoupper(Str::random(5)), 
+        	"ticketcategory_id" => $request->input("ticketcategory"), 
+        	"priority" => $request->input("priority"), 
+        	"message" => $request->input("message"), 
+        	"status" => "Open",
+            "server" => $request->input("server"))
+   		);
+        $ticket->save();
+        $user = Auth::user();
+        $admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
+        $user->notify(new CreateNotification($ticket));
+        Notification::send($admin, new AdminCreateNotification($ticket, $user));
+        
+        return redirect()->route('ticket.index')->with('success', __('A ticket has been opened, ID: #') . $ticket->ticket_id);
+    }
+    public function show($ticket_id) {
+        $ticket = Ticket::where("ticket_id", $ticket_id)->firstOrFail();
+        $ticketcomments = $ticket->ticketcomments;
+        $ticketcategory = $ticket->ticketcategory;
+        $server = Server::where('id', $ticket->server)->first();
+        return view("ticket.show", compact("ticket", "ticketcategory", "ticketcomments", "server"));
+    }
+    public function reply(Request $request) {
+        $this->validate($request, array("ticketcomment" => "required"));
+        $ticket = Ticket::where('id', $request->input("ticket_id"))->firstOrFail();
+        $ticket->status = "Client Reply";
+        $ticket->update();
+        $ticketcomment = TicketComment::create(array(
+        	"ticket_id" => $request->input("ticket_id"), 
+        	"user_id" => Auth::user()->id, 
+        	"ticketcomment" => $request->input("ticketcomment"), 
+        	"message" => $request->input("message")
+        ));
+        $user = Auth::user();
+        $admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
+        $newmessage = $request->input("ticketcomment");
+        Notification::send($admin, new AdminReplyNotification($ticket, $user, $newmessage));
+        return redirect()->back()->with('success', __('Your comment has been submitted'));
+    }
+}

+ 2 - 0
app/Http/Kernel.php

@@ -6,6 +6,7 @@ use App\Http\Middleware\ApiAuthToken;
 use App\Http\Middleware\CheckSuspended;
 use App\Http\Middleware\GlobalNames;
 use App\Http\Middleware\isAdmin;
+use App\Http\Middleware\isMod;
 use App\Http\Middleware\LastSeen;
 use Illuminate\Foundation\Http\Kernel as HttpKernel;
 
@@ -72,6 +73,7 @@ class Kernel extends HttpKernel
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
         'admin' => isAdmin::class,
+        'mod' => isMod::class,
         'api.token' => ApiAuthToken::class,
         'checkSuspended' => CheckSuspended::class
     ];

+ 27 - 0
app/Http/Middleware/isMod.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Providers\RouteServiceProvider;
+use Closure;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+
+class isMod
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param Request $request
+     * @param Closure $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        if (Auth::user() && Auth::user()->role == 'mod' || Auth::user() && Auth::user()->role == 'admin') {
+            return $next($request);
+        }
+
+        return redirect(RouteServiceProvider::HOME);
+    }
+}

+ 21 - 0
app/Models/Ticket.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Ticket extends Model {
+    protected $fillable = [
+        'user_id', 'ticketcategory_id', 'ticket_id', 'title', 'priority', 'message', 'status', 'server'
+    ];
+
+    public function ticketcategory(){
+    return $this->belongsTo(TicketCategory::class);}
+
+    public function ticketcomments(){
+    return $this->hasMany(TicketComment::class);}
+
+    public function user(){
+    return $this->belongsTo(User::class);}
+} 
+  

+ 13 - 0
app/Models/TicketCategory.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class TicketCategory extends Model {
+    protected $fillable = ['name'];
+    
+    public function tickets(){
+    return $this->hasMany(Ticket::class);}
+}
+ 

+ 21 - 0
app/Models/TicketComment.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class TicketComment extends Model {
+protected $fillable = [
+    'ticket_id', 'user_id', 'ticketcomment'
+];
+
+    public function ticketcategory(){
+    return $this->belongsTo(TicketCategory::class);}
+
+    public function ticket(){
+    return $this->belongsTo(Ticket::class);}
+
+    public function user(){
+    return $this->belongsTo(User::class);}
+}
+ 

+ 71 - 0
app/Notifications/Ticket/Admin/AdminCreateNotification.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Notifications\Ticket\Admin;
+
+use App\Models\Ticket;
+use App\Models\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class AdminCreateNotification extends Notification implements ShouldQueue
+{
+
+    //THIS IS BASICALLY NOT USED ANYMORE WITH INVOICENOTIFICATION IN PLACE
+
+    use Queueable;
+
+    private Ticket $ticket;
+    private User $user;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @return void
+     */
+    public function __construct(Ticket $ticket, User $user)
+    {
+        $this->ticket = $ticket;
+        $this->user   = $user;
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        $via = ['mail','database'];
+        return $via;
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return MailMessage
+     */
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject('[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title)
+            ->markdown('mail.ticket.admin.create' , ['ticket' => $this->ticket, 'user' => $this->user]);
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'title'   => '[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title,
+            'content' => "Ticket With ID : {$this->ticket->ticket_id} has been opened by <strong>{$this->user->name}</strong>",
+        ];
+    }
+}

+ 78 - 0
app/Notifications/Ticket/Admin/AdminReplyNotification.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Notifications\Ticket\Admin;
+
+use App\Models\Ticket;
+use App\Models\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class AdminReplyNotification extends Notification implements ShouldQueue
+{
+
+    //THIS IS BASICALLY NOT USED ANYMORE WITH INVOICENOTIFICATION IN PLACE
+
+    use Queueable;
+
+    private Ticket $ticket;
+    private User $user;
+    private $newmessage;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @return void
+     */
+    public function __construct(Ticket $ticket, User $user, $newmessage)
+    {
+        $this->ticket     = $ticket;
+        $this->user       = $user;
+        $this->newmessage = $newmessage;
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        $via = ['mail','database'];
+        return $via;
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return MailMessage
+     */
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject('[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title)
+            ->markdown('mail.ticket.admin.reply' , ['ticket' => $this->ticket, 'user' => $this->user, 'newmessage' => $this->newmessage]);
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'title'   => '[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title,
+            'content' => "
+                <p>Ticket With ID : {$this->ticket->ticket_id} has had a new reply posted by <strong>{$this->user->name}</strong></p>
+                <br>
+                <p><strong>Message:</strong></p>
+                <p>{$this->newmessage}</p>
+            ",
+        ];
+    }
+}

+ 68 - 0
app/Notifications/Ticket/User/CreateNotification.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace App\Notifications\Ticket\User;
+
+use App\Models\Ticket;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class CreateNotification extends Notification implements ShouldQueue
+{
+
+    //THIS IS BASICALLY NOT USED ANYMORE WITH INVOICENOTIFICATION IN PLACE
+
+    use Queueable;
+
+    private Ticket $ticket;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @return void
+     */
+    public function __construct(Ticket $ticket)
+    {
+        $this->ticket = $ticket;
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        $via = ['mail','database'];
+        return $via;
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return MailMessage
+     */
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject('[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title)
+            ->markdown('mail.ticket.user.create' , ['ticket' => $this->ticket]);
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'title'   => '[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title,
+            'content' => "Your Ticket has been Created With ID : {$this->ticket->ticket_id}",
+        ];
+    }
+}

+ 78 - 0
app/Notifications/Ticket/User/ReplyNotification.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Notifications\Ticket\User;
+
+use App\Models\User;
+use App\Models\Ticket;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class ReplyNotification extends Notification implements ShouldQueue
+{
+
+    //THIS IS BASICALLY NOT USED ANYMORE WITH INVOICENOTIFICATION IN PLACE
+
+    use Queueable;
+
+    private Ticket $ticket;
+    private User $user;
+    private $newmessage;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @return void
+     */
+    public function __construct(Ticket $ticket, User $user, $newmessage)
+    {
+        $this->ticket     = $ticket;
+        $this->user       = $user;
+        $this->newmessage = $newmessage;
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        $via = ['mail','database'];
+        return $via;
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return MailMessage
+     */
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject('[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title)
+            ->markdown('mail.ticket.user.reply' , ['ticket' => $this->ticket, 'user' => $this->user, 'newmessage' => $this->newmessage]);
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'title'   => '[Ticket ID: ' . $this->ticket->ticket_id . '] ' . $this->ticket->title,
+            'content' => "
+                <p>Ticket With ID : {$this->ticket->ticket_id} A response has been added to your ticket. Please see below for our response!</p>
+                <br>
+                <p><strong>Message:</strong></p>
+                <p>{$this->newmessage}</p>
+            ",
+        ];
+    }
+}

+ 39 - 0
database/migrations/2022_08_01_170819_create_tickets_table.php

@@ -0,0 +1,39 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateTicketsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */ 
+    public function up()
+    {
+        Schema::create('tickets', function (Blueprint $table) {
+            $table->increments('id');
+            $table->integer('user_id')->unsigned();
+            $table->integer('ticketcategory_id')->unsigned();
+            $table->string('ticket_id')->unique();
+            $table->string('title');
+            $table->string('priority');
+            $table->text('message');
+            $table->string('status');
+            $table->string('server')->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('tickets');
+    }
+}

+ 59 - 0
database/migrations/2022_08_01_171633_create_ticketcategories_table.php

@@ -0,0 +1,59 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateTicketCategoriesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void 
+     */
+    public function up()
+    {
+        Schema::create('ticket_categories', function (Blueprint $table) {
+            $table->increments('id');
+               $table->string('name');
+            $table->timestamps();
+        });
+
+        DB::table('ticket_categories')->insert(
+            array(
+                'name' => 'Technical',
+            )
+        );
+        DB::table('ticket_categories')->insert(
+            array(
+                'name' => 'Billing',
+            )
+        );
+        DB::table('ticket_categories')->insert(
+            array(
+                'name' => 'Issue',
+            )
+        );
+        DB::table('ticket_categories')->insert(
+            array(
+                'name' => 'Request',
+            )
+        );
+        DB::table('ticket_categories')->insert(
+            array(
+                'name' => 'Other',
+            )
+        );
+    }
+    
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('ticket_categories');
+    }
+}

+ 34 - 0
database/migrations/2022_08_01_181607_create_ticketcomments_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateTicketCommentsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void 
+     */
+    public function up()
+    {
+        Schema::create('ticket_comments', function (Blueprint $table) {
+            $table->increments('id');
+            $table->integer('ticket_id')->unsigned();
+            $table->integer('user_id')->unsigned();
+            $table->text('ticketcomment');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('ticket_comments');
+    }
+}

+ 3 - 0
resources/views/admin/users/edit.blade.php

@@ -104,6 +104,9 @@
                                                     value="admin">
                                         {{__(' Administrator')}}
                                      </option>
+                                     <option @if($user->role == 'mod') selected @endif class="text-info" value="mod">
+                                        {{__(' Moderator')}}
+                                     </option>
                                      <option @if($user->role == 'client') selected @endif class="text-success"
                                              value="client">
                                         {{__('Client')}}

+ 1 - 1
resources/views/admin/users/show.blade.php

@@ -72,7 +72,7 @@
                                 </div>
                                 <div class="col-lg-8">
                                        <span style="max-width: 250px;"
-                                             class="d-inline-block text-truncate badge {{$user->role == 'admin' ? 'badge-info' : 'badge-secondary'}}">
+                                             class="d-inline-block text-truncate badge {{$user->role == 'admin' || $user->role == 'mod' ? 'badge-info' : 'badge-secondary'}}">
                                            {{$user->role}}
                                        </span>
                                 </div>

+ 17 - 0
resources/views/layouts/main.blade.php

@@ -225,7 +225,24 @@
                                 </a>
                             </li>
                         @endif
+                        <li class="nav-item">
+                            <a href="{{ route('ticket.index') }}" class="nav-link @if (Request::routeIs('ticket.*')) active @endif">
+                                <i class="nav-icon fas fas fa-ticket-alt"></i>
+                                <p>{{ __('Support Ticket') }}</p> 
+                            </a>
+                        </li>
+
+                        @if (Auth::user()->role == 'admin' || Auth::user()->role == 'mod')
+                            <li class="nav-header">{{ __('Moderation') }}</li>
 
+                            <li class="nav-item">
+                                <a href="{{ route('mod.ticket.index') }}" class="nav-link @if (Request::routeIs('mod.ticket.*')) active @endif">
+                                    <i class="nav-icon fas fa-ticket-alt"></i>
+                                    <p>{{ __('Ticket List') }}</p> 
+                                </a>
+                            </li>
+                        @endif
+                        
                         @if (Auth::user()->role == 'admin')
 
                             <li class="nav-header">{{ __('Administration') }}</li>

+ 25 - 0
resources/views/mail/ticket/admin/create.blade.php

@@ -0,0 +1,25 @@
+@component('mail::message')
+Ticket #{{$ticket->ticket_id}} has been opened by **{{$user->name}}**
+
+### Details:
+Client: {{$user->name}} <br>
+Subject: {{$ticket->title}} <br>
+Category: {{ $ticket->ticketcategory->name }} <br>
+Priority: {{ $ticket->priority }} <br>
+Status: {{ $ticket->status }} <br>
+
+___
+```
+{{ $ticket->message }}
+```
+___
+<br>
+You can respond to this ticket by simply replying to this email or through the admin area at the url below.
+<br>
+
+{{ route('mod.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
+
+<br>
+{{__('Thanks')}},<br>
+{{ config('app.name') }}
+@endcomponent

+ 25 - 0
resources/views/mail/ticket/admin/reply.blade.php

@@ -0,0 +1,25 @@
+@component('mail::message')
+Ticket #{{$ticket->ticket_id}} has had a new reply posted by **{{$user->name}}**
+
+### Details
+Client: {{$user->name}} <br>
+Subject: {{$ticket->title}} <br>
+Category: {{ $ticket->ticketcategory->name }} <br>
+Priority: {{ $ticket->priority }} <br>
+Status: {{ $ticket->status }} <br>
+
+___
+```
+{{ $newmessage }}
+```
+___
+<br>
+You can respond to this ticket by simply replying to this email or through the admin area at the url below.
+<br>
+
+{{ route('mod.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}
+
+<br>
+{{__('Thanks')}},<br>
+{{ config('app.name') }}
+@endcomponent

+ 13 - 0
resources/views/mail/ticket/user/create.blade.php

@@ -0,0 +1,13 @@
+@component('mail::message')
+Hello {{$ticket->user->name}},
+
+This is a notification that we have received your support request, and your ticket number is **#{{$ticket->ticket_id}}**.
+
+We will be responding to this ticket as soon as possible. If this is a Setup request, please understand that these requests take longer than regular support timeframes. Please be aware that Setups may take up to 48 hours to be completed. 
+
+Thank you so much for being so understanding. 
+
+<br>
+{{__('Thanks')}},<br>
+{{ config('app.name') }}
+@endcomponent

+ 18 - 0
resources/views/mail/ticket/user/reply.blade.php

@@ -0,0 +1,18 @@
+@component('mail::message')
+A response has been added to your ticket. Please see below for our response!
+
+### Details
+Ticket ID : {{ $ticket->ticket_id }} <br>
+Subject: {{ $ticket->title }} <br>
+Status: {{ $ticket->status }} <br>
+
+___
+```
+{{ $newmessage }}
+```
+___
+<br>
+<br>
+{{__('Thanks')}},<br>
+{{ config('app.name') }}
+@endcomponent

+ 104 - 0
resources/views/mod/ticket/index.blade.php

@@ -0,0 +1,104 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{__('Ticket')}}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{route('mod.ticket.index')}}">{{__('Ticket List')}}</a></li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER --> 
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+
+            <div class="card">
+
+                <div class="card-header">
+                    <div class="d-flex justify-content-between">
+                        <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('Ticket List')}}</h5>
+                    </div>
+                </div>
+
+                <div class="card-body table-responsive">
+
+                    <table id="datatable" class="table table-striped">
+                        <thead>
+                        <tr>
+                            <th>Category</th>
+                            <th>Title</th>
+                            <th>User</th>
+                            <th>Status</th>
+                            <th>Last Updated</th>
+                            <th>Actions</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                            @foreach ($tickets as $ticket)
+                                <tr>
+                                    <td>
+                                        {{ $ticket->ticketcategory->name }}
+                                    </td>
+                                    <td>
+                                        <a href="{{ route('mod.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}">
+                                            #{{ $ticket->ticket_id }} - {{ $ticket->title }}
+                                        </a>
+                                    </td>
+                                    <td>
+                                        <a href="/admin/users/{{$ticket->user->id}}">
+                                            {{ $ticket->user->name }}
+                                        </a>
+                                    </td>
+                                    <td>
+                                        @if ($ticket->status === 'Open')
+                                        <span class="badge badge-success">Open</span>
+                                        @elseif ($ticket->status === 'Closed')
+                                        <span class="badge badge-danger">Closed</span>
+                                        @elseif ($ticket->status === 'Answered')
+                                        <span class="badge badge-info">Answered</span>
+                                        @elseif ($ticket->status === 'Client Reply')
+                                        <span class="badge badge-warning">Client Reply</span>
+                                        @endif
+                                    </td>
+                                    <td>{{ $ticket->updated_at }}</td>
+                                    <td>
+                                        <a data-content="View" data-toggle="popover" data-trigger="hover" data-placement="top" href="{{ route('mod.ticket.show', ['ticket_id' => $ticket->ticket_id]) }}" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
+                                        <form class="d-inline" action="{{ route('mod.ticket.close', ['ticket_id' => $ticket->ticket_id ]) }}" method="POST">
+                                        @csrf
+                                        <button data-content="Close" data-toggle="popover" data-trigger="hover" data-placement="top" type="submit" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-times"></i></button>
+                                        </form>
+                                        <form class="d-inline" action="{{ route('mod.ticket.delete', ['ticket_id' => $ticket->ticket_id ]) }}" method="POST">
+                                            @csrf
+                                            <button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" type="submit" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                                        </form>
+                                    </td>
+                                </tr>
+                            @endforeach
+                        </tbody>
+                    </table>
+
+                </div>
+            </div>
+
+
+        </div>
+        <!-- END CUSTOM CONTENT -->
+
+    </section>
+    <!-- END CONTENT -->
+
+
+
+@endsection

+ 141 - 0
resources/views/mod/ticket/show.blade.php

@@ -0,0 +1,141 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{ __('Ticket') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{ route('mod.ticket.index') }}">{{ __('Ticket') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="col-lg-12">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between">
+                                <h5 class="card-title"><i class="fas fa-users mr-2"></i>#{{ $ticket->ticket_id }}</h5>
+                            </div>
+                        </div>
+                        <div class="card-body">
+                            <div class="ticket-info">
+                                @if(!empty($server))
+                                <p><b>Server:</b> <a href="{{ config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/servers/view/' . $server->pterodactyl_id }}" target="__blank">{{ $server->name }}</a></p>
+                                @endif
+                                <p><b>Title:</b> {{ $ticket->title }}</p>
+                                <p><b>Category:</b> {{ $ticketcategory->name }}</p>
+                                <p>
+                                    @if ($ticket->status === 'Open')
+                                    <b>Status:</b> <span class="badge badge-success">Open</span>
+                                    @elseif ($ticket->status === 'Closed')
+                                    <b>Status:</b> <span class="badge badge-danger">Closed</span>
+                                    @elseif ($ticket->status === 'Answered')
+                                    <b>Status:</b> <span class="badge badge-info">Answered</span>
+                                    @elseif ($ticket->status === 'Client Reply')
+                                    <b>Status:</b> <span class="badge badge-warning">Client Reply</span>
+                                    @endif
+                                </p>
+                                <p><b>Created on:</b> {{ $ticket->created_at->diffForHumans() }}</p>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-lg-12">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between">
+                                <h5 class="card-title"><i class="fas fa-cloud mr-2"></i>{{__('Comment')}}</h5>
+                            </div>
+                        </div> 
+                        <div class="card-body">
+                            <div class="card">
+                                <div class="card-header">
+                                    <div class="d-flex justify-content-between">
+                                        <h5 class="card-title"><img
+                                            src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticket->user->email)) }}?s=25"
+                                            class="user-image" alt="User Image">
+                                        <a href="/admin/users/{{$ticket->user->id}}">{{ $ticket->user->name }}</a>
+                                        @if($ticket->user->role === "member")
+                                            <span class="badge badge-secondary"> Member </span>
+                                        @elseif ($ticket->user->role === "client")
+                                            <span class="badge badge-success"> Client </span>
+                                        @elseif ($ticket->user->role === "mod")
+                                            <span class="badge badge-info"> Moderator </span>
+                                        @elseif ($ticket->user->role === "admin")
+                                            <span class="badge badge-danger"> Admin </span>
+                                        @endif
+                                    </h5>
+                                        <span class="badge badge-primary">{{ $ticket->created_at->diffForHumans() }}</span>
+                                    </div>
+                                </div>
+                                <div class="card-body">
+                                    {{ $ticket->message }}
+                                </div>
+                            </div>
+                            @foreach ($ticketcomments as $ticketcomment)
+                            <div class="card">
+                                <div class="card-header">
+                                    <div class="d-flex justify-content-between">
+                                        <h5 class="card-title"><img
+                                            src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticketcomment->user->email)) }}?s=25"
+                                            class="user-image" alt="User Image">
+                                        <a href="/admin/users/{{$ticketcomment->user->id}}">{{ $ticketcomment->user->name }}</a>
+                                        @if($ticketcomment->user->role === "member")
+                                            <span class="badge badge-secondary"> Member </span>
+                                        @elseif ($ticketcomment->user->role === "client")
+                                            <span class="badge badge-success"> Client </span>
+                                        @elseif ($ticketcomment->user->role === "mod")
+                                            <span class="badge badge-info"> Moderator </span>
+                                        @elseif ($ticketcomment->user->role === "admin")
+                                            <span class="badge badge-danger"> Admin </span>
+                                        @endif
+                                    </h5>
+                                        <span class="badge badge-primary">{{ $ticketcomment->created_at->diffForHumans() }}</span>
+                                    </div>
+                                </div>
+                                <div class="card-body">
+                                    {{ $ticketcomment->ticketcomment }}
+                                </div>
+                            </div>
+                            @endforeach
+                            <div class="comment-form">
+                                <form action="{{ route('mod.ticket.reply')}}" method="POST" class="form">
+                                    {!! csrf_field() !!}
+                                    <input type="hidden" name="ticket_id" value="{{ $ticket->id }}">
+                                    <div class="form-group{{ $errors->has('ticketcomment') ? ' has-error' : '' }}">
+                                        <textarea rows="10" id="ticketcomment" class="form-control" name="ticketcomment"></textarea>
+                                        @if ($errors->has('ticketcomment'))
+                                        <span class="help-block">
+                                            <strong>{{ $errors->first('ticketcomment') }}</strong>
+                                        </span>
+                                        @endif
+                                    </div>
+                                    <div class="form-group">
+                                        <button type="submit" class="btn btn-primary">Submit</button>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT -->
+@endsection
+

+ 127 - 0
resources/views/ticket/create.blade.php

@@ -0,0 +1,127 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{ __('Ticket') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{ route('ticket.index') }}">{{ __('Ticket') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+            <form action="{{route('ticket.new.store')}}" method="POST">
+                @csrf
+                <div class="row">
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">
+                                    <i class="fas fa-money-check-alt mr-2"></i>{{__('Open a new ticket')}}
+                                </h5>
+                            </div>
+                            <div class="card-body">
+                                <div class="form-group col-sm-12 {{ $errors->has('title') ? ' has-error' : '' }}">
+                                    <label for="title" class="control-label">Title</label>
+                                    <input id="title" type="text" class="form-control" name="title" value="{{ old('title') }}">
+                                    @if ($errors->has('title'))
+                                    <span class="help-block">
+                                        <strong>{{ $errors->first('title') }}</strong>
+                                    </span>
+                                    @endif
+                                </div>
+                                @if ($servers->count() >= 1)
+                                <div class="form-group col-sm-12 {{ $errors->has('server') ? ' has-error' : '' }}">
+                                    <label for="server" class="control-label">Servers</label>
+                                    <select id="server" type="server" class="form-control" name="server">
+                                        <option value="">Select Servers</option>
+                                        @foreach ($servers as $server)
+                                        <option value="{{ $server->id }}">{{ $server->name }}</option>
+                                        @endforeach
+                                    </select>
+    
+                                    @if ($errors->has('category'))
+                                    <span class="help-block">
+                                        <strong>{{ $errors->first('ticketcategory') }}</strong>
+                                    </span>
+                                    @endif
+                                </div>
+                                @endif
+                                <div class="form-group col-sm-12 {{ $errors->has('ticketcategory') ? ' has-error' : '' }}">
+                                    <label for="ticketcategory" class="control-label">Category</label>
+                                    <select id="ticketcategory" type="ticketcategory" class="form-control" name="ticketcategory">
+                                        <option value="">Select Category</option>
+                                        @foreach ($ticketcategories as $ticketcategory)
+                                        <option value="{{ $ticketcategory->id }}">{{ $ticketcategory->name }}</option>
+                                        @endforeach
+                                    </select>
+    
+                                    @if ($errors->has('category'))
+                                    <span class="help-block">
+                                        <strong>{{ $errors->first('ticketcategory') }}</strong>
+                                    </span>
+                                    @endif
+                                </div>
+                                <div class="form-group col-sm-12 {{ $errors->has('priority') ? ' has-error' : '' }}">
+                                    <label for="priority" class="control-label">Priority</label>
+                                    <select id="priority" type="" class="form-control" name="priority">
+                                        <option value="">Select Priority</option>
+                                        <option value="Low">Low</option>
+                                        <option value="Medium">Medium</option>
+                                        <option value="High">High</option>
+                                    </select>
+                                    @if ($errors->has('priority'))
+                                    <span class="help-block">
+                                        <strong>{{ $errors->first('priority') }}</strong>
+                                    </span>
+                                    @endif
+                                </div>
+                            </div>
+                            <div class="card-footer">
+                                <button type="submit" class="btn btn-primary">
+                                    {{__('Open Ticket')}}
+                                </button>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">
+                                    <i class="fas fa-money-check-alt mr-2"></i>{{__('Ticket details')}}
+                                </h5>
+                            </div>
+                            <div class="card-body">
+                                <div class="form-group col-sm-12 {{ $errors->has('message') ? ' has-error' : '' }}">
+                                    <label for="message" class="control-label">Message</label>
+                                    <textarea rows="8" id="message" class="form-control" name="message"></textarea>
+                                    @if ($errors->has('message'))
+                                    <span class="help-block">
+                                        <strong>{{ $errors->first('message') }}</strong>
+                                    </span>
+                                    @endif
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </section>
+    <!-- END CONTENT -->
+@endsection
+

+ 100 - 0
resources/views/ticket/index.blade.php

@@ -0,0 +1,100 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{ __('Ticket') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{ route('ticket.index') }}">{{ __('Ticket') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="col-lg-8">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between">
+                                <h5 class="card-title"><i class="fas fa-ticket-alt mr-2"></i>{{__('My Ticket')}}</h5>
+                                <a href="{{route('ticket.new')}}" class="btn btn-sm btn-primary"><i
+                                        class="fas fa-plus mr-1"></i>{{__('New Ticket')}}</a>
+                            </div>
+                        </div>
+                        <div class="card-body table-responsive">
+
+                            <table id="datatable" class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th>Category</th>
+                                    <th>Title</th>
+                                    <th>Status</th>
+                                    <th>Last Updated</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                    @foreach ($tickets as $ticket)
+                                    <tr>
+                                        <td>
+                                            {{ $ticket->ticketcategory->name }}
+                                        </td>
+                                        <td>
+                                            <a href="{{ route('ticket.show', ['ticket_id' => $ticket->ticket_id]) }}">
+                                                #{{ $ticket->ticket_id }} - {{ $ticket->title }}
+                                            </a>
+                                        </td>
+                                        <td>
+                                            @if ($ticket->status === 'Open')
+                                            <span class="badge badge-success">Open</span>
+                                            @elseif ($ticket->status === 'Closed')
+                                            <span class="badge badge-danger">Closed</span>
+                                            @elseif ($ticket->status === 'Answered')
+                                            <span class="badge badge-info">Answered</span>
+                                            @elseif ($ticket->status === 'Client Reply')
+                                            <span class="badge badge-warning">Client Reply</span>
+                                            @endif
+                                        </td>
+                                        <td>{{ $ticket->updated_at }}</td>
+                                    </tr>
+                                    @endforeach
+                                </tbody>
+                            </table>
+        
+                        </div>
+                    </div>
+                </div>
+                <div class="col-lg-4">
+                    <div class="card">
+                        <div class="card-header">
+                            <h5 class="card-title">{{__('Ticket Information')}}
+                                <i data-toggle="popover"
+                                data-trigger="hover"
+                                data-content="{{__('please make the best of it')}}"
+                                class="fas fa-info-circle"></i></h5>
+                        </div>
+                        <div class="card-body">
+                            <p>Can't start your server? Need an additional port? Do you have any other questions? Let us know by
+                                opening a ticket.</p>
+
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT -->
+@endsection
+

+ 141 - 0
resources/views/ticket/show.blade.php

@@ -0,0 +1,141 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>{{ __('Ticket') }}</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{ route('ticket.index') }}">{{ __('Ticket') }}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="col-lg-12">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between">
+                                <h5 class="card-title"><i class="fas fa-users mr-2"></i>#{{ $ticket->ticket_id }}</h5>
+                            </div>
+                        </div>
+                        <div class="card-body">
+                            <div class="ticket-info">
+                                @if(!empty($server))
+                                <p><b>Server:</b> <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}" target="__blank">{{ $server->name }} </a></p>
+                                @endif
+                                <p><b>Title:</b> {{ $ticket->title }}</p>
+                                <p><b>Category:</b> {{ $ticketcategory->name }}</p>
+                                <p>
+                                    @if ($ticket->status === 'Open')
+                                    <b>Status:</b> <span class="badge badge-success">Open</span>
+                                    @elseif ($ticket->status === 'Closed')
+                                    <b>Status:</b> <span class="badge badge-danger">Closed</span>
+                                    @elseif ($ticket->status === 'Answered')
+                                    <b>Status:</b> <span class="badge badge-info">Answered</span>
+                                    @elseif ($ticket->status === 'Client Reply')
+                                    <b>Status:</b> <span class="badge badge-warning">Client Reply</span>
+                                    @endif
+                                </p>
+                                <p><b>Created on:</b> {{ $ticket->created_at->diffForHumans() }}</p>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-lg-12">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="d-flex justify-content-between">
+                                <h5 class="card-title"><i class="fas fa-cloud mr-2"></i>{{__('Comment')}}</h5>
+                            </div>
+                        </div>
+                        <div class="card-body">
+                            <div class="card">
+                                <div class="card-header">
+                                    <div class="d-flex justify-content-between">
+                                        <h5 class="card-title"><img
+                                            src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticket->user->email)) }}?s=25"
+                                            class="user-image" alt="User Image">
+                                        <a href="/admin/users/{{$ticket->user->id}}">{{ $ticket->user->name }} </a>
+                                        @if($ticket->user->role === "member")
+                                            <span class="badge badge-secondary"> Member </span>
+                                        @elseif ($ticket->user->role === "client")
+                                            <span class="badge badge-success"> Client </span>
+                                        @elseif ($ticket->user->role === "mod")
+                                            <span class="badge badge-info"> Moderator </span>
+                                        @elseif ($ticket->user->role === "admin")
+                                            <span class="badge badge-danger"> Admin </span>
+                                        @endif
+                                        </h5>
+                                        <span class="badge badge-primary">{{ $ticket->created_at->diffForHumans() }}</span>
+                                    </div>
+                                </div>
+                                <div class="card-body">
+                                    {{ $ticket->message }}
+                                </div>
+                            </div>
+                            @foreach ($ticketcomments as $ticketcomment)
+                            <div class="card">
+                                <div class="card-header">
+                                    <div class="d-flex justify-content-between">
+                                        <h5 class="card-title"><img
+                                            src="https://www.gravatar.com/avatar/{{ md5(strtolower($ticketcomment->user->email)) }}?s=25"
+                                            class="user-image" alt="User Image">
+                                        <a href="/admin/users/{{$ticketcomment->user->id}}">{{ $ticketcomment->user->name }}</a>
+                                        @if($ticketcomment->user->role === "member")
+                                            <span class="badge badge-secondary"> Member </span>
+                                        @elseif ($ticketcomment->user->role === "client")
+                                            <span class="badge badge-success"> Client </span>
+                                        @elseif ($ticketcomment->user->role === "mod")
+                                            <span class="badge badge-info"> Moderator </span>
+                                        @elseif ($ticketcomment->user->role === "admin")
+                                            <span class="badge badge-danger"> Admin </span>
+                                        @endif
+                                    </h5>
+                                        <span class="badge badge-primary">{{ $ticketcomment->created_at->diffForHumans() }}</span>
+                                    </div>
+                                </div>
+                                <div class="card-body">
+                                    {{ $ticketcomment->ticketcomment }}
+                                </div>
+                            </div>
+                            @endforeach
+                            <div class="comment-form">
+                                <form action="{{ route('ticket.reply')}}" method="POST" class="form">
+                                    {!! csrf_field() !!}
+                                    <input type="hidden" name="ticket_id" value="{{ $ticket->id }}">
+                                    <div class="form-group{{ $errors->has('ticketcomment') ? ' has-error' : '' }}">
+                                        <textarea rows="10" id="ticketcomment" class="form-control" name="ticketcomment"></textarea>
+                                        @if ($errors->has('ticketcomment'))
+                                        <span class="help-block">
+                                            <strong>{{ $errors->first('ticketcomment') }}</strong>
+                                        </span>
+                                        @endif
+                                    </div>
+                                    <div class="form-group">
+                                        <button type="submit" class="btn btn-primary">Submit</button>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT -->
+@endsection
+

+ 19 - 1
routes/web.php

@@ -14,6 +14,7 @@ use App\Http\Controllers\Admin\SettingsController;
 use App\Http\Controllers\Admin\UsefulLinkController;
 use App\Http\Controllers\Admin\UserController;
 use App\Http\Controllers\Admin\VoucherController;
+use App\Http\Controllers\Mod\TicketsController as ModTicketsController;
 use App\Http\Controllers\Auth\SocialiteController;
 use App\Http\Controllers\HomeController;
 use App\Http\Controllers\NotificationController;
@@ -22,6 +23,7 @@ use App\Http\Controllers\ProfileController;
 use App\Http\Controllers\ServerController;
 use App\Http\Controllers\StoreController;
 use App\Http\Controllers\TranslationController;
+use App\Http\Controllers\TicketsController;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Route;
@@ -89,7 +91,13 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
 
     #switch language
     Route::post('changelocale', [TranslationController::class, 'changeLocale'])->name('changeLocale');
-
+    
+    #ticket user
+    Route::get('ticket', [TicketsController::class, 'index'])->name('ticket.index');
+    Route::get('ticket/new', [TicketsController::class, 'create'])->name('ticket.new');
+    Route::post('ticket/new', [TicketsController::class, 'store'])->name('ticket.new.store');
+    Route::get('ticket/show/{ticket_id}', [TicketsController::class, 'show'])->name('ticket.show');
+    Route::post('ticket/reply', [TicketsController::class, 'reply'])->name('ticket.reply');
 
     #admin
     Route::prefix('admin')->name('admin.')->middleware('admin')->group(function () {
@@ -164,5 +172,15 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
         ]);
     });
 
+    #mod
+    Route::prefix('mod')->name('mod.')->middleware('mod')->group(function () {
+        #ticket moderation
+        Route::get('ticket', [ModTicketsController::class, 'index'])->name('ticket.index');
+        Route::get('ticket/show/{ticket_id}', [ModTicketsController::class, 'show'])->name('ticket.show');
+        Route::post('ticket/reply', [ModTicketsController::class, 'reply'])->name('ticket.reply');
+        Route::post('ticket/close/{ticket_id}', [ModTicketsController::class, 'close'])->name('ticket.close');
+        Route::post('ticket/delete/{ticket_id}', [ModTicketsController::class, 'delete'])->name('ticket.delete');
+    });
+    
     Route::get('/home', [HomeController::class, 'index'])->name('home');
 });