diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index dc673f87..5bed71a5 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -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']); + + + + + + + +}); /* * -------------------------------------------------------------------- diff --git a/ci4/app/Controllers/Chat/ChatController.php b/ci4/app/Controllers/Chat/ChatController.php new file mode 100644 index 00000000..775ae028 --- /dev/null +++ b/ci4/app/Controllers/Chat/ChatController.php @@ -0,0 +1,189 @@ +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); + } +} diff --git a/ci4/app/Controllers/Mensajeria/MensajesDirectos.php b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php index e951ffc1..ff1e8686 100644 --- a/ci4/app/Controllers/Mensajeria/MensajesDirectos.php +++ b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php @@ -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); } diff --git a/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php b/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php index 52bc6437..0993133e 100644 --- a/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php +++ b/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php @@ -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() diff --git a/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php b/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php index 25ac44de..f4b69606 100644 --- a/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php +++ b/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php @@ -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); } diff --git a/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php b/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php index 6ce55b86..289918d5 100644 --- a/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php +++ b/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php @@ -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); } diff --git a/ci4/app/Database/Seeds/ChatSeeder.php b/ci4/app/Database/Seeds/ChatSeeder.php index a6fd6c2e..28df32ab 100644 --- a/ci4/app/Database/Seeds/ChatSeeder.php +++ b/ci4/app/Database/Seeds/ChatSeeder.php @@ -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]); } } diff --git a/ci4/app/Language/es/Chat.php b/ci4/app/Language/es/Chat.php new file mode 100644 index 00000000..3981f2ce --- /dev/null +++ b/ci4/app/Language/es/Chat.php @@ -0,0 +1,5 @@ + "Chat" +]; \ No newline at end of file diff --git a/ci4/app/Models/Chat/ChatDeparmentModel.php b/ci4/app/Models/Chat/ChatDeparmentModel.php index 16a94953..4558bbd3 100644 --- a/ci4/app/Models/Chat/ChatDeparmentModel.php +++ b/ci4/app/Models/Chat/ChatDeparmentModel.php @@ -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; + } } diff --git a/ci4/app/Models/Chat/ChatMessageModel.php b/ci4/app/Models/Chat/ChatMessageModel.php index 6d030205..e9f72308 100644 --- a/ci4/app/Models/Chat/ChatMessageModel.php +++ b/ci4/app/Models/Chat/ChatMessageModel.php @@ -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; + } } diff --git a/ci4/app/Models/Chat/ChatModel.php b/ci4/app/Models/Chat/ChatModel.php index 5927fc27..65cf010e 100644 --- a/ci4/app/Models/Chat/ChatModel.php +++ b/ci4/app/Models/Chat/ChatModel.php @@ -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; + } + } diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index 85eb6e8f..0150f6af 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -781,4 +781,7 @@ class PresupuestoModel extends \App\Models\BaseModel return $description_interior . $description_cubierta . $description_sobrecubierta . $acabado; } + + + } diff --git a/ci4/app/Views/themes/vuexy/components/chat_factura.php b/ci4/app/Views/themes/vuexy/components/chat_factura.php new file mode 100644 index 00000000..cdfa7115 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_factura.php @@ -0,0 +1,161 @@ +
+
+

+ +

+
+
+
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+ +
+
+section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/components/chat_general.php b/ci4/app/Views/themes/vuexy/components/chat_general.php new file mode 100644 index 00000000..e69de29b diff --git a/ci4/app/Views/themes/vuexy/components/chat_pedido.php b/ci4/app/Views/themes/vuexy/components/chat_pedido.php new file mode 100644 index 00000000..0a77facf --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_pedido.php @@ -0,0 +1,164 @@ +
+
+

+ +

+
+
+
+ +
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
+ +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ + + +section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php b/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php new file mode 100644 index 00000000..78e97c68 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php @@ -0,0 +1,156 @@ +
+
+

+ +

+
+
+
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ +section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js index 89395845..4e7667b8 100644 --- a/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js @@ -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 = $('
').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(); - } - }); + // 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'); +// // 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) +// 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 +// // 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 index 8d330963..77c7cbe1 100644 --- a/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php @@ -5,360 +5,12 @@ 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 -
    -
    -
    -
  • -
