feat: add logging, marketplace, and admin enhancements
Database & Migrations: - Add application_logs table migration for hybrid cloud logging - Add companies table migration and restructure vendor relationships Logging System: - Implement hybrid logging system (database + file) - Add log_service for centralized log management - Create admin logs page with filtering and viewing capabilities - Add init_log_settings.py script for log configuration - Enhance core logging with database integration Marketplace Integration: - Add marketplace admin page with product management - Create marketplace vendor page with product listings - Implement marketplace.js for both admin and vendor interfaces - Add marketplace integration documentation Admin Enhancements: - Add imports management page and functionality - Create settings page for admin configuration - Add vendor themes management page - Enhance vendor detail and edit pages - Improve code quality dashboard and violation details - Add logs viewing and management - Update icons guide and shared icon system Architecture & Documentation: - Document frontend structure and component architecture - Document models structure and relationships - Add vendor-in-token architecture documentation - Add vendor RBAC (role-based access control) documentation - Document marketplace integration patterns - Update architecture patterns documentation Infrastructure: - Add platform static files structure (css, img, js) - Move architecture_scan.py to proper models location - Update model imports and registrations - Enhance exception handling - Update dependency injection patterns UI/UX: - Improve vendor edit interface - Update admin user interface - Enhance page templates documentation - Add vendor marketplace interface
This commit is contained in:
199
docs/frontend/vendor/page-templates.md
vendored
199
docs/frontend/vendor/page-templates.md
vendored
@@ -220,7 +220,7 @@ app/
|
||||
class="flex items-center justify-center p-2 text-red-600 rounded-lg hover:bg-red-50 dark:text-gray-400 dark:hover:bg-gray-700"
|
||||
title="Delete"
|
||||
>
|
||||
<span x-html="$icon('trash', 'w-5 h-5')"></span>
|
||||
<span x-html="$icon('delete', 'w-5 h-5')"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -994,3 +994,200 @@ The base template loads scripts in this specific order:
|
||||
---
|
||||
|
||||
This template provides a complete, production-ready pattern for building vendor admin pages with consistent structure, error handling, and user experience.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Real-World Example: Marketplace Import Page
|
||||
|
||||
The marketplace import page is a comprehensive real-world implementation demonstrating all best practices.
|
||||
|
||||
### Implementation Files
|
||||
|
||||
**Template**: `app/templates/vendor/marketplace.html`
|
||||
**JavaScript**: `static/vendor/js/marketplace.js`
|
||||
**Route**: `app/routes/vendor_pages.py` - `vendor_marketplace_page()`
|
||||
|
||||
### Key Features Demonstrated
|
||||
|
||||
#### 1. Complete Form Handling
|
||||
```javascript
|
||||
// Import form with validation
|
||||
importForm: {
|
||||
csv_url: '',
|
||||
marketplace: 'Letzshop',
|
||||
language: 'fr',
|
||||
batch_size: 1000
|
||||
},
|
||||
|
||||
async startImport() {
|
||||
if (!this.importForm.csv_url) {
|
||||
this.error = 'Please enter a CSV URL';
|
||||
return;
|
||||
}
|
||||
|
||||
this.importing = true;
|
||||
try {
|
||||
const response = await apiClient.post('/vendor/marketplace/import', {
|
||||
source_url: this.importForm.csv_url,
|
||||
marketplace: this.importForm.marketplace,
|
||||
batch_size: this.importForm.batch_size
|
||||
});
|
||||
|
||||
this.successMessage = `Import job #${response.job_id} started!`;
|
||||
await this.loadJobs(); // Refresh list
|
||||
} catch (error) {
|
||||
this.error = error.message;
|
||||
} finally {
|
||||
this.importing = false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Auto-Refresh for Active Jobs
|
||||
```javascript
|
||||
startAutoRefresh() {
|
||||
this.autoRefreshInterval = setInterval(async () => {
|
||||
const hasActiveJobs = this.jobs.some(job =>
|
||||
job.status === 'pending' || job.status === 'processing'
|
||||
);
|
||||
|
||||
if (hasActiveJobs) {
|
||||
await this.loadJobs();
|
||||
}
|
||||
}, 10000); // Every 10 seconds
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Quick Fill from Settings
|
||||
```javascript
|
||||
// Load vendor settings
|
||||
async loadVendorSettings() {
|
||||
const response = await apiClient.get('/vendor/settings');
|
||||
this.vendorSettings = {
|
||||
letzshop_csv_url_fr: response.letzshop_csv_url_fr || '',
|
||||
letzshop_csv_url_en: response.letzshop_csv_url_en || '',
|
||||
letzshop_csv_url_de: response.letzshop_csv_url_de || ''
|
||||
};
|
||||
}
|
||||
|
||||
// Quick fill function
|
||||
quickFill(language) {
|
||||
const urlMap = {
|
||||
'fr': this.vendorSettings.letzshop_csv_url_fr,
|
||||
'en': this.vendorSettings.letzshop_csv_url_en,
|
||||
'de': this.vendorSettings.letzshop_csv_url_de
|
||||
};
|
||||
|
||||
if (urlMap[language]) {
|
||||
this.importForm.csv_url = urlMap[language];
|
||||
this.importForm.language = language;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Job Details Modal
|
||||
```javascript
|
||||
async viewJobDetails(jobId) {
|
||||
try {
|
||||
const response = await apiClient.get(`/vendor/marketplace/imports/${jobId}`);
|
||||
this.selectedJob = response;
|
||||
this.showJobModal = true;
|
||||
} catch (error) {
|
||||
this.error = error.message;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. Pagination
|
||||
```javascript
|
||||
async nextPage() {
|
||||
if (this.page * this.limit < this.totalJobs) {
|
||||
this.page++;
|
||||
await this.loadJobs();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 6. Utility Functions
|
||||
```javascript
|
||||
formatDate(dateString) {
|
||||
if (!dateString) return 'N/A';
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
|
||||
calculateDuration(job) {
|
||||
if (!job.started_at) return 'Not started';
|
||||
|
||||
const start = new Date(job.started_at);
|
||||
const end = job.completed_at ? new Date(job.completed_at) : new Date();
|
||||
const durationMs = end - start;
|
||||
|
||||
const seconds = Math.floor(durationMs / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}h ${minutes % 60}m`;
|
||||
} else if (minutes > 0) {
|
||||
return `${minutes}m ${seconds % 60}s`;
|
||||
}
|
||||
return `${seconds}s`;
|
||||
}
|
||||
```
|
||||
|
||||
### Template Features
|
||||
|
||||
#### Dynamic Status Badges
|
||||
```html
|
||||
<span class="px-2 py-1 font-semibold leading-tight rounded-full text-xs"
|
||||
:class="{
|
||||
'text-green-700 bg-green-100 dark:bg-green-700 dark:text-green-100': job.status === 'completed',
|
||||
'text-blue-700 bg-blue-100 dark:bg-blue-700 dark:text-blue-100': job.status === 'processing',
|
||||
'text-yellow-700 bg-yellow-100 dark:bg-yellow-700 dark:text-yellow-100': job.status === 'pending',
|
||||
'text-red-700 bg-red-100 dark:bg-red-700 dark:text-red-100': job.status === 'failed'
|
||||
}"
|
||||
x-text="job.status.toUpperCase()">
|
||||
</span>
|
||||
```
|
||||
|
||||
#### Conditional Display
|
||||
```html
|
||||
<!-- Quick fill buttons -->
|
||||
<button
|
||||
type="button"
|
||||
@click="quickFill('fr')"
|
||||
x-show="vendorSettings.letzshop_csv_url_fr"
|
||||
class="...">
|
||||
<span x-html="$icon('lightning-bolt', 'w-3 h-3 mr-1')"></span>
|
||||
French CSV
|
||||
</button>
|
||||
```
|
||||
|
||||
#### Progress Metrics
|
||||
```html
|
||||
<div class="space-y-1">
|
||||
<div class="text-xs text-gray-600 dark:text-gray-400">
|
||||
<span class="text-green-600" x-text="job.imported_count"></span> imported,
|
||||
<span class="text-blue-600" x-text="job.updated_count"></span> updated
|
||||
</div>
|
||||
<div x-show="job.error_count > 0" class="text-xs text-red-600">
|
||||
<span x-text="job.error_count"></span> errors
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Related Documentation
|
||||
|
||||
- [Marketplace Integration Guide](../../guides/marketplace-integration.md) - Complete marketplace system documentation
|
||||
- [Admin Page Templates](../admin/page-templates.md) - Admin page patterns
|
||||
- [Icons Guide](../../development/icons-guide.md) - Available icons
|
||||
|
||||
|
||||
Reference in New Issue
Block a user