refactor: migrate templates and static files to self-contained modules

Templates Migration:
- Migrate admin templates to modules (tenancy, billing, monitoring, marketplace, etc.)
- Migrate vendor templates to modules (tenancy, billing, orders, messaging, etc.)
- Migrate storefront templates to modules (catalog, customers, orders, cart, checkout, cms)
- Migrate public templates to modules (billing, marketplace, cms)
- Keep shared templates in app/templates/ (base.html, errors/, partials/, macros/)
- Migrate letzshop partials to marketplace module

Static Files Migration:
- Migrate admin JS to modules: tenancy (23 files), core (5 files), monitoring (1 file)
- Migrate vendor JS to modules: tenancy (4 files), core (2 files)
- Migrate shared JS: vendor-selector.js to core, media-picker.js to cms
- Migrate storefront JS: storefront-layout.js to core
- Keep framework JS in static/ (api-client, utils, money, icons, log-config, lib/)
- Update all template references to use module_static paths

Naming Consistency:
- Rename static/platform/ to static/public/
- Rename app/templates/platform/ to app/templates/public/
- Update all extends and static references

Documentation:
- Update module-system.md with shared templates documentation
- Update frontend-structure.md with new module JS organization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-01 14:34:16 +01:00
parent 843703258f
commit 4e28d91a78
542 changed files with 11603 additions and 9037 deletions

View File

@@ -0,0 +1,129 @@
// noqa: js-006 - async init pattern is safe, loadData has try/catch
// static/admin/js/platform-health.js
/**
* Admin platform health monitoring page logic
* Displays system metrics, capacity thresholds, and scaling recommendations
*/
const adminPlatformHealthLog = window.LogConfig.loggers.adminPlatformHealth ||
window.LogConfig.createLogger('adminPlatformHealth', false);
adminPlatformHealthLog.info('Loading...');
function adminPlatformHealth() {
adminPlatformHealthLog.info('adminPlatformHealth() called');
return {
// Inherit base layout state
...data(),
// Set page identifier
currentPage: 'platform-health',
// Loading states
loading: true,
error: '',
// Health data
health: null,
// Auto-refresh interval (30 seconds)
refreshInterval: null,
async init() {
adminPlatformHealthLog.info('Platform Health init() called');
// Guard against multiple initialization
if (window._adminPlatformHealthInitialized) {
adminPlatformHealthLog.warn('Already initialized, skipping');
return;
}
window._adminPlatformHealthInitialized = true;
// Load initial data
await this.loadHealth();
// Set up auto-refresh every 30 seconds
this.refreshInterval = setInterval(() => {
this.loadHealth();
}, 30000);
adminPlatformHealthLog.info('Platform Health initialization complete');
},
/**
* Clean up on component destroy
*/
destroy() {
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
this.refreshInterval = null;
}
},
/**
* Load platform health data
*/
async loadHealth() {
this.loading = true;
this.error = '';
try {
const response = await apiClient.get('/admin/platform/health');
this.health = response;
adminPlatformHealthLog.info('Loaded health data:', {
status: response.overall_status,
tier: response.infrastructure_tier
});
} catch (error) {
adminPlatformHealthLog.error('Failed to load health:', error);
this.error = error.message || 'Failed to load platform health';
} finally {
this.loading = false;
}
},
/**
* Manual refresh
*/
async refresh() {
await this.loadHealth();
},
/**
* Format number with locale
*/
formatNumber(num) {
if (num === null || num === undefined) return '0';
if (typeof num === 'number' && num % 1 !== 0) {
return num.toFixed(2);
}
return new Intl.NumberFormat('en-US').format(num);
},
/**
* Format storage size
*/
formatStorage(gb) {
if (gb === null || gb === undefined) return '0 GB';
if (gb < 1) {
return (gb * 1024).toFixed(0) + ' MB';
}
return gb.toFixed(2) + ' GB';
},
/**
* Format timestamp
*/
formatTime(timestamp) {
if (!timestamp) return 'Unknown';
try {
const date = new Date(timestamp);
return date.toLocaleTimeString();
} catch (e) {
return 'Unknown';
}
}
};
}