// 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}/>
{orders.map(o => ( ))}
Hora@Produto · TamValorStatus
{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 */}
AO VIVO 38:14
{/* 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
setInstagram(e.target.value)} placeholder="@usuario" style={{flex:1, fontSize:13}} autoFocus/>
{/* 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" && (
{PEDIDOS_LIVE.length} resultados
{PEDIDOS_LIVE.map(p => ( ))}
@InstagramClienteProduto · TamHoraValorStatus
{p.nr} {p.instagram} {p.cliente} {p.produto} · {p.tam} {p.hora} {brl(p.valor)}
)} {tab === "fretes" && (

Tabela de frete · Live #48

RegiãoTipoValorFrete grátis acima
Goiânia capitalMotoboy{brl(12.00)}{brl(200.00)}
Centro-OesteSedex{brl(28.50)}{brl(350.00)}
Sul/SudestePAC{brl(34.90)}{brl(450.00)}
NordestePAC{brl(42.00)}{brl(500.00)}
NorteSedex{brl(58.00)}{brl(600.00)}
)} {tab === "itens" && (

Itens vendidos na live

53 unidades
{PRODUTOS.slice(0, 7).map((p,i) => ( ))}
ProdutoMarcaTamQtdTotal
{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
{SACOLAS.map((s, i) => ( ))}
Cliente@ItensValorAberta háStatus aviso
{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
{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
)}

Histórico de sorteios

Ver tudo
{[ { 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 });