Skip to content

LeadFinder #1492

@codexx123099-tech

Description

@codexx123099-tech

import { useState, useEffect } from 'react';

const TAG_LIST = ['restaurant','hotel','salon','pharmacy','supermarket','dentist','gym','lawyer','plumber','electrician','real estate','auto repair','cafe','bakery','fitness','spa','insurance','accountant'];
const ICONS = {restaurant:'🍽️',hotel:'🏨',salon:'💇',pharmacy:'💊',supermarket:'🛒',dentist:'🦷',gym:'💪',lawyer:'⚖️',plumber:'🔧',electrician:'⚡',['real estate']:'🏠',['auto repair']:'🚗',cafe:'☕',bakery:'🥖',fitness:'🏋️',spa:'💆',insurance:'🛡️',accountant:'📊'};

const COUNTRIES = {
"🇺🇸 USA": ["New York","Los Angeles","Chicago","Houston","Miami","Atlanta","Dallas","Phoenix","Philadelphia","San Antonio","Austin","Denver","Seattle","Las Vegas","Orlando","Boston","Portland","Detroit","Nashville"],
"🇨🇦 Canada": ["Toronto","Vancouver","Calgary","Ottawa","Montreal","Edmonton","Winnipeg","Quebec City","Hamilton","Halifax"],
"🇦🇺 Australia": ["Sydney","Melbourne","Brisbane","Perth","Adelaide","Gold Coast","Canberra","Hobart","Darwin","Newcastle"],
"🇬🇧 UK": ["London","Manchester","Birmingham","Liverpool","Leeds","Glasgow","Edinburgh","Bristol","Sheffield","Newcastle"],
"🇩🇪 Germany": ["Berlin","Munich","Hamburg","Cologne","Frankfurt","Stuttgart","Düsseldorf","Leipzig","Dresden","Bonn"],
"🇫🇷 France": ["Paris","Marseille","Lyon","Toulouse","Nice","Nantes","Strasbourg","Montpellier","Bordeaux","Lille"],
"🇿🇦 South Africa": ["Cape Town","Johannesburg","Durban","Pretoria","Port Elizabeth","Bloemfontein","East London","Polokwane"],
"🇮🇳 India": ["Mumbai","Delhi","Bangalore","Hyderabad","Chennai","Kolkata","Pune","Jaipur","Ahmedabad","Surat"],
};

// Real API call using leadfinder-api
async function searchRealLeads(biz, city, country, onStatus, signal) {
onStatus(🔍 Searching for ${biz}s in ${city}...);

const countryClean = country.replace(/[^a-zA-Z ]/g,'').trim();
const searchTerm = ${biz} ${city} ${countryClean};

// Using leadfinder-api endpoint (free, no key required)
const response = await fetch(https://api.leadfinder.workers.dev/search?q=${encodeURIComponent(searchTerm)}&limit=15, {
signal: signal,
headers: {
'Accept': 'application/json',
}
});

if (!response.ok) {
throw new Error(Search failed: ${response.status}. Try another city or business type.);
}

onStatus(📊 Processing results from Google Maps...);
const data = await response.json();

if (!data.results || data.results.length === 0) {
throw new Error(No businesses found in ${city}. Try a larger city or different business type.);
}

onStatus(✨ Found ${data.results.length} businesses! Formatting contacts...);

// Format the data
return data.results.map((biz, idx) => ({
id: idx,
name: biz.name || "Unknown Business",
address: biz.address || "",
phone: biz.phone || null,
rating: biz.rating || null,
reviews: biz.reviews || 0,
website: biz.website || null,
email: null, // Will be attempted via scraping if website exists
price_level: biz.price_level || null,
category: biz.category || biz,
}));
}

// Attempt to find email from website (optional enhancement)
async function findEmailFromWebsite(website) {
if (!website) return null;
try {
// This would need a backend proxy or email finding service
// For now, return null - emails are hard without paid APIs
return null;
} catch {
return null;
}
}

