@@ -388,41 +388,6 @@ function app_link_reset(evt) {
388388 })
389389 }
390390
391- function toggle_expiration_controls(metaKey) {
392- const neverExpiresCheckbox = document.getElementById('app-expiration-never-' + metaKey);
393- const amountInput = document.getElementById('app-expiration-amount-' + metaKey);
394- const timeUnitSelect = document.getElementById('app-expiration-time-unit-' + metaKey);
395-
396- if (neverExpiresCheckbox && amountInput && timeUnitSelect) {
397- const isChecked = neverExpiresCheckbox.checked;
398- amountInput.disabled = isChecked;
399- timeUnitSelect.disabled = isChecked;
400-
401- // Clear values when disabled
402- if (isChecked) {
403- amountInput.value = '';
404- timeUnitSelect.value = 'days';
405- }
406- }
407- }
408-
409- // Initialize expiration controls on page load
410- function initialize_expiration_controls() {
411- const checkboxes = document.querySelectorAll('input[id^="app-expiration-never-"]');
412- checkboxes.forEach(function(checkbox) {
413- const metaKey = checkbox.getAttribute('data-meta-key') || checkbox.id.replace('app-expiration-never-', '');
414- toggle_expiration_controls(metaKey);
415- });
416- }
417-
418- // Run initialization when DOM is ready
419- if (document.readyState === 'loading') {
420- document.addEventListener('DOMContentLoaded', initialize_expiration_controls);
421- } else {
422- // DOM is already ready
423- initialize_expiration_controls();
424- }
425-
426391 function clear_expiration_after_reset(metaKey, id, sysType) {
427392 if (!window.wpApiShare) return;
428393
@@ -454,17 +419,13 @@ function clear_expiration_after_reset(metaKey, id, sysType) {
454419 if (expirationDisplay) {
455420 expirationDisplay.textContent = '---';
456421 }
457-
458- // Uncheck "Never expires" checkbox
459- const neverExpiresCheckbox = document.getElementById('app-expiration-never-' + metaKey);
460- if (neverExpiresCheckbox) {
461- neverExpiresCheckbox.checked = false;
462- toggle_expiration_controls(metaKey);
463- }
464-
465- // Remove expiration badge if it exists
422+
423+ // Remove expiration badge and clear data attributes
466424 const appAccordion = document.querySelector('.app-accordion.' + metaKey);
467425 if (appAccordion) {
426+ appAccordion.dataset.expiresTs = '';
427+ appAccordion.dataset.expiresFormatted = '---';
428+ appAccordion.dataset.expiresFormattedShort = '';
468429 const badge = appAccordion.querySelector('.app-expiration-badge');
469430 if (badge) {
470431 badge.remove();
@@ -506,11 +467,10 @@ function app_link_set_expiration(evt) {
506467 const metaKey = key;
507468 const expirationAmount = document.getElementById('app-expiration-amount-' + metaKey).value;
508469 const expirationTimeUnit = document.getElementById('app-expiration-time-unit-' + metaKey).value;
509- const neverExpires = document.getElementById('app-expiration-never-' + metaKey).checked;
510470
511- // Validate input
512- if (!neverExpires && (! expirationAmount || expirationAmount <= 0) ) {
513- alert('<?php echo esc_js ( __ ( 'Please enter a valid expiration amount or select "Never expires" . ' , 'disciple_tools ' ) ) ?> ');
471+ // Validate input (amount and unit required)
472+ if (!expirationAmount || parseInt( expirationAmount, 10) <= 0 || !expirationTimeUnit ) {
473+ alert('<?php echo esc_js ( __ ( 'Please enter a valid expiration amount and time unit . ' , 'disciple_tools ' ) ) ?> ');
514474 return;
515475 }
516476
@@ -522,9 +482,8 @@ function app_link_set_expiration(evt) {
522482 const payload = {
523483 meta_key: metaKey,
524484 sys_type: sys_type,
525- links_expire_within_amount: neverExpires ? '' : expirationAmount,
526- links_expire_within_time_unit: neverExpires ? '' : expirationTimeUnit,
527- links_never_expires: neverExpires ? 'true' : 'false'
485+ links_expire_within_amount: expirationAmount,
486+ links_expire_within_time_unit: expirationTimeUnit
528487 };
529488
530489 // Add id based on sys_type
@@ -553,32 +512,40 @@ function app_link_set_expiration(evt) {
553512 },
554513 success: function(data) {
555514 if (data && data.success) {
556- // Update expiration display
515+ // Update expiration display (full date inside accordion)
557516 const expirationDisplay = document.getElementById('app-expiration-display-' + metaKey);
558517 if (data.expires) {
559- const formatted = data.expires.ts_formatted || '<?php echo esc_js ( __ ( 'Never ' , 'disciple_tools ' ) ) ?> ';
560- expirationDisplay.textContent = formatted;
561-
518+ const formatted = data.expires.ts_formatted || '---';
519+ if (expirationDisplay) {
520+ expirationDisplay.textContent = formatted;
521+ }
522+
562523 // Update data attributes
563524 appAccordion.dataset.expiresTs = data.expires.ts || '';
564525 appAccordion.dataset.expiresFormatted = data.expires.ts_formatted || '---';
565-
566- // Update summary badge if it exists
526+ appAccordion.dataset.expiresFormattedShort = data.expires.ts_formatted_short || '';
527+
528+ // Update or create summary badge with short format (Exp: M/D/YY H:mm)
529+ const shortFormatted = data.expires.ts_formatted_short || '';
567530 const badge = appAccordion.querySelector('.app-expiration-badge');
568- if (badge) {
569- badge.textContent = formatted !== '<?php echo esc_js ( __ ( 'Never ' , 'disciple_tools ' ) ) ?> ' ?
570- ('<?php echo esc_js ( __ ( 'Expires: ' , 'disciple_tools ' ) ) ?> ' + formatted) :
571- '<?php echo esc_js ( __ ( 'Never expires ' , 'disciple_tools ' ) ) ?> ';
572- } else if (formatted !== '<?php echo esc_js ( __ ( 'Never ' , 'disciple_tools ' ) ) ?> ') {
573- // Create badge if it doesn't exist
574- const appLabel = appAccordion.querySelector('.app-label');
531+ if (shortFormatted) {
532+ const badgeText = '<?php echo esc_js ( __ ( 'Exp: ' , 'disciple_tools ' ) ) ?> ' + shortFormatted;
533+ if (badge) {
534+ badge.textContent = badgeText;
535+ } else {
536+ const appLabel = appAccordion.querySelector('.app-label');
575537 if (appLabel) {
576538 const newBadge = document.createElement('span');
577539 newBadge.className = 'app-expiration-badge';
578- newBadge.style.cssText = 'font-size: 0.85em; color: #666; margin-left: 0.5rem;';
579- newBadge.textContent = '<?php echo esc_js ( __ ( 'Expires: ' , 'disciple_tools ' ) ) ?> ' + formatted;
580- appLabel.appendChild(newBadge);
540+ newBadge.style.cssText = 'font-size: 0.85em; color: #666; margin-top: 0.25rem;';
541+ newBadge.textContent = badgeText;
542+ // Insert under the title (after first child)
543+ const insertBefore = appLabel.children[1] || null;
544+ appLabel.insertBefore(newBadge, insertBefore);
581545 }
546+ }
547+ } else if (badge) {
548+ badge.remove();
582549 }
583550 }
584551
@@ -641,8 +608,7 @@ private function add_app_row( $post, $app, $enabled = true ) {
641608 $ expiration_data = [
642609 'ts ' => '' ,
643610 'ts_formatted ' => '--- ' ,
644- 'ts_base ' => '' ,
645- 'links_never_expires ' => false
611+ 'ts_base ' => ''
646612 ];
647613 $ post_id = isset ( $ post ['ID ' ] ) ? $ post ['ID ' ] : get_the_ID ();
648614 $ sys_type = $ user_id ? 'wp_user ' : 'post ' ;
@@ -664,19 +630,12 @@ private function add_app_row( $post, $app, $enabled = true ) {
664630 }
665631
666632 // Fetch expiration using unified wrapper (checks meta first, then link_obj)
667- $ expiration_data_result = Disciple_Tools_Bulk_Magic_Link_Sender_API::capture_expiry_details (
633+ $ expiration_data = Disciple_Tools_Bulk_Magic_Link_Sender_API::capture_expiry_details (
668634 $ meta_key ,
669635 $ record_id ,
670636 $ sys_type ,
671637 $ matching_link_obj
672638 );
673-
674- // Also fetch full expiration data to get links_never_expires flag
675- $ full_expiration_data = Disciple_Tools_Bulk_Magic_Link_Sender_API::fetch_link_expiration_from_meta ( $ meta_key , $ record_id , $ sys_type );
676-
677- $ expiration_data = array_merge ( $ expiration_data_result , [
678- 'links_never_expires ' => $ full_expiration_data ['links_never_expires ' ] ?? false
679- ] );
680639 }
681640 ?>
682641 <details class="app-accordion <?php echo esc_attr ( $ meta_key ); ?> "
@@ -692,23 +651,29 @@ private function add_app_row( $post, $app, $enabled = true ) {
692651 data-record-id="<?php echo esc_attr ( $ record_id ) ?> "
693652 data-expires-ts="<?php echo esc_attr ( $ expiration_data ['ts ' ] ?? '' ) ?> "
694653 data-expires-formatted="<?php echo esc_attr ( $ expiration_data ['ts_formatted ' ] ?? '--- ' ) ?> "
654+ data-expires-formatted-short="<?php echo esc_attr ( ! empty ( $ expiration_data ['ts ' ] ) ? date_i18n ( 'n/j/y G:i ' , (int ) $ expiration_data ['ts ' ] ) : '' ) ?> "
695655 >
696656 <summary class="app-summary">
697- <div class="app-label"><?php echo esc_html ( $ app ['label ' ] ) ?>
698- <?php if ( !empty ( $ expiration_data ) && !empty ( $ expiration_data ['ts_formatted ' ] ) && $ expiration_data ['ts_formatted ' ] !== '--- ' ): ?>
699- <span class="app-expiration-badge" style="font-size: 0.85em; color: #666; margin-left: 0.5rem;">
700- <?php echo esc_html ( sprintf ( __ ( 'Expires: %s ' , 'disciple_tools ' ), $ expiration_data ['ts_formatted ' ] ) ) ?>
701- </span>
702- <?php endif ; ?>
703- <?php if ( !empty ( $ app ['description ' ] ) ): ?>
704- <div class="dt-tooltip">
705- <span class="tooltiptext"><?php echo esc_attr ( $ app ['description ' ] ) ?> </span>
706- <img class="help-icon app-description-tooltip"
707- src="<?php echo esc_url ( get_template_directory_uri () . '/dt-assets/images/help.svg ' ) ?> "
708- title="<?php echo esc_attr ( $ app ['description ' ] ) ?> "
709- />
710- </div>
711- <?php endif ; ?>
657+ <div class="app-label" style="display: flex; flex-direction: column; align-items: flex-start;">
658+ <span class="app-label-title"><?php echo esc_html ( $ app ['label ' ] ) ?> </span>
659+ <?php
660+ $ exp_ts = $ expiration_data ['ts ' ] ?? '' ;
661+ $ exp_short = ! empty ( $ exp_ts ) ? date_i18n ( 'n/j/y G:i ' , (int ) $ exp_ts ) : '' ;
662+ if ( ! empty ( $ exp_short ) ) :
663+ ?>
664+ <span class="app-expiration-badge" style="font-size: 0.85em; color: #666; margin-top: 0.25rem;">
665+ <?php echo esc_html ( sprintf ( __ ( 'Exp: %s ' , 'disciple_tools ' ), $ exp_short ) ) ?>
666+ </span>
667+ <?php endif ; ?>
668+ <?php if ( !empty ( $ app ['description ' ] ) ): ?>
669+ <div class="dt-tooltip" style="margin-top: 0.25rem;">
670+ <span class="tooltiptext"><?php echo esc_attr ( $ app ['description ' ] ) ?> </span>
671+ <img class="help-icon app-description-tooltip"
672+ src="<?php echo esc_url ( get_template_directory_uri () . '/dt-assets/images/help.svg ' ) ?> "
673+ title="<?php echo esc_attr ( $ app ['description ' ] ) ?> "
674+ />
675+ </div>
676+ <?php endif ; ?>
712677 </div>
713678
714679 <a class="app-link dt-action-button small button view"
@@ -782,25 +747,25 @@ class="dt-action-button small button qr"
782747 </div>
783748 <div class="app-link-row">
784749 <a data-tooltip
785- title="<?php esc_html_e ( 'Reset ' , 'disciple_tools ' ) ?> "
750+ title="<?php esc_html_e ( 'Reset link ' , 'disciple_tools ' ) ?> "
786751 type="button"
787752 onclick="app_link_reset(event)"
788753 class="dt-action-button small button reset"
789754 ><img class="dt-icon" alt="undo" src="<?php echo esc_url ( get_template_directory_uri () . '/dt-assets/images/undo.svg ' ) ?> " /></a>
790- <span class="app-link-label"><?php esc_html_e ( 'Reset link ' , 'disciple_tools ' ) ?> </span>
755+ <span class="app-link-label"><?php esc_html_e ( 'Reset link (also clears expiration) ' , 'disciple_tools ' ) ?> </span>
791756 </div>
792757 <?php if ( class_exists ( 'Disciple_Tools_Bulk_Magic_Link_Sender_API ' ) ): ?>
793758 <div class="app-link-row" style="margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #e0e0e0;">
794759 <div style="display: flex; flex-direction: column; gap: 0.75rem; width: 100%; box-sizing: border-box;">
795760 <div style="display: flex; align-items: center; gap: 0.5rem;">
796761 <label style="font-weight: bold; min-width: 120px;"><?php esc_html_e ( 'Link Expiration ' , 'disciple_tools ' ) ?> :</label>
797762 <span id="app-expiration-display-<?php echo esc_attr ( $ meta_key ) ?> " style="flex-grow: 1;">
798- <?php echo esc_html ( $ expiration_data ['ts_formatted ' ] ?? __ ( ' Never ' , ' disciple_tools ' ) ) ?>
763+ <?php echo esc_html ( $ expiration_data ['ts_formatted ' ] ?? ' --- ' ) ?>
799764 </span>
800765 </div>
801766 <div style="display: flex; align-items: center; gap: 0.5rem; width: 100%; box-sizing: border-box;">
802- <input type="number"
803- id="app-expiration-amount-<?php echo esc_attr ( $ meta_key ) ?> "
767+ <input type="number"
768+ id="app-expiration-amount-<?php echo esc_attr ( $ meta_key ) ?> "
804769 placeholder="<?php esc_attr_e ( 'Amount ' , 'disciple_tools ' ) ?> "
805770 style="flex: 2; min-width: 0; box-sizing: border-box;"
806771 min="1"
@@ -813,23 +778,6 @@ class="dt-action-button small button reset"
813778 <option value="months"><?php esc_html_e ( 'Months ' , 'disciple_tools ' ) ?> </option>
814779 </select>
815780 </div>
816- <div style="display: flex; align-items: center; gap: 0.25rem;">
817- <?php
818- // Check if expiration is explicitly set to "Never" (only check if links_never_expires is true)
819- $ is_never_expires = ( $ expiration_data ['links_never_expires ' ] === true ||
820- $ expiration_data ['ts_formatted ' ] === __ ( 'Never ' , 'disciple_tools ' ) ||
821- $ expiration_data ['ts_formatted ' ] === 'Never ' );
822- ?>
823- <input type="checkbox"
824- id="app-expiration-never-<?php echo esc_attr ( $ meta_key ) ?> "
825- style="margin: 0; vertical-align: middle;"
826- onchange="toggle_expiration_controls('<?php echo esc_js ( $ meta_key ) ?> ')"
827- <?php echo $ is_never_expires ? 'checked ' : '' ; ?>
828- data-meta-key="<?php echo esc_attr ( $ meta_key ) ?> ">
829- <label for="app-expiration-never-<?php echo esc_attr ( $ meta_key ) ?> " style="display: flex; align-items: center; margin: 0; vertical-align: middle;">
830- <?php esc_html_e ( 'Never expires ' , 'disciple_tools ' ) ?>
831- </label>
832- </div>
833781 <button type="button"
834782 class="button small"
835783 onclick="app_link_set_expiration(event)"
0 commit comments