feat: Add comprehensive documentation suite and reorganize project structure

- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
This commit is contained in:
SamiAhmed7777
2025-10-21 00:39:45 -07:00
commit 0b7e2d0a5b
6080 changed files with 1332936 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
<?php
/**
* Search and Filter JavaScript for Admin Settings
* This file provides client-side search and filtering for settings
*/
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Add search box HTML if not already present
if (!document.getElementById('settings-search-container')) {
const searchHTML = `
<div id="settings-search-container" class="row mb-3">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-search"></i></span>
<input type="text" id="settings-search" class="form-control"
placeholder="Search settings... (Ctrl+K or Cmd+K)">
<button class="btn btn-outline-secondary" type="button" id="clear-search">
<i class="bi bi-x"></i>
</button>
</div>
<div id="search-results-count" class="text-muted small mt-1"></div>
</div>
<div class="col-md-4">
<select id="settings-category-filter" class="form-select">
<option value="">All Categories</option>
<option value="general">General</option>
<option value="modules">Modules</option>
<option value="branding">Branding</option>
<option value="payment">Payments</option>
<option value="email">Email</option>
<option value="payout">Payouts</option>
<option value="seo">SEO</option>
<option value="security">Security</option>
</select>
</div>
</div>
`;
// Insert before the tab content
const tabContent = document.querySelector('.tab-content');
if (tabContent) {
tabContent.insertAdjacentHTML('beforebegin', searchHTML);
}
}
const searchInput = document.getElementById('settings-search');
const clearBtn = document.getElementById('clear-search');
const categoryFilter = document.getElementById('settings-category-filter');
const resultsCount = document.getElementById('search-results-count');
if (!searchInput || !categoryFilter) return;
// Add data attributes to all form groups for searchability
function tagSettingFields() {
const currentTab = new URLSearchParams(window.location.search).get('tab') || 'general';
document.querySelectorAll('.mb-3, .form-group, .module-item').forEach(formGroup => {
const label = formGroup.querySelector('label, strong');
const input = formGroup.querySelector('input, select, textarea');
const helpText = formGroup.querySelector('.form-text, small');
if (label) {
const fieldName = input ? (input.name || input.id) : '';
const labelText = label.textContent.trim();
const helpContent = helpText ? helpText.textContent.trim() : '';
formGroup.setAttribute('data-setting-name', fieldName.toLowerCase());
formGroup.setAttribute('data-setting-label', labelText.toLowerCase());
formGroup.setAttribute('data-setting-info', helpContent.toLowerCase());
formGroup.setAttribute('data-setting-category', currentTab);
}
});
}
// Filter settings based on search and category
function filterSettings() {
const searchTerm = searchInput.value.toLowerCase().trim();
const category = categoryFilter.value;
let visibleCount = 0;
let totalCount = 0;
document.querySelectorAll('[data-setting-name]').forEach(element => {
totalCount++;
const name = element.getAttribute('data-setting-name') || '';
const label = element.getAttribute('data-setting-label') || '';
const info = element.getAttribute('data-setting-info') || '';
const settingCategory = element.getAttribute('data-setting-category') || '';
const matchesSearch = !searchTerm ||
name.includes(searchTerm) ||
label.includes(searchTerm) ||
info.includes(searchTerm);
const matchesCategory = !category || settingCategory === category;
const isVisible = matchesSearch && matchesCategory;
element.style.display = isVisible ? '' : 'none';
if (isVisible) visibleCount++;
});
updateResultCount(visibleCount, totalCount, searchTerm);
// Highlight search terms
if (searchTerm) {
highlightSearchTerms(searchTerm);
} else {
removeHighlights();
}
}
function updateResultCount(visible, total, searchTerm) {
if (!resultsCount) return;
if (searchTerm || categoryFilter.value) {
resultsCount.textContent = `Showing ${visible} of ${total} settings`;
resultsCount.style.display = 'block';
} else {
resultsCount.textContent = '';
resultsCount.style.display = 'none';
}
}
function highlightSearchTerms(term) {
removeHighlights();
document.querySelectorAll('[data-setting-name]:not([style*="display: none"])').forEach(element => {
const labels = element.querySelectorAll('label, .form-text, small');
labels.forEach(label => {
const text = label.textContent;
const regex = new RegExp(`(${term})`, 'gi');
if (regex.test(text)) {
label.innerHTML = text.replace(regex, '<mark>$1</mark>');
}
});
});
}
function removeHighlights() {
document.querySelectorAll('mark').forEach(mark => {
mark.replaceWith(mark.textContent);
});
}
function clearSearch() {
searchInput.value = '';
categoryFilter.value = '';
filterSettings();
searchInput.focus();
}
// Event listeners
searchInput.addEventListener('input', filterSettings);
categoryFilter.addEventListener('change', filterSettings);
clearBtn.addEventListener('click', clearSearch);
// Keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Ctrl+K or Cmd+K to focus search
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
searchInput.focus();
searchInput.select();
}
// Escape to clear search
if (e.key === 'Escape' && document.activeElement === searchInput) {
clearSearch();
}
});
// Initialize
tagSettingFields();
// Re-tag when tab changes
const tabLinks = document.querySelectorAll('.nav-tabs a');
tabLinks.forEach(link => {
link.addEventListener('click', function() {
setTimeout(tagSettingFields, 100);
});
});
// Show keyboard shortcut hint
searchInput.setAttribute('title', 'Press Ctrl+K (or Cmd+K) to focus, Esc to clear');
});
</script>
<style>
#settings-search-container {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
mark {
background-color: #ffeb3b;
padding: 2px 4px;
border-radius: 3px;
font-weight: 600;
}
#search-results-count {
margin-top: 5px;
font-size: 0.875rem;
}
#settings-search:focus {
border-color: #1a73e8;
box-shadow: 0 0 0 0.2rem rgba(26, 115, 232, 0.25);
}
.input-group .btn-outline-secondary {
border-color: #ced4da;
}
.input-group .btn-outline-secondary:hover {
background-color: #dc3545;
border-color: #dc3545;
color: white;
}
</style>
<?php