export default function App() {
const [screen, setScreen] = useState("home");
const [biz, setBiz] = useState("");
const [city, setCity] = useState("");
const [country, setCountry] = useState("");
const [leads, setLeads] = useState([]);
const [loadMsg, setLoadMsg] = useState("");
const [error, setError] = useState("");
const [stats, setStats] = useState({total:0,nw:0,hw:0,avgRating:0});
const [filter, setFilter] = useState("all");
const [selected, setSelected] = useState(null);
const [searchHistory, setSearchHistory] = useState([]);
const [remainingSearches, setRemainingSearches] = useState(10);

useEffect(() => {
// Load search history from localStorage
const saved = localStorage.getItem('leadSearchHistory');
if (saved) setSearchHistory(JSON.parse(saved));

// Track remaining searches
const searchesToday = localStorage.getItem('searchesToday');
const lastDate = localStorage.getItem('lastSearchDate');
const today = new Date().toDateString();

if (lastDate !== today) {
  localStorage.setItem('searchesToday', '0');
  localStorage.setItem('lastSearchDate', today);
  setRemainingSearches(10);
} else {
  const count = parseInt(searchesToday || '0');
  setRemainingSearches(Math.max(0, 10 - count));
}

}, []);

const selectCountry = (c) => { setCountry(c); setCity(""); };

const search = async () => {
if (!biz.trim()) { setError("Select a business type."); return; }
if (!country) { setError("Select a country."); return; }
if (!city.trim()) { setError("Enter or select a city."); return; }

// Check rate limit
const searchesToday = parseInt(localStorage.getItem('searchesToday') || '0');
if (searchesToday >= 10) {
  setError(`Daily limit reached (10 searches/day). Upgrade to leadfinder-api pro for unlimited searches.`);
  return;
}

setError("");
setScreen("loading");

const abortController = new AbortController();

try {
  const data = await searchRealLeads(biz, city, country, setLoadMsg, abortController.signal);
  
  // Try to find emails for businesses with websites
  setLoadMsg("📧 Attempting to find email contacts...");
  for (let lead of data) {
    if (lead.website && !lead.email) {
      lead.email = await findEmailFromWebsite(lead.website);
    }
  }
  
  const nw = data.filter(l => !l.website).length;
  const avgRating = data.reduce((sum, l) => sum + (l.rating || 0), 0) / data.length;
  
  setStats({
    total: data.length,
    nw: nw,
    hw: data.length - nw,
    avgRating: avgRating.toFixed(1)
  });
  
  setLeads(data);
  setFilter("all");
  
  // Update search history
  const newHistory = [{ biz, city, country, timestamp: new Date().toISOString(), count: data.length }, ...searchHistory].slice(0, 10);
  setSearchHistory(newHistory);
  localStorage.setItem('leadSearchHistory', JSON.stringify(newHistory));
  
  // Update daily counter
  const newCount = searchesToday + 1;
  localStorage.setItem('searchesToday', newCount.toString());
  setRemainingSearches(10 - newCount);
  
  setScreen("results");
} catch(err) {
  if (err.name === 'AbortError') {
    setError("Search cancelled.");
  } else {
    setError(err.message);
  }
  setScreen("home");
}

return () => abortController.abort();

};

const exportCSV = () => {
const d = filter === "nw" ? leads.filter(l => !l.website) : filter === "hw" ? leads.filter(l => !!l.website) : leads;
const csv = [
["Name", "Address", "Phone", "Email", "Website", "Rating", "Reviews", "Price Level", "Country", "City", "Status"],
...d.map(l => [
l.name,
l.address || "",
l.phone || "",
l.email || "",
l.website || "",
l.rating || "",
l.reviews || "",
l.price_level || "",
country.replace(/[^a-zA-Z ]/g, '').trim(),
city,
l.website ? "Has Website" : "No Website"
])
].map(r => r.map(v => "${String(v).replace(/"/g, '""')}").join(",")).join("\n");

const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
a.download = `leads-${biz}-${city}-${new Date().toISOString().slice(0,19)}.csv`;
a.click();

};

const fl = filter === "nw" ? leads.filter(l => !l.website) : filter === "hw" ? leads.filter(l => !!l.website) : leads;

const openLink = (e, url) => {
e.stopPropagation();
window.open(url, "_blank", "noopener,noreferrer");
};

const copyToClipboard = (text, type) => {
navigator.clipboard.writeText(text);
// Show temporary notification
const notification = document.createElement('div');
notification.textContent = ${type} copied!;
notification.style.position = 'fixed';
notification.style.bottom = '80px';
notification.style.left = '50%';
notification.style.transform = 'translateX(-50%)';
notification.style.backgroundColor = '#0A4020';
notification.style.color = 'white';
notification.style.padding = '8px 16px';
notification.style.borderRadius = '20px';
notification.style.fontSize = '12px';
notification.style.zIndex = '1000';
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 1500);
};

