chat function

This commit is contained in:
abdul-wahab12345 2024-07-09 10:58:20 +00:00
parent f0e7e09ef8
commit f13e2a1945
20 changed files with 630 additions and 31 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ yarn-error.log
/.fleet /.fleet
/.idea /.idea
/.vscode /.vscode
/chat.kundesone.no

View File

@ -8,6 +8,15 @@
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use Mailgun\Mailgun; use Mailgun\Mailgun;
use App\Models\Company; use App\Models\Company;
use App\Models\ChatGroup;
use App\Models\Message;
use App\Models\CompanyUser;
function get_company_users($company_id){
return CompanyUser::where('company_id', $company_id)->with('user')->get();
}
function get_company($key,$value){ function get_company($key,$value){
@ -206,3 +215,65 @@ function createResponse($ticket_id, $message, $user_id = 0)
return $response; return $response;
} }
} }
/**
* Create a new chat group.
*
* @param int $companyId The ID of the company associated with the chat.
* @param int $userId The ID of the user creating the chat group.
* @param string $customerId Identifier for the customer involved in the chat.
* @param string $name Name or title of the chat group.
* @param string $email Email address associated with the chat group.
* @param string $subject Subject or initial topic of the chat group.
* @param string $status Current status of the chat group (e.g., 'active', 'closed').
* @return ChatGroup The newly created chat group object.
*/
function createChatGroup($companyId, $userId, $customerId, $name, $email, $subject, $status)
{
return ChatGroup::create([
'company_id' => $companyId,
'user_id' => $userId,
'customer_id' => $customerId,
'name' => $name,
'email' => $email,
'subject' => $subject,
'status' => $status
]);
}
/**
* Store a new message in a specified chat group.
*
* @param int $chatId The ID of the chat group.
* @param string $from Sender identifier.
* @param string $to Receiver identifier.
* @param string $message Content of the message.
* @param string $type Type of the message.
* @return Message The newly created message object.
*/
function storeMessage($chatId, $from, $to, $message, $type)
{
return Message::create([
'chat_id' => $chatId,
'from' => $from,
'to' => $to,
'message' => $message,
'type' => $type
]);
}
/**
* Retrieve all messages from a specified chat group.
*
* @param int $chatId The ID of the chat group.
* @return \Illuminate\Database\Eloquent\Collection A collection of messages.
*/
function getMessagesByChatId($chatId)
{
return Message::where('chat_id', $chatId)->orderBy('created_at', 'asc')->get();
}

View File

