/* global React */ /* Step renderers — one per step of the wizard */ function StepCategory({ state, update }) { return (
{STEP_KICKER.category}

What are you selling?

Pick the category that fits best — we'll only ask questions relevant to it.

{CATEGORIES.map(c => ( { if (state.category !== id) { update({ ...defaultState(), category: id, sellerName: state.sellerName, sellerPhone: state.sellerPhone, sellerEmail: state.sellerEmail }); } else { update({ category: id }); } }} /> ))}
); } function StepType({ state, update }) { const freeText = state.category === "accessories" || state.category === "technology"; const types = TYPES_BY_CATEGORY[state.category]; return (
{STEP_KICKER.type}

{freeText ? "Describe the item" : "Pick the type"}

{freeText ? "A short, searchable name. Think what buyers would scroll past looking for." : "This helps us ask the right follow-up questions about size and fit."}

{freeText ? (
update({ type: v })} placeholder="Type or paste here" />
) : ( <>
{types.map(t => ( update({ type: id })} /> ))}
{state.category === "luggage" && state.type === "other" && (
update({ customType: v })} placeholder="e.g. Hydration pack, seat bag, rain cover…" />
)} )}
); } function StepSize({ state, update }) { const isMotorcycle = state.category === "motorcycle"; const isLuggage = state.category === "luggage"; const isBoots = state.category === "riding-gears" && state.type === "boots"; const sizes = getSizeOptions(state.category, state.type, state.sizeSystem); return (
{STEP_KICKER.size}

{isMotorcycle ? "Which engine band?" : isLuggage ? "What's the capacity?" : "What size is it?"}

{isMotorcycle ? "We group motorcycles by CC band so buyers can filter easily." : isLuggage ? "Give the litre capacity — that's what buyers search by." : "Match what's printed on the tag — mismatched sizes are the #1 reason deals fall through."}

{isLuggage ? (
update({ size: v })} type="number" placeholder="20" prefix="L" />
) : isBoots ? ( <>
update({ sizeSystem: v })} options={["UK","US","EU"]} />
update({ size: v })} options={sizes} />
) : (
update({ size: v })} options={sizes} />
)}
); } function StepDetails({ state, update }) { const isMotorcycle = state.category === "motorcycle"; const isGear = state.category === "riding-gears"; const isHelmet = isGear && state.type === "helmet"; const isJacketPant = isGear && (state.type === "jacket" || state.type === "pant"); const isGloves = isGear && state.type === "gloves"; const isBoots = isGear && state.type === "boots"; const isAccTech = state.category === "accessories" || state.category === "technology"; const isLuggage = state.category === "luggage"; return (
{STEP_KICKER.details}

The details that matter

The more specific you are here, the fewer follow-up messages you'll field.

{/* Brand + model */}

Brand & model

{isMotorcycle ? update({ condition: v })} options={CONDITIONS} placeholder="How is it?" />
{/* Motorcycle specifics */} {isMotorcycle && (

Motorcycle specifics

update({ regYear: v })} options={YEARS} placeholder="Select year" /> update({ odometer: v })} type="number" placeholder="25000" prefix="km" /> update({ fuelType: v })} options={FUEL_TYPES} placeholder="Select" /> update({ shell: v })} options={HELMET_SHELL} placeholder="Select" /> update({ bluetooth: v })} options={["Yes","No"]} /> update({ safetyRatings: v })} options={SAFETY_RATINGS} /> update({ visor: v })} options={VISOR_TYPES} />
)} {/* Jacket / pants */} {isJacketPant && (

Fabric & protection

update({ material: v })} options={MATERIALS} /> update({ protectionLevel: v })} options={["Level 1","Level 2"]} /> update({ waterproof: v })} options={["Yes","No"]} />
)} {/* Gloves */} {isGloves && (

Glove specifics

update({ material: v })} options={MATERIALS} placeholder="Select" /> update({ protectionLevel: v })} options={["Level 1","Level 2"]} />
)} {/* Boots */} {isBoots && (

Boot specifics

update({ purchaseYear: v })} options={YEARS} placeholder="Select" />
)}
); } function StepPrice({ state, update }) { return (
{STEP_KICKER.price}

Pricing & location

Pin where it is and what you want for it. Clear numbers get faster replies.

update({ price: v })} type="number" placeholder="5000" prefix="₹" /> update({ priceType: v })} options={[{ value: "fixed", label: "Fixed" },{ value: "negotiable", label: "Negotiable" }]} /> update({ location: v })} placeholder="City · locality (e.g. Bengaluru, Indiranagar)" /> update({ timeline: v })} options={TIMELINES.map(t => ({ id: t, label: t }))} />
); } function StepPhotos({ state, update }) { const inputRef = React.useRef(null); const [dragOver, setDragOver] = React.useState(false); const [dragId, setDragId] = React.useState(null); async function addFiles(fileList) { const files = Array.from(fileList || []).slice(0, 2 - (state.photos?.length || 0)); const reads = await Promise.all(files.map(f => new Promise(res => { const reader = new FileReader(); reader.onload = e => res({ id: Math.random().toString(36).slice(2), name: f.name, dataUrl: e.target.result }); reader.readAsDataURL(f); }))); const combined = [...(state.photos || []), ...reads].slice(0, 2); update({ photos: combined }); } function remove(id) { update({ photos: state.photos.filter(p => p.id !== id) }); } function onDrop(e) { e.preventDefault(); setDragOver(false); if (e.dataTransfer.files?.length) addFiles(e.dataTransfer.files); } function reorder(from, to) { if (from === to) return; const arr = [...state.photos]; const [m] = arr.splice(from, 1); arr.splice(to, 0, m); update({ photos: arr }); } return (
{STEP_KICKER.photos}

Add up to two photos

One wide shot plus a close-up of any wear or detail is usually enough. The first photo leads the post.

inputRef.current?.click()} onDragOver={e => { e.preventDefault(); setDragOver(true); }} onDragLeave={() => setDragOver(false)} onDrop={onDrop} >

Drop photos here or click to choose

PNG or JPG · up to 2 photos · drag to reorder

addFiles(e.target.files)} />
{state.photos?.length > 0 && (
{state.photos.map((p, i) => (
setDragId(p.id)} onDragOver={e => e.preventDefault()} onDrop={() => { const from = state.photos.findIndex(x => x.id === dragId); const to = i; setDragId(null); reorder(from, to); }} onDragEnd={() => setDragId(null)} > {p.name}
{i === 0 ? "Lead" : "Photo 2"}
Drag to reorder
))}
)}
); } function StepReason({ state, update }) { return (
{STEP_KICKER.reason}

A few lines, in your own words

The human part. Buyers read this first after the specs — keep it honest and short.