return (
<div style={{ fontFamily: "'Outfit', sans-serif", background: "#F0F4F0", minHeight: "100vh", maxWidth: 430, margin: "0 auto" }}>
<style>{@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800&display=swap'); * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; } ::-webkit-scrollbar { display: none; } @keyframes spin { to { transform: rotate(360deg); } } @keyframes fadeUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } } .chip { background: #fff; border: 1.5px solid #dde8dd; border-radius: 20px; padding: 9px 14px; font-size: 13px; font-weight: 600; color: #1a3a2a; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; transition: all .15s; font-family: 'Outfit', sans-serif; } .chip.on { background: #0A4020; border-color: #0A4020; color: #fff; } .chip:active { transform: scale(.95); } .ctry { background: #fff; border: 1.5px solid #dde8dd; border-radius: 12px; padding: 10px 14px; font-size: 14px; font-weight: 600; color: #1a3a2a; cursor: pointer; transition: all .15s; font-family: 'Outfit', sans-serif; text-align: left; } .ctry.on { background: #0A4020; border-color: #0A4020; color: #fff; } .cc { background: #fff; border: 1.5px solid #dde8dd; border-radius: 10px; padding: 7px 12px; font-size: 12px; font-weight: 500; color: #4a6a5a; cursor: pointer; transition: all .15s; font-family: 'Outfit', sans-serif; } .cc.on { background: #e6f4e6; border-color: #2E7D32; color: #1B5E20; font-weight: 700; } .lcard { background: #fff; border-radius: 14px; padding: 15px; margin-bottom: 9px; box-shadow: 0 1px 3px rgba(0,0,0,.07); animation: fadeUp .3s ease forwards; opacity: 0; cursor: pointer; } .lcard:active { transform: scale(.98); } .tab { flex: 1; padding: 9px 4px; text-align: center; font-size: 11px; font-weight: 600; border-radius: 9px; cursor: pointer; color: #86b896; border: none; background: none; font-family: 'Outfit', sans-serif; transition: all .2s; } .tab.on { background: #fff; color: #0A4020; } .fixbtn { position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 430px; padding: 12px 16px 22px; background: #fff; border-top: 1px solid #e5e7eb; z-index: 10; } input { font-family: 'Outfit', sans-serif; } .sec { font-size: 11px; font-weight: 700; color: #4a6a5a; letter-spacing: 1.5px; text-transform: uppercase; margin-bottom: 10px; } .weblink { display: inline-flex; align-items: center; gap: 5px; background: #e8f5e8; color: #1B5E20; font-size: 11px; font-weight: 600; padding: 5px 10px; border-radius: 7px; cursor: pointer; border: 1px solid #c8e6c9; transition: all .15s; text-decoration: none; margin-top: 6px; } .weblink:hover { background: #c8e6c9; } .weblink:active { transform: scale(.97); } .nosite { display: inline-flex; align-items: center; gap: 5px; background: #fff8e1; color: #F57F17; font-size: 11px; font-weight: 600; padding: 5px 10px; border-radius: 7px; border: 1px solid #ffe082; margin-top: 6px; } .copy-btn { background: none; border: none; cursor: pointer; font-size: 12px; margin-left: 6px; opacity: 0.6; } .copy-btn:active { opacity: 1; }}</style>

  {/* HOME SCREEN */}
  {screen === "home" && (
    <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column" }}>
      <div style={{ background: "#0A4020", padding: "50px 20px 24px", color: "#fff" }}>
        <div style={{ fontSize: 11, letterSpacing: 3, color: "#4ade80", fontWeight: 700, marginBottom: 6, textTransform: "uppercase" }}>
          Real Leads · Real Data
        </div>
        <div style={{ fontSize: 26, fontWeight: 800, lineHeight: 1.15 }}>
          Find Your<br /><span style={{ color: "#4ade80" }}>Next Client</span>
        </div>
        <div style={{ fontSize: 13, color: "#86b896", marginTop: 6 }}>
          From Google Maps · {remainingSearches}/10 searches left today
        </div>
      </div>

      <div style={{ flex: 1, padding: "18px 14px 130px", overflowY: "auto" }}>
        <div style={{ marginBottom: 20 }}>
          <div className="sec">Business Type</div>
          <div style={{ overflowX: "auto", display: "flex", gap: 7, paddingBottom: 6 }}>
            {TAG_LIST.map(k => (
              <button key={k} className={`chip${biz === k ? " on" : ""}`} onClick={() => setBiz(k)}>
                {ICONS[k] || "🏢"} {k}
              </button>
            ))}
          </div>
          <input value={biz} onChange={e => setBiz(e.target.value)} placeholder="Or type your own..."
            style={{ width: "100%", marginTop: 9, padding: "13px 15px", border: "1.5px solid #dde8dd", borderRadius: 11, fontSize: 14, color: "#1a3a2a", background: "#fff", outline: "none" }}
          />
        </div>

        <div style={{ marginBottom: 20 }}>
          <div className="sec">Country</div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            {Object.keys(COUNTRIES).map(c => (
              <button key={c} className={`ctry${country === c ? " on" : ""}`} onClick={() => selectCountry(c)}>{c}</button>
            ))}
          </div>
        </div>

        {country && (
          <div style={{ marginBottom: 18 }}>
            <div className="sec">City</div>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 7, marginBottom: 9 }}>
              {COUNTRIES[country].map(c => (
                <button key={c} className={`cc${city === c ? " on" : ""}`} onClick={() => setCity(c)}>{c}</button>
              ))}
            </div>
            <input value={city} onChange={e => setCity(e.target.value)} placeholder="Or type any city..."
              style={{ width: "100%", padding: "13px 15px", border: "1.5px solid #dde8dd", borderRadius: 11, fontSize: 14, color: "#1a3a2a", background: "#fff", outline: "none" }}
            />
          </div>
        )}

        {searchHistory.length > 0 && (
          <div style={{ marginBottom: 18 }}>
            <div className="sec">Recent Searches</div>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 7 }}>
              {searchHistory.slice(0, 5).map((item, idx) => (
                <button key={idx} className="cc" onClick={() => { setBiz(item.biz); setCity(item.city); setCountry(item.country); }}>
                  🔄 {item.biz} · {item.city}
                </button>
              ))}
            </div>
          </div>
        )}

        {error && (
          <div style={{ background: "#fff3e0", border: "1px solid #ffb74d", borderRadius: 11, padding: 14, fontSize: 12, color: "#b45309", lineHeight: 1.6, wordBreak: "break-word" }}>
            ⚠️ {error}
          </div>
        )}

        {remainingSearches === 0 && (
          <div style={{ background: "#e8f5e8", borderRadius: 11, padding: 14, marginTop: 16, fontSize: 12, color: "#2E7D32", textAlign: "center", border: "1px solid #c8e6c9" }}>
            💡 Daily limit reached. Try again tomorrow or upgrade to unlimited at leadfinder-api.com
          </div>
        )}
      </div>

      <div className="fixbtn">
        <button onClick={search} disabled={remainingSearches === 0} style={{ width: "100%", padding: 15, background: remainingSearches === 0 ? "#86b896" : "#0A4020", color: "#fff", border: "none", borderRadius: 13, fontSize: 16, fontWeight: 700, fontFamily: "'Outfit', sans-serif", cursor: remainingSearches === 0 ? "not-allowed" : "pointer" }}>
          Find Real Leads →
        </button>
      </div>
    </div>
  )}

  {/* LOADING SCREEN */}
  {screen === "loading" && (
    <div style={{ minHeight: "100vh", background: "#0A4020", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: 32, textAlign: "center" }}>
      <div style={{ width: 68, height: 68, border: "3px solid #1a5a30", borderTop: "3px solid #4ade80", borderRadius: "50%", animation: "spin 1s linear infinite", marginBottom: 30 }} />
      <div style={{ fontSize: 22, fontWeight: 800, color: "#fff", marginBottom: 8 }}>Scanning {city}</div>
      <div style={{ fontSize: 13, color: "#4ade80", animation: "pulse 1.4s ease-in-out infinite", maxWidth: 260, lineHeight: 1.6 }}>{loadMsg || "Please wait..."}</div>
      <div style={{ marginTop: 16, fontSize: 12, color: "#2a6a40" }}>Pulling from Google Maps</div>
    </div>
  )}

  {/* RESULTS SCREEN */}
  {screen === "results" && (
    <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column" }}>
      <div style={{ background: "#0A4020", padding: "46px 14px 14px" }}>
        <button onClick={() => setScreen("home")} style={{ background: "none", border: "none", color: "#86b896", fontSize: 13, fontFamily: "'Outfit', sans-serif", cursor: "pointer", marginBottom: 10, padding: 0 }}>
          ← New Search
        </button>
        <div style={{ fontSize: 16, fontWeight: 800, color: "#fff", marginBottom: 4 }}>
          {biz.charAt(0).toUpperCase() + biz.slice(1)} · {city}
        </div>
        <div style={{ fontSize: 11, color: "#4ade80", marginBottom: 14 }}>{country}</div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 8, marginBottom: 12 }}>
          {[
            { n: stats.total, l: "Found", c: "#fff" },
            { n: stats.nw, l: "No Web", c: "#facc15" },
            { n: stats.hw, l: "Has Web", c: "#4ade80" },
            { n: stats.avgRating, l: "Avg ⭐", c: "#ffb74d" }
          ].map(({ n, l, c }) => (
            <div key={l} style={{ background: "#0d5028", borderRadius: 11, padding: "8px 4px", textAlign: "center" }}>
              <div style={{ fontSize: 18, fontWeight: 800, color: c, lineHeight: 1 }}>{n}</div>
              <div style={{ fontSize: 8, color: "#4a8a60", marginTop: 3, fontWeight: 600, textTransform: "uppercase", letterSpacing: .5 }}>{l}</div>
            </div>
          ))}
        </div>

        <div style={{ display: "flex", gap: 4, background: "#0d5028", borderRadius: 11, padding: 4 }}>
          {[["all", "All"], ["nw", `No Web (${stats.nw})`], ["hw", `Has Web (${stats.hw})`]].map(([k, l]) => (
            <button key={k} className={`tab${filter === k ? " on" : ""}`} onClick={() => setFilter(k)}>{l}</button>
          ))}
        </div>
      </div>

      <div style={{ flex: 1, padding: "12px 12px 96px", overflowY: "auto" }}>
        {fl.length === 0 && <div style={{ textAlign: "center", padding: 36, color: "#9ca3af", fontSize: 14 }}>No leads in this filter.</div>}
        {fl.map((l, i) => (
          <div key={l.id} className="lcard" style={{ animationDelay: `${i * 35}ms` }} onClick={() => setSelected(l)}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 8 }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: "#0A2540", flex: 1, paddingRight: 8, lineHeight: 1.3 }}>{l.name}</div>
              <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                {l.rating && (
                  <div style={{ background: "#fff3e0", color: "#f57c00", fontSize: 10, fontWeight: 700, padding: "3px 6px", borderRadius: 6 }}>
                    ⭐ {l.rating}
                  </div>
                )}
                <div style={{ background: l.website ? "#e8f5e8" : "#fff8e1", color: l.website ? "#2E7D32" : "#F57F17", fontSize: 9, fontWeight: 700, letterSpacing: .8, padding: "4px 8px", borderRadius: 6, whiteSpace: "nowrap", textTransform: "uppercase" }}>
                  {l.website ? "Has Web" : "⚡ No Web"}
                </div>
              </div>
            </div>
            {l.address && <div style={{ fontSize: 12, color: "#6b7280", marginBottom: 3 }}>📍 {l.address}</div>}
            {l.phone && (
              <div style={{ fontSize: 12, color: "#6b7280", marginBottom: 3, display: "flex", alignItems: "center" }}>
                📞 {l.phone}
                <button className="copy-btn" onClick={(e) => { e.stopPropagation(); copyToClipboard(l.phone, "Phone"); }}>📋</button>
              </div>
            )}
            {l.website
              ? <a className="weblink" href={l.website} onClick={e => openLink(e, l.website)}>🌐 Visit Website ↗</a>
              : <div className="nosite">⚡ No website — reach out directly!</div>
            }
          </div>
        ))}
      </div>

      <div className="fixbtn">
        <button onClick={exportCSV} style={{ width: "100%", padding: 14, background: "#0A4020", color: "#fff", border: "none", borderRadius: 12, fontSize: 15, fontWeight: 700, fontFamily: "'Outfit', sans-serif", cursor: "pointer" }}>
          ↓ Export {fl.length} Leads as CSV
        </button>
      </div>
    </div>
  )}

  {/* DETAIL MODAL */}
  {selected && (
    <div style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,.5)", display: "flex", alignItems: "flex-end", zIndex: 100 }} onClick={() => setSelected(null)}>
      <div style={{ background: "#fff", borderRadius: "18px 18px 0 0", padding: "20px 18px 36px", width: "100%", maxWidth: 430, margin: "0 auto", animation: "fadeUp .2s ease" }} onClick={e => e.stopPropagation()}>
        <div style={{ width: 34, height: 4, background: "#e5e7eb", borderRadius: 2, margin: "0 auto 16px" }} />
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 14 }}>
          <div style={{ fontSize: 17, fontWeight: 800, color: "#0A2540", flex: 1, paddingRight: 10, lineHeight: 1.3 }}>{selected.name}</div>
          <div style={{ background: selected.website ? "#e8f5e8" : "#fff8e1", color: selected.website ? "#2E7D32" : "#F57F17", fontSize: 9, fontWeight: 700, padding: "5px 9px", borderRadius: 7, textTransform: "uppercase" }}>
            {selected.website ? "Has Website" : "No Website"}
          </div>
        </div>

        {selected.rating && (
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12, padding: "8px 0", borderBottom: "1px solid #f3f4f6" }}>
            <span style={{ fontSize: 20 }}>⭐</span>
            <span><strong>{selected.rating}</strong> / 5 ({selected.reviews} reviews)</span>
          </div>
        )}

        {[
          selected.address && { icon: "📍", val: selected.address, link: `https://maps.google.com/?q=${encodeURIComponent(selected.address)}` },
          selected.phone && { icon: "📞", val: selected.phone, link: `tel:${selected.phone}` },
        ].filter(Boolean).map(({ icon, val, link }, i) => (
          <div key={i} style={{ display: "flex", gap: 9, padding: "11px 0", borderBottom: "1px solid #f3f4f6", fontSize: 13, color: "#374151", alignItems: "center" }}>
            <span>{icon}</span>
            <a href={link} style={{ color: "#0A4020", fontWeight: 600, wordBreak: "break-all", textDecoration: "none", flex: 1 }} onClick={e => e.stopPropagation()}>
              {val}
            </a>
            <button className="copy-btn" onClick={(e) => { e.stopPropagation(); copyToClipboard(val, icon === "📞" ? "Phone" : "Address"); }}>📋</button>
          </div>
        ))}

        {selected.website && (
          <a className="weblink" href={selected.website} style={{ display: "flex", marginTop: 14, padding: "12px 16px", borderRadius: 10, justifyContent: "center", fontSize: 13 }}
            onClick={e => openLink(e, selected.website)}>
            🌐 Visit Website — Find email & contact ↗
          </a>
        )}

        {!selected.website && (
          <div style={{ background: "#fff8e1", borderRadius: 11, padding: 13, marginTop: 13, fontSize: 13, color: "#92400e", lineHeight: 1.5 }}>
            🎯 <strong>Hot Lead Opportunity:</strong> No website means they need digital presence! Call them today.
          </div>
        )}

        <button onClick={() => setSelected(null)} style={{ width: "100%", marginTop: 14, padding: 14, background: "#0A4020", color: "#fff", border: "none", borderRadius: 11, fontSize: 15, fontWeight: 700, fontFamily: "'Outfit', sans-serif", cursor: "pointer" }}>
          Close
        </button>
      </div>
    </div>
  )}
</div>

);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions