created specific route files for frontends
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
Admin API router aggregation.
|
Admin API router aggregation.
|
||||||
|
|
||||||
This module combines all admin-related API endpoints:
|
This module combines all admin-related JSON API endpoints:
|
||||||
- Authentication (login/logout)
|
- Authentication (login/logout)
|
||||||
- Vendor management (CRUD, bulk operations)
|
- Vendor management (CRUD, bulk operations)
|
||||||
- Vendor domains management (custom domains, DNS verification)
|
- Vendor domains management (custom domains, DNS verification)
|
||||||
@@ -13,7 +13,11 @@ This module combines all admin-related API endpoints:
|
|||||||
- Audit logging
|
- Audit logging
|
||||||
- Platform settings
|
- Platform settings
|
||||||
- Notifications and alerts
|
- Notifications and alerts
|
||||||
- HTML Pages - Server-rendered pages using Jinja2
|
|
||||||
|
IMPORTANT:
|
||||||
|
- This router is for JSON API endpoints only
|
||||||
|
- HTML page routes are mounted separately in main.py at /vendor/*
|
||||||
|
- Do NOT include pages.router here - it causes route conflicts
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
@@ -30,8 +34,7 @@ from . import (
|
|||||||
monitoring,
|
monitoring,
|
||||||
audit,
|
audit,
|
||||||
settings,
|
settings,
|
||||||
notifications,
|
notifications
|
||||||
pages
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create admin router
|
# Create admin router
|
||||||
@@ -100,14 +103,5 @@ router.include_router(settings.router, tags=["admin-settings"])
|
|||||||
# Include notifications and alerts endpoints
|
# Include notifications and alerts endpoints
|
||||||
router.include_router(notifications.router, tags=["admin-notifications"])
|
router.include_router(notifications.router, tags=["admin-notifications"])
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# HTML Page Routes (Jinja2 Templates)
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
# Include HTML page routes (these return rendered templates, not JSON)
|
|
||||||
router.include_router(pages.router, tags=["admin-pages"])
|
|
||||||
|
|
||||||
|
|
||||||
# Export the router
|
# Export the router
|
||||||
__all__ = ["router"]
|
__all__ = ["router"]
|
||||||
|
|||||||
15
app/api/v1/vendor/__init__.py
vendored
15
app/api/v1/vendor/__init__.py
vendored
@@ -1,6 +1,6 @@
|
|||||||
# app/api/v1/vendor/__init__.py
|
# app/api/v1/vendor/__init__.py
|
||||||
"""
|
"""
|
||||||
Vendor API endpoints.
|
Vendor API router aggregation.
|
||||||
|
|
||||||
This module aggregates all vendor-related JSON API endpoints.
|
This module aggregates all vendor-related JSON API endpoints.
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ from fastapi import APIRouter
|
|||||||
|
|
||||||
# Import all sub-routers (JSON API only)
|
# Import all sub-routers (JSON API only)
|
||||||
from . import (
|
from . import (
|
||||||
info, # NEW: Vendor info endpoint
|
info,
|
||||||
auth,
|
auth,
|
||||||
dashboard,
|
dashboard,
|
||||||
profile,
|
profile,
|
||||||
@@ -29,7 +29,6 @@ from . import (
|
|||||||
media,
|
media,
|
||||||
notifications,
|
notifications,
|
||||||
analytics,
|
analytics,
|
||||||
# NOTE: pages is NOT imported here - it's mounted separately in main.py
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -66,14 +65,4 @@ router.include_router(media.router, tags=["vendor-media"])
|
|||||||
router.include_router(notifications.router, tags=["vendor-notifications"])
|
router.include_router(notifications.router, tags=["vendor-notifications"])
|
||||||
router.include_router(analytics.router, tags=["vendor-analytics"])
|
router.include_router(analytics.router, tags=["vendor-analytics"])
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# NOTE: HTML Page Routes
|
|
||||||
# ============================================================================
|
|
||||||
# HTML page routes (pages.router) are NOT included here.
|
|
||||||
# They are mounted separately in main.py at /vendor/* to avoid conflicts.
|
|
||||||
#
|
|
||||||
# This separation ensures:
|
|
||||||
# - JSON API: /api/v1/vendor/* (this router)
|
|
||||||
# - HTML Pages: /vendor/* (mounted in main.py)
|
|
||||||
|
|
||||||
__all__ = ["router"]
|
__all__ = ["router"]
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# app/routes/__init__.py
|
|
||||||
"""
|
|
||||||
Frontend route handlers.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .frontend import router
|
|
||||||
|
|
||||||
__all__ = ["router"]
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/admin/pages.py
|
# app/routes/admin_pages.py
|
||||||
"""
|
"""
|
||||||
Admin HTML page routes using Jinja2 templates.
|
Admin HTML page routes using Jinja2 templates.
|
||||||
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
# app/routes/frontend.py
|
|
||||||
"""
|
|
||||||
Frontend HTML route handlers.
|
|
||||||
|
|
||||||
Serves static HTML files for admin, vendor, and customer interfaces.
|
|
||||||
Supports both path-based (/vendor/{vendor_code}/) and query-based access.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Path
|
|
||||||
from fastapi.responses import FileResponse
|
|
||||||
|
|
||||||
router = APIRouter(include_in_schema=False)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# ADMIN ROUTES - DISABLED (Now using Jinja2 templates in pages.py)
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
# @router.get("/admin/")
|
|
||||||
# @router.get("/admin/login")
|
|
||||||
# async def admin_login():
|
|
||||||
# """Serve admin login page"""
|
|
||||||
# return FileResponse("static/admin/login.html")
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/admin/dashboard")
|
|
||||||
# async def admin_dashboard():
|
|
||||||
# """Serve admin dashboard page"""
|
|
||||||
# return FileResponse("static/admin/dashboard.html")
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/admin/vendors")
|
|
||||||
# async def admin_vendors():
|
|
||||||
# """Serve admin vendors management page"""
|
|
||||||
# return FileResponse("static/admin/vendors.html")
|
|
||||||
|
|
||||||
# @router.get("/admin/vendor-edit")
|
|
||||||
# async def admin_vendor_edit():
|
|
||||||
# """Serve admin vendor edit page"""
|
|
||||||
# return FileResponse("static/admin/vendor-edit.html")
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# VENDOR ROUTES (with vendor code in path)
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/")
|
|
||||||
@router.get("/vendor/{vendor_code}/login")
|
|
||||||
async def vendor_login_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor login page with vendor code in path"""
|
|
||||||
return FileResponse("static/vendor/login.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/dashboard")
|
|
||||||
async def vendor_dashboard_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor dashboard page with vendor code in path"""
|
|
||||||
return FileResponse("static/vendor/dashboard.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/products")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/products")
|
|
||||||
async def vendor_products_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor products management page"""
|
|
||||||
return FileResponse("static/vendor/admin/products.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/orders")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/orders")
|
|
||||||
async def vendor_orders_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor orders management page"""
|
|
||||||
return FileResponse("static/vendor/admin/orders.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/marketplace")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/marketplace")
|
|
||||||
async def vendor_marketplace_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor marketplace import page"""
|
|
||||||
return FileResponse("static/vendor/admin/marketplace.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/customers")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/customers")
|
|
||||||
async def vendor_customers_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor customers management page"""
|
|
||||||
return FileResponse("static/vendor/admin/customers.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/inventory")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/inventory")
|
|
||||||
async def vendor_inventory_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor inventory management page"""
|
|
||||||
return FileResponse("static/vendor/admin/inventory.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/{vendor_code}/team")
|
|
||||||
@router.get("/vendor/{vendor_code}/admin/team")
|
|
||||||
async def vendor_team_with_code(vendor_code: str = Path(...)):
|
|
||||||
"""Serve vendor team management page"""
|
|
||||||
return FileResponse("static/vendor/admin/team.html")
|
|
||||||
|
|
||||||
|
|
||||||
# Fallback vendor routes (without vendor code - for query parameter access)
|
|
||||||
@router.get("/vendor/")
|
|
||||||
@router.get("/vendor/login")
|
|
||||||
async def vendor_login():
|
|
||||||
"""Serve vendor login page (query parameter based)"""
|
|
||||||
return FileResponse("static/vendor/login.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/vendor/dashboard")
|
|
||||||
async def vendor_dashboard():
|
|
||||||
"""Serve vendor dashboard page (query parameter based)"""
|
|
||||||
return FileResponse("static/vendor/dashboard.html")
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# CUSTOMER/SHOP ROUTES
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
@router.get("/shop/")
|
|
||||||
@router.get("/shop/products")
|
|
||||||
async def shop_products():
|
|
||||||
"""Serve shop products catalog page"""
|
|
||||||
return FileResponse("static/shop/products.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/products/{product_id}")
|
|
||||||
async def shop_product_detail(product_id: int):
|
|
||||||
"""Serve product detail page"""
|
|
||||||
return FileResponse("static/shop/product.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/cart")
|
|
||||||
async def shop_cart():
|
|
||||||
"""Serve shopping cart page"""
|
|
||||||
return FileResponse("static/shop/cart.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/checkout")
|
|
||||||
async def shop_checkout():
|
|
||||||
"""Serve checkout page"""
|
|
||||||
return FileResponse("static/shop/checkout.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/register")
|
|
||||||
async def shop_register():
|
|
||||||
"""Serve customer registration page"""
|
|
||||||
return FileResponse("static/shop/account/register.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/login")
|
|
||||||
async def shop_login():
|
|
||||||
"""Serve customer login page"""
|
|
||||||
return FileResponse("static/shop/account/login.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/dashboard")
|
|
||||||
async def shop_account_dashboard():
|
|
||||||
"""Serve customer account dashboard"""
|
|
||||||
return FileResponse("static/shop/account/dashboard.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/orders")
|
|
||||||
async def shop_orders():
|
|
||||||
"""Serve customer orders history page"""
|
|
||||||
return FileResponse("static/shop/account/orders.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/orders/{order_id}")
|
|
||||||
async def shop_order_detail(order_id: int):
|
|
||||||
"""Serve customer order detail page"""
|
|
||||||
return FileResponse("static/shop/account/order-detail.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/profile")
|
|
||||||
async def shop_profile():
|
|
||||||
"""Serve customer profile page"""
|
|
||||||
return FileResponse("static/shop/account/profile.html")
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/shop/account/addresses")
|
|
||||||
async def shop_addresses():
|
|
||||||
"""Serve customer addresses management page"""
|
|
||||||
return FileResponse("static/shop/account/addresses.html")
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/shop/pages.py
|
# app/routes/shop_pages.py
|
||||||
"""
|
"""
|
||||||
Shop/Customer HTML page routes using Jinja2 templates.
|
Shop/Customer HTML page routes using Jinja2 templates.
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/pages.py
|
# app/routes/vendor_pages.py
|
||||||
"""
|
"""
|
||||||
Vendor HTML page routes using Jinja2 templates.
|
Vendor HTML page routes using Jinja2 templates.
|
||||||
|
|
||||||
10
app/templates/admin/vendor-create.html
Normal file
10
app/templates/admin/vendor-create.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4
app/templates/vendor/admin/dashboard.html
vendored
4
app/templates/vendor/admin/dashboard.html
vendored
@@ -4,8 +4,6 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Vendor Dashboard - Multi-Tenant Ecommerce Platform</title>
|
<title>Vendor Dashboard - Multi-Tenant Ecommerce Platform</title>
|
||||||
<link rel="stylesheet" href="/static/css/shared/base.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/admin/admin.css">
|
|
||||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body x-data="vendorDashboard()" x-init="init()" x-cloak>
|
<body x-data="vendorDashboard()" x-init="init()" x-cloak>
|
||||||
@@ -155,6 +153,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/shared/js/api-client.js"></script>
|
<script src="/static/shared/js/api-client.js"></script>
|
||||||
<script src="/static/js/vendor/dashboard.js"></script>
|
<script src="/static/vendor/js/dashboard.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -986,7 +986,7 @@ from fastapi.staticfiles import StaticFiles
|
|||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
from app.api.v1.admin import routes as admin_api_routes
|
from app.api.v1.admin import routes as admin_api_routes
|
||||||
from app.api.v1.admin import pages as admin_page_routes
|
from app.routes import pages as admin_page_routes
|
||||||
|
|
||||||
app = FastAPI(title="Multi-Tenant Platform")
|
app = FastAPI(title="Multi-Tenant Platform")
|
||||||
|
|
||||||
@@ -1010,6 +1010,7 @@ app.include_router(
|
|||||||
tags=["admin-pages"]
|
tags=["admin-pages"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
async def root():
|
async def root():
|
||||||
return {"message": "Multi-Tenant Platform API"}
|
return {"message": "Multi-Tenant Platform API"}
|
||||||
|
|||||||
5
main.py
5
main.py
@@ -22,9 +22,7 @@ from sqlalchemy.orm import Session
|
|||||||
from app.api.main import api_router
|
from app.api.main import api_router
|
||||||
|
|
||||||
# Import page routers
|
# Import page routers
|
||||||
from app.api.v1.admin import pages as admin_pages
|
from app.routes import admin_pages, vendor_pages, shop_pages
|
||||||
from app.api.v1.vendor import pages as vendor_pages
|
|
||||||
from app.api.v1.public.vendors import pages as shop_pages
|
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.core.database import get_db
|
from app.core.database import get_db
|
||||||
from app.core.lifespan import lifespan
|
from app.core.lifespan import lifespan
|
||||||
@@ -128,6 +126,7 @@ async def vendor_favicon():
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# HTML PAGE ROUTES (Jinja2 Templates)
|
# HTML PAGE ROUTES (Jinja2 Templates)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
# Include HTML page routes (these return rendered templates, not JSON)
|
||||||
|
|
||||||
# Admin pages
|
# Admin pages
|
||||||
app.include_router(
|
app.include_router(
|
||||||
|
|||||||
57
static/vendor/js/login.js
vendored
57
static/vendor/js/login.js
vendored
@@ -3,9 +3,8 @@
|
|||||||
* Vendor login page logic
|
* Vendor login page logic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ✅ Use centralized logger - ONE LINE!
|
// Create custom logger for vendor login page
|
||||||
// Create custom logger for login page
|
const vendorLoginLog = window.LogConfig.createLogger('VENDOR-LOGIN');
|
||||||
const loginLog = window.LogConfig.createLogger('LOGIN');
|
|
||||||
|
|
||||||
function vendorLogin() {
|
function vendorLogin() {
|
||||||
return {
|
return {
|
||||||
@@ -23,29 +22,38 @@ function vendorLogin() {
|
|||||||
dark: false,
|
dark: false,
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
vendorLoginLog.info('=== VENDOR LOGIN PAGE INITIALIZING ===');
|
||||||
|
|
||||||
// Load theme
|
// Load theme
|
||||||
const theme = localStorage.getItem('theme');
|
const theme = localStorage.getItem('theme');
|
||||||
if (theme === 'dark') {
|
if (theme === 'dark') {
|
||||||
this.dark = true;
|
this.dark = true;
|
||||||
}
|
}
|
||||||
|
vendorLoginLog.debug('Dark mode:', this.dark);
|
||||||
|
|
||||||
// Get vendor code from URL path
|
// Get vendor code from URL path
|
||||||
const pathSegments = window.location.pathname.split('/').filter(Boolean);
|
const pathSegments = window.location.pathname.split('/').filter(Boolean);
|
||||||
if (pathSegments[0] === 'vendor' && pathSegments[1]) {
|
if (pathSegments[0] === 'vendor' && pathSegments[1]) {
|
||||||
this.vendorCode = pathSegments[1];
|
this.vendorCode = pathSegments[1];
|
||||||
|
vendorLoginLog.debug('Vendor code from URL:', this.vendorCode);
|
||||||
await this.loadVendor();
|
await this.loadVendor();
|
||||||
}
|
}
|
||||||
this.checked = true;
|
this.checked = true;
|
||||||
|
vendorLoginLog.info('=== VENDOR LOGIN PAGE INITIALIZATION COMPLETE ===');
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadVendor() {
|
async loadVendor() {
|
||||||
|
vendorLoginLog.info('Loading vendor information...');
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get(`/vendor/${this.vendorCode}`);
|
const response = await apiClient.get(`/vendor/${this.vendorCode}`);
|
||||||
this.vendor = response;
|
this.vendor = response;
|
||||||
logInfo('Vendor loaded', this.vendor);
|
vendorLoginLog.info('Vendor loaded successfully:', {
|
||||||
|
code: this.vendor.code,
|
||||||
|
name: this.vendor.name
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logError('Failed to load vendor', error);
|
window.LogConfig.logError(error, 'Load Vendor');
|
||||||
this.error = 'Failed to load vendor information';
|
this.error = 'Failed to load vendor information';
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@@ -53,6 +61,7 @@ function vendorLogin() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async handleLogin() {
|
async handleLogin() {
|
||||||
|
vendorLoginLog.info('=== VENDOR LOGIN ATTEMPT STARTED ===');
|
||||||
this.clearErrors();
|
this.clearErrors();
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
@@ -65,30 +74,50 @@ function vendorLogin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(this.errors).length > 0) {
|
if (Object.keys(this.errors).length > 0) {
|
||||||
|
vendorLoginLog.warn('Validation failed:', this.errors);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vendorLoginLog.info('Calling vendor login API...');
|
||||||
|
vendorLoginLog.debug('Username:', this.credentials.username);
|
||||||
|
vendorLoginLog.debug('Vendor code:', this.vendorCode);
|
||||||
|
|
||||||
|
window.LogConfig.logApiCall('POST', '/vendor/auth/login', {
|
||||||
|
username: this.credentials.username,
|
||||||
|
vendor_code: this.vendorCode
|
||||||
|
}, 'request');
|
||||||
|
|
||||||
|
const startTime = performance.now();
|
||||||
const response = await apiClient.post('/vendor/auth/login', {
|
const response = await apiClient.post('/vendor/auth/login', {
|
||||||
username: this.credentials.username,
|
username: this.credentials.username,
|
||||||
password: this.credentials.password,
|
password: this.credentials.password,
|
||||||
vendor_code: this.vendorCode
|
vendor_code: this.vendorCode
|
||||||
});
|
});
|
||||||
|
const duration = performance.now() - startTime;
|
||||||
|
|
||||||
logInfo('Login successful', response);
|
window.LogConfig.logApiCall('POST', '/vendor/auth/login', {
|
||||||
|
hasToken: !!response.access_token,
|
||||||
|
user: response.user?.username
|
||||||
|
}, 'response');
|
||||||
|
window.LogConfig.logPerformance('Vendor Login', duration);
|
||||||
|
|
||||||
|
vendorLoginLog.info('Login successful!');
|
||||||
|
vendorLoginLog.debug('Storing authentication data...');
|
||||||
|
|
||||||
localStorage.setItem('accessToken', response.access_token);
|
localStorage.setItem('accessToken', response.access_token);
|
||||||
localStorage.setItem('currentUser', JSON.stringify(response.user));
|
localStorage.setItem('currentUser', JSON.stringify(response.user));
|
||||||
localStorage.setItem('vendorCode', this.vendorCode);
|
localStorage.setItem('vendorCode', this.vendorCode);
|
||||||
|
|
||||||
this.success = 'Login successful! Redirecting...';
|
this.success = 'Login successful! Redirecting...';
|
||||||
|
vendorLoginLog.info('Redirecting to vendor dashboard...');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = `/vendor/${this.vendorCode}/dashboard`;
|
window.location.href = `/vendor/${this.vendorCode}/dashboard`;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logError('Login failed', error);
|
window.LogConfig.logError(error, 'Vendor Login');
|
||||||
|
|
||||||
if (error.status === 401) {
|
if (error.status === 401) {
|
||||||
this.error = 'Invalid username or password';
|
this.error = 'Invalid username or password';
|
||||||
@@ -97,14 +126,26 @@ function vendorLogin() {
|
|||||||
} else {
|
} else {
|
||||||
this.error = error.message || 'Login failed. Please try again.';
|
this.error = error.message || 'Login failed. Please try again.';
|
||||||
}
|
}
|
||||||
|
vendorLoginLog.info('Error message displayed to user:', this.error);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
vendorLoginLog.info('=== VENDOR LOGIN ATTEMPT FINISHED ===');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearErrors() {
|
clearErrors() {
|
||||||
|
vendorLoginLog.debug('Clearing form errors');
|
||||||
this.error = '';
|
this.error = '';
|
||||||
this.errors = {};
|
this.errors = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleDarkMode() {
|
||||||
|
vendorLoginLog.debug('Toggling dark mode...');
|
||||||
|
this.dark = !this.dark;
|
||||||
|
localStorage.setItem('theme', this.dark ? 'dark' : 'light');
|
||||||
|
vendorLoginLog.info('Dark mode:', this.dark ? 'ON' : 'OFF');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vendorLoginLog.info('Vendor login module loaded');
|
||||||
|
|||||||
Reference in New Issue
Block a user