/** * WooAApanel Admin JS * * Handles all admin pages: Servers, Site Assignments, DB Assignments, * Sites (full management), Databases (full management), WC Products. */ (function ($) { 'use strict'; var ajaxUrl = wooaapanel.ajax_url; var nonce = wooaapanel.nonce; /* ── Utility ──────────────────────────────────────────────────── */ function post(action, data, cb) { data = $.extend({ action: action, nonce: nonce }, data); $.post(ajaxUrl, data, cb).fail(function () { alert('Request failed. Check your network and try again.'); }); } function notice($el, msg, type) { $el.removeClass('success error').addClass(type).text(msg).show(); } function confirm_action(msg) { return window.confirm(msg || 'Are you sure?'); } function pretty(obj) { return JSON.stringify(obj, null, 2); } /* ── Page detection ───────────────────────────────────────────── */ var $body = $('body'); var page_id = ''; if ($('#wooaapanel-servers-page').length) page_id = 'servers'; if ($('#wooaapanel-site-assignments-page').length) page_id = 'site-assignments'; if ($('#wooaapanel-db-assignments-page').length) page_id = 'db-assignments'; if ($('#wooaapanel-sites-page').length) page_id = 'sites'; if ($('#wooaapanel-databases-page').length) page_id = 'databases'; if ($('#wooaapanel-products-page').length) page_id = 'products'; /* ══════════════════════════════════════════════════════════════ SERVERS PAGE ══════════════════════════════════════════════════════════════ */ if (page_id === 'servers') { var $wrap = $('#wap-servers-wrap'); function loadServers() { post('wooaapanel_servers_list', {}, function (res) { if (!res.success) return; var html = '' + '' + '' + '' + ''; $.each(res.data, function (i, s) { html += '' + '' + '' + '' + '' + ''; }); html += '
IDNameURLActiveActions
' + s.id + '' + escHtml(s.name) + '' + escHtml(s.url) + '' + (s.active ? 'Active' : 'Inactive') + '' + ' ' + ' ' + '' + '
'; $wrap.html(html); bindServerEvents(); }); } function serverForm(id, name, url, api_key, active) { return '

' + (id ? 'Edit Server' : 'Add Server') + '

' + '' + '' + '' + '' + '' + ' ' + '
'; } function bindServerEvents() { $('#wap-server-add-btn').on('click', function () { $('#wap-server-form').html(serverForm()).show(); }); $wrap.on('click', '.wap-server-edit', function () { var $btn = $(this); $('#wap-server-form').html(serverForm( $btn.data('id'), $btn.data('name'), $btn.data('url'), '', $btn.data('active') )).show(); // API key intentionally left blank on edit for security }); $wrap.on('click', '.wap-s-save', function () { var $form = $(this).closest('.wap-inline-form, #wap-server-form'); var data = { id: $form.find('.wap-s-id').val(), name: $form.find('.wap-s-name').val(), url: $form.find('.wap-s-url').val(), api_key: $form.find('.wap-s-key').val(), active: $form.find('.wap-s-active').val() }; if (!data.name || !data.url) { alert('Name and URL are required.'); return; } if (!data.id || data.id == '0') { if (!data.api_key) { alert('API key is required for new servers.'); return; } } post('wooaapanel_server_save', data, function (res) { if (res.success) { loadServers(); } else { alert(res.data || 'Error saving.'); } }); }); $wrap.on('click', '.wap-s-cancel', function () { $('#wap-server-form').hide(); }); $wrap.on('click', '.wap-server-del', function () { if (!confirm_action('Delete this server?')) return; post('wooaapanel_server_delete', { id: $(this).data('id') }, function (res) { if (res.success) loadServers(); else alert(res.data || 'Error.'); }); }); $wrap.on('click', '.wap-server-test', function () { var id = $(this).data('id'); var $btn = $(this); $btn.text('Testing…').prop('disabled', true); post('wooaapanel_server_test', { id: id }, function (res) { $btn.text('Test').prop('disabled', false); alert(res.success ? 'Connection OK! Response: ' + JSON.stringify(res.data) : 'Failed: ' + (res.data || res.error)); }); }); } loadServers(); } /* ══════════════════════════════════════════════════════════════ SITE ASSIGNMENTS PAGE ══════════════════════════════════════════════════════════════ */ if (page_id === 'site-assignments') { var $wrap = $('#wap-site-assignments-wrap'); function loadSiteAssignments() { post('wooaapanel_site_assignments_list', {}, function (res) { if (!res.success) return; var html = '' + '' + '' + '' + ''; $.each(res.data, function (i, a) { html += '' + '' + '' + '' + '' + '' + ''; }); html += '
IDCustomerServerSite NameDomainActions
' + a.id + '' + escHtml(a.customer_name || '') + '
' + escHtml(a.customer_email || '') + '
' + escHtml(a.server_name || '') + '' + escHtml(a.site_name) + '' + escHtml(a.domain || '—') + '' + '' + '
'; $wrap.html(html); bindSAEvents(); }); } function loadServersSelect(cb) { post('wooaapanel_servers_list', {}, function (res) { if (!res.success) return; cb(res.data); }); } function bindSAEvents() { $('#wap-sa-add-btn').on('click', function () { loadServersSelect(function (servers) { var opts = ''; $.each(servers, function (i, s) { opts += ''; }); var html = '

Assign Site to Customer

' + '' + '' + '' + '' + ' ' + '
'; $('#wap-sa-form').html(html).show(); bindSAFormEvents(); }); }); $wrap.on('click', '.wap-sa-del', function () { if (!confirm_action('Remove this site assignment?')) return; post('wooaapanel_site_assignment_delete', { id: $(this).data('id') }, function (res) { if (res.success) loadSiteAssignments(); else alert(res.data || 'Error.'); }); }); } function bindSAFormEvents() { $('#wap-sa-load-sites').on('click', function () { var sid = $('#wap-sa-server').val(); if (!sid) { alert('Select a server first.'); return; } post('wooaapanel_remote_sites', { server_id: sid }, function (res) { var sites = res.data && res.data.data ? res.data.data : []; var opts = ''; $.each(sites, function (i, s) { var name = s.name || s.siteName || s.webname || JSON.stringify(s); opts += ''; }); $('#wap-sa-site').html(opts); }); }); var searchTimer; $('#wap-sa-customer-q').on('keyup', function () { clearTimeout(searchTimer); var q = $(this).val(); searchTimer = setTimeout(function () { if (!q) return; post('wooaapanel_customers_search', { q: q }, function (res) { if (!res.success) return; var $list = $('#wap-sa-customer-results').empty().show(); $.each(res.data, function (i, u) { $('
' + escHtml(u.label) + '
') .on('click', function () { $('#wap-sa-customer-id').val(u.id); $('#wap-sa-customer-q').val(u.label); $list.hide(); }) .appendTo($list); }); }); }, 300); }); $('#wap-sa-save').on('click', function () { var data = { server_id: $('#wap-sa-server').val(), site_name: $('#wap-sa-site').val(), domain: $('#wap-sa-domain').val(), customer_id: $('#wap-sa-customer-id').val() }; if (!data.server_id || !data.site_name || !data.customer_id) { alert('Server, site and customer are all required.'); return; } post('wooaapanel_site_assignment_save', data, function (res) { if (res.success) { loadSiteAssignments(); } else { alert(res.data || 'Error.'); } }); }); $('#wap-sa-cancel').on('click', function () { $('#wap-sa-form').hide(); }); } loadSiteAssignments(); } /* ══════════════════════════════════════════════════════════════ DB ASSIGNMENTS PAGE ══════════════════════════════════════════════════════════════ */ if (page_id === 'db-assignments') { var $wrap = $('#wap-db-assignments-wrap'); function loadDbAssignments() { post('wooaapanel_db_assignments_list', {}, function (res) { if (!res.success) return; var html = '' + '' + '' + '' + ''; $.each(res.data, function (i, a) { html += '' + '' + '' + '' + '' + '' + ''; }); html += '
IDCustomerServerDatabaseActions
' + a.id + '' + escHtml(a.customer_name || '') + '
' + escHtml(a.customer_email || '') + '
' + escHtml(a.server_name || '') + '' + escHtml(a.db_name) + '
'; $wrap.html(html); bindDAEvents(); }); } function bindDAEvents() { $('#wap-da-add-btn').on('click', function () { post('wooaapanel_servers_list', {}, function (res) { var opts = ''; $.each(res.data || [], function (i, s) { opts += ''; }); var html = '

Assign Database to Customer

' + '' + '' + '' + ' '; $('#wap-da-form').html(html).show(); $('#wap-da-load-dbs').on('click', function () { var sid = $('#wap-da-server').val(); if (!sid) { alert('Select a server first.'); return; } post('wooaapanel_remote_dbs', { server_id: sid }, function (res2) { var dbs = res2.data && res2.data.data ? res2.data.data : []; var opts2 = ''; $.each(dbs, function (i, d) { var name = d.name || d.database || JSON.stringify(d); opts2 += ''; }); $('#wap-da-db').html(opts2); }); }); var searchTimer; $('#wap-da-customer-q').on('keyup', function () { clearTimeout(searchTimer); var q = $(this).val(); searchTimer = setTimeout(function () { if (!q) return; post('wooaapanel_customers_search', { q: q }, function (r) { if (!r.success) return; var $list = $('#wap-da-customer-results').empty().show(); $.each(r.data, function (i, u) { $('
' + escHtml(u.label) + '
') .on('click', function () { $('#wap-da-customer-id').val(u.id); $('#wap-da-customer-q').val(u.label); $list.hide(); }).appendTo($list); }); }); }, 300); }); $('#wap-da-save').on('click', function () { var data = { server_id: $('#wap-da-server').val(), db_name: $('#wap-da-db').val(), customer_id: $('#wap-da-customer-id').val() }; if (!data.server_id || !data.db_name || !data.customer_id) { alert('Server, database and customer are required.'); return; } post('wooaapanel_db_assignment_save', data, function (r) { if (r.success) { loadDbAssignments(); } else { alert(r.data || 'Error.'); } }); }); $('#wap-da-cancel').on('click', function () { $('#wap-da-form').hide(); }); }); }); $wrap.on('click', '.wap-da-del', function () { if (!confirm_action('Remove this database assignment?')) return; post('wooaapanel_db_assignment_delete', { id: $(this).data('id') }, function (res) { if (res.success) loadDbAssignments(); else alert(res.data || 'Error.'); }); }); } loadDbAssignments(); } /* ══════════════════════════════════════════════════════════════ SITES PAGE (admin full management) ══════════════════════════════════════════════════════════════ */ if (page_id === 'sites') { var $wrap = $('#wap-sites-wrap'); function renderSitesToolbar(servers) { var opts = ''; $.each(servers, function (i, s) { opts += ''; }); $wrap.html( '
' + '' + '' + '' + '' + '
' + '' + '' + '
' ); $('#wap-sites-load').on('click', loadSitesList); $('#wap-site-add-btn').on('click', function () { var sid = $('#wap-sites-server').val(); if (!sid) { alert('Select a server first.'); return; } $('#wap-site-form').html(siteAddForm(sid)).show(); $('#wap-site-detail').hide(); }); $wrap.on('click', '.wap-site-manage', function () { var $row = $(this).closest('tr'); openSiteDetail({ server_id: $row.data('server'), site_name: $row.data('site') }); }); $wrap.on('click', '.wap-site-del', function () { if (!confirm_action('Delete this site? This is irreversible.')) return; var $row = $(this).closest('tr'); post('wooaapanel_admin_site_delete', { server_id: $row.data('server'), site_name: $row.data('site') }, function (res) { alert(res.success ? 'Site deleted.' : 'Error: ' + JSON.stringify(res.data)); loadSitesList(); }); }); } function loadSitesList() { var sid = $('#wap-sites-server').val(); var search = $('#wap-sites-search').val(); if (!sid) { alert('Select a server.'); return; } post('wooaapanel_admin_site_list', { server_id: sid, search: search }, function (res) { var sites = res.data && res.data.data ? res.data.data : []; var html = '' + '' + ''; $.each(sites, function (i, s) { html += '' + '' + '' + '' + '' + '' + ''; }); html += '
IDNameDomainPHPStatusActions
' + (s.id || '—') + '' + escHtml(s.name || s.siteName || '') + '' + escHtml(s.domain || '') + '' + escHtml(s.php_version || s.phpVersion || '') + '' + escHtml(s.status || '') + '' + ' ' + '' + '
'; $('#wap-sites-list').html(html); }); } function siteAddForm(server_id) { return '

Add PHP Project Site

' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
'; } $wrap.on('click', '.wap-sf-save', function () { var $f = $(this).closest('.wap-inline-form'); post('wooaapanel_admin_site_add', { server_id: $f.find('.wap-sf-server').val(), webname: $f.find('.wap-sf-webname').val(), version: $f.find('.wap-sf-phpver').val(), port: $f.find('.wap-sf-port').val(), ps: $f.find('.wap-sf-ps').val(), sql: $f.find('.wap-sf-sql').val() ? 'MySQL' : '', datauser: $f.find('.wap-sf-datauser').val(), datapassword: $f.find('.wap-sf-datapass').val() }, function (res) { var $n = $f.find('#wap-site-form-notice'); notice($n, res.success ? 'Site created!' : 'Error: ' + JSON.stringify(res.data), res.success ? 'success' : 'error'); if (res.success) loadSitesList(); }); }); $wrap.on('click', '.wap-sf-cancel', function () { $('#wap-site-form').hide(); }); function openSiteDetail(opts) { var $d = $('#wap-site-detail').show(); $d.html( '

Manage: ' + escHtml(opts.site_name) + '

' + '
' + '
Domains
' + '
PHP
' + '
URL Rewrite
' + '
SSL
' + '
Anti-XSS
' + '
' + '
' + '
' + '
' + '
' + '
' ); // Tab switching $d.find('.wap-tab').on('click', function () { $d.find('.wap-tab').removeClass('active'); $d.find('.wap-tab-content').removeClass('active'); $(this).addClass('active'); $d.find('#wap-site-tab-' + $(this).data('tab')).addClass('active'); }); loadDomainsTab(opts, $d); $d.find('.wap-tab[data-tab="php"]').on('click', function () { loadPhpTab(opts, $d); }); $d.find('.wap-tab[data-tab="rewrite"]').on('click', function () { loadRewriteTab(opts, $d); }); $d.find('.wap-tab[data-tab="ssl"]').on('click', function () { loadSslTab(opts, $d); }); $d.find('.wap-tab[data-tab="xss"]').on('click', function () { loadXssTab(opts, $d); }); } // ── Domains tab ────────────────────────────────────────── function loadDomainsTab(opts, $d) { var $tab = $d.find('#wap-site-tab-domains'); post('wooaapanel_admin_site_domains', opts, function (res) { var domains = res.data && res.data.data ? res.data.data : []; var html = ''; $.each(domains, function (i, dm) { html += '' + ''; }); html += '
DomainPort
' + escHtml(dm.name || dm.domain || '') + '' + (dm.port || '') + '
' + '
' + '' + '' + '' + '
'; $tab.html(html); $tab.find('.wap-del-domain').on('click', function () { if (!confirm_action('Delete this domain?')) return; post('wooaapanel_admin_site_del_domain', $.extend({}, opts, { domain: $(this).data('domain'), site_id: $(this).data('id') }), function () { loadDomainsTab(opts, $d); }); }); $tab.find('.wap-add-domain-btn').on('click', function () { var domain = $tab.find('.wap-add-domain-input').val(); post('wooaapanel_admin_site_add_domain', $.extend({}, opts, { domain: domain }), function (res) { $tab.find('.wap-domain-msg').text(res.success ? 'Added!' : JSON.stringify(res.data)); if (res.success) loadDomainsTab(opts, $d); }); }); }); } // ── PHP tab ────────────────────────────────────────────── function loadPhpTab(opts, $d) { var $tab = $d.find('#wap-site-tab-php'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); post('wooaapanel_admin_site_php_get', opts, function (res) { var current = res.data && res.data.version ? res.data.version : '?'; post('wooaapanel_admin_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 += ''; }); $tab.html( '

Current: ' + escHtml(current) + '

' + '' + ' ' + '' ); $tab.find('.wap-php-set').on('click', function () { post('wooaapanel_admin_site_php_set', $.extend({}, opts, { version: $tab.find('#wap-php-select').val() }), function (res) { $tab.find('#wap-php-notice').text(res.success ? 'Updated!' : JSON.stringify(res.data)); }); }); }); }); } // ── Rewrite tab ────────────────────────────────────────── function loadRewriteTab(opts, $d) { var $tab = $d.find('#wap-site-tab-rewrite'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); post('wooaapanel_admin_site_rewrite_get', opts, function (res) { var content = res.data && res.data.data ? res.data.data : (res.data || ''); $tab.html( '' + '' + '' ); $tab.find('.wap-rewrite-save').on('click', function () { post('wooaapanel_admin_site_rewrite_set', $.extend({}, opts, { content: $tab.find('#wap-rewrite-ta').val() }), function (res) { $tab.find('#wap-rewrite-notice').text(res.success ? 'Saved!' : JSON.stringify(res.data)); }); }); }); } // ── SSL tab ────────────────────────────────────────────── function loadSslTab(opts, $d) { var $tab = $d.find('#wap-site-tab-ssl'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); post('wooaapanel_admin_site_ssl_get', opts, function (res) { var d = res.data || {}; $tab.html('
' + escHtml(pretty(d)) + '
' + '' + ' '); $tab.find('.wap-ssl-close').on('click', function () { if (!confirm_action('Disable SSL for this site?')) return; post('wooaapanel_admin_site_ssl_close', opts, function (res) { $tab.find('#wap-ssl-notice').text(res.success ? 'SSL disabled.' : JSON.stringify(res.data)); }); }); }); } // ── XSS tab ────────────────────────────────────────────── function loadXssTab(opts, $d) { var $tab = $d.find('#wap-site-tab-xss'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); post('wooaapanel_admin_site_xss_get', $.extend({ site_path: '/www/wwwroot/' + opts.site_name }, opts), function (res) { var status = res.data; $tab.html('
' + escHtml(pretty(status)) + '
' + '' + ' ' + ' '); $tab.find('.wap-xss-on').on('click', function () { post('wooaapanel_admin_site_xss_set', $.extend({ site_path: '/www/wwwroot/' + opts.site_name, enable: 1 }, opts), function (res) { $tab.find('#wap-xss-notice').text(res.success ? 'XSS enabled.' : JSON.stringify(res.data)); }); }); $tab.find('.wap-xss-off').on('click', function () { post('wooaapanel_admin_site_xss_set', $.extend({ site_path: '/www/wwwroot/' + opts.site_name, enable: 0 }, opts), function (res) { $tab.find('#wap-xss-notice').text(res.success ? 'XSS disabled.' : JSON.stringify(res.data)); }); }); }); } // Bootstrap post('wooaapanel_servers_list', {}, function (res) { renderSitesToolbar(res.data || []); }); } /* ══════════════════════════════════════════════════════════════ DATABASES PAGE (admin full management) ══════════════════════════════════════════════════════════════ */ if (page_id === 'databases') { var $wrap = $('#wap-databases-wrap'); function renderDbToolbar(servers) { var opts = ''; $.each(servers, function (i, s) { opts += ''; }); $wrap.html( '
' + '' + '' + '' + '' + '' + '' + '
' + '' + '' + '
' ); $('#wap-dbs-load').on('click', loadDbList); $('#wap-db-add-btn').on('click', function () { var sid = $('#wap-dbs-server').val(); if (!sid) { alert('Select a server first.'); return; } $('#wap-db-form').html(dbAddForm(sid)).show(); }); $('#wap-db-sync-btn').on('click', function () { var sid = $('#wap-dbs-server').val(); if (!sid) { alert('Select a server.'); return; } post('wooaapanel_admin_db_sync', { server_id: sid }, function (res) { alert(res.success ? (res.data && res.data.message || 'Synced.') : 'Error: ' + JSON.stringify(res.data)); }); }); $('#wap-db-recycle-btn').on('click', function () { var sid = $('#wap-dbs-server').val(); if (!sid) { alert('Select a server.'); return; } post('wooaapanel_admin_db_recycle', { server_id: sid }, function (res) { alert(res.success ? 'Recycle bin:\n' + pretty(res.data) : 'Error.'); }); }); $wrap.on('click', '.wap-db-manage', function () { openDbDetail({ server_id: $(this).closest('tr').data('server'), db_name: $(this).closest('tr').data('db') }); }); $wrap.on('click', '.wap-db-del-row', function () { if (!confirm_action('Delete this database? This is irreversible.')) return; var $row = $(this).closest('tr'); post('wooaapanel_admin_db_delete', { server_id: $row.data('server'), db_name: $row.data('db') }, function (res) { alert(res.success ? 'Database deleted.' : 'Error: ' + JSON.stringify(res.data)); loadDbList(); }); }); } function loadDbList() { var sid = $('#wap-dbs-server').val(); var search = $('#wap-dbs-search').val(); if (!sid) { alert('Select a server.'); return; } post('wooaapanel_admin_db_list', { server_id: sid, search: search }, function (res) { var dbs = res.data && res.data.data ? res.data.data : []; var html = '' + '' + ''; $.each(dbs, function (i, d) { html += '' + '' + '' + '' + '' + '' + ''; }); html += '
IDNameUserTypeSizeActions
' + (d.id || '—') + '' + escHtml(d.name || '') + '' + escHtml(d.username || d.db_user || '') + '' + escHtml(d.type || 'MySQL') + '' + escHtml(d.dataLength || '') + '' + ' ' + '' + '
'; $('#wap-dbs-list').html(html); }); } function dbAddForm(server_id) { return '

Add Database

' + '' + '' + '' + '' + '' + '' + ' ' + '
'; } $wrap.on('click', '.wap-dbf-save', function () { var $f = $(this).closest('.wap-inline-form'); post('wooaapanel_admin_db_add', { server_id: $f.find('.wap-dbf-server').val(), db_name: $f.find('.wap-dbf-name').val(), db_user: $f.find('.wap-dbf-user').val(), password: $f.find('.wap-dbf-pass').val(), codeing: $f.find('.wap-dbf-enc').val() }, function (res) { notice($f.find('#wap-db-form-notice'), res.success ? 'Created!' : 'Error: ' + JSON.stringify(res.data), res.success ? 'success' : 'error'); if (res.success) loadDbList(); }); }); $wrap.on('click', '.wap-dbf-cancel', function () { $('#wap-db-form').hide(); }); function openDbDetail(opts) { var $d = $('#wap-db-detail').show(); $d.html( '

Manage: ' + escHtml(opts.db_name) + '

' + '
' + '
Backups
' + '
Access
' + '
Password
' + '
Quota
' + '
' + '
' + '
' + '
' + '
' + '
' + '' + ' ' + ' ' + ' ' + '
' ); $d.find('.wap-tab').on('click', function () { $d.find('.wap-tab').removeClass('active'); $d.find('.wap-tab-content').removeClass('active'); $(this).addClass('active'); $d.find('#wap-db-tab-' + $(this).data('tab')).addClass('active'); }); loadDbBackupsTab(opts, $d); $d.find('.wap-tab[data-tab="access"]').on('click', function () { loadDbAccessTab(opts, $d); }); $d.find('.wap-tab[data-tab="password"]').on('click', function () { renderDbPasswordTab(opts, $d); }); $d.find('.wap-tab[data-tab="quota"]').on('click', function () { renderDbQuotaTab(opts, $d); }); $d.find('.wap-db-backup-now').on('click', function () { post('wooaapanel_admin_db_backup', opts, function (res) { $d.find('#wap-db-quick-notice').text(res.success ? 'Backup started!' : JSON.stringify(res.data)); loadDbBackupsTab(opts, $d); }); }); $d.find('.wap-db-optimize').on('click', function () { post('wooaapanel_admin_db_optimize', opts, function (res) { $d.find('#wap-db-quick-notice').text(res.success ? 'Optimized!' : JSON.stringify(res.data)); }); }); $d.find('.wap-db-repair').on('click', function () { post('wooaapanel_admin_db_repair', opts, function (res) { $d.find('#wap-db-quick-notice').text(res.success ? 'Repaired!' : JSON.stringify(res.data)); }); }); } function loadDbBackupsTab(opts, $d) { var $tab = $d.find('#wap-db-tab-backups'); post('wooaapanel_admin_db_backups', opts, function (res) { var backups = res.data && res.data.data ? res.data.data : []; var html = ''; $.each(backups, function (i, b) { html += '' + ''; }); html += '
IDFilenameSizeDate
' + (b.id || '') + '' + escHtml(b.name || '') + '' + escHtml(b.size || '') + '' + escHtml(b.addtime || '') + '
'; $tab.html(html); $tab.find('.wap-del-backup').on('click', function () { if (!confirm_action('Delete this backup?')) return; post('wooaapanel_admin_db_backup_delete', $.extend({}, opts, { backup_id: $(this).data('id') }), function () { loadDbBackupsTab(opts, $d); }); }); }); } function loadDbAccessTab(opts, $d) { var $tab = $d.find('#wap-db-tab-access'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); post('wooaapanel_admin_db_access_get', opts, function (res) { var acc = res.data && res.data.access ? res.data.access : '%'; $tab.html( '

Current: ' + escHtml(acc) + '

' + '' + '' + '' ); $tab.find('.wap-set-access').on('click', function () { post('wooaapanel_admin_db_access_set', $.extend({}, opts, { access: $tab.find('#wap-access-input').val() }), function (res) { $tab.find('#wap-access-notice').text(res.success ? 'Updated!' : JSON.stringify(res.data)); }); }); }); } function renderDbPasswordTab(opts, $d) { var $tab = $d.find('#wap-db-tab-password'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); $tab.html( '' + '' + '' + '' ); $tab.find('.wap-set-password').on('click', function () { post('wooaapanel_admin_db_password', $.extend({}, opts, { db_user: $tab.find('#wap-pw-user').val(), password: $tab.find('#wap-pw-pass').val() }), function (res) { $tab.find('#wap-pw-notice').text(res.success ? 'Password updated!' : JSON.stringify(res.data)); }); }); } function renderDbQuotaTab(opts, $d) { var $tab = $d.find('#wap-db-tab-quota'); if ($tab.data('loaded')) return; $tab.data('loaded', 1); $tab.html( '' + '' + '' ); $tab.find('.wap-set-quota').on('click', function () { post('wooaapanel_admin_db_quota', $.extend({}, opts, { quota_mb: $tab.find('#wap-quota-input').val() }), function (res) { $tab.find('#wap-quota-notice').text(res.success ? 'Quota set!' : JSON.stringify(res.data)); }); }); } post('wooaapanel_servers_list', {}, function (res) { renderDbToolbar(res.data || []); }); } /* ══════════════════════════════════════════════════════════════ WC PRODUCTS PAGE ══════════════════════════════════════════════════════════════ */ if (page_id === 'products') { var $wrap = $('#wap-products-wrap'); post('wooaapanel_products_list', {}, function (res) { if (!res.success) { $wrap.html('

Error loading products.

'); return; } var products = res.data.products || []; var servers = res.data.servers || []; var serverOpts = ''; $.each(servers, function (i, s) { serverOpts += ''; }); var html = '

Assign an aaPanel server to a product. When an order for that product completes, a site and database will be automatically created on the linked server.

' + ''; $.each(products, function (i, p) { var selOpts = serverOpts.replace('value="' + p.server_id + '"', 'value="' + p.server_id + '" selected'); html += '' + '' + '' + ''; }); html += '
ProductLinked Server
' + escHtml(p.name) + ' (#' + p.id + ')
'; $wrap.html(html); $wrap.on('click', '.wap-prod-save', function () { var $row = $(this).closest('tr'); var prod_id = $(this).data('id'); var server_id = $row.find('.wap-prod-server').val(); var $msg = $row.find('.wap-prod-msg'); post('wooaapanel_product_server_save', { product_id: prod_id, server_id: server_id }, function (res) { $msg.text(res.success ? '✓ Saved' : 'Error'); setTimeout(function () { $msg.text(''); }, 2000); }); }); }); } /* ── HTML escape helpers ──────────────────────────────────── */ function escHtml(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } function escAttr(s) { return escHtml(s); } })(jQuery);