Delaware's Marketplace for Low Digit Tags

import React, { useState, useRef } from "react"; /** * PlateHub – Single-file React app * ------------------------------------------------------ * What this does * - Lets users submit: plate photos + proof of ownership + contact info * - You review and send them a 7-day cash offer * - Built to be embedded into an existing website as a single page * * How to integrate * - Drop this component into your React site, or export to a static bundle * - Replace the `SUBMIT_ENDPOINT` with your backend or a form service * - Add your analytics / CRM hook in `handleSubmit` where indicated */ const SUBMIT_ENDPOINT = "/api/platehub/submit"; // TODO: replace with your endpoint or Formspree URL export default function PlateHubApp() { const [step, setStep] = useState(1); const [isSubmitting, setIsSubmitting] = useState(false); const [submittedId, setSubmittedId] = useState(""); const [error, setError] = useState(""); const [previewUrls, setPreviewUrls] = useState({ plate: "", proof: "" }); const [form, setForm] = useState({ firstName: "", lastName: "", email: "", phone: "", plateNumber: "", plateState: "DE", plateType: "Passenger (PC)", askingPrice: "", notes: "", agree: false, }); const plateFileRef = useRef(null); const proofFileRef = useRef(null); function onChange(e) { const { name, value, type, checked } = e.target; setForm((f) => ({ ...f, [name]: type === "checkbox" ? checked : value })); } function onFileChange(kind, file) { if (!file) return; const url = URL.createObjectURL(file); setPreviewUrls((p) => ({ ...p, [kind]: url })); } function validate() { const problems = []; if (!form.firstName.trim()) problems.push("First name is required."); if (!form.lastName.trim()) problems.push("Last name is required."); if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) problems.push("Valid email is required."); if (!form.phone.trim()) problems.push("Phone is required."); if (!form.plateNumber.trim()) problems.push("Plate number is required."); if (!plateFileRef.current?.files?.[0]) problems.push("A clear photo of the plate is required."); if (!proofFileRef.current?.files?.[0]) problems.push("Proof of ownership is required."); if (!form.agree) problems.push("You must agree to the 7-day offer policy."); return problems; } async function handleSubmit(e) { e.preventDefault(); setError(""); const problems = validate(); if (problems.length) { setError(problems.join("\n")); return; } try { setIsSubmitting(true); // Build multipart form data const fd = new FormData(); Object.entries(form).forEach(([k, v]) => fd.append(k, String(v))); if (plateFileRef.current?.files?.[0]) fd.append("platePhoto", plateFileRef.current.files[0]); if (proofFileRef.current?.files?.[0]) fd.append("proofDoc", proofFileRef.current.files[0]); // Send to your backend (replace endpoint above). For demo, we'll simulate success if no real endpoint. let ok = true, id = "PH-" + Math.random().toString(36).slice(2, 8).toUpperCase(); if (SUBMIT_ENDPOINT && !SUBMIT_ENDPOINT.startsWith("/api/platehub/submit")) { // Real submit mode const res = await fetch(SUBMIT_ENDPOINT, { method: "POST", body: fd }); ok = res.ok; id = res.ok ? (await res.json()).id || id : ""; } else { // Demo mode await new Promise((r) => setTimeout(r, 800)); } if (!ok) throw new Error("Submission failed. Please try again."); setSubmittedId(id); setStep(3); // TODO: Add your analytics/CRM hook here (HubSpot, Zapier, etc.) } catch (err) { setError(err.message || "Something went wrong."); } finally { setIsSubmitting(false); } } return (

{step === 1 && } {step === 2 && ( setStep(1)} /> )} {step === 3 && }
); } function Header() { return (
PH

PlateHub

7‑day cash offers for your plate

); } function Hero() { return (

Get an offer for your license plate in minutes.

Upload a photo of your plate and proof of ownership. We’ll review and send you a no‑obligation cash offer that’s valid for 7 days.

  • ✔️ Fast, private valuation
  • ✔️ Secure file uploads
  • ✔️ Delaware low‑digit friendly
); } function Steps({ current }) { const items = [ { id: 1, title: "Your info" }, { id: 2, title: "Upload docs" }, { id: 3, title: "Done" }, ]; return (
{items.map((it) => (
= it.id ? "border-blue-500/40 bg-blue-500/10 text-blue-200" : "border-neutral-800 bg-neutral-900/60 text-neutral-400") } >
{it.title}
))}
); } function InfoForm({ form, onChange, setStep }) { return (
{ e.preventDefault(); setStep(2); }} className="rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 sm:p-8" >