feat: add email settings with database overrides for admin and vendor
Platform Email Settings (Admin): - Add GET/PUT/DELETE /admin/settings/email/* endpoints - Settings stored in admin_settings table override .env values - Support all providers: SMTP, SendGrid, Mailgun, Amazon SES - Edit mode UI with provider-specific configuration forms - Reset to .env defaults functionality - Test email to verify configuration Vendor Email Settings: - Add VendorEmailSettings model with one-to-one vendor relationship - Migration: v0a1b2c3d4e5_add_vendor_email_settings.py - Service: vendor_email_settings_service.py with tier validation - API endpoints: /vendor/email-settings/* (CRUD, status, verify) - Email tab in vendor settings page with full configuration - Warning banner until email is configured (like billing warnings) - Premium providers (SendGrid, Mailgun, SES) tier-gated to Business+ Email Service Updates: - get_platform_email_config(db) checks DB first, then .env - Configurable provider classes accept config dict - EmailService uses database-aware providers - Vendor emails use vendor's own SMTP (Wizamart doesn't pay) - "Powered by Wizamart" footer for Essential/Professional tiers - White-label (no footer) for Business/Enterprise tiers Other: - Add scripts/install.py for first-time platform setup - Add make install target - Update init-prod to include email template seeding 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
9
static/vendor/js/messages.js
vendored
9
static/vendor/js/messages.js
vendored
@@ -23,6 +23,7 @@ function vendorMessages(initialConversationId = null) {
|
||||
loadingMessages: false,
|
||||
sendingMessage: false,
|
||||
creatingConversation: false,
|
||||
error: '',
|
||||
|
||||
// Conversations state
|
||||
conversations: [],
|
||||
@@ -384,7 +385,8 @@ function vendorMessages(initialConversationId = null) {
|
||||
if (diff < 3600) return `${Math.floor(diff / 60)}m`;
|
||||
if (diff < 86400) return `${Math.floor(diff / 3600)}h`;
|
||||
if (diff < 172800) return 'Yesterday';
|
||||
return date.toLocaleDateString();
|
||||
const locale = window.VENDOR_CONFIG?.locale || 'en-GB';
|
||||
return date.toLocaleDateString(locale);
|
||||
},
|
||||
|
||||
formatTime(dateString) {
|
||||
@@ -392,11 +394,12 @@ function vendorMessages(initialConversationId = null) {
|
||||
const date = new Date(dateString);
|
||||
const now = new Date();
|
||||
const isToday = date.toDateString() === now.toDateString();
|
||||
const locale = window.VENDOR_CONFIG?.locale || 'en-GB';
|
||||
|
||||
if (isToday) {
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
return date.toLocaleTimeString(locale, { hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
return date.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
||||
return date.toLocaleString(locale, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user