HBT-software / src /components /SocialPromoter.tsx
embedingHF's picture
Upload folder using huggingface_hub
46463e1 verified
Raw
History Blame Contribute Delete
22.7 kB
/**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import React, { useState, useMemo } from 'react';
import { motion } from 'motion/react';
import {
Megaphone,
Share2,
Copy,
Check,
Download,
MessageSquare,
Sparkles,
ChevronRight,
FileImage,
Tag,
Percent,
Search
} from 'lucide-react';
import { TireProduct, SystemSettings } from '../types';
interface SocialPromoterProps {
products: TireProduct[];
settings: SystemSettings;
}
export default function SocialPromoter({ products, settings }: SocialPromoterProps) {
const [selectedProdId, setSelectedProdId] = useState<string>(products[0]?.id || '');
const [marketingTopic, setMarketingTopic] = useState<'DISCOUNT' | 'SAFETY' | 'WINTER' | 'PERFORMANCE'>('DISCOUNT');
const [promoCode, setPromoCode] = useState('HAIDER_TREATS_26');
const [customDiscountPercent, setCustomDiscountPercent] = useState(10);
const [copied, setCopied] = useState(false);
const [promSearch, setPromSearch] = useState('');
const selectedProduct = useMemo(() => {
return products.find(p => p.id === selectedProdId) || products[0] || null;
}, [products, selectedProdId]);
// Dynamic search list
const filteredProducts = useMemo(() => {
return products.filter(p =>
p.brand.toLowerCase().includes(promSearch.toLowerCase()) ||
p.model.toLowerCase().includes(promSearch.toLowerCase()) ||
p.size.toLowerCase().includes(promSearch.toLowerCase())
);
}, [products, promSearch]);
// Math calculated prices
const promoPrice = useMemo(() => {
if (!selectedProduct) return 0;
const computed = selectedProduct.price * (1 - (customDiscountPercent / 100));
return Math.round(computed);
}, [selectedProduct, customDiscountPercent]);
// High conversion copy algorithms based on topic
const promoCopyText = useMemo(() => {
if (!selectedProduct) return '';
const brand = selectedProduct.brand.toUpperCase();
const model = selectedProduct.model;
const size = selectedProduct.size;
const oldPriceStr = `${settings.currencySymbol}${selectedProduct.price.toLocaleString()}`;
const newPriceStr = `${settings.currencySymbol}${promoPrice.toLocaleString()}`;
switch(marketingTopic) {
case 'DISCOUNT':
return `🔥 *MEGA TIRE DEAL AT HAIDER BROTHER TRADERS* 🔥\n\nUpgrade your ride with premium *${brand} ${model}* tires today! Under our limited-time warehouse clearance festival, enjoy unprecedented markdowns!\n\n🛞 *Profile Specs:* ${size}\n💰 *Regular MSRP:* ~${oldPriceStr}~\n📉 *Promotional rate:* *${newPriceStr}* (SAVE ${customDiscountPercent}%!)\n🎟️ *Use checkout token:* \`${promoCode}\` for free nitrogen fill!\n\n🏢 *Branch Address:* ${settings.shopAddress}\n📞 *Order Line Call/WhatsApp:* ${settings.shopPhone}\n\n_Drive safe, drive on certified treads! #HaiderBrotherTraders #PremiumTyreClearance #SafeJourneys_`;
case 'SAFETY':
return `🌧️ *MONSOON ROAD SAFETY INITIATIVE — HAIDER BROTHERS* 🌧️\n\nDid you inspect your tire tread lines recently? Worn tire grooves are highly dangerous under wet road conditions!\n\nEquip your vehicle with fresh high-traction *${brand} ${model}* SUV/Passenger radial tires today. Maximum hydroplaning resistance:\n\n🛞 *Specs Size:* ${size}\n⚡ *Active Grips Price:* *${newPriceStr}* per piece (includes balancing check!)\n🎖️ *Features:* Steel Belted, Deep wet-road grip grooves.\n\n🏢 *Stop By:* ${settings.shopAddress}\n✨ *Hotline:* ${settings.shopPhone}\n\n_Protect your family. Invest in solid road friction! #TyreSafetyCheck #HaiderTradersQuetta_`;
case 'WINTER':
return `❄️ *AGGRESSIVE TERRAIN GRIP SPECIALISTS* ❄️\n\nConquer unpredictable paths and mountain highways with rugged All-Terrain *${brand} ${model}* treads!\n\nEngineered to withstand extreme temperature ranges and gravel trails:\n\n🛞 *Tire profile size:* ${size}\n💰 *Promo cost:* *${newPriceStr}* (Original MSRP: ~${oldPriceStr}~)\n🚜 *Ideal for:* SUV Crossovers, Light Freight rigs, and heavy loading.\n\n🏢 *Stop by our Auto Vault:* ${settings.shopAddress}\n📞 *Call for booking advice:* ${settings.shopPhone}\n\n_No territory is too hard. Travel fearlessly! #TerrainMastery #SailunTerramax #BridgestonePak #HaiderBrothers_`;
case 'PERFORMANCE':
return `🏎️ *ELITE RACING COMPOUND HANDLINGS — HIGH PERFORMANCE* 🏎️\n\nUnleash extreme tarmac performance and responsive steering control with premium racing radial *${brand} ${model}*!\n\nEngineered by Yokohama/Bridgestone for high cornering friction matrices:\n\n🛞 *Dimension size:* ${size}\n🏁 *Precision Rate:* *${newPriceStr}* (Limited retail sets available!)\n🛠️ *Complimentary layout:* Balancing, high-durability valves and nitrogen check done on spot.\n\n📞 *Reserve yours now:* ${settings.shopPhone}\n🏢 *Haider Brother Traders* — Quetta's No. 1 premium hub.\n\n_Upgrade handling, transform high-speed braking thresholds! #AdvanComfort #YokohamaDB #PremiumRadials_`;
}
}, [selectedProduct, marketingTopic, promoPrice, customDiscountPercent, promoCode, settings]);
const handleCopyClipboard = () => {
navigator.clipboard.writeText(promoCopyText);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
const shareWhatsApp = () => {
const encoded = encodeURIComponent(promoCopyText);
window.open(`https://api.whatsapp.com/send?text=${encoded}`, '_blank');
};
const shareFacebook = () => {
const link = "https://www.facebook.com/sharer/sharer.php?u=" + encodeURIComponent("https://haidertraders.com");
window.open(link, '_blank');
};
// Compile a highly polished self-contained single-flyer visual page HTML and download it!
const downloadFlyerHTML = () => {
if (!selectedProduct) return;
// Theme colors predicated on campaign topic
let gradient = "linear-gradient(135deg, #1e3a8a, #0f172a)"; // blue
if (marketingTopic === 'SAFETY') gradient = "linear-gradient(135deg, #0f766e, #0f172a)"; // teal
if (marketingTopic === 'WINTER') gradient = "linear-gradient(135deg, #4338ca, #111827)"; // dark indigo
if (marketingTopic === 'PERFORMANCE') gradient = "linear-gradient(135deg, #b91c1c, #0f172a)"; // red
const flyerHTML = `
<!DOCTYPE html>
<html>
<head>
<title>Marketing Poster - ${selectedProduct.brand}</title>
<style>
body { margin: 0; padding: 0; background-color: #f1f5f9; display: flex; justify-content: center; align-items: center; min-height: 100vh; font-family: system-ui, sans-serif; }
.poster { width: 500px; height: 600px; background: ${gradient}; color: #fff; border-radius: 20px; overflow: hidden; padding: 40px; display: flex; flex-col; justify-content: space-between; box-sizing: border-box; position: relative; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.badge { background: #e11d48; color: white; display: inline-block; padding: 6px 15px; border-radius: 99px; font-weight: bold; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }
.title { font-size: 36px; font-weight: 900; line-height: 1.1; text-transform: uppercase; margin-top: 10px; }
.sub { font-size: 16px; opacity: 0.8; margin-top: 5px; }
.size { font-family: monospace; font-size: 24px; color: #60a5fa; font-weight: bold; border-left: 4px solid #60a5fa; padding-left: 10px; margin: 25px 0; }
.description { font-size: 13px; opacity: 0.7; max-width: 80%; line-height: 1.5; }
.pricing { background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); border-radius: 15px; padding: 20px; display: flex; justify-content: space-between; align-items: center; }
.old-price { font-size: 14px; opacity: 0.5; text-decoration: line-through; }
.new-price { font-size: 32px; font-weight: 900; color: #4ade80; font-family:-apple-system, sans-serif; }
.footer { font-size: 11px; opacity: 0.6; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 15px; display: flex; justify-content: space-between; }
</style>
</head>
<body>
<div class="poster">
<div style="height: 100%; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<span class="badge">${marketingTopic} SPECIAL</span>
<div class="title">${selectedProduct.brand}<br/><span style="color:#fcd34d">${selectedProduct.model}</span></div>
<div class="sub">Haider Brother Traders Premium Radial</div>
<div class="size">${selectedProduct.size}</div>
<p class="description">${selectedProduct.description || "Incomparably robust tread design built for extreme wear and wet grip."}</p>
</div>
<div style="margin-top:auto; display:flex; flex-direction:column; gap:20px;">
<div class="pricing">
<div>
<div class="old-price">MSRP: ${settings.currencySymbol}${selectedProduct.price.toLocaleString()}</div>
<div style="font-size:11px; opacity:0.8; font-weight:700;">PROMO DEAL</div>
</div>
<div class="new-price">${settings.currencySymbol}${promoPrice.toLocaleString()}</div>
</div>
<div class="footer">
<div>🏢 Showroom: Main Chaman Road, Quetta</div>
<div>📞 Call/WA: ${settings.shopPhone}</div>
</div>
</div>
</div>
</div>
</body>
</html>
`;
const blob = new Blob([flyerHTML], { type: 'text/html' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `Promo flyer_${selectedProduct.brand}_${selectedProduct.model}.html`;
link.click();
};
return (
<div className="space-y-6 animate-fade-in" id="social-integration-cockpit">
{/* Mega header explaining direct shares */}
<div className="bg-white border border-slate-200 rounded-xl p-5 md:p-6 text-slate-950 flex flex-col md:flex-row justify-between items-start md:items-center gap-6 shadow-sm">
<div className="space-y-1.5 max-w-xl">
<div className="bg-slate-150 text-slate-700 text-[10px] font-bold px-2.5 py-0.5 rounded-md border border-slate-200/30 w-fit uppercase">
🚀 SOCIAL PROMOTION MULTIPLIER
</div>
<h2 className="text-sm font-bold text-slate-900 uppercase tracking-wide">Social Marketing Campaign Wizard</h2>
<p className="text-slate-400 text-xs md:text-sm">
Generate high-converting ads and social outreach posts directly from live stock indices to WhatsApp, FB, and downloadable digital pamphlets.
</p>
</div>
<div className="p-3 bg-slate-50 border border-slate-250/60 rounded-xl text-slate-850 self-center">
<Megaphone className="w-6 h-6" />
</div>
</div>
<div className="grid grid-cols-1 xl:grid-cols-12 gap-6">
{/* LEFT COLUMN: Setup flyer parameters */}
<div className="xl:col-span-4 bg-white border border-slate-200 rounded-xl p-5 shadow-sm space-y-5">
<div className="flex items-center gap-1.5 pb-3 border-b border-slate-100 uppercase">
<Sparkles className="w-4 h-4 text-slate-700" />
<span className="text-xs font-bold text-slate-900">Campaign Parameters</span>
</div>
{/* Search match */}
<div className="space-y-1">
<label className="text-[10px] text-slate-500 font-bold uppercase">1. Search & Select Tire Product</label>
<div className="relative mb-2">
<span className="absolute left-2.5 top-2.5 text-slate-400">
<Search className="w-3.5 h-3.5" />
</span>
<input
type="text"
placeholder="Search warehouse tires..."
value={promSearch}
onChange={(e) => setPromSearch(e.target.value)}
className="w-full text-xs border border-slate-200 p-2 pl-8 rounded-lg outline-none focus:border-slate-800 bg-white transition"
/>
</div>
<select
value={selectedProdId}
onChange={(e) => setSelectedProdId(e.target.value)}
className="w-full text-xs font-sans border border-slate-200 bg-white px-3 py-2 rounded-lg outline-none focus:border-slate-800 transition"
>
{filteredProducts.map(p => (
<option key={p.id} value={p.id}>
{p.brand} {p.model} ({p.size}) — {settings.currencySymbol}{p.price.toLocaleString()}
</option>
))}
</select>
</div>
{/* Marketing Theme Selection */}
<div className="space-y-1">
<label className="text-[10px] text-slate-500 font-bold uppercase">2. Select Campaign Vibe</label>
<div className="grid grid-cols-2 gap-2 text-xs font-sans">
<button
onClick={() => setMarketingTopic('DISCOUNT')}
className={`p-2 border rounded-lg transition text-left cursor-pointer font-bold ${marketingTopic === 'DISCOUNT' ? 'bg-slate-900 text-white shadow' : 'bg-slate-50 text-slate-600 hover:bg-slate-100 border-slate-200'}`}
>
🔥 MEGA Clearance
</button>
<button
onClick={() => setMarketingTopic('SAFETY')}
className={`p-2 border rounded-lg transition text-left cursor-pointer font-bold ${marketingTopic === 'SAFETY' ? 'bg-slate-900 text-white shadow' : 'bg-slate-50 text-slate-600 hover:bg-slate-100 border-slate-200'}`}
>
💧 Wet-Road Safety
</button>
<button
onClick={() => setMarketingTopic('WINTER')}
className={`p-2 border rounded-lg transition text-left cursor-pointer font-bold ${marketingTopic === 'WINTER' ? 'bg-slate-900 text-white shadow' : 'bg-slate-50 text-slate-600 hover:bg-slate-100 border-slate-200'}`}
>
❄️ All-Terrain Grip
</button>
<button
onClick={() => setMarketingTopic('PERFORMANCE')}
className={`p-2 border rounded-lg transition text-left cursor-pointer font-bold ${marketingTopic === 'PERFORMANCE' ? 'bg-slate-900 text-white shadow' : 'bg-slate-50 text-slate-600 hover:bg-slate-100 border-slate-200'}`}
>
🏁 Cornering Sport
</button>
</div>
</div>
{/* Pricing configurations & promo codes */}
<div className="grid grid-cols-2 gap-3 pb-2">
<div className="space-y-1">
<label className="text-[10px] text-slate-550 font-bold uppercase">Coupon discount</label>
<div className="relative">
<span className="absolute right-3 top-2 text-slate-400">
<Percent className="w-3.5 h-3.5" />
</span>
<input
type="number"
min="0"
max="90"
value={customDiscountPercent}
onChange={(e) => setCustomDiscountPercent(Math.min(90, Math.max(0, parseInt(e.target.value) || 0)))}
className="w-full text-xs font-mono border border-slate-200 bg-white px-3 py-2 rounded-lg outline-none focus:border-slate-800 transition"
/>
</div>
</div>
<div className="space-y-1">
<label className="text-[10px] text-slate-550 font-bold uppercase">Promo code token</label>
<input
type="text"
value={promoCode}
onChange={(e) => setPromoCode(e.target.value.toUpperCase())}
className="w-full text-xs font-mono font-bold border border-slate-200 bg-white px-3 py-2 rounded-lg outline-none text-slate-900 focus:border-slate-800 transition"
/>
</div>
</div>
</div>
{/* MIDDLE COLUMN: Text marketing output copy block */}
<div className="xl:col-span-5 bg-white border border-slate-200 rounded-xl p-5 shadow-sm flex flex-col justify-between">
<div className="space-y-3">
<div className="flex justify-between items-center border-b border-slate-100 pb-3 h-8">
<span className="text-xs font-bold text-slate-900 uppercase flex items-center gap-1.5">
<Megaphone className="w-4 h-4 text-slate-700" />
Social Outgoing Copy (Refined)
</span>
<button
type="button"
onClick={handleCopyClipboard}
className="text-xs text-slate-800 bg-slate-100 hover:bg-slate-200/80 border border-slate-250/50 px-2.5 py-1 rounded-md flex items-center gap-1 cursor-pointer transition shadow-sm"
>
{copied ? (
<>
<Check className="w-3.5 h-3.5 text-emerald-600" />
Copied!
</>
) : (
<>
<Copy className="w-3.5 h-3.5" />
Copy Code
</>
)}
</button>
</div>
<textarea
rows={14}
readOnly
value={promoCopyText}
className="w-full text-xs bg-slate-50 border border-slate-200 rounded-lg p-3 font-mono leading-relaxed resize-none outline-none focus:border-slate-800 transition"
/>
</div>
<div className="grid grid-cols-2 gap-3 pt-4">
<button
onClick={shareWhatsApp}
className="py-2.5 bg-slate-900 hover:bg-slate-800 text-white font-medium text-xs rounded-lg flex items-center justify-center gap-1.5 shadow-sm transition cursor-pointer"
>
<MessageSquare className="w-3.5 h-3.5" />
WhatsApp Blast
</button>
<button
onClick={shareFacebook}
className="py-2.5 bg-white hover:bg-slate-100 text-slate-800 font-semibold border border-slate-200 text-xs rounded-lg flex items-center justify-center gap-1.5 shadow-xs transition cursor-pointer"
>
<Share2 className="w-3.5 h-3.5" />
Facebook Feed
</button>
</div>
</div>
{/* RIGHT COLUMN: Real-time rendered poster image display container */}
<div className="xl:col-span-3 bg-white border border-slate-200 rounded-xl p-5 shadow-sm flex flex-col justify-between">
<div className="space-y-4">
<span className="text-xs font-bold text-slate-900 uppercase tracking-tight block border-b border-slate-100 pb-3">Poster Preview (500x600 px)</span>
{/* Visual flyer preview board */}
{selectedProduct ? (
<div
className={`rounded-xl p-6 text-white h-96 flex flex-col justify-between relative overflow-hidden shadow-md font-sans ${
marketingTopic === 'DISCOUNT' ? 'bg-gradient-to-b from-blue-900 to-slate-950 border border-blue-800' :
marketingTopic === 'SAFETY' ? 'bg-gradient-to-b from-teal-800 to-slate-950 border border-teal-700' :
marketingTopic === 'WINTER' ? 'bg-gradient-to-b from-indigo-900 to-slate-950 border border-indigo-800' :
'bg-gradient-to-b from-red-800 to-slate-950 border border-red-700'
}`}
>
<div className="space-y-2">
<span className="bg-red-600 text-white font-bold text-[9px] uppercase tracking-widest px-2 py-0.5 rounded-full">
{marketingTopic} Campaign
</span>
<div>
<h5 className="text-2xl font-black uppercase tracking-tight leading-none text-white">{selectedProduct.brand}</h5>
<p className="text-xs font-medium text-amber-300 leading-tight">{selectedProduct.model}</p>
</div>
<p className="font-mono text-xs font-bold text-blue-300 border-l-2 border-blue-400 pl-2">
{selectedProduct.size}
</p>
</div>
<div className="space-y-3 relative z-10">
<div className="bg-white/10 border border-white/10 rounded-xl p-3 flex justify-between items-center text-xs">
<div className="space-y-0.5">
<span className="text-[10px] text-white/50 text-decoration-line-through">MSRP: {selectedProduct.price.toLocaleString()}</span>
<p className="font-black text-white text-[10px]">CLEARANCE VALUE</p>
</div>
<span className="text-xl font-black text-emerald-400 font-mono">
{settings.currencySymbol}{promoPrice.toLocaleString()}
</span>
</div>
<div className="text-[9px] text-white/50 text-center leading-normal">
{settings.shopName} • {settings.shopPhone}
</div>
</div>
{/* Geometric tire tread watermarks on poster bg */}
<div className="absolute right-[-20px] bottom-10 opacity-5 pointer-events-none transform rotate-45 scale-125">
<div className="w-40 h-40 border-[15px] border-white rounded-full border-dashed"></div>
</div>
</div>
) : (
<div className="bg-slate-50 h-96 border rounded-2xl flex items-center justify-center text-slate-400 text-xs">
Select a warehouse product to preview flyer.
</div>
)}
</div>
<button
onClick={downloadFlyerHTML}
disabled={!selectedProduct}
className={`w-full py-2.5 mt-4 text-xs font-semibold rounded-lg flex items-center justify-center gap-1.5 cursor-pointer shadow-sm transition border ${
!selectedProduct
? 'bg-slate-100 text-slate-400 border-slate-200 cursor-not-allowed shadow-none'
: 'bg-slate-900 border-slate-900 hover:bg-slate-800 text-white'
}`}
>
<Download className="w-4.5 h-4.5" />
Download Poster Template
</button>
</div>
</div>
</div>
);
}