Skip to main content

Option to display exact ticket date and time instead of relative time

Fluent Support currently does not provide a setting to change date display from relative time, such as "2 hours ago" or "5 days ago", to an exact date and time.

It would be very useful to add an option for absolute date/time display, so admins can see the exact creation or update date and time of a ticket instead of relative time.

Joachim Meyer

This would be very helpful for me, too.

Roelinde Brons

I created a snippet (Dutch) that adds a red or green β€˜status’ at each ticket with the last communication β€˜timestemp’.

Not exactly time, but:

Green: team is waiting for 3 days

Red: clients is waiting for 20 min

Red means action for us, green β€˜we can kind of relax’

The snippet:

add_action('admin_footer', function () {

if (empty($_GET['page']) || $_GET['page'] !== 'fluent-support') {
    return;
}

?>

<style>
    .swp-response-badges {
        display: flex;
        gap: 6px;
        justify-content: flex-end;
        margin-top: 6px;
        flex-wrap: wrap;
    }

    .swp-response-badge {
        font-size: 11px;
        padding: 4px 7px;
        border-radius: 999px;
        font-weight: 600;
        white-space: nowrap;
    }

    .swp-response-badge.customer-waits {
        background: #fee2e2;
        color: #991b1b;
    }

    .swp-response-badge.team-waits {
        background: #dcfce7;
        color: #166534;
    }
</style>

<script>
(function () {

    function timeAgo(dateString) {
        if (!dateString) return null;

        const date = new Date(dateString.replace(' ', 'T'));
        const seconds = Math.floor((new Date() - date) / 1000);

        if (isNaN(seconds)) return dateString;
        if (seconds < 60) return 'net';
        if (seconds < 3600) return Math.floor(seconds / 60) + 'm geleden';
        if (seconds < 86400) return Math.floor(seconds / 3600) + 'u geleden';

        return Math.floor(seconds / 86400) + 'd geleden';
    }

    function toDate(dateString) {
        if (!dateString) return null;

        const date = new Date(dateString.replace(' ', 'T'));
        return isNaN(date.getTime()) ? null : date;
    }

    function getTicketMap() {
        try {
            const tickets = window.fluentSupportAppp.$pinia.state.value.ticketList.tickets || [];
            const map = {};

            tickets.forEach(function(ticket) {
                map[String(ticket.id)] = ticket;
            });

            return map;
        } catch (e) {
            return {};
        }
    }

    function getTicketId(item) {
        const text = item.innerText || '';
        const match = text.match(/#(\d+)/);

        return match ? match[1] : null;
    }

    function isClosedTicket(ticket) {
        const status = String(ticket.status || '').toLowerCase();
        return status === 'closed';
    }

    function renderBadges() {
        const ticketMap = getTicketMap();

        document.querySelectorAll('.fs_ticket_item').forEach(function(item) {
            const existing = item.querySelector('.swp-response-badges');

            if (existing) {
                existing.remove();
            }

            const ticketId = getTicketId(item);

            if (!ticketId || !ticketMap[ticketId]) {
                return;
            }

            const ticket = ticketMap[ticketId];

            if (isClosedTicket(ticket)) {
                return;
            }

            const customerDate = toDate(ticket.last_customer_response);
            const agentDate = toDate(ticket.last_agent_response);

            const customerTime = timeAgo(ticket.last_customer_response);
            const agentTime = timeAgo(ticket.last_agent_response);

            if (!customerDate && !agentDate) {
                return;
            }

            const wrap = document.createElement('div');
            wrap.className = 'swp-response-badges';

            if (customerDate && (!agentDate || customerDate > agentDate)) {
                const badge = document.createElement('span');

                badge.className = 'swp-response-badge customer-waits';
                badge.title = 'Laatste reactie klant: ' + ticket.last_customer_response;
                badge.textContent = 'Klant wacht: ' + customerTime;

                wrap.appendChild(badge);
            }

            if (agentDate && (!customerDate || agentDate > customerDate)) {
                const badge = document.createElement('span');

                badge.className = 'swp-response-badge team-waits';
                badge.title = 'Laatste reactie team: ' + ticket.last_agent_response;
                badge.textContent = 'Team wacht: ' + agentTime;

                wrap.appendChild(badge);
            }

            const target = item.querySelector('.fs_ticket_right_section') || item;
            target.appendChild(wrap);
        });
    }

    setInterval(renderBadges, 1000);

})();
</script>

<?php

});