// detail.jsx — vehicle detail page, scheduling modal, contact footer
// ---------- Scheduling calendar modal ----------
const MESES = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];
const DIAS_SEM = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"];
function MiniCalendar({ selected, onSelect }) {
const today = new Date(); today.setHours(0, 0, 0, 0);
const [cursor, setCursor] = React.useState(() => new Date(today.getFullYear(), today.getMonth(), 1));
const maxDate = new Date(today); maxDate.setDate(maxDate.getDate() + 45);
const year = cursor.getFullYear(), month = cursor.getMonth();
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const cells = [];
for (let i = 0; i < firstDay; i++) cells.push(null);
for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(year, month, d));
const canPrev = new Date(year, month, 1) > new Date(today.getFullYear(), today.getMonth(), 1);
const canNext = new Date(year, month + 1, 1) <= maxDate;
const sameDay = (a, b) => a && b && a.toDateString() === b.toDateString();
return (
{MESES[month]} {year}
{DIAS_SEM.map((d) =>
{d}
)}
{cells.map((date, i) => {
if (!date) return
;
const past = date < today;
const tooFar = date > maxDate;
const closed = !STORE.diasAtendimento.includes(date.getDay());
const disabled = past || tooFar || closed;
const sel = sameDay(date, selected);
return (
);
})}
);
}
function SchedulingModal({ open, onClose, vehicle }) {
const [date, setDate] = React.useState(null);
const [time, setTime] = React.useState(null);
const [nome, setNome] = React.useState("");
const [tel, setTel] = React.useState("");
const [done, setDone] = React.useState(false);
React.useEffect(() => { if (open) { setDate(null); setTime(null); setNome(""); setTel(""); setDone(false); } }, [open, vehicle]);
if (!vehicle) return null;
const fmtDate = (d) => d ? `${d.getDate()} de ${MESES[d.getMonth()].toLowerCase()}` : "";
const ready = date && time && nome.trim() && tel.trim();
const confirm = () => setDone(true);
const waText = `Olá! Quero agendar uma visita para ver o *${vehicle.marca} ${vehicle.modelo} ${vehicle.ano}*.\n\n📅 Dia: ${fmtDate(date)}\n🕐 Horário: ${time}\n👤 Nome: ${nome}\n📞 Telefone: ${tel}`;
return (
{done ? (
Visita agendada!
{nome.split(" ")[0]}, sua visita para ver o {vehicle.modelo} está marcada para
{fmtDate(date)} às {time}.
Confirme pelo WhatsApp para garantir seu horário — o vendedor responde rapidinho.
) : (
<>
1. Escolha o dia
{ setDate(d); setTime(null); }} />
{date && (
2. Escolha o horário
{STORE.horarios.map((h) => (
))}
)}
{time && (
)}
>
)}
);
}
// ---------- Vehicle detail page ----------
function VehicleDetail({ vehicle, onBack, onSchedule }) {
const [activeFoto, setActiveFoto] = React.useState(0);
React.useEffect(() => { setActiveFoto(0); window.scrollTo(0, 0); }, [vehicle && vehicle.id]);
if (!vehicle) return null;
const fotos = vehicle.fotos && vehicle.fotos.length ? vehicle.fotos : [null];
const sold = vehicle.status === "vendido";
const isOferta = vehicle.status === "oferta" && vehicle.precoAntigo > vehicle.preco;
const desconto = isOferta ? Math.round((1 - vehicle.preco / vehicle.precoAntigo) * 100) : 0;
const galVehicle = { ...vehicle, fotos: fotos[activeFoto] ? [fotos[activeFoto]] : [] };
const waText = `Olá! Tenho interesse no *${vehicle.marca} ${vehicle.modelo} ${vehicle.ano}* (${formatBRL(vehicle.preco)}). Ainda está disponível?`;
return (
{/* gallery + info */}
{isOferta && -{desconto}%}
{fotos.length > 1 && (
{fotos.map((f, i) => (
))}
)}
{/* specs */}
{/* description */}
{vehicle.descricao && (
Descrição
{vehicle.descricao}
)}
{/* opcionais */}
{vehicle.opcionais && vehicle.opcionais.length > 0 && (
Opcionais e itens
{vehicle.opcionais.map((o) => (
{o}
))}
)}
{/* sticky sidebar */}
{vehicle.marca} · {vehicle.ano}
{vehicle.modelo}
{isOferta &&
{formatBRL(vehicle.precoAntigo)}
}
{formatBRL(vehicle.preco)}
{isOferta &&
Economize {formatBRL(vehicle.precoAntigo - vehicle.preco)}
}
{sold ? (
Este veículo já foi vendido
) : (
Falar no WhatsApp
)}
Atendimento direto com o vendedor
Onde estamos
{STORE.endereco}
{STORE.horario}
);
}
// ---------- Contact footer ----------
function Footer() {
return (
);
}
Object.assign(window, { SchedulingModal, VehicleDetail, Footer, MiniCalendar });