HEX
Server: LiteSpeed
System: Linux oxygen.shetabanhost.com 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User: rasapedi (1695)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/rasapedi/public_html/wp-content/plugins/post-views-counter/js/column-modal.js
/**
 * Post Views Counter - Column Modal Chart
 */
( function( $ ) {
	'use strict';

	// check if jQuery is available
	if ( typeof $ === 'undefined' )
		return;

	let pvcModalChart = null;
	let currentPostId = null;

	// check if localized data is available
	if ( typeof pvcColumnModal === 'undefined' )
		return;

	/**
	 * Initialize Micromodal
	 */
	function initMicromodal() {
		if ( typeof MicroModal === 'undefined' )
			return false;

		// initialize with basic config
		MicroModal.init( {
			disableScroll: true,
			awaitCloseAnimation: true
		} );

		return true;
	}

	/**
	 * Prepare modal for specific post
	 */
	function prepareModalForPost( postId, postTitle ) {
		if ( ! postId )
			return false;

		currentPostId = postId;

		// set modal title
		$( '#pvc-modal-title' ).text( postTitle );

		// show loading state
		const $container = $( '.pvc-modal-chart-container' );
		$container.addClass( 'loading' );
		$container.find( '.spinner' ).addClass( 'is-active' );

		// clear previous content
		$( '.pvc-modal-views-label' ).text( '' );
		$( '.pvc-modal-count' ).text( '' );
		$( '.pvc-modal-dates' ).html( '' );

		return true;
	}

	function resetModalContent() {
		$( '#pvc-modal-title' ).text( '' );
		$( '.pvc-modal-views-label' ).text( '' );
		$( '.pvc-modal-count' ).text( '' );
		$( '.pvc-modal-dates' ).html( '' );

		const $container = $( '.pvc-modal-chart-container' );
		$container.removeClass( 'loading' );
		$container.find( '.spinner' ).removeClass( 'is-active' );

		// remove any error messages
		$( '.pvc-modal-error' ).remove();
	}

	/**
	 * Load chart data via AJAX
	 */
	function loadChartData( postId, period ) {
		const $container = $( '.pvc-modal-chart-container' );

		// show loading
		$container.addClass( 'loading' );
		$container.find( '.spinner' ).addClass( 'is-active' );

		$.ajax( {
			url: pvcColumnModal.ajaxURL,
			type: 'POST',
			dataType: 'json',
			data: {
				action: 'pvc_column_chart',
				nonce: pvcColumnModal.nonce,
				post_id: postId,
				period: period
			},
			success: function( response ) {
				if ( response.success ) {
					renderChart( response.data );
				} else {
					showError( response.data.message || pvcColumnModal.i18n.error );
				}
			},
			error: function( xhr, status, error ) {
				showError( pvcColumnModal.i18n.error );
			},
			complete: function() {
				$container.removeClass( 'loading' );
				$container.find( '.spinner' ).removeClass( 'is-active' );
			}
		} );
	}

	/**
	 * Render chart with data
	 */
	function renderChart( data ) {
		const ctx = document.getElementById( 'pvc-modal-chart' );

		if ( ! ctx )
			return;

		// destroy existing chart
		if ( pvcModalChart ) {
			pvcModalChart.destroy();
			pvcModalChart = null;
		}

		// remove any error messages and show canvas
		$( '.pvc-modal-error' ).remove();
		$( ctx ).show();

		// update stats
		$( '.pvc-modal-views-label' ).text( pvcColumnModal.i18n.summary );
		$( '.pvc-modal-count' ).text( data.total_views.toLocaleString() );

		// update date navigation
		$( '.pvc-modal-dates' ).html( data.dates_html );

		/* debug logging (admins only) - shows views keys returned from AJAX
		if ( typeof console !== 'undefined' && data.debug_views_keys ) {
			console.debug( 'PVC debug: views keys for post ' + data.post_id + ':', data.debug_views_keys );
			console.debug( 'PVC debug: views sample by keys:', data.debug_views );
			console.debug( 'PVC debug: example date_key used by client:', data.debug_date_key_example );
		}

		if ( typeof console !== 'undefined' && data.data ) {
			console.debug( 'PVC debug: chart data object', data.data );
			console.debug( 'PVC debug: dataset length', data.data.datasets && data.data.datasets[0] ? data.data.datasets[0].data.length : 0 );
		}
		*/

		// chart configuration
		const config = {
			type: 'line',
			data: data.data,
			options: {
				maintainAspectRatio: false,
				responsive: true,
				plugins: {
					legend: {
						display: false
					},
					tooltip: {
						callbacks: {
							title: function( context ) {
								return data.data.dates[context[0].dataIndex];
							},
							label: function( context ) {
								const count = context.parsed.y;
								const viewText = count === 1 ? pvcColumnModal.i18n.view : pvcColumnModal.i18n.views;
								return count.toLocaleString() + ' ' + viewText;
							}
						}
					}
				},
				scales: {
					x: {
						display: true,
						grid: {
							display: false
						}
					},
					y: {
						display: true,
						beginAtZero: true,
						ticks: {
							precision: 0
						},
						grid: {
							color: 'rgba(0, 0, 0, 0.05)'
						}
					}
				}
			}
		};

		// apply design from server
		if ( data.design ) {
			config.data.datasets.forEach( function( dataset ) {
				Object.assign( dataset, data.design );
				dataset.tension = 0.4; // match dashboard curve
			} );
		}

		// create chart
		pvcModalChart = new Chart( ctx.getContext( '2d' ), config );
	}

	/**
	 * Show error message without destroying modal structure
	 */
	function showError( message ) {
		// destroy existing chart
		if ( pvcModalChart ) {
			pvcModalChart.destroy();
			pvcModalChart = null;
		}

		// reset states
		$( '.pvc-modal-summary' ).text( '' );
		$( '.pvc-modal-dates' ).html( '' );

		const $container = $( '.pvc-modal-chart-container' );
		$container.removeClass( 'loading' );
		$container.find( '.spinner' ).removeClass( 'is-active' );

		// remove any existing error message
		$( '.pvc-modal-error' ).remove();

		// inject error message before chart container
		$container.before( '<p class="pvc-modal-error">' + message + '</p>' );

		// hide canvas during error
		$container.find( 'canvas' ).hide();
	}

	/**
	 * Document ready
	 */
	$( function() {
		// check if modal HTML exists
		if ( $( '#pvc-chart-modal' ).length === 0 )
			return;

		// initialize Micromodal
		if ( ! initMicromodal() )
			return;

		// handle click on view chart link
		$( document ).on( 'click', '.pvc-view-chart', function( e ) {
			e.preventDefault();

			const postId = $( this ).data( 'post-id' );
			const postTitle = $( this ).data( 'post-title' );

			if ( ! postId )
				return;

			// prepare modal with post data
			if ( prepareModalForPost( postId, postTitle ) ) {
				// open modal using MicroModal with callbacks
				if ( typeof MicroModal !== 'undefined' ) {
					MicroModal.show( 'pvc-chart-modal', {
						onShow: function( modal ) {
							if ( currentPostId )
								loadChartData( currentPostId, '' );
						},
						onClose: function() {
							// destroy chart when modal closes
							if ( pvcModalChart ) {
								pvcModalChart.destroy();
								pvcModalChart = null;
							}

							currentPostId = null;

							// reset modal content
							resetModalContent();
						},
						disableScroll: true,
						awaitCloseAnimation: true
					} );
				}
			}
		} );

		// handle period navigation
		$( document ).on( 'click', '.pvc-modal-nav-prev, .pvc-modal-nav-next', function( e ) {
			e.preventDefault();

			// check if disabled
			if ( $( this ).hasClass( 'pvc-disabled' ) )
				return;

			const period = $( this ).data( 'period' );

			if ( period && currentPostId ) {
				loadChartData( currentPostId, period );
			}
		} );
	} );

} )( jQuery );