diff --git a/workloads/ecommerce/components/checkout/checkout-client.tsx b/workloads/ecommerce/components/checkout/checkout-client.tsx index ee6db1d..2caef9f 100644 --- a/workloads/ecommerce/components/checkout/checkout-client.tsx +++ b/workloads/ecommerce/components/checkout/checkout-client.tsx @@ -6,9 +6,13 @@ import { ArrowLeft, MapPin, MessageCircle, Truck } from "lucide-react"; import { type FormEvent, useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { ciudadesPorDepartamento, departamentos } from "@/lib/data/colombia"; import { formatMoney } from "@/lib/utils"; import { useCartStore } from "@/store/cart-store"; +const SELECT_CLASS = + "h-12 w-full rounded-full border border-slate-200 bg-white px-5 text-sm text-slate-950 outline-none transition focus:border-cyan-500 focus:ring-4 focus:ring-cyan-300/30 disabled:opacity-50"; + // ADR 0009, siguiente corte tras el carrito real: direccion + seleccion de // envio contra el Store API real (mismos endpoints ya verificados en vivo // para las shipping options). El pago (PayU custom) todavia no existe -- @@ -35,7 +39,21 @@ async function postJson(url: string, body: unknown) { export function CheckoutClient() { const { cartId, items, hasHydrated } = useCartStore(); const [step, setStep] = useState("address"); - const [form, setForm] = useState({ firstName: "", lastName: "", address1: "", city: "", province: "", phone: "", email: "" }); + const [form, setForm] = useState({ + firstName: "", + lastName: "", + address1: "", + // Se guarda el id DIVIPOLA seleccionado, no el texto libre -- ver + // lib/data/colombia.ts. El nombre real se deriva de este id para + // mandarlo a Medusa (que solo espera texto en shipping_address). + departmentId: null as number | null, + cityId: null as number | null, + phone: "", + email: "", + }); + const availableCities = form.departmentId ? ciudadesPorDepartamento(form.departmentId) : []; + const selectedDepartamento = departamentos.find((departamento) => departamento.id === form.departmentId); + const selectedCiudad = availableCities.find((ciudad) => ciudad.id === form.cityId); const [shippingOptions, setShippingOptions] = useState([]); const [selectedOptionId, setSelectedOptionId] = useState(null); const [shippingTotal, setShippingTotal] = useState(0); @@ -48,11 +66,20 @@ export function CheckoutClient() { async function submitAddress(event: FormEvent) { event.preventDefault(); - if (!cartId) return; + if (!cartId || !selectedCiudad || !selectedDepartamento) return; setLoading(true); setError(null); try { - const cart = await postJson("/api/cart/address", { cartId, ...form }); + const cart = await postJson("/api/cart/address", { + cartId, + firstName: form.firstName, + lastName: form.lastName, + address1: form.address1, + city: selectedCiudad.name, + province: selectedDepartamento.name, + phone: form.phone, + email: form.email, + }); if (cart.error) throw new Error(cart.error); const response = await fetch(`/api/cart/shipping-options?cartId=${cartId}`); const data = await response.json(); @@ -86,7 +113,7 @@ export function CheckoutClient() { function continueOnWhatsApp() { const lines = items.map((item) => `• ${item.quantity} x ${item.product.name}`).join("\n"); - const message = `Hola Ari Shopping 👋\nQuiero confirmar mi pedido:\n\n${lines}\n\nSubtotal: ${formatMoney(itemsSubtotal, currency)}\nEnvío: ${formatMoney(shippingTotal, currency)}\nTotal: ${formatMoney(total, currency)}\n\nNombre: ${form.firstName} ${form.lastName}\nDirección: ${form.address1}, ${form.city}${form.province ? `, ${form.province}` : ""}\nTeléfono: ${form.phone}`; + const message = `Hola Ari Shopping 👋\nQuiero confirmar mi pedido:\n\n${lines}\n\nSubtotal: ${formatMoney(itemsSubtotal, currency)}\nEnvío: ${formatMoney(shippingTotal, currency)}\nTotal: ${formatMoney(total, currency)}\n\nNombre: ${form.firstName} ${form.lastName}\nDirección: ${form.address1}, ${selectedCiudad?.name ?? ""}${selectedDepartamento ? `, ${selectedDepartamento.name}` : ""}\nTeléfono: ${form.phone}`; void navigator.clipboard?.writeText(message); window.open(process.env.NEXT_PUBLIC_WHATSAPP_URL ?? "https://wa.link/rvcqqc", "_blank", "noopener,noreferrer"); } @@ -116,8 +143,25 @@ export function CheckoutClient() { setForm({ ...form, address1: event.target.value })} />
- setForm({ ...form, city: event.target.value })} /> - setForm({ ...form, province: event.target.value })} /> + +
setForm({ ...form, phone: event.target.value })} /> @@ -130,7 +174,7 @@ export function CheckoutClient() { {step === "shipping" && (
-

{form.address1}, {form.city}{form.province ? `, ${form.province}` : ""}

+

{form.address1}, {selectedCiudad?.name}{selectedDepartamento ? `, ${selectedDepartamento.name}` : ""}

{shippingOptions.map((option) => (