import { useState } from "react"; // ── AI Campaign Generator ───────────────────────────────────────────────────── const PLATFORMS = [ { id: "facebook", label: "Facebook Post", icon: "📘", color: "#1877F2", charLimit: 500, hint: "Engaging post with emojis, call to action, best for local reach" }, { id: "marketplace", label: "FB Marketplace", icon: "🛒", color: "#0866FF", charLimit: 300, hint: "Listing-style, price focused, short and punchy" }, { id: "google", label: "Google Ad", icon: "🔍", color: "#4285F4", charLimit: 90, hint: "Headline + description, keyword-rich, professional tone" }, { id: "instagram", label: "Instagram Caption", icon: "📸", color: "#E1306C", charLimit: 300, hint: "Visual-first, hashtags, energetic tone" }, { id: "craigslist", label: "Craigslist Ad", icon: "📋", color: "#800000", charLimit: 600, hint: "Plain text, detailed, practical info for local renters" }, ]; const PLATFORM_LINKS = { facebook: "https://www.facebook.com/", marketplace: "https://www.facebook.com/marketplace/create/item/", google: "https://ads.google.com/home/", instagram: "https://www.instagram.com/", craigslist: "https://post.craigslist.org/", }; async function generateCampaign({ equipment, promoDetails, selectedPlatforms, businessName }) { const platformDescriptions = selectedPlatforms.map(pid => { const p = PLATFORMS.find(x => x.id === pid); return `- ${p.label} (max ${p.charLimit} chars): ${p.hint}`; }).join("\n"); const equipList = equipment.map(e => `${e.name} (${e.type}, ${e.year}, $${e.dailyRate}/day)`).join(", "); const prompt = `You are a marketing expert for an equipment rental company called "${businessName || "our equipment rental company"}". Create ad copy for the following available equipment: ${equipList} ${promoDetails ? `Special promo/details: ${promoDetails}` : ""} Generate ad copy for each of these platforms. Return ONLY a valid JSON object (no markdown, no backticks) with platform IDs as keys and objects with "headline" and "body" fields: Platforms needed: ${platformDescriptions} Platform IDs to use as keys: ${selectedPlatforms.join(", ")} Requirements: - Each ad must be tailored to that platform's style and character limit - Include pricing info naturally - Add urgency and local appeal - For facebook and instagram include relevant emojis - For google keep headline under 30 chars, body under 90 chars - For craigslist be detailed and practical - Sound like a real local business, not corporate Return ONLY the JSON object, nothing else.`; const response = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4-6", max_tokens: 1000, messages: [{ role: "user", content: prompt }], }), }); const data = await response.json(); const text = data.content.map(i => i.text || "").join(""); const clean = text.replace(/```json|```/g, "").trim(); return JSON.parse(clean); } function CopyBtn({ text }) { const [copied, setCopied] = useState(false); const copy = () => { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return ( ); } function MarketingTab({ equipment, businessName, setBusinessName }) { const [step, setStep] = useState(1); // 1=setup, 2=generating, 3=results const [selectedEquip, setSelectedEquip] = useState([]); const [selectedPlatforms, setSelectedPlatforms] = useState(["facebook", "marketplace", "google"]); const [promoDetails, setPromoDetails] = useState(""); const [campaigns, setCampaigns] = useState(null); const [error, setError] = useState(""); const [savedCampaigns, setSavedCampaigns] = useState([]); const [activeResult, setActiveResult] = useState(null); const availableEquip = equipment.filter(e => e.status === "Available"); const toggleEquip = (id) => setSelectedEquip(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]); const togglePlatform = (id) => setSelectedPlatforms(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]); const generate = async () => { if (selectedEquip.length === 0) { setError("Select at least one piece of equipment."); return; } if (selectedPlatforms.length === 0) { setError("Select at least one platform."); return; } setError(""); setStep(2); try { const equip = equipment.filter(e => selectedEquip.includes(e.id)); const result = await generateCampaign({ equipment: equip, promoDetails, selectedPlatforms, businessName }); setCampaigns(result); setActiveResult(selectedPlatforms[0]); setStep(3); setSavedCampaigns(prev => [{ id: Date.now(), date: new Date().toLocaleDateString(), equipment: equip.map(e => e.name).join(", "), platforms: selectedPlatforms, result, }, ...prev]); } catch (e) { setError("Failed to generate campaign. Please try again."); setStep(1); } }; const reset = () => { setStep(1); setCampaigns(null); setSelectedEquip([]); setPromoDetails(""); setActiveResult(null); }; const INP2 = { width: "100%", boxSizing: "border-box", border: "1.5px solid #dde", borderRadius: 8, padding: "9px 12px", fontSize: 13, outline: "none", background: "#fafafa", fontFamily: "inherit", color: "#1a1a2e" }; return (
{/* Header row */}
Marketing Campaigns
AI-generated ads ready to post on each platform
{savedCampaigns.length > 0 && step !== 3 && (
{savedCampaigns.length} campaign{savedCampaigns.length > 1 ? "s" : ""} saved
)}
{/* Step 1: Setup */} {step === 1 && (
{/* Left col */}
Your Business Name
setBusinessName(e.target.value)} placeholder="e.g. Johnson Equipment Rentals" style={INP2} />
{/* Equipment picker */}
Select Equipment to Promote
Only available units shown
{availableEquip.length === 0 ? (
No available equipment right now.
) : (
setSelectedEquip(selectedEquip.length === availableEquip.length ? [] : availableEquip.map(e => e.id))} style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", padding: "8px 10px", borderRadius: 8, background: "#f8f9fb", marginBottom: 4 }}>
{selectedEquip.length === availableEquip.length && }
Select All
{availableEquip.map(e => (
toggleEquip(e.id)} style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", padding: "10px 12px", borderRadius: 8, border: `1.5px solid ${selectedEquip.includes(e.id) ? "#e8b84b" : "#eee"}`, background: selectedEquip.includes(e.id) ? "#fffbf0" : "#fff", transition: "all 0.15s" }}>
{selectedEquip.includes(e.id) && }
{e.image} {e.name}
${e.dailyRate}/day · {e.type}
))}
)}
{/* Platform picker + promo */}
Target Platforms
{PLATFORMS.map(p => (
togglePlatform(p.id)} style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", padding: "10px 12px", borderRadius: 8, border: `1.5px solid ${selectedPlatforms.includes(p.id) ? p.color : "#eee"}`, background: selectedPlatforms.includes(p.id) ? p.color + "10" : "#fff", transition: "all 0.15s" }}>
{selectedPlatforms.includes(p.id) && }
{p.icon} {p.label}
))}
Special Promo Details
e.g. "10% off this weekend" or "Free delivery within 30 miles"