From 7badee9ee4793f5722eae13b562afffa85aa94eb Mon Sep 17 00:00:00 2001 From: dwindown Date: Thu, 13 Nov 2025 13:38:51 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20Enhanced=20Email=20Customization=20-=20?= =?UTF-8?q?Logo,=20Social,=20Hero=20Text!=20=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Frontend Improvements (1-3, 5) ### 1. Logo URL with WP Media Library ✅ - Added "Select" button next to logo URL input - Opens WordPress Media Library - Logo preview below input - Easier for users to select from existing media ### 2. Footer Text with {current_year} Variable ✅ - Updated placeholder to show {current_year} usage - Help text explains dynamic year variable - Backend will replace with actual year ### 3. Social Links in Footer ✅ **Platforms Supported:** - Facebook - Twitter - Instagram - LinkedIn - YouTube - Website **Features:** - Add/remove social links - Platform dropdown with icons - URL input for each link - Visual icons in UI - Will render as icons in email footer ### 5. Hero Card Text Color ✅ - Added hero_text_color field - Color picker + hex input - Applied to preview - Separate control for heading/text color - Usually white for dark gradients **Updated Interface:** ```typescript interface EmailSettings { // ... existing hero_text_color: string; social_links: SocialLink[]; } interface SocialLink { platform: string; url: string; } ``` **File:** - `routes/Settings/Notifications/EmailCustomization.tsx` Next: Wire to backend (task 4)! --- .../Notifications/EmailCustomization.tsx | 228 +++++++++++++++++- 1 file changed, 216 insertions(+), 12 deletions(-) diff --git a/admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx b/admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx index ced0e09..f39c5ae 100644 --- a/admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx +++ b/admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx @@ -8,18 +8,27 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { __ } from '@/lib/i18n'; -import { ArrowLeft, RefreshCw } from 'lucide-react'; +import { ArrowLeft, RefreshCw, Upload, Plus, Trash2, Facebook, Twitter, Instagram, Linkedin, Youtube, Globe } from 'lucide-react'; import { toast } from 'sonner'; +import { openWPMediaLogo } from '@/lib/wp-media'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; + +interface SocialLink { + platform: string; + url: string; +} interface EmailSettings { primary_color: string; secondary_color: string; hero_gradient_start: string; hero_gradient_end: string; + hero_text_color: string; button_text_color: string; logo_url: string; header_text: string; footer_text: string; + social_links: SocialLink[]; } export default function EmailCustomization() { @@ -35,10 +44,12 @@ export default function EmailCustomization() { secondary_color: '#7f54b3', hero_gradient_start: '#667eea', hero_gradient_end: '#764ba2', + hero_text_color: '#ffffff', button_text_color: '#ffffff', logo_url: '', header_text: '', footer_text: '', + social_links: [], }, }); @@ -47,10 +58,12 @@ export default function EmailCustomization() { secondary_color: '#7f54b3', hero_gradient_start: '#667eea', hero_gradient_end: '#764ba2', + hero_text_color: '#ffffff', button_text_color: '#ffffff', logo_url: '', header_text: '', footer_text: '', + social_links: [], }); // Update form when settings load @@ -104,6 +117,50 @@ export default function EmailCustomization() { setFormData(prev => ({ ...prev, [field]: value })); }; + const handleLogoSelect = () => { + openWPMediaLogo((media) => { + if (media && media.url) { + handleChange('logo_url', media.url); + } + }); + }; + + const addSocialLink = () => { + setFormData(prev => ({ + ...prev, + social_links: [...prev.social_links, { platform: 'facebook', url: '' }], + })); + }; + + const removeSocialLink = (index: number) => { + setFormData(prev => ({ + ...prev, + social_links: prev.social_links.filter((_, i) => i !== index), + })); + }; + + const updateSocialLink = (index: number, field: 'platform' | 'url', value: string) => { + setFormData(prev => ({ + ...prev, + social_links: prev.social_links.map((link, i) => + i === index ? { ...link, [field]: value } : link + ), + })); + }; + + const getSocialIcon = (platform: string) => { + const icons: Record = { + facebook: Facebook, + twitter: Twitter, + instagram: Instagram, + linkedin: Linkedin, + youtube: Youtube, + website: Globe, + }; + const Icon = icons[platform] || Globe; + return ; + }; + if (isLoading) { return ( +
+ +
+ handleChange('hero_text_color', e.target.value)} + className="w-20 h-10 p-1 cursor-pointer" + /> + handleChange('hero_text_color', e.target.value)} + placeholder="#ffffff" + className="flex-1" + /> +
+

+ {__('Text and heading color for hero cards (usually white)')} +

+
+ {/* Preview */} -

{__('Preview')}

{__('This is how your hero cards will look')}

@@ -323,16 +404,37 @@ export default function EmailCustomization() {
- handleChange('logo_url', e.target.value)} - placeholder="https://example.com/logo.png" - /> +
+ handleChange('logo_url', e.target.value)} + placeholder="https://example.com/logo.png" + className="flex-1" + /> + +

{__('Full URL to your logo image (recommended: 200x60px)')}

+ {formData.logo_url && ( +
+ Logo preview +
+ )}
@@ -356,10 +458,112 @@ export default function EmailCustomization() { type="text" value={formData.footer_text} onChange={(e) => handleChange('footer_text', e.target.value)} - placeholder={__('© 2024 Your Store. All rights reserved.')} + placeholder={__('© {current_year} Your Store. All rights reserved.')} />

- {__('Text shown in email footer (copyright, address, etc.)')} + {__('Text shown in email footer. Use {current_year} for dynamic year.')} +

+
+ + {/* Social Links */} +
+
+ + +
+ + {formData.social_links.length === 0 ? ( +

+ {__('No social links added. Click "Add Social Link" to get started.')} +

+ ) : ( +
+ {formData.social_links.map((link, index) => ( +
+
+
+ +
+ updateSocialLink(index, 'url', e.target.value)} + placeholder="https://..." + className="h-9" + /> +
+ +
+ ))} +
+ )} +

+ {__('Social links will appear as icons in the email footer')}