@ -0,0 +1,112 @@
<?php
namespace App\Http\Controllers\Chat;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Company;
use App\Models\ChatGroup;
use App\Models\Message;
use Illuminate\Support\Facades\Validator;
class ChatController extends Controller
{
/**
* Start a new chat by creating a chat group.
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function startChat(Request $request)
{
$validator = Validator::make($request->all(), [
'company_id' => 'required|integer|exists:companies,id',
//'user_id' => 'required|integer|exists:users,id',
'customer_id' => 'required|string|max:255',
'name' => 'required|string|max:255',
'email' => 'required|email|max:255',
'subject' => 'required|string|max:1000',
//'status' => 'required|string|max:255'
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$company_id = $request->company_id;
$user_id = $this->select_user($company_id);
if($user_id){
$data = [
'company_id' => $company_id,
'user_id' => $user_id,
'customer_id' => $request->customer_id,
'name' => $request->name,
'email' => $request->email,
'subject' => $request->subject,
'status' => 'open',
];
$chatGroup = ChatGroup::create($data);
return response()->json(['chat_id' => $chatGroup->id], 200);
}else{
return response()->json(['message' => 'user not found'], 400);
}
}
public function sendMessage(Request $request)
{
$validator = Validator::make($request->all(), [
'chat_id' => 'required|integer|exists:chat_group,id',
'from' => 'required|string|max:255',
//'to' => 'required|string|max:255',
'message' => 'required|string',
'type' => 'required|string|max:255'
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$data = [
'chat_id' => $request->chat_id,
'from' => $request->from,
'to' => $request->from == 'user'?'company':'user',
'message' => $request->message,
'type' => $request->type,
];
$message = Message::create($data);
return response()->json(['message' => 'Message sent successfully', 'data' => $message], 200);
}
public function select_user($company_id){
$companyUsers = get_company_users($company_id);
$selected = false;
foreach($companyUsers as $user){
$access = json_decode($user->access);
if(in_array('chat',$access)){
$selected = $user->user_id;
}
}
return $selected;
}
}

View File

@ -348,7 +348,7 @@ public function fetchActionBox($ticketId)
{ {
$selectedCompany = getSelectedCompany(); $selectedCompany = getSelectedCompany();
$ticket = Ticket::where('id', $ticketId)->with('comments')->first(); $ticket = Ticket::where('id', $ticketId)->with('comments')->first();
$companyUsers = CompanyUser::where('company_id', $selectedCompany)->with('user')->get(); $companyUsers = get_company_users($selectedCompany);//CompanyUser::where('company_id', $selectedCompany)->with('user')->get();
return view('partials.action-box', compact('ticket','companyUsers'))->render(); return view('partials.action-box', compact('ticket','companyUsers'))->render();
} }

19
app/Models/ChatGroup.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ChatGroup extends Model
{
use HasFactory;
protected $table = 'chat_group';
protected $fillable = ['company_id', 'user_id', 'customer_id', 'name', 'email', 'subject', 'status'];
public function messages()
{
return $this->hasMany(Message::class, 'chat_id');
}
}

20
app/Models/Message.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
use HasFactory;
protected $table = 'message';
protected $fillable = ['chat_id', 'from', 'to', 'message', 'type'];
public function chat()
{
return $this->belongsTo(ChatGroup::class, 'chat_id');
}
}

View File

@ -0,0 +1,34 @@
<?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::create('chat_group', function (Blueprint $table) {
$table->id();
$table->foreignId('company_id')->constrained('companies')->onDelete('cascade');
$table->foreignId('user_id')->constrained('users');
$table->string('customer_id');
$table->string('name');
$table->string('email');
$table->text('subject');
$table->string('status');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('chat_group');
}
};

View File

@ -0,0 +1,32 @@
<?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::create('message', function (Blueprint $table) {
$table->id();
$table->foreignId('chat_id')->constrained('chat_group')->onDelete('cascade');
$table->string('from');
$table->string('to');
$table->text('message');
$table->string('type');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('message');
}
};

View File

@ -39,3 +39,9 @@
[30-Jun-2024 04:00:06 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0 [30-Jun-2024 04:00:06 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[30-Jun-2024 04:30:35 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0 [30-Jun-2024 04:30:35 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[01-Jul-2024 18:34:48 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0 [01-Jul-2024 18:34:48 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:01:01 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:01:29 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:14:30 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:14:45 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:14:56 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0
[09-Jul-2024 09:21:16 UTC] PHP Warning: Module "fileinfo" is already loaded in Unknown on line 0

View File

@ -0,0 +1,8 @@
# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php81” package as the default “PHP” programming language.
<IfModule mime_module>
AddHandler application/x-httpd-ea-php81 .php .php8 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit

View File

@ -5,14 +5,168 @@
@section('content') @section('content')
<script> <script>
$(document).ready(function() {
// Initially disable all the buttons
$('.handle_multiple__options .tags button').prop('disabled', true);
// Toggle visibility of handle_multiple__options on button click
$('.handle-multiple-btn').click(function() {
$('.handle_multiple__options').toggle();
});
// Enable/disable buttons based on the select all checkbox
$('#select-all').change(function() {
if ($(this).is(':checked')) {
$('.handle_multiple__options .tags button').prop('disabled', false);
} else {
$('.handle_multiple__options .tags button').prop('disabled', true);
}
});
// Show the modal when "Assign post" button is clicked
$('.handle_multiple__options .tags button:contains("Assign post")').click(function(e) {
e.preventDefault(); // Prevent default action to avoid any conflict
$('#customModal').show();
});
// Close the modal when the close button or outside the modal is clicked
$('.modal-close, .modal').click(function() {
$('#customModal').hide();
});
// Prevent modal content from closing the modal when clicked
$('.modal-content').click(function(e) {
e.stopPropagation();
});
// Show the modal when "Move" button is clicked
$('.handle_multiple__options .tags button:contains("Move")').click(function(e) {
e.preventDefault(); // Prevent default action to avoid any conflict
$('#customModal2').show();
});
// Close the modal when the close button or outside the modal is clicked
$('.modal-close, .modal').click(function() {
$('#customModal2').hide();
});
// Show the modal when "Reply to multiple" button is clicked
$('.handle_multiple__options .tags button:contains("Reply to multiple")').click(function(e) {
e.preventDefault(); // Prevent default action to avoid any conflict
$('#customModal3').show();
});
// Close the modal when the close button or outside the modal is clicked
$('.modal-close, .modal').click(function() {
$('#customModal3').hide();
});
$(document).ready(function(){
$('.side-bar-links a').removeClass('bg-light-color');
$('.aw-a-all').addClass('bg-light-color');
}); });
</script> </script>
<style>
.handle_multiple__options {
display: none;
background-color: #f8f9fa;
padding: 10px;
border: 1px solid #ddd;
margin-top: 10px;
}
.handle_multiple__options label {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.handle_multiple__options .tags {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.handle_multiple__options .tags button {
background-color: #748C62;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
}
.handle_multiple__options .tags button:hover {
background-color: #383F33;
}
.handle_multiple__options .tags button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.handle_multiple__options input{
width: 32px;
height: 19px;
}
.handle_multiple__options .common_shre{
display: flex;
justify-content: space-between;
}
/* Custom Modal CSS */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 13%;
border-radius: 10px;
position: relative;
}
#customModal3 .modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 40%;
border-radius: 10px;
position: relative;
}
.modal-content .btn-primary{
background-color: #748C62 !important;
}
.modal-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
position: absolute;
right: 20px;
top: 10px;
cursor: pointer;
}
.modal-close:hover,
.modal-close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
</style>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="ui card chat-card"> <div class="ui card chat-card">
<div class="content chat-card-header d-flex align-items-center justify-content-between"> <div class="content chat-card-header d-flex align-items-center justify-content-between">
@ -31,6 +185,22 @@
</div> </div>
</div> </div>
<div class="handle_multiple__options">
<div class="common_shre">
<label for="select-all"> <input type="checkbox" name="" id="select-all"> Select all</label>
<div class="tags">
<button>Assign post</button>
<button>Delete</button>
<button>Move</button>
<button>Open</button>
<button>Waiting</button>
<button>Done</button>
<button>Tag</button>
<button>Not spam</button>
<button>Reply to multiple</button>
</div>
</div>
</div>
<div class="content chat-content"> <div class="content chat-content">
<ul class="chat-details"> <ul class="chat-details">
@foreach($tickets as $ticket) @foreach($tickets as $ticket)
@ -55,8 +225,8 @@ class="chat-status-icon rounded-circle text-center align-content-center position
</div> </div>
<div class="chat-ticket-row d-flex justify-content-between"> <div class="chat-ticket-row d-flex justify-content-between">
<div class="ticket-status d-flex"> <div class="ticket-status d-flex">
<p class="color-dark-green receiver-name">{{ $ticket->subject }}</p> <p class="color-dark-green receiver-name">{{ $ticket->sender_name }}</p>
<p class="receiver-message"> - {{ $ticket->content }}</p> <p class="receiver-message"> - {{\Illuminate\Support\Str::limit($ticket->subject, 90)}}</p>
</div> </div>
<p class="color-dark-green bold message-time">{{\Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p> <p class="color-dark-green bold message-time">{{\Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p>
</div> </div>
@ -70,5 +240,52 @@ class="chat-status-icon rounded-circle text-center align-content-center position
</div> </div>
</div> </div>
<!-- Custom Modal post -->
<div id="customModal" class="modal">
<div class="modal-content">
<span class="modal-close">&times;</span>
<h5>Assign Post</h5>
<form>
<div class="mb-3">
<label for="recipient-name" class="col-form-label">Recipient:</label>
<input type="text" class="form-control" id="recipient-name">
</div>
<div class="mb-3">
<label for="message-text" class="col-form-label">Message:</label>
<textarea class="form-control" id="message-text"></textarea>
</div>
</form>
<button type="button" class="btn btn-primary">Send</button>
</div>
</div>
<!-- Custom Modal move-->
<div id="customModal2" class="modal">
<div class="modal-content">
<span class="modal-close">&times;</span>
<h5>Move</h5>
<form>
<div class="mb-3">
<label for="recipient-name" class="col-form-label">Conversation moved:</label>
<input type="text" class="form-control" id="recipient-name" placeholder="Inbox">
</div>
</form>
<button type="button" class="btn btn-primary">Confirm</button>
</div>
</div>
<!-- Custom Modal Replay to multiple-->
<div id="customModal3" class="modal">
<div class="modal-content">
<span class="modal-close">&times;</span>
<h5>Replay to multiple</h5>
<form>
<div class="mb-3 mt-4">
<p>Please choose only email conversations and try again</p>
</div>
</form>
</div>
</div>
@endsection @endsection

View File

@ -98,3 +98,12 @@ class="ui secondary basic button shadow-none setting-btn text-white align-conten
</div> </div>
</div> </div>
</header> </header>
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>
<style>
.cke_notification.cke_notification_warning{
display:none!important;
}
</style>

View File

@ -9,6 +9,13 @@
.side-bar-links ul li .bg-light-color .color-light{ .side-bar-links ul li .bg-light-color .color-light{
color: #383f33 !important; color: #383f33 !important;
} }
.sidebar_icon{
font-size: 20px !important;
color: white !important;
}
.bg-light-color .sidebar_icon{
color: #383F33 !important;
}
</style> </style>
<div class="side-bar-links"> <div class="side-bar-links">
@ -17,7 +24,7 @@
<a href="{{ route('index') }}" <a href="{{ route('index') }}"
class="side-bar-link bg-light-color d-flex align-items-center justify-content-between aw-a-inbox"> class="side-bar-link bg-light-color d-flex align-items-center justify-content-between aw-a-inbox">
<div class="link-left-content align-items-center d-flex"> <div class="link-left-content align-items-center d-flex">
<img src="{{ asset('images/icons/Message.png') }}" alt="Message"> <i class="fa fa-envelope-o sidebar_icon" aria-hidden="true"></i>
<h6 class="color-light">Inbox</h6> <h6 class="color-light">Inbox</h6>
</div> </div>
<div class="link-right-content"> <div class="link-right-content">
@ -29,7 +36,7 @@ class="side-bar-link bg-light-color d-flex align-items-center justify-content-be
<a href="{{ route('waiting') }}" <a href="{{ route('waiting') }}"
class="side-bar-link d-flex align-items-center justify-content-between aw-a-waiting"> class="side-bar-link d-flex align-items-center justify-content-between aw-a-waiting">
<div class="link-left-content align-items-center d-flex"> <div class="link-left-content align-items-center d-flex">
<img src="{{ asset('images/icons/Time_light.png') }}" alt="Message"> <i class="fa fa-clock-o sidebar_icon" aria-hidden="true"></i>
<h6 class="color-light">Waiting</h6> <h6 class="color-light">Waiting</h6>
</div> </div>
<div class="link-right-content"> <div class="link-right-content">
@ -41,7 +48,7 @@ class="side-bar-link d-flex align-items-center justify-content-between aw-a-wai
<a href="{{ route('all.tickets') }}" <a href="{{ route('all.tickets') }}"
class="side-bar-link d-flex align-items-center justify-content-between aw-a-all"> class="side-bar-link d-flex align-items-center justify-content-between aw-a-all">
<div class="link-left-content align-items-center d-flex"> <div class="link-left-content align-items-center d-flex">
<img src="{{ asset('images/Ticket_use.svg') }}" alt="Message"> <i class="fa fa-ticket sidebar_icon" aria-hidden="true"></i>
<h6 class="color-light">All Tickets</h6> <h6 class="color-light">All Tickets</h6>
</div> </div>
<div class="link-right-content"> <div class="link-right-content">
@ -52,7 +59,7 @@ class="side-bar-link d-flex align-items-center justify-content-between aw-a-all
<li> <li>
<a href="#" class="side-bar-link d-flex align-items-center justify-content-between aw-a-stats"> <a href="#" class="side-bar-link d-flex align-items-center justify-content-between aw-a-stats">
<div class="link-left-content align-items-center d-flex"> <div class="link-left-content align-items-center d-flex">
<img src="{{ asset('images/chart-square.svg') }}" alt="Message"> <i class="fa fa-bar-chart sidebar_icon" aria-hidden="true"></i>
<h6 class="color-light">Statistics</h6> <h6 class="color-light">Statistics</h6>
</div> </div>
<div class="link-right-content"> <div class="link-right-content">
@ -69,7 +76,7 @@ class="side-bar-link d-flex align-items-center justify-content-between aw-a-all
<li class="channels-widgets-wrapper side-bar-link bg-light-color d-flex align-items-center justify-content-between"> <li class="channels-widgets-wrapper side-bar-link bg-light-color d-flex align-items-center justify-content-between">
<div class="link-left-content align-items-center d-flex"> <div class="link-left-content align-items-center d-flex">
<img src="{{ asset('images/icons/Message.png') }}" alt="Message"> <i class="fa fa-envelope-o sidebar_icon" aria-hidden="true"></i>
<h6 class="color-dark-green">Channels</h6> <h6 class="color-dark-green">Channels</h6>
</div> </div>
<div class="link-right-content"> <div class="link-right-content">

View File

@ -74,7 +74,7 @@ class="form-control input-reply-textarea" id="editor1" required></textarea>
</div> </div>
</div> </div>
<!--wysywyg editor--> <!--wysywyg editor-->
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script> <!--<script src="https://cdn.ckeditor.com/4.24.0/standard/ckeditor.js"></script>-->
<!-- Canned Response Modal --> <!-- Canned Response Modal -->

View File

@ -57,8 +57,8 @@
</div> </div>
<div class="chat-ticket-row d-flex justify-content-between"> <div class="chat-ticket-row d-flex justify-content-between">
<div class="ticket-status d-flex"> <div class="ticket-status d-flex">
<p class="color-dark-green receiver-name">{{$ticket->subject}}</p> <p class="color-dark-green receiver-name">{{$ticket->sender_name}}</p>
<p class="receiver-message"> - {{$ticket->content}}.</p> <p class="receiver-message"> - {{\Illuminate\Support\Str::limit($ticket->subject, 90)}}.</p>
</div> </div>
<p class="color-dark-green bold message-time">{{ \Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p> <p class="color-dark-green bold message-time">{{ \Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p>
</div> </div>

View File

@ -15,6 +15,7 @@
<!-- Main Styles --> <!-- Main Styles -->
<link rel="stylesheet" href="{{ asset('assets/style.css') }}"> <link rel="stylesheet" href="{{ asset('assets/style.css') }}">
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png"> <link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
</head> </head>
</head> </head>
@ -143,12 +144,15 @@
</div> </div>
<div class="outer-message-input-box"> <div class="outer-message-input-box">
<div class="inner-message-input d-flex align-items-center justify-content-between "> <div class="inner-message-input d-flex align-items-center justify-content-between">
<input type="text" class="border-0" placeholder="Type a reply"> <input type="text" class="border-0" placeholder="Type a reply">
<p class="input-action d-flex align-items-center "> <p class="input-action d-flex align-items-center">
<img src="{{ asset('images/icons/gif.png') }}" alt="Gif"> <img src="{{ asset('images/icons/gif.png') }}" alt="Gif">
<img src="{{ asset('images/icons/emoji.png') }}" alt="Gif"> <img src="{{ asset('images/icons/emoji.png') }}" alt="Emoji">
<img src="{{ asset('images/icons/attachment.png') }}" alt="Gif"> <img src="{{ asset('images/icons/attachment.png') }}" alt="Attachment">
<input type="file" id="file-picker" class="file-picker">
<i class="fa fa-paper-plane-o send-icon" aria-hidden="true"></i>
</p> </p>
</div> </div>
</div> </div>
@ -263,6 +267,52 @@
<!-- Main Custom Js --> <!-- Main Custom Js -->
<script src="{{ asset('assets/script.js') }}"></script> <script src="{{ asset('assets/script.js') }}"></script>
<script>document.querySelector('.input-action img[alt="Attachment"]').addEventListener('click', function() {
document.getElementById('file-picker').click();
});
</script>
<style>
.outer-message-input-box {
width: 100%;
padding: 10px;
background-color: #f8f9fa;
}
.inner-message-input {
width: 100%;
background-color: #ffffff;
border-radius: 5px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.inner-message-input input {
flex-grow: 1;
margin-right: 10px;
}
.input-action img {
margin-left: 10px;
cursor: pointer;
}
.input-action .file-picker {
display: none;
}
.fa-paper-plane-o {
font-size: 17px !important;
background: #748C62 !important;
padding: 3px 7px !important;
color: white !important;
border-radius: 3px !important;
cursor: pointer !important;
}
</style>
</body> </body>
</html> </html>

View File

@ -31,7 +31,7 @@
<input name="access[]" type="checkbox" value="inbox"> <input name="access[]" type="checkbox" value="inbox">
<span class="checkmark"></span> <span class="checkmark"></span>
</label> </label>
<label class="dev-checkbox-wrapper">Inbox Module <label class="dev-checkbox-wrapper">Chat Module
<input name="access[]" type="checkbox" value="chat"> <input name="access[]" type="checkbox" value="chat">
<span class="checkmark"></span> <span class="checkmark"></span>
</label> </label>

View File

@ -4,6 +4,12 @@
@section('content') @section('content')
<style>
div.chat-inbox>.chat-content-wrapper>.chat-message>.single-message-chat>.user-message{
max-width:90%!important;
}
</style>
<div class="inbox-content-wrapper w-100 "> <div class="inbox-content-wrapper w-100 ">
<div class="inbox-inner-wrapper w-100 d-flex"> <div class="inbox-inner-wrapper w-100 d-flex">
@ -23,7 +29,7 @@
<div class="chat-ticket-row align-items-center d-flex justify-content-between"> <div class="chat-ticket-row align-items-center d-flex justify-content-between">
<div class="ticket-status d-flex flex-column"> <div class="ticket-status d-flex flex-column">
<p class="color-dark-green receiver-name">{{$ticket->sender_name}}</p> <p class="color-dark-green receiver-name">{{$ticket->sender_name}}</p>
<p class="receiver-message">{!! strip_tags($ticket?->lastResponse?->message) ?? '' !!}</p> <p class="receiver-message">{!! \Illuminate\Support\Str::limit(strip_tags($ticket?->lastResponse?->message) ?? '', 90) !!}</p>
</div> </div>
<p class=" bold message-time">{{\Carbon\Carbon::parse($ticket?->lastResponse?->created_at)->format('h:i A') ?? ''}}</p> <p class=" bold message-time">{{\Carbon\Carbon::parse($ticket?->lastResponse?->created_at)->format('h:i A') ?? ''}}</p>
</div> </div>
@ -74,7 +80,7 @@ class="form-control input-reply-textarea" id="editor1" required></textarea>
</div> </div>
</div> </div>
<!--wysywyg editor--> <!--wysywyg editor-->
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script> <!--<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>-->
<!-- Canned Response Modal --> <!-- Canned Response Modal -->

View File

@ -51,8 +51,8 @@
</div> </div>
<div class="chat-ticket-row d-flex justify-content-between"> <div class="chat-ticket-row d-flex justify-content-between">
<div class="ticket-status d-flex"> <div class="ticket-status d-flex">
<p class="color-dark-green receiver-name">{{$ticket->subject}}</p> <p class="color-dark-green receiver-name">{{$ticket->sender_name}}</p>
<p class="receiver-message"> - {{$ticket->content}}.</p> <p class="receiver-message"> - {{\Illuminate\Support\Str::limit($ticket->subject, 90)}}.</p>
</div> </div>
<p class="color-dark-green bold message-time">{{ \Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p> <p class="color-dark-green bold message-time">{{ \Carbon\Carbon::parse($ticket->created_at)->format('h:i A')}}</p>
</div> </div>

View File

@ -3,6 +3,7 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Mailgun\EmailController; use App\Http\Controllers\Mailgun\EmailController;
use App\Http\Controllers\Chat\ChatController;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -18,6 +19,12 @@
Route::post('/save-email', [EmailController::class, 'saveEmail']); Route::post('/save-email', [EmailController::class, 'saveEmail']);
Route::post('/chat/start', [ChatController::class, 'startChat']);
Route::post('/chat/send-message', [ChatController::class, 'sendMessage']);
Route::middleware('auth:sanctum')->get('/user', function (Request $request) { Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user(); return $request->user();