Skip to content

Commit

Permalink
🎉 feat: suggested search (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
casperiv0 authored Jan 5, 2022
1 parent 77d6ffc commit e3e454d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 11 deletions.
5 changes: 1 addition & 4 deletions packages/api/src/controllers/leo/SearchController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,7 @@ export class SearchController {
};

if (includeMany) {
const vehicles = await prisma.registeredVehicle.findMany({
where: { plate: { startsWith: plateOrVin.toUpperCase() } },
include: data.include,
});
const vehicles = await prisma.registeredVehicle.findMany(data);

return vehicles;
}
Expand Down
1 change: 1 addition & 0 deletions packages/client/locales/en/leo.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
"noWarrants": "This citizen does not have any warrants",
"revokeWarrant": "Revoke Warrant",
"releaseCitizen": "You are about to release this citizen. Please select the reason why they are getting released.",
"reportedStolen": "Reported Stolen",
"alert_deleteRecord": "Are you sure you want to delete this record? This action cannot be undone.",
"alert_deleteOfficer": "Are you sure you want to delete <span>{officer}</span>? This action cannot be undone.",
"alert_allowCheckout": "Are you sure you to checkout this vehicle from the impound lot?",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ import { Form, Formik, useFormikContext } from "formik";
import useFetch from "lib/useFetch";
import { ModalIds } from "types/ModalIds";
import { useTranslations } from "use-intl";
import { Input } from "components/form/Input";
import { Citizen, RecordType } from "types/prisma";
import { calculateAge } from "lib/utils";
import format from "date-fns/format";
import { VehiclesAndWeaponsSection } from "./VehiclesAndWeapons";
import { RecordsArea } from "./RecordsArea";
import { useNameSearch } from "state/nameSearchState";
import { NameSearchResult, useNameSearch } from "state/nameSearchState";
import { normalizeValue } from "context/ValuesContext";
import { useRouter } from "next/router";
import { ArrowLeft, PersonFill } from "react-bootstrap-icons";
import { useImageUrl } from "hooks/useImageUrl";
import { useAuth } from "context/AuthContext";
import { EditCitizenLicenses } from "./EditCitizenLicensesModal";
import { useFeatureEnabled } from "hooks/useFeatureEnabled";
import { InputSuggestions } from "components/form/InputSuggestions";

const enum Toggled {
VEHICLES,
Expand Down Expand Up @@ -124,10 +124,35 @@ export function NameSearchModal() {
className="w-[850px]"
>
<Formik initialValues={INITIAL_VALUES} onSubmit={onSubmit}>
{({ handleChange, errors, values, isValid }) => (
{({ handleChange, setFieldValue, errors, values, isValid }) => (
<Form>
<FormField errorMessage={errors.name} label={cT("fullName")}>
<Input value={values.name} name="name" onChange={handleChange} />
<InputSuggestions
onSuggestionClick={(suggestion: NameSearchResult) => {
setFieldValue("name", `${suggestion.name} ${suggestion.surname}`);
setCurrentResult(suggestion);
}}
Component={({ suggestion }: { suggestion: Citizen }) => (
<div className="flex items-center">
<p>
{suggestion.name} {suggestion.surname}{" "}
{SOCIAL_SECURITY_NUMBERS && suggestion.socialSecurityNumber ? (
<>(SSN: {suggestion.socialSecurityNumber})</>
) : null}
</p>
</div>
)}
options={{
apiPath: "/search/name",
method: "POST",
dataKey: "name",
}}
inputProps={{
value: values.name,
name: "name",
onChange: handleChange,
}}
/>
</FormField>

{typeof results === "boolean" ? <p>{t("nameNotFound")}</p> : null}
Expand Down
41 changes: 38 additions & 3 deletions packages/client/src/components/leo/modals/VehicleSearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import { Form, Formik } from "formik";
import useFetch from "lib/useFetch";
import { ModalIds } from "types/ModalIds";
import { useTranslations } from "use-intl";
import { Input } from "components/form/Input";
import { Citizen, RegisteredVehicle, Value } from "types/prisma";
import { format } from "date-fns";
import { useRouter } from "next/router";
import { InputSuggestions } from "components/form/InputSuggestions";
import { yesOrNoText } from "lib/utils";
import { classNames } from "lib/classNames";

export function VehicleSearchModal() {
const [results, setResults] = React.useState<VehicleSearchResult | null | boolean>(null);
Expand Down Expand Up @@ -72,10 +74,32 @@ export function VehicleSearchModal() {
className="w-[750px]"
>
<Formik initialValues={INITIAL_VALUES} onSubmit={onSubmit}>
{({ handleChange, errors, values, isValid }) => (
{({ handleChange, setFieldValue, errors, values, isValid }) => (
<Form>
<FormField errorMessage={errors.plateOrVin} label={t("plateOrVin")}>
<Input value={values.plateOrVin} name="plateOrVin" onChange={handleChange} />
<InputSuggestions
onSuggestionClick={(suggestion: VehicleSearchResult) => {
setFieldValue("plateOrVin", suggestion.vinNumber);
setResults(suggestion);
}}
Component={({ suggestion }: { suggestion: RegisteredVehicle }) => (
<div className="flex items-center">
<p>
{suggestion.plate.toUpperCase()} ({suggestion.vinNumber})
</p>
</div>
)}
options={{
apiPath: "/search/vehicle?includeMany=true",
method: "POST",
dataKey: "plateOrVin",
}}
inputProps={{
value: values.plateOrVin,
name: "plateOrVin",
onChange: handleChange,
}}
/>
</FormField>

{typeof results === "boolean" && results !== null ? (
Expand Down Expand Up @@ -123,6 +147,17 @@ export function VehicleSearchModal() {
{results.citizen.name} {results.citizen.surname}
</span>
</li>
<li>
<span className="font-semibold">{t("reportedStolen")}: </span>
<span
className={classNames(
"capitalize",
results.reportedStolen && "text-red-700 font-semibold",
)}
>
{common(yesOrNoText(results.reportedStolen))}
</span>
</li>
</ul>
</div>
) : null}
Expand Down

0 comments on commit e3e454d

Please sign in to comment.