` state from Admin.php — confirmed via grep * before extraction, so this is a clean lift, not a rewrite. The enqueued filenames * changed (js/dashboard.js -> js/post-import-feedback.js, css/dashboard-style.css -> * css/post-import-feedback-style.css) to match the renamed webpack entry (spec 027's * own Build Artifacts note); the WordPress script/style HANDLE and the localized JS * global variable name both stay 'templately' — react-src's widget entry reads * `window.templately` directly, so renaming either would break data delivery. * * FR-005 rolling 30-day cooldown (2026-07-16): eligibility used to be a one-shot * `$is_complete !== 'done'` check (no expiry once dismissed). It is now * time-boxed via `is_eligible()` — see that method's docblock for the migration * handling of the old no-expiry `'done'` sentinel. * * @package Templately */ namespace Templately\Modules\PostImportFeedback; use Templately\Utils\Options; class Widget { /** * User-meta key holding the Unix timestamp of the last time this user * submitted or dismissed the feedback widget. Drives the FR-005 30-day * rolling cooldown, replacing the old no-expiry `'done'` sentinel * previously stored (and still legacy-read) in `templately_fsi_complete`. */ const LAST_SHOWN_META = 'templately_feedback_last_shown'; /** FR-005 cooldown window: 30 days. */ const COOLDOWN_SECONDS = 30 * DAY_IN_SECONDS; public function enqueue( $hook = '' ) { if ( 'index.php' !== $hook ) { return; } if ( ! self::is_eligible() || wp_is_mobile() ) { return; } $user = Options::get_instance()->get( 'user' ); $email = isset( $user['email'] ) ? $user['email'] : ''; templately()->assets->enqueue( 'templately', 'css/post-import-feedback-style.css', [] ); templately()->assets->enqueue( 'templately', 'js/post-import-feedback.js', [], true ); templately()->assets->localize( 'templately', 'templately', [ 'email' => $email, 'nonce' => wp_create_nonce( 'templately_nonce' ), ] ); } public function render_mount_point() { global $current_screen; if ( ! $current_screen ) { return false; } if ( $current_screen->id !== 'dashboard' ) { return false; } if ( self::is_eligible() && ! wp_is_mobile() ) : ?>
= self::COOLDOWN_SECONDS; } }