/** * Care API Documentation Admin JavaScript * * @package Care_API */ (function($) { 'use strict'; var CareAPIDocs = { /** * Initialize the documentation interface */ init: function() { this.bindEvents(); this.initializeTabs(); this.initializeCodeEditor(); this.loadStoredToken(); }, /** * Bind event handlers */ bindEvents: function() { // Toggle endpoint groups $(document).on('click', '.endpoint-group-header', this.toggleEndpointGroup); // Toggle individual endpoints $(document).on('click', '.endpoint-header', this.toggleEndpoint); // Copy code examples $(document).on('click', '.copy-button', this.copyToClipboard); // API Tester form submission $(document).on('click', '.test-button', this.testEndpoint); // Generate test token $(document).on('click', '.generate-token-button', this.generateTestToken); // Method selection change $(document).on('change', '#test-method', this.onMethodChange); // Endpoint selection change $(document).on('change', '#test-endpoint', this.onEndpointChange); // Auto-format JSON $(document).on('blur', '#test-body', this.formatJSON); }, /** * Initialize navigation tabs */ initializeTabs: function() { $('.nav-tab').on('click', function(e) { e.preventDefault(); var target = $(this).data('tab'); // Update active tab $('.nav-tab').removeClass('nav-tab-active'); $(this).addClass('nav-tab-active'); // Show/hide content $('.tab-content').hide(); $('#' + target).show(); }); }, /** * Initialize code editor for JSON formatting */ initializeCodeEditor: function() { if (typeof wp !== 'undefined' && wp.codeEditor) { var editorSettings = wp.codeEditor.defaultSettings ? _.clone(wp.codeEditor.defaultSettings) : {}; editorSettings.codemirror = _.extend( {}, editorSettings.codemirror, { mode: 'application/json', lineNumbers: true, autoCloseBrackets: true, matchBrackets: true, lint: true } ); // Initialize code editors $('.json-editor').each(function() { wp.codeEditor.initialize($(this), editorSettings); }); } }, /** * Load stored authentication token */ loadStoredToken: function() { var storedToken = localStorage.getItem('care_api_test_token'); if (storedToken) { $('#test-token').val(storedToken); } }, /** * Toggle endpoint group visibility */ toggleEndpointGroup: function(e) { e.preventDefault(); var $group = $(this).closest('.endpoint-group'); $group.toggleClass('expanded'); }, /** * Toggle individual endpoint details */ toggleEndpoint: function(e) { e.preventDefault(); e.stopPropagation(); var $endpoint = $(this).closest('.endpoint-item'); $endpoint.toggleClass('expanded'); }, /** * Copy text to clipboard */ copyToClipboard: function(e) { e.preventDefault(); var $button = $(this); var $codeContent = $button.closest('.code-example').find('.code-content'); var text = $codeContent.text(); navigator.clipboard.writeText(text).then(function() { $button.text(care_api_docs.strings.copy_success); setTimeout(function() { $button.html(''); }, 2000); }).catch(function(err) { console.error('Could not copy text: ', err); }); }, /** * Test API endpoint */ testEndpoint: function(e) { e.preventDefault(); var $button = $(this); var $form = $button.closest('form'); var $responseSection = $('.response-section'); // Get form data var method = $('#test-method').val(); var endpoint = $('#test-endpoint').val(); var token = $('#test-token').val(); var body = $('#test-body').val(); var headers = $('#test-headers').val(); // Validate required fields if (!method || !endpoint) { CareAPIDocs.showNotice('Please select method and endpoint', 'error'); return; } // Show loading state $button.prop('disabled', true).text(care_api_docs.strings.testing); $responseSection.hide(); // Prepare request data var requestData = { action: 'care_api_test_endpoint', nonce: care_api_docs.nonce, method: method, endpoint: endpoint, token: token, body: body, headers: headers }; // Store token for future use if (token) { localStorage.setItem('care_api_test_token', token); } // Make AJAX request $.ajax({ url: care_api_docs.ajax_url, type: 'POST', data: requestData, success: function(response) { if (response.success) { CareAPIDocs.displayResponse(response.data); CareAPIDocs.showNotice(care_api_docs.strings.success, 'success'); } else { CareAPIDocs.showNotice(response.data.message || care_api_docs.strings.error, 'error'); } }, error: function(xhr, status, error) { CareAPIDocs.showNotice('Request failed: ' + error, 'error'); }, complete: function() { $button.prop('disabled', false).text('Test Endpoint'); } }); }, /** * Generate test authentication token */ generateTestToken: function(e) { e.preventDefault(); var $button = $(this); $button.prop('disabled', true).text('Generating...'); $.ajax({ url: care_api_docs.ajax_url, type: 'POST', data: { action: 'care_api_generate_token', nonce: care_api_docs.nonce }, success: function(response) { if (response.success) { $('#test-token').val(response.data.token); localStorage.setItem('care_api_test_token', response.data.token); CareAPIDocs.showNotice('Token generated successfully!', 'success'); // Show user info CareAPIDocs.displayUserInfo(response.data.user); } else { CareAPIDocs.showNotice(response.data.message || 'Failed to generate token', 'error'); } }, error: function() { CareAPIDocs.showNotice('Failed to generate token', 'error'); }, complete: function() { $button.prop('disabled', false).text('Generate Token'); } }); }, /** * Handle method selection change */ onMethodChange: function() { var method = $(this).val(); var $bodyGroup = $('.body-group'); // Show/hide body field based on method if (method === 'GET' || method === 'DELETE') { $bodyGroup.hide(); } else { $bodyGroup.show(); } }, /** * Handle endpoint selection change */ onEndpointChange: function() { var endpoint = $(this).val(); var $bodyField = $('#test-body'); // Auto-populate example request body if available var exampleData = CareAPIDocs.getExampleRequestBody(endpoint); if (exampleData) { $bodyField.val(JSON.stringify(exampleData, null, 2)); } }, /** * Format JSON in textarea */ formatJSON: function() { var $textarea = $(this); var value = $textarea.val().trim(); if (value) { try { var parsed = JSON.parse(value); var formatted = JSON.stringify(parsed, null, 2); $textarea.val(formatted); } catch (e) { // Invalid JSON, leave as is } } }, /** * Display API response */ displayResponse: function(data) { var $responseSection = $('.response-section'); var $statusElement = $('.response-status'); var $headersElement = $('.response-headers pre'); var $bodyElement = $('.response-body pre'); // Update status $statusElement.removeClass('status-success status-error status-warning'); var statusClass = 'status-success'; if (data.status_code >= 400) { statusClass = 'status-error'; } else if (data.status_code >= 300) { statusClass = 'status-warning'; } $statusElement.addClass(statusClass).text('HTTP ' + data.status_code); // Update headers var headersText = ''; if (data.headers && typeof data.headers === 'object') { for (var header in data.headers) { headersText += header + ': ' + data.headers[header] + '\n'; } } $headersElement.text(headersText || 'No headers'); // Update body var bodyText = data.body || ''; if (data.formatted_body && typeof data.formatted_body === 'object') { bodyText = JSON.stringify(data.formatted_body, null, 2); } $bodyElement.text(bodyText || 'No response body'); // Syntax highlight JSON CareAPIDocs.highlightJSON($bodyElement); // Show response section $responseSection.show(); }, /** * Display user information */ displayUserInfo: function(user) { var $userInfo = $('.user-info'); if ($userInfo.length === 0) { $userInfo = $('
'); $('.generate-token-button').after($userInfo); } var html = 'Current User: ' + user.username + ' (' + user.role + ')' + '
Email: ' + user.email; $userInfo.html(html).show(); }, /** * Get example request body for endpoint */ getExampleRequestBody: function(endpoint) { var examples = { '/auth/login': { username: 'doctor_john', password: 'secure_password' }, '/clinics': { name: 'New Medical Center', email: 'info@newmedical.com', telephone_no: '+351 213 999 888', address: 'Avenida da República, 456', city: 'Porto', country: 'Portugal', specialties: ['Pediatrics', 'Dermatology'] }, '/patients': { first_name: 'João', last_name: 'Silva', email: 'joao@email.com', phone: '+351912345678', birth_date: '1985-05-15', gender: 'M', clinic_id: 1 }, '/appointments': { patient_id: 123, doctor_id: 456, clinic_id: 1, appointment_start_date: '2024-12-20', appointment_start_time: '14:30:00', appointment_end_date: '2024-12-20', appointment_end_time: '15:00:00', visit_type: 'consultation', description: 'Regular checkup' } }; return examples[endpoint] || null; }, /** * Simple JSON syntax highlighting */ highlightJSON: function($element) { var text = $element.text(); try { var parsed = JSON.parse(text); var highlighted = JSON.stringify(parsed, null, 2); // Apply basic syntax highlighting highlighted = highlighted .replace(/"([^"]+)":/g, '"$1":') .replace(/: "([^"]+)"/g, ': "$1"') .replace(/: (\d+)/g, ': $1') .replace(/: (true|false)/g, ': $1') .replace(/: null/g, ': null'); $element.html(highlighted); } catch (e) { // Not valid JSON, leave as plain text } }, /** * Show notification message */ showNotice: function(message, type) { type = type || 'info'; var $notice = $('

' + message + '

'); $('.api-docs-content').prepend($notice); // Auto-remove after 5 seconds setTimeout(function() { $notice.fadeOut(function() { $notice.remove(); }); }, 5000); // Add dismiss functionality $notice.on('click', '.notice-dismiss', function() { $notice.fadeOut(function() { $notice.remove(); }); }); }, /** * Expand all endpoint groups */ expandAll: function() { $('.endpoint-group').addClass('expanded'); }, /** * Collapse all endpoint groups */ collapseAll: function() { $('.endpoint-group').removeClass('expanded'); $('.endpoint-item').removeClass('expanded'); }, /** * Filter endpoints by search term */ filterEndpoints: function(searchTerm) { searchTerm = searchTerm.toLowerCase(); $('.endpoint-item').each(function() { var $item = $(this); var title = $item.find('.endpoint-title').text().toLowerCase(); var path = $item.find('.endpoint-path').text().toLowerCase(); var description = $item.find('.endpoint-description').text().toLowerCase(); var matches = title.includes(searchTerm) || path.includes(searchTerm) || description.includes(searchTerm); $item.toggle(matches); }); // Hide empty groups $('.endpoint-group').each(function() { var $group = $(this); var hasVisibleItems = $group.find('.endpoint-item:visible').length > 0; $group.toggle(hasVisibleItems); }); } }; // Initialize when document is ready $(document).ready(function() { CareAPIDocs.init(); // Add search functionality var $searchInput = $(''); $('.api-docs-content').prepend($searchInput); $searchInput.on('input', function() { var searchTerm = $(this).val(); if (searchTerm.length > 2 || searchTerm.length === 0) { CareAPIDocs.filterEndpoints(searchTerm); } }); // Add expand/collapse all buttons var $controls = $('
' + '' + '' + '
'); $('.api-docs-content').prepend($controls); $('.expand-all').on('click', CareAPIDocs.expandAll); $('.collapse-all').on('click', CareAPIDocs.collapseAll); }); })(jQuery);