mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
feat: chat module
This commit is contained in:
@ -737,7 +737,28 @@ $routes->group('mensajes', ['namespace' => 'App\Controllers\Mensajeria'], functi
|
||||
});
|
||||
|
||||
});
|
||||
$routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($routes) {
|
||||
$routes->get('departments', 'ChatController::get_chat_departments', ['as' => 'getChatDepartments']);
|
||||
$routes->get('department/presupuesto/(:num)/(:num)', 'ChatController::get_chat_presupuesto/$1/$2', ['as' => 'getChatPresupuesto']);
|
||||
$routes->get('department/pedido/(:num)/(:num)', 'ChatController::get_chat_pedido/$1/$2', ['as' => 'getChatPedido']);
|
||||
$routes->get('department/factura/(:num)/(:num)', 'ChatController::get_chat_factura/$1/$2', ['as' => 'getChatFactura']);
|
||||
|
||||
$routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']);
|
||||
$routes->post('message/presupuesto', 'ChatController::store_chat_message_presupuesto', ['as' => 'storeChatMessagePresupuesto']);
|
||||
$routes->post('message/pedido', 'ChatController::store_chat_message_pedido', ['as' => 'storeChatMessagePedido']);
|
||||
$routes->post('message/factura', 'ChatController::store_chat_message_factura', ['as' => 'storeChatMessageFactura']);
|
||||
$routes->post('message/internal', 'ChatController::store_chat_message_single', ['as' => 'storeChatMessageSingle']);
|
||||
$routes->get('contacts', 'ChatController::get_chat_internal_contacts', ['as' => 'getChatInternalContacts']);
|
||||
$routes->get('contacts/(:num)', 'ChatController::get_chat_internal_contact/$1', ['as' => 'getChatInternalContact']);
|
||||
$routes->get('contact/(:num)/messages', 'ChatController::get_chat_internal_messages/$1', ['as' => 'getChatInternalMessages']);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
|
||||
189
ci4/app/Controllers/Chat/ChatController.php
Normal file
189
ci4/app/Controllers/Chat/ChatController.php
Normal file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Chat;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\Chat\ChatDeparmentModel;
|
||||
use App\Models\Chat\ChatDeparmentUserModel;
|
||||
use App\Models\Chat\ChatMessageModel;
|
||||
use App\Models\Chat\ChatModel;
|
||||
use App\Models\Usuarios\UserModel;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\Log\Logger;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ChatController extends BaseController
|
||||
{
|
||||
protected ChatDeparmentModel $chatDeparmentModel;
|
||||
protected ChatDeparmentUserModel $chatDeparmentUserModel;
|
||||
protected ChatModel $chatModel;
|
||||
protected ChatMessageModel $chatMessageModel;
|
||||
protected UserModel $userModel;
|
||||
|
||||
|
||||
|
||||
public function initController(
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
parent::initController($request, $response, $logger);
|
||||
|
||||
// Add your code here.
|
||||
$this->chatDeparmentModel = model(ChatDeparmentModel::class);
|
||||
$this->chatDeparmentUserModel = model(ChatDeparmentUserModel::class);
|
||||
$this->chatModel = model(ChatModel::class);
|
||||
$this->chatMessageModel = model(ChatMessageModel::class);
|
||||
$this->userModel = model(UserModel::class);
|
||||
}
|
||||
public function index() {}
|
||||
public function get_chat_departments()
|
||||
{
|
||||
|
||||
$data = $this->chatDeparmentModel->getChatDepartments();
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
public function get_chat_presupuesto(int $chat_department_id, int $presupuesto_id)
|
||||
{
|
||||
|
||||
$data = [
|
||||
"chat" => null,
|
||||
"messages" => null,
|
||||
];
|
||||
$chat = $this->chatModel->getChatPresupuesto($chat_department_id, $presupuesto_id);
|
||||
if ($chat) {
|
||||
$data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
|
||||
}
|
||||
$data["chat"] = $chat;
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
public function get_chat_pedido(int $chat_department_id, int $pedido_id)
|
||||
{
|
||||
|
||||
$data = [
|
||||
"chat" => null,
|
||||
"messages" => null,
|
||||
];
|
||||
$chat = $this->chatModel->getChatPedido($chat_department_id, $pedido_id);
|
||||
if ($chat) {
|
||||
$data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
|
||||
}
|
||||
$data["chat"] = $chat;
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
public function get_chat_factura(int $chat_department_id, int $factura_id)
|
||||
{
|
||||
|
||||
$data = [
|
||||
"chat" => null,
|
||||
"messages" => null,
|
||||
];
|
||||
$chat = $this->chatModel->getChatFactura($chat_department_id, $factura_id);
|
||||
if ($chat) {
|
||||
$data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
|
||||
}
|
||||
$data["chat"] = $chat;
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
public function get_chat(int $chat_id)
|
||||
{
|
||||
|
||||
$data = $this->chatModel->getChat($chat_id);
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
public function store_chat_message_presupuesto()
|
||||
{
|
||||
|
||||
$data = $this->request->getPost();
|
||||
// $data = $this->chatModel->createChatPresupuesto();
|
||||
$existChat = $this->chatModel->existChatPresupuesto($data["chat_department_id"], $data["model_id"]);
|
||||
if ($existChat == false) {
|
||||
$chatId = $this->chatModel->createChatPresupuesto($data["chat_department_id"], $data["model_id"]);
|
||||
} else {
|
||||
$chat = $this->chatModel->getChatPresupuesto($data["chat_department_id"], $data["model_id"]);
|
||||
$chatId = $chat->id;
|
||||
}
|
||||
$chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
|
||||
$dataResponse = $this->chatMessageModel->find($chat_message_id);
|
||||
return $this->response->setJSON($dataResponse);
|
||||
}
|
||||
public function store_chat_message_pedido()
|
||||
{
|
||||
|
||||
$data = $this->request->getPost();
|
||||
$existChat = $this->chatModel->existChatPedido($data["chat_department_id"], $data["model_id"]);
|
||||
if ($existChat == false) {
|
||||
$chatId = $this->chatModel->createChatPedido($data["chat_department_id"], $data["model_id"]);
|
||||
} else {
|
||||
$chat = $this->chatModel->getChatPedido($data["chat_department_id"], $data["model_id"]);
|
||||
$chatId = $chat->id;
|
||||
}
|
||||
$chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
|
||||
$dataResponse = $this->chatMessageModel->find($chat_message_id);
|
||||
return $this->response->setJSON($dataResponse);
|
||||
}
|
||||
public function store_chat_message_factura()
|
||||
{
|
||||
|
||||
$data = $this->request->getPost();
|
||||
$existChat = $this->chatModel->existChatFactura($data["chat_department_id"], $data["model_id"]);
|
||||
if ($existChat == false) {
|
||||
$chatId = $this->chatModel->createChatFactura($data["chat_department_id"], $data["model_id"]);
|
||||
} else {
|
||||
$chat = $this->chatModel->getChatFactura($data["chat_department_id"], $data["model_id"]);
|
||||
$chatId = $chat->id;
|
||||
}
|
||||
$chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
|
||||
$dataResponse = $this->chatMessageModel->find($chat_message_id);
|
||||
return $this->response->setJSON($dataResponse);
|
||||
}
|
||||
public function store_chat_message_single()
|
||||
{
|
||||
$data = $this->request->getPost();
|
||||
|
||||
$existChat = $this->chatMessageModel->get_chat_contact_messages($data["receiver_id"]);
|
||||
if (count($existChat) > 0) {
|
||||
$chatId = $existChat[0]->chat_id;
|
||||
} else {
|
||||
$chatId = $this->chatModel->createChatSingle();
|
||||
}
|
||||
$chat_message_id = $this->chatMessageModel->insert(
|
||||
[
|
||||
"chat_id" => $chatId,
|
||||
"sender_id" => auth()->user()->id,
|
||||
"message" => $data["message"],
|
||||
"receiver_id" => $data["receiver_id"]
|
||||
]
|
||||
);
|
||||
$dataResponse = $this->chatMessageModel->find($chat_message_id);
|
||||
return $this->response->setJSON($dataResponse);
|
||||
}
|
||||
public function get_chat_internal_contacts()
|
||||
{
|
||||
$users = $this->userModel->builder()
|
||||
->where("cliente_id", null)
|
||||
->whereNotIn("id", [auth()->user()->id])
|
||||
->where("deleted_at", null)
|
||||
->get()->getResultObject();
|
||||
foreach ($users as $user) {
|
||||
$user->unreadMessages = $this->chatMessageModel->get_chat_unread_messages_count($user->id);
|
||||
}
|
||||
return $this->response->setJSON($users);
|
||||
}
|
||||
public function get_chat_internal_contact(int $user_id)
|
||||
{
|
||||
$users = $this->userModel->builder()
|
||||
->where("cliente_id", null)
|
||||
->where("deleted_at", null)
|
||||
->where("id", $user_id)
|
||||
->get()->getFirstRow();
|
||||
$this->chatMessageModel->set_chat_messages_as_read($user_id);
|
||||
return $this->response->setJSON($users);
|
||||
}
|
||||
public function get_chat_internal_messages(int $user_id)
|
||||
{
|
||||
$conversation = $this->chatMessageModel->get_chat_contact_messages($user_id);
|
||||
return $this->response->setJSON($conversation);
|
||||
}
|
||||
}
|
||||
@ -36,23 +36,7 @@ class MensajesDirectos extends BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
// Modelos
|
||||
$participantModel = model('App\Models\Mensajeria\ParticipanteModel');
|
||||
|
||||
|
||||
$viewData = [
|
||||
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Paises.pais')]),
|
||||
'conversacionesEntity' => new ConversacionEntity(),
|
||||
'usingServerSideDataTable' => true,
|
||||
];
|
||||
|
||||
//$viewData['conversaciones'] = $participantModel->getChatsByUser(auth()->user()->id);
|
||||
$viewData['conversaciones'] = $participantModel->getChatsByUser(639);
|
||||
|
||||
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
|
||||
|
||||
return view(static::$viewPath . static::$indexRoute, $viewData);
|
||||
return view(static::$viewPath . static::$indexRoute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -22,6 +22,15 @@ class ChatDepartments extends Migration
|
||||
"type" => "VARCHAR",
|
||||
"constraint" => '255',
|
||||
],
|
||||
"description" => [
|
||||
"type" => "TEXT",
|
||||
"null" => true,
|
||||
],
|
||||
"type" => [
|
||||
"type" => "ENUM",
|
||||
'constraint' => ['general', 'presupuesto', 'pedido'],
|
||||
'default' => 'general',
|
||||
],
|
||||
|
||||
];
|
||||
public function up()
|
||||
|
||||
@ -16,11 +16,25 @@ class ChatsTable extends Migration
|
||||
"chat_department_id" => [
|
||||
"type" => "INT",
|
||||
"unsigned" => true,
|
||||
"null" => true
|
||||
],
|
||||
"pedido_id" => [
|
||||
"type" => "INT",
|
||||
"constraint" => 16,
|
||||
"unsigned" => true,
|
||||
"null" => true
|
||||
],
|
||||
"presupuesto_id" => [
|
||||
"type" => "INT",
|
||||
"constraint" => 10,
|
||||
"unsigned" => true,
|
||||
"null" => true
|
||||
],
|
||||
"factura_id" => [
|
||||
"type" => "INT",
|
||||
"constraint" => 10,
|
||||
"unsigned" => true,
|
||||
"null" => true
|
||||
],
|
||||
|
||||
|
||||
@ -31,6 +45,7 @@ class ChatsTable extends Migration
|
||||
$this->forge->dropTable("chat_mensajes", true);
|
||||
$this->forge->dropTable("chat_participantes", true);
|
||||
|
||||
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql("CURRENT_TIMESTAMP");
|
||||
$this->forge->addField([
|
||||
@ -51,6 +66,10 @@ class ChatsTable extends Migration
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('pedido_id', 'pedidos', 'id');
|
||||
$this->forge->addForeignKey('chat_department_id', 'chat_departments', 'id');
|
||||
$this->forge->addForeignKey('factura_id', 'facturas', 'id');
|
||||
$this->forge->addForeignKey('presupuesto_id', 'presupuestos', 'id');
|
||||
|
||||
|
||||
$this->forge->createTable("chats", true);
|
||||
}
|
||||
|
||||
|
||||
@ -17,14 +17,25 @@ class ChatMessages extends Migration
|
||||
"unsigned" => true
|
||||
],
|
||||
|
||||
"user_id" => [
|
||||
"sender_id" => [
|
||||
"type" => "INT",
|
||||
"unsigned" => true,
|
||||
"null" => true,
|
||||
|
||||
],
|
||||
"receiver_id" => [
|
||||
"type" => "INT",
|
||||
"unsigned" => true,
|
||||
"null" => true,
|
||||
],
|
||||
"message" => [
|
||||
"type" => "TEXT",
|
||||
],
|
||||
"viewed" => [
|
||||
"type" => "TEXT",
|
||||
"type" => "boolean",
|
||||
"default" => false,
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
@ -51,7 +62,8 @@ class ChatMessages extends Migration
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey(['user_id'], 'users', ['id']);
|
||||
$this->forge->addForeignKey(['receiver_id'], 'users', ['id']);
|
||||
$this->forge->addForeignKey(['sender_id'], 'users', ['id']);
|
||||
$this->forge->addForeignKey(['chat_id'], 'chats', ['id']);
|
||||
$this->forge->createTable("chat_messages", true);
|
||||
}
|
||||
|
||||
@ -18,7 +18,8 @@ class ChatSeeder extends Seeder
|
||||
"users" => [
|
||||
"mbalbaci@safekat.com",
|
||||
"mari.cano@safekat.com",
|
||||
"beatriz@safekat.com"
|
||||
"beatriz@safekat.com",
|
||||
"imnavajas@coit.es",
|
||||
],
|
||||
],
|
||||
[
|
||||
@ -26,6 +27,7 @@ class ChatSeeder extends Seeder
|
||||
"display" => "POD",
|
||||
"users" => [
|
||||
"pod@safekat.com",
|
||||
"imnavajas@coit.es",
|
||||
],
|
||||
],
|
||||
[
|
||||
@ -33,6 +35,7 @@ class ChatSeeder extends Seeder
|
||||
"display" => "Maquetación",
|
||||
"users" => [
|
||||
"maquetacion@safekat.com",
|
||||
"imnavajas@coit.es",
|
||||
],
|
||||
],
|
||||
// [
|
||||
@ -54,6 +57,7 @@ class ChatSeeder extends Seeder
|
||||
"display" => "Logística",
|
||||
"users" => [
|
||||
"logistica@safekat.com",
|
||||
"imnavajas@coit.es",
|
||||
],
|
||||
],
|
||||
[
|
||||
@ -61,19 +65,21 @@ class ChatSeeder extends Seeder
|
||||
"display" => "Administración",
|
||||
"users" => [
|
||||
"contabilidad@safekat.com",
|
||||
"imnavajas@coit.es",
|
||||
],
|
||||
],
|
||||
];
|
||||
$chatDeparmentModel = model(ChatDeparmentModel::class);
|
||||
$chatDeparmentUsersModel = model(ChatDeparmentUserModel::class);
|
||||
$userModel = model(UserModel::class);
|
||||
|
||||
foreach ($data as $row) {
|
||||
$chatDeparmentId = $chatDeparmentModel->insert(["name" => $row["name"], "display" => $row["display"]]);
|
||||
if (count($row["users"]) > 0) {
|
||||
foreach ($row["users"] as $mail) {
|
||||
$user = $userModel->like("username", $mail)->first();
|
||||
$user = $userModel->like("username", explode("@",$mail)[0])->first();
|
||||
|
||||
if ($user) {
|
||||
echo $user->id."\r\n";
|
||||
$chatDeparmentUsersModel->insert(['user_id' => $user->id, "chat_department_id" => $chatDeparmentId]);
|
||||
}
|
||||
}
|
||||
|
||||
5
ci4/app/Language/es/Chat.php
Normal file
5
ci4/app/Language/es/Chat.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
"chat" => "Chat"
|
||||
];
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Chat;
|
||||
|
||||
use App\Models\Usuarios\UserModel;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class ChatDeparmentModel extends Model
|
||||
@ -14,7 +15,9 @@ class ChatDeparmentModel extends Model
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"name",
|
||||
"display"
|
||||
"display",
|
||||
"description",
|
||||
"type"
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
@ -46,4 +49,53 @@ class ChatDeparmentModel extends Model
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
public function getChatDepartments(string $type = "general"): array
|
||||
{
|
||||
$userModel = model(UserModel::class);
|
||||
$query = $this->db->table('chat_departments')
|
||||
->select(
|
||||
[
|
||||
'chat_departments.id',
|
||||
'chat_departments.name',
|
||||
'chat_departments.display',
|
||||
'chat_department_users.user_id'
|
||||
]
|
||||
)
|
||||
->join(
|
||||
"chat_department_users",
|
||||
"chat_department_users.chat_department_id = chat_departments.id",
|
||||
'left'
|
||||
)
|
||||
->join(
|
||||
"users",
|
||||
"chat_department_users.user_id = users.id",
|
||||
'left'
|
||||
)->where("chat_departments.type",$type)
|
||||
->where("chat_department_users.user_id",auth()->user()->id);
|
||||
|
||||
$results = $query->get()->getResultArray();
|
||||
// Create the desired structure
|
||||
$departments = [];
|
||||
|
||||
foreach ($results as $row) {
|
||||
$departmentName = $row['name'];
|
||||
|
||||
// If the department is not yet added to the array, initialize it
|
||||
if (!isset($departments[$departmentName])) {
|
||||
$departments[$departmentName] = [
|
||||
'id' => $row['id'],
|
||||
'name' => $row['name'],
|
||||
'display' => $row['display'],
|
||||
'users' => [] // Initialize users as an empty array
|
||||
];
|
||||
}
|
||||
|
||||
// If user_id is not null, add the user to the department's 'users' array
|
||||
if ($row['user_id']) {
|
||||
$departments[$departmentName]['users'][] = $userModel->find($row["user_id"]);
|
||||
}
|
||||
}
|
||||
return $departments;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Models\Chat;
|
||||
|
||||
|
||||
use App\Models\Usuarios\UserModel;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class ChatMessageModel extends Model
|
||||
@ -13,7 +13,13 @@ class ChatMessageModel extends Model
|
||||
protected $returnType = 'array';
|
||||
protected $useSoftDeletes = false;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [];
|
||||
protected $allowedFields = [
|
||||
"message",
|
||||
"chat_id",
|
||||
"sender_id",
|
||||
"receiver_id",
|
||||
"viewed"
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
@ -44,4 +50,72 @@ class ChatMessageModel extends Model
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
/**
|
||||
* Devuelve los mensajes del chat
|
||||
*
|
||||
* @param integer $chat_id
|
||||
* @return object
|
||||
*/
|
||||
public function get_chat_messages(int $chat_id): array
|
||||
{
|
||||
$user = model(UserModel::class);
|
||||
$messages = $this->builder()->where("chat_id", $chat_id)->orderBy("created_at", "asc")->get()->getResultObject();
|
||||
foreach ($messages as $message) {
|
||||
$message->pos = auth()->user()->id == $message->sender_id ? "right" : "left";
|
||||
if (auth()->user()->id == $message->sender_id) {
|
||||
$message->user = auth()->user();
|
||||
} else {
|
||||
$message->user = $user->find($message->sender_id);
|
||||
}
|
||||
}
|
||||
return $messages;
|
||||
}
|
||||
public function get_chat_contact_messages(int $receiver_id): array
|
||||
{
|
||||
$conversationArray = [];
|
||||
$userModel = model(UserModel::class);
|
||||
$receiverUser = $userModel->find($receiver_id);
|
||||
$messagesFromClient = $this->builder()
|
||||
->where("sender_id", auth()->user()->id)
|
||||
->where("receiver_id", $receiverUser->id)
|
||||
->get()->getResultObject();
|
||||
$messagesFromReceiver = $this->builder()
|
||||
->where("sender_id", $receiver_id)
|
||||
->where("receiver_id", auth()->user()->id)
|
||||
->get()->getResultObject();
|
||||
foreach ($messagesFromClient as $message) {
|
||||
$message->pos = "right";
|
||||
$message->user = auth()->user();
|
||||
$conversationArray[] = $message;
|
||||
}
|
||||
foreach ($messagesFromReceiver as $message) {
|
||||
$message->pos = "left";
|
||||
$message->user = $receiverUser;
|
||||
$conversationArray[] = $message;
|
||||
}
|
||||
$dates = array();
|
||||
foreach ($conversationArray as $key => $row) {
|
||||
$dates[$key] = strtotime($row->created_at);
|
||||
}
|
||||
array_multisort($dates, SORT_ASC, $conversationArray);
|
||||
return $conversationArray;
|
||||
}
|
||||
|
||||
public function get_chat_unread_messages_count(int $sender_id): int
|
||||
{
|
||||
$messagesFromReceiver = $this->builder()
|
||||
->where("sender_id", $sender_id)
|
||||
->where("viewed", false)
|
||||
->where("receiver_id", auth()->user()->id)->countAllResults();
|
||||
return $messagesFromReceiver;
|
||||
}
|
||||
public function set_chat_messages_as_read(int $sender_id): int
|
||||
{
|
||||
$messagesFromReceiver = $this->builder()
|
||||
->set("viewed", true)
|
||||
->where("sender_id", $sender_id)
|
||||
->where("receiver_id", auth()->user()->id)->update();
|
||||
return $messagesFromReceiver;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ namespace App\Models\Chat;
|
||||
|
||||
|
||||
use CodeIgniter\Model;
|
||||
use stdClass;
|
||||
|
||||
class ChatModel extends Model
|
||||
{
|
||||
@ -15,7 +16,9 @@ class ChatModel extends Model
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"pedido_id",
|
||||
"chat_department_id"
|
||||
"chat_department_id",
|
||||
"presupuesto_id",
|
||||
"factura_id",
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
@ -49,22 +52,145 @@ class ChatModel extends Model
|
||||
protected $afterDelete = [];
|
||||
|
||||
|
||||
public function getChat(int $chat_id)
|
||||
public function getChat(int $chat_id): array
|
||||
{
|
||||
$this->db->table('chats')
|
||||
return $this->db->table('chats')
|
||||
->select(
|
||||
[
|
||||
"chats.id as chatId",
|
||||
"users.id as userId",
|
||||
"chats.pedido_id as pedidoId",
|
||||
"users.email",
|
||||
"chats.*",
|
||||
"chat_messages.created_at as messageCreatedAt",
|
||||
"chat_messages.message as messageText",
|
||||
]
|
||||
)
|
||||
->join("users", "users.id == chat_messages.user_id", "left")
|
||||
->join("chat_deparments", "chat_deparments.id == chats.chat_deparment_id", "left")
|
||||
->join("chat_messages", "chats.id == chat_messages.chat_id", "left")
|
||||
->where("chatId", $chat_id)->get()->getResultObject();
|
||||
->join("chat_messages", "chats.id = chat_messages.chat_id", "left")
|
||||
->orderBy("created_at", "desc")
|
||||
->where("chats.id", $chat_id)
|
||||
->get()->getResultObject();
|
||||
}
|
||||
public function getChatPresupuesto(int $chat_department_id, int $presupuesto_id)
|
||||
{
|
||||
return $this->builder()->where("presupuesto_id", $presupuesto_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow();
|
||||
}
|
||||
public function getChatPedido(int $chat_department_id, int $pedido_id)
|
||||
{
|
||||
return $this->builder()->where("pedido_id", $pedido_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow();
|
||||
}
|
||||
public function getChatFactura(int $chat_department_id, int $factura_id)
|
||||
{
|
||||
return $this->builder()->where("factura_id", $factura_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow();
|
||||
}
|
||||
|
||||
public function createChatPresupuesto(int $chat_department_id, int $presupuesto_id): int
|
||||
{
|
||||
return $this->insert([
|
||||
"presupuesto_id" => $presupuesto_id,
|
||||
"chat_department_id" => $chat_department_id
|
||||
]);
|
||||
}
|
||||
public function createChatPedido(int $chat_department_id, int $pedido_id) : int
|
||||
{
|
||||
|
||||
return $this->insert([
|
||||
"pedido_id" => $pedido_id,
|
||||
"chat_department_id" => $chat_department_id
|
||||
]);
|
||||
}
|
||||
public function createChatFactura(int $chat_department_id, int $factura_id) : int
|
||||
{
|
||||
|
||||
return $this->insert([
|
||||
"factura_id" => $factura_id,
|
||||
"chat_department_id" => $chat_department_id
|
||||
]);
|
||||
}
|
||||
public function createChatSingle() : int
|
||||
{
|
||||
return $this->insert(["chat_department_id" => null]);
|
||||
}
|
||||
public function existChatPresupuesto(int $chat_department_id, int $presupuesto_id): bool
|
||||
{
|
||||
$countChatPresupuesto = $this->builder()
|
||||
->where("presupuesto_id", $presupuesto_id)
|
||||
->where("chat_department_id", $chat_department_id)
|
||||
->countAllResults();
|
||||
return $countChatPresupuesto > 0;
|
||||
}
|
||||
public function existChatPedido(int $chat_department_id, int $pedido_id): bool
|
||||
{
|
||||
$countChatPresupuesto = $this->builder()
|
||||
->where("pedido_id", $pedido_id)
|
||||
->where("chat_department_id", $chat_department_id)
|
||||
->countAllResults();
|
||||
return $countChatPresupuesto > 0;
|
||||
}
|
||||
public function existChatFactura(int $chat_department_id, int $factura_id): bool
|
||||
{
|
||||
$countChatPresupuesto = $this->builder()
|
||||
->where("factura_id", $factura_id)
|
||||
->where("chat_department_id", $chat_department_id)
|
||||
->countAllResults();
|
||||
return $countChatPresupuesto > 0;
|
||||
}
|
||||
|
||||
public function getChatPedidosChat() : array
|
||||
{
|
||||
$query = $this->db->table("chats")
|
||||
->select([
|
||||
"chats.id as chatId",
|
||||
"chats.pedido_id as pedidoId",
|
||||
"chats.chat_department_id as chatDepartmentId",
|
||||
"chat_departments.display as chatDisplay",
|
||||
"pedidos.id as title"
|
||||
])
|
||||
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
|
||||
->join("pedidos","pedidos.id = chats.pedido_id","left")
|
||||
->get()->getResultObject();
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getChatPresupuestosChat() : array
|
||||
{
|
||||
$query = $this->db->table("chats")
|
||||
->select([
|
||||
"chats.id as chatId",
|
||||
"chats.pedido_id as pedidoId",
|
||||
"chats.chat_department_id as chatDepartmentId",
|
||||
"chat_departments.display as chatDisplay",
|
||||
"presupuestos.titulo as title"
|
||||
])
|
||||
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
|
||||
->join("presupuestos","presupuestos.id = chats.pedido_id","left")
|
||||
->get()->getResultObject();
|
||||
return $query;
|
||||
}
|
||||
public function getChatFacturasChat() : array
|
||||
{
|
||||
$query = $this->db->table("chats")
|
||||
->select([
|
||||
"chats.id as chatId",
|
||||
"chats.pedido_id as pedidoId",
|
||||
"chats.chat_department_id as chatDepartmentId",
|
||||
"chat_departments.display as chatDisplay",
|
||||
"facturas.numero as title"
|
||||
])
|
||||
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
|
||||
->join("facturas","facturas.id = chats.pedido_id","left")
|
||||
->get()->getResultObject();
|
||||
return $query;
|
||||
}
|
||||
public function getChatSingleChat() : array
|
||||
{
|
||||
$query = $this->db->table("chats")
|
||||
->select([
|
||||
"chats.id as chatId",
|
||||
"chats.chat_department_id as chatDepartmentId",
|
||||
"chat_departments.display as chatDisplay",
|
||||
"facturas.numero as title"
|
||||
])
|
||||
->join("chat_departments","chat_departments.id = chats.chat_department_id","left")
|
||||
->join("facturas","facturas.id = chats.pedido_id","left")
|
||||
->get()->getResultObject();
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -781,4 +781,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
|
||||
return $description_interior . $description_cubierta . $description_sobrecubierta . $acabado;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
161
ci4/app/Views/themes/vuexy/components/chat_factura.php
Normal file
161
ci4/app/Views/themes/vuexy/components/chat_factura.php
Normal file
@ -0,0 +1,161 @@
|
||||
<div class="accordion accordion-bordered mt-3" id="accordionChatFactura">
|
||||
<div class="card accordion-item active">
|
||||
<h2 class="accordion-header" id="headingChatFactura">
|
||||
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionChatFacturaTip" aria-expanded="false" aria-controls="accordionAlbaranesTip">
|
||||
<h3><?= lang("Chat.chat") ?></h3>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="accordionChatFacturaTip" class="accordion-collapse collapse show" data-bs-parent="#accordionChatPresupuesto">
|
||||
<div class="accordion-body">
|
||||
<div class="container-xxl flex-grow-1 container-p-y" id="chat-presupuesto" data-id="<?= $facturaId ?>">
|
||||
<div class="app-chat card overflow-hidden">
|
||||
<div class="row g-0">
|
||||
|
||||
<!-- Chat & Contacts -->
|
||||
<div
|
||||
class="col app-chat-contacts app-sidebar flex-grow-0 overflow-hidden border-end"
|
||||
id="app-chat-contacts">
|
||||
<div class="sidebar-header">
|
||||
<div class="d-flex align-items-center me-3 me-lg-0">
|
||||
<div class="flex-shrink-0 avatar me-3">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">U</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow-1 input-group input-group-merge rounded-pill">
|
||||
<span class="input-group-text" id="basic-addon-search31">
|
||||
<i class="ti ti-search"></i>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control chat-search-input"
|
||||
placeholder="Buscar..."
|
||||
aria-label="Buscar..."
|
||||
aria-describedby="basic-addon-search31" />
|
||||
</div>
|
||||
</div>
|
||||
<i
|
||||
class="ti ti-x cursor-pointer d-lg-none d-block position-absolute mt-2 me-1 top-0 end-0"
|
||||
data-overlay
|
||||
data-bs-toggle="sidebar"
|
||||
data-target="#app-chat-contacts"></i>
|
||||
</div>
|
||||
<hr class="container-m-nx m-0" />
|
||||
<div class="sidebar-body">
|
||||
<div class="chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Departamentos</h5>
|
||||
</div>
|
||||
<!-- Chats -->
|
||||
<ul class="list-unstyled chat-contact-list" id="chat-list">
|
||||
<li class="chat-contact-list-item chat-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Chats Found</h6>
|
||||
</li>
|
||||
<!-- CHAT LIST -->
|
||||
|
||||
</ul>
|
||||
<!-- Contacts -->
|
||||
<ul class="list-unstyled chat-contact-list mb-0" id="contact-list">
|
||||
<!-- <li class="chat-contact-list-item chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0">Contacts</h5>
|
||||
</li>
|
||||
<li class="chat-contact-list-item contact-list-item-0 ">
|
||||
<h6 class="text-muted mb-0">No Contacts Found</h6>
|
||||
</li> -->
|
||||
<!-- <li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">JJ</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Jaime Jimenez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li> -->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat contacts -->
|
||||
|
||||
<!-- Chat History -->
|
||||
<div class="col app-chat-history bg-body">
|
||||
<div class="chat-history-wrapper ">
|
||||
<div class="chat-history-header border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex overflow-hidden align-items-center">
|
||||
<i
|
||||
class="ti ti-menu-2 ti-sm cursor-pointer d-lg-none d-block me-2"
|
||||
data-bs-toggle="sidebar"
|
||||
data-overlay
|
||||
data-target="#app-chat-contacts"></i>
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">P</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="m-0">Departamento Producción</h6>
|
||||
<small class="user-status text-muted">Consulta sobre el presupuesto P001</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="dropdown d-flex align-self-center">
|
||||
<button
|
||||
class="btn p-0"
|
||||
type="button"
|
||||
id="chat-header-actions"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="chat-header-actions">
|
||||
<a class="dropdown-item" href="javascript:void(0);">Silenciar Conversacion</a>
|
||||
<a class="dropdown-item" href="javascript:void(0);">Limpiar Conversacion</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-history-body bg-body ">
|
||||
<ul class="list-unstyled chat-history" id="chat-conversation">
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Chat message form -->
|
||||
<div class="chat-history-footer shadow-sm">
|
||||
<div class="form-send-message d-flex justify-content-between align-items-center">
|
||||
<input
|
||||
class="form-control message-input border-0 me-3 shadow-none"
|
||||
placeholder="Type your message here" />
|
||||
<div class="message-actions d-flex align-items-center">
|
||||
|
||||
<a class="btn btn-primary d-flex send-msg-btn ">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block d-none">Enviar</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat History -->
|
||||
|
||||
<div class="app-overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||
<?= $this->endSection() ?>
|
||||
<!------------------------------------------------------->
|
||||
<!-- Código JS logica -->
|
||||
<!------------------------------------------------------->
|
||||
<?= $this->section("additionalExternalJs") ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/chatPresupuesto.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<!-- <script src="<?= site_url('js_loader/chat_js') ?>"></script> -->
|
||||
<?= $this->endSection() ?>
|
||||
164
ci4/app/Views/themes/vuexy/components/chat_pedido.php
Normal file
164
ci4/app/Views/themes/vuexy/components/chat_pedido.php
Normal file
@ -0,0 +1,164 @@
|
||||
<div class="accordion accordion-bordered mt-3" id="accordionChatPedido">
|
||||
<div class="card accordion-item active">
|
||||
<h2 class="accordion-header" id="headingChatPedido">
|
||||
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionChatPedidoTip" aria-expanded="false" aria-controls="accordionAlbaranesTip">
|
||||
<h3><?= lang("Chat.chat") ?></h3>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="accordionChatPedidoTip" class="accordion-collapse collapse show" data-bs-parent="#accordionChatPedido">
|
||||
<div class="accordion-body">
|
||||
<div class="container-xxl flex-grow-1 container-p-y" id="chat-pedido" data-id="<?= $pedidoId ?>">
|
||||
|
||||
<div class="app-chat card overflow-hidden">
|
||||
<div class="row g-0">
|
||||
|
||||
<!-- Chat & Contacts -->
|
||||
<div
|
||||
class="col app-chat-contacts app-sidebar flex-grow-0 overflow-hidden border-end"
|
||||
id="app-chat-contacts">
|
||||
<div class="sidebar-header">
|
||||
<div class="d-flex align-items-center me-3 me-lg-0">
|
||||
<div class="flex-shrink-0 avatar me-3">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">U</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow-1 input-group input-group-merge rounded-pill">
|
||||
<span class="input-group-text" id="basic-addon-search31">
|
||||
<i class="ti ti-search"></i>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control chat-search-input"
|
||||
placeholder="Buscar..."
|
||||
aria-label="Buscar..."
|
||||
aria-describedby="basic-addon-search31" />
|
||||
</div>
|
||||
</div>
|
||||
<i
|
||||
class="ti ti-x cursor-pointer d-lg-none d-block position-absolute mt-2 me-1 top-0 end-0"
|
||||
data-overlay
|
||||
data-bs-toggle="sidebar"
|
||||
data-target="#app-chat-contacts"></i>
|
||||
</div>
|
||||
<hr class="container-m-nx m-0" />
|
||||
<div class="sidebar-body">
|
||||
<div class="chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Pedidos</h5>
|
||||
</div>
|
||||
<!-- Chats -->
|
||||
<ul class="list-unstyled chat-contact-list" id="chat-list">
|
||||
<li class="chat-contact-list-item chat-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Chats Found</h6>
|
||||
</li>
|
||||
<!-- CHAT LIST -->
|
||||
|
||||
</ul>
|
||||
<!-- Contacts -->
|
||||
<ul class="list-unstyled chat-contact-list mb-0" id="contact-list">
|
||||
<!-- <li class="chat-contact-list-item chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0">Contacts</h5>
|
||||
</li>
|
||||
<li class="chat-contact-list-item contact-list-item-0 ">
|
||||
<h6 class="text-muted mb-0">No Contacts Found</h6>
|
||||
</li> -->
|
||||
<!-- <li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">JJ</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Jaime Jimenez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li> -->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat contacts -->
|
||||
|
||||
<!-- Chat History -->
|
||||
<div class="col app-chat-history bg-body">
|
||||
<div class="chat-history-wrapper ">
|
||||
<div class="chat-history-header border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex overflow-hidden align-items-center">
|
||||
<i
|
||||
class="ti ti-menu-2 ti-sm cursor-pointer d-lg-none d-block me-2"
|
||||
data-bs-toggle="sidebar"
|
||||
data-overlay
|
||||
data-target="#app-chat-contacts"></i>
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">P</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="m-0"></h6>
|
||||
<small class="user-status text-muted"></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="dropdown d-flex align-self-center">
|
||||
<button
|
||||
class="btn p-0"
|
||||
type="button"
|
||||
id="chat-header-actions"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="chat-header-actions">
|
||||
<a class="dropdown-item" href="javascript:void(0);">Silenciar Conversacion</a>
|
||||
<a class="dropdown-item" href="javascript:void(0);">Limpiar Conversacion</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-history-body bg-body ">
|
||||
<ul class="list-unstyled chat-history" id="chat-conversation">
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Chat message form -->
|
||||
<div class="chat-history-footer shadow-sm">
|
||||
<div class="form-send-message d-flex justify-content-between align-items-center">
|
||||
<input
|
||||
class="form-control message-input border-0 me-3 shadow-none"
|
||||
placeholder="Type your message here" />
|
||||
<div class="message-actions d-flex align-items-center">
|
||||
|
||||
<a class="btn btn-primary d-flex send-msg-btn ">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block d-none">Enviar</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat History -->
|
||||
|
||||
<div class="app-overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||
<?= $this->endSection() ?>
|
||||
<!------------------------------------------------------->
|
||||
<!-- Código JS logica -->
|
||||
<!------------------------------------------------------->
|
||||
<?= $this->section("additionalExternalJs") ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/chatPedido.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<!-- <script src="<?= site_url('js_loader/chat_js') ?>"></script> -->
|
||||
<?= $this->endSection() ?>
|
||||
156
ci4/app/Views/themes/vuexy/components/chat_presupuesto.php
Normal file
156
ci4/app/Views/themes/vuexy/components/chat_presupuesto.php
Normal file
@ -0,0 +1,156 @@
|
||||
<div class="accordion accordion-bordered mt-3" id="accordionChatPresupuesto">
|
||||
<div class="card accordion-item active">
|
||||
<h2 class="accordion-header" id="headingChatPresupuesto">
|
||||
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionChatPresupuestoTip" aria-expanded="false" aria-controls="accordionAlbaranesTip">
|
||||
<h3><?= lang("Chat.chat") ?></h3>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="accordionChatPresupuestoTip" class="accordion-collapse collapse show" data-bs-parent="#accordionChatPresupuesto">
|
||||
<div class="accordion-body">
|
||||
<div class="container-xxl flex-grow-1" id="chat-presupuesto" data-id="<?= $modelId ?>">
|
||||
<div class="app-chat card overflow-hidden">
|
||||
<div class="row g-0">
|
||||
|
||||
<!-- Chat & Contacts -->
|
||||
<div
|
||||
class="col app-chat-contacts app-sidebar flex-grow-0 overflow-hidden border-end"
|
||||
id="app-chat-contacts">
|
||||
<div class="sidebar-header">
|
||||
<div class="d-flex align-items-center me-3 me-lg-0">
|
||||
<div class="flex-shrink-0 avatar me-3">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">U</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow-1 input-group input-group-merge rounded-pill">
|
||||
<span class="input-group-text" id="basic-addon-search31">
|
||||
<i class="ti ti-search"></i>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control chat-search-input"
|
||||
placeholder="Buscar..."
|
||||
aria-label="Buscar..."
|
||||
aria-describedby="basic-addon-search31" />
|
||||
</div>
|
||||
</div>
|
||||
<i
|
||||
class="ti ti-x cursor-pointer d-lg-none d-block position-absolute mt-2 me-1 top-0 end-0"
|
||||
data-overlay
|
||||
data-bs-toggle="sidebar"
|
||||
data-target="#app-chat-contacts"></i>
|
||||
</div>
|
||||
<hr class="container-m-nx m-0" />
|
||||
<div class="sidebar-body">
|
||||
<div class="chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Departamentos</h5>
|
||||
</div>
|
||||
<!-- Chats -->
|
||||
<ul class="list-unstyled chat-contact-list" id="chat-list">
|
||||
<li class="chat-contact-list-item chat-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Chats Found</h6>
|
||||
</li>
|
||||
<!-- CHAT LIST -->
|
||||
|
||||
</ul>
|
||||
<!-- Contacts -->
|
||||
<ul class="list-unstyled chat-contact-list mb-0 d-none" id="contact-list">
|
||||
<li class="chat-contact-list-item chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0">Contacts</h5>
|
||||
</li>
|
||||
<li class="chat-contact-list-item contact-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Contacts Found</h6>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat contacts -->
|
||||
|
||||
<!-- Chat History -->
|
||||
<div class="col app-chat-history bg-body">
|
||||
<div class="chat-history-wrapper ">
|
||||
<div class="chat-history-header border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex overflow-hidden align-items-center">
|
||||
<i
|
||||
class="ti ti-menu-2 ti-sm cursor-pointer d-lg-none d-block me-2"
|
||||
data-bs-toggle="sidebar"
|
||||
data-overlay
|
||||
data-target="#app-chat-contacts"></i>
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">P</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="m-0">Departamento Producción</h6>
|
||||
<small class="user-status text-muted">Consulta sobre el presupuesto P001</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="dropdown d-flex align-self-center">
|
||||
<button
|
||||
class="btn p-0"
|
||||
type="button"
|
||||
id="chat-header-actions"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="chat-header-actions">
|
||||
<a class="dropdown-item" href="javascript:void(0);">Silenciar Conversacion</a>
|
||||
<a class="dropdown-item" href="javascript:void(0);">Limpiar Conversacion</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-history-body bg-body ">
|
||||
<ul class="list-unstyled chat-history" id="chat-conversation">
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Chat message form -->
|
||||
<div class="chat-history-footer shadow-sm">
|
||||
<div class="form-send-message d-flex justify-content-between align-items-center">
|
||||
<input
|
||||
class="form-control message-input border-0 me-3 shadow-none"
|
||||
placeholder="Type your message here" />
|
||||
<div class="message-actions d-flex align-items-center">
|
||||
|
||||
<a class="btn btn-success d-flex send-msg-btn" id="send-msg-btn-deparment">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block">Enviar</span>
|
||||
</a>
|
||||
<a class="btn btn-success d-flex send-msg-btn" id="send-msg-btn-internal">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block ">Enviar</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat History -->
|
||||
|
||||
<div class="app-overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||
<?= $this->endSection() ?>
|
||||
<!------------------------------------------------------->
|
||||
<!-- Código JS logica -->
|
||||
<!------------------------------------------------------->
|
||||
<?= $this->section("additionalExternalJs") ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/chatPresupuesto.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<!-- <script src="<?= site_url('js_loader/chat_js') ?>"></script> -->
|
||||
<?= $this->endSection() ?>
|
||||
@ -86,53 +86,53 @@ function searchChatContacts(searchListItems, searchValue) {
|
||||
|
||||
// Enviar mensaje
|
||||
if (sendMsgBtn.length) {
|
||||
sendMsgBtn.on('click', function (e) {
|
||||
e.preventDefault();
|
||||
if (messageInput.val()) {
|
||||
const renderMsg = $('<div>').addClass('chat-message-text mt-2').html(`<p class="mb-0">${messageInput.val()}</p>`);
|
||||
const lastChatMessageWrapper = $('li:last-child .chat-message-wrapper');
|
||||
if (lastChatMessageWrapper.length) {
|
||||
lastChatMessageWrapper.append(renderMsg);
|
||||
}
|
||||
messageInput.val('');
|
||||
scrollToBottom();
|
||||
}
|
||||
});
|
||||
// sendMsgBtn.on('click', function (e) {
|
||||
// e.preventDefault();
|
||||
// if (messageInput.val()) {
|
||||
// const renderMsg = $('<div>').addClass('chat-message-text mt-2').html(`<p class="mb-0">${messageInput.val()}</p>`);
|
||||
// const lastChatMessageWrapper = $('li:last-child .chat-message-wrapper');
|
||||
// if (lastChatMessageWrapper.length) {
|
||||
// lastChatMessageWrapper.append(renderMsg);
|
||||
// }
|
||||
// messageInput.val('');
|
||||
// scrollToBottom();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
// Seleccionar los elementos <p> con la clase .chat-contact-status
|
||||
$('.chat-contact-status').on('click', function () {
|
||||
// Obtener el id de la conversación desde el atributo id del elemento <p>
|
||||
var conversationId = $(this).attr('id');
|
||||
// // Seleccionar los elementos <p> con la clase .chat-contact-status
|
||||
// $('.chat-contact-status').on('click', function () {
|
||||
// // Obtener el id de la conversación desde el atributo id del elemento <p>
|
||||
// var conversationId = $(this).attr('id');
|
||||
|
||||
console.log(conversationId)
|
||||
// console.log(conversationId)
|
||||
|
||||
// Realizar la llamada AJAX
|
||||
$.ajax({
|
||||
url: 'internos/chat/' + conversationId, // Cambia esta URL por la ruta correcta a tu API
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
// Manejar la respuesta exitosa de la llamada AJAX
|
||||
console.log('Datos recibidos:', data);
|
||||
// Aquí puedes actualizar el DOM o realizar otras acciones con los datos recibidos
|
||||
if (Array.isArray(data.people) && data.people.length > 0) {
|
||||
// Limpiar el contenedor donde se mostrarán los participantes
|
||||
$('#participants-container').empty();
|
||||
data.people.forEach(person => {
|
||||
// Crear el HTML para cada participante y agregarlo al contenedor
|
||||
var participantHtml = `
|
||||
<div class="avatar d-block flex-shrink-0 me-2">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary ">${person.user_id}</span>
|
||||
</div>`;
|
||||
$('#participants-container').append(participantHtml);
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
// Manejar errores en la llamada AJAX
|
||||
console.error('Error en la llamada AJAX:', textStatus, errorThrown);
|
||||
}
|
||||
});
|
||||
})
|
||||
;
|
||||
// // Realizar la llamada AJAX
|
||||
// $.ajax({
|
||||
// url: 'internos/chat/' + conversationId, // Cambia esta URL por la ruta correcta a tu API
|
||||
// type: 'GET',
|
||||
// dataType: 'json',
|
||||
// success: function (data) {
|
||||
// // Manejar la respuesta exitosa de la llamada AJAX
|
||||
// console.log('Datos recibidos:', data);
|
||||
// // Aquí puedes actualizar el DOM o realizar otras acciones con los datos recibidos
|
||||
// if (Array.isArray(data.people) && data.people.length > 0) {
|
||||
// // Limpiar el contenedor donde se mostrarán los participantes
|
||||
// $('#participants-container').empty();
|
||||
// data.people.forEach(person => {
|
||||
// // Crear el HTML para cada participante y agregarlo al contenedor
|
||||
// var participantHtml = `
|
||||
// <div class="avatar d-block flex-shrink-0 me-2">
|
||||
// <span class="avatar-initial rounded-circle bg-label-primary ">${person.user_id}</span>
|
||||
// </div>`;
|
||||
// $('#participants-container').append(participantHtml);
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// error: function (jqXHR, textStatus, errorThrown) {
|
||||
// // Manejar errores en la llamada AJAX
|
||||
// console.error('Error en la llamada AJAX:', textStatus, errorThrown);
|
||||
// }
|
||||
// });
|
||||
// })
|
||||
// ;
|
||||
@ -5,360 +5,12 @@
|
||||
<?= $this->section('content'); ?>
|
||||
<!--Content Body-->
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="app-chat card overflow-hidden">
|
||||
<div class="row g-0">
|
||||
<!-- Chat & Contacts -->
|
||||
<div
|
||||
class="col app-chat-contacts app-sidebar flex-grow-0 overflow-hidden border-end"
|
||||
id="app-chat-contacts">
|
||||
<div class="sidebar-header">
|
||||
<div class="d-flex align-items-center me-3 me-lg-0">
|
||||
<div class="flex-shrink-0 avatar me-3">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">U</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow-1 input-group input-group-merge rounded-pill">
|
||||
<span class="input-group-text" id="basic-addon-search31">
|
||||
<i class="ti ti-search"></i>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control chat-search-input"
|
||||
placeholder="Buscar..."
|
||||
aria-label="Buscar..."
|
||||
aria-describedby="basic-addon-search31"/>
|
||||
</div>
|
||||
</div>
|
||||
<i
|
||||
class="ti ti-x cursor-pointer d-lg-none d-block position-absolute mt-2 me-1 top-0 end-0"
|
||||
data-overlay
|
||||
data-bs-toggle="sidebar"
|
||||
data-target="#app-chat-contacts"></i>
|
||||
</div>
|
||||
<hr class="container-m-nx m-0"/>
|
||||
<div class="sidebar-body">
|
||||
<div class="chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Conversaciones</h5>
|
||||
</div>
|
||||
<!-- Chats -->
|
||||
<ul class="list-unstyled chat-contact-list" id="chat-list">
|
||||
<li class="chat-contact-list-item chat-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No hay conversaciones</h6>
|
||||
</li>
|
||||
<?php foreach ($conversaciones as $conversacion): ?>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="flex-shrink-0 avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-secondary">SK</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Safekat Interno</h6>
|
||||
<p
|
||||
id="<?= $conversacion->id ?>"
|
||||
class="chat-contact-status text-muted text-truncate mb-0"
|
||||
title="<?= $conversacion->asunto ?>"
|
||||
>
|
||||
<?= $conversacion->asunto ?>
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</ul>
|
||||
<!-- Contacts -->
|
||||
<ul class="list-unstyled chat-contact-list mb-0" id="contact-list">
|
||||
<li class="chat-contact-list-item chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0">Contacts</h5>
|
||||
</li>
|
||||
<li class="chat-contact-list-item contact-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Contacts Found</h6>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">IM</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Ignacio Martinez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">JJ</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Jaime Jimenez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat contacts -->
|
||||
|
||||
<!-- Chat History -->
|
||||
<div class="col app-chat-history bg-body">
|
||||
<div class="chat-history-wrapper">
|
||||
<div class="chat-history-header border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div id="participants-container" class="d-flex overflow-hidden align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">P</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="dropdown d-flex align-self-center">
|
||||
<button
|
||||
class="btn p-0"
|
||||
type="button"
|
||||
id="chat-header-actions"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end"
|
||||
aria-labelledby="chat-header-actions">
|
||||
<a class="dropdown-item" href="javascript:void(0);">Silenciar
|
||||
Conversacion</a>
|
||||
<a class="dropdown-item" href="javascript:void(0);">Limpiar Conversacion</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-history-body bg-body">
|
||||
<ul class="list-unstyled chat-history">
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">How can we help? We're here for you! 😄</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:00 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Hey John, I am looking for the best admin template.</p>
|
||||
<p class="mb-0">Could you please help me to find it out? 🤔</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">It should be Bootstrap 5 compatible.</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:02 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Vuexy has all the components you'll ever need in a
|
||||
app.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:03 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Looks clean and fresh UI. 😃</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">It's perfect for my next project.</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">How can I purchase it?</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:05 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Thanks, you can purchase it.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:06 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">I will purchase it for sure. 👍</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">Thanks.</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:08 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Great, Feel free to get in touch.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:10 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Do you have design files for Vuexy?</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:15 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1 w-50">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">
|
||||
Yes that's correct documentation file, Design files are included
|
||||
with
|
||||
the template.
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1"></i>
|
||||
<small>10:15 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Chat message form -->
|
||||
<div class="chat-history-footer shadow-sm">
|
||||
<div class="form-send-message d-flex justify-content-between align-items-center">
|
||||
<input
|
||||
class="form-control message-input border-0 me-3 shadow-none"
|
||||
placeholder="Type your message here"
|
||||
/>
|
||||
<div class="message-actions d-flex align-items-center">
|
||||
<a class="btn btn-primary d-flex send-msg-btn">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block d-none">Send</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Chat History -->
|
||||
</div>
|
||||
</div>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria",data:["presupuestoId" => null]) ?>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('additionalInlineJs') ?>
|
||||
|
||||
|
||||
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
<?= $this->section('additionalExternalJs') ?>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<script src="<?= site_url('js_loader/chat_js') ?>"></script>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
@ -19,8 +19,9 @@
|
||||
<?= view("themes/vuexy/form/pedidos/_lineasItems") ?>
|
||||
<?php if (!(auth()->user()->inGroup('cliente-admin') || auth()->user()->inGroup('cliente-editor'))) : ?>
|
||||
<?= view("themes/vuexy/form/pedidos/_albaranesItems") ?>
|
||||
<?php endif; ?>
|
||||
<?= view("themes/vuexy/form/pedidos/_facturasItems") ?>
|
||||
<?php endif; ?>
|
||||
<?= view("themes/vuexy/form/pedidos/_facturasItems") ?>
|
||||
<?= view("themes/vuexy/components/chat_pedido",data:["pedidoId" => $pedidoEntity->id]) ?>
|
||||
</div><!-- /.card-body -->
|
||||
<div class="pt-4">
|
||||
<?= anchor(route_to("listaPresupuestos"), lang("Basic.global.Cancel"), ["class" => "btn btn-secondary float-start"]) ?>
|
||||
@ -30,6 +31,7 @@
|
||||
</div><!--//.col -->
|
||||
</div><!--//.row -->
|
||||
<?= view("themes/_commonPartialsBs/_modalConfirmDialog") ?>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-xxl flex-grow-1 container-p-y" id="chat-presupuesto" data-id="<?=$presupuestoId ?>">
|
||||
<div class="app-chat card overflow-hidden">
|
||||
<div class="row g-0">
|
||||
|
||||
@ -33,56 +33,14 @@
|
||||
<hr class="container-m-nx m-0"/>
|
||||
<div class="sidebar-body">
|
||||
<div class="chat-contact-list-item-title">
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Chats</h5>
|
||||
<h5 class="text-primary mb-0 px-4 pt-3 pb-2">Departamentos</h5>
|
||||
</div>
|
||||
<!-- Chats -->
|
||||
<ul class="list-unstyled chat-contact-list" id="chat-list">
|
||||
<li class="chat-contact-list-item chat-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Chats Found</h6>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="flex-shrink-0 avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">P</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Producción</h6>
|
||||
<p class="chat-contact-status text-muted text-truncate mb-0">
|
||||
Descripcion dpto. produccion
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="flex-shrink-0 avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success"><small>POD</small></span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">POD</h6>
|
||||
<p class="chat-contact-status text-muted text-truncate mb-0">
|
||||
Descripcion dpto. POD
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="flex-shrink-0 avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">M</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Maquetación</h6>
|
||||
<p class="chat-contact-status text-muted text-truncate mb-0">
|
||||
Descripcion dpto. Maquetación
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- CHAT LIST -->
|
||||
|
||||
</ul>
|
||||
<!-- Contacts -->
|
||||
@ -93,17 +51,7 @@
|
||||
<li class="chat-contact-list-item contact-list-item-0 d-none">
|
||||
<h6 class="text-muted mb-0">No Contacts Found</h6>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">IM</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">Ignacio Martinez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="chat-contact-list-item">
|
||||
<!-- <li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">JJ</span>
|
||||
@ -112,7 +60,7 @@
|
||||
<h6 class="chat-contact-name text-truncate m-0">Jaime Jimenez</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</li> -->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
@ -121,7 +69,7 @@
|
||||
|
||||
<!-- Chat History -->
|
||||
<div class="col app-chat-history bg-body">
|
||||
<div class="chat-history-wrapper">
|
||||
<div class="chat-history-wrapper ">
|
||||
<div class="chat-history-header border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex overflow-hidden align-items-center">
|
||||
@ -157,191 +105,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-history-body bg-body">
|
||||
<ul class="list-unstyled chat-history">
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">How can we help? We're here for you! 😄</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:00 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Hey John, I am looking for the best admin template.</p>
|
||||
<p class="mb-0">Could you please help me to find it out? 🤔</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">It should be Bootstrap 5 compatible.</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:02 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Vuexy has all the components you'll ever need in a app.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:03 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Looks clean and fresh UI. 😃</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">It's perfect for my next project.</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">How can I purchase it?</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:05 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Thanks, you can purchase it.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:06 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">I will purchase it for sure. 👍</p>
|
||||
</div>
|
||||
<div class="chat-message-text mt-2">
|
||||
<p class="mb-0">Thanks.</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:08 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Great, Feel free to get in touch.</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>10:10 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="user-avatar flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">Do you have design files for Vuexy?</p>
|
||||
</div>
|
||||
<div class="text-muted mt-1">
|
||||
<small>10:15 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="chat-message chat-message-right">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1 w-50">
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">
|
||||
Yes that's correct documentation file, Design files are included with
|
||||
the template.
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<i class="ti ti-checks ti-xs me-1"></i>
|
||||
<small>10:15 AM</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar"
|
||||
class="rounded-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<div class="chat-history-body bg-body ">
|
||||
<ul class="list-unstyled chat-history" id="chat-conversation">
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Chat message form -->
|
||||
@ -352,9 +119,10 @@
|
||||
placeholder="Type your message here"
|
||||
/>
|
||||
<div class="message-actions d-flex align-items-center">
|
||||
<a class="btn btn-primary d-flex send-msg-btn">
|
||||
|
||||
<a class="btn btn-primary d-flex send-msg-btn ">
|
||||
<i class="ti ti-send me-md-1 me-0"></i>
|
||||
<span class="align-middle d-md-inline-block d-none">Send</span>
|
||||
<span class="align-middle d-md-inline-block d-none">Enviar</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -368,131 +136,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||
<?= $this->endSection() ?>
|
||||
<!------------------------------------------------------->
|
||||
<!-- Código JS logica -->
|
||||
<!------------------------------------------------------->
|
||||
<?= $this->section("additionalInlineJs") ?>
|
||||
|
||||
/**
|
||||
* App Chat
|
||||
*/
|
||||
|
||||
// Seleccionar elementos del DOM
|
||||
const chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body'),
|
||||
chatContactListItems = [].slice.call(
|
||||
document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)')
|
||||
),
|
||||
chatHistoryBody = document.querySelector('.chat-history-body'),
|
||||
chatSidebarLeftUserAbout = document.querySelector('.chat-sidebar-left-user-about'),
|
||||
messageInput = document.querySelector('.message-input'),
|
||||
searchInput = document.querySelector('.chat-search-input'),
|
||||
sendMsgBtn = document.querySelector('.send-msg-btn'); // Seleccionar el botón de envío de mensaje
|
||||
|
||||
// Inicializar PerfectScrollbar
|
||||
if (chatContactsBody) {
|
||||
new PerfectScrollbar(chatContactsBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
if (chatHistoryBody) {
|
||||
new PerfectScrollbar(chatHistoryBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Función para desplazar el scroll al final
|
||||
function scrollToBottom() {
|
||||
if (chatHistoryBody) {
|
||||
chatHistoryBody.scrollTo(0, chatHistoryBody.scrollHeight);
|
||||
}
|
||||
}
|
||||
scrollToBottom();
|
||||
|
||||
// Seleccionar chat o contacto
|
||||
chatContactListItems.forEach(chatContactListItem => {
|
||||
chatContactListItem.addEventListener('click', e => {
|
||||
chatContactListItems.forEach(item => {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
e.currentTarget.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Filtrar chats
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener('keyup', e => {
|
||||
const searchValue = e.currentTarget.value.toLowerCase(),
|
||||
chatListItem0 = document.querySelector('.chat-list-item-0'),
|
||||
contactListItem0 = document.querySelector('.contact-list-item-0'),
|
||||
searchChatListItems = [].slice.call(
|
||||
document.querySelectorAll('#chat-list li:not(.chat-contact-list-item-title)')
|
||||
),
|
||||
searchContactListItems = [].slice.call(
|
||||
document.querySelectorAll('#contact-list li:not(.chat-contact-list-item-title)')
|
||||
);
|
||||
|
||||
// Buscar en chats
|
||||
const chatListItemsCount = searchChatContacts(searchChatListItems, searchValue);
|
||||
// Mostrar u ocultar mensaje de "No se encontraron resultados" en chats
|
||||
if (chatListItem0) {
|
||||
chatListItem0.classList.toggle('d-none', chatListItemsCount !== 0);
|
||||
}
|
||||
|
||||
// Buscar en contactos
|
||||
const contactListItemsCount = searchChatContacts(searchContactListItems, searchValue);
|
||||
// Mostrar u ocultar mensaje de "No se encontraron resultados" en contactos
|
||||
if (contactListItem0) {
|
||||
contactListItem0.classList.toggle('d-none', contactListItemsCount !== 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Función para buscar en chats y contactos
|
||||
function searchChatContacts(searchListItems, searchValue) {
|
||||
let searchListItemsCount = 0;
|
||||
searchListItems.forEach(searchListItem => {
|
||||
const searchListItemText = searchListItem.textContent.toLowerCase();
|
||||
const matchesSearch = searchListItemText.indexOf(searchValue) !== -1;
|
||||
|
||||
searchListItem.classList.toggle('d-flex', matchesSearch);
|
||||
searchListItem.classList.toggle('d-none', !matchesSearch);
|
||||
|
||||
if (matchesSearch) {
|
||||
searchListItemsCount++;
|
||||
}
|
||||
});
|
||||
|
||||
return searchListItemsCount;
|
||||
}
|
||||
|
||||
// Enviar mensaje
|
||||
if (sendMsgBtn) {
|
||||
sendMsgBtn.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
if (messageInput.value) {
|
||||
const renderMsg = document.createElement('div');
|
||||
renderMsg.className = 'chat-message-text mt-2';
|
||||
renderMsg.innerHTML = `<p class="mb-0">${messageInput.value}</p>`;
|
||||
const lastChatMessageWrapper = document.querySelector('li:last-child .chat-message-wrapper');
|
||||
if (lastChatMessageWrapper) {
|
||||
lastChatMessageWrapper.appendChild(renderMsg);
|
||||
}
|
||||
messageInput.value = '';
|
||||
scrollToBottom();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<?= $this->section("additionalExternalJs") ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/chatPresupuesto.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<!-- <script src="<?= site_url('js_loader/chat_js') ?>"></script> -->
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems") ?>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_datosEnvios") ?>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_comentariosItems") ?>
|
||||
<?= view("themes/vuexy/components/chat_presupuesto",data:["modelId" => $presupuestoId]) ?>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestoItems") ?>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_tiradasAlternativasItems") ?>
|
||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria") ?>
|
||||
<?php else: ?>
|
||||
<input type="hidden" name="total_presupuesto" id="total_presupuesto" class="form-control"
|
||||
value="0.0"></input>
|
||||
|
||||
46
httpdocs/assets/js/safekat/components/ajax.js
Normal file
46
httpdocs/assets/js/safekat/components/ajax.js
Normal file
@ -0,0 +1,46 @@
|
||||
class Ajax{
|
||||
constructor(url, data, headers, success, error, type='default'){
|
||||
this.url = url;
|
||||
this.data = data;
|
||||
this.headers = headers;
|
||||
this.success = success;
|
||||
this.error = error;
|
||||
this.type = type;
|
||||
}
|
||||
post(){
|
||||
(this.type == 'default') ? this.ajax('POST'): this.ajaxForm('POST');
|
||||
}
|
||||
get(){
|
||||
this.ajax('GET');
|
||||
}
|
||||
put(){
|
||||
(this.type == 'default') ? this.ajax('PUT'): this.ajaxForm('PUT');
|
||||
}
|
||||
delete(){
|
||||
(this.type == 'default') ? this.ajax('DELETE'): this.ajaxForm('DELETE');
|
||||
}
|
||||
ajax(method){
|
||||
$.ajax({
|
||||
url : this.url,
|
||||
type : method,
|
||||
data: this.data,
|
||||
headers: this.headers,
|
||||
success: this.success,
|
||||
error: this.error
|
||||
})
|
||||
}
|
||||
ajaxForm(method){
|
||||
$.ajax({
|
||||
url : this.url,
|
||||
type : method,
|
||||
data: this.data,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: this.headers,
|
||||
success: this.success,
|
||||
error: this.error
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Ajax
|
||||
446
httpdocs/assets/js/safekat/components/chat.js
Normal file
446
httpdocs/assets/js/safekat/components/chat.js
Normal file
@ -0,0 +1,446 @@
|
||||
import Ajax from '../components/ajax.js'
|
||||
|
||||
|
||||
|
||||
class Chat {
|
||||
constructor(domItem) {
|
||||
this.domItem = domItem
|
||||
this.chatList = this.domItem.find("#chat-list")
|
||||
this.chatHistory = this.domItem.find("#chat-conversation")
|
||||
this.modelId = this.domItem.data("id")
|
||||
this.chatHistoryBody = document.querySelector(".chat-history-body")
|
||||
this.sendBtnMessageDepartment = this.domItem.find("#send-msg-btn-deparment")
|
||||
this.sendBtnMessageInternal= this.domItem.find("#send-msg-btn-internal")
|
||||
|
||||
this.messageInput = this.domItem.find(".message-input")
|
||||
this.sideBar = this.domItem.find(".sidebar-body")
|
||||
this.chatDeparmentId = undefined
|
||||
|
||||
this.headers = {}
|
||||
|
||||
this.chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body')
|
||||
this.chatContactListItems = [].slice.call(
|
||||
document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)')
|
||||
)
|
||||
}
|
||||
init() {
|
||||
// Inicializar PerfectScrollbar
|
||||
this.sendBtnMessageDepartment.addClass("d-none")
|
||||
this.sendBtnMessageInternal.addClass("d-none")
|
||||
if (this.chatContactsBody) {
|
||||
this.scrollbarContacts = new PerfectScrollbar(this.chatContactsBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
if (this.chatHistoryBody) {
|
||||
this.scrollbarChatHistory = new PerfectScrollbar(this.chatHistoryBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
}
|
||||
initGeneral() {
|
||||
this.chatType = "general"
|
||||
this._handleGetChatList()
|
||||
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
|
||||
|
||||
}
|
||||
initPresupuesto() {
|
||||
this.chatType = "presupuesto"
|
||||
this._handleGetChatList()
|
||||
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
|
||||
|
||||
}
|
||||
initPedido() {
|
||||
this.chatType = "pedido"
|
||||
this._handleGetChatList()
|
||||
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
|
||||
|
||||
}
|
||||
initFactura() {
|
||||
this.chatType = "factura"
|
||||
this._handleGetChatList()
|
||||
this.sendBtnMessageDepartment.on("click", this._sendMessage.bind(this))
|
||||
|
||||
}
|
||||
initContacts() {
|
||||
this.chatType = "internal"
|
||||
|
||||
}
|
||||
_setBtnInternal()
|
||||
{
|
||||
this.sendBtnMessageInternal.removeClass("d-none")
|
||||
this.sendBtnMessageDepartment.addClass("d-none")
|
||||
}
|
||||
_setBtnDeparment()
|
||||
{
|
||||
this.sendBtnMessageDepartment.removeClass("d-none")
|
||||
this.sendBtnMessageInternal.addClass("d-none")
|
||||
}
|
||||
/**============================================
|
||||
* PRESUPUESTOS
|
||||
*=============================================**/
|
||||
_handleGetChatList(event) {
|
||||
let ajax = new Ajax(
|
||||
"/chat/departments",
|
||||
null,
|
||||
null,
|
||||
this._handleGetChatListSuccess.bind(this),
|
||||
this._handleGetChatListError.bind(this),
|
||||
|
||||
|
||||
);
|
||||
ajax.get();
|
||||
}
|
||||
_handleGetChatListSuccess(data) {
|
||||
Object.values(data).map(row => {
|
||||
this.chatList.append(this._getContact(row))
|
||||
this.chatList.find(`#chat_${row.name}`).on("click", (event) => {
|
||||
let chatDeparmentId = this.chatList.find(`#chat_${row.name}`).data("id")
|
||||
this.domItem.find(".chat-history-header div.chat-contact-info h6").text(row.display)
|
||||
this.domItem.find(".chat-history-header div.chat-contact-info small.user-status").text(row.display)
|
||||
this._getChatMessage(chatDeparmentId)
|
||||
})
|
||||
|
||||
})
|
||||
this.chatList.find(`#chat__produccion`).trigger("click");
|
||||
}
|
||||
_handleGetChatListError(error) {
|
||||
console.error(error)
|
||||
}
|
||||
_getContact(row) {
|
||||
let chat = `
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center" id="chat_${row.name}" data-id="${row.id}">
|
||||
<div class="flex-shrink-0 avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success">${row.display.charAt(0)}</span>
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">${row.display}</h6>
|
||||
<p class="chat-contact-status text-muted text-truncate mb-0">
|
||||
${row.display}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
`
|
||||
return chat
|
||||
}
|
||||
_getChatMessage(chatDeparmentId) {
|
||||
this.chatDeparmentId = chatDeparmentId
|
||||
let ajax = new Ajax(
|
||||
`/chat/department/${this.chatType}/${this.chatDeparmentId}/${this.modelId}`,
|
||||
null,
|
||||
null,
|
||||
this._getChatMessageSuccess.bind(this),
|
||||
this._getChatMessageError.bind(this),
|
||||
|
||||
|
||||
);
|
||||
ajax.get();
|
||||
}
|
||||
_getChatMessageSuccess(data) {
|
||||
this.chatHistory.empty()
|
||||
this._setBtnDeparment()
|
||||
if (data.messages) {
|
||||
data.messages.map((m) => {
|
||||
this._addChatMessage(m)
|
||||
})
|
||||
}
|
||||
}
|
||||
_getChatMessageError(err) {
|
||||
console.log(err)
|
||||
|
||||
}
|
||||
_addChatMessage(chatMessage, pos = "left") {
|
||||
let chatItem = `
|
||||
<li class="chat-message chat-message-${chatMessage.pos}">
|
||||
<div class="d-flex overflow-hidden">
|
||||
<div class="chat-message-wrapper flex-grow-1">
|
||||
|
||||
<div class="chat-message-text">
|
||||
<p class="mb-0">${chatMessage?.message}</p>
|
||||
</div>
|
||||
<div class="text-end text-muted mt-1">
|
||||
<div class="text-start text-muted mt-1">
|
||||
<i class="ti me-1"></i>
|
||||
<small>${chatMessage?.user?.first_name + " " + chatMessage?.user?.last_name}</small>
|
||||
</div>
|
||||
<i class="ti ti-checks ti-xs me-1 text-success"></i>
|
||||
<small>${chatMessage.created_at}</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="user-avatar flex-shrink-0 ms-3">
|
||||
<div class="avatar avatar-sm">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">${chatMessage?.user?.first_name.charAt(0) + chatMessage?.user?.last_name.charAt(0)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
`
|
||||
this.chatHistory.append(chatItem)
|
||||
return chatItem
|
||||
}
|
||||
_sendMessage() {
|
||||
let messageText = this.messageInput.val()
|
||||
const body = {
|
||||
message: messageText,
|
||||
chat_department_id: this.chatDeparmentId,
|
||||
user: this.userId,
|
||||
model_id: this.modelId
|
||||
}
|
||||
if (messageText) {
|
||||
let ajax = new Ajax(
|
||||
`/chat/message/${this.chatType}`,
|
||||
body,
|
||||
null,
|
||||
this._sendMessageSuccess.bind(this),
|
||||
this._sendMessageError.bind(this),
|
||||
|
||||
);
|
||||
ajax.post();
|
||||
}
|
||||
}
|
||||
_sendMessageSuccess(data) {
|
||||
this.messageInput.val("")
|
||||
this._getChatMessage(this.chatDeparmentId)
|
||||
}
|
||||
_sendMessageError(err) {
|
||||
console.error(err)
|
||||
}
|
||||
_handleListContacts() {
|
||||
this.sideBar.find("#contact-list").removeClass("d-none")
|
||||
this.sendBtnMessageInternal.on("click",this._sendMessageInternal.bind(this))
|
||||
let ajax = new Ajax(
|
||||
"/chat/contacts",
|
||||
null,
|
||||
null,
|
||||
this._handleListContactsSuccess.bind(this),
|
||||
this._handleListContactsError.bind(this)
|
||||
|
||||
)
|
||||
ajax.get()
|
||||
|
||||
}
|
||||
_handleListContactsSuccess(contacts) {
|
||||
if (contacts) {
|
||||
contacts.map((c) => {
|
||||
this._addContactToList(c)
|
||||
});
|
||||
} else {
|
||||
this.sideBar.find("#contact-list").removeClass("d-none")
|
||||
}
|
||||
this.sideBar.find(".contact-chat").on("click", (e) => {
|
||||
let userId = $(e.currentTarget).data("id")
|
||||
this.receiverId = userId
|
||||
this._handleGetSingleContact(userId)
|
||||
this._setBtnInternal()
|
||||
this.chatHistory.empty()
|
||||
})
|
||||
}
|
||||
_handleListContactsError(err) {
|
||||
console.error(err)
|
||||
}
|
||||
_handleGetSingleContact(userId) {
|
||||
let ajax = new Ajax(
|
||||
`/chat/contacts/${userId}`,
|
||||
null,
|
||||
null,
|
||||
this._handleGetSingleContactSuccess.bind(this),
|
||||
this._handleGetSingleContactError.bind(this),
|
||||
)
|
||||
ajax.get()
|
||||
}
|
||||
|
||||
_handleGetSingleContactSuccess(contact) {
|
||||
this.domItem.find(".chat-history-header div.chat-contact-info h6").text([contact.first_name, contact.last_name].join(" "))
|
||||
this.domItem.find(".chat-history-header div.chat-contact-info small.user-status").text(contact.username)
|
||||
let ajax = new Ajax(
|
||||
`/chat/contact/${contact.id}/messages`,
|
||||
null,
|
||||
null,
|
||||
this._handleGetSingleContactMessagesSuccess.bind(this),
|
||||
this._handleGetSingleContactMessagesError.bind(this)
|
||||
)
|
||||
ajax.get()
|
||||
}
|
||||
_handleGetSingleContactMessagesSuccess(data) {
|
||||
if (data) {
|
||||
data.map((m) => {
|
||||
this._addChatMessage(m)
|
||||
})
|
||||
}
|
||||
}
|
||||
_handleGetSingleContactMessagesError(err) { }
|
||||
|
||||
_handleGetSingleContactError(err) {
|
||||
|
||||
}
|
||||
_sendMessageInternal() {
|
||||
let messageText = this.messageInput.val()
|
||||
const body = {
|
||||
message: messageText,
|
||||
receiver_id: this.receiverId,
|
||||
}
|
||||
if (messageText) {
|
||||
let ajax = new Ajax(
|
||||
`/chat/message/internal`,
|
||||
body,
|
||||
null,
|
||||
this._sendMessageInternalSuccess.bind(this),
|
||||
this._sendMessageInternalError.bind(this),
|
||||
|
||||
);
|
||||
ajax.post();
|
||||
}
|
||||
}
|
||||
_sendMessageInternalSuccess(message) {
|
||||
this.messageInput.val("")
|
||||
this._handleGetSingleContact(this.receiverId)
|
||||
}
|
||||
_sendMessageInternalError(err) {
|
||||
console.error(err)
|
||||
}
|
||||
_addContactToList(contact) {
|
||||
|
||||
let contactItem =
|
||||
`
|
||||
<li class="chat-contact-list-item">
|
||||
<a class="d-flex align-items-center contact-chat" data-id="${contact.id}"
|
||||
id="chat-contact-list-item-${contact.id}">
|
||||
<div class="avatar d-block flex-shrink-0">
|
||||
<span class="avatar-initial rounded-circle bg-label-primary">
|
||||
${contact?.first_name?.charAt(0) ?? "?"
|
||||
+ contact?.last_name?.charAt(0) ?? "?"}</span>
|
||||
|
||||
</div>
|
||||
<div class="chat-contact-info flex-grow-1 ms-2">
|
||||
<h6 class="chat-contact-name text-truncate m-0">${contact?.first_name ?? "" + " " +
|
||||
contact?.last_name ?? ""}</h6>
|
||||
<p class="chat-contact-status text-muted text-truncate mb-0">
|
||||
${contact.username}
|
||||
</p>
|
||||
</div>
|
||||
${contact.unreadMessages ? `<span class="badge badge-center rounded-pill bg-primary">${contact.unreadMessages}</span>` : ""}
|
||||
</a>
|
||||
</li>
|
||||
`
|
||||
|
||||
if (contact.first_name || contact.last_name) {
|
||||
this.sideBar.find("#contact-list").append(contactItem)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
export default Chat
|
||||
|
||||
|
||||
// // Seleccionar elementos del DOM
|
||||
// const chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body'),
|
||||
// chatContactListItems = [].slice.call(
|
||||
// document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)')
|
||||
// ),
|
||||
// chatHistoryBody = document.querySelector('.chat-history-body'),
|
||||
// chatSidebarLeftUserAbout = document.querySelector('.chat-sidebar-left-user-about'),
|
||||
// messageInput = document.querySelector('.message-input'),
|
||||
// searchInput = document.querySelector('.chat-search-input'),
|
||||
// sendMsgBtn = document.querySelector('.send-msg-btn'); // Seleccionar el botón de envío de mensaje
|
||||
|
||||
// // Inicializar PerfectScrollbar
|
||||
// if (chatContactsBody) {
|
||||
// new PerfectScrollbar(chatContactsBody, {
|
||||
// wheelPropagation: false,
|
||||
// suppressScrollX: true
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (chatHistoryBody) {
|
||||
// new PerfectScrollbar(chatHistoryBody, {
|
||||
// wheelPropagation: false,
|
||||
// suppressScrollX: true
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Función para desplazar el scroll al final
|
||||
// function scrollToBottom() {
|
||||
// if (chatHistoryBody) {
|
||||
// chatHistoryBody.scrollTo(0, chatHistoryBody.scrollHeight);
|
||||
// }
|
||||
// }
|
||||
// scrollToBottom();
|
||||
|
||||
// // Seleccionar chat o contacto
|
||||
|
||||
|
||||
// // Filtrar chats
|
||||
// if (searchInput) {
|
||||
// searchInput.addEventListener('keyup', e => {
|
||||
// const searchValue = e.currentTarget.value.toLowerCase(),
|
||||
// chatListItem0 = document.querySelector('.chat-list-item-0'),
|
||||
// contactListItem0 = document.querySelector('.contact-list-item-0'),
|
||||
// searchChatListItems = [].slice.call(
|
||||
// document.querySelectorAll('#chat-list li:not(.chat-contact-list-item-title)')
|
||||
// ),
|
||||
// searchContactListItems = [].slice.call(
|
||||
// document.querySelectorAll('#contact-list li:not(.chat-contact-list-item-title)')
|
||||
// );
|
||||
|
||||
// // Buscar en chats
|
||||
// const chatListItemsCount = searchChatContacts(searchChatListItems, searchValue);
|
||||
// // Mostrar u ocultar mensaje de "No se encontraron resultados" en chats
|
||||
// if (chatListItem0) {
|
||||
// chatListItem0.classList.toggle('d-none', chatListItemsCount !== 0);
|
||||
// }
|
||||
|
||||
// // Buscar en contactos
|
||||
// const contactListItemsCount = searchChatContacts(searchContactListItems, searchValue);
|
||||
// // Mostrar u ocultar mensaje de "No se encontraron resultados" en contactos
|
||||
// if (contactListItem0) {
|
||||
// contactListItem0.classList.toggle('d-none', contactListItemsCount !== 0);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Función para buscar en chats y contactos
|
||||
// function searchChatContacts(searchListItems, searchValue) {
|
||||
// let searchListItemsCount = 0;
|
||||
// searchListItems.forEach(searchListItem => {
|
||||
// const searchListItemText = searchListItem.textContent.toLowerCase();
|
||||
// const matchesSearch = searchListItemText.indexOf(searchValue) !== -1;
|
||||
|
||||
// searchListItem.classList.toggle('d-flex', matchesSearch);
|
||||
// searchListItem.classList.toggle('d-none', !matchesSearch);
|
||||
|
||||
// if (matchesSearch) {
|
||||
// searchListItemsCount++;
|
||||
// }
|
||||
// });
|
||||
|
||||
// return searchListItemsCount;
|
||||
// }
|
||||
|
||||
// // // Enviar mensaje
|
||||
// // if (sendMsgBtn) {
|
||||
// // sendMsgBtn.addEventListener('click', e => {
|
||||
// // e.preventDefault();
|
||||
// // if (messageInput.value) {
|
||||
// // const renderMsg = document.createElement('div');
|
||||
// // renderMsg.className = 'chat-message-text mt-2';
|
||||
// // renderMsg.innerHTML = `<p class="mb-0">${messageInput.value}</p>`;
|
||||
// // const lastChatMessageWrapper = document.querySelector('li:last-child .chat-message-wrapper');
|
||||
// // if (lastChatMessageWrapper) {
|
||||
// // lastChatMessageWrapper.appendChild(renderMsg);
|
||||
// // }
|
||||
// // messageInput.value = '';
|
||||
// // scrollToBottom();
|
||||
// // }
|
||||
// // });
|
||||
// // }
|
||||
4
httpdocs/assets/js/safekat/pages/chatFactura.js
Normal file
4
httpdocs/assets/js/safekat/pages/chatFactura.js
Normal file
@ -0,0 +1,4 @@
|
||||
import Chat from '../components/chat.js'
|
||||
|
||||
let chat = new Chat($("#chat-factura"))
|
||||
chat.initFactura()
|
||||
5
httpdocs/assets/js/safekat/pages/chatPedido.js
Normal file
5
httpdocs/assets/js/safekat/pages/chatPedido.js
Normal file
@ -0,0 +1,5 @@
|
||||
import Chat from '../components/chat.js'
|
||||
|
||||
let chat = new Chat($("#chat-pedido"))
|
||||
chat.init()
|
||||
chat.initPedido()
|
||||
6
httpdocs/assets/js/safekat/pages/chatPresupuesto.js
Normal file
6
httpdocs/assets/js/safekat/pages/chatPresupuesto.js
Normal file
@ -0,0 +1,6 @@
|
||||
import Chat from '../components/chat.js'
|
||||
|
||||
let chat = new Chat($("#chat-presupuesto"))
|
||||
chat.init()
|
||||
chat.initPresupuesto()
|
||||
chat._handleListContacts()
|
||||
BIN
httpdocs/themes/vuexy/img/avatars/user.png
Normal file
BIN
httpdocs/themes/vuexy/img/avatars/user.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@ -57,6 +57,7 @@
|
||||
height: calc(calc(100vh - 11.5rem) - 5rem - 2.2rem);
|
||||
}
|
||||
}
|
||||
|
||||
.app-chat .app-chat-contacts .sidebar-body .chat-contact-list li.chat-contact-list-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
Reference in New Issue
Block a user