diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 01f07dbd..3abe4e05 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -690,6 +690,23 @@ $routes->group( ); $routes->resource('buscadorpresupuestos', ['namespace' => 'App\Controllers\Presupuestos', 'controller' => 'Buscador', 'except' => 'show,new,create,update']); +/* Rutas para mensajeria */ +$routes->group('mensajes', ['namespace' => 'App\Controllers\Mensajeria'], function ($routes) { + + /* Interna */ + $routes->group('internos', ['namespace' => 'App\Controllers\Mensajeria'], function ($routes) { + + $routes->get('', 'MensajesDirectos::index', ['as' => 'mensajeriaView']); + $routes->get('chat/(:num)', 'MensajesDirectos::getChatInfo/$1', ['as' => 'getChatInfo']); + /*$routes->match(['get', 'post'], 'add', 'TarifaAcabados::add', ['as' => 'tarifaAcabadoAdd']); + $routes->match(['get', 'post'], 'edit/(:num)', 'TarifaAcabados::edit/$1', ['as' => 'tarifaAcabadoEdit']); + $routes->get('delete/(:num)', 'TarifaAcabados::delete/$1', ['as' => 'tarifaAcabadoDelete']); + $routes->post('datatable', 'TarifaAcabados::datatable', ['as' => 'tarifaAcabadoDT']);*/ + + }); + +}); + /* * -------------------------------------------------------------------- diff --git a/ci4/app/Controllers/Js_loader.php b/ci4/app/Controllers/Js_loader.php index 7fabccd0..58b9aa02 100755 --- a/ci4/app/Controllers/Js_loader.php +++ b/ci4/app/Controllers/Js_loader.php @@ -117,5 +117,13 @@ class Js_loader extends BaseController $this->response->setHeader('Content-Type', 'text/javascript'); return view('themes/vuexy/form/presupuestos/cliente/previews.js'); } + + function chat_js() + { + $this->response->setHeader('Content-Type', 'text/javascript'); + return view('themes/vuexy/form/mensajes/mensajeria.js'); + } + + } \ No newline at end of file diff --git a/ci4/app/Controllers/Mensajeria/MensajesDirectos.php b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php new file mode 100644 index 00000000..e951ffc1 --- /dev/null +++ b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php @@ -0,0 +1,80 @@ +viewData['pageTitle'] = "Mensajeria interna"; + + // Breadcrumbs + $this->viewData['breadcrumb'] = [ + ['title' => "Home", 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_mensajes"), 'route' => route_to('mensajeriaView'), 'active' => true] + ]; + + parent::initController($request, $response, $logger); + } + + 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); + } + + + public function getChatInfo($conversacionId) + { + // Modelos + $conversacionModel = model('App\Models\Mensajeria\ConversacionModel'); + + // Verificar si es una solicitud AJAX + if ($this->request->isAJAX()) { + // Obtener los datos + $data = [ + 'people' => $conversacionModel->getChatParticipants($conversacionId), + 'messages' => $conversacionModel->getChatMessages($conversacionId) + ]; + + // Devolver respuesta JSON + return $this->respond($data, 200, 'Chat information retrieved successfully'); + } else { + return $this->failForbidden('Only AJAX requests are allowed'); + } + } + + +} diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index 3b6973fc..c8242825 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -20,27 +20,30 @@ class Test extends BaseController public function index() { - $model = new PresupuestoModel(); - $data = $model->generarLineaPedido(123); - echo '
';
-        var_dump($data);
-        echo '
'; + // Modelos + $conversacionModel = model('App\Models\Mensajeria\ConversacionModel'); + + + echo "
";
+        echo var_dump($conversacionModel->getChatMessages(190286));
+        echo "
"; } - private function clonar_tarifa_encuadernacion($teOrigen, $teDestino){ + private function clonar_tarifa_encuadernacion($teOrigen, $teDestino) + { $tet_model = model('App\Models\Tarifas\TarifaEncuadernacionTiradaModel'); $tel_model = model('App\Models\Tarifas\TarifaEncuadernacionLineaModel'); - $tarifasTiradas = $tet_model->asObject()->where('tarifa_encuadernacion_id',$teOrigen)->findAll(); + $tarifasTiradas = $tet_model->asObject()->where('tarifa_encuadernacion_id', $teOrigen)->findAll(); - foreach ($tarifasTiradas as $tarifasTirada){ + foreach ($tarifasTiradas as $tarifasTirada) { echo "--->" . $tarifasTirada->id . "
"; - $tarifasLineas = $tel_model->asObject()->where('tirada_encuadernacion_id',$tarifasTirada->id)->findAll(); + $tarifasLineas = $tel_model->asObject()->where('tirada_encuadernacion_id', $tarifasTirada->id)->findAll(); // Prepare the data unset($tarifasTirada->id); @@ -53,7 +56,7 @@ class Test extends BaseController $tet_model->insert($tarifasTirada); $inserted_id = $tet_model->insertID(); - foreach ($tarifasLineas as $tarifasLinea){ + foreach ($tarifasLineas as $tarifasLinea) { echo "------>" . $tarifasLinea->id . "
"; @@ -73,11 +76,10 @@ class Test extends BaseController } - - private function test_get_tirada_alt($tirada, $merma, $tipo_impresion_id, - $json_data, $cliente_id, $ancho, $alto, - $solapas_cubierta, $solapas_ancho_cubierta, $solapas_sobrecubierta, $solapas_ancho_sobrecubierta, $lomo) - { + private function test_get_tirada_alt($tirada, $merma, $tipo_impresion_id, + $json_data, $cliente_id, $ancho, $alto, + $solapas_cubierta, $solapas_ancho_cubierta, $solapas_sobrecubierta, $solapas_ancho_sobrecubierta, $lomo) + { $values = []; if ($json_data) { @@ -160,7 +162,6 @@ class Test extends BaseController } - $opciones_papel = PresupuestoService::get_opciones_papel($uso, $isColor); $datosTipolog = $linea['gotaNegro'] ?? null; @@ -214,7 +215,7 @@ class Test extends BaseController // Previo a ejecutar, vaciar la tabla clientes_precios (ojo si hay customizaciones) - $db = \Config\Database::connect(); + $db = \Config\Database::connect(); $builder = $db->table('cliente_precios'); $plantillaDefectoId = 5; @@ -525,7 +526,6 @@ class Test extends BaseController } - public static function testLineasIntRotativa() { @@ -533,7 +533,6 @@ class Test extends BaseController $tipo = 'negro'; - $datosPedido = (object)array( 'paginas' => 240, 'tirada' => 100, @@ -546,8 +545,8 @@ class Test extends BaseController $parametrosRotativa = (object)array( 'a_favor_fibra' => 0, - 'bnPages' => 240, - 'colorPages' => 0, + 'bnPages' => 240, + 'colorPages' => 0, 'rotativa_gota_negro' => 0, 'rotativa_gota_color' => 0, ); @@ -579,12 +578,12 @@ class Test extends BaseController var_dump($datosTipologias); echo ''; - $parametrosRotativa->rotativa_gota_negro = $datosTipologias[0]->gota_negro; - $parametrosRotativa->rotativa_gota_color = $datosTipologias[0]->gota_color; - $parametrosRotativa->rotativa_negro = $datosTipologias[0]->negro; - $parametrosRotativa->rotativa_cyan = $datosTipologias[0]->cyan; - $parametrosRotativa->rotativa_magenta = $datosTipologias[0]->magenta; - $parametrosRotativa->rotativa_amarillo = $datosTipologias[0]->amarillo; + $parametrosRotativa->rotativa_gota_negro = $datosTipologias[0]->gota_negro; + $parametrosRotativa->rotativa_gota_color = $datosTipologias[0]->gota_color; + $parametrosRotativa->rotativa_negro = $datosTipologias[0]->negro; + $parametrosRotativa->rotativa_cyan = $datosTipologias[0]->cyan; + $parametrosRotativa->rotativa_magenta = $datosTipologias[0]->magenta; + $parametrosRotativa->rotativa_amarillo = $datosTipologias[0]->amarillo; echo '-------------------------------'; $maquinas = $maquina_model->getMaquinaImpresionForPresupuesto( @@ -596,7 +595,6 @@ class Test extends BaseController ); - foreach ($maquinas as $maquina) { echo '----------------------------
'; diff --git a/ci4/app/Models/Mensajeria/ConversacionModel.php b/ci4/app/Models/Mensajeria/ConversacionModel.php index 32aff33d..e6863051 100644 --- a/ci4/app/Models/Mensajeria/ConversacionModel.php +++ b/ci4/app/Models/Mensajeria/ConversacionModel.php @@ -46,6 +46,69 @@ class ConversacionModel extends Model ->get() ->getFirstRow(); } + + + public function getConversacion($convesacionId) + { + $builder = $this->db + ->table($this->table . " t1") + //->select("t1.conversacion_id AS id, t2.asunto AS asunto") + ->where("t1.id", $convesacionId) + ->join("chat_participantes t2", "t2.conversacion_id = t1.id", "left") + ->join("chat_mensajes t3", "t3.conversacion_id = t1.id", "left") + ->orderBy('t1.created_at', 'DESC') + ->get() + ->getResultArray(); + + return $builder; + } + + public function getChatParticipants($chatId) + { + return $this->db + ->table($this->table . " t1") + ->select("t2.usuario_id as user_id, t3.first_name AS nombre, t3.last_name AS apellidos") + ->where("t1.id", $chatId) + ->join("chat_participantes t2", "t2.conversacion_id = t1.id", "left") + ->join("users t3", "t3.id = t2.usuario_id", "left") + ->get() + ->getResultArray(); + } + + public function getChatMessages($chatId) + { + return $this->db + ->table($this->table . " t1") + ->select("t2.mensaje AS mensaje, t2.usuario_id as user_id") + ->select("t3.first_name AS nombre, t3.last_name AS apellidos") + ->where("t1.id", intval($chatId)) + ->join("chat_mensajes t2", "t2.conversacion_id = t1.id", "left") + ->join("users t3", "t3.id = t2.usuario_id", "left") + ->get() + ->getResultArray(); + } + + + + + + + + + + + + + + + + + + + + + + /** * Devuelve si la conversacion tiene algún cliente diff --git a/ci4/app/Models/Mensajeria/ParticipanteModel.php b/ci4/app/Models/Mensajeria/ParticipanteModel.php index f20c177e..7a0e0a9c 100644 --- a/ci4/app/Models/Mensajeria/ParticipanteModel.php +++ b/ci4/app/Models/Mensajeria/ParticipanteModel.php @@ -20,7 +20,29 @@ class ParticipanteModel extends BaseModel 'last_read', ]; - protected $useTimestamps = true; + public function getPeopleInChat($conversacionId){ + + $builder = $this->db + ->table($this->table . " t1") + ->where("t1.conversacion_id", $conversacionId); + + return $builder; + } + + public function getChatsByUser($userId){ + + $builder = $this->db + ->table($this->table . " t1") + ->select("t1.conversacion_id AS id, t2.asunto AS asunto") + ->where("t1.usuario_id", $userId) + ->join("chat_conversaciones t2", "t2.id = conversacion_id", "left") + ->orderBy('t1.created_at', 'DESC') + ->get() + ->getResultObject(); + + return $builder; + } + public function getCustomer() { diff --git a/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js new file mode 100644 index 00000000..89395845 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js @@ -0,0 +1,138 @@ +/** + * App Chat + */ + +// Seleccionar elementos del DOM +const chatContactsBody = $('.app-chat-contacts .sidebar-body'), + chatContactListItems = $('.chat-contact-list-item:not(.chat-contact-list-item-title)'), + chatHistoryBody = $('.chat-history-body'), + chatSidebarLeftUserAbout = $('.chat-sidebar-left-user-about'), + messageInput = $('.message-input'), + searchInput = $('.chat-search-input'), + sendMsgBtn = $('.send-msg-btn'); // Seleccionar el botón de envío de mensaje + +// Inicializar PerfectScrollbar +if (chatContactsBody.length) { + new PerfectScrollbar(chatContactsBody[0], { + wheelPropagation: false, + suppressScrollX: true + }); +} + +if (chatHistoryBody.length) { + new PerfectScrollbar(chatHistoryBody[0], { + wheelPropagation: false, + suppressScrollX: true + }); +} + +// Función para desplazar el scroll al final +function scrollToBottom() { + if (chatHistoryBody.length) { + chatHistoryBody.scrollTop(chatHistoryBody[0].scrollHeight); + } +} + +scrollToBottom(); + +// Seleccionar chat o contacto +chatContactListItems.on('click', function () { + chatContactListItems.removeClass('active'); + $(this).addClass('active'); +}); + +// Filtrar chats +if (searchInput.length) { + searchInput.on('keyup', function () { + const searchValue = $(this).val().toLowerCase(), + chatListItem0 = $('.chat-list-item-0'), + contactListItem0 = $('.contact-list-item-0'), + searchChatListItems = $('#chat-list li:not(.chat-contact-list-item-title)'), + searchContactListItems = $('#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.length) { + chatListItem0.toggleClass('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.length) { + contactListItem0.toggleClass('d-none', contactListItemsCount === 0); + } + }); +} + +// Función para buscar en chats y contactos +function searchChatContacts(searchListItems, searchValue) { + let searchListItemsCount = 0; + searchListItems.each(function () { + const searchListItemText = $(this).text().toLowerCase(); + const matchesSearch = searchListItemText.indexOf(searchValue) !== -1; + + $(this).toggleClass('d-flex', matchesSearch); + $(this).toggleClass('d-none', !matchesSearch); + + if (matchesSearch) { + searchListItemsCount++; + } + }); + + return searchListItemsCount; +} + +// Enviar mensaje +if (sendMsgBtn.length) { + sendMsgBtn.on('click', function (e) { + e.preventDefault(); + if (messageInput.val()) { + const renderMsg = $('
').addClass('chat-message-text mt-2').html(`

