compiling project documentation
This commit is contained in:
239
docs/__temp/FRONTEND/FRONTEND_ARCHITECTURE_OVERVIEW.txt
Normal file
239
docs/__temp/FRONTEND/FRONTEND_ARCHITECTURE_OVERVIEW.txt
Normal file
@@ -0,0 +1,239 @@
|
||||
╔══════════════════════════════════════════════════════════════════╗
|
||||
║ ALPINE.JS PAGE ARCHITECTURE OVERVIEW ║
|
||||
╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
📂 FILE STRUCTURE
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
static/admin/js/
|
||||
├── init-alpine.js ............. Base Alpine.js data & theme
|
||||
├── dashboard.js ............... Dashboard page (✅ WORKING)
|
||||
├── vendors.js ................. Vendor list page (✅ FIXED)
|
||||
└── vendor-edit.js ............. Vendor edit page (✅ FIXED)
|
||||
|
||||
|
||||
🔄 HOW PAGES INHERIT BASE FUNCTIONALITY
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ init-alpine.js │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ function data() { │ │
|
||||
│ │ return { │ │
|
||||
│ │ dark: ..., ← Theme state │ │
|
||||
│ │ toggleTheme() {...}, ← Theme toggle │ │
|
||||
│ │ isSideMenuOpen: false, ← Side menu state │ │
|
||||
│ │ toggleSideMenu() {...}, ← Side menu toggle │ │
|
||||
│ │ isProfileMenuOpen: false, ← Profile menu state │ │
|
||||
│ │ toggleProfileMenu() {...}, ← Profile menu toggle │ │
|
||||
│ │ currentPage: '' ← Page identifier │ │
|
||||
│ │ }; │ │
|
||||
│ │ } │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ Uses ...data() spread operator
|
||||
│
|
||||
┌─────────────────────┼─────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ dashboard.js │ │ vendors.js │ │vendor-edit.js │
|
||||
├───────────────┤ ├───────────────┤ ├───────────────┤
|
||||
│function admin │ │function admin │ │function admin │
|
||||
│Dashboard() { │ │Vendors() { │ │VendorEdit() { │
|
||||
│ return { │ │ return { │ │ return { │
|
||||
│ ...data(), │ │ ...data(), │ │ ...data(), │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ └──────────┼───┼────┘ │ │ │ │
|
||||
│ Inherits │ │ Inherits │ │ Inherits │
|
||||
│ all base │ │ all base │ │ all base │
|
||||
│ functions │ │ functions │ │ functions │
|
||||
│ │ │ │ │ │
|
||||
│ // Page │ │ // Page │ │ // Page │
|
||||
│ specific │ │ specific │ │ specific │
|
||||
│ state │ │ state │ │ state │
|
||||
│ }; │ │ }; │ │ }; │
|
||||
│} │ │} │ │} │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
|
||||
|
||||
⚙️ API CLIENT USAGE PATTERN
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
All pages must use lowercase 'apiClient':
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ✅ CORRECT ❌ WRONG │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ apiClient.get(url) │ ApiClient.get(url) │
|
||||
│ apiClient.post(url, data) │ API_CLIENT.post(url, data) │
|
||||
│ apiClient.put(url, data) │ Apiclient.put(url, data) │
|
||||
│ apiClient.delete(url) │ APIClient.delete(url) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
🪵 LOGGING PATTERN
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
Each page has its own logger object:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ dashboard.js vendors.js vendor-edit.js │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ const dashLog = { const vendorsLog = const editLog = { │
|
||||
│ error: (...) => error: (...) => error: (...) => │
|
||||
│ warn: (...) => warn: (...) => warn: (...) => │
|
||||
│ info: (...) => info: (...) => info: (...) => │
|
||||
│ debug: (...) => debug: (...) => debug: (...) => │
|
||||
│ }; }; }; │
|
||||
│ │
|
||||
│ dashLog.info('...') vendorsLog.info() editLog.info() │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
🔒 INITIALIZATION GUARD PATTERN
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
Prevents multiple Alpine.js initializations:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ async init() { │
|
||||
│ // Check if already initialized │
|
||||
│ if (window._yourPageInitialized) { │
|
||||
│ log.warn('Already initialized, skipping...'); │
|
||||
│ return; // Exit early │
|
||||
│ } │
|
||||
│ window._yourPageInitialized = true; // Set flag │
|
||||
│ │
|
||||
│ // Continue with initialization │
|
||||
│ await this.loadData(); │
|
||||
│ } │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
📊 STATE MANAGEMENT
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
Alpine.js reactive state structure:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ function yourPage() { │
|
||||
│ return { │
|
||||
│ ...data(), ← Base UI state (inherited) │
|
||||
│ currentPage: 'name', ← Page identifier │
|
||||
│ │
|
||||
│ // Loading states │
|
||||
│ loading: false, ← General loading │
|
||||
│ loadingItem: false, ← Specific item loading │
|
||||
│ saving: false, ← Save operation state │
|
||||
│ │
|
||||
│ // Data │
|
||||
│ items: [], ← List data │
|
||||
│ item: null, ← Single item │
|
||||
│ stats: {}, ← Statistics │
|
||||
│ │
|
||||
│ // Error handling │
|
||||
│ error: null, ← Error message │
|
||||
│ errors: {}, ← Field-specific errors │
|
||||
│ │
|
||||
│ // Methods │
|
||||
│ async init() {...}, ← Initialization │
|
||||
│ async loadData() {...}, ← Data loading │
|
||||
│ async save() {...}, ← Save operation │
|
||||
│ formatDate(d) {...} ← Helper functions │
|
||||
│ }; │
|
||||
│ } │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
🎯 TEMPLATE BINDING
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
HTML template connects to Alpine.js component:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ vendor-edit.html │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ {% extends "admin/base.html" %} │
|
||||
│ │
|
||||
│ {# This binds to the JavaScript function #} │
|
||||
│ {% block alpine_data %}adminVendorEdit(){% endblock %} │
|
||||
│ └──────────────────┐ │
|
||||
│ {% block content %} │ │
|
||||
│ <div x-show="loading">Loading...</div> │ │
|
||||
│ <div x-show="!loading"> │ │
|
||||
│ <p x-text="vendor.name"></p> ← Reactive binding │ │
|
||||
│ </div> │ │
|
||||
│ {% endblock %} │ │
|
||||
│ │ │
|
||||
│ {% block extra_scripts %} │ │
|
||||
│ <script src="...vendor-edit.js"></script> ──────────┐ │ │
|
||||
│ {% endblock %} │ │ │
|
||||
└───────────────────────────────────────────────────────│──│─┘
|
||||
│ │
|
||||
│ │
|
||||
┌───────────────────────────────────────────────────────│──│─┐
|
||||
│ vendor-edit.js │ │ │
|
||||
├───────────────────────────────────────────────────────│──│─┤
|
||||
│ function adminVendorEdit() { ◄────────────────────────┘ │ │
|
||||
│ return { │ │
|
||||
│ ...data(), │ │
|
||||
│ vendor: null, ← Bound to x-text="vendor.name"│ │
|
||||
│ loading: false, ← Bound to x-show="loading" │ │
|
||||
│ async init() {...} │ │
|
||||
│ }; │ │
|
||||
│ } │ │
|
||||
└───────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
🔄 PAGE LIFECYCLE
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
1. Page Load
|
||||
↓
|
||||
2. Alpine.js Initialization
|
||||
↓
|
||||
3. x-data="yourPageComponent()" called
|
||||
↓
|
||||
4. Component function executes
|
||||
↓
|
||||
5. ...data() spreads base state
|
||||
↓
|
||||
6. Page-specific state added
|
||||
↓
|
||||
7. init() method runs
|
||||
↓
|
||||
8. Check initialization guard
|
||||
↓
|
||||
9. Load data from API
|
||||
↓
|
||||
10. Reactive bindings update UI
|
||||
|
||||
|
||||
✅ CHECKLIST FOR NEW PAGES
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
JavaScript File:
|
||||
□ Create logger object (pageLog)
|
||||
□ Define component function
|
||||
□ Add ...data() at start of return object
|
||||
□ Set currentPage: 'page-name'
|
||||
□ Add initialization guard
|
||||
□ Use lowercase apiClient for API calls
|
||||
□ Add performance tracking (optional)
|
||||
□ Use page-specific logger
|
||||
|
||||
HTML Template:
|
||||
□ Extend admin/base.html
|
||||
□ Set alpine_data block with function name
|
||||
□ Add x-show for loading states
|
||||
□ Add x-text for reactive data
|
||||
□ Load JavaScript file in extra_scripts block
|
||||
|
||||
|
||||
══════════════════════════════════════════════════════════════════
|
||||
Your dashboard.js is perfect!
|
||||
Use it as the template for all new pages.
|
||||
══════════════════════════════════════════════════════════════════
|
||||
Reference in New Issue
Block a user