import { useState, useEffect } from "react"; import { useLocalStorage } from "../../useLocalStorage"; const TYPE_VIN = "vin"; /** * Match VIN with RegEx * @param {string} vin - potential VIN * @returns {boolean} */ function isVIN(vin) { var re = new RegExp("^[A-HJ-NPR-Z\\d]{8}[\\dX][A-HJ-NPR-Z\\d]{2}\\d{6}$"); return vin.match(re) } /** * Convert a string into a QueryPart tuple. * @typedef {"search" | "vin"} Type - the type of value represented * @typedef {string} Value - the value * @typedef {[Type, Value]} QueryPart - a tuple representing a substring of a query * @param {string} part - substring of a query to turn into a QueryPart * @returns {QueryPart} */ function parseQueryPart(part) { let type = "search"; if (isVIN(part)) { type = TYPE_VIN; part = `${part}`; } return [type, part]; } export default function useQuery() { const [query, setQuery] = useLocalStorage("VEHICLE_SEARCH", ""); const [parts, setParts] = useState([]); const [payload, setPayload] = useState({}); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true); let vins = []; let search = ""; const parts = query.replaceAll(" ", ",").split(",").map(parseQueryPart); setParts(parts); parts.forEach(([type, value]) => { if (type === "vin") { vins.push(value); } if (type === "search") { search = `${search} ${value}`.trim(); } }); setPayload({ search, vins: vins.join(","), }) }, [query, setPayload]); useEffect(() => { setLoading(false); }, [payload, setLoading]) return { parts, payload, query, setQuery, loading, } }