FEAT_CLAIM_MAIL_EDITOR_SRI

This commit is contained in:
Srinivas-Saravanan 2025-01-28 15:26:49 +05:30
parent 5cbc177402
commit 44c3506704
6 changed files with 481 additions and 30 deletions

View File

@ -499,6 +499,8 @@ $routes->group("/ticket", ["filter" => "authMVC"], function ($routes) {
$routes->post('create','TicketController::createTicket');
$routes->get('update','TicketController::updateTicket');
$routes->get('view/(:any)','TicketController::view_ticket/$1');
$routes->get('mail_template','TicketController::createMailTemplate');
$routes->get('mail_template','TicketController::mailTemplate');
$routes->post('crud_mail_template/(:any)','TicketController::crudTemplate/$1');
$routes->post('note','TicketController::crudNote');
});

View File

@ -27,6 +27,7 @@ class TicketController extends BaseController
protected $modeOFIntimate;
protected $claimType;
protected $claimStatus;
protected $placeHolders;
protected $clientModel;
protected $ticketMasterModel;
@ -34,6 +35,7 @@ class TicketController extends BaseController
protected $ticketMailTemplateModel;
protected $ticketMesageModel;
protected $ticketNoteModel;
protected $triggerType;
public function __construct()
{
@ -80,10 +82,25 @@ class TicketController extends BaseController
4 => "Death",
]
];
$this->triggerType = [
1 => "Trigger 1",
2 => "Trigger 2",
3 => "Trigger 3",
4 => "Trigger 4",
5 => "Trigger 5",
6 => "Trigger 6",
7 => "Trigger 7"
];
$this->placeHolders = ['member_name', 'nhance_logo', 'tpa_id', 'ecard_download_link',
'client_logo', 'policy_no', 'member_summary', 'app_link', 'post_enrollment_app_link',
'client_name'];
$this->ticketMasterModel = new TicketMasterModel();
$this->claimStatus = new TicketClaimStatusModel();
$this->clientModel = new ClientModel();
$this->ticketHistoryModel = new TicketHistoryModel();
$this->ticketMailTemplateModel = new TicketMailTemplateModel();
}
@ -177,6 +194,7 @@ class TicketController extends BaseController
public function view_ticket($ticket_id)
{
$data = [];
$data['ticket_note'] = $this->ticketNoteModel->where('is_active', 1)->findAll();
return $this->loadLayout('ticket_edit_onbording', $data);
}
@ -215,11 +233,63 @@ class TicketController extends BaseController
{
}
public function createMailTemplate()
public function mailTemplate()
{
$data = [];
return $this->loadLayout('ticket_mail_template', $data);
$data = [];
$data['trigger_type'] = $this->triggerType;
$data['policy_type'] = $this->ticketType;
$data['placeHolders'] = $this->placeHolders;
$data['ticket_data'] = $this->ticketMailTemplateModel->where('is_active',1)->findAll();
$data['ticket_type'] = $this->ticketType;
$data['trigger_type'] = $this->triggerType;
return $this->loadLayout('ticket_mail_template', $data);
}
public function crudTemplate($action){
//action 1 is create. action 2 is edit and action 3 is delete
if ($action == 1){
$received_data = $this->request->getPost();
if (isset($received_data['id']) && $received_data['id'] != '' ){
$status = $this->ticketMailTemplateModel->save($received_data);
if ($status){
return $this->respond(['status'=> true],200);
}else{
return $this->respond(['status' => false],200);
}
}else{
$status = $this->ticketMailTemplateModel->save($received_data);
if ($status){
return $this->respond(['status'=> true],200);
}else{
return $this->respond(['status' => false],200);
}
}
}
elseif ($action == 2){
$table_id = (int)$this->request->getPost('id');
$data = $this->ticketMailTemplateModel->where('id',$table_id)->where('is_active',1)->first();
if ($data){
return $this->respond(['status' => true,'data'=> $data],200);
}else{
return $this->respond(['status' => false],404);
}
}
elseif ($action == 3){
$table_id = (int)$this->request->getPost('id');
$sql = "update ticket_mail_template set is_active = 0 where id = $table_id ";
$status = $this->ticketMailTemplateModel->query($sql);
if($status){
return $this->respond(['status'=> true],200);
}else{
return $this->respond(['status' => false],404);
}
}
}
public function crudNote(){
}
}

View File

@ -12,7 +12,7 @@ class TicketMailTemplateModel extends Model
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = [];
protected $allowedFields = ['id','template_name','subject','ticket_type','is_auto_mail','trigger_type','mail_content'];
// Callbacks
protected $allowCallbacks = true;

View File

@ -12,7 +12,7 @@ class TicketNoteModel extends Model
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = ['id,created_by','updated_by','is_active'];
protected $allowedFields = ['id','ticket_id','note','created_by','updated_by','is_active'];
// Callbacks
protected $allowCallbacks = true;

