Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev

This commit is contained in:
VENKATESHWARAN 2025-12-20 11:04:59 +05:30
commit dddfb36473
4 changed files with 248 additions and 5 deletions

View File

@ -221,7 +221,7 @@ class AppContentManagementController extends AdminController
}
}
public function FAQ()
{
$method = strtolower($this->request->getMethod());
@ -330,4 +330,42 @@ class AppContentManagementController extends AdminController
}
}
// public function frontend_content_files()
// {
// // 1. Define your physical system path
// define('UPLOAD_PATH', ROOTPATH . 'public/uploads/add_image_upload/');
// // 2. Define the public URL so the editor can display the image later
// // This is what the browser uses to see the image (e.g., https://site.com/uploads/...)
// // $publicUrl = "https://yourdomain.com/public/uploads/add_image_upload/";
// $publicUrl = ROOTPATH . 'public/uploads/add_image_upload/';
// // if (!is_dir($uploadPath)) mkdir($uploadPath, 0755, true);
// header('Content-Type: application/json');
// if ($_FILES['files']) {
// // Ensure directory exists
// if (!is_dir(UPLOAD_PATH)) {
// mkdir(UPLOAD_PATH, 0775, true);
// }
// $fileName = time() . '_' . basename($_FILES['files']['name'][0]);
// $fullPath = UPLOAD_PATH . $fileName;
// if (move_uploaded_file($_FILES['files']['tmp_name'][0], $fullPath)) {
// echo json_encode([
// "success" => true,
// "data" => [
// "baseurl" => $publicUrl,
// "files" => [$fileName]
// ]
// ]);
// } else {
// echo json_encode(["success" => false, "error" => "Failed to move file to " . UPLOAD_PATH]);
// }
// }
// }
}

View File

@ -92,6 +92,10 @@
<div class="form-group col-md-12">
<label for="category">Category<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="category" name="category" placeholder="Enter Category" required>
<small class="form-text text-muted text-end text-right">
Please enter the sub-category separated by '/'. For Example: Category / Category-1 / Category-2
</small>
</div>
</div>
<div class="form-row">

View File

