mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Configuraciones iniciales del sistema de mensajeria
This commit is contained in:
28
ci4/app/Entities/Mensajeria/ConversacionEntity.php
Normal file
28
ci4/app/Entities/Mensajeria/ConversacionEntity.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entities\Mensajeria;
|
||||||
|
|
||||||
|
use CodeIgniter\Entity\Entity;
|
||||||
|
|
||||||
|
class ConversacionEntity extends Entity
|
||||||
|
{
|
||||||
|
protected $attributes = [
|
||||||
|
'id' => null,
|
||||||
|
'pedido_libro_id' => null,
|
||||||
|
'pedido_maquetacion_id' => null,
|
||||||
|
'factura_id' => null,
|
||||||
|
'departamento' => null,
|
||||||
|
'asunto' => null,
|
||||||
|
'created_at' => null,
|
||||||
|
'updated_at' => null,
|
||||||
|
'deleted_at' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
"pedido_libro_id" => "?int",
|
||||||
|
"pedido_maquetacion_id" => "?int",
|
||||||
|
"factura_id" => "?int"
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
26
ci4/app/Entities/Mensajeria/ParticipanteEntity.php
Normal file
26
ci4/app/Entities/Mensajeria/ParticipanteEntity.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entities\Mensajeria;
|
||||||
|
|
||||||
|
use CodeIgniter\Entity\Entity;
|
||||||
|
|
||||||
|
class ParticipanteEntity extends Entity
|
||||||
|
{
|
||||||
|
protected $attributes = [
|
||||||
|
'id' => null,
|
||||||
|
'conversacion_id' => null,
|
||||||
|
'usuario_id' => null,
|
||||||
|
'cliente_id' => null,
|
||||||
|
'email' => null,
|
||||||
|
'last_read' => null,
|
||||||
|
'created_at' => null,
|
||||||
|
'updated_at' => null,
|
||||||
|
'deleted_at' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
"conversacion_id" => "?int",
|
||||||
|
"usuario_id" => "?int",
|
||||||
|
"cliente_id" => "?int"
|
||||||
|
];
|
||||||
|
}
|
||||||
138
ci4/app/Models/Mensajeria/ConversacionModel.php
Normal file
138
ci4/app/Models/Mensajeria/ConversacionModel.php
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Mensajeria;
|
||||||
|
|
||||||
|
use CodeIgniter\Model;
|
||||||
|
|
||||||
|
|
||||||
|
class ConversacionModel extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'chat_conversaciones'; // Asegúrate de que este sea el nombre correcto de la tabla
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $returnType = 'App\Entities\Mensajeria\ConversacionEntity';
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
protected $allowedFields = [
|
||||||
|
'asunto',
|
||||||
|
'pedido_libro_id',
|
||||||
|
'pedido_maquetacion_id',
|
||||||
|
'factura_id',
|
||||||
|
'departamento'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function pedidoLibro()
|
||||||
|
{
|
||||||
|
return $this->db
|
||||||
|
->table('pedido_libros')
|
||||||
|
->where('id', $this->pedido_libro_id)
|
||||||
|
->get()
|
||||||
|
->getFirstRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pedidoMaquetacion()
|
||||||
|
{
|
||||||
|
return $this->db
|
||||||
|
->table('pedido_maquetaciones')
|
||||||
|
->where('id', $this->pedido_maquetacion_id)
|
||||||
|
->get()
|
||||||
|
->getFirstRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function factura()
|
||||||
|
{
|
||||||
|
return $this->db
|
||||||
|
->table('facturas')
|
||||||
|
->where('id', $this->factura_id)
|
||||||
|
->get()
|
||||||
|
->getFirstRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Devuelve si la conversacion tiene algún cliente
|
||||||
|
*/
|
||||||
|
public function isClient()
|
||||||
|
{
|
||||||
|
$isCliente = false;
|
||||||
|
$participantes = $this->participantes(); // Asegúrate de implementar este método
|
||||||
|
foreach ($participantes as $p) {
|
||||||
|
if (($p->user && $p->user->customer_id) || $p->customer_id) {
|
||||||
|
$isCliente = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $isCliente;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comprueba si la conversacion del mensaje tiene el cliente
|
||||||
|
*/
|
||||||
|
public function haveCliente($userCustomer)
|
||||||
|
{
|
||||||
|
$customer_id = $userCustomer->customer_id;
|
||||||
|
$participants = $this->participantes(); // Asegúrate de implementar este método
|
||||||
|
|
||||||
|
foreach ($participants as $p) {
|
||||||
|
if ($p->customer_id && $p->customer_id === $customer_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParticipanteDesdeCliente($cliente_id)
|
||||||
|
{
|
||||||
|
return $this->db->table('chat_participantes')
|
||||||
|
->where('cliente_id', $cliente_id)
|
||||||
|
->where('conversacion_id', $this->id)
|
||||||
|
->get()
|
||||||
|
->getFirstRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function marcarLeidoCliente($cliente_id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$participante = $this->getParticipanteDesdeCliente($cliente_id);
|
||||||
|
if ($participante) {
|
||||||
|
$this->db->table('chat_participantes')
|
||||||
|
->where('id', $participante->id)
|
||||||
|
->update(['last_read' => date('Y-m-d H:i:s')]);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function marcarNoLeido($usuario_id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$participante = $this->getParticipanteDesdeUsuario($usuario_id); // Asegúrate de implementar este método
|
||||||
|
if ($participante) {
|
||||||
|
$this->db->table('chat_participantes')
|
||||||
|
->where('id', $participante->id)
|
||||||
|
->update(['last_read' => null]);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function participantes()
|
||||||
|
{
|
||||||
|
return $this->db
|
||||||
|
->table('chat_participantes')
|
||||||
|
->where('conversacion_id', $this->id)
|
||||||
|
->get()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getParticipanteDesdeUsuario($usuario_id)
|
||||||
|
{
|
||||||
|
return $this->db->table('chat_participantes')
|
||||||
|
->where('usuario_id', $usuario_id)
|
||||||
|
->where('conversacion_id', $this->id)
|
||||||
|
->get()
|
||||||
|
->getFirstRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
ci4/app/Models/Mensajeria/ParticipanteModel.php
Normal file
30
ci4/app/Models/Mensajeria/ParticipanteModel.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Mensajeria;
|
||||||
|
|
||||||
|
use App\Models\BaseModel;
|
||||||
|
use App\Models\Customers\Customer;
|
||||||
|
|
||||||
|
class ParticipanteModel extends BaseModel
|
||||||
|
{
|
||||||
|
protected $table = 'chat_participantes';
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $returnType = 'App\Entities\Mensajeria\ParticipanteEntity';
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
protected $allowedFields = [
|
||||||
|
'conversacion_id',
|
||||||
|
'usuario_id',
|
||||||
|
'cliente_id',
|
||||||
|
'email',
|
||||||
|
'last_read',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
|
||||||
|
public function getCustomer()
|
||||||
|
{
|
||||||
|
//$customerModel = new Customer();
|
||||||
|
//return $customerModel->find($this->attributes['customer_id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,498 @@
|
|||||||
|
<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">Chats</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>
|
||||||
|
|
||||||
|
|
||||||
|
</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 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">
|
||||||
|
<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 class="app-overlay"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!------------------------------------------------------->
|
||||||
|
<!-- 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->endSection() ?>
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +35,8 @@
|
|||||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_datosEnvios") ?>
|
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_datosEnvios") ?>
|
||||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_comentariosItems") ?>
|
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_comentariosItems") ?>
|
||||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestoItems") ?>
|
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestoItems") ?>
|
||||||
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_tiradasAlternativasItems") ?>
|
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_tiradasAlternativasItems") ?>
|
||||||
|
<?= view("themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria") ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<input type="hidden" name="total_presupuesto" id="total_presupuesto" class="form-control"
|
<input type="hidden" name="total_presupuesto" id="total_presupuesto" class="form-control"
|
||||||
value="0.0"></input>
|
value="0.0"></input>
|
||||||
@ -367,6 +368,7 @@ $('#bc-save').on( "click", function() {
|
|||||||
<?= $this->section('css') ?>
|
<?= $this->section('css') ?>
|
||||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>">
|
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>">
|
||||||
<link rel="stylesheet" href="<?= site_url("themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
|
<link rel="stylesheet" href="<?= site_url("themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
|
||||||
|
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/pages/app-chat.css') ?>">
|
||||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/sk-datatables.css') ?>">
|
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/sk-datatables.css') ?>">
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|
||||||
@ -390,5 +392,6 @@ $('#bc-save').on( "click", function() {
|
|||||||
<script src="<?= site_url('js_loader/tiradasAlternativas_js') ?>"></script>
|
<script src="<?= site_url('js_loader/tiradasAlternativas_js') ?>"></script>
|
||||||
<script src="<?= site_url('js_loader/datosServicios_js') ?>"></script>
|
<script src="<?= site_url('js_loader/datosServicios_js') ?>"></script>
|
||||||
<script src="<?= site_url('themes/vuexy/vendor/libs/two/two.js') ?>"></script>
|
<script src="<?= site_url('themes/vuexy/vendor/libs/two/two.js') ?>"></script>
|
||||||
|
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user