{Auth.isLogged() && wallet?.balance != null && (
)}
{/* search input */}
setSearchQuery(e.target.value)}
placeholder="Buscar lojas e produtos"
style={{ flex: 1, border: "none", background: "none", outline: "none", font: "500 14.5px var(--ui)", color: "var(--text)" }}
/>
{searchQuery && (
)}
{/* Segmentos — 9 visíveis + 10° é "Ver mais" que abre bottom sheet */}
{(() => {
const LIMIT = 9;
const visibleSegs = segs.slice(0, LIMIT);
const extraSegs = segs.slice(LIMIT);
const hasMore = extraSegs.length > 0;
const activeInExtra = shopSeg && extraSegs.some(s => s.id === shopSeg);
const segBtn = (s, onClick) => {
const active = shopSeg === s.id;
const label = (s.question || s.q || "").replace(/^Onde /i, "").replace(/\?$/, "");
return (
{/* Bottom sheet — segmentos extras */}
{moreSegsOpen && (
setMoreSegsOpen(false)} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,.45)", backdropFilter: "blur(3px)" }} />
Mais segmentos
{extraSegs.map(s => segBtn(s, () => { setShopSeg(shopSeg === s.id ? null : s.id); setMoreSegsOpen(false); }))}
{activeInExtra && (
)}
)}
>
);
})()}
{/* Jornadas — layout horizontal compacto */}
{[
{ fn: onNovoLar, bg: "var(--brand)", ic: "home", t: "Novo Lar", s: "Terreno ao décor" },
{ fn: onServices, bg: "var(--accent)", ic: "health", t: "Serviços", s: "Limpeza, chaveiro…" },
{ fn: onGastro, bg: "linear-gradient(135deg,#E8552D,#C98A1B)", ic: "food", t: "Gastronômico", s: "Gastronomia local" },
].map(f => (
))}
{/* Resultados filtrados (busca ou segmento ativo) */}
{isFiltering ? (
s.id === shopSeg)?.q || "Resultados" : `Resultados para "${searchQuery}"`}>
{filtered.length === 0
? Nenhum parceiro encontrado.
:
}
) : (
<>
{/* turbo rail */}
{turbo.length > 0 && (
)}
{/* best rated list */}
{filtered.slice(0, 8).map(p =>
)}
>
)}
{/* ── Seletor de endereço ── */}
{addrPickerOpen && (
setAddrPickerOpen(false)} style={{ position: "absolute", inset: 0, background: "rgba(16,18,45,.45)" }} />
Entregar em
{savedAddresses.length === 0 ? (
Nenhum endereço cadastrado.
Adicione em Perfil → Endereços.
) : (
{savedAddresses.map(addr => {
const active = defaultAddr?.id === addr.id;
return (
);
})}
)}
)}
);
}
function Section({ title, sub, children }) {
return (
);
}
// ── Loja do parceiro ─────────────────────────────────────────
function StoreScreen({ partner, mode, setMode, onBack, onPick, getQty, cartCount, cartTotal, onOpenCart, onNeedLogin }) {
const companyId = partner._raw?.id || partner.id;
// Busca detalhe completo (garante phone/whatsapp/instagram/video mesmo
// quando o partner veio do listing sem todos os campos)
const [detail, setDetail] = React.useState(null);
React.useEffect(() => {
if (!companyId) return;
API.company(companyId).then(c => setDetail(apiCompanyToPartner(c))).catch(() => {});
}, [companyId]);
const p = detail || partner;
const [showMapSheet, setShowMapSheet] = React.useState(false);
const [videoOpen, setVideoOpen] = React.useState(false);
const [reviewOpen, setReviewOpen] = React.useState(false);
const handleReview = () => { if (!Auth.isLogged()) { onNeedLogin?.(); return; } setReviewOpen(true); };
const [isFav, setIsFav] = React.useState(false);
React.useEffect(() => {
if (!companyId || !Auth.isLogged()) return;
API.me.favorites().then(d => {
setIsFav((d.favorites || []).some(f => f.id === companyId));
}).catch(() => {});
}, [companyId]);
const toggleFav = () => {
if (!Auth.isLogged()) { onNeedLogin?.(); return; }
if (isFav) { API.me.removeFavorite(companyId).catch(() => {}); setIsFav(false); }
else { API.me.addFavorite(companyId).catch(() => {}); setIsFav(true); }
};
// Carrega produtos reais da API
const [apiMenu, setApiMenu] = React.useState(null);
React.useEffect(() => {
API.products(companyId).then(d => {
const prods = d.products || [];
// Agrupa por category_name (igual ao formato de menu do mock)
const groups = {};
prods.filter(pr => pr.active).forEach(pr => {
const grp = pr.category_name || "Cardápio";
if (!groups[grp]) groups[grp] = [];
groups[grp].push({
id: pr.id,
name: pr.name,
desc: pr.description || "",
price: parseFloat(pr.price) || 0,
img: pr.image_url || null,
});
});
const sections = Object.entries(groups).map(([title, items]) => ({ title, items }));
setApiMenu(sections.length ? sections : null);
}).catch(() => {});
}, [companyId]);
const menu = apiMenu || menuFor(p.id);
const totalCb = p.cashback + p.turbo;
return (
0 ? 92 : 24 }}>
{/* hero */}
{p.coverUrl
?

:
}
{
const url = window.location.href.split('?')[0] + '?loja=' + (p._raw?.slug || p.id);
if (navigator.share) {
navigator.share({ title: p.name, text: p.blurb || 'Confira no Morar Bem!', url });
} else {
navigator.clipboard?.writeText(url).then(() => {});
}
}} />
{/* store card */}
{p.name}
{p.cat} · {p.area} · {p.price}
{p.reviews > 0 && (
{parseFloat(p.rating).toFixed(1)} ({p.reviews})
)}
{p.dist > 0 ? p.dist + " km" : "—"}
{p.time}
{p.turbo > 0 && }
{p.turbo > 0 && = {totalCb}% de volta}
{/* mode toggle */}
{[["delivery", "Entrega", "bike", p.delivery], ["pickup", "Retirada na loja", "store", p.pickup]].map(([id, lbl, ic, ok]) => (
))}
{p.turbo > 0 && (
Esta loja turbinou o cashback. Você recebe {totalCb}% de volta em BemCash a cada compra.
)}
{/* one-purchase rule note */}
Cashback válido em 1 compra por parceiro a cada pedido.
{/* quick-action bar */}
{(p.address || p.whatsapp || p.phone || p.instagram || p.video) && (
{p.video && (
)}
{p.address && (
)}
{p.phone && (
Ligar agora
)}
{p.whatsapp && (
WhatsApp
)}
{p.instagram && (
Instagram
)}
)}
{/* video modal */}
{videoOpen && p.video && (
setVideoOpen(false)} />
)}
{/* avaliação geral */}
{reviewOpen && setReviewOpen(false)} />}
{/* map options sheet */}
{showMapSheet && (
setShowMapSheet(false)} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,.45)" }} />
Localização
{p.address &&
{p.address}
}
{(() => {
const lat = p._raw?.latitude, lng = p._raw?.longitude;
const gmUrl = lat && lng
? `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}`
: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(p.address || p.name)}`;
const wazeUrl = lat && lng
? `https://waze.com/ul?ll=${lat},${lng}&navigate=yes`
: `https://waze.com/ul?q=${encodeURIComponent(p.address || p.name)}`;
return (<>
Abrir no Google Maps
Abrir no Waze
{p.phone && (
{p.phone}
)}
>);
})()}
)}
{/* menu */}
{menu.map(sec => (
{sec.title}
{sec.items.map(it => {
const q = getQty(it.id);
return (
);
})}
))}
{/* cart bar */}
{cartCount > 0 && (
)}
);
}
function qaBtn(bg, color) {
return {
display: "inline-flex", alignItems: "center", gap: 6, flexShrink: 0,
padding: "9px 14px", borderRadius: 12, border: "none", cursor: "pointer",
background: bg, font: "600 13px var(--ui)", color, textDecoration: "none",
whiteSpace: "nowrap",
};
}
function mapOptionBtn(bg) {
return {
display: "flex", alignItems: "center", gap: 12, padding: "14px 16px",
borderRadius: 14, background: bg, textDecoration: "none", border: "none", cursor: "pointer",
};
}
Object.assign(window, { money, ShopScreen, Section, StoreScreen, VideoModal, getVideoEmbed });