/** * WooAApanel Account JS * * Customer My Account "Web Hosting" tab. * Handles site and database panels. * Integrates WooDomains PowerDNS for DNS management if active. */ (function ($) { 'use strict'; var cfg = wooaapanelAcct; var ajaxUrl = cfg.ajax_url; var nonce = cfg.nonce; var pdnsActive = parseInt(cfg.pdns_active, 10) === 1; var pdnsNonce = cfg.pdns_nonce; /* ── Utility ──────────────────────────────────────────────── */ function post(action, data, cb) { data = $.extend({ action: action, nonce: nonce }, data); $.post(ajaxUrl, data, cb).fail(function () { setNotice('#wap-acct-notices', 'Request failed. Please reload and try again.', 'error'); }); } function pdnsPost(action, data, cb) { data = $.extend({ action: action, nonce: pdnsNonce }, data); $.post(ajaxUrl, data, cb); } function setNotice(selector, msg, type) { var $el = $(selector); $el.attr('class', 'woocommerce-' + (type === 'error' ? 'error' : 'message') + ' woocommerce-info') .text(msg).show(); setTimeout(function () { $el.fadeOut(); }, 5000); } function inlineNotice($el, msg, type) { $el.text(msg).attr('class', 'wap-notice-inline ' + (type === 'error' ? 'error' : 'ok')); setTimeout(function () { $el.text('').removeClass('ok error'); }, 4000); } function escHtml(s) { return String(s) .replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } function siteOpts($panel) { return { server_id: $panel.data('server-id'), site_name: $panel.data('site-name') }; } function dbOpts($panel) { return { server_id: $panel.data('server-id'), db_name: $panel.data('db-name') }; } /* ══════════════════════════════════════════════════════════ SITE PANELS ══════════════════════════════════════════════════════════ */ /* ── Domains ──────────────────────────────────────────────── */ $(document).on('click', '.wap-load-domains', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-domains-section'); $sec.toggle(); if ($sec.is(':visible')) { loadDomains($panel); } }); function loadDomains($panel) { var opts = siteOpts($panel); var $list = $panel.find('.wap-domains-list').html('Loading…'); post('wooaapanel_acct_site_domains', opts, function (res) { var domains = res.data && res.data.data ? res.data.data : []; if (!domains.length) { $list.html('

No extra domains.

'); return; } var html = ''; $.each(domains, function (i, d) { html += '' + ''; }); html += '
DomainPort
' + escHtml(d.name || d.domain || '') + '' + (d.port || '') + '
'; $list.html(html); $list.find('.wap-del-domain').on('click', function () { if (!confirm('Remove this domain?')) return; post('wooaapanel_acct_site_del_domain', $.extend({}, opts, { domain: $(this).data('domain'), site_id: $(this).data('id') }), function () { loadDomains($panel); }); }); }); } $(document).on('click', '.wap-add-domain-btn', function () { var $panel = $(this).closest('.wap-site-panel'); var domain = $panel.find('.wap-new-domain').val(); var $notice = $panel.find('.wap-domain-notice'); if (!domain) { inlineNotice($notice, 'Enter a domain name.', 'error'); return; } post('wooaapanel_acct_site_add_domain', $.extend({}, siteOpts($panel), { domain: domain }), function (res) { inlineNotice($notice, res.success ? 'Domain added!' : (res.data || 'Error.'), res.success ? 'ok' : 'error'); if (res.success) { $panel.find('.wap-new-domain').val(''); loadDomains($panel); } }); }); /* ── PHP Version ──────────────────────────────────────────── */ $(document).on('click', '.wap-load-php', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-php-section'); $sec.toggle(); if ($sec.is(':visible') && !$sec.data('loaded')) { $sec.data('loaded', 1); loadPhpSection($panel, $sec); } }); function loadPhpSection($panel, $sec) { var opts = siteOpts($panel); $sec.find('.wap-php-current').text('Loading…'); post('wooaapanel_acct_site_php_get', opts, function (res) { var current = res.data && res.data.version ? res.data.version : '?'; $sec.find('.wap-php-current').html('Current PHP version: ' + escHtml(current) + ''); post('wooaapanel_acct_site_php_versions', opts, function (res2) { var versions = res2.data && res2.data.version ? res2.data.version : []; var opts2 = ''; $.each(versions, function (i, v) { var ver = v.version || v; opts2 += ''; }); $sec.find('.wap-php-select').html(opts2); }); }); } $(document).on('click', '.wap-php-set-btn', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-php-section'); var $notice = $sec.find('.wap-php-notice'); var version = $sec.find('.wap-php-select').val(); post('wooaapanel_acct_site_php_set', $.extend({}, siteOpts($panel), { version: version }), function (res) { inlineNotice($notice, res.success ? 'PHP version updated!' : (res.data || 'Error.'), res.success ? 'ok' : 'error'); if (res.success) { $sec.data('loaded', 0); loadPhpSection($panel, $sec); } }); }); /* ── URL Rewrite ──────────────────────────────────────────── */ $(document).on('click', '.wap-load-rewrite', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-rewrite-section'); $sec.toggle(); if ($sec.is(':visible') && !$sec.data('loaded')) { $sec.data('loaded', 1); post('wooaapanel_acct_site_rewrite_get', siteOpts($panel), function (res) { var content = res.data && res.data.data ? res.data.data : (res.data || ''); $sec.find('.wap-rewrite-content').val(content); }); } }); $(document).on('click', '.wap-rewrite-save-btn', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-rewrite-section'); var $notice = $sec.find('.wap-rewrite-notice'); var content = $sec.find('.wap-rewrite-content').val(); post('wooaapanel_acct_site_rewrite_set', $.extend({}, siteOpts($panel), { content: content }), function (res) { inlineNotice($notice, res.success ? 'Saved!' : (res.data || 'Error.'), res.success ? 'ok' : 'error'); }); }); /* ── SSL ──────────────────────────────────────────────────── */ $(document).on('click', '.wap-load-ssl', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-ssl-section'); $sec.toggle(); if ($sec.is(':visible') && !$sec.data('loaded')) { $sec.data('loaded', 1); post('wooaapanel_acct_site_ssl_get', siteOpts($panel), function (res) { var d = res.data || {}; var html = ''; if (d.status !== undefined) { var valid = d.status == 1 || d.status === true; html += '

Status: ' + (valid ? 'Active' : 'Inactive') + '

'; } if (d.notAfter) html += '

Expires: ' + escHtml(d.notAfter) + '

'; if (d.issuer) html += '

Issuer: ' + escHtml(d.issuer) + '

'; if (d.subject) html += '

Domain: ' + escHtml(d.subject) + '

'; if (!html) html = '
' + escHtml(JSON.stringify(d, null, 2)) + '
'; $sec.find('.wap-ssl-info').html(html); }); } }); /* ── Server Info ──────────────────────────────────────────── */ $(document).on('click', '.wap-load-server-info', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-server-section'); $sec.toggle(); if ($sec.is(':visible') && !$sec.data('loaded')) { $sec.data('loaded', 1); post('wooaapanel_acct_server_info', siteOpts($panel), function (res) { if (!res.success) { $sec.find('.wap-server-info').text(res.data || 'Error.'); return; } var d = res.data; var html = '' + '' + '' + ''; if (d.panel_status) { html += ''; } html += '
Server Name' + escHtml(d.server_name || '') + '
Server Host / IP' + escHtml(d.server_host || '') + '
Panel URL' + escHtml(d.panel_url || '') + '
Panel Status
' + escHtml(JSON.stringify(d.panel_status, null, 2)) + '
'; $sec.find('.wap-server-info').html(html); }); } }); /* ── DNS (WooDomains PowerDNS integration) ────────────────── */ if (pdnsActive) { $(document).on('click', '.wap-load-dns', function () { var $panel = $(this).closest('.wap-site-panel'); var zone = $(this).data('zone'); var $sec = $panel.find('.wap-dns-section'); $sec.toggle(); if ($sec.is(':visible')) { loadDnsRecords($sec, zone); } }); function loadDnsRecords($sec, zone) { $sec.find('.wap-dns-records-list').html('Loading DNS records…'); pdnsPost('woodomains_dns_get', { zone: zone }, function (res) { if (!res.success) { $sec.find('.wap-dns-records-list').html('

' + escHtml(res.data && res.data.message ? res.data.message : 'Error.') + '

'); return; } var records = res.data.records || []; var html = '' + '' + ''; $.each(records, function (i, rr) { var contents = $.map(rr.records, function (r) { return escHtml(r.content); }).join('
'); html += '' + '' + ''; }); html += '
NameTypeTTLContent
' + escHtml(rr.name) + '' + escHtml(rr.type) + '' + rr.ttl + '' + contents + '
'; $sec.find('.wap-dns-records-list').html(html); $sec.find('.wap-dns-del').on('click', function () { if (!confirm('Delete this DNS record?')) return; pdnsPost('woodomains_dns_delete', { zone: $(this).data('zone'), name: $(this).data('name'), type: $(this).data('type') }, function () { loadDnsRecords($sec, zone); }); }); }); } $(document).on('click', '.wap-dns-save-btn', function () { var $panel = $(this).closest('.wap-site-panel'); var $sec = $panel.find('.wap-dns-section'); var zone = $sec.data('zone'); var $notice = $sec.find('.wap-dns-notice'); var contents = $sec.find('.wap-dns-content').val() .split('\n').filter(function (s) { return s.trim(); }); pdnsPost('woodomains_dns_upsert', { zone: zone, name: $sec.find('.wap-dns-name').val(), type: $sec.find('.wap-dns-type').val(), ttl: parseInt($sec.find('.wap-dns-ttl').val(), 10) || 3600, contents: contents }, function (res) { inlineNotice($notice, res.success ? 'Saved!' : (res.data && res.data.message ? res.data.message : 'Error.'), res.success ? 'ok' : 'error'); if (res.success) loadDnsRecords($sec, zone); }); }); } /* ══════════════════════════════════════════════════════════ DATABASE PANELS ══════════════════════════════════════════════════════════ */ /* ── Backup ───────────────────────────────────────────────── */ $(document).on('click', '.wap-db-backup-btn', function () { var $panel = $(this).closest('.wap-db-panel'); var $notice = $panel.find('.wap-db-action-notice'); post('wooaapanel_acct_db_backup', dbOpts($panel), function (res) { $notice.attr('class', 'wap-db-action-notice ' + (res.success ? 'ok' : 'error')) .text(res.success ? 'Backup started!' : (res.data || 'Error.')); }); }); /* ── Backup list ──────────────────────────────────────────── */ $(document).on('click', '.wap-load-db-backups', function () { var $panel = $(this).closest('.wap-db-panel'); var $sec = $panel.find('.wap-db-backups-section'); $sec.toggle(); if ($sec.is(':visible')) { loadDbBackups($panel, $sec); } }); function loadDbBackups($panel, $sec) { $sec.find('.wap-db-backups-list').html('Loading…'); post('wooaapanel_acct_db_backups', dbOpts($panel), function (res) { var backups = res.data && res.data.data ? res.data.data : []; if (!backups.length) { $sec.find('.wap-db-backups-list').html('

No backups found.

'); return; } var html = ''; $.each(backups, function (i, b) { html += '' + ''; }); html += '
FileSizeDate
' + escHtml(b.name || '') + '' + escHtml(b.size || '') + '' + escHtml(b.addtime || '') + '
'; $sec.find('.wap-db-backups-list').html(html); $sec.find('.wap-del-db-backup').on('click', function () { if (!confirm('Delete this backup?')) return; post('wooaapanel_acct_db_backup_delete', $.extend({}, dbOpts($panel), { backup_id: $(this).data('id') }), function () { loadDbBackups($panel, $sec); }); }); }); } /* ── Optimize ─────────────────────────────────────────────── */ $(document).on('click', '.wap-db-optimize-btn', function () { var $panel = $(this).closest('.wap-db-panel'); var $notice = $panel.find('.wap-db-action-notice'); post('wooaapanel_acct_db_optimize', dbOpts($panel), function (res) { $notice.attr('class', 'wap-db-action-notice ' + (res.success ? 'ok' : 'error')) .text(res.success ? 'Database optimized!' : (res.data || 'Error.')); }); }); /* ── Repair ───────────────────────────────────────────────── */ $(document).on('click', '.wap-db-repair-btn', function () { var $panel = $(this).closest('.wap-db-panel'); var $notice = $panel.find('.wap-db-action-notice'); post('wooaapanel_acct_db_repair', dbOpts($panel), function (res) { $notice.attr('class', 'wap-db-action-notice ' + (res.success ? 'ok' : 'error')) .text(res.success ? 'Database repaired!' : (res.data || 'Error.')); }); }); /* ── Change Password ──────────────────────────────────────── */ $(document).on('click', '.wap-db-password-btn', function () { var $panel = $(this).closest('.wap-db-panel'); $panel.find('.wap-db-password-section').toggle(); }); $(document).on('click', '.wap-db-pass-save-btn', function () { var $panel = $(this).closest('.wap-db-panel'); var $sec = $panel.find('.wap-db-password-section'); var $notice = $sec.find('.wap-db-pass-notice'); var db_user = $sec.find('.wap-db-user').val(); var password = $sec.find('.wap-db-new-pass').val(); if (!db_user || !password) { inlineNotice($notice, 'Database user and password are required.', 'error'); return; } post('wooaapanel_acct_db_password', $.extend({}, dbOpts($panel), { db_user: db_user, password: password }), function (res) { inlineNotice($notice, res.success ? 'Password updated!' : (res.data || 'Error.'), res.success ? 'ok' : 'error'); if (res.success) { $sec.find('.wap-db-user, .wap-db-new-pass').val(''); } }); }); })(jQuery);