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 (
Pick your machine, choose your dates, and pay securely.
Your request for {sel && sel.name} from {formatDate(form.start)} to {formatDate(form.end)} has been received. {" "}{stripeKey ? "Your payment is being processed." : "We will contact you to confirm and collect payment."}