PageSourceSearch

https://kareconnect.com.au/assets/js/custom.js

js kareconnect.com.au collected 2026-10-02 01:17:30 UTC 241,245 bytes, 5,955 lines download raw bytes

1var selectedUserId = null;
2var selectedDate = null;
3var WAcalendar = null;
4
5$(document).ready(function () {
6    var $menu = $("#dynamic-menu");
7    if ($menu.length === 0) {
8        return; // Exit if menu not found
9    }
10    $menu.addClass("d-none");
11    var $menuItems = $menu.children("li");
12    // Load usage counts and pinned states from localStorage
13    var usageCounts = JSON.parse(localStorage.getItem("menuUsageCounts")) || {};
14    var pinnedItems = JSON.parse(localStorage.getItem("menuPinnedItems")) || {};
15    // Function to get a unique key for each menu item
16    function getMenuItemKey($item) {
17        if (!$item || !$item.length) {
18            return null;
19        }
20        var text = $item.find("a div").text().trim();
21        if (text) return text;
22        var classes = $item.attr("class");
23        if (classes) {
24            var classList = classes.split(/\s+/);
25            for (var i = 0; i < classList.length; i++) {
26                if (classList[i] !== "menu-item" && classList[i] !== "active") {
27                    return classList[i];
28                }
29            }
30        }
31        var href = $item.find("a").attr("href");
32        if (href) return href;
33        return null;
34    }
35    // Initialize counts and pinned states if not present
36    $menuItems.each(function () {
37        var key = getMenuItemKey($(this));
38        if (key) {
39            if (!(key in usageCounts)) {
40                usageCounts[key] = 0;
41            }
42            if (!(key in pinnedItems)) {
43                pinnedItems[key] = false;
44            }
45        }
46    });
47    // Function to reorder menu items
48    function reorderMenu() {
49        $menu.css("visibility", "hidden");
50        var pinnedMenuItems = $menuItems
51            .filter(function () {
52                var key = getMenuItemKey($(this));
53                return key && pinnedItems[key];
54            })
55            .detach();
56        var unpinnedMenuItems = $menuItems
57            .filter(function () {
58                var key = getMenuItemKey($(this));
59                return key && !pinnedItems[key];
60            })
61            .detach()
62            .sort(function (a, b) {
63                var keyA = getMenuItemKey($(a));
64                var keyB = getMenuItemKey($(b));
65                return keyA && keyB
66                    ? (usageCounts[keyB] || 0) - (usageCounts[keyA] || 0)
67                    : 0;
68            });
69        $menu
70            .append(pinnedMenuItems)
71            .append(unpinnedMenuItems)
72            .css("visibility", "visible");
73    }
74    // Initial ordering
75    reorderMenu();
76    // Add click event listeners to menu items
77    $menuItems.find("> a").on("click", function (e) {
78        var key = getMenuItemKey($(this).parent());
79        if (key) {
80            usageCounts[key] = (usageCounts[key] || 0) + 1;
81            localStorage.setItem(
82                "menuUsageCounts",
83                JSON.stringify(usageCounts)
84            );
85        }
86    });
87    // Add pin/unpin functionality
88    $menuItems.each(function () {
89        var $item = $(this);
90        var key = getMenuItemKey($item);
91        var $menuLink = $item.find("> a.menu-link");
92        var $pinIcon = $('<i class="bx bx-pin pin-icon"></i>').appendTo(
93            $menuLink
94        );
95        $pinIcon.on("click", function (e) {
96            e.preventDefault();
97            e.stopPropagation();
98            pinnedItems[key] = !pinnedItems[key];
99            localStorage.setItem(
100                "menuPinnedItems",
101                JSON.stringify(pinnedItems)
102            );
103            $item.toggleClass("pinned");
104            $(this).toggleClass("bx-pin").toggleClass("bxs-pin  text-warning");
105            reorderMenu();
106        });
107        if (pinnedItems[key]) {
108            $item.addClass("pinned");
109            $pinIcon.removeClass("bx-pin").addClass("bxs-pin  text-warning");
110        }
111    });
112    // Implement a decay mechanism
113    function decayUsageCounts() {
114        var changed = false;
115        $.each(usageCounts, function (key, value) {
116            if (value > 0 && !pinnedItems[key]) {
117                usageCounts[key] = Math.max(0, value - 1);
118                changed = true;
119            }
120        });
121        if (changed) {
122            localStorage.setItem(
123                "menuUsageCounts",
124                JSON.stringify(usageCounts)
125            );
126            reorderMenu();
127        }
128    }
129    // Call decay function daily
130    var DECAY_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
131    var lastDecayTime = localStorage.getItem("lastDecayTime") || 0;
132    var currentTime = Date.now();
133    if (currentTime - lastDecayTime > DECAY_INTERVAL) {
134        decayUsageCounts();
135        localStorage.setItem("lastDecayTime", currentTime.toString());
136    }
137    $menu.css("opacity", 0).removeClass("d-none").animate({ opacity: 1 }, 500);
138});
139("use strict");
140toastr.options = {
141    positionClass: toastPosition,
142    timeOut: parseFloat(toastTimeOut) * 1000,
143    showDuration: "300",
144    hideDuration: "1000",
145    extendedTimeOut: "1000",
146    progressBar: true,
147    closeButton: true,
148};
149var urlPrefix = window.location.pathname.split("/")[1];
150$(document).ready(function () {
151    if ($(".js-example-basic-multiple").length) {
152        $(".js-example-basic-multiple").select2();
153    }
154
155    if ($("#plan_id").length) {
156        $("#plan_id").select2();
157    }
158
159    if ($("#filter_plans").length) {
160        $("#filter_plans").select2();
161    }
162
163    if ($("#filter_by_users").length) {
164        $("#filter_by_users").select2();
165    }
166
167    if ($("#user_id").length) {
168        $("#user_id").select2();
169    }
170
171    if ($("#staff_ids").length) {
172        $("#staff_ids").select2();
173    }
174
175    if ($("#staff_ids_edit").length) {
176        $("#staff_ids_edit").select2();
177    }
178});
179
180
181$(document).on("click", ".delete-invoice", function (e) {
182    e.preventDefault();
183    var id = $(this).data("id");
184    var type = $(this).data("type");
185    var reload = $(this).data("reload") === true; // Simplified the reload condition
186    var tableID = $(this).data("table") || "table";
187    // Map types to their respective actions and API routes
188    var actions = {
189        default: "delete",
190    };
191    var typeMappings = {
192        default: type,
193    };
194    var destroy = actions[type] || actions["default"];
195    type = typeMappings[type] || typeMappings["default"];
196    var urlPrefix = window.location.pathname.split("/")[1];
197
198    // Show confirmation modal
199    $("#deleteModal").modal("show");
200    $("#deleteModal").off("click", "#confirmDelete");
201    // On confirmation click
202    $("#deleteModal").on("click", "#confirmDelete", function () {
203        $("#confirmDelete").html(label_please_wait).attr("disabled", true);
204        // Perform the AJAX request
205        $.ajax({
206            url: `/${urlPrefix}/${type}/${destroy}/${id}`,
207            type: "DELETE",
208            headers: {
209                "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval
210            },
211            success: function (response) {
212                $("#confirmDelete").html(label_yes).attr("disabled", false);
213                $("#deleteModal").modal("hide");
214                if (!response.error) {
215                    toastr.success(response.message);
216                    if (reload) {
217                        location.reload();
218                    } else if (tableID) {
219                        $("#" + tableID).bootstrapTable("refresh");
220                    } else {
221                        location.reload();
222                    }
223                } else {
224                    toastr.error(response.message);
225                }
226            },
227            error: function () {
228                $("#confirmDelete").html(label_yes).attr("disabled", false);
229                $("#deleteModal").modal("hide");
230                toastr.error(label_something_went_wrong);
231            },
232        });
233    });
234});
235$(document).on("click", ".delete", function (e) {
236    e.preventDefault();
237    var id = $(this).data("id");
238    var type = $(this).data("type");
239
240    //alert(type);
241
242    var reload = $(this).data("reload") === true; // Simplified the reload condition
243    var tableID = $(this).data("table") || "table";
244    // Map types to their respective actions and API routes
245    var actions = {
246        users: "delete_user",
247        "contract-type": "delete-contract-type",
248        "project-media": "delete-media",
249        "task-media": "delete-media",
250        "expense-type": "delete-expense-type",
251        milestone: "delete-milestone",
252        default: "destroy",
253    };
254    var typeMappings = {
255        "contract-type": "contracts",
256        "project-media": "projects",
257        "task-media": "tasks",
258        "expense-type": "expenses",
259        milestone: "projects",
260        default: type,
261    };
262    var destroy = actions[type] || actions["default"];
263    type = typeMappings[type] || typeMappings["default"];
264    var urlPrefix = window.location.pathname.split("/")[1];
265
266    // Show confirmation modal
267    $("#deleteModal").modal("show");
268    $("#deleteModal").off("click", "#confirmDelete");
269    // On confirmation click
270    $("#deleteModal").on("click", "#confirmDelete", function () {
271        $("#confirmDelete").html(label_please_wait).attr("disabled", true);
272        // Perform the AJAX request
273        $.ajax({
274            url: `/${urlPrefix}/${type}/${destroy}/${id}`,
275            type: "DELETE",
276            headers: {
277                "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval
278            },
279            success: function (response) {
280                $("#confirmDelete").html(label_yes).attr("disabled", false);
281                $("#deleteModal").modal("hide");
282                if (!response.error) {
283                    toastr.success(response.message);
284                    if (reload) {
285                        location.reload();
286                    } else if (tableID) {
287                        $("#" + tableID).bootstrapTable("refresh");
288                    } else {
289                        location.reload();
290                    }
291                } else {
292                    toastr.error(response.message);
293                }
294            },
295            error: function () {
296                $("#confirmDelete").html(label_yes).attr("disabled", false);
297                $("#deleteModal").modal("hide");
298                toastr.error(label_something_went_wrong);
299            },
300        });
301    });
302});
303
304
305$(document).on("click", ".delete-shift", function (e) {
306    e.preventDefault();
307    var id = $(this).data("id");
308    var type = $(this).data("type");
309
310    //alert(type);
311
312    var reload = $(this).data("reload") === true; // Simplified the reload condition
313    var tableID = $(this).data("table") || "table";
314    // Map types to their respective actions and API routes
315    var actions = {
316        users: "delete_user",
317        "contract-type": "delete-contract-type",
318        "project-media": "delete-media",
319        "task-media": "delete-media",
320        "expense-type": "delete-expense-type",
321        milestone: "delete-milestone",
322        default: "destroy",
323    };
324    var typeMappings = {
325        "contract-type": "contracts",
326        "project-media": "projects",
327        "task-media": "tasks",
328        "expense-type": "expenses",
329        milestone: "projects",
330        default: type,
331    };
332    var destroy = actions[type] || actions["default"];
333    type = typeMappings[type] || typeMappings["default"];
334    var urlPrefix = window.location.pathname.split("/")[1];
335
336    // Show confirmation modal
337    $("#deleteModal").modal("show");
338    $("#deleteModal").off("click", "#confirmDelete");
339    // On confirmation click
340    $("#deleteModal").on("click", "#confirmDelete", function () {
341        $("#confirmDelete").html(label_please_wait).attr("disabled", true);
342        // Perform the AJAX request
343        $.ajax({
344            url: `/${urlPrefix}/${type}/${destroy}/${id}`,
345            type: "DELETE",
346            headers: {
347                "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval
348            },
349            success: function (response) {
350                $("#confirmDelete").html(label_yes).attr("disabled", false);
351                $("#deleteModal").modal("hide");
352                if (!response.error) {
353                    toastr.success(response.message);
354                    if (reload) {
355                        location.reload();
356                    } else if (tableID) {
357                        $("#" + tableID).bootstrapTable("refresh");
358                    } else {
359                        location.reload();
360                    }
361                } else {
362                    toastr.error(response.message);
363                }
364            },
365            error: function () {
366                $("#confirmDelete").html(label_yes).attr("disabled", false);
367                $("#deleteModal").modal("hide");
368                toastr.error(label_something_went_wrong);
369            },
370        });
371    });
372});
373
374
375$(document).on("click", ".delete-selected", function (e) {
376    e.preventDefault();
377    const $this = $(this);
378    const table = $this.data("table");
379    const type = $this.data("type");
380    const destroyActionMap = {
381        users: "delete_multiple_user",
382        "contract-type": "delete-multiple-contract-type",
383        "project-media": "delete-multiple-media",
384        "task-media": "delete-multiple-media",
385        "expense-type": "delete-multiple-expense-type",
386        milestone: "delete-multiple-milestone",
387        default: "destroy_multiple",
388    };
389    const typeMap = {
390        "contract-type": "contracts",
391        "project-media": "projects",
392        "task-media": "tasks",
393        "expense-type": "expenses",
394        milestone: "projects",
395    };
396    const destroy = destroyActionMap[type] || destroyActionMap.default;
397    const mappedType = typeMap[type] || type;
398    const urlPrefix = window.location.pathname.split("/")[1];
399    const selections = $(`#${table}`).bootstrapTable("getSelections");
400    const selectedIds = selections.map((row) => row.id);
401    if (selectedIds.length === 0) {
402        return toastr.error(label_please_select_records_to_delete);
403    }
404    $("#confirmDeleteSelectedModal")
405        .modal("show")
406        .off("click", "#confirmDeleteSelections")
407        .on("click", "#confirmDeleteSelections", function () {
408            const $confirmBtn = $("#confirmDeleteSelections");
409            $confirmBtn.html(label_please_wait).prop("disabled", true);
410            $.ajax({
411                url: `/${urlPrefix}/${mappedType}/${destroy}/`,
412                type: "DELETE",
413                data: { ids: selectedIds },
414                headers: {
415                    "X-CSRF-TOKEN": $('input[name="_token"]').val(),
416                },
417                complete: () => {
418                    $confirmBtn.html(label_yes).prop("disabled", false);
419                    $("#confirmDeleteSelectedModal").modal("hide");
420                },
421                success: function (response) {
422                    $(`#${table}`).bootstrapTable("refresh");
423                    toastr[response.error ? "error" : "success"](
424                        response.message
425                    );
426                },
427                error: () => toastr.error(label_something_went_wrong),
428            });
429        });
430});
431function update_status(e) {
432    var id = e["id"];
433    var name = e["name"];
434    var reload = e.getAttribute("reload") ? true : false;
435    var status;
436    var is_checked = $("input[name=" + name + "]:checked");
437    if (is_checked.length >= 1) {
438        status = 1;
439    } else {
440        status = 0;
441    }
442    $.ajax({
443        url: "/master-panel/todos/update_status",
444        type: "POST", // Use POST method
445        headers: {
446            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
447        },
448        data: {
449            _method: "PUT", // Specify the desired method
450            id: id,
451            status: status,
452        },
453        success: function (response) {
454            if (response.error == false) {
455                if (reload) {
456                    location.reload();
457                }
458                toastr.success(response.message); // show a success message
459                $("#" + id + "_title").toggleClass("striked");
460            } else {
461                toastr.error(response.message);
462            }
463        },
464    });
465}
466$(document).on("click", ".edit-todo", function () {
467    var id = $(this).data("id");
468    var url = $(this).data("url");
469    $("#edit_todo_modal").modal("show");
470    $.ajax({
471        url: "/master-panel/todos/get/" + id,
472        type: "get",
473        headers: {
474            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
475        },
476        dataType: "json",
477        success: function (response) {
478            $("#todo_id").val(response.todo.id);
479            $("#todo_title").val(response.todo.title);
480            $("#todo_priority").val(response.todo.priority);
481            $("#todo_description").val(response.todo.description);
482        },
483    });
484});
485$(document).on("click", ".edit-note", function () {
486    var id = $(this).data("id");
487    $("#edit_note_modal").modal("show");
488    var url = $(this).data("url");
489    var classes = $("#note_color").attr("class").split(" ");
490    var currentColorClass = classes.filter(function (className) {
491        return className.startsWith("select-");
492    })[0];
493    $.ajax({
494        url: url,
495        type: "get",
496        headers: {
497            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
498        },
499        dataType: "json",
500        success: function (response) {
501            $("#note_id").val(response.note.id);
502            $("#note_title").val(response.note.title);
503            $("#note_color")
504                .val(response.note.color)
505                .removeClass(currentColorClass)
506                .addClass("select-bg-label-" + response.note.color);
507            var description =
508                response.note.description !== null
509                    ? response.note.description
510                    : "";
511            $("#edit_note_modal").find("#note_description").val(description);
512        },
513    });
514});
515$(document).on("click", ".edit-status", function () {
516    var id = $(this).data("id");
517    var routePrefix = $("#table").data("routePrefix");
518    $("#edit_status_modal").modal("show");
519    var classes = $("#status_color").attr("class").split(" ");
520    var currentColorClass = classes.filter(function (className) {
521        return className.startsWith("select-");
522    })[0];
523    $.ajax({
524        url: routePrefix + "/status/get/" + id,
525        type: "get",
526        headers: {
527            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
528        },
529        dataType: "json",
530        success: function (response) {
531            $("#status_id").val(response.status.id);
532            $("#status_title").val(response.status.title);
533            $("#status_color")
534                .val(response.status.color)
535                .removeClass(currentColorClass)
536                .addClass("select-bg-label-" + response.status.color);
537            var modalForm = $("#edit_status_modal").find("form");
538            var usersSelect = modalForm.find(
539                '.js-example-basic-multiple[name="role_ids[]"]'
540            );
541            usersSelect.val(response.roles);
542            usersSelect.trigger("change"); // Trigger change event to update select2
543        },
544    });
545});
546$(document).on("click", ".edit-scheduler-status", function () {
547    var id = $(this).data("id");
548    var routePrefix = $("#table").data("routePrefix");
549    $("#edit_scheduler_statuses_modal").modal("show");
550    $.ajax({
551        url: routePrefix + "/scheduler-statuses/get/" + id,
552        type: "get",
553        headers: {
554            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
555        },
556        dataType: "json",
557        success: function (response) {
558            $("#scheduler_statuses_id").val(response.status.id);
559            $("#scheduler_status_title").val(response.status.name);
560            $("#scheduler_lable").val(response.status.label);
561            $("#color_code").val(response.status.color_code);
562            var modalForm = $("#edit_scheduler_statuses_modal").find("form");
563        },
564    });
565});
566$(document).on("click", ".edit-document-categories", function () {
567    var id = $(this).data("id");
568    var routePrefix = $("#table").data("routePrefix");
569    $("#edit_dc_document_modal").modal("show");
570    $.ajax({
571        url: routePrefix + "/document-categories/get/" + id,
572        type: "get",
573        headers: {
574            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
575        },
576        dataType: "json",
577        success: function (response) {
578            console.log(response);
579            $("#dc_id").val(response.status.id);
580            $("#dc_update_title").val(response.status.title);
581            //$("#status_title").val(response.status.title);
582        },
583    });
584});
585$(document).on("click", ".edit-shift-type", function () {
586    var id = $(this).data("id");
587    var routePrefix = $("#table").data("routePrefix");
588    $("#edit_shift_type_modal").modal("show");
589    $.ajax({
590        url: routePrefix + "/shift-type/get/" + id,
591        type: "get",
592        headers: {
593            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
594        },
595        dataType: "json",
596        success: function (response) {
597            console.log(response);
598            $("#st_id").val(response.status.id);
599            $("#st_update_title").val(response.status.title);
600            //$("#status_title").val(response.status.title);
601        },
602    });
603});
604$(document).on("click", ".edit-tag", function () {
605    var id = $(this).data("id");
606    var routePrefix = $("#table").data("routePrefix");
607    var classes = $("#tag_color").attr("class").split(" ");
608    var currentColorClass = classes.filter(function (className) {
609        return className.startsWith("select-");
610    })[0];
611    $("#edit_tag_modal").modal("show");
612    $.ajax({
613        url: routePrefix + "/tags/get/" + id,
614        type: "get",
615        headers: {
616            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
617        },
618        dataType: "json",
619        success: function (response) {
620            $("#tag_id").val(response.tag.id);
621            $("#tag_title").val(response.tag.title);
622            $("#tag_color")
623                .val(response.tag.color)
624                .removeClass(currentColorClass)
625                .addClass("select-bg-label-" + response.tag.color);
626        },
627    });
628});
629$(document).on("click", ".edit-leave-request", function () {
630    var id = $(this).data("id");
631    $("#edit_leave_request_modal").modal("show");
632    $.ajax({
633        url: "/master-panel/leave-requests/get/" + id,
634        type: "get",
635        headers: {
636            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
637        },
638        dataType: "json",
639        success: function (response) {
640            var formattedFromDate = moment(response.lr.from_date).format(
641                js_date_format
642            );
643            var formattedToDate = moment(response.lr.to_date).format(
644                js_date_format
645            );
646            var fromDateSelect = $("#edit_leave_request_modal").find(
647                "#update_start_date"
648            );
649            var toDateSelect = $("#edit_leave_request_modal").find(
650                "#update_end_date"
651            );
652            var reasonSelect = $("#edit_leave_request_modal").find(
653                '[name="reason"]'
654            );
655            var totalDaysSelect = $("#edit_leave_request_modal").find(
656                "#update_total_days"
657            );
658            $("#lr_id").val(response.lr.id);
659            $("#leaveUser").val(
660                response.lr.user.first_name + " " + response.lr.user.last_name
661            );
662            fromDateSelect.val(formattedFromDate);
663            toDateSelect.val(formattedToDate);
664            initializeDateRangePicker("#update_start_date,#update_end_date");
665            var start_date = moment(fromDateSelect.val(), js_date_format);
666            var end_date = moment(toDateSelect.val(), js_date_format);
667            var total_days = end_date.diff(start_date, "days") + 1;
668            totalDaysSelect.val(total_days);
669            if (response.lr.from_time && response.lr.to_time) {
670                $("#updatePartialLeave")
671                    .prop("checked", true)
672                    .trigger("change");
673                var fromTimeSelect = $("#edit_leave_request_modal").find(
674                    '[name="from_time"]'
675                );
676                var toTimeSelect = $("#edit_leave_request_modal").find(
677                    '[name="to_time"]'
678                );
679                fromTimeSelect.val(response.lr.from_time);
680                toTimeSelect.val(response.lr.to_time);
681            } else {
682                $("#updatePartialLeave")
683                    .prop("checked", false)
684                    .trigger("change");
685            }
686            if (response.lr.visible_to_all) {
687                $("#edit_leave_request_modal")
688                    .find(".leaveVisibleToAll")
689                    .prop("checked", true)
690                    .trigger("change");
691            } else {
692                $("#edit_leave_request_modal")
693                    .find(".leaveVisibleToAll")
694                    .prop("checked", false)
695                    .trigger("change");
696                var visibleToSelect = $("#edit_leave_request_modal").find(
697                    '.js-example-basic-multiple[name="visible_to_ids[]"]'
698                );
699                var visibleToUsers = response.visibleTo.map((user) => user.id);
700                visibleToSelect.val(visibleToUsers);
701                visibleToSelect.trigger("change");
702            }
703            reasonSelect.val(response.lr.reason);
704            $("input[name=status][value=" + response.lr.status + "]").prop(
705                "checked",
706                true
707            );
708        },
709    });
710});
711$(document).on("click", ".edit-contract-type", function () {
712    var routePrefix = $("#table").data("routePrefix");
713    var id = $(this).data("id");
714    $("#edit_contract_type_modal").modal("show");
715    $.ajax({
716        url: "" + routePrefix + "/contracts/get-contract-type/" + id,
717        type: "get",
718        headers: {
719            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
720        },
721        dataType: "json",
722        success: function (response) {
723            $("#update_contract_type_id").val(response.ct.id);
724            $("#contract_type").val(response.ct.type);
725        },
726    });
727});
728$(document).on("click", ".edit-contract", function () {
729    var id = $(this).data("id");
730    var routePrefix = $("#contracts_table").data("routePrefix");
731    $("#edit_contract_modal").modal("show");
732    $.ajax({
733        url: "/master-panel/contracts/get/" + id,
734        type: "get",
735        headers: {
736            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
737        },
738        dataType: "json",
739        success: function (response) {
740            if (response.error == false) {
741                var formattedStartDate = moment(
742                    response.contract.start_date
743                ).format(js_date_format);
744                var formattedEndDate = moment(
745                    response.contract.end_date
746                ).format(js_date_format);
747                $("#contract_id").val(response.contract.id);
748                $("#title").val(response.contract.title);
749                $("#value").val(response.contract.value);
750                $("#client_id").val(response.contract.client_id);
751                $("#project_id").val(response.contract.project_id);
752                $("#contract_type_id").val(response.contract.contract_type_id);
753                $("#update_contract_description").val(
754                    response.contract.description
755                );
756                $("#update_start_date").val(formattedStartDate);
757                $("#update_end_date").val(formattedEndDate);
758                initializeDateRangePicker(
759                    "#update_start_date, #update_end_date"
760                );
761            } else {
762                location.reload();
763            }
764        },
765    });
766});
767function initializeDateRangePicker(inputSelector) {
768    // Find the modal that contains the input field
769    var modalId = $(inputSelector).closest(".modal").attr("id");
770    // Initialize daterangepicker and bind it to the modal using the modal ID
771    $(inputSelector).daterangepicker({
772        alwaysShowCalendars: true,
773        showCustomRangeLabel: true,
774        minDate: moment($(inputSelector).val(), js_date_format),
775        singleDatePicker: true,
776        showDropdowns: true,
777        autoUpdateInput: true,
778        parentEl: "#" + modalId, // Attach the daterangepicker to the modal
779        locale: {
780            cancelLabel: "Clear",
781            format: js_date_format,
782        },
783    });
784    // Optional: Reposition on modal scroll
785    $("#" + modalId).on("scroll", function () {
786        if ($(inputSelector).data("daterangepicker")) {
787            $(inputSelector).data("daterangepicker").hide();
788            $(inputSelector).data("daterangepicker").show();
789        }
790    });
791}
792$(document).on("click", "#set-as-default", function (e) {
793    e.preventDefault();
794    var lang = $(this).data("lang");
795    var url = $(this).data("url");
796    $("#default_language_modal").modal("show"); // show the confirmation modal
797    $("#default_language_modal").on("click", "#confirm", function () {
798        $.ajax({
799            url: url,
800            type: "PUT",
801            headers: {
802                "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
803            },
804            data: {
805                lang: lang,
806            },
807            success: function (response) {
808                if (response.error == false) {
809                    location.reload();
810                } else {
811                    toastr.error(response.message);
812                }
813            },
814        });
815    });
816});
817$(document).on("click", "#remove-participant", function (e) {
818    e.preventDefault();
819    var routePrefix = $(this).data("routePrefix");
820    $("#leaveWorkspaceModal").modal("show"); // show the confirmation modal
821    $("#leaveWorkspaceModal").on("click", "#confirm", function () {
822        $.ajax({
823            url: routePrefix + "/workspaces/remove_participant",
824            type: "GET",
825            headers: {
826                "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
827            },
828            success: function (response) {
829                location.reload();
830            },
831            error: function (data) {
832                location.reload();
833            },
834        });
835    });
836});
837$(document).ready(function () {
838    // Define the IDs you want to process
839    var idsToProcess = [
840        "#start_date",
841        "#end_date",
842        "#update_start_date",
843        "#update_end_date",
844        "#lr_end_date",
845        "#meeting_end_date",
846        "#expense_date",
847        "#update_expense_date",
848        "#payment_date",
849        "#update_payment_date",
850        "#update_milestone_start_date",
851        "#update_milestone_end_date",
852        "#task_start_date",
853        "#task_end_date",
854        "#edit_announcement_start_date",
855        "#edit_announcement_end_date",
856    ];
857    // Loop through the IDs
858    for (var i = 0; i < idsToProcess.length; i++) {
859        var id = idsToProcess[i];
860        if ($(id).length) {
861            if (
862                id === "#payment_date" &&
863                !$(id).closest("#create_payment_modal").length
864            ) {
865                continue;
866            }
867            if ($(id).val() == "") {
868                $(id).val(moment(new Date()).format(js_date_format));
869            }
870            var modalId = $(id).closest(".modal").attr("id");
871            $(id).daterangepicker({
872                alwaysShowCalendars: true,
873                showCustomRangeLabel: true,
874                // minDate: moment($(id).val(), js_date_format),
875                parentEl: "#" + modalId, // Attach the daterangepicker to the modal
876                singleDatePicker: true,
877                showDropdowns: true,
878                autoUpdateInput: true,
879                locale: {
880                    cancelLabel: "Clear",
881                    format: js_date_format,
882                },
883                function(start, end, label) {
884                    // Replace Font Awesome/Glyphicon icons with Boxicons
885                    $(".daterangepicker .prev").html(
886                        '<i class="bx bx-chevron-left"></i>'
887                    );
888                    $(".daterangepicker .next").html(
889                        '<i class="bx bx-chevron-right"></i>'
890                    );
891                },
892            });
893        }
894    }
895    // Define the IDs you want to process
896    var idsToProcess = ["#payment_date", "#dob", "#doj"];
897    var minDateStr = "01/01/1950";
898    var minDate = moment(minDateStr, "DD/MM/YYYY");
899    // Loop through the IDs
900    for (var i = 0; i < idsToProcess.length; i++) {
901        var id = idsToProcess[i];
902        if ($(id).length) {
903            var modalId = $(id).closest(".modal").attr("id");
904            $(id).daterangepicker({
905                alwaysShowCalendars: true,
906                showCustomRangeLabel: true,
907                singleDatePicker: true,
908                showDropdowns: true,
909                autoUpdateInput: false,
910                minDate: minDate,
911                parentEl: "#" + modalId,
912                locale: {
913                    cancelLabel: "Clear",
914                    format: js_date_format,
915                },
916            });
917            $(id).on("apply.daterangepicker", function (ev, picker) {
918                // Update the input with the selected date
919
920
921
922                if ($(this).attr('id') === 'dob') {
923                    $('#start').val(picker.startDate.format("YYYY-MM-DD")).trigger('change');
924                    console.log('Start date set:', $('#start').val());
925                } else if ($(this).attr('id') === 'doj') {
926                    $('#end').val(picker.startDate.format("YYYY-MM-DD")).trigger('change');
927                    console.log('End date set:', $('#end').val());
928                }
929
930
931
932                $(this).val(picker.startDate.format(js_date_format));
933            });
934        }
935    }
936});
937if ($("#total_days").length) {
938    $("#end_date").on("apply.daterangepicker", function (ev, picker) {
939        // Calculate the inclusive difference in days between start_date and end_date
940        var start_date = moment($("#start_date").val(), js_date_format);
941        var end_date = picker.startDate;
942        var total_days = end_date.diff(start_date, "days") + 1;
943        // Display the total_days in the total_days input field
944        $("#total_days").val(total_days);
945    });
946}
947$(document).ready(function () {
948    $(
949        "#report_start_date_between,#report_end_date_between,#filter_date_range,#project_start_date_between,#project_end_date_between,#task_start_date_between,#task_end_date_between,#lr_start_date_between,#lr_end_date_between,#contract_start_date_between,#contract_end_date_between,#timesheet_start_date_between,#timesheet_end_date_between,#meeting_start_date_between,#meeting_end_date_between,#activity_log_between_date,#start_date_between,#end_date_between,#expense_from_date_between"
950    ).daterangepicker({
951        alwaysShowCalendars: true,
952        showCustomRangeLabel: true,
953        singleDatePicker: false,
954        showDropdowns: true,
955        autoUpdateInput: false,
956        locale: {
957            cancelLabel: "Clear",
958            format: js_date_format,
959        },
960    });
961    $(
962        "#report_start_date_between,#report_end_date_between,#filter_date_range,#project_start_date_between,#project_end_date_between,#task_start_date_between,#task_end_date_between,#lr_start_date_between,#lr_end_date_between,#contract_start_date_between,#contract_end_date_between,#timesheet_start_date_between,#timesheet_end_date_between,#meeting_start_date_between,#meeting_end_date_between,#activity_log_between_date,#start_date_between,#end_date_between,#expense_from_date_between"
963    ).on("apply.daterangepicker", function (ev, picker) {
964        $(this).val(
965            picker.startDate.format(js_date_format) +
966            " To " +
967            picker.endDate.format(js_date_format)
968        );
969    });
970});
971if ($("#project_start_date_between").length) {
972    $("#project_start_date_between").on(
973        "apply.daterangepicker",
974        function (ev, picker) {
975            var startDate = picker.startDate.format("YYYY-MM-DD");
976            var endDate = picker.endDate.format("YYYY-MM-DD");
977            $("#project_start_date_from").val(startDate);
978            $("#project_start_date_to").val(endDate);
979            $("#projects_table").bootstrapTable("refresh");
980        }
981    );
982    $("#project_start_date_between").on(
983        "cancel.daterangepicker",
984        function (ev, picker) {
985            $("#project_start_date_from").val("");
986            $("#project_start_date_to").val("");
987            $("#projects_table").bootstrapTable("refresh");
988            $("#project_start_date_between").val("");
989        }
990    );
991    $("#project_end_date_between").on(
992        "apply.daterangepicker",
993        function (ev, picker) {
994            var startDate = picker.startDate.format("YYYY-MM-DD");
995            var endDate = picker.endDate.format("YYYY-MM-DD");
996            $("#project_end_date_from").val(startDate);
997            $("#project_end_date_to").val(endDate);
998            $("#projects_table").bootstrapTable("refresh");
999        }
1000    );
1001    $("#project_end_date_between").on(
1002        "cancel.daterangepicker",
1003        function (ev, picker) {
1004            $("#project_end_date_from").val("");
1005            $("#project_end_date_to").val("");
1006            $("#projects_table").bootstrapTable("refresh");
1007            $("#project_end_date_between").val("");
1008        }
1009    );
1010}
1011if ($("#task_start_date_between").length) {
1012    $("#task_start_date_between").on(
1013        "apply.daterangepicker",
1014        function (ev, picker) {
1015            var startDate = picker.startDate.format("YYYY-MM-DD");
1016            var endDate = picker.endDate.format("YYYY-MM-DD");
1017            $("#task_start_date_from").val(startDate);
1018            $("#task_start_date_to").val(endDate);
1019            $("#task_table").bootstrapTable("refresh");
1020        }
1021    );
1022    $("#task_start_date_between").on(
1023        "cancel.daterangepicker",
1024        function (ev, picker) {
1025            $("#task_start_date_from").val("");
1026            $("#task_start_date_to").val("");
1027            $("#task_table").bootstrapTable("refresh");
1028            $("#task_start_date_between").val("");
1029        }
1030    );
1031    $("#task_end_date_between").on(
1032        "apply.daterangepicker",
1033        function (ev, picker) {
1034            var startDate = picker.startDate.format("YYYY-MM-DD");
1035            var endDate = picker.endDate.format("YYYY-MM-DD");
1036            $("#task_end_date_from").val(startDate);
1037            $("#task_end_date_to").val(endDate);
1038            $("#task_table").bootstrapTable("refresh");
1039        }
1040    );
1041    $("#task_end_date_between").on(
1042        "cancel.daterangepicker",
1043        function (ev, picker) {
1044            $("#task_end_date_from").val("");
1045            $("#task_end_date_to").val("");
1046            $("#task_table").bootstrapTable("refresh");
1047            $("#task_end_date_between").val("");
1048        }
1049    );
1050}
1051if ($("#timesheet_start_date_between").length) {
1052    $("#timesheet_start_date_between").on(
1053        "apply.daterangepicker",
1054        function (ev, picker) {
1055            var startDate = picker.startDate.format("YYYY-MM-DD");
1056            var endDate = picker.endDate.format("YYYY-MM-DD");
1057            $("#timesheet_start_date_from").val(startDate);
1058            $("#timesheet_start_date_to").val(endDate);
1059            $("#timesheet_table").bootstrapTable("refresh");
1060        }
1061    );
1062    $("#timesheet_start_date_between").on(
1063        "cancel.daterangepicker",
1064        function (ev, picker) {
1065            $("#timesheet_start_date_from").val("");
1066            $("#timesheet_start_date_to").val("");
1067            $("#timesheet_table").bootstrapTable("refresh");
1068            $("#timesheet_start_date_between").val("");
1069        }
1070    );
1071    $("#timesheet_end_date_between").on(
1072        "apply.daterangepicker",
1073        function (ev, picker) {
1074            var startDate = picker.startDate.format("YYYY-MM-DD");
1075            var endDate = picker.endDate.format("YYYY-MM-DD");
1076            $("#timesheet_end_date_from").val(startDate);
1077            $("#timesheet_end_date_to").val(endDate);
1078            $("#timesheet_table").bootstrapTable("refresh");
1079        }
1080    );
1081    $("#timesheet_end_date_between").on(
1082        "cancel.daterangepicker",
1083        function (ev, picker) {
1084            $("#timesheet_end_date_from").val("");
1085            $("#timesheet_end_date_to").val("");
1086            $("#timesheet_table").bootstrapTable("refresh");
1087            $("#timesheet_end_date_between").val("");
1088        }
1089    );
1090}
1091if ($("#meeting_start_date_between").length) {
1092    $("#meeting_start_date_between").on(
1093        "apply.daterangepicker",
1094        function (ev, picker) {
1095            var startDate = picker.startDate.format("YYYY-MM-DD");
1096            var endDate = picker.endDate.format("YYYY-MM-DD");
1097            $("#meeting_start_date_from").val(startDate);
1098            $("#meeting_start_date_to").val(endDate);
1099            $("#meetings_table").bootstrapTable("refresh");
1100        }
1101    );
1102    $("#meeting_start_date_between").on(
1103        "cancel.daterangepicker",
1104        function (ev, picker) {
1105            $("#meeting_start_date_from").val("");
1106            $("#meeting_start_date_to").val("");
1107            $("#meetings_table").bootstrapTable("refresh");
1108            $("#meeting_start_date_between").val("");
1109        }
1110    );
1111    $("#meeting_end_date_between").on(
1112        "apply.daterangepicker",
1113        function (ev, picker) {
1114            var startDate = picker.startDate.format("YYYY-MM-DD");
1115            var endDate = picker.endDate.format("YYYY-MM-DD");
1116            $("#meeting_end_date_from").val(startDate);
1117            $("#meeting_end_date_to").val(endDate);
1118            $("#meetings_table").bootstrapTable("refresh");
1119        }
1120    );
1121    $("#meeting_end_date_between").on(
1122        "cancel.daterangepicker",
1123        function (ev, picker) {
1124            $("#meeting_end_date_from").val("");
1125            $("#meeting_end_date_to").val("");
1126            $("#meetings_table").bootstrapTable("refresh");
1127            $("#meeting_end_date_between").val("");
1128        }
1129    );
1130}
1131$(
1132    "textarea#footer_text,textarea#contract_description,textarea#update_contract_description , #privacy_policy , #terms_and_conditions , #refund_policy , #company_address,.description"
1133).tinymce({
1134    height: 250,
1135    menubar: false,
1136    plugins: [
1137        "link",
1138        "a11ychecker",
1139        "advlist",
1140        "advcode",
1141        "advtable",
1142        "autolink",
1143        "checklist",
1144        "export",
1145        "lists",
1146        "link",
1147        "image",
1148        "charmap",
1149        "preview",
1150        "anchor",
1151        "searchreplace",
1152        "visualblocks",
1153        "powerpaste",
1154        "fullscreen",
1155        "formatpainter",
1156        "insertdatetime",
1157        "media",
1158        "table",
1159        "help",
1160        "wordcount",
1161    ],
1162    toolbar:
1163        "link | undo redo | a11ycheck casechange blocks | bold italic backcolor | alignleft aligncenter alignright al
1163ignjustify | bullist numlist checklist outdent indent | removeformat | code table help",
1164});
1165$(document).on("submit", ".form-submit-event", function (e) {
1166    e.preventDefault();
1167    if ($("#net_payable").length > 0) {
1168        var net_payable = $("#net_payable").text();
1169        $("#net_pay").val(net_payable);
1170    }
1171    var formData = new FormData(this);
1172    var currentForm = $(this);
1173    var parentModal = $(this).closest(".modal");
1174    var submit_btn = $(this).find("#submit_btn");
1175    if (submit_btn.length == 0) {
1176        submit_btn = parentModal.find('button[type="submit"]');
1177    }
1178    // If still no submit button found, check within the form
1179    if (submit_btn.length === 0) {
1180        submit_btn = currentForm.find('button[type="submit"]');
1181    }
1182    var btn_html = submit_btn.html();
1183    var btn_val = submit_btn.val();
1184    var redirect_url = currentForm.find('input[name="redirect_url"]').val();
1185    redirect_url =
1186        typeof redirect_url !== "undefined" && redirect_url ? redirect_url : "";
1187    var button_text =
1188        btn_html != "" || btn_html != "undefined" ? btn_html : btn_val;
1189    var tableInput = currentForm.find('input[name="table"]');
1190    var tableID = tableInput.length ? tableInput.val() : "table";
1191    $.ajax({
1192        type: "POST",
1193        url: $(this).attr("action"),
1194        data: formData,
1195        headers: {
1196            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
1197        },
1198        beforeSend: function () {
1199            submit_btn.html(label_please_wait);
1200            submit_btn.attr("disabled", true);
1201        },
1202        cache: false,
1203        contentType: false,
1204        processData: false,
1205        dataType: "json",
1206        success: function (result) {
1207            submit_btn.html(button_text);
1208            submit_btn.attr("disabled", false);
1209            if (result["error"] == true) {
1210                toastr.error(result["message"]);
1211            } else {
1212                if ($(".empty-state").length > 0) {
1213                    if (result.hasOwnProperty("message")) {
1214                        toastr.success(result["message"]);
1215                        // Show toastr for 3 seconds before reloading or redirecting
1216                        setTimeout(handleRedirection, 3000);
1217                    } else {
1218                        handleRedirection();
1219                    }
1220                } else {
1221                    if (currentForm.find('input[name="dnr"]').length > 0) {
1222                        var modalWithClass = $(".modal.fade.show");
1223                        if (modalWithClass.length > 0) {
1224                            var idOfModal = modalWithClass.attr("id");
1225                            $("#" + idOfModal).modal("hide");
1226                            $("#" + tableID).bootstrapTable("refresh");
1227                            currentForm[0].reset();
1228                            var partialLeaveCheckbox = $("#partialLeave");
1229                            if (partialLeaveCheckbox.length) {
1230                                partialLeaveCheckbox.trigger("change");
1231                            }
1232                            resetDateFields(currentForm);
1233                            if (idOfModal == "create_status_modal") {
1234                                var dropdownSelector = modalWithClass.find(
1235                                    'select[name="status_id"]'
1236                                );
1237                                if (dropdownSelector.length) {
1238                                    var newItem = result.status;
1239                                    var newOption = $("<option></option>")
1240                                        .attr("value", newItem.id)
1241                                        .attr("data-color", newItem.color)
1242                                        .attr("selected", true)
1243                                        .text(
1244                                            newItem.title +
1245                                            " (" +
1246                                            newItem.color +
1247                                            ")"
1248                                        );
1249                                    $(dropdownSelector).append(newOption);
1250                                    var openModalId = dropdownSelector
1251                                        .closest(".modal.fade.show")
1252                                        .attr("id");
1253                                    // List of all possible modal IDs
1254                                    var modalIds = [
1255                                        "#create_project_modal",
1256                                        "#edit_project_modal",
1257                                        "#create_task_modal",
1258                                        "#edit_task_modal",
1259                                    ];
1260                                    // Iterate through each modal ID
1261                                    modalIds.forEach(function (modalId) {
1262                                        // If the modal ID is not the open one
1263                                        if (modalId !== "#" + openModalId) {
1264                                            // Find the select element within the modal
1265                                            var otherModalSelector = $(
1266                                                modalId
1267                                            ).find('select[name="status_id"]');
1268                                            // Create a new option without 'selected' attribute
1269                                            var otherOption = $(
1270                                                "<option></option>"
1271                                            )
1272                                                .attr("value", newItem.id)
1273                                                .attr(
1274                                                    "data-color",
1275                                                    newItem.color
1276                                                )
1277                                                .text(
1278                                                    newItem.title +
1279                                                    " (" +
1280                                                    newItem.color +
1281                                                    ")"
1282                                                );
1283                                            // Append the option to the select element in the modal
1284                                            otherModalSelector.append(
1285                                                otherOption
1286                                            );
1287                                        }
1288                                    });
1289                                }
1290                            }
1291                            if (idOfModal == "create_priority_modal") {
1292                                var dropdownSelector = modalWithClass.find(
1293                                    'select[name="priority_id"]'
1294                                );
1295                                if (dropdownSelector.length) {
1296                                    var newItem = result.priority;
1297                                    var newOption = $("<option></option>")
1298                                        .attr("value", newItem.id)
1299                                        .attr(
1300                                            "class",
1301                                            "badge bg-label-" + newItem.color
1302                                        )
1303                                        .attr("selected", true)
1304                                        .text(
1305                                            newItem.title +
1306                                            " (" +
1307                                            newItem.color +
1308                                            ")"
1309                                        );
1310                                    $(dropdownSelector).append(newOption);
1311                                    var openModalId = dropdownSelector
1312                                        .closest(".modal.fade.show")
1313                                        .attr("id");
1314                                    // List of all possible modal IDs
1315                                    var modalIds = [
1316                                        "#create_project_modal",
1317                                        "#edit_project_modal",
1318                                        "#create_task_modal",
1319                                        "#edit_task_modal",
1320                                    ];
1321                                    // Iterate through each modal ID
1322                                    modalIds.forEach(function (modalId) {
1323                                        // If the modal ID is not the open one
1324                                        if (modalId !== "#" + openModalId) {
1325                                            // Find the select element within the modal
1326                                            var otherModalSelector = $(
1327                                                modalId
1328                                            ).find(
1329                                                'select[name="priority_id"]'
1330                                            );
1331                                            // Create a new option without 'selected' attribute
1332                                            var otherOption = $(
1333                                                "<option></option>"
1334                                            )
1335                                                .attr("value", newItem.id)
1336                                                .attr(
1337                                                    "class",
1338                                                    "badge bg-label-" +
1339                                                    newItem.color
1340                                                )
1341                                                .text(
1342                                                    newItem.title +
1343                                                    " (" +
1344                                                    newItem.color +
1345                                                    ")"
1346                                                );
1347                                            // Append the option to the select element in the modal
1348                                            otherModalSelector.append(
1349                                                otherOption
1350                                            );
1351                                        }
1352                                    });
1353                                }
1354                            }
1355                            if (idOfModal == "create_tag_modal") {
1356                                var dropdownSelector = modalWithClass.find(
1357                                    'select[name="tag_ids[]"]'
1358                                );
1359                                if (dropdownSelector.length) {
1360                                    var newItem = result.tag;
1361                                    var newOption = $("<option></option>")
1362                                        .attr("value", newItem.id)
1363                                        .attr("data-color", newItem.color)
1364                                        .attr("selected", true)
1365                                        .text(newItem.title);
1366                                    $(dropdownSelector).append(newOption);
1367                                    $(dropdownSelector).trigger("change");
1368                                    var openModalId = dropdownSelector
1369                                        .closest(".modal.fade.show")
1370                                        .attr("id");
1371                                    // List of all possible modal IDs
1372                                    var modalIds = [
1373                                        "#create_project_modal",
1374                                        "#edit_project_modal",
1375                                    ];
1376                                    // Iterate through each modal ID
1377                                    modalIds.forEach(function (modalId) {
1378                                        // If the modal ID is not the open one
1379                                        if (modalId !== "#" + openModalId) {
1380                                            // Find the select element within the modal
1381                                            var otherModalSelector = $(
1382                                                modalId
1383                                            ).find('select[name="tag_ids[]"]');
1384                                            // Create a new option without 'selected' attribute
1385                                            var otherOption = $(
1386                                                "<option></option>"
1387                                            )
1388                                                .attr("value", newItem.id)
1389                                                .attr(
1390                                                    "data-color",
1391                                                    newItem.color
1392                                                )
1393                                                .text(newItem.title);
1394                                            // Append the option to the select element in the modal
1395                                            otherModalSelector.append(
1396                                                otherOption
1397                                            );
1398                                        }
1399                                    });
1400                                }
1401                            }
1402                            if (idOfModal == "create_item_modal") {
1403                                var dropdownSelector = $("#item_id");
1404                                if (dropdownSelector.length) {
1405                                    var newItem = result.item;
1406                                    var newOption = $("<option></option>")
1407                                        .attr("value", newItem.id)
1408                                        .attr("selected", true)
1409                                        .text(newItem.title);
1410                                    $(dropdownSelector).append(newOption);
1411                                    $(dropdownSelector).trigger("change");
1412                                }
1413                            }
1414                            if (idOfModal === "create_contract_type_modal") {
1415                                var dropdownSelector = modalWithClass.find(
1416                                    'select[name="contract_type_id"]'
1417                                );
1418                                if (dropdownSelector.length) {
1419                                    var newItem = result.ct;
1420                                    var newOption = $("<option></option>")
1421                                        .attr("value", newItem.id)
1422                                        .attr("selected", true)
1423                                        .text(newItem.type);
1424                                    // Append and select the new option in the current modal
1425                                    dropdownSelector.append(newOption);
1426                                    var openModalId = dropdownSelector
1427                                        .closest(".modal.fade.show")
1428                                        .attr("id");
1429                                    var otherModalId =
1430                                        openModalId === "create_contract_modal"
1431                                            ? "#edit_contract_modal"
1432                                            : "#create_contract_modal";
1433                                    var otherModalSelector = $(
1434                                        otherModalId
1435                                    ).find('select[name="contract_type_id"]');
1436                                    // Create a new option for the other modal without 'selected' attribute
1437                                    var otherOption = $("<option></option>")
1438                                        .attr("value", newItem.id)
1439                                        .text(newItem.type);
1440                                    // Append the option to the other modal
1441                                    otherModalSelector.append(otherOption);
1442                                }
1443              
1443              }
1444                            if (idOfModal == "create_pm_modal") {
1445                                var dropdownSelector = $(
1446                                    'select[name="payment_method_id"]'
1447                                );
1448                                if (dropdownSelector.length) {
1449                                    var newItem = result.pm;
1450                                    var newOption = $("<option></option>")
1451                                        .attr("value", newItem.id)
1452                                        .attr("selected", true)
1453                                        .text(newItem.title);
1454                                    $(dropdownSelector).append(newOption);
1455                                    $(dropdownSelector).trigger("change");
1456                                }
1457                            }
1458                            if (idOfModal == "create_allowance_modal") {
1459                                var dropdownSelector = $(
1460                                    'select[name="allowance_id"]'
1461                                );
1462                                if (dropdownSelector.length) {
1463                                    var newItem = result.allowance;
1464                                    var newOption = $("<option></option>")
1465                                        .attr("value", newItem.id)
1466                                        .attr("selected", true)
1467                                        .text(newItem.title);
1468                                    $(dropdownSelector).append(newOption);
1469                                    $(dropdownSelector).trigger("change");
1470                                }
1471                            }
1472                            if (idOfModal == "create_deduction_modal") {
1473                                var dropdownSelector = $(
1474                                    'select[name="deduction_id"]'
1475                                );
1476                                if (dropdownSelector.length) {
1477                                    var newItem = result.deduction;
1478                                    var newOption = $("<option></option>")
1479                                        .attr("value", newItem.id)
1480                                        .attr("selected", true)
1481                                        .text(newItem.title);
1482                                    $(dropdownSelector).append(newOption);
1483                                    $(dropdownSelector).trigger("change");
1484                                }
1485                            }
1486                        }
1487                        toastr.success(result["message"]);
1488                    } else {
1489                        if (result.hasOwnProperty("message")) {
1490                            toastr.success(result["message"]);
1491                            // Show toastr for 3 seconds before reloading or redirecting
1492                            setTimeout(handleRedirection, 3000);
1493                        } else {
1494                            handleRedirection();
1495                        }
1496                    }
1497                }
1498            }
1499        },
1500        error: function (xhr, status, error) {
1501            submit_btn.html(button_text);
1502            submit_btn.attr("disabled", false);
1503
1504            if (!navigator.onLine) {
1505                // Browser reports offline
1506                toastr.error("No internet connection. Please check your network.");
1507                return;
1508            }
1509
1510            if (xhr.status === 422) {
1511                // Handle validation errors here
1512                var response = xhr.responseJSON; // Assuming you're returning JSON
1513                if (response.error) {
1514                    // Handle the general error message
1515                    var generalErrorMessage = response.message;
1516                    toastr.error(generalErrorMessage);
1517                }
1518                // You can access validation errors from the response object
1519                var errors = response.errors;
1520                for (var key in errors) {
1521                    if (
1522                        errors.hasOwnProperty(key) &&
1523                        Array.isArray(errors[key])
1524                    ) {
1525                        errors[key].forEach(function (error) {
1526                            toastr.error(error);
1527                        });
1528                    }
1529                }
1530                // Example: Display the first validation error message
1531                toastr.error(label_please_correct_errors);
1532                // Assuming you have a list of all input fields with error messages
1533                var inputFields = currentForm.find(
1534                    "input[name], select[name], textarea[name]"
1535                );
1536                inputFields = $(inputFields.toArray().reverse());
1537                // Iterate through all input fields
1538                inputFields.each(function () {
1539                    var inputField = $(this);
1540                    var fieldName = inputField.attr("name");
1541                    var errorMessageElement;
1542                    if (errors && errors[fieldName]) {
1543                        if (inputField.closest(".input-group").length) {
1544                            errorMessageElement = inputField
1545                                .closest(".input-group")
1546                                .next(".error-message");
1547                            if (errorMessageElement.length === 0) {
1548                                errorMessageElement = $(
1549                                    '<span class="text-danger error-message"></span>'
1550                                );
1551                                inputField
1552                                    .closest(".input-group")
1553                                    .after(errorMessageElement);
1554                            }
1555                        } else {
1556                            errorMessageElement = inputField.next(
1557                                ".text-danger.error-message"
1558                            );
1559                            if (errorMessageElement.length === 0) {
1560                                errorMessageElement = $(
1561                                    '<span class="text-danger error-message"></span>'
1562                                );
1563                                inputField.after(errorMessageElement);
1564                            }
1565                        }
1566                        errorMessageElement.text(errors[fieldName][0]);
1567                        inputField[0].scrollIntoView({
1568                            behavior: "smooth",
1569                            block: "start",
1570                        });
1571                        inputField.focus();
1572                    } else {
1573                        // If there is no validation error message, clear the existing message
1574                        errorMessageElement = inputField.next(".error-message");
1575                        if (errorMessageElement.length === 0) {
1576                            errorMessageElement = inputField
1577                                .parent()
1578                                .nextAll(".error-message")
1579                                .first();
1580                        }
1581                        if (
1582                            errorMessageElement &&
1583                            errorMessageElement.length > 0
1584                        ) {
1585                            errorMessageElement.remove();
1586                        }
1587                    }
1588                });
1589            } else {
1590                // Handle other errors (non-validation errors) here
1591                toastr.error(error);
1592            }
1593        },
1594    });
1595    function handleRedirection() {
1596        if (redirect_url === "") {
1597            window.location.reload(); // Reload the current page
1598        } else {
1599            window.location.href = redirect_url; // Redirect to specified URL
1600        }
1601    }
1602});
1603// Click event handler for the favorite icon
1604$(document).on("click", ".favorite-icon", function () {
1605    var icon = $(this);
1606    var routePrefix = $(this).data("routePrefix");
1607    var projectId = $(this).data("id");
1608    var isFavorite = icon.attr("data-favorite");
1609    isFavorite = isFavorite == 1 ? 0 : 1;
1610    var reload = $(this).data("require_reload") !== undefined ? 1 : 0;
1611    var dataTitle = icon.data("bs-original-title");
1612    var temp = dataTitle !== undefined ? "data-bs-original-title" : "title";
1613    // Send an AJAX request to update the favorite status
1614    $.ajax({
1615        url: "/master-panel/projects/update-favorite/" + projectId,
1616        type: "POST",
1617        headers: {
1618            "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
1619        },
1620        data: {
1621            is_favorite: isFavorite,
1622        },
1623        success: function (response) {
1624            if (reload) {
1625                location.reload();
1626            } else {
1627                icon.attr("data-favorite", isFavorite);
1628                // Update the tooltip text
1629                if (isFavorite == 0) {
1630                    icon.removeClass("bxs-star");
1631                    icon.addClass("bx-star");
1632                    icon.attr(temp, add_favorite); // Update the tooltip text
1633                    toastr.success(
1634                        label_project_removed_from_favorite_successfully
1635                    );
1636                } else {
1637                    icon.removeClass("bx-star");
1638                    icon.addClass("bxs-star");
1639                    icon.attr(temp, remove_favorite); // Update the tooltip text
1640                    toastr.success(
1641                        label_project_marked_as_favorite_successfully
1642                    );
1643                }
1644            }
1645        },
1646        error: function (data) {
1647            // Handle errors if necessary
1648            toastr.error(error);
1649        },
1650    });
1651});
1652$(document).on("click", ".duplicate", function (e) {
1653    e.preventDefault();
1654    var id = $(this).data("id");
1655    var type = $(this).data("type");
1656    var reload = $(this).data("reload"); // Get the value of data-reload attribute
1657    if (typeof reload !== "undefined" && reload === true) {
1658        reload = true;
1659    } else {
1660        reload = false;
1661    }
1662    var tableID = $(this).data("table") || "table";
1663    $("#duplicateModal").modal("show"); // show the confirmation modal
1664    $("#duplicateModal").off("click", "#confirmDuplicate");
1665    if (type != "estimates-invoices" && type != "payslips") {
1666        $("#duplicateModal").find("#titleDiv").removeClass("d-none");
1667        var title = $(this).data("title");
1668        $("#duplicateModal").find("#updateTitle").val(title);
1669    } else {
1670        $("#duplicateModal").find("#titleDiv").addClass("d-none");
1671    }
1672    $("#duplicateModal").on("click", "#confirmDuplicate", function (e) {
1673        e.preventDefault();
1674        var title = $("#duplicateModal").find("#updateTitle").val();
1675        $("#confirmDuplicate").html(label_please_wait).attr("disabled", true);
1676        $.ajax({
1677            url:
1678                "/master-panel/" +
1679                type +
1680                "/duplicate/" +
1681                id +
1682                "?reload=" +
1683                reload +
1684                "&title=" +
1685                title,
1686            type: "GET",
1687            headers: {
1688                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
1689            },
1690            success: function (response) {
1691                $("#confirmDuplicate").html(label_yes).attr("disabled", false);
1692                $("#duplicateModal").modal("hide");
1693                if (response.error == false) {
1694                    if (reload) {
1695                        location.reload();
1696                    } else {
1697                        toastr.success(response.message);
1698                        if (tableID) {
1699                            $("#" + tableID).bootstrapTable("refresh");
1700                        }
1701                    }
1702                } else {
1703                    toastr.error(response.message);
1704                }
1705            },
1706            error: function (data) {
1707                $("#confirmDuplicate").html(label_yes).attr("disabled", false);
1708                $("#duplicateModal").modal("hide");
1709                var response = data.responseJSON;
1710                if (response.error) {
1711                    toastr.error(response.message);
1712                } else {
1713                    toastr.error(label_something_went_wrong);
1714                }
1715            },
1716        });
1717    });
1718});
1719$("#deduction_type").on("change", function (e) {
1720    if ($("#deduction_type").val() == "amount") {
1721        $("#amount_div").removeClass("d-none");
1722        $("#percentage_div").addClass("d-none");
1723    } else if ($("#deduction_type").val() == "percentage") {
1724        $("#amount_div").addClass("d-none");
1725        $("#percentage_div").removeClass("d-none");
1726    } else {
1727        $("#amount_div").addClass("d-none");
1728        $("#percentage_div").addClass("d-none");
1729    }
1730});
1731$("#update_deduction_type").on("change", function (e) {
1732    if ($("#update_deduction_type").val() == "amount") {
1733        $("#update_amount_div").removeClass("d-none");
1734        $("#update_percentage_div").addClass("d-none");
1735    } else if ($("#update_deduction_type").val() == "percentage") {
1736        $("#update_amount_div").addClass("d-none");
1737        $("#update_percentage_div").removeClass("d-none");
1738    } else {
1739        $("#update_amount_div").addClass("d-none");
1740        $("#update_percentage_div").addClass("d-none");
1741    }
1742});
1743if (document.getElementById("system-update-dropzone")) {
1744    var is_error = false;
1745    if (!$("#system-update").hasClass("dropzone")) {
1746        var systemDropzone = new Dropzone("#system-update-dropzone", {
1747            url: $("#system-update").attr("action"),
1748            paramName: "update_file",
1749            autoProcessQueue: false,
1750            parallelUploads: 1,
1751            maxFiles: 1,
1752            acceptedFiles: ".zip",
1753            timeout: 360000,
1754            autoDiscover: false,
1755            headers: {
1756                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), // Pass the CSRF token as a header
1757            },
1758            addRemoveLinks: true,
1759            dictRemoveFile: "x",
1760            dictMaxFilesExceeded: "Only 1 file can be uploaded at a time",
1761            dictResponseError: "Error",
1762            uploadMultiple: true,
1763            dictDefaultMessage:
1764                '<p><input type="button" value="Select Files" class="btn btn-primary" /><br> or <br> Drag & Drop System Update / Installable / Plugin\'s .zip file Here</p>',
1765        });
1766        systemDropzone.on("addedfile", function (file) {
1767            var i = 0;
1768            if (this.files.length) {
1769                var _i, _len;
1770                for (_i = 0, _len = this.files.length; _i < _len - 1; _i++) {
1771                    if (
1772                        this.files[_i].name === file.name &&
1773                        this.files[_i].size === file.size &&
1774                        this.files[_i].lastModifiedDate.toString() ===
1775                        file.lastModifiedDate.toString()
1776                    ) {
1777                        this.removeFile(file);
1778                        i++;
1779                    }
1780                }
1781            }
1782        });
1783        systemDropzone.on("error", function (file, response) { });
1784        systemDropzone.on("sending", function (file, xhr, formData) {
1785            formData.append("flash_message", 1);
1786            xhr.onreadystatechange = function (response) {
1787                // return;
1788                setTimeout(function () {
1789                    location.reload();
1790                }, 2000);
1791            };
1792        });
1793        $("#system_update_btn").on("click", function (e) {
1794            e.preventDefault();
1795            if (is_error == false) {
1796                if (systemDropzone.files.length === 0) {
1797                    // Show toast message if no file is selected
1798                    toastr.error("Please select a file to upload.");
1799                    setTimeout(function () {
1800                        location.reload();
1801                    }, 2000);
1802                }
1803                $("#system_update_btn")
1804                    .attr("disabled", true)
1805                    .text(label_please_wait);
1806                systemDropzone.processQueue();
1807            }
1808        });
1809    }
1810}
1811if (document.getElementById("media-upload-dropzone")) {
1812    var is_error = false;
1813    var mediaDropzone = new Dropzone("#media-upload-dropzone", {
1814        url: $("#media-upload").attr("action"),
1815        paramName: "media_files",
1816        autoProcessQueue: false,
1817        timeout: 360000,
1818        autoDiscover: false,
1819        headers: {
1820            "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), // Pass the CSRF token as a header
1821        },
1822        addRemoveLinks: true,
1823        dictRemoveFile: "x",
1824        dictResponseError: "Error",
1825        uploadMultiple: true,
1826        dictDefaultMessage:
1827            '<p><input type="button" value="Select" class="btn btn-primary" /><br> or <br> Drag & Drop Files Here</p>',
1828    });
1829    mediaDropzone.on("addedfile", function (file) {
1830        var i = 0;
1831        if (this.files.length) {
1832            var _i, _len;
1833            for (_i = 0, _len = this.files.length; _i < _len - 1; _i++) {
1834                if (
1835                    this.files[_i].name === file.name &&
1836                    this.files[_i].size === file.size &&
1837                    this.files[_i].lastModifiedDate.toString() ===
1838                    file.lastModifiedDate.toString()
1839                ) {
1840                    this.removeFile(file);
1841                    i++;
1842                }
1843            }
1844        }
1845    });
1846    mediaDropzone.on("error", function (file, response) {
1847        return;
1848    });
1849    mediaDropzone.on("sending", function (file, xhr, formData) {
1850        var id = $("#media_type_id").val();
1851        formData.append("flash_message", 1);
1852        formData.append("id", id);
1853        xhr.onreadystatechange = function (response) {
1854            setTimeout(function () {
1855                location.reload();
1856            }, 2000);
1857        };
1858    });
1859    $("#upload_media_btn").on("click", function (e) {
1860        e.preventDefault();
1861        if (mediaDropzone.getQueuedFiles().length > 0) {
1862            if (is_error == false) {
1863                $("#upload_media_btn")
1864                    .attr("disabled", true)
1865                    .text(label_please_wait);
1866                mediaDropzone.processQueue();
1867                return;
1868            }
1869        } else {
1870            toastr.error("No file(s) chosen.");
1871        }
1872    });
1873}
1874// Row-wise Select/Deselect All
1875$(".row-permission-checkbox").change(function () {
1876    var module = $(this).data("module");
1877    var isChecked = $(this).prop("checked");
1878    $(`.permission-checkbox[data-module="${module}"]`).prop(
1879        "checked",
1880        isChecked
1881    );
1882});
1883$("#selectAllColumnPermissions").change(function () {
1884    var isChecked = $(this).prop("checked");
1885    $(".permission-checkbox").prop("checked", isChecked);
1886    if (isChecked) {
1887        $(".row-permission-checkbox").prop("checked", true).trigger("change"); // Check all row permissions when select all is checked
1888    } else {
1889        $(".row-permission-checkbox").prop("checked", false).trigger("change"); // Uncheck all row permissions when select all is unchecked
1890    }
1891    checkAllPermissions(); // Check all permissions
1892});
1893// Select/Deselect All for Rows
1894$("#selectAllPermissions").change(function () {
1895    var isChecked = $(this).prop("checked");
1896    $(".row-permission-checkbox").prop("checked", isChecked).trigger("change");
1897});
1898// Function to check/uncheck all permissions for a module
1899function checkModulePermissions(module) {
1900    var allChecked = true;
1901    $('.permission-checkbox[data-module="' + module + '"]').each(function () {
1902        if (!$(this).prop("checked")) {
1903            allChecked = false;
1904        }
1905    });
1906    $("#selectRow" + module).prop("checked", allChecked);
1907}
1908// Function to check if all permissions are checked and select/deselect "Select all" checkbox
1909function checkAllPermissions() {
1910    var allPermissionsChecked = true;
1911    $(".permission-checkbox").each(function () {
1912        if (!$(this).prop("checked")) {
1913            allPermissionsChecked = false;
1914        }
1915    });
1916    $("#selectAllColumnPermissions").prop("checked", allPermissionsChecked);
1917}
1918// Event handler for individual permission checkboxes
1919$(".permission-checkbox").on("change", function () {
1920    var module = $(this).data("module");
1921    checkModulePermissions(module);
1922    checkAllPermissions();
1923});
1924// Event handler for "Select all" checkbox
1925$("#selectAllColumnPermissions").on("change", function () {
1926    var isChecked = $(this).prop("checked");
1927    $(".permission-checkbox").prop("checked", isChecked);
1928});
1929// Initial check for permissions on page load
1930$(".row-permission-checkbox").each(function () {
1931    var module = $(this).data("module");
1932    checkModulePermissions(module);
1933});
1934checkAllPermissions();
1935$(document).ready(function () {
1936    $(".fixed-table-toolbar").each(function () {
1937        var $toolbar = $(this);
1938        var $data_type = $toolbar
1939            .closest(".table-responsive")
1940            .find("#data_type");
1941        var $data_table = $toolbar
1942            .closest(".table-responsive")
1943            .find("#data_table");
1944        var $save_column_visibility = $toolbar
1945            .closest(".table-responsive")
1946            .find("#save_column_visibility");
1947        if ($data_type.length > 0) {
1948            var data_type = $data_type.val();
1949            var data_table = $data_table.val() || "table";
1950            // Create the "Delete selected" button
1951            if (window.location.href.includes("scheduler-statuses")) {
1952                var $deleteButton = '';
1953            } else {
1954                var $deleteButton = $(
1955                    '<div class="columns columns-left btn-group float-left action_delete_' +
1956                    data_type.replace("-", "_") +
1957                    '">' +
1958                    '<button type="button" class="btn btn-outline-danger float-left delete-selected" data-type="' +
1959                    data_type +
1960                    '" data-table="' +
1961                    data_table +
1962                    '">' +
1963                    '<i class="bx bx-trash"></i> ' +
1964                    label_delete_selected +
1965                    "</button>" +
1966                    "</div>"
1967                );
1968            }
1969            // Add the "Delete selected" button before the first element in the toolbar
1970            $toolbar.prepend($deleteButton);
1971            if (data_type == "tasks") {
1972                // Create the "Clear Filters" button
1973                var $clearFiltersButton = $(
1974                    '<div class="columns columns-left btn-group float-left">' +
1975                    '<button type="button" class="btn btn-outline-secondary clear-filters">' +
1976                    '<i class="bx bx-x-circle"></i> ' +
1977                    label_clear_filters +
1978                    "</button>" +
1979                    "</div>"
1980                );
1981                $deleteButton.after($clearFiltersButton);
1982            }
1983            if ($save_column_visibility.length > 0) {
1984                var $savePreferencesButton = $(
1985                    '<div class="columns columns-left btn-group float-left">' +
1986                    '<button type="button" class="btn btn-outline-primary save-column-visibility" data-type="' +
1987                    data_type +
1988                    '" data-table="' +
1989                    data_table +
1990                    '">' +
1991                    '<i class="bx bx-save"></i> ' +
1992                    label_save_column_visibility +
1993                    "</button>" +
1994                    "</div>"
1995                );
1996                $deleteButton.after($savePreferencesButton);
1997            }
1998        }
1999    });
2000});
2001$("#media_storage_type").on("change", function (e) {
2002    if ($("#media_storage_type").val() == "s3") {
2003        $(".aws-s3-fields").removeClass("d-none");
2004    } else {
2005        $(".aws-s3-fields").addClass("d-none");
2006    }
2007});
2008$(document).on("click", ".edit-milestone", function () {
2009    var id = $(this).data("id");
2010    var urlPrefix = window.location.pathname.split("/")[1];
2011    $.ajax({
2012        url: "/" + urlPrefix + "/projects/get-milestone/" + id,
2013        type: "get",
2014        headers: {
2015            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2016        },
2017        dataType: "json",
2018        success: function (response) {
2019            var formattedStartDate = moment(response.ms.start_date).format(
2020                js_date_format
2021            );
2022            var formattedEndDate = moment(response.ms.end_date).format(
2023                js_date_format
2024            );
2025            $("#milestone_id").val(response.ms.id);
2026            $("#milestone_title").val(response.ms.title);
2027            $("#update_milestone_start_date").val(formattedStartDate);
2028            $("#update_milestone_end_date").val(formattedEndDate);
2029            $("#milestone_status").val(response.ms.status);
2030            $("#milestone_cost").val(response.ms.cost);
2031            $("#milestone_description").val(response.ms.description);
2032            $("#milestone_progress").val(response.ms.progress);
2033            $(".milestone-progress").text(response.ms.progress + "%");
2034        },
2035    });
2036});
2037// subscriptions start and end date
2038$(document).ready(function () {
2039    if (
2040        window.location.href.includes("transactions") ||
2041        window.location.href.includes("plans") ||
2042        window.location.href.includes("customers")
2043    ) {
2044        var deleteBtn = $(".delete-selected");
2045        // Hide the delete button
2046        deleteBtn.addClass("d-none");
2047    }
2048});
2049$(document).on("click", ".edit-expense-type", function () {
2050    var id = $(this).data("id");
2051    $("#edit_expense_type_modal").modal("show");
2052    var urlPrefix = window.location.pathname.split("/")[1];
2053    $.ajax({
2054        url: "/" + urlPrefix + "/expenses/get-expense-type/" + id,
2055        type: "get",
2056        headers: {
2057            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2058        },
2059        dataType: "json",
2060        success: function (response) {
2061            $("#update_expense_type_id").val(response.et.id);
2062            $("#expense_type_title").val(response.et.title);
2063            $("#expense_type_description").val(response.et.description);
2064        },
2065    });
2066});
2067$(document).on("click", ".edit-expense", function () {
2068    var id = $(this).data("id");
2069    $("#edit_expense_modal").modal("show");
2070    var urlPrefix = window.location.pathname.split("/")[1];
2071    $.ajax({
2072        url: "/" + urlPrefix + "/expenses/get/" + id,
2073        type: "get",
2074        headers: {
2075            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2076        },
2077        dataType: "json",
2078        success: function (response) {
2079            var formattedExpDate = moment(response.exp.expense_date).format(
2080                js_date_format
2081            );
2082            var amount = parseFloat(response.exp.amount);
2083            $("#update_expense_id").val(response.exp.id);
2084            $("#expense_title").val(response.exp.title);
2085            $("#expense_type_id").val(response.exp.expense_type_id);
2086            $("#expense_user_id").val(response.exp.user_id);
2087            $("#expense_amount").val(amount.toFixed(decimal_points));
2088            $("#update_expense_date").val(formattedExpDate);
2089            $("#expense_note").val(response.exp.note);
2090        },
2091    });
2092});
2093$(document).on("click", ".edit-payment", function () {
2094    var id = $(this).data("id");
2095    $("#edit_payment_modal").modal("show");
2096    var urlPrefix = window.location.pathname.split("/")[1];
2097    $.ajax({
2098        url: "/" + urlPrefix + "/payments/get/" + id,
2099        type: "get",
2100        headers: {
2101            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2102        },
2103        dataType: "json",
2104        success: function (response) {
2105            var formattedExpDate = moment(response.payment.payment_date).format(
2106                js_date_format
2107            );
2108            var amount = parseFloat(response.payment.amount);
2109            $("#update_payment_id").val(response.payment.id);
2110            $("#payment_invoice_id").val(response.payment.invoice_id);
2111            $("#payment_amount").val(amount.toFixed(decimal_points));
2112            $("#update_payment_date").val(formattedExpDate);
2113            $("#payment_note").val(response.payment.note);
2114            var userId = response.payment.user.id;
2115            var userName =
2116                response.payment.user.first_name +
2117                " " +
2118                response.payment.user.last_name;
2119            if (
2120                $("#payment_user_id").find("option[value='" + userId + "']")
2121                    .length
2122            ) {
2123                $("#payment_user_id").val(userId).trigger("change");
2124            } else {
2125                var newOption = new Option(userName, userId, true, true);
2126                $("#payment_user_id").append(newOption).trigger("change");
2127            }
2128            var pm_id = response.payment.payment_method.id;
2129            var pm_title = response.payment.payment_method.title;
2130            if (
2131                $("#payment_pm_id").find("option[value='" + pm_id + "']").length
2132            ) {
2133                $("#payment_pm_id").val(pm_id).trigger("change");
2134            } else {
2135                var newOption = new Option(pm_title, pm_id, true, true);
2136                $("#payment_pm_id").append(newOption).trigger("change");
2137            }
2138        },
2139    });
2140});
2141function initializeDateRangePicker(inputSelector) {
2142    var modalId = $(inputSelector).closest(".modal").attr("id");
2143    $(inputSelector).daterangepicker({
2144        alwaysShowCalendars: true,
2145        showCustomRangeLabel: true,
2146        minDate: moment($(inputSelector).val(), js_date_format),
2147        singleDatePicker: true,
2148        showDropdowns: true,
2149        autoUpdateInput: true,
2150        parentEl: "#" + modalId,
2151        locale: {
2152            cancelLabel: "Clear",
2153            format: js_date_format,
2154        },
2155    });
2156}
2157$(document).ready(function () {
2158    $("#togglePassword").on("click", function () {
2159        var passwordInput = $("#password");
2160        var toggleButton = $(this);
2161        // Toggle password visibility
2162        if (passwordInput.attr("type") === "password") {
2163            passwordInput.attr("type", "text");
2164            toggleButton.html('<i class="far fa-eye"></i>');
2165        } else {
2166            passwordInput.attr("type", "password");
2167            toggleButton.html('<i class="far fa-eye-slash"></i>');
2168        }
2169    });
2170});
2171$(document).on("click", ".superadmin-login", function (e) {
2172    e.preventDefault();
2173    $("#email").val("[email protected]");
2174    $("#password").val("12345678");
2175});
2176$(document).on("click", ".admin-login", function (e) {
2177    e.preventDefault();
2178    $("#email").val("[email protected]");
2179    $("#password").val("12345678");
2180});
2181$(document).on("click", ".member-login", function (e) {
2182    e.preventDefault();
2183    $("#email").val("[email protected]");
2184    $("#password").val("12345678");
2185});
2186$(document).on("click", ".client-login", function (e) {
2187    e.preventDefault();
2188    $("#email").val("[email protected]");
2189    $("#password").val("12345678");
2190});
2191$("#show_password").on("click", function () {
2192    var eyeicon = $(this).find("i");
2193    let password = document.getElementById("password");
2194    if (password.type == "password") {
2195        password.type = "text";
2196        eyeicon.removeClass("bx-hide");
2197        eyeicon.addClass("bx-show");
2198    } else {
2199        password.type = "password";
2200        eyeicon.removeClass("bx-show");
2201        eyeicon.addClass("bx-hide");
2202    }
2203});
2204$("#show_confirm_password").on("click", function () {
2205    var eyeicon = $(this).find("i");
2206    let confirm_password = document.getElementById("password_confirmation");
2207    if (confirm_password.type == "password") {
2208        confirm_password.type = "text";
2209        eyeicon.removeClass("bx-hide");
2210        eyeicon.addClass("bx-show");
2211    } else {
2212        confirm_password.type = "password";
2213        eyeicon.removeClass("bx-show");
2214        eyeicon.addClass("bx-hide");
2215    }
2216});
2217$(".min_0").on("change", function () {
2218    var amount = $(this).val();
2219    if (amount < 0) {
2220        $(this).val("");
2221        toastr.error(label_min_0);
2222    } else {
2223        // Clear error message if the value is valid
2224    }
2225});
2226$(".max_100").on("change", function () {
2227    var percentage = $(this).val();
2228    if (percentage > 100) {
2229        toastr.error(lable_max_100);
2230    } else {
2231        // Clear error message if the value is valid
2232    }
2233});
2234function clearModalContents($modal) {
2235    // Clear all input fields
2236    $modal.find('input:not([type="hidden"])').each(function () {
2237        if (
2238            $(this).attr("type") === "checkbox" ||
2239            $(this).attr("type") === "radio"
2240        ) {
2241            $(this).prop("checked", false);
2242        } else {
2243            $(this).val("");
2244        }
2245    });
2246    // Clear all textarea fields
2247    $modal.find("textarea").val("");
2248    // Reset all select elements
2249    $modal.find("select").prop("selectedIndex", 0);
2250    // Clear any error messages or validation states
2251    $modal
2252        .find(".error-message")
2253        .removeClass("text-danger")
2254        .closest("p")
2255        .text("");
2256    // Reset Select2 elements
2257    $modal.find("select").each(function () {
2258        if ($(this).data("select2")) {
2259            $(this).val(null).trigger("change");
2260        }
2261    });
2262    // Reset the form inside the modal
2263    $modal.find("form").trigger("reset");
2264}
2265// Usage for all modals
2266$(document).on("hidden.bs.modal", ".modal", function () {
2267    // var $modal = $(this);
2268    // if ($modal.attr('id') !== 'timerModal') {
2269    //     clearModalContents($modal);
2270    // }
2271    var modalId = $(this).attr("id");
2272    var $form = $(this).find("form"); // Find the form inside the modal
2273    $form.trigger("reset"); // Reset the form
2274    $form.find(".error-message").html("");
2275    var partialLeaveCheckbox = $("#partialLeave");
2276    if (partialLeaveCheckbox.length) {
2277        partialLeaveCheckbox.trigger("change");
2278    }
2279    var leaveVisibleToAllCheckbox = $form.find(".leaveVisibleToAll");
2280    if (leaveVisibleToAllCheckbox.length) {
2281        leaveVisibleToAllCheckbox.trigger("change");
2282    }
2283    var defaultColor =
2284        modalId == "create_note_modal" || modalId == "edit_note_modal"
2285            ? "success"
2286            : "primary";
2287    var colorSelect = $form.find('select[name="color"]');
2288    if (colorSelect.length) {
2289        var classes = colorSelect.attr("class").split(" ");
2290        var currentColorClass = classes.filter(function (className) {
2291            return className.startsWith("select-");
2292        })[0];
2293    }
2294    colorSelect
2295        .removeClass(currentColorClass)
2296        .addClass("select-bg-label-" + defaultColor);
2297    $form.find(".js-example-basic-multiple").trigger("change");
2298    if ($('.selectTaskProject[name="project"]').length) {
2299        $form.find($('.selectTaskProject[name="project"]')).trigger("change");
2300    }
2301    if ($('.selectLruser[name="user_id"]').length) {
2302        $form.find($('.selectLruser[name="user_id"]')).trigger("change");
2303    }
2304    if ($("#users_associated_with_project").length) {
2305        $("#users_associated_with_project").text("");
2306    }
2307    if ($("#task_update_users_associated_with_project").length) {
2308        $("#task_update_users_associated_with_project").text("");
2309    }
2310    $form.find("#reminder-settings").addClass("d-none");
2311    $form.find("#edit-reminder-settings").addClass("d-none");
2312    $form.find("#reminder-settings").find("input").prop("checked", false);
2313    $form.find("#edit-reminder-settings").find("input").prop("checked", false);
2314    $form.find("#recurring-task-settings").addClass("d-none");
2315    $form.find("#edit-recurring-task-settings").addClass("d-none");
2316    $form.find("#recurring-task-settings").find("input").prop("checked", false);
2317    $form.find("#edit-recurring-task-settings").find("input").prop("checked", false);
2318    resetDateFields($form);
2319});
2320$(document).on("click", "#mark-all-notifications-as-read", function (e) {
2321    e.preventDefault();
2322    $("#mark_all_notifications_as_read_modal").modal("show"); // show the confirmation modal
2323    $("#mark_all_notifications_as_read_modal").on(
2324        "click",
2325        "#confirmMarkAllAsRead",
2326        function () {
2327            $("#confirmMarkAllAsRead")
2328                .html(label_please_wait)
2329                .attr("disabled", true);
2330            $.ajax({
2331                url: "/master-panel/notifications/mark-all-as-read",
2332                type: "PUT",
2333                headers: {
2334                    "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2335                },
2336                success: function (response) {
2337                    location.reload();
2338                    // $('#confirmMarkAllAsRead').html(label_yes).attr('disabled', false);
2339                },
2340            });
2341        }
2342    );
2343});
2344
2345$(document).on("click", ".notification-open-popup", function (e) {
2346    e.preventDefault();
2347    var $this = $(this);
2348    var title = $this.data('title');
2349    var message = $this.data('message');
2350    var date = $this.data('date');
2351    var url = $this.data('url');
2352
2353    $('#notificationModalTitle').html(title);
2354    $('#notificationModalMessage').text(message);
2355    $('#notificationModalDate').text(date);
2356    $('#notificationModalLink').attr('href', url);
2357
2358    $('#notificationDetailModal').modal('show');
2359
2360    // if ($('#table').length) {
2361    //     $('#table').bootstrapTable('refresh');
2362    // }
2363
2364    var notificationId = $this.data("id");
2365    var needConfirm = $this.data("needconfirm") || false;
2366    performUpdate(notificationId, needConfirm, $this);
2367});
2368
2369$(document).on("click", ".update-notification-status", function (e) {
2370    var $this = $(this);
2371
2372    if ($this.hasClass('dropdown-item')) {
2373        e.preventDefault();
2374        var title = $this.data('title');
2375        var message = $this.data('message');
2376        var date = $this.data('date');
2377        var url = $this.data('url');
2378
2379        $('#notificationModalTitle').text(title);
2380        $('#notificationModalMessage').text(message);
2381        $('#notificationModalDate').text(date);
2382        $('#notificationModalLink').attr('href', url);
2383
2384        $('#notificationDetailModal').modal('show');
2385        // if ($('#table').length) {
2386        //     $('#table').bootstrapTable('refresh');
2387        // }
2388    }
2389
2390    var notificationId = $this.data("id");
2391    var needConfirm = true;
2392
2393    /*if (needConfirm) {
2394        // Show the confirmation modal
2395        $("#update_notification_status_modal").modal("show");
2396        // Attach click event handler to the confirmation button
2397        $("#update_notification_status_modal").off(
2398            "click",
2399            "#confirmNotificationStatus"
2400        );
2401        $("#update_notification_status_modal").on(
2402            "click",
2403            "#confirmNotificationStatus",
2404            function () {
2405                $("#confirmNotificationStatus")
2406                    .html(label_please_wait)
2407                    .attr("disabled", true);
2408                performUpdate(notificationId, needConfirm, $this);
2409            }
2410        );
2411    } else {*/
2412    // If confirmation is not needed, directly perform the update and handle response
2413    performUpdate(notificationId, needConfirm, $this);
2414    //}
2415});
2416function performUpdate(notificationId, needConfirm = "", $element = null) {
2417    $.ajax({
2418        url: "/master-panel/notifications/update-status",
2419        type: "PUT",
2420        data: { id: notificationId, needConfirm: needConfirm },
2421        headers: {
2422            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2423        },
2424        success: function (response) {
2425            if (response.error == false && response.unread_count !== undefined) {
2426                let countElem = $('#unreadNotificationsCount');
2427                countElem.text(response.unread_count);
2428                if (response.unread_count > 0) {
2429                    countElem.removeClass('d-none');
2430                } else {
2431                    countElem.addClass('d-none');
2432                }
2433            }
2434
2435            if (needConfirm) {
2436                $("#confirmNotificationStatus")
2437                    .html(label_yes)
2438                    .attr("disabled", false);
2439                if (response.error == false) {
2440                    toastr.success(response.message);
2441                    $("#table").bootstrapTable("refresh");
2442                } else {
2443                    toastr.error(response.message);
2444                }
2445                $("#update_notification_status_modal").modal("hide");
2446            } else {
2447                if (response.error == false) {
2448                    if ($element && $element.hasClass('dropdown-item')) {
2449                        $element.removeClass('update-notification-status');
2450                    }
2451                    if ($('#table').length) {
2452                        $('#table').bootstrapTable('refresh');
2453                    }
2454                }
2455            }
2456        },
2457    });
2458}
2459
2460$(
2461    "textarea#email_verify_email,textarea#email_account_creation,textarea#email_forgot_password,textarea#email_project_assignment,textarea#email_task_assignment,textarea#email_workspace_assignment,textarea#email_meeting_assignment,textarea#email_leave_request_creation,textarea#email_leave_request_status_updation,textarea#email_project_status_updation,textarea#email_task_status_updation,textarea#email_team_member_on_leave_alert,textarea#email_project_issue_assignment,textarea#email_announcement,textarea#email_task_reminder,textarea#email_recurring_task"
2462).tinymce({
2463    height: 821,
2464    menubar: true,
2465    plugins: [
2466        "link",
2467        "a11ychecker",
2468        "advlist",
2469        "advcode",
2470        "advtable",
2471        "autolink",
2472        "checklist",
2473        "export",
2474        "lists",
2475        "link",
2476        "image",
2477        "charmap",
2478        "preview",
2479        "anchor",
2480        "searchreplace",
2481        "visualblocks",
2482        "powerpaste",
2483        "fullscreen",
2484        "formatpainter",
2485        "insertdatetime",
2486        "media",
2487        "table",
2488        "help",
2489        "wordcount",
2490        "emoticons",
2491        "code",
2492    ],
2493    toolbar: false,
2494    // toolbar: 'link | undo redo | a11ycheck casechange blocks | bold italic backcolor | alignleft aligncenter alignright al
2494ignjustify | bullist numlist checklist outdent indent | removeformat | code blockquote emoticons table help'
2495});
2496// Handle click event on toolbar items
2497$(".tox-tbtn").click(function () {
2498    // Get the current editor instance
2499    var editor = tinyMCE.activeEditor;
2500    // Close any open toolbar dropdowns
2501    tinymce.ui.Factory.each(function (ctrl) {
2502        if (ctrl.type === "toolbarbutton" && ctrl.settings.toolbar) {
2503            if (ctrl !== this && ctrl.settings.toolbar === "toolbox") {
2504                ctrl.panel.hide();
2505            }
2506        }
2507    }, editor);
2508    // Execute the action associated with the clicked toolbar item
2509    editor.execCommand("mceInsertContent", false, "Clicked!");
2510});
2511$(document).on("click", ".restore-default", function (e) {
2512    e.preventDefault();
2513    var form = $(this).closest("form");
2514    var type = form.find('input[name="type"]').val();
2515    var name = form.find('input[name="name"]').val();
2516    var textarea = type + "_" + name;
2517    $("#restore_default_modal").modal("show"); // show the confirmation modal
2518    $("#restore_default_modal").off("click", "#confirmRestoreDefault");
2519    $("#restore_default_modal").on(
2520        "click",
2521        "#confirmRestoreDefault",
2522        function () {
2523            $("#confirmRestoreDefault")
2524                .html(label_please_wait)
2525                .attr("disabled", true);
2526            $.ajax({
2527                url: "/superadmin/settings/get-default-template",
2528                type: "POST",
2529                data: { type: type, name: name },
2530                headers: {
2531                    "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2532                },
2533                dataType: "json",
2534                success: function (response) {
2535                    $("#confirmRestoreDefault")
2536                        .html(label_yes)
2537                        .attr("disabled", false);
2538                    $("#restore_default_modal").modal("hide");
2539                    if (response.error == false) {
2540                        tinymce.get(textarea).setContent(response.content);
2541                        toastr.success(response.message);
2542                    } else {
2543                        toastr.error(response.message);
2544                    }
2545                },
2546            });
2547        }
2548    );
2549});
2550$(document).on("click", ".sms-restore-default", function (e) {
2551    e.preventDefault();
2552    var form = $(this).closest("form");
2553    var type = form.find('input[name="type"]').val();
2554    var name = form.find('input[name="name"]').val();
2555    var textarea = type + "_" + name;
2556    $("#restore_default_modal").modal("show"); // show the confirmation modal
2557    $("#restore_default_modal").off("click", "#confirmRestoreDefault");
2558    $("#restore_default_modal").on(
2559        "click",
2560        "#confirmRestoreDefault",
2561        function () {
2562            $("#confirmRestoreDefault")
2563                .html(label_please_wait)
2564                .attr("disabled", true);
2565            $.ajax({
2566                url: "/superadmin/settings/get-default-template",
2567                type: "POST",
2568                data: { type: type, name: name },
2569                headers: {
2570                    "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2571                },
2572                dataType: "json",
2573                success: function (response) {
2574                    $("#confirmRestoreDefault")
2575                        .html(label_yes)
2576                        .attr("disabled", false);
2577                    $("#restore_default_modal").modal("hide");
2578                    if (response.error == false) {
2579                        $("#" + textarea).val(response.content);
2580                        toastr.success(response.message);
2581                    } else {
2582                        toastr.error(response.message);
2583                    }
2584                },
2585            });
2586        }
2587    );
2588});
2589$(document).on("click", ".edit-language", function () {
2590    var id = $(this).data("id");
2591    $("#edit_language_modal").modal("show");
2592    $.ajax({
2593        url: "/superadmin/settings/languages/get/" + id,
2594        type: "get",
2595        headers: {
2596            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2597        },
2598        dataType: "json",
2599        success: function (response) {
2600            $("#language_id").val(response.language.id);
2601            $("#language_title").val(response.language.name);
2602        },
2603    });
2604});
2605$(document).on("click", ".edit-priority", function () {
2606    var id = $(this).data("id");
2607    $("#edit_priority_modal").modal("show");
2608    var classes = $("#priority_color").attr("class").split(" ");
2609    var currentColorClass = classes.filter(function (className) {
2610        return className.startsWith("select-");
2611    })[0];
2612    $.ajax({
2613        url: "/master-panel/priority/get/" + id,
2614        type: "get",
2615        headers: {
2616            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
2617        },
2618        dataType: "json",
2619        success: function (response) {
2620            $("#priority_id").val(response.priority.id);
2621            $("#priority_title").val(response.priority.title);
2622            $("#priority_color")
2623                .val(response.priority.color)
2624                .removeClass(currentColorClass)
2625                .addClass("select-bg-label-" + response.priority.color);
2626        },
2627    });
2628});
2629$(document).on("click", ".openCreateStatusModal", function (e) {
2630    e.preventDefault();
2631    $("#create_status_modal").modal("show");
2632});
2633$(document).on("click", ".openCreatePriorityModal", function (e) {
2634    e.preventDefault();
2635    $("#create_priority_modal").modal("show");
2636});
2637$(document).on("click", ".openCreateTagModal", function (e) {
2638    e.preventDefault();
2639    $("#create_tag_modal").modal("show");
2640});
2641$(document).ready(function () {
2642    function formatTag(tag) {
2643        if (!tag.id) {
2644            return tag.text;
2645        }
2646        var color = $(tag.element).data("color");
2647        var $tag = $(
2648            '<span class="badge bg-label-' + color + '">' + tag.text + "</span>"
2649        );
2650        return $tag;
2651    }
2652    function formatStatus(status) {
2653        if (!status.id) {
2654            return status.text;
2655        }
2656        var color = $(status.element).data("color");
2657        var $status = $(
2658            '<span class="badge bg-label-' +
2659            color +
2660            '">' +
2661            status.text +
2662            "</span>"
2663        );
2664        return $status;
2665    }
2666    function formatPriority(priority) {
2667        if (!priority.id) {
2668            return priority.text;
2669        }
2670        var color = $(priority.element).data("color");
2671        var $priority = $(
2672            '<span class="badge bg-label-' +
2673            color +
2674            '">' +
2675            priority.text +
2676            "</span>"
2677        );
2678        return $priority;
2679    }
2680    if ($(".tagsDropdown").length) {
2681        $(".tagsDropdown").select2({
2682            templateResult: formatTag,
2683            templateSelection: formatTag,
2684            escapeMarkup: function (markup) {
2685                return markup;
2686            },
2687        });
2688    }
2689    $(".statusDropdown").each(function () {
2690        var $this = $(this);
2691        $this.select2({
2692            dropdownParent: $this.closest(".modal"),
2693            templateResult: formatStatus,
2694            templateSelection: formatStatus,
2695            escapeMarkup: function (markup) {
2696                return markup;
2697            },
2698        });
2699    });
2700    $(".priorityDropdown").each(function () {
2701        var $this = $(this);
2702        $this.select2({
2703            dropdownParent: $this.closest(".modal"),
2704            templateResult: formatPriority,
2705            templateSelection: formatPriority,
2706            allowClear: true,
2707            escapeMarkup: function (markup) {
2708                return markup;
2709            },
2710            language: {
2711                noResults: function () {
2712                    return label_no_results_found;
2713                },
2714                searching: function () {
2715                    return label_searching;
2716                },
2717            },
2718        });
2719        // Prevent dropdown from opening when clear button is clicked
2720        $this
2721            .on("select2:unselecting", function (e) {
2722                $(this).data("state", "unselecting");
2723            })
2724            .on("select2:open", function (e) {
2725                if ($(this).data("state") === "unselecting") {
2726                    $(this).removeData("state");
2727                    $this.select2("close"); // Close the dropdown immediately
2728                }
2729            });
2730    });
2731    $(".selectTaskProject").each(function () {
2732        var $this = $(this);
2733        $this.select2({
2734            dropdownParent: $this.closest(".modal"),
2735        });
2736    });
2737});
2738$(document).on("click", ".edit-project", function () {
2739    var id = $(this).data("id");
2740    $("#edit_project_modal").modal("show");
2741    $.ajax({
2742        url: "/master-panel/projects/get/" + id,
2743        type: "get",
2744        headers: {
2745            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2746        },
2747        dataType: "json",
2748        success: function (response) {
2749            var formattedStartDate = moment(response.project.start_date).format(
2750                js_date_format
2751            );
2752            var formattedEndDate = moment(response.project.end_date).format(
2753                js_date_format
2754            );
2755            var $modal = $("#edit_project_modal"); // Cache the modal element for better performance
2756            $("#project_id").val(response.project.id);
2757            $("#project_title").val(response.project.title);
2758            $modal
2759                .find("#project_status_id")
2760                .val(response.project.status_id)
2761                .trigger("change");
2762            $modal
2763                .find("#project_priority_id")
2764                .val(response.project.priority_id)
2765                .trigger("change");
2766            $("#project_budget").val(response.project.budget);
2767            $("#update_start_date").val(formattedStartDate);
2768            $("#update_end_date").val(formattedEndDate);
2769            initializeDateRangePicker("#update_start_date, #update_end_date");
2770            $("#task_accessiblity").val(response.project.task_accessiblity);
2771            $("#edit_tasks_time_entries").prop(
2772                "checked",
2773                Boolean(response.project.enable_tasks_time_entries)
2774            );
2775            $("#project_description").val(response.project.description);
2776            $("#projectNote").val(response.project.note);
2777            // Populate project users in the multi-select dropdown
2778            var usersSelect = $("#edit_project_modal").find(
2779                '.js-example-basic-multiple[name="user_id[]"]'
2780            );
2781            // Preselect project users if they exist
2782            var projectUsers = response.users.map((user) => user.id);
2783            usersSelect.val(projectUsers);
2784            usersSelect.trigger("change"); // Trigger change event to update select2
2785            var clientsSelect = $("#edit_project_modal").find(
2786                '.js-example-basic-multiple[name="client_id[]"]'
2787            );
2788            var projectClients = response.clients.map((client) => client.id);
2789            clientsSelect.val(projectClients);
2790            clientsSelect.trigger("change"); // Trigger change event to update select2
2791            var tagsSelect = $("#edit_project_modal").find(
2792                '[name="tag_ids[]"]'
2793            );
2794            var projectTags = response.tags.map((tag) => tag.id);
2795            // Select old tags
2796            tagsSelect.val(projectTags);
2797            // Trigger change event to update Select2
2798            tagsSelect.trigger("change.select2");
2799        },
2800        error: function (xhr, status, error) {
2801            console.error(error);
2802        },
2803    });
2804});
2805$(document).on("click", "#set-default-view", function (e) {
2806    e.preventDefault();
2807    var type = $(this).data("type");
2808    var view = $(this).data("view");
2809    var url = "/master-panel/save-" + type + "-view-preference";
2810    $("#set_default_view_modal").modal("show");
2811    $("#set_default_view_modal").off("click", "#confirm");
2812    $("#set_default_view_modal").on("click", "#confirm", function () {
2813        $("#set_default_view_modal")
2814            .find("#confirm")
2815            .html(label_please_wait)
2816            .attr("disabled", true);
2817        $.ajax({
2818            url: url,
2819            type: "PUT",
2820            headers: {
2821                "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2822            },
2823            data: {
2824                type: type,
2825                view: view,
2826            },
2827            success: function (response) {
2828                $("#set_default_view_modal")
2829                    .find("#confirm")
2830                    .html(label_yes)
2831                    .attr("disabled", false);
2832                if (response.error == false) {
2833                    $("#set-default-view")
2834                        .text(label_default_view)
2835                        .removeClass("bg-secondary")
2836                        .addClass("bg-primary");
2837                    $("#set_default_view_modal").modal("hide");
2838                    toastr.success(response.message);
2839                } else {
2840                    toastr.error(response.message);
2841                }
2842            },
2843        });
2844    });
2845});
2846//task project select
2847$(document).ready(function () {
2848    $('.selectTaskProject[name="project"]').on("change", function (e) {
2849        var projectId = $(this).val();
2850        if (projectId) {
2851            $.ajax({
2852                url: "/master-panel/projects/get/" + projectId,
2853                type: "GET",
2854                success: function (response) {
2855                    $("#users_associated_with_project").html(
2856                        "(" +
2857                        label_users_associated_with_project +
2858                        " <strong>" +
2859                        response.project.title +
2860                        "</strong>)"
2861                    );
2862                    var usersSelect = $(
2863                        '.js-example-basic-multiple[name="users_id[]"]'
2864                    );
2865                    usersSelect.empty(); // Clear existing options
2866                    // Check if task_accessibility is 'project_users'
2867                    $.each(response.users, function (index, user) {
2868                        var option = $("<option>", {
2869                            value: user.id,
2870                            text: user.first_name + " " + user.last_name,
2871                        });
2872                        usersSelect.append(option);
2873                    });
2874                    if (
2875                        response.project.task_accessibility == "project_users"
2876                    ) {
2877                        var taskUsers = response.users.map((user) => user.id);
2878                        usersSelect.val(taskUsers);
2879                    } else {
2880                        usersSelect.val(authUserId);
2881                    }
2882                    usersSelect.trigger("change");
2883
2884                    var taskLists = $('#task_list');
2885                    taskLists.empty(); // Clear existing options
2886                    // Check if task_accessibility is 'project_users'
2887                    $.each(response.task_lists, function (index, taskList) {
2888                        var option = $("<option>", {
2889                            value: taskList.id,
2890                            text: taskList.name,
2891                        });
2892                        taskLists.append(option);
2893                    });
2894                    if (response.task_lists.length == 0) {
2895                        var option = $("<option>", {
2896                            value: '',
2897                            text: label_no_task_list,
2898                        });
2899                        taskLists.append(option);
2900                    }
2901
2902
2903                },
2904                error: function (xhr, status, error) {
2905                    console.error(error);
2906                },
2907            });
2908        }
2909    });
2910});
2911$(document).on("click", ".quick-view", function (e) {
2912    e.preventDefault();
2913    var id = $(this).data("id");
2914    var type = $(this).data("type") || "task";
2915    $("#type").val(type);
2916    $("#typeId").val(id);
2917    $.ajax({
2918        url: "/master-panel/" + type + "s/get/" + id,
2919        type: "GET",
2920        success: function (response) {
2921            if (response.error == false) {
2922                $("#quickViewModal").modal("show");
2923                if (type == "task" && response.task) {
2924                    $("#quickViewTitlePlaceholder").text(response.task.title);
2925                    $("#quickViewDescPlaceholder").html(
2926                        response.task.description
2927                    );
2928                } else if (type == "project" && response.project) {
2929                    $("#quickViewTitlePlaceholder").text(
2930                        response.project.title
2931                    );
2932                    $("#quickViewDescPlaceholder").html(
2933                        response.project.description
2934                    );
2935                }
2936                $("#typePlaceholder").text(
2937                    type == "task" ? label_task : label_project
2938                );
2939                $("#usersTable").bootstrapTable("refresh");
2940                $("#clientsTable").bootstrapTable("refresh");
2941            } else {
2942                toastr.error(response.message);
2943            }
2944        },
2945        error: function (xhr, status, error) {
2946            // Handle error
2947            toastr.error("Something Went Wrong");
2948        },
2949    });
2950});
2951//edit task modal
2952$(document).on("click", ".edit-task", function () {
2953    var id = $(this).data("id");
2954    $("#edit_task_modal").modal("show");
2955    $.ajax({
2956        url: "/master-panel/tasks/get/" + id,
2957        type: "get",
2958        headers: {
2959            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
2960        },
2961        dataType: "json",
2962        success: function (response) {
2963            console.log(response);
2964            var formattedStartDate = moment(response.task.start_date).format(
2965                js_date_format
2966            );
2967            var formattedEndDate = moment(response.task.end_date).format(
2968                js_date_format
2969            );
2970            $("#task_update_users_associated_with_project").html(
2971                "(" +
2972                label_users_associated_with_project +
2973                " <strong>" +
2974                response.project.title +
2975                "</strong>)"
2976            );
2977            $("#id").val(response.task.id);
2978            $("#title").val(response.task.title);
2979            $("#task_status_id").val(response.task.status_id).trigger("change");
2980            $("#priority_id").val(response.task.priority_id).trigger("change");
2981            $("#update_start_date").val(formattedStartDate);
2982            $("#update_end_date").val(formattedEndDate);
2983            initializeDateRangePicker("#update_start_date, #update_end_date");
2984            $("#update_project_title").val(response.project.title);
2985            $("#task_description").val(response.task.description);
2986            $("#taskNote").val(response.task.note);
2987            $("#edit_billing_type")
2988                .val(response.task.billing_type)
2989                .trigger("change");
2990            $("#edit_completion_percentage")
2991                .val(response.task.completion_percentage)
2992                .trigger("change");
2993            // Populate project users in the multi-select dropdown
2994            var usersSelect = $("#edit_task_modal").find(
2995                '.js-example-basic-multiple[name="user_id[]"]'
2996            );
2997            usersSelect.empty(); // Clear existing options
2998            $.each(response.project.users, function (index, user) {
2999                var option = $("<option>", {
3000                    value: user.id,
3001                    text: user.first_name + " " + user.last_name,
3002                });
3003                usersSelect.append(option);
3004            });
3005            // Preselect task users if they exist
3006            var taskUsers = response.task.users.map((user) => user.id);
3007            usersSelect.val(taskUsers);
3008            usersSelect.trigger("change"); // Trigger change event to update select2
3009
3010            // Populate reminders
3011            if (response.task.reminders && response.task.reminders.length > 0) {
3012                const reminder = response.task.reminders[0];
3013                console.log(reminder);
3014
3015                // Set reminder switch
3016                $('#edit-reminder-switch').prop('checked', reminder.is_active === 1);
3017
3018                // Show reminder settings if active
3019                if (reminder.is_active === 1) {
3020                    $('#edit-reminder-settings').removeClass('d-none');
3021                } else {
3022                    $('#edit-reminder-settings').addClass('d-none');
3023                }
3024
3025                // Set frequency type
3026                $('#edit-frequency-type').val(reminder.frequency_type).trigger('change');
3027
3028                // Handle visibility and values for day selectors based on frequency type
3029                switch (reminder.frequency_type) {
3030                    case 'weekly':
3031                        $('#edit-day-of-week-group').removeClass('d-none');
3032                        $('#edit-day-of-month-group').addClass('d-none');
3033                        $('#edit-day-of-week').val(reminder.day_of_week || '');
3034                        break;
3035                    case 'monthly':
3036                        $('#edit-day-of-month-group').removeClass('d-none');
3037                        $('#edit-day-of-week-group').addClass('d-none');
3038                        $('#edit-day-of-month').val(reminder.day_of_month || '');
3039                        break;
3040                    default: // daily
3041                        $('#edit-day-of-week-group').addClass('d-none');
3042                        $('#edit-day-of-month-group').addClass('d-none');
3043                }
3044
3045                // Set time of day
3046                // Convert the time string to correct format for input type="time"
3047                const timeOfDay = reminder.time_of_day.slice(0, 5); // Get HH:mm from HH:mm:ss
3048                $('#edit-time-of-day').val(timeOfDay);
3049            }
3050
3051            // Populate recurring task settings
3052            if (response.task.recurring_task) {
3053                const recurring_task = response.task.recurring_task;
3054
3055
3056       
3056         // Set recurring task switch
3057                $('#edit-recurring-task-switch').prop('checked', recurring_task.is_active === 1);
3058
3059                // Show recurring task settings if active
3060                if (recurring_task.is_active === 1) {
3061                    $('#edit-recurring-task-settings').removeClass('d-none');
3062                } else {
3063                    $('#edit-recurring-task-settings').addClass('d-none');
3064                }
3065
3066                // Set frequency type
3067                $('#edit-recurrence-frequency').val(recurring_task.frequency).trigger('change');
3068
3069                // Handle visibility and values for day selectors based on frequency type
3070                switch (recurring_task.frequency) {
3071                    case 'weekly':
3072                        $('#edit-recurrence-day-of-week-group').removeClass('d-none');
3073                        $('#edit-recurrence-day-of-month-group').addClass('d-none');
3074                        $('#edit-recurrence-day-of-week').val(recurring_task.day_of_week || '');
3075                        break;
3076                    case 'monthly':
3077                        $('#edit-recurrence-day-of-month-group').removeClass('d-none');
3078                        $('#edit-recurrence-day-of-week-group').addClass('d-none');
3079                        $('#edit-recurrence-day-of-month').val(recurring_task.day_of_month || '');
3080                        break;
3081                    case 'yearly':
3082                        $('#edit-recurrence-day-of-month-group').removeClass('d-none');
3083                        $('#edit-recurrence-day-of-week-group').addClass('d-none');
3084                        $('#edit-recurrence-day-of-month').val(recurring_task.day_of_month || '');
3085                        $('#edit-recurrence-month-of-year-group').removeClass('d-none');
3086                        $('#edit-recurrence-month-of-year').val(recurring_task.month_of_year || '');
3087                        break;
3088                    default: // daily
3089                        $('#edit-recurrence-day-of-week-group').addClass('d-none');
3090                        $('#edit-recurrence-day-of-month-group').addClass('d-none');
3091                        $('#edit-recurrence-month-of-year-group').addClass('d-none');
3092                }
3093
3094                // Starts From and Number of Occuerences
3095                $('#edit-recurrence-starts-from').val(recurring_task.starts_from);
3096                $('#edit-recurrence-occurrences').val(recurring_task.number_of_occurrences);
3097            }
3098        },
3099        error: function (xhr, status, error) {
3100            console.error(error);
3101        },
3102    });
3103});
3104// Column Visibility
3105$(document).on("click", ".save-column-visibility", function (e) {
3106    e.preventDefault();
3107    var tableName = $(this).data("table");
3108    var type = $(this).data("type");
3109    type = type.replace(/-/g, "_"); // This replaces all hyphens with underscores
3110    $("#confirmSaveColumnVisibility").modal("show");
3111    $("#confirmSaveColumnVisibility").off("click", "#confirm");
3112    $("#confirmSaveColumnVisibility").on("click", "#confirm", function () {
3113        $("#confirmSaveColumnVisibility")
3114            .find("#confirm")
3115            .html(label_please_wait)
3116            .attr("disabled", true);
3117        var visibleColumns = [];
3118        $("#" + tableName)
3119            .bootstrapTable("getVisibleColumns")
3120            .forEach((column) => {
3121                if (!column.checkbox) {
3122                    visibleColumns.push(column.field);
3123                }
3124            });
3125        // Send preferences to the server
3126        $.ajax({
3127            url: "/master-panel/save-column-visibility",
3128            type: "POST",
3129            data: {
3130                type: type,
3131                visible_columns: JSON.stringify(visibleColumns),
3132            },
3133            headers: {
3134                "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
3135            },
3136            success: function (response) {
3137                $("#confirmSaveColumnVisibility")
3138                    .find("#confirm")
3139                    .html(label_yes)
3140                    .attr("disabled", false);
3141                if (response.error == false) {
3142                    $("#confirmSaveColumnVisibility").modal("hide");
3143                    toastr.success(response.message);
3144                } else {
3145                    toastr.error(response.message);
3146                }
3147            },
3148            error: function (data) {
3149                $("#confirmSaveColumnVisibility")
3150                    .find("#confirm")
3151                    .html(label_yes)
3152                    .attr("disabled", false);
3153                $("#confirmSaveColumnVisibility").modal("hide");
3154                toastr.error(label_something_went_wrong);
3155            },
3156        });
3157    });
3158});
3159// Edit Workspace Modal
3160$(document).on("click", ".edit-workspace", function () {
3161    var id = $(this).data("id");
3162    $("#editWorkspaceModal").modal("show");
3163    $.ajax({
3164        url: "/master-panel/workspaces/get/" + id,
3165        type: "get",
3166        headers: {
3167            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
3168        },
3169        dataType: "json",
3170        success: function (response) {
3171            $("#workspace_id").val(response.workspace.id);
3172            $("#workspace_title").val(response.workspace.title);
3173            var usersSelect = $("#editWorkspaceModal").find(
3174                '.js-example-basic-multiple[name="user_ids[]"]'
3175            );
3176            var workspaceUsers = response.workspace.users.map(
3177                (user) => user.id
3178            );
3179            usersSelect.val(workspaceUsers);
3180            usersSelect.trigger("change"); // Trigger change event to update select2
3181            var clientsSelect = $("#editWorkspaceModal").find(
3182                '.js-example-basic-multiple[name="client_ids[]"]'
3183            );
3184            var workspaceClients = response.workspace.clients.map(
3185                (client) => client.id
3186            );
3187            clientsSelect.val(workspaceClients);
3188            clientsSelect.trigger("change"); // Trigger change event to update select2
3189            if (response.workspace.is_primary == 1) {
3190                $("#editWorkspaceModal")
3191                    .find("#updatePrimaryWorkspace")
3192                    .prop("checked", true)
3193                    .prop("disabled", true);
3194            } else {
3195                $("#editWorkspaceModal")
3196                    .find("#updatePrimaryWorkspace")
3197                    .prop("checked", false)
3198                    .prop("disabled", false);
3199            }
3200        },
3201        error: function (xhr, status, error) {
3202            console.error(error);
3203        },
3204    });
3205});
3206// Edit Meetings
3207$(document).on("click", ".edit-meeting", function () {
3208    var id = $(this).data("id");
3209    $("#editMeetingModal").modal("show");
3210    $.ajax({
3211        url: "/master-panel/meetings/get/" + id,
3212        type: "get",
3213        headers: {
3214            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
3215        },
3216        dataType: "json",
3217        success: function (response) {
3218            var formattedStartDate = moment(response.meeting.start_date).format(
3219                js_date_format
3220            );
3221            var formattedEndDate = moment(response.meeting.end_date).format(
3222                js_date_format
3223            );
3224            var startDateInput = $("#editMeetingModal").find(
3225                '[name="start_date"]'
3226            );
3227            var endDateInput = $("#editMeetingModal").find('[name="end_date"]');
3228            $("#meeting_id").val(response.meeting.id);
3229            $("#meeting_title").val(response.meeting.title);
3230            startDateInput.val(formattedStartDate);
3231            endDateInput.val(formattedEndDate);
3232            // $("#meeting_start_time").val(response.meeting.start_time);
3233            // $("#meeting_end_time").val(response.meeting.end_time);
3234
3235            let startTime = response.meeting.start_time;
3236            let endTime = response.meeting.end_time;
3237
3238            // ✅ Set input value
3239            $("#meeting_start_time").val(startTime);
3240            $("#meeting_end_time").val(endTime);
3241
3242            // ✅ Sync with flatpickr (VERY IMPORTANT)
3243            let startEl = document.querySelector("#meeting_start_time");
3244            let endEl = document.querySelector("#meeting_end_time");
3245
3246            if (startEl && startEl._flatpickr) {
3247                startEl._flatpickr.setDate(startTime, true);
3248            }
3249            if (endEl && endEl._flatpickr) {
3250                endEl._flatpickr.setDate(endTime, true);
3251            }
3252            var usersSelect = $("#editMeetingModal").find(
3253                '.js-example-basic-multiple[name="user_ids[]"]'
3254            );
3255            var meetingUsers = response.meeting.admin.map((admin) => admin.id);
3256            usersSelect.val(meetingUsers);
3257            usersSelect.trigger("change"); // Trigger change event to update select2
3258            var clientsSelect = $("#editMeetingModal").find(
3259                '.js-example-basic-multiple[name="client_ids[]"]'
3260            );
3261            var meetingClients = response.meeting.clients.map(
3262                (client) => client.id
3263            );
3264            clientsSelect.val(meetingClients);
3265            clientsSelect.trigger("change"); // Trigger change event to update select2
3266
3267            var staffsSelect = $("#editMeetingModal").find(
3268                '.js-example-basic-multiple[name="staff_ids[]"]'
3269            );
3270            var meetingStaffs = response.meeting.staffs.map(
3271                (staff) => staff.id
3272            );
3273            staffsSelect.val(meetingStaffs);
3274            staffsSelect.trigger("change");
3275
3276            // ["#meeting_start_time","#meeting_end_time"].forEach(selector => {
3277            // 	flatpickr(selector, {
3278            // 		enableTime: true,
3279            // 		noCalendar: true,
3280            // 		dateFormat: "h:i K",
3281            // 		time_24hr: false,
3282            // 		defaultDate: selector.value || null,
3283            // 	});
3284            // });
3285
3286
3287        },
3288        error: function (xhr, status, error) {
3289            console.error(error);
3290        },
3291    });
3292});
3293$("#partialLeave, #updatePartialLeave").on("change", function () {
3294    var $form = $(this).closest("form"); // Get the closest form element
3295    var isChecked = $(this).prop("checked");
3296    if (isChecked) {
3297        // If the checkbox is checked
3298        $form
3299            .find(".leave-from-date-div")
3300            .removeClass("col-5")
3301            .addClass("col-3");
3302        $form.find(".leave-to-date-div").removeClass("col-5").addClass("col-3");
3303        $form
3304            .find(".leave-from-time-div, .leave-to-time-div")
3305            .removeClass("d-none");
3306        $form.find("#guide_text").removeClass("d-none");
3307    } else {
3308        // If the checkbox is unchecked, revert the changes
3309        $form.find('input[name="from_time"]').val("");
3310        $form.find('input[name="to_time"]').val("");
3311        $form
3312            .find(".leave-from-date-div")
3313            .removeClass("col-3")
3314            .addClass("col-5");
3315        $form.find(".leave-to-date-div").removeClass("col-3").addClass("col-5");
3316        $form
3317            .find(".leave-from-time-div, .leave-to-time-div")
3318            .addClass("d-none");
3319        $form.find("#guide_text").addClass("d-none");
3320    }
3321});
3322$(".leaveVisibleToAll").on("change", function () {
3323    var $form = $(this).closest("form"); // Get the closest form element
3324    var isChecked = $(this).prop("checked");
3325    if (isChecked) {
3326        // If the checkbox is checked
3327        $form.find(".leaveVisibleToDiv").addClass("d-none");
3328        var visibleToSelect = $form.find(
3329            '.js-example-basic-multiple[name="visible_to_ids[]"]'
3330        );
3331        visibleToSelect.val(null).trigger("change");
3332    } else {
3333        // If the checkbox is unchecked, revert the changes
3334        $form.find(".leaveVisibleToDiv").removeClass("d-none");
3335    }
3336});
3337$(document).ready(function () {
3338    var upcomingBDCalendarInitialized = false;
3339    var upcomingWACalendarInitialized = false;
3340    var membersOnLeaveCalendarInitialized = false;
3341    // Add event listener for tab shown event
3342    $(".nav-tabs .nav-item").on("shown.bs.tab", function (event) {
3343        var tabId = $(event.target).attr("data-bs-target");
3344        if (
3345            tabId == "#navs-top-upcoming-birthdays-calendar" &&
3346            !upcomingBDCalendarInitialized
3347        ) {
3348            initializeUpcomingBDCalendar();
3349            upcomingBDCalendarInitialized = true;
3350        } else if (
3351            tabId == "#navs-top-upcoming-work-anniversaries-calendar" &&
3352            !upcomingWACalendarInitialized
3353        ) {
3354            initializeUpcomingWACalendar();
3355            upcomingWACalendarInitialized = true;
3356        } else if (
3357            tabId == "#navs-top-members-on-leave-calendar" &&
3358            !membersOnLeaveCalendarInitialized
3359        ) {
3360            initializeMembersOnLeaveCalendar();
3361            membersOnLeaveCalendarInitialized = true;
3362        }
3363    });
3364});
3365function initializeUpcomingBDCalendar() {
3366    var upcomingBDCalendar = document.getElementById(
3367        "upcomingBirthdaysCalendar"
3368    );
3369    // Check if the calendar element exists
3370    if (upcomingBDCalendar) {
3371        var BDcalendar = new FullCalendar.Calendar(upcomingBDCalendar, {
3372            plugins: ["interaction", "dayGrid", "list"],
3373            headerToolbar: {
3374                left: "prev,next today",
3375                center: "title",
3376                right: "dayGridMonth,listYear",
3377            },
3378            editable: true,
3379            events: function (fetchInfo, successCallback, failureCallback) {
3380                // Make AJAX request to fetch dynamic data
3381                $.ajax({
3382                    url: "/master-panel/home/upcoming-birthdays-calendar",
3383                    type: "GET",
3384                    data: {
3385                        startDate: fetchInfo.startStr,
3386                        endDate: fetchInfo.endStr,
3387                    },
3388                    success: function (response) {
3389                        // Parse and format dynamic data for FullCalendar
3390                        var events = response.map(function (event) {
3391                            return {
3392                                title: event.title,
3393                                start: event.start,
3394                                end: event.start,
3395                                backgroundColor: event.backgroundColor,
3396                                borderColor: event.borderColor,
3397                                textColor: event.textColor,
3398                                userId: event.userId,
3399                            };
3400                        });
3401                        // Invoke success callback with dynamic data
3402                        successCallback(events);
3403                    },
3404                    error: function (xhr, status, error) {
3405                        console.error(xhr.responseText);
3406                        // Invoke failure callback if there's an error
3407                        failureCallback(error);
3408                    },
3409                });
3410            },
3411            eventClick: function (info) {
3412                if (
3413                    info.event.extendedProps &&
3414                    info.event.extendedProps.userId
3415                ) {
3416                    var userId = info.event.extendedProps.userId;
3417                    var url = "/master-panel/users/profile/" + userId;
3418                    window.open(url, "_blank"); // Open in a new tab
3419                }
3420            },
3421        });
3422        BDcalendar.render();
3423    }
3424}
3425function initializeUpcomingWACalendar() {
3426    var upcomingWACalendar = document.getElementById(
3427        "upcomingWorkAnniversariesCalendar"
3428    );
3429    // Check if the calendar element exists
3430    if (upcomingWACalendar) {
3431        var WAcalendar = new FullCalendar.Calendar(upcomingWACalendar, {
3432            plugins: ["interaction", "dayGrid", "list"],
3433            headerToolbar: {
3434                left: "prev,next today",
3435                center: "title",
3436                right: "dayGridMonth,listYear",
3437            },
3438            editable: true,
3439            height: "auto",
3440            events: function (fetchInfo, successCallback, failureCallback) {
3441                // Make AJAX request to fetch dynamic data
3442                $.ajax({
3443                    url: "/master-panel/home/upcoming-work-anniversaries-calendar",
3444                    type: "GET",
3445                    data: {
3446                        startDate: fetchInfo.startStr,
3447                        endDate: fetchInfo.endStr,
3448                    },
3449                    success: function (response) {
3450                        // Parse and format dynamic data for FullCalendar
3451                        var events = response.map(function (event) {
3452                            return {
3453                                title: event.title,
3454                                start: event.start,
3455                                end: event.start,
3456                                backgroundColor: event.backgroundColor,
3457                                borderColor: event.borderColor,
3458                                textColor: event.textColor,
3459                                userId: event.userId,
3460                            };
3461                        });
3462                        // Invoke success callback with dynamic data
3463                        successCallback(events);
3464                    },
3465                    error: function (xhr, status, error) {
3466                        console.error(xhr.responseText);
3467                        // Invoke failure callback if there's an error
3468                        failureCallback(error);
3469                    },
3470                });
3471            },
3472            eventClick: function (info) {
3473                if (
3474                    info.event.extendedProps &&
3475                    info.event.extendedProps.userId
3476                ) {
3477                    var userId = info.event.extendedProps.userId;
3478                    var url = "/master-panel/users/profile/" + userId;
3479                    window.open(url, "_blank"); // Open in a new tab
3480                }
3481            },
3482        });
3483        WAcalendar.render();
3484    }
3485}
3486function initializeMembersOnLeaveCalendar() {
3487    var membersOnLeaveCalendar = document.getElementById("membersOnLeaveCalendar");
3488
3489    if (membersOnLeaveCalendar) {
3490        // Optional: clear and re-init if needed
3491        membersOnLeaveCalendar.innerHTML = ""; // Reset content
3492
3493        var MOLcalendar = new FullCalendar.Calendar(membersOnLeaveCalendar, {
3494            plugins: ["interaction", "dayGrid", "list"],
3495            headerToolbar: {
3496                left: "prev,next today",
3497                center: "title",
3498                right: "dayGridMonth,listYear",
3499            },
3500            editable: true,
3501            displayEventTime: true,
3502            events: function (fetchInfo, successCallback, failureCallback) {
3503                $.ajax({
3504                    url: "/master-panel/home/members-on-leave-calendar",
3505                    type: "GET",
3506                    data: {
3507                        startDate: fetchInfo.startStr,
3508                        endDate: fetchInfo.endStr,
3509                    },
3510                    success: function (response) {
3511                        var events = response.map(function (event) {
3512                            var eventData = {
3513                                title: event.title,
3514                                start: event.start,
3515                                end: moment(event.end).add(1, "days").format("YYYY-MM-DD"),
3516                                backgroundColor: event.backgroundColor,
3517                                borderColor: event.borderColor,
3518                                textColor: event.textColor,
3519                                userId: event.userId,
3520                            };
3521                            if (event.startTime && event.endTime) {
3522                                eventData.extendedProps = {
3523                                    startTime: event.startTime,
3524                                    endTime: event.endTime,
3525                                };
3526                            }
3527                            return eventData;
3528                        });
3529                        successCallback(events);
3530                    },
3531                    error: function (xhr, status, error) {
3532                        console.error(xhr.responseText);
3533                        failureCallback(error);
3534                    },
3535                });
3536            },
3537            eventClick: function (info) {
3538                if (info.event.extendedProps && info.event.extendedProps.userId) {
3539                    var userId = info.event.extendedProps.userId;
3540                    window.open("/master-panel/users/profile/" + userId, "_blank");
3541                }
3542            },
3543        });
3544
3545        MOLcalendar.render();
3546    }
3547}
3548
3549// Run on page load
3550window.addEventListener("load", initializeMembersOnLeaveCalendar);
3551
3552// Also run when clicking a button (example)
3553document.addEventListener("DOMContentLoaded", function () {
3554    const btn = document.getElementById("showLeaveCalendarBtn");
3555    if (btn) {
3556        btn.addEventListener("click", initializeMembersOnLeaveCalendar);
3557    }
3558});
3559
3560// View Assigned Projects and Tasks
3561$(document).on("click", ".viewAssigned", function (e) {
3562    e.preventDefault();
3563    var projectsUrl = "/master-panel/projects/listing";
3564    var tasksUrl = "/master-panel/tasks/list";
3565    var id = $(this).data("id");
3566    var type = $(this).data("type");
3567    var user = $(this).data("user");
3568    projectsUrl = projectsUrl + (id ? "/" + id : "");
3569    tasksUrl = tasksUrl + (id ? "/" + id : "");
3570    $("#viewAssignedModal").modal("show");
3571    var projectsTable = $("#viewAssignedModal").find("#projects_table");
3572    var tasksTable = $("#viewAssignedModal").find("#task_table");
3573    if (type === "tasks") {
3574        $('.nav-link[data-bs-target="#navs-top-view-assigned-tasks"]').tab(
3575            "show"
3576        );
3577        $(
3578            '.nav-link[data-bs-target="#navs-top-view-assigned-projects"]'
3579        ).removeClass("active");
3580        $("#navs-top-view-assigned-projects").removeClass("show active");
3581        $("#navs-top-view-assigned-tasks").addClass("show active");
3582    } else {
3583        $('.nav-link[data-bs-target="#navs-top-view-assigned-projects"]').tab(
3584            "show"
3585        );
3586        $(
3587            '.nav-link[data-bs-target="#navs-top-view-assigned-tasks"]'
3588        ).removeClass("active");
3589        $("#navs-top-view-assigned-tasks").removeClass("show active");
3590        $("#navs-top-view-assigned-projects").addClass("show active");
3591    }
3592    $("#userPlaceholder").text(user);
3593    $(projectsTable).bootstrapTable("refresh", {
3594        url: projectsUrl,
3595    });
3596    $(tasksTable).bootstrapTable("refresh", {
3597        url: tasksUrl,
3598    });
3599});
3600// Internal Client
3601$("#internal_client").change(function () {
3602    var isChecked = $(this).prop("checked");
3603    $("#password, #password_confirmation").val("");
3604    $("#passDiv, #confirmPassDiv, #statusDiv, #requireEvDiv").toggleClass(
3605        "d-none",
3606        isChecked
3607    );
3608    $("#client_deactive").prop("checked", true);
3609    $("#require_ev_" + (isChecked ? "no" : "yes")).prop("checked", true);
3610    $("#password").next(".error-message").remove();
3611    $("#password_confirmation").next(".error-message").remove();
3612});
3613$("#update_internal_client").change(function () {
3614    var isChecked = $(this).prop("checked");
3615    $("#password, #password_confirmation").val("");
3616    $("#passDiv, #confirmPassDiv, #statusDiv, #requireEvDiv").toggleClass(
3617        "d-none",
3618        isChecked
3619    );
3620    // Remove .error-message elements next to #password and #password_confirmation
3621    $("#password").next(".error-message").remove();
3622    $("#password_confirmation").next(".error-message").remove();
3623});
3624//Open Create Contract Type Modal
3625$(document).on("click", ".openCreateContractTypeModal", function (e) {
3626    e.preventDefault();
3627    $("#create_contract_type_modal").modal("show");
3628});
3629// reset date
3630function resetDateFields($form) {
3631    var currentDate = moment(new Date()).format(js_date_format); // Get current date
3632    $form.find("input").each(function () {
3633        var $this = $(this);
3634        if ($this.data("daterangepicker")) {
3635            // Destroy old instance
3636            $this.data("daterangepicker").remove();
3637            // Reinitialize with new value
3638            $this.val(currentDate).daterangepicker({
3639                alwaysShowCalendars: true,
3640                showCustomRangeLabel: true,
3641                // minDate: moment($(id).val(), js_date_format),
3642                singleDatePicker: true,
3643                showDropdowns: true,
3644                autoUpdateInput: true,
3645                locale: {
3646                    cancelLabel: "Clear",
3647                    format: js_date_format,
3648                },
3649            });
3650        }
3651    });
3652}
3653// Change Select Color
3654$(document).on("change", 'select[name="color"]', function (e) {
3655    e.preventDefault();
3656    var select = $(this);
3657    var classes = $(this).attr("class").split(" ");
3658    var currentColorClass = classes.filter(function (className) {
3659        return className.startsWith("select-");
3660    })[0];
3661    var selectedOption = $(this).find("option:selected");
3662    var selectedOptionClasses = selectedOption.attr("class").split(" ");
3663    var newColorClass = "select-" + selectedOptionClasses[1];
3664    select.removeClass(currentColorClass).addClass(newColorClass);
3665});
3666// Select All Preferences
3667$(document).ready(function () {
3668    if ($("#selectAllPreferences").length) {
3669        // Check initial state of checkboxes and update selectAllPreferences checkbox
3670        updateSelectAll();
3671        // Select/deselect all checkboxes when the selectAllPreferences checkbox is clicked
3672        $("#selectAllPreferences").click(function () {
3673            var isChecked = $(this).prop("checked");
3674            $('input[name="enabled_notifications[]"]:not(:disabled)').prop(
3675                "checked",
3676                isChecked
3677            );
3678        });
3679        // Update the selectAllPreferences checkbox state based on the checkboxes' status
3680        $('input[name="enabled_notifications[]"]').change(function () {
3681            updateSelectAll();
3682        });
3683        // Function to update selectAllPreferences checkbox based on checkboxes' status
3684        function updateSelectAll() {
3685            var allChecked =
3686                $('input[name="enabled_notifications[]"]:not(:disabled)')
3687                    .length ===
3688                $(
3689                    'input[name="enabled_notifications[]"]:not(:disabled):checked'
3690                ).length;
3691            $("#selectAllPreferences").prop("checked", allChecked);
3692        }
3693    }
3694});
3695function toggleChatIframe() {
3696    var iframeContainer = document.getElementById("chatIframeContainer");
3697    if (
3698        iframeContainer.style.display === "none" ||
3699        iframeContainer.style.display === ""
3700    ) {
3701        iframeContainer.style.display = "block";
3702    } else {
3703        iframeContainer.style.display = "none";
3704    }
3705}
3706$(document).on("change", "#statusSelect", function (e) {
3707    e.preventDefault();
3708    var id = $(this).data("id");
3709    var statusId = this.value;
3710    var type = $(this).data("type") || "project";
3711    var reload = $(this).data("reload") || false;
3712    var select = $(this);
3713    var originalStatusId = $(this).data("original-status-id");
3714    var originalColorClass = $(this).data("original-color-class");
3715    var classes = $(this).attr("class").split(" ");
3716    var currentColorClass = classes.filter(function (className) {
3717        return className.startsWith("select-");
3718    })[0];
3719    var selectedOption = $(this).find("option:selected");
3720    var selectedOptionClasses = selectedOption.attr("class").split(" ");
3721    var newColorClass = "select-" + selectedOptionClasses[1];
3722    select.removeClass(currentColorClass).addClass(newColorClass);
3723    $.ajax({
3724        url: "/master-panel/" + type + "s/get/" + id,
3725        type: "GET",
3726        success: function (response) {
3727            if (response.error == false) {
3728                $("#confirmUpdateStatusModal").modal("show"); // show the confirmation modal
3729                $("#confirmUpdateStatusModal").off(
3730                    "click",
3731                    "#confirmUpdateStatus"
3732                );
3733                if (type == "task" && response.task) {
3734                    $("#statusNote").val(response.task.note);
3735                    originalStatusId = response.task.status_id;
3736                } else if (type == "project" && response.project) {
3737                    $("#statusNote").val(response.project.note);
3738                    originalStatusId = response.project.status_id;
3739                }
3740                $("#confirmUpdateStatusModal").on(
3741                    "click",
3742                    "#confirmUpdateStatus",
3743                    function (e) {
3744                        $("#confirmUpdateStatus")
3745                            .html(label_please_wait)
3746                            .attr("disabled", true);
3747                        // Send AJAX request to update status
3748                        $.ajax({
3749                            type: "POST",
3750                            url: "/master-panel/update-" + type + "-status",
3751                            headers: {
3752                                "X-CSRF-TOKEN": $('input[name="_token"]').attr(
3753                                    "value"
3754                                ),
3755                            },
3756                            data: {
3757                                id: id,
3758                                statusId: statusId,
3759                                note: $("#statusNote").val(),
3760                            },
3761                            success: function (response) {
3762                                $("#confirmUpdateStatus")
3763                                    .html(label_yes)
3764                                    .attr("disabled", false);
3765                                if (response.error == false) {
3766                                    setTimeout(function () {
3767                                        if (reload) {
3768                                            window.location.reload(); // Reload the current page
3769                                        }
3770                                    }, 3000);
3771                                    $("#confirmUpdateStatusModal").modal(
3772                                        "hide"
3773                                    );
3774                                    var tableSelector =
3775                                        type == "project"
3776                                            ? "projects_table"
3777                                            : "task_table";
3778                                    var $table = $("#" + tableSelector);
3779                                    if ($table.length) {
3780                                        $table.bootstrapTable("refresh");
3781                                    }
3782                                    toastr.success(response.message);
3783                                } else {
3784                                    select
3785                                        .removeClass(newColorClass)
3786                                        .addClass(originalColorClass);
3787                                    select.val(originalStatusId);
3788                                    toastr.error(response.message);
3789                                }
3790                            },
3791                            error: function (xhr, status, error) {
3792                                $("#confirmUpdateStatus")
3793                                    .html(label_yes)
3794                                    .attr("disabled", false);
3795                                // Handle error
3796                                select
3797                                    .removeClass(newColorClass)
3798                                    .addClass(originalColorClass);
3799                                select.val(originalStatusId);
3800                                toastr.error("Something Went Wrong");
3801                            },
3802                        });
3803                    }
3804                );
3805            } else {
3806                $("#confirmUpdateStatus")
3807                    .html(label_yes)
3808                    .attr("disabled", false);
3809                select.val(originalStatusId);
3810                toastr.error(response.message);
3811            }
3812        },
3813        error: function (xhr, status, error) {
3814            // Handle error
3815            toastr.error("Something Went Wrong");
3816        },
3817    });
3818    // Handle modal close event
3819    $("#confirmUpdateStatusModal").off(
3820        "click",
3821        ".btn-close, #declineUpdateStatus"
3822    );
3823    $("#confirmUpdateStatusModal").on(
3824        "click",
3825        ".btn-close, #declineUpdateStatus",
3826        function (e) {
3827            // Set original status when modal is closed without confirmation
3828            select.val(originalStatusId);
3829            select.removeClass(newColorClass).addClass(originalColorClass);
3830        }
3831    );
3832});
3833$(document).on("change", "#prioritySelect", function (e) {
3834    e.preventDefault();
3835    var id = $(this).data("id");
3836    var priorityId = this.value;
3837    var type = $(this).data("type") || "project";
3838    var reload = $(this).data("reload") || false;
3839    var select = $(this);
3840    var originalPriorityId = $(this).data("original-priority-id") || 0;
3841    var originalColorClass = $(this).data("original-color-class");
3842    var classes = $(this).attr("class").split(" ");
3843    var currentColorClass = classes.filter(function (className) {
3844        return className.startsWith("select-");
3845    })[0];
3846    var selectedOption = $(this).find("option:selected");
3847    var selectedOptionClasses = selectedOption.attr("class").split(" ");
3848    var newColorClass = "select-" + selectedOptionClasses[1];
3849    select.removeClass(currentColorClass).addClass(newColorClass);
3850    $("#confirmUpdatePriorityModal").modal("show"); // show the confirmation modal
3851    $("#confirmUpdatePriorityModal").off("click", "#confirmUpdatePriority");
3852    $("#confirmUpdatePriorityModal").on(
3853        "click",
3854        "#confirmUpdatePriority",
3855        function (e) {
3856            $("#confirmUpdatePriority")
3857                .html(label_please_wait)
3858                .attr("disabled", true);
3859            $.ajax({
3860                type: "POST",
3861                url: "/master-panel/update-" + type + "-priority",
3862                headers: {
3863                    "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
3864                },
3865                data: {
3866                    id: id,
3867                    priorityId: priorityId,
3868                },
3869                success: function (response) {
3870                    $("#confirmUpdatePriority")
3871                        .html(label_yes)
3872                        .attr("disabled", false);
3873                    if (response.error == false) {
3874                        setTimeout(function () {
3875                            if (reload) {
3876                                window.location.reload(); // Reload the current page
3877                            }
3878                        }, 3000);
3879                        $("#confirmUpdatePriorityModal").modal("hide");
3880                        toastr.success(response.message);
3881                        var tableSelector =
3882                            type == "project" ? "projects_table" : "task_table";
3883                        var $table = $("#" + tableSelector);
3884                        if ($table.length) {
3885                            $table.bootstrapTable("refresh");
3886                        }
3887                    } else {
3888                        select
3889                            .removeClass(newColorClass)
3890                            .addClass(originalColorClass);
3891                        select.val(originalPriorityId);
3892                        toastr.error(response.message);
3893                    }
3894                },
3895                error: function (xhr, status, error) {
3896                    $("#confirmUpdatePriority")
3897                        .html(label_yes)
3898                        .attr("disabled", false);
3899                    // Handle error
3900                    select
3901                        .removeClass(newColorClass)
3902                        .addClass(originalColorClass);
3903                    select.val(originalPriorityId);
3904                    toastr.error("Something Went Wrong");
3905                },
3906            });
3907        }
3908    );
3909});
3910$(document).ready(function () {
3911    if ($("#total_days").length) {
3912        // Function to calculate and display the total days for create modal
3913        function calculateCreateTotalDays() {
3914            var start_date = moment($("#start_date").val(), js_date_format);
3915            var end_date = moment($("#lr_end_date").val(), js_date_format);
3916            if (start_date.isValid() && end_date.isValid()) {
3917                var total_days = end_date.diff(start_date, "days") + 1;
3918                $("#total_days").val(total_days);
3919            }
3920        }
3921        // Bind the event handlers to both date pickers in the create modal
3922        $("#start_date").on("apply.daterangepicker", function (ev, picker) {
3923            calculateCreateTotalDays();
3924        });
3925        $("#lr_end_date").on("apply.daterangepicker", function (ev, picker) {
3926            calculateCreateTotalDays();
3927        });
3928    }
3929    if ($("#update_total_days").length) {
3930        // Function to calculate and display the total days for update modal
3931        function calculateUpdateTotalDays() {
3932            var start_date = moment(
3933                $("#update_start_date").val(),
3934                js_date_format
3935            );
3936            var end_date = moment($("#update_end_date").val(), js_date_format);
3937            if (start_date.isValid() && end_date.isValid()) {
3938                var total_days = end_date.diff(start_date, "days") + 1;
3939                $("#update_total_days").val(total_days);
3940            }
3941        }
3942        // Bind the event handlers to both date pickers in the update modal
3943        $("#update_start_date").on(
3944            "apply.daterangepicker",
3945            function (ev, picker) {
3946                calculateUpdateTotalDays();
3947            }
3948        );
3949        $("#update_end_date").on(
3950            "apply.daterangepicker",
3951            function (ev, picker) {
3952                calculateUpdateTotalDays();
3953            }
3954        );
3955    }
3956});
3957/// Search Functionality for the Menu Bar
3958$(document).ready(function () {
3959    var $searchInput = $("#menu-search");
3960    var $clearButton = $("#clear-search");
3961    var menuItems = $(".menu-item");
3962    // Search input event handler
3963    $searchInput.on("input", function () {
3964        var searchQuery = $searchInput.val().toLowerCase();
3965        $clearButton.toggle(searchQuery.length > 0);
3966        menuItems.each(function () {
3967            const $menuItem = $(this);
3968            const $parentMenu = $menuItem.closest(".menu-sub");
3969            const $parentMenuItem = $parentMenu.closest(".menu-item");
3970            const itemText = $menuItem.text().toLowerCase();
3971            if (itemText.includes(searchQuery)) {
3972                $menuItem.show();
3973                // Show and open parent menu item
3974                if ($parentMenuItem.length) {
3975                    $parentMenuItem.show().addClass("open");
3976                }
3977                // If this item has a submenu
3978                const $subMenu = $menuItem.find("> .menu-sub");
3979                if ($subMenu.length) {
3980                    $menuItem.addClass("open");
3981                }
3982            } else {
3983                // Only hide if it doesn't have visible children
3984                if (!$menuItem.find(".menu-item:visible").length) {
3985                    $menuItem.hide();
3986                }
3987            }
3988        });
3989    });
3990    // Clear button click event handler
3991    $clearButton.on("click", function () {
3992        $searchInput.val("");
3993        $clearButton.hide();
3994        menuItems.find(".open").removeClass("open");
3995        menuItems.show(); // Show all menu items
3996    });
3997});
3998function calenderView() {
3999    var calendar = document.getElementById("taskCalenderDiv");
4000    // Check if the calendar element exists
4001    if (calendar) {
4002        var project_id = $("#project_id").val();
4003        var WAcalendar = new FullCalendar.Calendar(calendar, {
4004            plugins: ["interaction", "dayGrid", "list"],
4005            headerToolbar: {
4006                left: "prev,next today",
4007                center: "title",
4008                right: "dayGridMonth,listYear",
4009            },
4010            editable: false,
4011            height: "auto",
4012            selectable: true, // Enable date selection
4013            select: function (info) {
4014                // Handle date selection
4015                openCreateTaskModal({
4016                    startDate: info.start,
4017                    endDate: info.end,
4018                });
4019            },
4020            dateClick: function (info) {
4021                // Handle single date click
4022                openCreateTaskModal({
4023                    startDate: info.date,
4024                    endDate: info.date,
4025                });
4026            },
4027            events: function (fetchInfo, successCallback, failureCallback) {
4028                // Fetch tasks for the current month
4029                fetchTasks(
4030                    fetchInfo.start,
4031                    fetchInfo.end,
4032                    successCallback,
4033                    failureCallback,
4034                    project_id
4035                );
4036            },
4037            datesSet: function (info) {
4038                // Fetch tasks when the month changes
4039                WAcalendar.removeAllEvents();
4040                WAcalendar.refetchEvents();
4041            },
4042            eventClick: function (info) {
4043                // Redirect to the task info page
4044                window.open(info.event.extendedProps.tasks_info_url, "_blank");
4045            },
4046        });
4047        WAcalendar.render();
4048    }
4049}
4050
4051var WAcalendarStaff = null; // move to global scope
4052
4053function calenderViewshiftC() {
4054    var calendarEl = document.getElementById("shiftCalenderDivC");
4055    if (!calendarEl) return;
4056
4057    if (WAcalendarStaff !== null) {
4058        WAcalendarStaff.destroy();
4059    }
4060
4061    var project_id = $("#project_id").val();
4062
4063    WAcalendarStaff = new FullCalendar.Calendar(calendarEl, {
4064        initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek',
4065        plugins: ["interaction", "dayGrid", "list"],
4066        headerToolbar: {
4067            left: viewMode === "monthly" ? "prev,next today" : "",
4068            center: "title",
4069            right: "dayGridMonth,listYear,timeGridWeek",
4070        },
4071        displayEventTime: false,
4072        editable: false,
4073        height: "auto",
4074        selectable: true,
4075
4076        validRange: function (nowDate) {
4077            if (viewMode === 'weekly') {
4078                const start = new Date(nowDate);
4079                const end = new Date(nowDate);
4080                start.setDate(start.getDate() - start.getDay()); // Sunday
4081                end.setDate(start.getDate() + 6); // Saturday
4082                return { start: start, end: end };
4083            }
4084            return null;
4085        },
4086
4087        dateClick: function (info) {
4088            var clickedDate = info.dateStr;
4089            const currentPath = window.location.pathname;
4090            let ajaxUrl = currentPath.includes('/master-panel/change-request')
4091                ? "/master-panel/getChangerequestStaff"
4092                : "/master-panel/staffs/shift/getShiftData";
4093
4094            $.ajax({
4095                url: ajaxUrl,
4096                method: "GET",
4097                data: {
4098                    start: info.date.toISOString(),
4099                    end: info.date.toISOString(),
4100                    user_id: selectedUserId || "",
4101                    date: clickedDate
4102                },
4103                success: function (response) {
4104                    if (response && response.length > 0) {
4105
4106
4107                        $("#shiftCalenderDivModal").modal("show");
4108                        $("#shiftCalenderDivModal .modal-title").text("Shift Details");
4109
4110                        let allShiftsHtml = '';
4111                        const today = new Date().toISOString().split('T')[0];
4112
4113                        response.forEach(function (shift) {
4114                            // ----------------------------
4115                            // Normalize dates
4116                            // ----------------------------
4117                            const normalizeDate = (dateStr) => {
4118                                if (dateStr.includes('/')) {
4119                                    const [d, m, y] = dateStr.split('/');
4120                                    return `${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`;
4121                                }
4122                                return dateStr;
4123                            };
4124
4125                            const clickedYmd = normalizeDate(clickedDate);
4126                            const shiftYmd = normalizeDate(shift.date);
4127                            const date_actual = shift.date_actual;
4128
4129                            // ----------------------------
4130                            // Time calculation
4131                            // ----------------------------
4132                            const now = new Date();
4133                            let isPast = false;
4134
4135                            if (shift.time && shift.date) {
4136
4137                                const [startStr, endStr] = shift.time.split('-').map(t => t.trim());
4138
4139                                const parseTime = (timeStr) => {
4140                                    let [time, meridian] = timeStr.split(' ');
4141                                    let [h, m] = time.split(':').map(Number);
4142
4143                                    if (meridian === 'PM' && h !== 12) h += 12;
4144                                    if (meridian === 'AM' && h === 12) h = 0;
4145
4146                                    return { h, m };
4147                                };
4148
4149                                const [shiftYear, shiftMonth, shiftDay] = shiftYmd.split('-').map(Number);
4150
4151                                const start = parseTime(startStr);
4152                                const end = parseTime(endStr);
4153
4154                                const startDateTime = new Date(
4155                                    shiftYear,
4156                                    shiftMonth - 1,
4157                                    shiftDay,
4158                                    start.h,
4159                                    start.m
4160                                );
4161
4162                                let endDateTime = new Date(
4163                                    shiftYear,
4164                                    shiftMonth - 1,
4165                                    shiftDay,
4166                                    end.h,
4167                                    end.m
4168                                );
4169
4170                                // Overnight shift
4171                                if (endDateTime <= startDateTime) {
4172                                    endDateTime.setDate(endDateTime.getDate() + 1);
4173                                }
4174
4175                                isPast = now > endDateTime;
4176                            }
4177
4178                            // ----------------------------
4179                            // Button logic ✅ (ONLY ONCE)
4180                            // ----------------------------
4181                            let actionButton = '';
4182
4183                            if (currentPath.includes('/master-panel/change-request') || currentPath.includes('/master-panel/staffs/shift/calender')) {
4184
4185                                // only on shift date
4186                                if (clickedYmd === date_actual) {
4187
4188                                    if (isPast) {
4189                                        actionButton =
4190                                            `<button class="btn btn-sm btn-danger" disabled>
4191                                                Your shift ended
4192                                            </button>`;
4193                                    } else {
4194                                        actionButton =
4195                                            `<a class="btn btn-sm btn-primary"
4196                                               href="/master-panel/change-request/edit/${shift.id}">
4197                                               Change Request
4198                                            </a>`;
4199                                    }
4200                                }
4201                            }
4202
4203                            // ----------------------------
4204                            // Render HTML
4205                            // ----------------------------
4206                            allShiftsHtml += `
4207                                <div class="border rounded p-2 mb-3">
4208                                    ${isAdmin ? `<div><strong>Staff:</strong> ${shift.user_name || 'N/A'}</div>` : ''}
4209                                    <div><strong>Participant:</strong> ${shift.client_name || 'N/A'}</div>
4210                                    <div><strong>Date:</strong> ${shift.date_show}</div>
4211                                    <div><strong>Time:</strong> ${shift.time || 'N/A'}</div>
4212                                    <div><strong>Shift Type:</strong> ${shift.shift_type || 'N/A'}</div>
4213                                    <div class="mt-2">
4214                                        <a class="btn btn-sm btn-primary me-2 d-none"
4215                                           href="${shift.shift_info_url}" target="_blank">
4216                                           View Shift
4217                                        </a>
4218                                        ${actionButton}
4219                                    </div>
4220                                </div>
4221                            `;
4222                        });
4223
4224
4225                        $("#shiftCalenderDivModal .modal-body").html(allShiftsHtml);
4226                        $("#shiftActionBtn").hide(); // Hide the old single shift button
4227                    } else {
4228                        $('#shiftCalenderDivModal').modal('hide');
4229                        if (!currentPath.includes('/master-panel/change-request')) {
4230                            window.location.href = "/master-panel/staffs/shift/create?date=" + clickedDate;
4231                        }
4232                    }
4233                },
4234                error: function () {
4235                    alert("Failed to fetch shift data.");
4236                }
4237            });
4238        },
4239
4240        events: function (fetchInfo, successCallback, failureCallback) {
4241            fetchShiftsStaff(
4242                fetchInfo.start,
4243                fetchInfo.end,
4244                successCallback,
4245                failureCallback,
4246                project_id,
4247                selectedUserId,
4248                selectedDate
4249            );
4250        },
4251
4252        datesSet: function () {
4253            WAcalendarStaff.removeAllEvents();
4254            WAcalendarStaff.refetchEvents();
4255            if (viewMode === 'weekly') {
4256                const todayBtn = document.querySelector('.fc-today-button');
4257                if (todayBtn && todayBtn.disabled) {
4258                    todayBtn.style.display = 'none';
4259                }
4260            }
4261        },
4262
4263        eventClick: function (info) {
4264            selectedUserId = info.event.extendedProps.user_id;
4265            selectedDate = info.event.start.toISOString().split("T")[0];
4266            WAcalendarStaff.removeAllEvents();
4267            WAcalendarStaff.refetchEvents();
4268        },
4269    });
4270
4271    WAcalendarStaff.render();
4272
4273    $("#resetFilterBtn").on("click", function () {
4274        selectedUserId = null;
4275        selectedDate = null;
4276        WAcalendarStaff.removeAllEvents();
4277        WAcalendarStaff.refetchEvents();
4278    });
4279
4280    window.viewStaffShifts = function (userId) {
4281        selectedUserId = userId;
4282        selectedDate = null;
4283        WAcalendarStaff.removeAllEvents();
4284        WAcalendarStaff.refetchEvents();
4285    };
4286
4287    $('#shiftCalenderDivModal [data-dismiss="modal"]').on('click', function () {
4288        $('#shiftCalenderDivModal').modal('hide');
4289        WAcalendarStaff.removeAllEvents();
4290        WAcalendarStaff.refetchEvents();
4291        $("#resetFilterBtn").trigger('click');
4292    });
4293}
4294
4295
4296function calenderViewshift() {
4297    const calendarEl = document.getElementById('shiftCalenderDiv');
4298    if (!calendarEl) return;
4299
4300    let WAcalendarAllocated = new FullCalendar.Calendar(calendarEl, {
4301        defaultView: 'dayGridMonth',
4302        plugins: ["interaction", "dayGrid", "timeGrid", "list"],
4303        header: {
4304            left: "prev,next",
4305            center: "title",
4306            right: "dayGridMonth,timeGridWeek,timeGridDay",
4307        },
4308        buttonText: {
4309            dayGridMonth: 'Monthly View',
4310            timeGridWeek: 'Weekly View',
4311            timeGridDay: 'Today View'
4312        },
4313        editable: false,
4314        height: "auto",
4315        selectable: true,
4316        displayEventTime: true,
4317        eventTimeFormat: {
4318            hour: 'numeric',
4319            minute: '2-digit',
4320            meridiem: 'short'
4321        },
4322        eventRender: function (info) {
4323            // Add status-based CSS class for custom styling
4324            if (info.event.extendedProps.status_id !== undefined) {
4325                $(info.el).addClass('event-status-' + info.event.extendedProps.status_id);
4326            }
4327
4328            // Helpful tooltip for truncated titles
4329            $(info.el).attr('title', info.event.title);
4330        },
4331        events: function (fetchInfo, successCallback, failureCallback) {
4332            $.ajax({
4333                url: "/master-panel/allocated-shifts/get-data/approved",
4334                type: "GET",
4335                data: {
4336                    start: fetchInfo.start.toISOString(),
4337                    end: fetchInfo.end.toISOString(),
4338                    client_id: $('#filter_client').val(),
4339                    user_id: $('#filter_staff').val(),
4340                    status_id: $('#filter_status').val()
4341                },
4342                success: function (response) {
4343                    successCallback(response);
4344                },
4345                error: function (xhr, status, error) {
4346                    toastr.error("Failed to load shift data");
4347                    failureCallback(error);
4348                }
4349            });
4350        },
4351        eventClick: function (info) {
4352            const userId = info.event.extendedProps.user_id;
4353            const shiftAcceptId = info.event.extendedProps.shift_accept_id;
4354
4355            // Format dates for the details query (range of the clicked day)
4356            const startDate = info.event.start.toISOString().split('T')[0];
4357            const endDate = info.event.end ? info.event.end.toISOString().split('T')[0] : startDate;
4358
4359            $('#shiftDetailsContent').html('<div class="text-center p-5"><div class="spinner-border text-primary" role="status"></div></div>');
4360            $('#shiftDetailsModal').modal('show');
4361
4362            $.ajax({
4363                url: "/master-panel/allocated-shifts/details",
4364                type: "GET",
4365                data: {
4366                    user_id: userId,
4367                    shift_accept_id: shiftAcceptId,
4368                    start_date: startDate,
4369                    end_date: endDate,
4370                    approve: 1
4371                },
4372                success: function (html) {
4373                    $('#shiftDetailsContent').html(html);
4374                },
4375                error: function () {
4376                    $('#shiftDetailsContent').html('<div class="alert alert-danger">Failed to load shift details.</div>');
4377                }
4378            });
4379        },
4380        dateClick: function (info) {
4381            const clickedDate = info.dateStr;
4382            const events = WAcalendarAllocated.getEvents();
4383
4384            // Check if there are any events on the clicked date
4385            const clickedDateStart = moment(clickedDate).startOf('day');
4386            const clickedDateEnd = moment(clickedDate).endOf('day');
4387
4388            const hasShifts = events.some(event => {
4389                const eventStart = moment(event.start);
4390                const eventEnd = moment(event.end || event.start);
4391                return eventStart.isBefore(clickedDateEnd) && eventEnd.isAfter(clickedDateStart);
4392            });
4393
4394            if (hasShifts) {
4395                // If shifts exist, open the day view
4396                WAcalendarAllocated.changeView('timeGridDay', clickedDate);
4397            } else {
4398                // If no shifts exist, redirect to the create page
4399                const createUrl = calendarEl.getAttribute('data-create-url');
4400                const isAdmin = calendarEl.getAttribute('data-is-admin') === 'true';
4401
4402                if (isAdmin && createUrl) {
4403                    window.location.href = `${createUrl}?date = ${clickedDate} `;
4404                } else {
4405                    WAcalendarAllocated.changeView('timeGridDay', clickedDate);
4406                }
4407            }
4408        }
4409    });
4410
4411    WAcalendarAllocated.render();
4412
4413    // ✅ Accept/Reject from Popup
4414    $(document).on('click', '#staff_accept_shift_btn, #staff_reject_shift_btn', function () {
4415        const shiftId = $(this).data('shift-accept-id');
4416        const isAccept = $(this).attr('id') === 'staff_accept_shift_btn';
4417        const newStatus = isAccept ? 2 : 3; // 2=Accepted, 3=Rejected
4418        const actionText = isAccept ? 'Accept' : 'Reject';
4419
4420        if (!confirm(`Are you sure you want to ${actionText.toLowerCase()} this shift ? `)) return;
4421
4422        const $btn = $(this);
4423        const originalHtml = $btn.html();
4424        $btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span> Processing...');
4425
4426        $.ajax({
4427            url: `/ master - panel / accept - shift / ${shiftId}/status`,
4428            type: "POST",
4429            data: {
4430                _token: $('meta[name="csrf-token"]').attr('content'),
4431                status: newStatus
4432            },
4433            success: function (response) {
4434                if (response.success) {
4435                    toastr.success(`Shift ${actionText.toLowerCase()}ed successfully`);
4436                    $('#shiftDetailsModal').modal('hide');
4437                    WAcalendarAllocated.refetchEvents();
4438                } else {
4439                    toastr.error(response.message || `Failed to ${actionText.toLowerCase()} shift`);
4440                    $btn.prop('disabled', false).html(originalHtml);
4441                }
4442            },
4443            error: function () {
4444                toastr.error("An error occurred. Please try again.");
4445                $btn.prop('disabled', false).html(originalHtml);
4446            }
4447        });
4448    });
4449
4450    // Apply Filter Button
4451    $('#btn_filter_calendar').on('click', function () {
4452        WAcalendarAllocated.refetchEvents();
4453    });
4454
4455    // Reset Filters
4456    $('#reset_filters').on('click', function () {
4457        $('#filter_client').val('');
4458        $('#filter_status').val('');
4459        $('#filter_staff').empty().append('<option value="">All Staff</option>');
4460        WAcalendarAllocated.refetchEvents();
4461    });
4462
4463    // Dependent Dropdown Logic
4464    $('#filter_client').on('change', function () {
4465        const clientId = $(this).val();
4466        const $staffSelect = $('#filter_staff');
4467
4468        if (clientId) {
4469            $.get("/master-panel/allocated-shifts/get-staff", { client_id: clientId }, function (data) {
4470                $staffSelect.empty().append('<option value="">All Staff</option>');
4471                if (data.staff && data.staff.length > 0) {
4472                    data.staff.forEach(function (s) {
4473                        const name = s.first_name + ' ' + (s.middle_name ? s.middle_name + ' ' : '') + s.last_name;
4474                        $staffSelect.append(`<option value="${s.id}">${name}</option>`);
4475                    });
4476                }
4477            });
4478        }
4479    });
4480}
4481
4482
4483
4484
4485function calenderViewshiftClient() {
4486    var calendar = document.getElementById("shiftCalenderDivClient");
4487
4488    if (calendar) {
4489        var project_id = $("#project_id").val();
4490        var WAcalendar = new FullCalendar.Calendar(calendar, {
4491            initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek',
4492            plugins: ["interaction", "dayGrid", "list"],
4493            headerToolbar: {
4494                left: viewMode === "monthly" ? "prev,next today" : "",
4495                center: "title",
4496                right: "dayGridMonth,listYear,timeGridWeek",
4497            },
4498
4499            displayEventTime: false,
4500            editable: false,
4501            height: "auto",
4502            selectable: true,
4503
4504            validRange: function (nowDate) {
4505                if (viewMode === 'weekly') {
4506                    const start = new Date(nowDate);
4507                    start.setDate(start.getDate() - start.getDay()); // Sunday
4508                    const end = new Date(start);
4509                    end.setDate(end.getDate() + 6); // Saturday
4510                    return {
4511                        start: start.toISOString().split("T")[0],
4512                        end: new Date(end.getTime() + 86400000).toISOString().split("T")[0]
4513                    };
4514                }
4515                return null; // full range allowed in monthly
4516            },
4517            // dateClick: function (info) {
4518            //     var clickedDate = info.dateStr;
4519            //     var hasShift = false;
4520            //     WAcalendar.getEvents().forEach(function (event) {
4521            //         var eventDate = event.start.toISOString().split("T")[0];
4522            //         if (eventDate === clickedDate) {
4523            //             hasShift = true;
4524            //         }
4525            //     });
4526            //     if (!hasShift) {
4527            //         window.open("/master-panel/clients/shift/create?date=" + clickedDate, "_blank");
4528            //     }
4529            // },
4530
4531            dateClick: function (info) {
4532                var clickedDate = info.dateStr;
4533                $.ajax({
4534                    //url:ajaxUrl,
4535                    url: "/master-panel/clients/shift/getShiftData",
4536                    method: "GET",
4537                    data: {
4538                        start: info.date.toISOString(),
4539                        end: info.date.toISOString(),
4540                        user_id: selectedUserId || "",
4541                        date: clickedDate
4542                    },
4543                    success: function (response) {
4544                        if (response && response.length > 0) {
4545                            const shift = response[0];
4546                            $("#shiftCalenderDivModal").modal("show");
4547                            $("#shiftCalenderDivModal .modal-title").text("Shift Details");
4548                            $("#shiftCalenderDivModal .event-user").text(shift.client_id || "N/A");
4549                            $("#shiftCalenderDivModal .event-client").text(shift.client_name || "N/A");
4550                            $("#shiftCalenderDivModal .event-date").text(shift.date || clickedDate);
4551                            // $("#shiftCalenderDivModal .event-time").text(shift.start_time + " - " + shift.end_time);
4552                            $("#shiftCalenderDivModal .event-time").text(shift.time);
4553                            $("#shiftCalenderDivModal .event-type").text(shift.shift_type || "N/A");
4554                            $("#shiftCalenderDivModal .edit-link").attr('href', `/master-panel/clients/shifts/edit/${shift.id}`).text('Edit');
4555
4556                            $("#shiftActionBtn")
4557                                .text("View Shift")
4558                                .attr("href", shift.shift_info_url)
4559                                .show();
4560                        } else {
4561                            $('#shiftCalenderDivModal').modal('hide');
4562
4563                            // $("#shiftCalenderDivModal .modal-title").text("Create New Shift");
4564                            // $("#shiftCalenderDivModal .event-user").text("N/A");
4565                            // $("#shiftCalenderDivModal .event-date").text(clickedDate);
4566                            // $("#shiftCalenderDivModal .event-time").text("N/A");
4567                            // $("#shiftCalenderDivModal .event-type").text("N/A");
4568
4569                            // $("#shiftActionBtn")
4570                            //     .text("Create Shift")
4571                            //     .attr("href", "/master-panel/staffs/shift/create?date=" + clickedDate)
4572                            //     .show();
4573
4574                            window.location.href = "/master-panel/clients/shift/create?date=" + clickedDate;
4575
4576                        }
4577                    },
4578                    error: function () {
4579                        alert("Failed to fetch shift data.");
4580                    }
4581                });
4582            },
4583
4584            events: function (fetchInfo, successCallback, failureCallback) {
4585                // ✅ Use global selectedUserId and selectedDate
4586                fetchShifts(
4587                    fetchInfo.start,
4588                    fetchInfo.end,
4589                    successCallback,
4590                    failureCallback,
4591                    project_id,
4592                    selectedUserId,
4593                    selectedDate
4594                );
4595            },
4596
4597            datesSet: function (info) {
4598                WAcalendar.removeAllEvents();
4599                WAcalendar.refetchEvents();
4600
4601            },
4602
4603            eventClick: function (info) {
4604                // ✅ Update global filters
4605                selectedUserId = info.event.extendedProps.user_id;
4606                selectedDate = info.event.start.toISOString().split("T")[0];
4607                WAcalendar.removeAllEvents();
4608                WAcalendar.refetchEvents();
4609            },
4610        });
4611
4612        WAcalendar.render();
4613    }
4614    $("#resetFilterBtn").on("click", function () {
4615        selectedUserId = null;
4616        selectedDate = null;
4617
4618        if (WAcalendar) {
4619            WAcalendar.removeAllEvents();
4620            WAcalendar.refetchEvents();
4621        }
4622    });
4623    window.viewUserShifts = function (userId) {
4624        selectedUserId = userId;
4625        selectedDate = null;
4626        if (WAcalendar) {
4627            WAcalendar.removeAllEvents();
4628            WAcalendar.refetchEvents();
4629        }
4630
4631    };
4632
4633    $('#shiftCalenderDivModal [data-dismiss="modal"]').on('click', function () {
4634        $('#shiftCalenderDivModal').modal('hide');
4635        // Just refresh events, not reinitialize calendar
4636        WAcalendarStaff.removeAllEvents();
4637        WAcalendarStaff.refetchEvents();
4638        $("#resetFilterBtn").trigger('click');
4639    });
4640}
4641
4642
4643
4644// Helper function to open the create task modal
4645function openCreateTaskModal(dates) {
4646    // Format dates to your required format (example uses YYYY-MM-DD)
4647    const startDate = formatDate(dates.startDate);
4648    const endDate = formatDate(dates.endDate);
4649    // If you're using a bootstrap modal
4650    const modal = new bootstrap.Modal(
4651        document.getElementById("create_task_modal")
4652    );
4653    // Set the date values in your form inputs
4654    document.getElementById("task_start_date").value = startDate;
4655    document.getElementById("task_end_date").value = endDate;
4656    // Show the modal
4657    modal.show();
4658}
4659// Helper function to format dates according to system format
4660function formatDate(date) {
4661    if (!date) return "";
4662    try {
4663        // Create a moment object and format according to system date format
4664        return moment(date).format(js_date_format);
4665    } catch (error) {
4666        console.error("Error formatting date:", error);
4667        // Fallback to ISO format if there's an error
4668        return date.toISOString().split("T")[0];
4669    }
4670}
4671function fetchTasks(
4672    startDate,
4673    endDate,
4674    successCallback,
4675    failureCallback,
4676    project_id
4677) {
4678    $.ajax({
4679        url: "/master-panel/tasks/get-calendar-data",
4680        type: "GET",
4681        data: {
4682            start: startDate.toISOString(), // Send the start date
4683            end: endDate.toISOString(), // Send the end date,
4684            project_id: project_id,
4685        },
4686        success: function (response) {
4687            // Parse and format dynamic data for FullCalendar
4688            var events = response.map(function (event) {
4689                return {
4690                    id: event.id,
4691                    tasks_info_url: event.tasks_info_url,
4692                    title: event.title,
4693                    start: event.start,
4694                    end: moment(event.end).add(1, "days").format("YYYY-MM-DD"),
4695                    backgroundColor: event.backgroundColor,
4696                    borderColor: event.borderColor,
4697                    textColor: event.textColor,
4698                };
4699            });
4700            // Invoke success callback with dynamic data
4701            successCallback(events);
4702        },
4703        error: function (xhr, status, error) {
4704            console.error(xhr.responseText);
4705            // Invoke failure callback if there's an error
4706            failureCallback(error);
4707        },
4708    });
4709}
4710
4711
4712function fetchShifts(
4713    startDate,
4714    endDate,
4715    successCallback,
4716    failureCallback,
4717    project_id,
4718    user_id = null,
4719    date = null
4720) {
4721    const currentPath = window.location.pathname;
4722    let ajaxUrl = ''; // Declare in outer scope
4723    if (currentPath.includes('/master-panel/clients/shift/list')) {
4724        ajaxUrl = "/master-panel/clients/shift/getShiftData";
4725    }
4726    else {
4727        ajaxUrl = "/master-panel/scheduler/getData";
4728    }
4729    $.ajax({
4730        url: ajaxUrl,
4731        //url: "/master-panel/clients/shift/getShiftData",
4732        type: "GET",
4733        data: {
4734            start: startDate.toISOString(),
4735            end: endDate.toISOString(),
4736            project_id: project_id,
4737            user_id: user_id,     // Pass user ID if set
4738            date: date            // Pass selected date if set
4739        },
4740        success: function (response) {
4741            var events = response.map(function (shift) {
4742                return {
4743                    id: shift.shift_id,
4744                    title: shift.shift_title,
4745                    start: new Date(shift.start_time).toISOString(),
4746                    end: new Date(shift.end_time).toISOString(),//shift.end_time,
4747                    backgroundColor: shift.backgroundColor,
4748                    borderColor: shift.borderColor,
4749                    textColor: shift.textColor,
4750                    shift_info_url: shift.shift_info_url,
4751                    user_id: shift.user_id // Include user_id if you want to filter later on client side too
4752                };
4753            });
4754
4755            successCallback(events);
4756        },
4757        error: function (xhr, status, error) {
4758            console.error(xhr.responseText);
4759            failureCallback(error);
4760        },
4761    });
4762}
4763function fetchShiftsStaff(
4764    startDate,
4765    endDate,
4766    successCallback,
4767    failureCallback,
4768    project_id,
4769    user_id = null,
4770    date = null
4771) {
4772    // const currentPath = window.location.pathname;
4773    const currentPath = window.location.pathname.replace(/\/+$/, '');
4774
4775    let ajaxUrl = ''; // Declare in outer scope
4776    // console.log("📍 currentPath:", currentPath); // Debug print
4777
4778    if (currentPath === '/master-panel/staffs/shift/calender') {
4779        ajaxUrl = "/master-panel/staffs/shift/getShiftData";
4780        //console.log("✅ ajaxUrl set to:", ajaxUrl);
4781    } else if (currentPath.includes('/master-panel/change-request')) {
4782        ajaxUrl = "/master-panel/getChangerequestStaff";
4783    } else {
4784        ajaxUrl = "/master-panel/scheduler/getData";
4785    }
4786
4787
4788    $.ajax({
4789        //url: "/master-panel/staffs/shift/getShiftData",
4790        url: ajaxUrl,
4791        type: "GET",
4792        data: {
4793            start: startDate.toISOString(),
4794            end: endDate.toISOString(),
4795            project_id: project_id,
4796            user_id: user_id,     // Pass user ID if set
4797            date: date            // Pass selected date if set
4798        },
4799        success: function (response) {
4800            console.log(response);
4801            var events = response.map(function (shift) {
4802
4803                return {
4804                    id: shift.shift_id,
4805                    title: shift.shift_title,
4806                    start: new Date(shift.start_time).toISOString(),// shift.start_time,
4807                    end: new Date(shift.end_time).toISOString(),//shift.end_time,
4808                    backgroundColor: shift.backgroundColor,
4809                    borderColor: shift.borderColor,
4810                    textColor: shift.textColor,
4811                    shift_info_url: shift.shift_info_url,
4812                    user_id: shift.user_id // Include user_id if you want to filter later on client side too
4813                };
4814            });
4815
4816            successCallback(events);
4817        },
4818        error: function (xhr, status, error) {
4819            console.error(xhr.responseText);
4820            failureCallback(error);
4821        },
4822    });
4823}
4824
4825function meetingData(
4826    startDate,
4827    endDate,
4828    successCallback,
4829    failureCallback,
4830    project_id,
4831    user_id = null,
4832    date = null
4833) {
4834    const currentPath = window.location.pathname;
4835    let ajaxUrl = "/master-panel/meetings-data";
4836    $.ajax({
4837        url: ajaxUrl,
4838        type: "GET",
4839        data: {
4840            start: startDate.toISOString(),
4841            end: endDate.toISOString()
4842        },
4843        success: function (response) {
4844            var events = response.map(function (meeting) {
4845                return {
4846                    id: meeting.id,
4847                    title: meeting.title,
4848                    start: meeting.start_time,
4849                    end: meeting.end_time,
4850                    borderColor: meeting.borderColor,
4851                    textColor: meeting.textColor,
4852                    url: meeting.url
4853                    // Include user_id if you want to filter later on client side too
4854                };
4855            });
4856            successCallback(events);
4857        },
4858        error: function (xhr, status, error) {
4859            console.error(xhr.responseText);
4860            failureCallback(error);
4861        },
4862    });
4863}
4864
4865
4866function meetingCalender() {
4867    var calendar = document.getElementById("meetingCalender");
4868    let isModalOpen = false;
4869    if (calendar) {
4870        var project_id = $("#project_id").val();
4871        var WAcalendar = new FullCalendar.Calendar(calendar, {
4872            initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek',
4873            plugins: ["interaction", "dayGrid", "list"],
4874            headerToolbar: {
4875                left: viewMode === "monthly" ? "prev,next today" : "",
4876                center: "title",
4877                right: "dayGridMonth,listYear,timeGridWeek",
4878            },
4879            displayEventTime: false,
4880            editable: false,
4881            height: "auto",
4882            selectable: true,
4883            events: function (fetchInfo, successCallback, failureCallback) {
4884                // ✅ Use global selectedUserId and selectedDate
4885                meetingData(
4886                    fetchInfo.start,
4887                    fetchInfo.end,
4888                    successCallback,
4889                    failureCallback,
4890                    project_id,
4891                    selectedUserId,
4892                    selectedDate
4893                );
4894            },
4895            eventClick: function (info) {
4896                info.jsEvent.preventDefault(); // don't let the browser navigate
4897                const eventId = info.event.id; // Event ID
4898                const eventDate = info.event.dateStr; // ISO formatted date-time string
4899                const eventDateOnly = info.event.start.toISOString().split('T')[0];
4900                const event_url = '/master-panel/meetings-data/' + eventId + '/' + eventDateOnly; // ISO formatted date-time string 
4901
4902                console.log(eventId);
4903                console.log(eventDate);
4904                console.log(info);
4905                $.ajax({
4906                    url: info.event.url,
4907                    method: "GET",
4908                    data: {},
4909                    success: function (response) {
4910                        console.log(response);
4911                        if (response) {
4912                            console.log(response);
4913                            // Clear old content if necessary
4914                            $("#MeetingDivModal .modal-body").empty();
4915
4916                            // Title, Start & End Time
4917                            $('#MeetingDivModal .modal-body').append(`<p><strong>Title:</strong> ${response.title}</p>`);
4918                            $('#MeetingDivModal .modal-body').append(`<p><strong>Start Time:</strong> ${response.start_date_time}</p>`);
4919                            $('#MeetingDivModal .modal-body').append(`<p><strong>End Time:</strong> ${response.end_date_time}</p>`);
4920
4921                            // Admins
4922                            if (response.admin && response.admin.length > 0) {
4923                                $('#MeetingDivModal .modal-body').append('<p><strong>Admin:</strong></p>');
4924                                response.admin.forEach(admin => {
4925                                    $('#MeetingDivModal .modal-body').append(`
4926										<p>
4927											<img src="${admin.photo}" alt="${admin.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;">
4928											${admin.name}<!--(${admin.email})-->
4929										</p>
4930									`);
4931                                });
4932                            }
4933
4934                            // Staffs
4935                            if (response.staffs && response.staffs.length > 0) {
4936                                if (response.staffs.length > 1) {
4937                                    $('#MeetingDivModal .modal-body').append('<p><strong>Staffs:</strong></p>');
4938                                } else {
4939                                    $('#MeetingDivModal .modal-body').append('<p><strong>Staff:</strong></p>');
4940                                }
4941                                response.staffs.forEach(staff => {
4942                                    $('#MeetingDivModal .modal-body').append(`
4943										<p>
4944											<img src="${staff.photo}" alt="${staff.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;">
4945											${staff.name}<!--(${staff.email})-->
4946										</p>
4947									`);
4948                                });
4949                            }
4950
4951                            // Clients
4952                            if (response.clients && response.clients.length > 0) {
4953                                if (response.clients.length > 1) {
4954                                    $('#MeetingDivModal .modal-body').append('<p><strong>Participants:</strong></p>');
4955                                } else {
4956                                    $('#MeetingDivModal .modal-body').append('<p><strong>Participant:</strong></p>');
4957                                }
4958                                response.clients.forEach(client => {
4959                                    $('#MeetingDivModal .modal-body').append(`
4960										<p>
4961											<img src="${client.photo}" alt="${client.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;">
4962											${client.name}<!--(${client.email})-->
4963										</p>
4964									`);
4965                                });
4966                            }
4967
4968                            // Clients
4969                            if (response.url) {
4970                                if (response.ended == 0) {
4971                                    $('#MeetingDivModal .modal-body').append(`<p><a target="_blank" class="btn btn-primary edit-link" style="display:block; text-align: center;" href="` + response.url + `" >Join Meeting</a></p>`);
4972                                } else {
4973                                    $('#MeetingDivModal .modal-body').append(`<p style="color:red;">Meeting has expired.</p>`);
4974                                }
4975                            }
4976
4977                            $("#MeetingDivModal").modal("show");
4978                        } else {
4979                            $('#MeetingDivModal').modal('hide');
4980                        }
4981                    },
4982                    error: function () {
4983                        alert("Failed to fetch meeting data.");
4984                    }
4985                });
4986            },
4987        });
4988        WAcalendar.render();
4989    }
4990
4991    $('#MeetingDivModal [data-dismiss="modal"]').on('click', function () {
4992        $('#MeetingDivModal').modal('hide');
4993    });
4994}
4995
4996
4997// Initialize the calendar on page load
4998meetingCalender();
4999calenderView();
5000calenderViewshift();
5001calenderViewshiftC();
5002calenderViewshiftClient();
5003
5004$(document).ready(function () {
5005    $("#previewToast").click(function () {
5006        var previewToastPosition = $("#toastPosition").val();
5007        var toastTimeoutInput = $("#toastTimeout");
5008        var previewToastTimeout = parseFloat(toastTimeoutInput.val());
5009        // Validate toast timeout is not blank and is a positive number
5010        if (isNaN(previewToastTimeout) || previewToastTimeout <= 0) {
5011            toastr.options = {
5012                positionClass: toastPosition,
5013                timeOut: parseFloat(toastTimeOut) * 1000,
5014                showDuration: "300",
5015                hideDuration: "1000",
5016                extendedTimeOut: "1000",
5017                progressBar: true,
5018                closeButton: true,
5019            };
5020            toastr.error("Please enter a valid timeout value in seconds.");
5021            toastTimeoutInput.focus();
5022            return;
5023        }
5024        // Convert timeout to milliseconds
5025        previewToastTimeout *= 1000;
5026        toastr.options = {
5027            positionClass: previewToastPosition,
5028            timeOut: previewToastTimeout,
5029            showDuration: "300",
5030            hideDuration: "1000",
5031            extendedTimeOut: "1000",
5032            progressBar: true,
5033            closeButton: true,
5034        };
5035        toastr.success(
5036            "This is a preview of your toast message!",
5037            "Toast Preview"
5038        );
5039    });
5040});
5041document.addEventListener("DOMContentLoaded", function () {
5042    var chatBox = document.getElementById("chatBox");
5043    if (chatBox) {
5044        chatBox.scrollTop = chatBox.scrollHeight;
5045    }
5046});
5047// Mention in the text area
5048function initializeMentionTextarea($textarea) {
5049    // Extract mention id and type from the data attributes of the textarea
5050    const mentionID = $textarea.data("mention-id");
5051    const mentionType = $textarea.data("mention-type");
5052    // Check if the textarea element exists
5053    if ($textarea.length === 0) {
5054        console.error("Textarea not found.");
5055        return;
5056    }
5057    // Initialize Tribute.js with the provided textarea
5058    const tribute = new Tribute({
5059        values: function (text, cb) {
5060            // Fetch users based on the search term and mention info
5061            $.ajax({
5062                url: `/master-panel/projects/get-users`,
5063                method: "GET",
5064                data: {
5065                    search: text,
5066                    mention_id: mentionID,
5067                    mention_type: mentionType,
5068                },
5069                success: function (response) {
5070                    const mappedUsers = response.map((user) => ({
5071                        key: user.id, // Use 'id' as key
5072                        value: user.first_name + " " + user.last_name,
5073                    }));
5074                    cb(mappedUsers); // Provide the data to Tribute.js callback
5075                },
5076                error: function (xhr, status, error) {
5077                    console.error("Error fetching users:", error);
5078                },
5079            });
5080        },
5081        selectTemplate: function (item) {
5082            return `@${item.original.value}`; // What gets inserted when selected
5083        },
5084        lookup: "value", // Attribute used for lookup
5085        menuItemTemplate: function (item) {
5086            return `${item.original.value}`; // How items appear in the dropdown
5087        },
5088    });
5089    // Attach Tribute.js to the textarea
5090    tribute.attach($textarea[0]);
5091}
5092function stripHtml(content) {
5093    // Replace <a> tags with the inner text, but only add '@' if the inner text doesn't already start with it
5094    return content.replace(
5095        /<a [^>]+>([^<]+)<\/a>/g,
5096        function (match, innerText) {
5097            // Check if the innerText already starts with @
5098            return innerText.startsWith("@") ? innerText : "@" + innerText;
5099        }
5100    );
5101}
5102// Initialize the Select2 and Ajax in the select
5103function initSelect2Ajax(
5104    elementId,
5105    ajaxUrl,
5106    placeholderText = "",
5107    allowClear = true,
5108    minimumInputLength = 0,
5109    initialData = true
5110) {
5111    const $element = $(elementId);
5112    const $modalParent = $element.closest('.modal');
5113
5114    $element.select2({
5115        placeholder: placeholderText,
5116        dropdownParent: $modalParent.length ? $modalParent : $(document.body), // ✅ Conditional handling
5117        ajax: {
5118            url: ajaxUrl,
5119            dataType: "json",
5120            delay: 250,
5121            data: function (params) {
5122                return {
5123                    q: params.term || "", // Search term
5124                    page: params.page || 1, // Pagination
5125                };
5126            },
5127            processResults: function (data, params) {
5128                params.page = params.page || 1;
5129                return {
5130                    results: data.items,
5131                    pagination: {
5132                        more: data.pagination.more,
5133                    },
5134                };
5135            },
5136            cache: true,
5137        },
5138        minimumInputLength: minimumInputLength,
5139        allowClear: allowClear,
5140        initSelection: function (element, callback) {
5141            if (initialData) {
5142                $.ajax({
5143                    url: ajaxUrl,
5144                    data: {
5145                        q: "",
5146                        page: 1,
5147                    },
5148                    dataType: "json",
5149                    success: function (data) {
5150                        callback(data.items);
5151                    },
5152                });
5153            }
5154        },
5155    });
5156}
5157function initPhoneInput(inputId, initialCountryCode = "", initialISOCode = "") {
5158    const input = document.querySelector(`#${inputId}`);
5159    // Create a wrapper and clear button for the input
5160    const wrapper = document.createElement("div");
5161    wrapper.style.position = "relative";
5162    input.parentNode.insertBefore(wrapper, input);
5163    wrapper.appendChild(input);
5164    const clearButton = document.createElement("button");
5165    clearButton.innerHTML = "✖"; // Use an X or any icon for clear
5166    clearButton.style.position = "absolute";
5167    clearButton.style.right = "10px"; // Adjust as needed
5168    clearButton.style.top = "50%";
5169    clearButton.style.transform = "translateY(-50%)";
5170    clearButton.style.border = "none";
5171    clearButton.style.background = "none";
5172    clearButton.style.cursor = "pointer";
5173    clearButton.style.display = "none"; // Initially hidden
5174    wrapper.appendChild(clearButton);
5175    const iti = window.intlTelInput(input, {
5176        utilsScript:
5177            "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/utils.js",
5178        separateDialCode: true,
5179        initialCountry: "auto",
5180        preferredCountries: ["US", "GB", "CA", "IN"],
5181        geoIpLookup: function (callback) {
5182            callback("US"); // Default to US for geo IP lookup
5183        },
5184    });
5185    // Show the clear button when input has a value
5186    input.addEventListener("input", () => {
5187        clearButton.style.display = input.value ? "block" : "none";
5188    });
5189    // Clear input on button click
5190    clearButton.addEventListener("click", (e) => {
5191        e.preventDefault();
5192        iti.setNumber(""); // Clear the input
5193        clearButton.style.display = "none";
5194    });
5195    // Set initial country if provided
5196    if (initialCountryCode) {
5197        const allCountries = window.intlTelInputGlobals.getCountryData();
5198        let country;
5199        if (initialISOCode) {
5200            country = allCountries.find(
5201                (c) =>
5202                    `+${c.dialCode}` === initialCountryCode &&
5203                    c.iso2 === initialISOCode
5204            );
5205        }
5206        if (!country) {
5207            country = allCountries.find(
5208                (c) => `+${c.dialCode}` === initialCountryCode
5209            );
5210        }
5211        if (country) {
5212            iti.setCountry(country.iso2);
5213        }
5214    }
5215    function getNumber() {
5216        return input.value;
5217    }
5218    function getCountryCode() {
5219        const countryData = iti.getSelectedCountryData();
5220        return countryData.dialCode ? `+${countryData.dialCode}` : "";
5221    }
5222    function getISOCode() {
5223        const countryData = iti.getSelectedCountryData();
5224        return countryData.iso2 ? countryData.iso2 : "";
5225    }
5226    function setNumber(phoneNumber, countryCode) {
5227        if (countryCode) {
5228            const allCountries = window.intlTelInputGlobals.getCountryData();
5229            const country = allCountries.find(
5230                (c) => `+${c.dialCode}` === countryCode
5231            );
5232            if (country) {
5233                iti.setCountry(country.iso2);
5234            }
5235        }
5236        iti.setNumber(phoneNumber);
5237    }
5238    input.phoneInputMethods = {
5239        getNumber,
5240        getCountryCode,
5241        setNumber,
5242        getISOCode,
5243        isValidNumber: () => iti.isValidNumber(),
5244        getValidationError: () => iti.getValidationError(),
5245    };
5246    return input.phoneInputMethods;
5247}
5248$(function () {
5249    if ($("#project_users").length) {
5250        initSelect2Ajax(
5251            "#project_users",
5252            "/master-panel/users/search-users",
5253            label_select_user,
5254            true,
5255            0,
5256            true
5257        );
5258    }
5259    if ($("#user_filter").length) {
5260        initSelect2Ajax(
5261            "#user_filter",
5262            "/master-panel/users/search-users",
5263            label_select_user,
5264            true,
5265            0,
5266            true
5267        );
5268    }
5269    if ($("#project_clients").length) {
5270        initSelect2Ajax(
5271            "#project_clients",
5272            "/master-panel/clients/search-clients",
5273            label_select_client,
5274            true,
5275            0,
5276            true
5277        );
5278    }
5279});
5280$(document).ready(function () {
5281    $("#generate-password").on("click", function () {
5282        function generatePassword(length) {
5283            var charset =
5284                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";
5285            var password = "";
5286            for (var i = 0, n = charset.length; i < length; ++i) {
5287                password += charset.charAt(Math.floor(Math.random() * n));
5288            }
5289            return password;
5290        }
5291        // Generate a new random password
5292        var newPassword = generatePassword(12);
5293        // Set the generated password in both password and confirm password fields
5294        $("#password").val(newPassword);
5295        $("#password_confirmation").val(newPassword);
5296        // Ensure password is visible after generation
5297        var passwordField = $("#password");
5298        var toggleIcon = $(".toggle-password i");
5299        // Explicitly set the password field type to 'text'
5300        if (passwordField.attr("type") === "password") {
5301            passwordField.attr("type", "text"); // Show password
5302            // Ensure the toggle icon is in 'show' state
5303            toggleIcon.removeClass("bx-hide").addClass("bx-show");
5304        }
5305    });
5306});
5307$(document).ready(function () {
5308    // Handle delete selected notes or todos
5309    $("#delete-selected").on("click", function () {
5310        const itemType = $(this).data("type");
5311        const selectedIds = $(".selected-items:checked")
5312            .map(function () {
5313                return $(this).val();
5314            })
5315            .get();
5316        if (selectedIds.length > 0) {
5317            $("#confirmDeleteSelectedModal").modal("show"); // show the confirmation modal
5318            $("#confirmDeleteSelectedModal").off(
5319                "click",
5320                "#confirmDeleteSelections"
5321            );
5322            $("#confirmDeleteSelectedModal").on(
5323                "click",
5324                "#confirmDeleteSelections",
5325                function (e) {
5326                    $("#confirmDeleteSelections")
5327                        .html(label_please_wait)
5328                        .attr("disabled", true);
5329                    $.ajax({
5330                        url:
5331                            "/master-panel" +
5332                            "/" +
5333                            itemType +
5334                            "/destroy_multiple", // Adjust URL based on item type
5335                        data: {
5336                            ids: selectedIds,
5337                        },
5338                        type: "POST",
5339                        headers: {
5340                            "X-CSRF-TOKEN": $('input[name="_token"]').attr(
5341                                "value"
5342                            ),
5343                        },
5344                        success: function (response) {
5345                            $("#confirmDeleteSelections")
5346                                .html(label_yes)
5347                                .attr("disabled", false);
5348                            $("#confirmDeleteSelectedModal").modal("hide");
5349                            location.reload();
5350                        },
5351                        error: function (data) {
5352                            $("#confirmDeleteSelections")
5353                                .html(label_yes)
5354                                .attr("disabled", false);
5355                            $("#confirmDeleteSelectedModal").modal("hide");
5356                            toastr.error(label_something_went_wrong);
5357                        },
5358                    });
5359                }
5360            );
5361        } else {
5362            toastr.error(label_please_select_records_to_delete);
5363        }
5364    });
5365});
5366$("#select-all").on("click", function () {
5367    $(".selected-items").prop("checked", this.checked);
5368});
5369$(function () {
5370    if ($("#birthday_user_filter").length) {
5371        initSelect2Ajax(
5372            "#birthday_user_filter",
5373            "/master-panel/users/search-users",
5374            label_select_user,
5375            true,
5376            0,
5377            true
5378        );
5379    }
5380    if ($("#wa_user_filter").length) {
5381        initSelect2Ajax(
5382            "#wa_user_filter",
5383            "/master-panel/users/search-users",
5384            label_select_user,
5385            true,
5386            0,
5387            true
5388        );
5389    }
5390    if ($("#mol_user_filter").length) {
5391        initSelect2Ajax(
5392            "#mol_user_filter",
5393            "/master-panel/users/search-users",
5394            label_select_user,
5395            true,
5396            0,
5397            true
5398        );
5399    }
5400});
5401// Check Email Settings Functionality
5402$(document).on("click", "#test-email-settings", function () {
5403    const label_test_email_settings = $(this).html();
5404    const test_url = $(this).data('url') || "/superadmin/settings/email/test-email-settings";
5405
5406    $(this).html(label_please_wait).attr("disabled", true);
5407    $.ajax({
5408        url: test_url,
5409        type: "POST",
5410        headers: {
5411            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
5412        },
5413        success: function (response) {
5414            if (response.error) {
5415                toastr.error(response.message);
5416            } else {
5417                toastr.success(response.message);
5418            }
5419            $("#test-email-settings")
5420                .html(label_test_email_settings)
5421                .attr("disabled", false);
5422        },
5423        error: function (data) {
5424            $("#test-email-settings")
5425                .html(label_test_email_settings)
5426                .attr("disabled", false);
5427            if (data.responseJSON && data.responseJSON.message) {
5428                toastr.error(data.responseJSON.message);
5429            } else {
5430                toastr.error(label_something_went_wrong);
5431            }
5432        },
5433    });
5434});
5435
5436$(document).on("click", "#send-test-email-btn", function (e) {
5437    e.preventDefault();
5438    const btn = $(this);
5439    const original_text = btn.html();
5440    const test_url = $("#test-email-settings").data('url') || "/superadmin/settings/email/test-email-settings";
5441    const email = $("#test_email_input").val();
5442
5443    if (!email) {
5444        toastr.error("Please enter an email address.");
5445        return;
5446    }
5447
5448    const form = $("#test-email-settings").closest("form");
5449    // Remove _method=PUT so Laravel doesn't spoof the AJAX POST request to PUT
5450    let serializedData = form.serialize().replace(/&?_method=(PUT|PATCH|DELETE)/gi, '');
5451    const formData = serializedData + (serializedData ? "&" : "") + "test_email=" + encodeURIComponent(email);
5452
5453    btn.html(label_please_wait).attr("disabled", true);
5454    $.ajax({
5455        url: test_url,
5456        type: "POST",
5457        data: formData,
5458        headers: {
5459            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"),
5460        },
5461        success: function (response) {
5462            if (response.error) {
5463                toastr.error(response.message);
5464            } else {
5465                toastr.success(response.message);
5466                $("#testEmailModal").modal('hide');
5467            }
5468            btn.html(original_text).attr("disabled", false);
5469        },
5470        error: function (data) {
5471            btn.html(original_text).attr("disabled", false);
5472            if (data.responseJSON && data.responseJSON.message) {
5473                toastr.error(data.responseJSON.message);
5474            } else {
5475                toastr.error(label_something_went_wrong);
5476            }
5477        },
5478    });
5479});
5480function announcementCalendar() {
5481    const calendarEl = $("#announcements_calendar")[0]; // jQuery selector to get the DOM element
5482
5483    const editButton = '#editAnnouncementBtn';
5484    const deleteButton = "#deleteAnnouncementBtn";
5485    // FullCalendar Initialization
5486    const calendar = new FullCalendar.Calendar(calendarEl, {
5487        plugins: ["interaction", "dayGrid", "list"],
5488        headerToolbar: {
5489            left: "prev,next today",
5490            center: "title",
5491            right: "dayGridMonth,listYear",
5492        },
5493        events: async function (info, successCallback, failureCallback) {
5494            try {
5495                // Make AJAX request to fetch dynamic data
5496                const response = await $.ajax({
5497                    url: "/master-panel/announcements/events",
5498                    type: "GET",
5499                    data: {
5500                        startDate: info.startStr,
5501                        endDate: info.endStr,
5502                    },
5503                });
5504                console.log("Raw Response:", response);
5505                // Parse and format dynamic data for FullCalendar
5506                const events = response.map(event => ({
5507
5508                    id: event.id,
5509                    title: event.title,
5510                    start: event.start,
5511                    end: event.end,
5512                    created_by: event.created_by,
5513                    backgroundColor: event.backgroundColor,
5514                    borderColor: event.borderColor || event.backgroundColor, // Fallback
5515                    textColor: event.textColor,
5516                    extendedProps: event.extendedProps, // Pass extendedProps directly
5517                }));
5518                console.log("Parsed Events:", events);
5519                // Invoke success callback with dynamic data
5520                successCallback(events);
5521            } catch (error) {
5522                console.error("Error fetching events:", error);
5523                failureCallback(error); // Call failureCallback on error
5524            }
5525        },
5526        eventClick: function (info) {
5527            // Show announcement details
5528            const event = info.event;
5529            $("#announcementTitle").text(event.title);
5530            $("#announcementContent").text(event.extendedProps.content);
5531            $("#announcementPriority").text(event.extendedProps.priority);
5532            $("#announcementCreatedBy").text(event.extendedProps.createdBy);
5533            const startDate = moment(event.start).format(js_date_format);
5534            const endDate = moment(event.end).subtract(1, 'day').format(js_date_format);
5535            $("#announcementStartDate").text(startDate);
5536            $("#announcementEndDate").text(endDate);
5537            const canEdit = $("#canEdit").val();
5538            const canDelete = $("#canDelete").val();
5539            const userId = $("#userId").val();
5540            const isAdminOrHasAllDataAccess = $("#isAdminOrHasAllDataAccess").val();
5541            // Show action buttons if the user is admin or the creator of the announcement
5542            $(editButton).data("id", event.id);
5543            $(deleteButton).data("id", event.id);
5544            $(editButton).attr("data-id", event.id);
5545            $(deleteButton).attr("data-id", event.id);
5546            // Debugging: log data-id values
5547            console.log("Edit Button data-id:", $(editButton).data("id"));
5548            console.log("Delete Button data-id:", $(deleteButton).data("id"));
5549            // Toggle button visibility
5550
5551            if (canEdit == 1 && userId == event.extendedProps.created_by) {
5552
5553                $(editButton).removeClass("d-none");
5554            } else {
5555                $(editButton).addClass("d-none");
5556            }
5557            if (canDelete == 1 || isAdminOrHasAllDataAccess == 1) {
5558                $(deleteButton).removeClass("d-none");
5559            } else {
5560                $(deleteButton).addClass("d-none");
5561            }
5562
5563            // Show the modal
5564            $("#announcementModal").modal("show");
5565        },
5566        timezone: 'UTC',  // Adjust the timezone if necessary
5567    });
5568    calendar.render();
5569}
5570$(document).ready(function () {
5571    if ($('#announcements_calendar').length) {
5572        announcementCalendar();
5573    }
5574});
5575
5576// Announcements Update
5577
5578$(document).on("click", "#mark-all-announcement-as-read", function (e) {
5579    e.preventDefault();
5580    $("#mark_all_announcements_as_read_modal").modal("show"); // show the confirmation modal
5581    $("#mark_all_announcements_as_read_modal").on(
5582        "click",
5583        "#confirmAnnouncementMarkAllAsRead",
5584        function () {
5585            $("#confirmAnnouncementMarkAllAsRead")
5586                .html(label_please_wait)
5587                .attr("disabled", true);
5588            $.ajax({
5589                url: "/master-panel/announcements/mark-all-as-read",
5590                type: "PUT",
5591                headers: {
5592                    "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
5593                },
5594                success: function (response) {
5595                    location.reload();
5596
5597                },
5598            });
5599        }
5600    );
5601});
5602
5603$(document).on("click", ".update-announcement-status", function (e) {
5604    var announcementId = $(this).data("id");
5605    var needConfirm = $(this).data("needconfirm") || false;
5606    if (needConfirm) {
5607        // Show the confirmation modal
5608        $("#update_announcement_status_modal").modal("show");
5609        // Attach click event handler to the confirmation button
5610        $("#update_announcement_status_modal").off(
5611            "click",
5612            "#confirmAnnouncementStatus"
5613        );
5614        $("#update_announcement_status_modal").on(
5615            "click",
5616            "#confirmAnnouncementStatus",
5617            function () {
5618                $("#confirmAnnouncementStatus")
5619                    .html(label_please_wait)
5620                    .attr("disabled", true);
5621                performAnnouncementUpdate(announcementId, needConfirm);
5622            }
5623        );
5624    } else {
5625        // If confirmation is not needed, directly perform the update and handle response
5626        performAnnouncementUpdate(announcementId);
5627    }
5628});
5629function performAnnouncementUpdate(announcementId, needConfirm = "") {
5630    $.ajax({
5631        url: "/master-panel/announcements/update-status",
5632        type: "PUT",
5633        data: { id: announcementId, needConfirm: needConfirm },
5634        headers: {
5635            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
5636        },
5637        success: function (response) {
5638            console.log(response);
5639
5640            if (needConfirm) {
5641                $("#confirmAnnouncementStatus")
5642                    .html(label_yes)
5643                    .attr("disabled", false);
5644                if (response.error == false) {
5645                    toastr.success(response.message);
5646                    $("#table").bootstrapTable("refresh");
5647                } else {
5648                    toastr.error(response.message);
5649                }
5650                $("#update_announcement_status_modal").modal("hide");
5651            }
5652        },
5653    });
5654}
5655
5656const body = document.body;
5657
5658// If body does NOT have class "superadmin"
5659if (!body.classList.contains("superadmin")) {
5660
5661    /*if (
5662        typeof manage_announcements !== "undefined" &&
5663        manage_announcements == "true"
5664    ) {
5665        function updateUnreadAnnouncements() {
5666            // Make an AJAX request to fetch the count and HTML of unread announcements
5667            $.ajax({
5668                url: "/master-panel/announcements/get-unread-announcements",
5669                type: "GET",
5670                dataType: "json",
5671                success: function (data) {
5672                    const unreadAnnouncementsCount = data.count;
5673                    const unreadAnnouncementsHtml = data.html;
5674                    // Update the count in the badge
5675                    $("#unreadAnnouncementsCount").text(unreadAnnouncementsCount);
5676                    if (unreadNotificationsCount > 0) {
5677                        $("#unreadNotificationsCount").removeClass('d-none');
5678                    } else {
5679                        $("#unreadNotificationsCount").addClass('d-none');
5680                    }
5681
5682                    // Update the announcements list with the new HTML
5683                    $("#unreadAnnouncementsContainer").html(unreadAnnouncementsHtml);
5684                }
5685            });
5686        }
5687
5688        updateUnreadAnnouncements();
5689        // Update the unread announcements every 30 seconds
5690        setInterval(updateUnreadAnnouncements, 30000);
5691    }*/
5692
5693    function updateUnreadNotifications() {
5694        //alert('aaaa==');
5695        // Make an AJAX request to fetch the count and HTML of unread notifications
5696        $.ajax({
5697            url: "/master-panel/notifications/get-unread-notifications",
5698            type: "GET",
5699            dataType: "json",
5700            success: function (data) {
5701                const unreadNotificationsCount = data.count;
5702                const unreadNotificationsHtml = data.html;
5703                console.log('unreadNotificationsCount', unreadNotificationsCount);
5704                // Update the count in the badge
5705                $("#unreadNotificationsCount").text(unreadNotificationsCount);
5706                if (unreadNotificationsCount > 0) {
5707                    $("#unreadNotificationsCount").removeClass('d-none');
5708                } else {
5709                    $("#unreadNotificationsCount").addClass('d-none');
5710                }
5711
5712                // Update the notifications list with the new HTML
5713                $("#unreadNotificationsContainer").html(
5714                    unreadNotificationsHtml
5715                );
5716            }
5717        });
5718    }
5719    // Call the updateUnreadNotifications function initially
5720    updateUnreadNotifications();
5721    // Update the unread notifications every 30 seconds
5722    setInterval(updateUnreadNotifications, 30000);
5723}
5724
5725
5726
5727// Task Reminder Settings
5728
5729$(document).ready(function () {
5730    // Toggle Reminder Settings Visibility
5731    $('#reminder-switch').on('change', function () {
5732        if ($(this).is(':checked')) {
5733            $('#reminder-settings').removeClass('d-none');
5734            $('#time-of-day').prop('required', true);
5735        } else {
5736            $('#reminder-settings').addClass('d-none');
5737            $('#time-of-day').prop('required', false);
5738        }
5739    });
5740
5741    // Dynamic Display Based on Frequency Type
5742    $('#frequency-type').on('change', function () {
5743        const value = $(this).val();
5744        $('#day-of-week-group').addClass('d-none');
5745        $('#day-of-month-group').addClass('d-none');
5746
5747        if (value === 'weekly') {
5748            $('#day-of-week-group').removeClass('d-none');
5749        } else if (value === 'monthly') {
5750            $('#day-of-month-group').removeClass('d-none');
5751        }
5752    });
5753
5754    $('#edit-reminder-switch').on('change', function () {
5755        if ($(this).is(':checked')) {
5756            $('#edit-reminder-settings').removeClass('d-none');
5757        } else {
5758            $('#edit-reminder-settings').addClass('d-none');
5759        }
5760    });
5761    $('#edit-frequency-type').on('change', function () {
5762        const value = $(this).val();
5763        $('#edit-day-of-week-group').addClass('d-none');
5764        $('#edit-day-of-month-group').addClass('d-none');
5765
5766        if (value === 'weekly') {
5767            $('#edit-day-of-week-group').removeClass('d-none');
5768        } else if (value === 'monthly') {
5769            $('#edit-day-of-month-group').removeClass('d-none');
5770        }
5771    });
5772});
5773
5774// Recurring Task Settings
5775$(document).ready(function () {
5776    // Toggle Recurring Task Settings Visibility
5777    $('#recurring-task-switch').on('change', function () {
5778        if ($(this).is(':checked')) {
5779            $('#recurring-task-settings').removeClass('d-none');
5780            $('#recurrence-frequency').prop('required', true);
5781            $('#recurrence-starts-from').prop('required', true);
5782            $('#recurrence-occurrences').prop('required', true);
5783        } else {
5784            $('#recurring-task-settings').addClass('d-none');
5785            $('#recurrence-frequency').prop('required', false);
5786            $('#recurrence-starts-from').prop('required', false);
5787            $('#recurrence-occurrences').prop('required', false);
5788        }
5789    });
5790
5791    // Dynamic Display Based on Recurrence Frequency Type
5792    $('#recurrence-frequency').on('change', function () {
5793        const value = $(this).val();
5794        $('#recurrence-day-of-week-group').addClass('d-none');
5795        $('#recurrence-day-of-month-group').addClass('d-none');
5796        $('#recurrence-month-of-year-group').addClass('d-none');
5797
5798        if (value === 'weekly') {
5799            $('#recurrence-day-of-week-group').removeClass('d-none');
5800        } else if (value === 'monthly') {
5801            $('#recurrence-day-of-month-group').removeClass('d-none');
5802        } else if (value === 'yearly') {
5803            $('#recurrence-day-of-month-group').removeClass('d-none');
5804            $('#recurrence-month-of-year-group').removeClass('d-none');
5805        }
5806    });
5807
5808    // Initialize Settings on Page Load
5809    const initializeSettings = function () {
5810        if ($('#recurring-task-switch').is(':checked')) {
5811            $('#recurring-task-settings').removeClass('d-none');
5812        } else {
5813            $('#recurring-task-settings').addClass('d-none');
5814        }
5815
5816        const value = $('#recurrence-frequency').val();
5817        if (value === 'weekly') {
5818            $('#recurrence-day-of-week-group').removeClass('d-none');
5819        } else if (value === 'monthly') {
5820            $('#recurrence-day-of-month-group').removeClass('d-none');
5821        } else if (value === 'yearly') {
5822            $('#recurrence-day-of-month-group').removeClass('d-none');
5823            $('#recurrence-month-of-year-group').removeClass('d-none');
5824        }
5825    };
5826
5827    initializeSettings();
5828});
5829
5830//Edit Recurring Task Settings
5831$(document).ready(function () {
5832    // Toggle Recurring Task Settings Visibility
5833    $('#edit-recurring-task-switch').on('change', function () {
5834        if ($(this).is(':checked')) {
5835            $('#edit-recurring-task-settings').removeClass('d-none');
5836            $('#edit-recurrence-frequency').prop('required', true);
5837            $('#edit-recurrence-starts-from').prop('required', true);
5838            $('#edit-recurrence-occurrences').prop('required', true);
5839        } else {
5840            $('#edit-recurring-task-settings').addClass('d-none');
5841            $('#edit-recurrence-frequency').prop('required', false);
5842            $('#edit-recurrence-starts-from').prop('required', false);
5843            $('#edit-recurrence-occurrences').prop('required', false);
5844        }
5845    });
5846
5847    // Dynamic Display Based on Recurrence Frequency Type
5848    $('#edit-recurrence-frequency').on('change', function () {
5849        const value = $(this).val();
5850        $('#edit-recurrence-day-of-week-group').addClass('d-none');
5851        $('#edit-recurrence-day-of-month-group').addClass('d-none');
5852        $('#edit-recurrence-month-of-year-group').addClass('d-none');
5853
5854        if (value === 'weekly') {
5855            $('#edit-recurrence-day-of-week-group').removeClass('d-none');
5856        } else if (value === 'monthly') {
5857            $('#edit-recurrence-day-of-month-group').removeClass('d-none');
5858        } else if (value === 'yearly') {
5859            $('#edit-recurrence-day-of-month-group').removeClass('d-none');
5860            $('#edit-recurrence-month-of-year-group').removeClass('d-none');
5861        }
5862    });
5863
5864    // Initialize Settings on Page Load
5865    const editinitializeSettings = function () {
5866        if ($('#edit-recurring-task-switch').is(':checked')) {
5867            $('#edit-recurring-task-settings').removeClass('d-none');
5868        } else {
5869            $('#edit-recurring-task-settings').addClass('d-none');
5870        }
5871
5872        const value = $('#edit-recurrence-frequency').val();
5873        if (value === 'weekly') {
5874            $('#edit-recurrence-day-of-week-group').removeClass('d-none');
5875        } else if (value === 'monthly') {
5876            $('#edit-recurrence-day-of-month-group').removeClass('d-none');
5877        } else if (value === 'yearly') {
5878            $('#edit-recurrence-day-of-month-group').removeClass('d-none');
5879            $('#edit-recurrence-month-of-year-group').removeClass('d-none');
5880        }
5881    };
5882
5883    editinitializeSettings();
5884});
5885$(function () {
5886    if ($('.project-select').length > 0) {
5887        initSelect2Ajax('.project-select', 'tasks/search-projects', label_project);
5888    }
5889})
5890
5891$(document).on("click", ".edit-task-list", function () {
5892    var id = $(this).data("id");
5893    var routePrefix = $("#table").data("routePrefix");
5894    $("#edit_task_list_modal").modal("show");
5895    $.ajax({
5896        url: "/master-panel/task-lists/get/" + id,
5897        type: "get",
5898        headers: {
5899            "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token
5900        },
5901        dataType: "json",
5902        success: function (response) {
5903            console.log(response.task_list.id);
5904
5905            $("#task_list_id").val(response.task_list.id);
5906            $("#task_list_project").val(response.task_list.project.title);
5907            $("#task_list_name").val(response.task_list.name);
5908            var projectData = {
5909                id: response.task_list.project.id, // Ensure this matches your project's ID field
5910                text: response.task_list.project.title, // Ensure this matches your project's title field
5911            };
5912
5913            var $projectSelect = $("#task_list_project_id");
5914            $projectSelect.empty().append(new Option(projectData.text, projectData.id, true, true)).trigger("change");
5915        },
5916    });
5917});
5918
5919// Show the Active Tab
5920document.querySelectorAll('[data-bs-toggle="tab"]').forEach(function (button) {
5921    button.addEventListener("click", function () {
5922        // Check if the clicked button has the "list-button" or "calendar-button" class
5923        if (
5924            this.classList.contains("list-button") ||
5925            this.classList.contains("calendar-button")
5926        ) {
5927            // Remove bg-primary and text-white from "List" and "Calendar" buttons only
5928            document
5929                .querySelectorAll(".list-button, .calendar-button")
5930                .forEach(function (specificButton) {
5931                    specificButton.classList.remove("bg-primary", "text-white");
5932                });
5933
5934            // Add bg-primary and text-white to the clicked button
5935            this.classList.add("bg-primary", "text-white");
5936        }
5937
5938        // Handle nested tabs
5939        const parentPane = document.querySelector(this.dataset.bsTarget);
5940        if (parentPane) {
5941            parentPane
5942                .querySelectorAll(".list-button, .calendar-button")
5943                .forEach(function (subTab) {
5944                    subTab.classList.remove("bg-primary", "text-white");
5945                });
5946
5947            const activeSubTab = parentPane.querySelector(
5948                ".list-button.active, .calendar-button.active"
5949            );
5950            if (activeSubTab) {
5951                activeSubTab.classList.add("bg-primary", "text-white");
5952            }
5953        }
5954    });
5955});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.