// Módulo LIVE — Apresentar (mobile), Pedidos, Bag, Sortear
// ---------- APRESENTAR (mobile phone frame) ----------
const ApresentarPage = () => {
const [presentingId, setPresentingId] = React.useState("AUR-2841");
const [selectedSize, setSelectedSize] = React.useState(null);
const [instagram, setInstagram] = React.useState("");
const [orders, setOrders] = React.useState(PEDIDOS_LIVE.slice());
const presenting = PRODUTOS.find(p => p.id === presentingId);
const liveOrderCount = orders.filter(o => o.produto === presenting.nome).length;
const registerOrder = () => {
if (!selectedSize || !instagram) return;
const tam = selectedSize;
const novo = {
nr: "L-" + (2848 + (orders.length - PEDIDOS_LIVE.length)),
instagram: instagram.startsWith("@") ? instagram : "@" + instagram,
cliente: "—",
produto: presenting.nome,
tam,
valor: presenting.precoLive,
status: "Sacola",
hora: new Date().toLocaleTimeString("pt-BR").slice(0, 5),
};
setOrders([novo, ...orders]);
setInstagram("");
setSelectedSize(null);
};
return (
AO VIVO · Live #48 · 38m
Apresentar produto
Tela operada pelo apresentador no celular. Registra pedido em 1 toque por @ do Instagram.
{/* Phone preview */}
{ setPresentingId(id); setSelectedSize(null); }}
selectedSize={selectedSize}
setSelectedSize={setSelectedSize}
instagram={instagram}
setInstagram={setInstagram}
registerOrder={registerOrder}
liveOrderCount={liveOrderCount}
/>
{/* Side panel — visão do que tá rolando */}
Pedidos da live · ao vivo
{orders.length} pedidos
o.status !== 'Cancelado' ? s + o.valor : s, 0))} glow="green"/>
o.status === 'Aguardando pgto').length}/>
o.status === 'Sacola').length} glow="cyan"/>
o.instagram)).size}/>
| Hora | @ | Produto · Tam | Valor | Status |
{orders.map(o => (
| {o.hora} |
{o.instagram} |
{o.produto} · {o.tam} |
{brl(o.valor)} |
|
))}
Roteiro da live
10 produtos · 4 apresentados
{PRODUTOS.slice(0, 6).map((p, i) => {
const isPresenting = p.id === presentingId;
const orderCount = orders.filter(o => o.produto === p.nome).length;
return (
setPresentingId(p.id)}>
{String(i+1).padStart(2,'0')}
{p.foto}
{p.nome}
{p.id}
·
{Object.entries(p.tamanhos).filter(([,q]) => q > 0).map(([t]) => t).join('/')}
{brl(p.precoLive)}
{brl(p.preco)}
0 ? "accent" : "muted"}>{orderCount} pedidos
);
})}
);
};
// Phone screen content — mobile operator view
const PhoneApresentar = ({ presenting, produtos, presentingId, setPresentingId, selectedSize, setSelectedSize, instagram, setInstagram, registerOrder, liveOrderCount }) => (
{/* Top status bar */}
{/* Big product card */}
{presenting.foto}
APRESENTANDO · {presenting.id}
{presenting.nome}
{brl(presenting.precoLive)}
{brl(presenting.preco)}
{liveOrderCount} pedidos
{/* Size grid */}
Tamanhos · toque para selecionar
{Object.entries(presenting.tamanhos).map(([t, q]) => (
))}
{/* Order input */}
Registrar pedido · @instagram
{/* Quick product switcher */}
Roteiro · próximos produtos
{produtos.slice(0, 6).map((p, i) => (
))}
);
// ---------- PEDIDOS ----------
const LivePedidosPage = () => {
const [tab, setTab] = React.useState("pedidos");
return (
Live em andamento
Pedidos da live
Todos os pedidos registrados nesta live + gestão de frete, juntou-levou e cashback.
{tab === "pedidos" && (
)}
{tab === "fretes" && (
Tabela de frete · Live #48
| Região | Tipo | Valor | Frete grátis acima | |
| Goiânia capital | Motoboy | {brl(12.00)} | {brl(200.00)} | ⋯ |
| Centro-Oeste | Sedex | {brl(28.50)} | {brl(350.00)} | ⋯ |
| Sul/Sudeste | PAC | {brl(34.90)} | {brl(450.00)} | ⋯ |
| Nordeste | PAC | {brl(42.00)} | {brl(500.00)} | ⋯ |
| Norte | Sedex | {brl(58.00)} | {brl(600.00)} | ⋯ |
)}
{tab === "itens" && (
Itens vendidos na live
53 unidades
| Produto | Marca | Tam | Qtd | Total |
{PRODUTOS.slice(0, 7).map((p,i) => (
{p.foto} {p.nome} |
{p.marca} |
{Object.keys(p.tamanhos).slice(0,2).join(',')} |
{Math.floor(Math.random()*8)+2} |
{brl(p.precoLive * (Math.floor(Math.random()*8)+2))} |
))}
)}
{tab === "juntou" && (
Juntou Levou · ativo nesta live
Cliente que comprar 3+ peças na live ganha desconto automático no fechamento.
Aplicado a · 14 clientes nesta live
)}
{(tab === "creditos" || tab === "wpp" || tab === "cb") && (
)}
);
};
// ---------- BAG ----------
const LiveBagPage = () => (
Sacolas abertas
Bag — sacolas em aberto
Clientes que adicionaram itens na live mas ainda não fecharam. Aviso automático após 1h.
Sacolas · live #48
{SACOLAS.length} ativas
| Cliente | @ | Itens | Valor | Aberta há | Status aviso | |
{SACOLAS.map((s, i) => (
| {s.cliente} |
{s.instagram} |
{s.itens} |
{brl(s.valor)} |
{s.abertaHa} |
{i === 2 ? Aviso enviado : Sem aviso} |
|
))}
);
// ---------- SORTEAR ----------
const LiveSortearPage = () => {
const [winner, setWinner] = React.useState(null);
const [spinning, setSpinning] = React.useState(false);
const [participants] = React.useState(CLIENTES.slice(0, 8));
const sortear = () => {
setSpinning(true);
setWinner(null);
setTimeout(() => {
setSpinning(false);
setWinner(participants[Math.floor(Math.random() * participants.length)]);
}, 2400);
};
return (
Sorteio
Sortear ganhador
Sorteie entre clientes que compraram na live ou uma lista personalizada.
Fonte do sorteio
{participants.length} participantes elegíveis
·
cada @ entra 1×
{spinning && (
SORTEANDO…
{participants[Math.floor(Math.random() * participants.length)].instagram}
)}
{!spinning && winner && (
★ GANHADORA ★
{winner.nome}
{winner.instagram}
)}
{!spinning && !winner && (
🎁
Pronto pra sortear entre {participants.length} clientes
)}
{[
{ live: "Live #47", data: "12/05", ganhadora: "Renata Pacheco", premio: "Vestido Luna" },
{ live: "Live #46", data: "05/05", ganhadora: "Patrícia Souza", premio: "Vale R$ 200" },
{ live: "Live #45", data: "28/04", ganhadora: "Daniela Rocha", premio: "Cropped Pétala" },
{ live: "Live #44", data: "21/04", ganhadora: "Beatriz Almeida", premio: "Vale R$ 150" },
].map((h, i) => (
🎁
{h.ganhadora}
{h.live} · {h.premio}
{h.data}
))}
);
};
Object.assign(window, { ApresentarPage, LivePedidosPage, LiveBagPage, LiveSortearPage });