Files
ota-admin-portal/src/components/Cars/List/useQuery.js
Tristan Timblin e5ccb23443 CEC-4729: remove race-condition (#458)
* resolve localStorage race condition

* fix

* fix
2023-10-03 09:14:05 -07:00

79 lines
1.7 KiB
JavaScript

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 [search, setSearch] = useState(null);
const [vins, setVins] = useState("");
const [loading, setLoading] = useState(true);
function reset() {
setSearch("");
setVins([]);
}
useEffect(() => {
reset();
const parts = query.replaceAll(" ", ",").split(",").map(parseQueryPart);
setParts(parts);
parts.forEach(([type, value]) => {
if (type === "vin") {
setVins(vins => {
if (vins.length) {
return `${vins},${value}`;
}
return value;
});
}
if (type === "search") {
setSearch(search => `${search} ${value}`.trim());
}
});
setLoading(false);
}, [query]);
return {
parts,
search,
vins,
query,
setQuery,
loading,
}
}