View File

@ -24,6 +24,33 @@ table.dataTable tbody td {
.addbtnStyle {
margin-left: 20px !important;
}
.custom-dropdown-menu {
display: none;
position: absolute;
background-color: #ffffff !important;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 0.25rem;
padding: 0.5rem 0;
min-width: 10rem;
z-index: 9999;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.custom-dropdown-menu .dropdown-item {
display: block !important;
width: 100% !important;
padding: 0.5rem 1rem !important;
color: #212529 !important;
text-decoration: none !important;
background-color: transparent !important;
}
.custom-dropdown-menu .dropdown-item:hover {
background-color: #f8f9fa !important;
color: #16181b !important;
cursor: pointer !important;
}
</style>
<div class="col-12">
@ -40,17 +67,29 @@ table.dataTable tbody td {
<thead class="bg-light">
<tr>
<th>Template Name</th>
<th>Status</th>
<th>Policy Type</th>
<th>Trigger Type</th>
<th>Mail Send Type</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (isset($ticket_data)) { ?>
<?php foreach($ticket_data as $index => $row){ ?>
<tr>
<td><?php echo $row['status']; ?></td>
<td><?php echo $row['claim_no']; ?></td>
<td><?php echo $row['tpa_id']; ?></td>
<td><?php echo $row['template_name']; ?></td>
<td><?php echo $ticket_type[$row['ticket_type']]; ?></td>
<td><?php echo $trigger_type[$row['trigger_type']]; ?></td>
<td><?=$row['is_auto_mail'] == 1?'Auto':"Manual" ?></td>
<td>
<div class="btn-group dropdown">
<a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown"aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#" onclick="getMailTemplateData(<?=$row['id']?>)"><i class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle"></i>Edit</a>
<a class="dropdown-item" onclick="deleteTemplate(<?=$row['id']?>)"><i class="mdi mdi-delete mr-2 text-muted font-18 vertical-middle"></i>Delete</a>
</div>
</div>
</td>
</tr>
<?php } ?>
<?php } ?>
@ -74,52 +113,84 @@ table.dataTable tbody td {
</div>
<div class="modal-body">
<div class="text-center" id="no_data"></div>
<form role="form" class="parsley-examples" method="post" id="account_maneger_summary_mail_form"
enctype="multipart/form-data">
<form role="form" class="parsley-examples" method="post" id="ticket_mail_editor_modal"
enctype="multipart/form-data" novalidate>
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-6">
<label for="emp_code">Template Name</label>
<input type="text" id="template_name" name="template_name" value="Trigger 1" class="form-control" placeholder="Template Name">
<input type="text" id="template_name" name="template_name" class="form-control" placeholder="Template Name" required>
</div>
<div class="form-group col-md-6">
<label for="template_subject">Subject</label>
<input type="text" id="template_subject" name="subject" class="form-control" placeholder="Subject" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3">
<div class="form-group col-md-4">
<label for="emp_code">Policy Type</label>
<select class="form-control" id="policy_type" name="policy_type">
<option value="0">Select Policy Type</option>
<select class="form-control" id="policy_type" name="ticket_type" required>
<option value="">Select Policy Type</option>
<?php
if (isset($claim_status) && count($claim_status)) {
foreach ($claim_status as $key => $value) {
echo "<option value=" . $value['id'] . ">" . $value['status'] . "</option>";
if (isset($policy_type) && count($policy_type)) {
foreach ($policy_type as $key => $value) {
echo "<option value=" . $key . ">" . $value . "</option>";
}
}
?>
</select>
</div>
<div class="form-group col-md-3">
<label for="emp_code">Claim Status</label>
<select class="form-control" id="claim_status" name="claim_status">
<option value="0">Select status</option>
<div class="form-group col-md-4">
<label for="trigger_type">Trigger Type</label>
<select class="form-control" id="trigger_type" name="trigger_type" required>
<option value="">Select status</option>
<?php
if (isset($claim_status) && count($claim_status)) {
foreach ($claim_status as $key => $value) {
echo "<option value=" . $value['id'] . ">" . $value['status'] . "</option>";
if (isset($trigger_type) && count($trigger_type)) {
foreach ($trigger_type as $key => $value) {
echo "<option value=" . $key . ">" . $value . "</option>";
}
}
?>
</select>
</select> <input id="primaryKey" type="hidden">
</div>
<div class="form-group col-md-4">
<div>
<div id="statusSwitchWrapper" class="dt-switch-wrapper" style="padding-top: 40px;padding-left: 10px;">
<div class="custom-control custom-switch" style="text-align: left;">
<input type="checkbox" class="custom-control-input" id="statusSwitch">
<label class="custom-control-label" for="statusSwitch">Auto Mail</label>
</div>
</div>
</div>
</div>
</div>
<hr>
<!-- Unlayer editor -->
<div class="form-row">
<div class="form-group col-md-12">
<textarea class="form-control" rows="5" placeholder="Enter Mail Content"></textarea>
<!-- <textarea class="form-control" rows="5" placeholder="Enter Mail Content"></textarea> -->
<div class="form-row" id="rac_rate_dropdown">
<div class="form-group col-md-12">
<select id="ticket_mail_customButton" class="form-control" style="border:none;right: 6px;width: auto;position: absolute;z-index: 1;top: 17px;height: 32px;float: right;">
<option value="">PlaceHolders</option>
<?php foreach ($placeHolders as $value): ?>
<?php if($value == 'member_name' || $value == 'member_mobile' || $value == 'nhance_logo' || $value == 'client_logo' || $value == 'app_link' || $value == 'client_name'){ ?>member_mobile
<?php $valueChange = str_replace('_', ' ', $value); $valueChange = ucwords($valueChange); ?>
<option value="[[<?php echo $value; ?>]]"><?php echo $valueChange; ?></option>
<?php } ?>
<?php endforeach; ?>
</select>
</div>
</div>
<div id="ticket_mail_editor" name="content" style="height: 300px;"></div>
</div>
</div>
<div class="form-group text-right m-b-0">
@ -165,10 +236,318 @@ $(document).ready(function() {
} else {
console.error("Table atet found.");
}
var toolbar = "bold,italic,strikethrough,|,superscript,subscript,|,align,";
const editorConfig = {
buttons: toolbar.concat(['fontsize']),
fontsize: [8, 10, 12, 14, 16, 18, 20, 22, 24], // Customize font sizes
showPlaceholder: false,
toolbarButtonSize: 'small',
toolbarAdaptive: false,
saveHeightInStorage: true,
minHeight: 400,
extraButtons: [
{
name: 'info',
iconURL: '<?= base_url()."public"; ?>/assets/images/image-solid.svg', // Replace with the actual icon URL
exec: function (editor) {
const fileInput = document.getElementById("Question_title_fileInput");
fileInput.click();
},
},
],
};
const editor = Jodit.make("#ticket_mail_editor", editorConfig);
document.addEventListener('change', function(event) {
var target = event.target;
if (target.matches('#ticket_mail_customButton'))
{
editor.selection.insertHTML($(target).val());
$(target).val('');
}
});
$('.close').click(function () {
$('#template_subject').val('');
$('#template_name').val('');
$('#primaryKey').val('');
$('#policy_type').val('').change();
$('#trigger_type').val('').change();
editor.setEditorValue('');
$('#primaryKey').val(null);
$('#statusSwitch').prop('checked', false);
})
$('#ticket_mail_editor_modal').submit(function (event) {
event.preventDefault();
let isValid = true;
$('#ticket_mail_editor_modal [required]').each(function () {
if (!this.value.trim()) {
isValid = false;
$(this).addClass('is-invalid'); // Add a red border for visibility
} else {
$(this).removeClass('is-invalid');
}
});
if (!isValid) {
toastr.error('Please fill all required fields.', 'Validation Error');
return; // Prevent submission
}
var joditEditor = editor;
if (joditEditor)
{
var mailContent = $(joditEditor.currentPlace.container).find('.jodit-wysiwyg').html();
var formData = $(this).serializeArray();
formData.push({ name: 'mail_content', value: mailContent });
// formData.push({ name: 'client_id', value: $('#general_PrimaryKey').val() });
var isAutoMailEnabled = $('#statusSwitch').is(':checked') ? 1 : 0;
formData.push({ name: 'is_auto_mail', value: isAutoMailEnabled });
var primary_key = $('#primaryKey').val();
if (primary_key != null && primary_key != ''){
formData.push({ name: 'id', value: primary_key});
}
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
var form_action = '<?= base_url("ticket/crud_mail_template/1") ?>';
$.ajax({
url: form_action,
type: "POST",
data: formData,
dataType: 'json',
success: function(res)
{
if(res.status == true){
$('#new_mail_template').find('.close').click();
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.success('Template saved successfully!', 'Success');
location.reload();
}else if (res.status == false){
toastr.error('Failed to Save Data', 'error');
}
},
error: function (xhr, status, error)
{
console.error(xhr.responseText);
console.error(status, error);
setTimeout(function()
{
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.error('Something Wrong!', 'warning');
}, 1000);
}
});
}
else
{
console.error("Jodit editor instance is not defined.");
}
})
});
function openModal() {
var myModal = new bootstrap.Modal(document.getElementById('new_mail_template'));
myModal.show();
}
function deleteTemplate(id){
const url = '<?= base_url("ticket/crud_mail_template/3") ?>';
const data = { id: id }; // Ensure data is passed as an object
Swal.fire({
title: "Are you sure?",
text: "You need to remove this template.",
icon: "info",
showCancelButton: true,
confirmButtonColor: "#3085d6",
confirmButtonText: "Yes",
}).then((result) => {
if (result.isConfirmed) {
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
$.ajax({
url: url,
type: "POST",
data: data,
success: function(res) {
if (res.status === true) {
location.reload();
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.success('Template Deleted successfully!', 'Success');
} else if (res.status === false) {
toastr.error('Failed to Delete Template', 'Error');
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
console.error(status, error);
setTimeout(function() {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.error('Something went wrong!', 'Warning');
}, 1000);
}
});
}
});
}
function getMailTemplateData(id) {
const template_name = 'new_mail_template';
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
var form_action = '<?= base_url("ticket/crud_mail_template/2") ?>';
var data = { id: id };
$.ajax({
url: form_action,
type: "POST",
data: data,
success: function(res) {
console.log('get Mail Template Data', res);
if (res) {
if (res.status == true) {
// Open the modal
openModal();
// Populate the form fields
$('#template_subject').val(res.data.subject);
$('#template_name').val(res.data.template_name);
$('#primaryKey').val(res.data.id);
$('#policy_type').val(res.data.ticket_type).change();
$('#trigger_type').val(res.data.ticket_type).change();
$('.jodit-wysiwyg').html(res.data.mail_content);
// Set the auto mail switch
if (res.data.is_auto_mail == 1) {
$('#statusSwitch').prop('checked', true);
} else {
$('#statusSwitch').prop('checked', false);
}
// Populate any additional fields if necessary, like placeholders
// Assuming `placeholders` is an array in the response
if (res.placeholders) {
res.placeholders.forEach(function(placeholder) {
// You can populate any dropdown or field as required
$('#ticket_mail_customButton').val(placeholder);
});
}
} else {
toastr.error('Data Not Found', 'error');
}
}
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
},
error: function (xhr, status, error) {
console.error(xhr.responseText);
console.error(status, error);
setTimeout(function() {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.warning('Something Went Wrong!', 'warning');
}, 1000);
}
});
}
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
const table = document.getElementById("scroll-horizontal-datatable");
// Create custom dropdown
function createCustomDropdown(row) {
// Get the original dropdown items
const originalDropdown = row.querySelector('.dropdown-menu');
if (!originalDropdown) return null;
// Create new dropdown with proper background and spacing
const customDropdown = document.createElement('div');
customDropdown.className = 'custom-dropdown-menu';
// Copy inner content while maintaining icon alignment
customDropdown.innerHTML = originalDropdown.innerHTML;
return customDropdown;
}
let activeDropdown = null;
// Add click event listener to rows
table.querySelectorAll("tbody tr").forEach(row => {
const customDropdown = createCustomDropdown(row);
if (!customDropdown) return;
document.body.appendChild(customDropdown);
row.addEventListener("click", function(event) {
// Ignore clicks on the action column
if (event.target.closest('td:last-child')) {
return;
}
// Hide any active dropdown
if (activeDropdown) {
activeDropdown.style.display = 'none';
}
// Get click position
const rect = event.target.getBoundingClientRect();
// Position the dropdown with some offset
customDropdown.style.display = 'block';
customDropdown.style.position = 'fixed';
customDropdown.style.left = `${rect.left}px`;
customDropdown.style.top = `${rect.bottom + 5}px`; // Add 5px gap
// Set as active dropdown
activeDropdown = customDropdown;
event.stopPropagation();
});
// Preserve click handlers and add auto-close
customDropdown.querySelectorAll('.dropdown-item').forEach(item => {
item.addEventListener('click', function(e) {
const onclickAttr = this.getAttribute('onclick');
if (onclickAttr) {
eval(onclickAttr);
}
const href = this.getAttribute('href');
if (href && href !== '#') {
window.location.href = href;
}
// Close the dropdown after handling the click
if (activeDropdown) {
activeDropdown.style.display = 'none';
activeDropdown = null;
}
e.stopPropagation();
});
});
});
// Close dropdown when clicking outside
document.addEventListener("click", function() {
if (activeDropdown) {
activeDropdown.style.display = 'none';
activeDropdown = null;
}
});
});
</script>

View File

@ -11,7 +11,7 @@
placeholder="Enter Text"><?= isset($client['addon_subheading']) ? $client['addon_subheading'] : '' ?></textarea>
</div>
</div>
</div>
</div><input type="hidden" value="">
<div class="form-group text-right m-b-0">
<button type="submit" class="btn btn-primary" id="ticket_note_submit">Submit</button>
</div>