From 13e82715a68aceea57581a0dce095689495284c8 Mon Sep 17 00:00:00 2001 From: Dev-CasperTheGhost <53900565+Dev-CasperTheGhost@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:49:24 +0200 Subject: [PATCH 1/2] feat: able to transfer vehicle to business --- .../business/BusinessController.ts | 21 +++++- apps/client/locales/en/citizen.json | 6 +- .../modals/transfer-vehicle-modal.tsx | 74 ++++++++++++++++--- 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/apps/api/src/controllers/business/BusinessController.ts b/apps/api/src/controllers/business/BusinessController.ts index e51ef3dbd..230386228 100644 --- a/apps/api/src/controllers/business/BusinessController.ts +++ b/apps/api/src/controllers/business/BusinessController.ts @@ -11,7 +11,14 @@ import { } from "@snailycad/schemas"; import { BadRequest, NotFound } from "@tsed/exceptions"; import { prisma } from "lib/data/prisma"; -import { type User, EmployeeAsEnum, MiscCadSettings, WhitelistStatus, cad } from "@prisma/client"; +import { + type User, + EmployeeAsEnum, + MiscCadSettings, + WhitelistStatus, + cad, + Prisma, +} from "@prisma/client"; import { validateSchema } from "lib/data/validate-schema"; import { UsePermissions, Permissions } from "middlewares/use-permissions"; import type * as APITypes from "@snailycad/types/api"; @@ -72,6 +79,18 @@ export class BusinessController { return { ownedBusinesses, joinedBusinesses, joinableBusinesses }; } + @Get("/search") + async searchBusinesses(@QueryParams("query") query: string) { + const where: Prisma.BusinessWhereInput = query + ? { name: { contains: query, mode: "insensitive" } } + : {}; + const joinableBusinesses = await prisma.business.findMany({ + where, + }); + + return joinableBusinesses; + } + @Get("/business/:id") async getBusinessById( @Context("user") user: User, diff --git a/apps/client/locales/en/citizen.json b/apps/client/locales/en/citizen.json index 8d1614470..fbb39c0b1 100644 --- a/apps/client/locales/en/citizen.json +++ b/apps/client/locales/en/citizen.json @@ -101,7 +101,8 @@ "trimLevels": "Trim Levels", "image": "Image", "transferVehicleInfo": "Transfer your {model} to a new owner. This means you will lose ownership of this vehicle and will be unable to manage it further.", - "alert_deleteVehicle": "Are you sure you want to delete this vehicle? This action cannot be undone." + "alert_deleteVehicle": "Are you sure you want to delete this vehicle? This action cannot be undone.", + "transferToBusiness": "Transfer to business" }, "Weapons": { "model": "Model", @@ -156,7 +157,7 @@ "LawBook": { "lawBook": "Law Book", "warningApplicable": "Warning Applicable", - "noPenalCodes": "No penal code has been registered", + "noPenalCodes": "No penal code has been registered", "warningNotApplicable": "Warning Not Applicable", "fines": "Fines", "bail": "Bail", @@ -164,4 +165,3 @@ "isPrimary": "Is Primary" } } - \ No newline at end of file diff --git a/apps/client/src/components/citizen/vehicles/modals/transfer-vehicle-modal.tsx b/apps/client/src/components/citizen/vehicles/modals/transfer-vehicle-modal.tsx index 146112cfb..5315595b6 100644 --- a/apps/client/src/components/citizen/vehicles/modals/transfer-vehicle-modal.tsx +++ b/apps/client/src/components/citizen/vehicles/modals/transfer-vehicle-modal.tsx @@ -1,10 +1,18 @@ -import { Loader, Button, TextField, FormRow } from "@snailycad/ui"; +import { + Loader, + Button, + TextField, + FormRow, + SwitchField, + AsyncListSearchField, + Item, +} from "@snailycad/ui"; import { Modal } from "components/modal/Modal"; import { useModal } from "state/modalState"; import { Form, Formik } from "formik"; import useFetch from "lib/useFetch"; import { useTranslations } from "use-intl"; -import type { RegisteredVehicle } from "@snailycad/types"; +import type { Business, RegisteredVehicle } from "@snailycad/types"; import { ModalIds } from "types/modal-ids"; import { handleValidate } from "lib/handleValidate"; import { TRANSFER_VEHICLE_SCHEMA } from "@snailycad/schemas"; @@ -37,6 +45,10 @@ export function TransferVehicleModal({ onTransfer, vehicle }: Props) { const validate = handleValidate(TRANSFER_VEHICLE_SCHEMA); const INITIAL_VALUES = { + transferType: "citizen" as "citizen" | "business", + businessName: "", + businessId: "", + ownerId: "", name: "", }; @@ -49,27 +61,65 @@ export function TransferVehicleModal({ onTransfer, vehicle }: Props) { className="w-[750px]" > - {({ isValid }) => ( + {({ isValid, values, errors, setValues, setFieldValue }) => ( - {t("transferVehicleInfo", { + {t.rich("transferVehicleInfo", { model: vehicle.model.value.value, + span: (children) => {children}, })} + + setFieldValue("transferType", isSelected ? "business" : "citizen") + } + > + {t("transferToBusiness")} + + - + {values.transferType === "business" ? ( + + className="w-full" + setValues={({ localValue, node }) => { + const labelValue = + typeof localValue !== "undefined" ? { businessName: localValue } : {}; + const valueField = node?.value ? { businessId: node.key as string } : {}; + + setValues({ ...values, ...labelValue, ...valueField }); + }} + localValue={values.businessName} + errorMessage={errors.businessId} + label="Business" + selectedKey={values.businessId} + fetchOptions={{ + apiPath: (query) => `/businesses/search?query=${query}`, + filterTextRequired: true, + }} + > + {(item) => { + return ( + + {item.name} + + ); + }} + + ) : ( + + )}
- {t("transferVehicleInfo", { + {t.rich("transferVehicleInfo", { model: vehicle.model.value.value, + span: (children) => {children}, })}