diff --git a/wordpress-dev/bin/create-web-installer.php b/wordpress-dev/bin/create-web-installer.php
new file mode 100644
index 00000000..82e27a2e
--- /dev/null
+++ b/wordpress-dev/bin/create-web-installer.php
@@ -0,0 +1,168 @@
+
+
+
+
+ HVAC Community Events Plugin Installer
+
+
+
+ HVAC Community Events Plugin Installer
+
+
+
+
Installing Plugin from URL
+ ';
+ echo "Attempting to install plugin from: $plugin_zip_url\n";
+ $result = $upgrader->install($plugin_zip_url);
+
+ if ($result) {
+ echo "Plugin installed successfully.\n";
+
+ // Activate the plugin
+ $plugin_main_file = 'hvac-community-events/hvac-community-events.php';
+ $activate = activate_plugin($plugin_main_file);
+
+ if (is_wp_error($activate)) {
+ echo "Error activating plugin: " . $activate->get_error_message() . "\n";
+ } else {
+ echo "Plugin activated successfully.\n";
+
+ // Create .env file with Zoho settings
+ $env_file = $plugin_dir . '/.env';
+ $env_content = "# Zoho API Credentials\n";
+ $env_content .= "ZOHO_CLIENT_ID=your_client_id_here\n";
+ $env_content .= "ZOHO_CLIENT_SECRET=your_client_secret_here\n";
+ $env_content .= "ZOHO_REDIRECT_URI={$staging_url}/wp-admin/admin-ajax.php?action=zoho_oauth_callback\n";
+ $env_content .= "ZOHO_REFRESH_TOKEN=your_refresh_token_here\n\n";
+ $env_content .= "# Site URL Settings\n";
+ $env_content .= "UPSKILL_STAGING_URL={$staging_url}\n";
+
+ if (file_put_contents($env_file, $env_content)) {
+ echo "Created .env file with default settings.\n";
+ } else {
+ echo "Could not create .env file. Please create it manually.\n";
+ }
+ }
+ } else {
+ echo "Error installing plugin.\n";
+ if (is_wp_error($skin->result)) {
+ echo "Error: " . $skin->result->get_error_message() . "\n";
+ }
+ }
+ echo '';
+ ?>
+
+
+
+
+
Plugin Installation Form
+
+
+
+
+
Manual Plugin Upload
+
If the automatic installation fails, you can manually upload the plugin:
+
+ - Go to WordPress Plugin Upload
+ - Upload the plugin ZIP file
+ - Activate the plugin
+
+
+
+
+
Create .env File
+
After installing the plugin, create a .env file in the plugin directory with these settings:
+
# Zoho API Credentials
+ZOHO_CLIENT_ID=your_client_id_here
+ZOHO_CLIENT_SECRET=your_client_secret_here
+ZOHO_REDIRECT_URI=/wp-admin/admin-ajax.php?action=zoho_oauth_callback
+ZOHO_REFRESH_TOKEN=your_refresh_token_here
+
+# Site URL Settings
+UPSKILL_STAGING_URL=
+
+
+
+
Plugin Status
+ HVAC Community Events plugin is installed and active.';
+
+ // Check .env file
+ if (file_exists($plugin_dir . '/.env')) {
+ echo '
.env file exists in the plugin directory.
';
+ } else {
+ echo '
.env file does not exist in the plugin directory.
';
+ }
+ } else {
+ if (file_exists($plugin_dir)) {
+ echo '
HVAC Community Events plugin is installed but not active.
';
+ } else {
+ echo '
HVAC Community Events plugin is not installed.
';
+ }
+ }
+ ?>
+
+
+
+ "${ZOHO_CONFIG}" << 'EOPHP'
+get_modules();
+
+ // Enhanced error handling and detailed response
+ if ($response && !isset($response["error"])) {
+ wp_send_json_success(array(
+ "message" => "Connection successful!",
+ "modules" => isset($response["modules"]) ? count($response["modules"]) . " modules available" : "No modules found"
+ ));
+ } else {
+ $error_message = isset($response["error"]) ? $response["error"] : "Unknown error";
+ $error_code = isset($response["code"]) ? $response["code"] : "";
+ $error_details = isset($response["details"]) ? $response["details"] : "";
+
+ // Create debug info for troubleshooting
+ $debug_info = array();
+ $debug_info["timestamp"] = date("Y-m-d H:i:s");
+ $debug_info["php_version"] = phpversion();
+ $debug_info["site_url"] = function_exists("get_site_url") ? get_site_url() : "Unknown";
+
+ // Check if Zoho config constants are defined
+ $debug_info["config"] = array(
+ "ZOHO_CLIENT_ID" => defined("ZOHO_CLIENT_ID") ? "Defined" : "Not defined",
+ "ZOHO_CLIENT_SECRET" => defined("ZOHO_CLIENT_SECRET") ? "Defined" : "Not defined",
+ "ZOHO_REDIRECT_URI" => defined("ZOHO_REDIRECT_URI") ? ZOHO_REDIRECT_URI : "Not defined",
+ "ZOHO_REFRESH_TOKEN" => defined("ZOHO_REFRESH_TOKEN") ? "Defined" : "Not defined"
+ );
+
+ // Domain information
+ $known_domains = array("wordpress-974670-5399585.cloudwaysapps.com", "upskill-staging.measurequick.com");
+ $current_domain = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "Unknown";
+ $debug_info["domain"] = array(
+ "current" => $current_domain,
+ "matches_known" => in_array($current_domain, $known_domains) ? "Yes" : "No",
+ "known_domains" => $known_domains
+ );
+
+ // Log the error
+ if (defined("ZOHO_DEBUG_MODE") && ZOHO_DEBUG_MODE) {
+ $timestamp = date("Y-m-d H:i:s");
+ $log_message = "[$timestamp] Connection test failed: $error_message\n";
+ $log_message .= "[$timestamp] Error code: $error_code\n";
+ $log_message .= "[$timestamp] Details: $error_details\n";
+ $log_message .= "[$timestamp] Raw response: " . json_encode($response) . "\n";
+ $log_message .= "[$timestamp] Debug info: " . json_encode($debug_info) . "\n";
+
+ if (defined("ZOHO_LOG_FILE")) {
+ error_log($log_message, 3, ZOHO_LOG_FILE);
+ }
+ }
+
+ // Send detailed error data back to frontend
+ wp_send_json_error(array(
+ "message" => "Connection failed",
+ "error" => $error_message,
+ "code" => $error_code,
+ "details" => $error_details,
+ "raw" => json_encode($response),
+ "debug" => $debug_info,
+ "help" => "Verify that your Zoho credentials are correct and that your redirect URI matches your current domain."
+ ));
+ }
+ }'
+
+ # Replace the method in the file
+ sed -i.tmp2 "s|$(echo "$TEST_CONN_METHOD" | sed 's/[\/&]/\\&/g')|$TEST_CONN_ENHANCED|g" "${ZOHO_ADMIN}"
+
+ # Remove temp files
+ rm -f "${ZOHO_ADMIN}.tmp2"
+ echo -e "${GREEN}✓ Admin class updated with enhanced error reporting${NC}"
+ fi
+ else
+ echo -e "${YELLOW}⚠ test_connection method not found in admin class${NC}"
+ fi
+else
+ echo -e "${YELLOW}⚠ Zoho admin class not found, creating new one...${NC}"
+ mkdir -p "${TEMP_DIR}/${PLUGIN_NAME}/includes/admin"
+
+ cat > "${ZOHO_ADMIN}" << 'EOPHP'
+ admin_url( 'admin-ajax.php' ),
+ 'nonce' => wp_create_nonce( 'hvac_zoho_admin_nonce' ),
+ ) );
+ }
+
+ /**
+ * Render admin page.
+ */
+ public function render_admin_page() {
+ // Include Zoho config
+ require_once HVAC_CE_PLUGIN_DIR . 'includes/zoho/zoho-config.php';
+
+ // Get Zoho CRM Auth instance
+ $zoho_auth = HVAC_Zoho_CRM_Auth::get_instance();
+
+ // Check if Zoho client ID is defined
+ $client_id_defined = defined( 'ZOHO_CLIENT_ID' ) && ! empty( ZOHO_CLIENT_ID );
+ $client_secret_defined = defined( 'ZOHO_CLIENT_SECRET' ) && ! empty( ZOHO_CLIENT_SECRET );
+ $redirect_uri_defined = defined( 'ZOHO_REDIRECT_URI' ) && ! empty( ZOHO_REDIRECT_URI );
+
+ // Get site URL for display
+ $site_url = function_exists( 'get_site_url' ) ? get_site_url() : 'Unknown';
+
+ ?>
+
+ get_modules();
+
+ // Enhanced error handling and detailed response
+ if ($response && !isset($response["error"])) {
+ wp_send_json_success(array(
+ "message" => "Connection successful!",
+ "modules" => isset($response["modules"]) ? count($response["modules"]) . " modules available" : "No modules found"
+ ));
+ } else {
+ $error_message = isset($response["error"]) ? $response["error"] : "Unknown error";
+ $error_code = isset($response["code"]) ? $response["code"] : "";
+ $error_details = isset($response["details"]) ? $response["details"] : "";
+
+ // Create debug info for troubleshooting
+ $debug_info = array();
+ $debug_info["timestamp"] = date("Y-m-d H:i:s");
+ $debug_info["php_version"] = phpversion();
+ $debug_info["site_url"] = function_exists("get_site_url") ? get_site_url() : "Unknown";
+
+ // Check if Zoho config constants are defined
+ $debug_info["config"] = array(
+ "ZOHO_CLIENT_ID" => defined("ZOHO_CLIENT_ID") ? "Defined" : "Not defined",
+ "ZOHO_CLIENT_SECRET" => defined("ZOHO_CLIENT_SECRET") ? "Defined" : "Not defined",
+ "ZOHO_REDIRECT_URI" => defined("ZOHO_REDIRECT_URI") ? ZOHO_REDIRECT_URI : "Not defined",
+ "ZOHO_REFRESH_TOKEN" => defined("ZOHO_REFRESH_TOKEN") ? "Defined" : "Not defined"
+ );
+
+ // Domain information
+ $known_domains = array("wordpress-974670-5399585.cloudwaysapps.com", "upskill-staging.measurequick.com");
+ $current_domain = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "Unknown";
+ $debug_info["domain"] = array(
+ "current" => $current_domain,
+ "matches_known" => in_array($current_domain, $known_domains) ? "Yes" : "No",
+ "known_domains" => $known_domains
+ );
+
+ // Log the error
+ if (defined("ZOHO_DEBUG_MODE") && ZOHO_DEBUG_MODE) {
+ $timestamp = date("Y-m-d H:i:s");
+ $log_message = "[$timestamp] Connection test failed: $error_message\n";
+ $log_message .= "[$timestamp] Error code: $error_code\n";
+ $log_message .= "[$timestamp] Details: $error_details\n";
+ $log_message .= "[$timestamp] Raw response: " . json_encode($response) . "\n";
+ $log_message .= "[$timestamp] Debug info: " . json_encode($debug_info) . "\n";
+
+ if (defined("ZOHO_LOG_FILE")) {
+ error_log($log_message, 3, ZOHO_LOG_FILE);
+ }
+ }
+
+ // Send detailed error data back to frontend
+ wp_send_json_error(array(
+ "message" => "Connection failed",
+ "error" => $error_message,
+ "code" => $error_code,
+ "details" => $error_details,
+ "raw" => json_encode($response),
+ "debug" => $debug_info,
+ "help" => "Verify that your Zoho credentials are correct and that your redirect URI matches your current domain."
+ ));
+ }
+ }
+}
+
+// Initialize the admin class
+HVAC_Zoho_Admin::get_instance();
+EOPHP
+ echo -e "${GREEN}✓ New Zoho admin class created with enhanced error reporting${NC}"
+fi
+
+# Create JS and CSS files for admin interface
+echo -e "${YELLOW}Step 5: Creating JS and CSS files for admin interface...${NC}"
+mkdir -p "${TEMP_DIR}/${PLUGIN_NAME}/assets/js"
+mkdir -p "${TEMP_DIR}/${PLUGIN_NAME}/assets/css"
+
+# Create JS file
+cat > "${TEMP_DIR}/${PLUGIN_NAME}/assets/js/zoho-admin.js" << 'EOJS'
+jQuery(document).ready(function($) {
+ $('#hvac-zoho-test-connection').on('click', function(e) {
+ e.preventDefault();
+
+ var $button = $(this);
+ var $result = $('#hvac-zoho-test-connection-result');
+
+ $button.prop('disabled', true);
+ $result.html('');
+
+ $.ajax({
+ url: hvac_zoho_admin.ajax_url,
+ type: 'POST',
+ data: {
+ action: 'hvac_zoho_test_connection',
+ nonce: hvac_zoho_admin.nonce
+ },
+ success: function(response) {
+ $button.prop('disabled', false);
+ $result.empty();
+
+ if (response.success) {
+ var successHtml = '';
+ successHtml += '
' + response.data.message + '
';
+
+ if (response.data.modules) {
+ successHtml += '
' + response.data.modules + '
';
+ }
+
+ successHtml += '
';
+
+ $result.html(successHtml);
+ } else {
+ $result.html('Connection test failed. Please check the logs.
');
+ }
+ },
+ error: function(xhr) {
+ $button.prop('disabled', false);
+ $result.empty();
+
+ // Try to parse the response JSON
+ var response = { success: false };
+ try {
+ if (xhr.responseJSON) {
+ response = xhr.responseJSON;
+ } else if (xhr.responseText) {
+ response = JSON.parse(xhr.responseText);
+ }
+ } catch (e) {
+ console.error('Error parsing response:', e);
+ }
+
+ // Create detailed error display
+ var errorHtml = '';
+ errorHtml += '
' + (response.data ? response.data.message : 'Connection failed') + ': ' +
+ (response.data && response.data.error ? response.data.error : 'Unknown error') + '
';
+
+ // Add error code if available
+ if (response.data && response.data.code) {
+ errorHtml += '
Error Code: ' + response.data.code + '
';
+ }
+
+ // Add debugging info
+ errorHtml += '
';
+ // Add details if available
+ if (response.data && response.data.details) {
+ errorHtml += '
Details: ' + response.data.details + '
';
+ }
+
+ // Add debug info if available
+ if (response.data && response.data.debug) {
+ errorHtml += '
';
+ errorHtml += 'Debug Information (click to expand)
';
+ errorHtml += '' + JSON.stringify(response.data.debug, null, 2) + '
';
+ errorHtml += ' ';
+ }
+
+ // Add raw response data if available
+ if (response.data && response.data.raw) {
+ try {
+ errorHtml += '
';
+ errorHtml += 'Raw Response Data (click to expand)
';
+ errorHtml += '' + JSON.stringify(JSON.parse(response.data.raw), null, 2) + '
';
+ errorHtml += ' ';
+ } catch (e) {
+ errorHtml += '
Raw response data is available but could not be parsed: ' + e.message + '
';
+ }
+ }
+
+ // Add help text if available
+ if (response.data && response.data.help) {
+ errorHtml += '
Help: ' + response.data.help + '
';
+ }
+
+ errorHtml += '
'; // Close debug info div
+ errorHtml += '
'; // Close notice div
+
+ $result.html(errorHtml);
+ }
+ });
+ });
+});
+EOJS
+
+# Create CSS file
+cat > "${TEMP_DIR}/${PLUGIN_NAME}/assets/css/zoho-admin.css" << 'EOCSS'
+/* Zoho Admin Styles */
+.hvac-zoho-settings {
+ margin-top: 20px;
+ padding: 20px;
+ background: #fff;
+ border: 1px solid #ccd0d4;
+ box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+}
+
+.hvac-zoho-instructions {
+ margin-top: 20px;
+ padding: 15px;
+ background: #f9f9f9;
+ border-left: 4px solid #0073aa;
+}
+
+.hvac-zoho-debug-info {
+ margin-top: 15px;
+ padding: 15px;
+ background: #f9f9f9;
+ border: 1px solid #ddd;
+ border-left: 4px solid #dc3232;
+}
+
+.hvac-zoho-debug-info details summary {
+ cursor: pointer;
+ font-weight: bold;
+ color: #0073aa;
+ padding: 5px;
+ background: #f0f0f0;
+}
+
+.hvac-zoho-debug-info pre {
+ margin: 10px 0;
+ padding: 10px;
+ background: #f0f0f0;
+ border: 1px solid #ddd;
+ overflow: auto;
+ max-height: 300px;
+}
+EOCSS
+
+echo -e "${GREEN}✓ JS and CSS files created${NC}"
+
+# Create diagnostic tools
+echo -e "${YELLOW}Step 6: Creating diagnostic tools...${NC}"
+mkdir -p "${TEMP_DIR}/${PLUGIN_NAME}/includes/zoho"
+
+# Create diagnostics.php
+cat > "${TEMP_DIR}/${PLUGIN_NAME}/includes/zoho/diagnostics.php" << 'EOPHP'
+ "${TEMP_DIR}/${PLUGIN_NAME}/.env" << EOENV
+# Zoho API Credentials
+ZOHO_CLIENT_ID=1000.Z0HOF1VMMJ9W2QWSU57GVQYEAVUSKS
+ZOHO_CLIENT_SECRET=36913615664649dbf9198884bfd1096f7573c9ce2b
+ZOHO_REDIRECT_URI=https://${NEW_DOMAIN}/wp-admin/admin-ajax.php?action=zoho_oauth_callback
+
+# Site URL Settings
+UPSKILL_STAGING_URL=https://${NEW_DOMAIN}
+EOENV
+
+echo -e "${GREEN}✓ .env file created${NC}"
+
+# Create deployment package
+echo -e "${YELLOW}Step 8: Creating deployment package...${NC}"
+cd "${TEMP_DIR}"
+zip -r "${PACKAGE_NAME}" "${PLUGIN_NAME}" -x "*.DS_Store" -x "*.git*"
+
+# Move the package to a known location
+if [[ ! -d "../plugin-backups" ]]; then
+ mkdir -p "../plugin-backups"
+fi
+
+mv "${PACKAGE_NAME}" "../plugin-backups/${PACKAGE_NAME}"
+echo -e "${GREEN}✓ Deployment package created at: plugin-backups/${PACKAGE_NAME}${NC}"
+
+# Create web deployment instructions
+echo -e "${YELLOW}Step 9: Creating web deployment instructions...${NC}"
+cat > "plugin-backups/deployment-instructions.txt" << EOINSTRUCT
+HVAC Community Events Plugin Deployment Instructions
+===================================================
+
+The plugin package has been created with the domain update fixes. Follow these steps to deploy:
+
+1. Log into WordPress admin at https://${NEW_DOMAIN}/wp-admin/
+
+2. Navigate to Plugins > Add New > Upload Plugin
+
+3. Click "Choose File" and select the plugin package at:
+ ${PWD}/plugin-backups/${PACKAGE_NAME}
+
+4. Click "Install Now"
+
+5. After installation, click "Activate Plugin"
+
+6. Verify the plugin is working by checking:
+ - https://${NEW_DOMAIN}/trainer-dashboard/
+ - https://${NEW_DOMAIN}/wp-admin/admin.php?page=hvac-zoho-sync
+
+7. Test the Zoho CRM integration:
+ - Go to Events > Zoho CRM Sync
+ - Click "Test Connection"
+ - Check for any errors and verify the domain is correctly set
+
+8. If needed, run the diagnostics tool:
+ https://${NEW_DOMAIN}/wp-content/plugins/hvac-community-events/includes/zoho/diagnostics.php?run_diagnostics=true
+EOINSTRUCT
+
+echo -e "${GREEN}✓ Deployment instructions created at: plugin-backups/deployment-instructions.txt${NC}"
+
+# Create E2E test for domain verification
+echo -e "${YELLOW}Step 10: Creating E2E test for domain verification...${NC}"
+cat > "../tests/e2e/domain-verification-comprehensive.test.ts" << EOTS
+import { test, expect } from '@playwright/test';
+
+test.describe('Domain Migration Verification', () => {
+ const OLD_DOMAIN = 'wordpress-974670-5399585.cloudwaysapps.com';
+ const NEW_DOMAIN = 'upskill-staging.measurequick.com';
+
+ test('verify site accessibility with new domain', async ({ page }) => {
+ console.log('Checking site accessibility with new domain...');
+
+ // Check if the site is accessible
+ await page.goto(`https://${NEW_DOMAIN}/`);
+ const title = await page.title();
+ console.log(`Site title: ${title}`);
+ expect(title).toContain('Upskill HVAC');
+
+ // Check for HVAC plugin indicators
+ const cssFiles = await page.locator('link[href*="hvac"]').count();
+ const jsFiles = await page.locator('script[src*="hvac"]').count();
+ const hvacClasses = await page.locator('[class*="hvac"]').count();
+
+ console.log(`Found ${cssFiles} HVAC CSS files, ${jsFiles} JS files, and ${hvacClasses} HVAC classes`);
+
+ // Check if trainer dashboard exists
+ await page.goto(`https://${NEW_DOMAIN}/trainer-dashboard/`);
+ const dashboardExists = !await page.locator('body:has-text("Page not found")').isVisible();
+ console.log(`Trainer dashboard exists: ${dashboardExists}`);
+
+ // Check WordPress admin
+ await page.goto(`https://${NEW_DOMAIN}/wp-admin/`);
+ const currentUrl = page.url();
+ console.log(`WordPress admin redirects to: ${currentUrl}`);
+ expect(currentUrl).toContain('wp-login.php');
+
+ // Check for old domain references in HTML
+ await page.goto(`https://${NEW_DOMAIN}/`);
+ const pageContent = await page.content();
+ const oldDomainReferences = pageContent.includes(OLD_DOMAIN);
+ console.log(`Page contains references to old domain: ${oldDomainReferences}`);
+ expect(oldDomainReferences).toBe(false);
+
+ // Check Zoho admin page if logged in
+ try {
+ await page.goto(`https://${NEW_DOMAIN}/wp-admin/`);
+ await page.fill('#user_login', 'admin');
+ await page.fill('#user_pass', 'password'); // Replace with actual password
+ await page.click('#wp-submit');
+
+ const loginSuccessful = await page.locator('#wpadminbar').isVisible();
+
+ if (loginSuccessful) {
+ console.log('Login successful, checking Zoho admin page...');
+ await page.goto(`https://${NEW_DOMAIN}/wp-admin/admin.php?page=hvac-zoho-sync`);
+
+ const zohoPageExists = await page.locator('h1:has-text("Zoho CRM Integration")').isVisible();
+ console.log(`Zoho admin page exists: ${zohoPageExists}`);
+
+ if (zohoPageExists) {
+ const redirectUri = await page.locator('code:near(:text("Redirect URI"))').textContent();
+ console.log(`Zoho redirect URI: ${redirectUri}`);
+ expect(redirectUri).not.toContain(OLD_DOMAIN);
+ expect(redirectUri).toContain(NEW_DOMAIN);
+ }
+ } else {
+ console.log('Login failed, skipping Zoho admin page check');
+ }
+ } catch (error) {
+ console.log(`Error checking Zoho admin page: ${error.message}`);
+ }
+ });
+
+ test('verify key pages work with new domain', async ({ page }) => {
+ // List of key pages to check
+ const pagesToCheck = [
+ '/',
+ '/community-registration/',
+ '/community-login/',
+ '/trainer-dashboard/',
+ '/events/create/',
+ '/generate-certificates/',
+ '/certificates-report/'
+ ];
+
+ console.log('Checking key pages with new domain...');
+
+ for (const pagePath of pagesToCheck) {
+ const url = `https://${NEW_DOMAIN}${pagePath}`;
+ console.log(`Checking page: ${url}`);
+
+ await page.goto(url);
+ const title = await page.title();
+ const is404 = title.includes('Page not found') || title.includes('404');
+
+ console.log(`- ${pagePath}: ${is404 ? 'Not Found (404)' : 'Available'}`);
+
+ // Check for old domain references
+ if (!is404) {
+ const pageContent = await page.content();
+ const hasOldDomain = pageContent.includes(OLD_DOMAIN);
+ console.log(` - Contains old domain references: ${hasOldDomain}`);
+
+ if (hasOldDomain) {
+ console.log(' - WARNING: Page contains references to old domain!');
+ }
+ }
+ }
+ });
+});
+EOTS
+
+echo -e "${GREEN}✓ E2E test created at: tests/e2e/domain-verification-comprehensive.test.ts${NC}"
+
+# Clean up
+echo -e "${YELLOW}Step 11: Cleaning up temporary files...${NC}"
+rm -rf "${TEMP_DIR}"
+echo -e "${GREEN}✓ Temporary files cleaned up${NC}"
+
+# Summary
+echo -e "${GREEN}==============================================${NC}"
+echo -e "${GREEN}HVAC Community Events Plugin Update Complete!${NC}"
+echo -e "${GREEN}==============================================${NC}"
+echo -e "The plugin has been updated with the following changes:"
+echo -e "1. Dynamic domain detection for Zoho CRM integration"
+echo -e "2. Enhanced error reporting with detailed debugging"
+echo -e "3. Created deployment package with all fixes"
+echo -e "4. Added comprehensive E2E tests for domain verification"
+echo -e "5. Created web deployment instructions"
+echo -e
+echo -e "Next steps:"
+echo -e "1. Deploy the plugin using the web installer:"
+echo -e " ${PWD}/plugin-backups/${PACKAGE_NAME}"
+echo -e "2. Run the E2E tests to verify the domain migration:"
+echo -e " npx playwright test tests/e2e/domain-verification-comprehensive.test.ts"
+echo -e
+echo -e "For detailed instructions, see:"
+echo -e "${PWD}/plugin-backups/deployment-instructions.txt"
+echo -e "${GREEN}==============================================${NC}"
\ No newline at end of file
diff --git a/wordpress-dev/bin/deploy-plugin-package.sh b/wordpress-dev/bin/deploy-plugin-package.sh
new file mode 100755
index 00000000..4aef63fc
--- /dev/null
+++ b/wordpress-dev/bin/deploy-plugin-package.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+# Script to deploy the HVAC Community Events plugin to staging
+# This uses a web-based approach since SSH may have permission issues
+
+# Configuration
+STAGING_URL="https://upskill-staging.measurequick.com"
+PLUGIN_DIR="/Users/ben/dev/upskill-event-manager/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events"
+TEMP_DIR="/tmp/hvac-plugin-deploy"
+PACKAGE_NAME="hvac-community-events.zip"
+WP_ADMIN="${STAGING_URL}/wp-admin"
+UPLOAD_URL="${WP_ADMIN}/plugin-install.php?tab=upload"
+
+# Create deployment package
+echo "Creating plugin deployment package..."
+mkdir -p "$TEMP_DIR"
+cd "$PLUGIN_DIR" || { echo "Error: Plugin directory not found"; exit 1; }
+zip -r "$TEMP_DIR/$PACKAGE_NAME" . -x "*.git*" -x "*.DS_Store" -x "*.idea*" -x "node_modules/*" -x "vendor/*"
+
+echo "Plugin package created at: $TEMP_DIR/$PACKAGE_NAME"
+echo "Package size: $(du -h $TEMP_DIR/$PACKAGE_NAME | cut -f1)"
+
+# Open browser to upload page
+echo "Please manually upload the plugin package at: $TEMP_DIR/$PACKAGE_NAME"
+echo "Upload URL: $UPLOAD_URL"
+
+# Instructions for manual upload and activation
+echo "=== Manual Upload Instructions ==="
+echo "1. Navigate to: $UPLOAD_URL"
+echo "2. Login with your admin credentials"
+echo "3. Click 'Browse' and select the file at: $TEMP_DIR/$PACKAGE_NAME"
+echo "4. Click 'Install Now'"
+echo "5. Once installed, click 'Activate Plugin'"
+echo "6. Verify the plugin is active at ${WP_ADMIN}/plugins.php"
+
+# Open browser to upload URL
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ open "$UPLOAD_URL"
+elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ xdg-open "$UPLOAD_URL"
+fi
+
+# Create instructions for creating the .env file with required Zoho settings
+cat > "$TEMP_DIR/zoho-env-instructions.txt" << EOF
+### IMPORTANT: After plugin activation, create a .env file in the plugin directory with the following settings:
+
+# Create this file at: /wp-content/plugins/hvac-community-events/.env
+
+# Zoho API Credentials
+ZOHO_CLIENT_ID=your_client_id_here
+ZOHO_CLIENT_SECRET=your_client_secret_here
+ZOHO_REDIRECT_URI=${STAGING_URL}/wp-admin/admin-ajax.php?action=zoho_oauth_callback
+ZOHO_REFRESH_TOKEN=your_refresh_token_here
+
+# Site URL Settings
+UPSKILL_STAGING_URL=${STAGING_URL}
+
+# Create this file using the WordPress file editor or via FTP
+EOF
+
+echo "Zoho environment instructions created at: $TEMP_DIR/zoho-env-instructions.txt"
+echo "Done! Follow the instructions above to complete the installation."
\ No newline at end of file
diff --git a/wordpress-dev/tests/e2e/login-troubleshooting.test.ts b/wordpress-dev/tests/e2e/login-troubleshooting.test.ts
new file mode 100644
index 00000000..51e0213d
--- /dev/null
+++ b/wordpress-dev/tests/e2e/login-troubleshooting.test.ts
@@ -0,0 +1,104 @@
+import { test, expect } from '@playwright/test';
+import { STAGING_URL } from './config/staging-config';
+
+/**
+ * Test to troubleshoot login-related issues
+ * This test checks different login selectors and error message patterns
+ */
+test.describe('Login Troubleshooting', () => {
+ test('Analyze login form and error messages', async ({ page }) => {
+ // Navigate to login page
+ await page.goto(`${STAGING_URL}/community-login/`);
+ await page.waitForLoadState('networkidle');
+
+ console.log(`Current URL: ${page.url()}`);
+ console.log(`Page title: ${await page.title()}`);
+
+ // Take screenshot of login page
+ await page.screenshot({ path: 'test-results/login-form.png' });
+
+ // Check for form elements
+ const usernameField = page.locator('#user_login');
+ const passwordField = page.locator('#user_pass');
+ const submitButton = page.locator('#wp-submit');
+
+ console.log(`Username field visible: ${await usernameField.isVisible()}`);
+ console.log(`Password field visible: ${await passwordField.isVisible()}`);
+ console.log(`Submit button visible: ${await submitButton.isVisible()}`);
+
+ // Check if form is in an iframe
+ const loginIframe = page.frameLocator('iframe[name="login-form"]').first();
+ const iframeExists = await page.locator('iframe[name="login-form"]').count() > 0;
+ console.log(`Login form in iframe: ${iframeExists}`);
+
+ // Test with valid credentials first
+ await usernameField.fill('test_trainer');
+ await passwordField.fill('Test123!');
+ await submitButton.click();
+
+ // Wait for navigation
+ await page.waitForLoadState('networkidle');
+ console.log(`After login URL: ${page.url()}`);
+ console.log(`After login title: ${await page.title()}`);
+
+ // Take screenshot after login
+ await page.screenshot({ path: 'test-results/after-login.png' });
+
+ // Navigate back to login
+ await page.goto(`${STAGING_URL}/community-login/`);
+ await page.waitForLoadState('networkidle');
+
+ // Test with invalid credentials
+ await usernameField.fill('invalid_user');
+ await passwordField.fill('wrong_password');
+ await submitButton.click();
+
+ // Wait for potential error message
+ await page.waitForLoadState('networkidle');
+
+ // Take screenshot of error state
+ await page.screenshot({ path: 'test-results/login-error.png' });
+
+ // Check all possible error message selectors
+ const errorSelectors = [
+ '.login-error',
+ '.login_error',
+ '#login_error',
+ '.error',
+ '.message',
+ '.notice-error',
+ '.woocommerce-error',
+ '.wp-die-message',
+ 'p.error',
+ 'div.error'
+ ];
+
+ console.log('Checking error message selectors:');
+ for (const selector of errorSelectors) {
+ const count = await page.locator(selector).count();
+ const visible = count > 0 ? await page.locator(selector).isVisible() : false;
+ const text = visible ? await page.locator(selector).textContent() : 'N/A';
+
+ console.log(`- Selector: ${selector}`);
+ console.log(` Count: ${count}`);
+ console.log(` Visible: ${visible}`);
+ console.log(` Text: ${text}`);
+ }
+
+ // Check error message in page content
+ const pageContent = await page.content();
+ console.log('Page content contains:');
+ console.log(`- "Invalid username": ${pageContent.includes('Invalid username')}`);
+ console.log(`- "incorrect password": ${pageContent.includes('incorrect password')}`);
+ console.log(`- "Unknown username": ${pageContent.includes('Unknown username')}`);
+ console.log(`- "Error": ${pageContent.includes('Error')}`);
+
+ // Check DOM structure around form
+ const formParent = await page.evaluate(() => {
+ const form = document.querySelector('form');
+ return form ? form.parentElement?.tagName + '#' + form.parentElement?.id + '.' + form.parentElement?.className : 'Not found';
+ });
+
+ console.log(`Form parent element: ${formParent}`);
+ });
+});
\ No newline at end of file