${messageInput.val()}

`); + const lastChatMessageWrapper = $('li:last-child .chat-message-wrapper'); + if (lastChatMessageWrapper.length) { + lastChatMessageWrapper.append(renderMsg); + } + messageInput.val(''); + scrollToBottom(); + } + }); +} + +// Seleccionar los elementos

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

+ var conversationId = $(this).attr('id'); + + 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 = ` +

+ ${person.user_id} +
`; + $('#participants-container').append(participantHtml); + }); + } + }, + error: function (jqXHR, textStatus, errorThrown) { + // Manejar errores en la llamada AJAX + console.error('Error en la llamada AJAX:', textStatus, errorThrown); + } + }); +}) +; \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php b/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php new file mode 100644 index 00000000..8d330963 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php @@ -0,0 +1,364 @@ +include("themes/_commonPartialsBs/select2bs5") ?> +include("themes/_commonPartialsBs/datatables") ?> +extend('themes/vuexy/main/defaultlayout') ?> + +section('content'); ?> + +
+
+
+ +
+ +
+ +
+ + + +
+
+
+
+
+
+ P +
+
+ + +
+
+
+
    +
  • +
    +
    +
    +

    How can we help? We're here for you! 😄

    +
    +
    + + 10:00 AM +
    +
    +
    +
    + Avatar +
    +
    +
    +
  • +
  • +
    +
    +
    + Avatar +
    +
    +
    +
    +

    Hey John, I am looking for the best admin template.

    +

    Could you please help me to find it out? 🤔

    +
    +
    +

    It should be Bootstrap 5 compatible.

    +
    +
    + 10:02 AM +
    +
    +
    +
  • +
  • +
    +
    +
    +

    Vuexy has all the components you'll ever need in a + app.

    +
    +
    + + 10:03 AM +
    +
    +
    +
    + Avatar +
    +
    +
    +
  • +
  • +
    +
    +
    + Avatar +
    +
    +
    +
    +

    Looks clean and fresh UI. 😃

    +
    +
    +

    It's perfect for my next project.

    +
    +
    +

    How can I purchase it?

    +
    +
    + 10:05 AM +
    +
    +
    +
  • +
  • +
    +
    +
    +

    Thanks, you can purchase it.

    +
    +
    + + 10:06 AM +
    +
    +
    +
    + Avatar +
    +
    +
    +
  • +
  • +
    +
    +
    + Avatar +
    +
    +
    +
    +

    I will purchase it for sure. 👍

    +
    +
    +

    Thanks.

    +
    +
    + 10:08 AM +
    +
    +
    +
  • +
  • +
    +
    +
    +

    Great, Feel free to get in touch.

    +
    +
    + + 10:10 AM +
    +
    +
    +
    + Avatar +
    +
    +
    +
  • +
  • +
    +
    +
    + Avatar +
    +
    +
    +
    +

    Do you have design files for Vuexy?

    +
    +
    + 10:15 AM +
    +
    +
    +
  • +
  • +
    +
    +
    +

    + Yes that's correct documentation file, Design files are included + with + the template. +

    +
    +
    + + 10:15 AM +
    +
    +
    +
    + Avatar +
    +
    +
    +
  • +
+
+ + +
+
+ +
+
+
+endSection() ?> + +section('additionalInlineJs') ?> + + + + +endSection() ?> + + + +section('css') ?> + +endSection() ?> + + +section('additionalExternalJs') ?> + + +endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php b/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php index 051999dc..44913967 100644 --- a/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php +++ b/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php @@ -6,7 +6,7 @@ if (auth()->user()->inGroup('beta')) { ?>