@ -129,6 +129,7 @@
let content_editor;
let notes_editor;
$(document).ready(function () {
// var baseUrl = '<?php echo base_url(); ?>';
const editorConfig = {
buttons: [
"undo", "redo", "|",
@ -163,6 +164,79 @@
enableDragAndDropFileToEditor: true, // Allow file uploads via drag and drop
placeholder: "Start typing here...", // Optional placeholder text
};
// const editorConfig = {
// buttons: [
// "undo", "redo", "|",
// "paragraph",
// "bold", "italic", "strikethrough", "|",
// "superscript", "subscript", "|",
// "ul", "ol", "|",
// "outdent", "indent", "|",
// "blockquote", "table", "|",
// "align", "fontsize", "|",
// "image", "video", "|", // <--- Added image and video here
// "source"
// ],
// // Configuration for handling uploads
// uploader: {
// insertImageAsBase64URI: true, // Simple way to handle images without a backend
// url: 'http://localhost/nhance/frontend_content_files',
// format: 'json',
// prepareData: function (formData) {
// return formData;
// },
// process: function (resp) {
// return {
// files: resp.data.files,
// baseurl: resp.data.baseurl,
// error: resp.error,
// msg: resp.msg
// };
// },
// // This tells Jodit how to build the <img> tag
// defaultHandlerSuccess: function (data) {
// const url = data.baseurl + data.files[0];
// this.selection.insertImage(url);
// },
// error: function (e) {
// console.error("Upload Error: ", e);
// }
// },
// // Configuration for the file browser (optional)
// filebrowser: {
// ajax: {
// url: 'http://localhost/nhance/frontend_content_files',
// data: {
// action: 'files' // Custom parameter for your PHP logic
// }
// },
// // This allows you to delete or rename files directly from the browser popup
// removeButtons: [],
// createNewFolder: false,
// deleteFile: true,
// },
// controls: {
// paragraph: {
// list: {
// p: "Normal",
// h1: "Heading 1",
// h2: "Heading 2",
// h3: "Heading 3",
// h4: "Heading 4"
// }
// }
// },
// fontsize: ["8px", "10px", "12px", "14px", "16px", "18px", "20px", "22px", "24px"],
// showPlaceholder: false,
// toolbarButtonSize: "small",
// toolbarAdaptive: false,
// saveHeightInStorage: true,
// minHeight: 400,
// height: 400,
// defaultMode: "1",
// enableDragAndDropFileToEditor: true,
// placeholder: "Start typing here...",
// };
content_editor = Jodit.make("#content", editorConfig);
notes_editor = Jodit.make("#notes", editorConfig);

View File

@ -39,6 +39,24 @@
.arrow.rotate {
transform: rotate(90deg);
}
/* Ensure the dropdown matches the width of the input field */
/* .select2-container {
width: 100% !important;
} */
/* Ensure the dropdown appears ABOVE the modal and is visible */
/* .select2-container--open {
z-index: 9999999 !important;
} */
/* Fix for the "empty" or "misaligned" look in your screenshot */
/* .select2-results__option {
display: block !important;
width: 100%;
clear: both;
} */
</style>
@ -491,20 +509,129 @@
// }
// function appendClientsForMobileSearch(data) {
// let $select = $('#mobile_emp_client_data_list');
// $select.empty();
// let options = '<option value="0">Select Client</option>';
// $.each(data, function(index, item) {
// options += `<option value="${item.id}">${item.short_name}</option>`;
// });
// $select.html(options);
// $select.select2(); // ✅ Only once
// }
function appendClientsForMobileSearch(data) {
let $select = $('#mobile_emp_client_data_list');
$select.empty();
let options = '<option value="0">Select Client</option>';
$.each(data, function(index, item) {
options += `<option value="${item.id}">${item.short_name}</option>`;
$.each(data, function (index, item) {
let safeName = item.client_name.slice(0, 12) + "...";
let safeShortName = item.short_name;
options += `<option value="${item.id}">
${safeShortName} - ${safeName}
</option>`;
});
$select.html(options);
$select.select2(); // ✅ Only once
$select.html(options).select2(); // init once
}
// function appendClientsForMobileSearch(data) {
// let $select = $('#mobile_emp_client_data_list');
// // 1. Destroy any existing Select2 to ensure our new settings apply
// if ($select.data('select2')) {
// $select.select2('destroy');
// }
// // 2. Re-build the options
// $select.empty();
// let options = '<option value="0">Select Client</option>';
// $.each(data, function(index, item) {
// // Store both names in data attributes
// options += `<option value="${item.id}"
// data-shortname="${item.short_name}"
// data-fullname="${item.client_name}">
// ${item.short_name}
// </option>`;
// });
// $select.html(options);
// // 3. Initialize Select2 with the template logic
// $select.select2({
// dropdownParent: $('.modal-body').length ? $('.modal-body') : $(document.body), // Fix for modals
// escapeMarkup: function(m) { return m; }, // This allows HTML to render
// templateResult: function(data) {
// // Check if it's the placeholder
// if (!data.id || data.id == "0") return data.text;
// // Get data from the attributes we saved in step 2
// let short = $(data.element).data('shortname');
// let full = $(data.element).data('fullname');
// // Return the two-line HTML string
// return `
// <div style="line-height: 1.2; padding: 4px 0;">
// <div style="font-weight: bold;">${short}</div>
// <div style="font-size: 0.75em; color: #6c757d;">${full}</div>
// </div>
// `;
// },
// templateSelection: function(data) {
// if (!data.id || data.id == "0") return data.text;
// // Only show short name in the selection box
// return $(data.element).data('shortname');
// }
// });
// }
// function appendClientsForMobileSearch(data) {
// let $select = $('#mobile_emp_client_data_list');
// // Destroy existing instance to reset position logic
// if ($select.data('select2')) {
// $select.select2('destroy');
// }
// $select.empty();
// // Initialize Select2
// $select.select2({
// // THIS IS KEY: Attach the dropdown to the modal container
// // Replace '.modal' with your specific modal ID if needed (e.g., '#myModal')
// dropdownParent: $select.closest('.modal'),
// data: $.map(data, function (item) {
// return {
// id: item.id,
// text: item.short_name,
// full: item.client_name // Passing extra data here
// };
// }),
// escapeMarkup: function(m) { return m; },
// templateResult: function (item) {
// if (!item.id || item.id == "0") return item.text;
// // Using template literals for the two lines
// return `
// <div style="padding: 5px; line-height: 1.2;">
// <div style="font-weight: bold; color: #333;">${item.text}</div>
// <div style="font-size: 11px; color: #6c757d;">${item.full}</div>
// </div>
// `;
// },
// templateSelection: function (item) {
// return item.text; // Only show short name when closed
// }
// });
// }
//append the clients branch data to the modal
function appendBranch(data) {
$('#emp_client_branch_data_list').empty();