/
home
/
altere25
/
.trash
/
wp-to-sanity-companion.1
/
assets
/
js
/
/home/altere25/.trash/wp-to-sanity-companion.1/assets/js
mkdir
upload
Name
Size
Mode
Actions
admin.js
16906
0644
edit
dl
rm
claude-connect.js
6502
0644
edit
dl
rm
Edit:
/home/altere25/.trash/wp-to-sanity-companion.1/assets/js/admin.js
(16906B)
/** * Altered Digital Migration — admin JS * * - ADProgress class: real-time polling of Worker /v2/migrations. * - updateSlug gated to plugin settings pages only (no global post-editor * side effect — the classic editor already has its own slug UI). * - wpToSanitySyncPost kept for the meta-box "Sync to Sanity" button. * - wpToSanityRegenerateSecret kept. * * Dead v1 code removed: pollMigrationStatus, updateMigrationMetaBox, * wpToSanityTrackProgress, showNotification, export/status polling (the * vestigial migration_queue table no longer exists). */ (function($) { 'use strict'; var W = window.wpToSanity = window.wpToSanity || {}; // ----------------------------------------------------------------- // Regenerate webhook secret (settings page) // ----------------------------------------------------------------- W.wpToSanityRegenerateSecret = function() { if (!confirm('Regenerate the webhook secret? You will need to update your Worker configuration.')) { return; } var newSecret = ''; var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; for (var i = 0; i < 32; i++) { newSecret += chars.charAt(Math.floor(Math.random() * chars.length)); } // Both v1 + v2 option names accept the value; the active input has // name="ad_settings[webhook_secret]" on v2. $('input[name="ad_settings[webhook_secret]"], input[name="wp_to_sanity_settings[webhook_secret]"]').val(newSecret); }; // ----------------------------------------------------------------- // Sync-now button (meta box on post-edit screen) // ----------------------------------------------------------------- W.wpToSanitySyncPost = function(postId) { $.ajax({ url: W.restUrl + 'export', method: 'POST', headers: { 'X-WP-Nonce': W.restNonce }, data: { post_id: postId }, success: function(resp) { if (resp && resp.success) { alert('Sync triggered. Status will update shortly.'); } else { alert('Sync failed: ' + (resp && resp.error ? resp.error : 'unknown error')); } }, error: function() { alert('Sync request failed.'); } }); }; // ----------------------------------------------------------------- // Slug helper — gated to plugin settings pages only. // The classic editor already manages its own slug; running this on // every post_title input was a v1 side-effect that overwrote user // slugs. Now it only runs when an AD settings field with // name="post_name" exists (rare; left for back-compat). // ----------------------------------------------------------------- function maybeUpdateSlug() { if (!W || !W.restUrl) { return; } // Only on a plugin settings page that exposes a post_name input. if (!$('input[name="post_name"]').length) { return; } if (!$('body').hasClass('wp-to-sanity_page_wp-to-sanity-settings') && !$('body').hasClass('toplevel_page_wp-to-sanity')) { return; } var title = $('input[name="post_title"]').val(); if (!title) { return; } var slug = title.toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim(); $('input[name="post_name"]').val(slug); } $(document).on('input', 'input[name="post_title"]', maybeUpdateSlug); // ----------------------------------------------------------------- // ADProgress — real-time migration progress // ----------------------------------------------------------------- function ADProgress() { this.pollMs = 5000; this.timer = null; } ADProgress.prototype.start = function() { var self = this; this.tick(); this.timer = setInterval(function() { self.tick(); }, this.pollMs); }; ADProgress.prototype.stop = function() { if (this.timer) { clearInterval(this.timer); this.timer = null; } }; ADProgress.prototype.tick = function() { if (!W || !W.restUrl) { return; } var self = this; $.ajax({ url: W.restUrl + 'progress', method: 'GET', headers: { 'X-WP-Nonce': W.restNonce }, success: function(resp) { if (resp && resp.success && resp.data) { self.render(resp.data); } }, error: function() { // Worker unreachable — leave last-known state in place. } }); }; ADProgress.prototype.render = function(data) { var stats = data.stats || {}; var total = parseInt(stats.total || 0, 10); var success = parseInt(stats.success || 0, 10); var pending = parseInt(stats.pending || 0, 10); var failed = parseInt(stats.failed || 0, 10); $('#ad-stat-total').text(total); $('#ad-stat-success').text(success); $('#ad-stat-pending').text(pending); $('#ad-stat-failed').text(failed); var pct = total > 0 ? Math.round((success / total) * 100) : 0; $('#ad-progress-fill').css('width', pct + '%'); $('#ad-progress-pct').text(pct + '%'); var recent = data.recent || []; var $tbody = $('#ad-progress-table tbody'); if (!$tbody.length) { return; } if (!recent.length) { $tbody.html('<tr class="ad-empty-row"><td colspan="5"><span class="description">No migrations yet.</span></td></tr>'); return; } var rows = ''; for (var i = 0; i < recent.length; i++) { var r = recent[i]; rows += '<tr>' + '<td>' + (r.post_id || '') + '</td>' + '<td>' + (r.action || '') + '</td>' + '<td><span class="status-badge ' + (r.status === 'success' ? 'success' : (r.status === 'failed' ? 'error' : 'pending')) + '">' + (r.status || '') + '</span></td>' + '<td><code>' + (r.sanity_id || '') + '</code></td>' + '<td>' + (r.updated_at || r.created_at || '') + '</td>' + '</tr>'; } $tbody.html(rows); }; $(function() { if ($('#ad-progress-table').length) { new ADProgress().start(); } }); // Expose for any future dashboard widget. W.ADProgress = ADProgress; // ----------------------------------------------------------------- // Wizard (onboarding-v2) — Phase B shell only. // Phase C wires the real flows; here we just advance panels. // ----------------------------------------------------------------- $(function() { if (!$('.ad-wizard-steps').length) { return; } function showPanel(n) { $('.ad-wizard-panel').attr('hidden', true); $('.ad-wizard-panel[data-panel="' + n + '"]').removeAttr('hidden'); $('.ad-wizard-steps li').removeClass('active'); $('.ad-wizard-steps li[data-step="' + n + '"]').addClass('active'); } // Login submit → Supabase auth via AD_Auth::login(). $('#ad-login-form').on('submit', function(e) { e.preventDefault(); var $form = $(this); var $status = $('#ad-login-status').removeAttr('hidden') .text('Signing in…').css('color', '#555'); $.ajax({ url: W.restUrl + 'auth/login', method: 'POST', headers: { 'X-WP-Nonce': W.restNonce }, data: { email: $form.find('input[name="email"]').val(), password: $form.find('input[name="password"]').val() }, success: function(resp) { if (resp && resp.success) { showPanel(2); } else { var msg = (resp && resp.data && resp.data.error) ? resp.data.error : (resp && resp.error) ? resp.error : 'Login failed.'; $status.text(msg).css('color', '#d63638'); } }, error: function(xhr) { var msg = 'Login request failed'; try { var body = JSON.parse(xhr.responseText); if (body && body.data && body.data.error) { msg = body.data.error; } else if (body && body.message) { msg = body.message; } else if (body && body.error) { msg = body.error; } } catch (ex) { if (xhr.status) { msg += ' (HTTP ' + xhr.status + ')'; } if (xhr.responseText) { msg += ': ' + xhr.responseText.substring(0, 200); } } $status.text(msg).css('color', '#d63638'); } }); }); $('#ad-analyze-trigger').on('click', function() { var $btn = $(this).prop('disabled', true).text('Analyzing…'); showPanel(3); $('#ad-analyze-stage').text('Gathering site data…'); // Step 1: POST /analyze → returns analysis_id + analysis synchronously. $.ajax({ url: W.restUrl + 'analyze', method: 'POST', headers: { 'X-WP-Nonce': W.restNonce }, success: function(resp) { if (!resp || !resp.success) { var msg = (resp && resp.data && resp.data.error) ? resp.data.error : (resp && resp.error) ? resp.error : 'Analysis failed.'; $('#ad-analyze-stage').text('Error: ' + msg).css('color', '#d63638'); $btn.prop('disabled', false).text('Analyze my site'); return; } var analysisId = resp.data.analysis_id; var analysis = resp.data.analysis || {}; $('#ad-analyze-fill').css('width', '60%'); $('#ad-analyze-stage').text('Generating quote…'); // Step 2: POST /quote with the analysis_id. $.ajax({ url: W.restUrl + 'quote', method: 'POST', headers: { 'X-WP-Nonce': W.restNonce }, data: { analysis_id: analysisId, add_ons: [] }, success: function(qresp) { if (!qresp || !qresp.success) { var msg = (qresp && qresp.data && qresp.data.error) ? qresp.data.error : (qresp && qresp.error) ? qresp.error : 'Quote failed.'; $('#ad-analyze-stage').text('Error: ' + msg).css('color', '#d63638'); $btn.prop('disabled', false).text('Analyze my site'); return; } $('#ad-analyze-fill').css('width', '100%'); $('#ad-analyze-stage').text('Done!'); renderQuote(qresp.data); showPanel(4); }, error: function(xhr) { var msg = 'Quote request failed'; try { var body = JSON.parse(xhr.responseText); if (body && body.data && body.data.error) { msg = body.data.error; } else if (body && body.error) { msg = body.error; } } catch (ex) { if (xhr.status) { msg += ' (HTTP ' + xhr.status + ')'; } } $('#ad-analyze-stage').text('Error: ' + msg).css('color', '#d63638'); $btn.prop('disabled', false).text('Analyze my site'); } }); }, error: function(xhr) { var msg = 'Analysis request failed'; try { var body = JSON.parse(xhr.responseText); if (body && body.data && body.data.error) { msg = body.data.error; } else if (body && body.error) { msg = body.error; } } catch (ex) { if (xhr.status) { msg += ' (HTTP ' + xhr.status + ')'; } if (xhr.responseText) { msg += ': ' + xhr.responseText.substring(0, 200); } } $('#ad-analyze-stage').text('Error: ' + msg).css('color', '#d63638'); $btn.prop('disabled', false).text('Analyze my site'); } }); }); function centsToUsd(cents) { return '$' + (cents / 100).toFixed(2); } function renderQuote(data) { var quote = data.quote || {}; var html = '<table class="widefat" style="margin-bottom:1em;">'; html += '<thead><tr><th>Item</th><th>Qty</th><th>Price</th><th>Total</th></tr></thead><tbody>'; (quote.line_items || []).forEach(function(item) { html += '<tr><td>' + (item.label || item.key) + '</td><td>' + item.quantity + '</td><td>' + centsToUsd(item.unit_price_cents) + '</td><td>' + centsToUsd(item.total_cents) + '</td></tr>'; }); html += '</tbody></table>'; if (quote.add_ons && quote.add_ons.length) { html += '<h4>Add-ons</h4><ul>'; quote.add_ons.forEach(function(a) { html += '<li>' + (a.label || a.key) + ' — ' + centsToUsd(a.total_cents) + '</li>'; }); html += '</ul>'; } html += '<p><strong>Subtotal: ' + centsToUsd(quote.subtotal_cents) + '</strong></p>'; html += '<p style="font-size:1.2em;"><strong>Total: ' + centsToUsd(quote.total_cents) + '</strong></p>'; html += '<p>Upfront (50%): <strong>' + centsToUsd(quote.upfront_50_cents) + '</strong> · Final (50%): ' + centsToUsd(quote.final_50_cents) + '</p>'; if (quote.estimated_days) { html += '<p class="description">Estimated time: ' + quote.estimated_days + ' days</p>'; } if (data.deterministic) { html += '<p class="description">Note: using estimated pricing (AI pricing model unavailable).</p>'; } var quoteId = data.quote_id || ''; html += '<button type="button" class="button button-primary" id="ad-checkout-trigger" ' + (quoteId ? '' : 'disabled') + '>Continue to payment</button>'; $('#ad-quote-body').html(html); // Wire checkout button → /checkout → redirect to Stripe. $('#ad-checkout-trigger').on('click', function() { var $cbtn = $(this).prop('disabled', true).text('Redirecting…'); $.ajax({ url: W.restUrl + 'checkout', method: 'POST', headers: { 'X-WP-Nonce': W.restNonce }, data: { quote_id: quoteId }, success: function(cresp) { if (cresp && cresp.success && cresp.data && cresp.data.checkout_url) { window.location.href = cresp.data.checkout_url; } else { var msg = (cresp && cresp.data && cresp.data.error) ? cresp.data.error : 'Checkout failed.'; $cbtn.prop('disabled', false).text('Continue to payment'); alert(msg); } }, error: function(xhr) { var msg = 'Checkout failed'; try { var body = JSON.parse(xhr.responseText); if (body && body.data && body.data.error) { msg = body.data.error; } else if (body && body.error) { msg = body.error; } } catch (ex) { if (xhr.status) { msg += ' (HTTP ' + xhr.status + ')'; } } $cbtn.prop('disabled', false).text('Continue to payment'); alert(msg); } }); }); } }); })(jQuery);
Save
cmd:
run