-
- - -
-
- -
-
+ null]) ?>
endSection() ?> -section('additionalInlineJs') ?> -endSection() ?> - - -section('css') ?> - -endSection() ?> - - -section('additionalExternalJs') ?> - - -endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php index fc16989d..78102e6e 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php @@ -19,8 +19,9 @@ user()->inGroup('cliente-admin') || auth()->user()->inGroup('cliente-editor'))) : ?> - - + + + $pedidoEntity->id]) ?>
"btn btn-secondary float-start"]) ?> @@ -30,6 +31,7 @@
+ endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php index 86abbe58..0e57e675 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php @@ -1,4 +1,4 @@ -
+
@@ -33,56 +33,14 @@
@@ -121,7 +69,7 @@
-
+
@@ -157,191 +105,10 @@
-
-
    -
  • -
    -
    -
    -

    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 -
    -
    -
    -
  • +
    +
      + +
    @@ -352,9 +119,10 @@ placeholder="Type your message here" />
@@ -368,131 +136,17 @@
- +section('css') ?> + +endSection() ?> -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 = `

${messageInput.value}

`; - const lastChatMessageWrapper = document.querySelector('li:last-child .chat-message-wrapper'); - if (lastChatMessageWrapper) { - lastChatMessageWrapper.appendChild(renderMsg); - } - messageInput.value = ''; - scrollToBottom(); - } - }); -} - - - - - - - +section("additionalExternalJs") ?> + + + endSection() ?> + diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php index 5d3c296c..638cc728 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php @@ -34,9 +34,9 @@ + $presupuestoId]) ?> - diff --git a/httpdocs/assets/js/safekat/components/ajax.js b/httpdocs/assets/js/safekat/components/ajax.js new file mode 100644 index 00000000..9045d117 --- /dev/null +++ b/httpdocs/assets/js/safekat/components/ajax.js @@ -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 \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/components/chat.js b/httpdocs/assets/js/safekat/components/chat.js new file mode 100644 index 00000000..67136447 --- /dev/null +++ b/httpdocs/assets/js/safekat/components/chat.js @@ -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 = ` +
  • + +
    + ${row.display.charAt(0)} +
    +
    +
    ${row.display}
    +

    + ${row.display} +

    +
    +
    +
  • + ` + 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 = ` +
  • +
    +
    + +
    +

    ${chatMessage?.message}

    +
    +
    +
    + + ${chatMessage?.user?.first_name + " " + chatMessage?.user?.last_name} +
    + + ${chatMessage.created_at} +
    + +
    +
    +
    + ${chatMessage?.user?.first_name.charAt(0) + chatMessage?.user?.last_name.charAt(0)} +
    +
    +
    +
  • + ` + 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 = + ` +
  • + +
    + + ${contact?.first_name?.charAt(0) ?? "?" + + contact?.last_name?.charAt(0) ?? "?"} + +
    +
    +
    ${contact?.first_name ?? "" + " " + + contact?.last_name ?? ""}
    +

    + ${contact.username} +

    +
    + ${contact.unreadMessages ? `${contact.unreadMessages}` : ""} +
    +
  • + ` + + 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 = `

    ${messageInput.value}

    `; +// // const lastChatMessageWrapper = document.querySelector('li:last-child .chat-message-wrapper'); +// // if (lastChatMessageWrapper) { +// // lastChatMessageWrapper.appendChild(renderMsg); +// // } +// // messageInput.value = ''; +// // scrollToBottom(); +// // } +// // }); +// // } diff --git a/httpdocs/assets/js/safekat/pages/chatFactura.js b/httpdocs/assets/js/safekat/pages/chatFactura.js new file mode 100644 index 00000000..76102699 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatFactura.js @@ -0,0 +1,4 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-factura")) +chat.initFactura() \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/chatPedido.js b/httpdocs/assets/js/safekat/pages/chatPedido.js new file mode 100644 index 00000000..90e25c42 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatPedido.js @@ -0,0 +1,5 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-pedido")) +chat.init() +chat.initPedido() \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/chatPresupuesto.js b/httpdocs/assets/js/safekat/pages/chatPresupuesto.js new file mode 100644 index 00000000..4a09c66d --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatPresupuesto.js @@ -0,0 +1,6 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-presupuesto")) +chat.init() +chat.initPresupuesto() +chat._handleListContacts() \ No newline at end of file diff --git a/httpdocs/themes/vuexy/img/avatars/user.png b/httpdocs/themes/vuexy/img/avatars/user.png new file mode 100644 index 00000000..2b8b6583 Binary files /dev/null and b/httpdocs/themes/vuexy/img/avatars/user.png differ diff --git a/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css b/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css index 5fa07556..647e1e2e 100755 --- a/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css +++ b/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css @@ -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;