feat(forklifts): added the ability to add new forklifts in
This commit is contained in:
114
app/src/internal/forklifts/routes/hours/addHours.ts
Normal file
114
app/src/internal/forklifts/routes/hours/addHours.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import axios from "axios";
|
||||
import { type DrizzleError, sql } from "drizzle-orm";
|
||||
import type { Request, Response } from "express";
|
||||
import { Router } from "express";
|
||||
import https from "https";
|
||||
import { db } from "../../../../pkg/db/db.js";
|
||||
import {
|
||||
insertLeasesCompanySchema,
|
||||
leases,
|
||||
} from "../../../../pkg/db/schema/forkliftLeases.js";
|
||||
import { createLogger } from "../../../../pkg/logger/logger.js";
|
||||
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.post("/", async (req: Request, res: Response) => {
|
||||
// when a new server is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there
|
||||
//res.status(200).json({ message: "Server added", ip: req.hostname });
|
||||
const log = createLogger({ module: "forklift", subModule: "add lease" });
|
||||
const parsed = insertLeasesCompanySchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
return res.status(400).json({ errors: parsed.error.flatten() });
|
||||
}
|
||||
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.insert(leases)
|
||||
.values({
|
||||
...parsed.data,
|
||||
add_user: req.user?.username,
|
||||
add_date: sql`NOW()`,
|
||||
upd_user: req.user?.username,
|
||||
upd_date: sql`NOW()`,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: leases.leaseNumber,
|
||||
set: {
|
||||
...parsed.data,
|
||||
add_user: req.user?.username,
|
||||
add_date: sql`NOW()`,
|
||||
upd_user: req.user?.username,
|
||||
upd_date: sql`NOW()`,
|
||||
},
|
||||
})
|
||||
.returning({
|
||||
leaseNumber: leases.leaseNumber,
|
||||
}),
|
||||
);
|
||||
|
||||
if (error) {
|
||||
const err: DrizzleError = error;
|
||||
return res.status(400).json({
|
||||
message: `Error adding lease`,
|
||||
error: err.cause,
|
||||
});
|
||||
}
|
||||
|
||||
// if (req.hostname === "localhost" && process.env.MAIN_SERVER) {
|
||||
// log.info({}, "Running in dev server about to add in a new server");
|
||||
// const axiosInstance = axios.create({
|
||||
// httpsAgent: new https.Agent({ rejectUnauthorized: false }),
|
||||
// baseURL: process.env.MAIN_SERVER, // e.g. "https://example.com"
|
||||
// withCredentials: true,
|
||||
// });
|
||||
|
||||
// const loginRes = (await axiosInstance.post(
|
||||
// `${process.env.MAIN_SERVER}/lst/api/auth/sign-in/username`,
|
||||
// {
|
||||
// username: process.env.MAIN_SERVER_USERNAME,
|
||||
// password: process.env.MAIN_SERVER_PASSWORD,
|
||||
// },
|
||||
// {
|
||||
// headers: { "Content-Type": "application/json" },
|
||||
// },
|
||||
// )) as any;
|
||||
// const setCookie = loginRes.headers["set-cookie"][0];
|
||||
|
||||
// if (!setCookie) {
|
||||
// throw new Error("Did not receive a Set-Cookie header from login");
|
||||
// }
|
||||
|
||||
// const { data, error } = await tryCatch(
|
||||
// axios.post(
|
||||
// `${process.env.MAIN_SERVER}/lst/api/forklifts/leases`,
|
||||
// parsed.data,
|
||||
// {
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// Cookie: setCookie.split(";")[0],
|
||||
// },
|
||||
// withCredentials: true,
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
|
||||
// if (error) {
|
||||
// log.error(
|
||||
// { stack: error },
|
||||
// "There was an error adding the company to Main Server",
|
||||
// );
|
||||
// }
|
||||
// log.info(
|
||||
// { stack: data?.data },
|
||||
// "A new Company was just added to the server.",
|
||||
// );
|
||||
// }
|
||||
|
||||
return res
|
||||
.status(201)
|
||||
.json({ message: `lease ${data[0]?.leaseNumber} added`, data: data });
|
||||
});
|
||||
|
||||
export default router;
|
||||
59
app/src/internal/forklifts/routes/hours/getHours.ts
Normal file
59
app/src/internal/forklifts/routes/hours/getHours.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { and, asc, eq } from "drizzle-orm";
|
||||
import type { Request, Response } from "express";
|
||||
import { Router } from "express";
|
||||
import { db } from "../../../../pkg/db/db.js";
|
||||
import { forkliftCompanies } from "../../../../pkg/db/schema/forkliftLeaseCompanys.js";
|
||||
import { leases } from "../../../../pkg/db/schema/forkliftLeases.js";
|
||||
import { forklifts } from "../../../../pkg/db/schema/forklifts.js";
|
||||
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", async (req: Request, res: Response) => {
|
||||
const conditions = [];
|
||||
|
||||
if (req.query.lease !== undefined) {
|
||||
conditions.push(eq(leases.leaseNumber, `${req.query.lease}`));
|
||||
}
|
||||
|
||||
if (req.query.companyId !== undefined) {
|
||||
conditions.push(eq(leases.companyId, `${req.query.companyId}`));
|
||||
}
|
||||
|
||||
//conditions.push(eq(forkliftCompanies.active, true));
|
||||
|
||||
const { data, error } = (await tryCatch(
|
||||
db
|
||||
.select({
|
||||
id: leases.id,
|
||||
leaseNumber: leases.leaseNumber,
|
||||
startDate: leases.startDate,
|
||||
endDate: leases.endDate,
|
||||
leaseLink: leases.leaseLink,
|
||||
companyName: forkliftCompanies.name,
|
||||
add_user: leases.add_user,
|
||||
add_date: leases.add_date,
|
||||
upd_user: leases.upd_user,
|
||||
upd_date: leases.upd_date,
|
||||
})
|
||||
.from(leases)
|
||||
.innerJoin(forkliftCompanies, eq(forkliftCompanies.id, leases.companyId))
|
||||
.where(and(...conditions))
|
||||
.orderBy(asc(leases.leaseNumber)),
|
||||
)) as any;
|
||||
|
||||
// add the forklifts that are in this lease
|
||||
const forkliftData = await db.select().from(forklifts);
|
||||
|
||||
if (error) {
|
||||
return res.status(400).json({ error: error });
|
||||
}
|
||||
|
||||
const leaseData = data.map((i: any) => ({
|
||||
...i,
|
||||
forklifts: forkliftData.filter((x) => x.leaseId === i.id),
|
||||
}));
|
||||
res.status(200).json({ message: "Current Leases", data: leaseData });
|
||||
});
|
||||
|
||||
export default router;
|
||||
20
app/src/internal/forklifts/routes/hours/leaseRoutes.ts
Normal file
20
app/src/internal/forklifts/routes/hours/leaseRoutes.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Router } from "express";
|
||||
import { requireAuth } from "../../../../pkg/middleware/authMiddleware.js";
|
||||
|
||||
import addHours from "./addHours.js";
|
||||
import gethours from "./getHours.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.use(
|
||||
"/",
|
||||
requireAuth("forklifts", ["systemAdmin", "admin", "manager", "supervisor"]),
|
||||
addHours,
|
||||
);
|
||||
router.use(
|
||||
"/",
|
||||
requireAuth("forklifts", ["systemAdmin", "admin", "manager", "supervisor"]),
|
||||
gethours,
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -61,7 +61,7 @@ export default function ForkliftSideBar() {
|
||||
},
|
||||
{
|
||||
title: "Forklifts",
|
||||
url: "/lst/app/admin/modules",
|
||||
url: "/lst/app/forklifts/forklifts",
|
||||
icon: Forklift,
|
||||
role: ["systemAdmin", "admin", "manager", "supervisor"],
|
||||
module: "forklifts",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Link, useRouterState } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
import NewCompanyForm from "@/routes/_app/_forklifts/-components/NewCompany";
|
||||
import NewForklift from "@/routes/_app/_forklifts/-components/NewForklift";
|
||||
import NewInvoice from "@/routes/_app/_forklifts/-components/NewInvoice";
|
||||
import NewLeaseForm from "@/routes/_app/_forklifts/-components/NewLease";
|
||||
import { useAuth, useLogout } from "../../lib/authClient";
|
||||
@@ -25,6 +26,7 @@ export default function Nav() {
|
||||
const [openDialog, setOpenDialog] = useState(false);
|
||||
const [openLeaseDialog, setOpenLeaseDialog] = useState(false);
|
||||
const [openInvoiceDialog, setOpenInvoiceDialog] = useState(false);
|
||||
const [openForkliftDialog, setOpenForkliftDialog] = useState(false);
|
||||
return (
|
||||
<nav className="flex justify-end w-full shadow ">
|
||||
<div className="m-2 flex flex-row gap-1">
|
||||
@@ -75,6 +77,14 @@ export default function Nav() {
|
||||
>
|
||||
New Invoice
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onSelect={() => {
|
||||
// just open the dialog when clicked
|
||||
setOpenForkliftDialog(true);
|
||||
}}
|
||||
>
|
||||
New Forklift
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
{/* Company */}
|
||||
@@ -105,6 +115,16 @@ export default function Nav() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)}
|
||||
{openForkliftDialog && (
|
||||
<Dialog
|
||||
open={openForkliftDialog}
|
||||
onOpenChange={setOpenForkliftDialog}
|
||||
>
|
||||
<DialogContent className="sm:max-w-fit">
|
||||
<NewForklift setOpenDialog={setOpenForkliftDialog} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
17
frontend/src/lib/querys/forklifts/getForklifts.ts
Normal file
17
frontend/src/lib/querys/forklifts/getForklifts.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getForklifts() {
|
||||
return queryOptions({
|
||||
queryKey: ["getForklifts"],
|
||||
queryFn: () => fetch(),
|
||||
staleTime: 5000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
const fetch = async () => {
|
||||
const { data } = await axios.get("/lst/api/forklifts");
|
||||
|
||||
return data.data;
|
||||
};
|
||||
@@ -31,6 +31,7 @@ import { Route as MobileMobileLayoutMDeliveryRouteImport } from './routes/_mobil
|
||||
import { Route as MobileMobileLayoutMCyclecountsRouteImport } from './routes/_mobile/_mobileLayout/m/cyclecounts'
|
||||
import { Route as AppForkliftsForkliftsLeasesRouteImport } from './routes/_app/_forklifts/forklifts/leases'
|
||||
import { Route as AppForkliftsForkliftsInvoicesRouteImport } from './routes/_app/_forklifts/forklifts/invoices'
|
||||
import { Route as AppForkliftsForkliftsForkliftsRouteImport } from './routes/_app/_forklifts/forklifts/forklifts'
|
||||
import { Route as AppForkliftsForkliftsCompaniesRouteImport } from './routes/_app/_forklifts/forklifts/companies'
|
||||
import { Route as AppAdminLayoutAdminServersRouteImport } from './routes/_app/_adminLayout/admin/servers'
|
||||
import { Route as ApplogisticsLogisticsDeliveryScheduleRouteImport } from './routes/_app/(logistics)/logistics/deliverySchedule'
|
||||
@@ -165,6 +166,12 @@ const AppForkliftsForkliftsInvoicesRoute =
|
||||
path: '/forklifts/invoices',
|
||||
getParentRoute: () => AppForkliftsRouteRoute,
|
||||
} as any)
|
||||
const AppForkliftsForkliftsForkliftsRoute =
|
||||
AppForkliftsForkliftsForkliftsRouteImport.update({
|
||||
id: '/forklifts/forklifts',
|
||||
path: '/forklifts/forklifts',
|
||||
getParentRoute: () => AppForkliftsRouteRoute,
|
||||
} as any)
|
||||
const AppForkliftsForkliftsCompaniesRoute =
|
||||
AppForkliftsForkliftsCompaniesRouteImport.update({
|
||||
id: '/forklifts/companies',
|
||||
@@ -300,6 +307,7 @@ export interface FileRoutesByFullPath {
|
||||
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
|
||||
'/forklifts/forklifts': typeof AppForkliftsForkliftsForkliftsRoute
|
||||
'/forklifts/invoices': typeof AppForkliftsForkliftsInvoicesRoute
|
||||
'/forklifts/leases': typeof AppForkliftsForkliftsLeasesRoute
|
||||
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
@@ -337,6 +345,7 @@ export interface FileRoutesByTo {
|
||||
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
|
||||
'/forklifts/forklifts': typeof AppForkliftsForkliftsForkliftsRoute
|
||||
'/forklifts/invoices': typeof AppForkliftsForkliftsInvoicesRoute
|
||||
'/forklifts/leases': typeof AppForkliftsForkliftsLeasesRoute
|
||||
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
@@ -382,6 +391,7 @@ export interface FileRoutesById {
|
||||
'/_app/(logistics)/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/_app/_adminLayout/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/_app/_forklifts/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
|
||||
'/_app/_forklifts/forklifts/forklifts': typeof AppForkliftsForkliftsForkliftsRoute
|
||||
'/_app/_forklifts/forklifts/invoices': typeof AppForkliftsForkliftsInvoicesRoute
|
||||
'/_app/_forklifts/forklifts/leases': typeof AppForkliftsForkliftsLeasesRoute
|
||||
'/_mobile/_mobileLayout/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
@@ -422,6 +432,7 @@ export interface FileRouteTypes {
|
||||
| '/logistics/deliverySchedule'
|
||||
| '/admin/servers'
|
||||
| '/forklifts/companies'
|
||||
| '/forklifts/forklifts'
|
||||
| '/forklifts/invoices'
|
||||
| '/forklifts/leases'
|
||||
| '/m/cyclecounts'
|
||||
@@ -459,6 +470,7 @@ export interface FileRouteTypes {
|
||||
| '/logistics/deliverySchedule'
|
||||
| '/admin/servers'
|
||||
| '/forklifts/companies'
|
||||
| '/forklifts/forklifts'
|
||||
| '/forklifts/invoices'
|
||||
| '/forklifts/leases'
|
||||
| '/m/cyclecounts'
|
||||
@@ -503,6 +515,7 @@ export interface FileRouteTypes {
|
||||
| '/_app/(logistics)/logistics/deliverySchedule'
|
||||
| '/_app/_adminLayout/admin/servers'
|
||||
| '/_app/_forklifts/forklifts/companies'
|
||||
| '/_app/_forklifts/forklifts/forklifts'
|
||||
| '/_app/_forklifts/forklifts/invoices'
|
||||
| '/_app/_forklifts/forklifts/leases'
|
||||
| '/_mobile/_mobileLayout/m/cyclecounts'
|
||||
@@ -684,6 +697,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof AppForkliftsForkliftsInvoicesRouteImport
|
||||
parentRoute: typeof AppForkliftsRouteRoute
|
||||
}
|
||||
'/_app/_forklifts/forklifts/forklifts': {
|
||||
id: '/_app/_forklifts/forklifts/forklifts'
|
||||
path: '/forklifts/forklifts'
|
||||
fullPath: '/forklifts/forklifts'
|
||||
preLoaderRoute: typeof AppForkliftsForkliftsForkliftsRouteImport
|
||||
parentRoute: typeof AppForkliftsRouteRoute
|
||||
}
|
||||
'/_app/_forklifts/forklifts/companies': {
|
||||
id: '/_app/_forklifts/forklifts/companies'
|
||||
path: '/forklifts/companies'
|
||||
@@ -899,6 +919,7 @@ const AppAdminLayoutRouteRouteWithChildren =
|
||||
|
||||
interface AppForkliftsRouteRouteChildren {
|
||||
AppForkliftsForkliftsCompaniesRoute: typeof AppForkliftsForkliftsCompaniesRoute
|
||||
AppForkliftsForkliftsForkliftsRoute: typeof AppForkliftsForkliftsForkliftsRoute
|
||||
AppForkliftsForkliftsInvoicesRoute: typeof AppForkliftsForkliftsInvoicesRoute
|
||||
AppForkliftsForkliftsLeasesRoute: typeof AppForkliftsForkliftsLeasesRoute
|
||||
AppForkliftsForkliftsIndexRoute: typeof AppForkliftsForkliftsIndexRoute
|
||||
@@ -906,6 +927,7 @@ interface AppForkliftsRouteRouteChildren {
|
||||
|
||||
const AppForkliftsRouteRouteChildren: AppForkliftsRouteRouteChildren = {
|
||||
AppForkliftsForkliftsCompaniesRoute: AppForkliftsForkliftsCompaniesRoute,
|
||||
AppForkliftsForkliftsForkliftsRoute: AppForkliftsForkliftsForkliftsRoute,
|
||||
AppForkliftsForkliftsInvoicesRoute: AppForkliftsForkliftsInvoicesRoute,
|
||||
AppForkliftsForkliftsLeasesRoute: AppForkliftsForkliftsLeasesRoute,
|
||||
AppForkliftsForkliftsIndexRoute: AppForkliftsForkliftsIndexRoute,
|
||||
|
||||
244
frontend/src/routes/_app/_forklifts/-components/NewForklift.tsx
Normal file
244
frontend/src/routes/_app/_forklifts/-components/NewForklift.tsx
Normal file
@@ -0,0 +1,244 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DialogClose,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { getServers } from "@/lib/querys/admin/getServers";
|
||||
import { getLeases } from "@/lib/querys/forklifts/getLeases";
|
||||
import { useAppForm } from "../../../../lib/formStuff";
|
||||
|
||||
const forkliftManufacturer: any = [
|
||||
{ value: "Jungheinrich", label: "Jungheinrich" },
|
||||
{ value: "Toyota", label: "Toyota" },
|
||||
{ value: "Caterpillar", label: "Caterpillar" },
|
||||
{ value: "Mitsubishi", label: "Mitsubishi" },
|
||||
{ value: "BigJoe", label: "BigJoe" },
|
||||
{ value: "Yale", label: "Yale" },
|
||||
{ value: "Hyster", label: "Hyster" },
|
||||
{ value: "Global", label: "Global" },
|
||||
{ value: "Wesco", label: "Wesco" },
|
||||
{ value: "JLG", label: "JLG" },
|
||||
{ value: "Genie", label: "Genie" },
|
||||
{ value: "Linde", label: "Linde" },
|
||||
{ value: "Skyjack", label: "Skyjack" },
|
||||
{ value: "NilFisk", label: "NilFisk" },
|
||||
{ value: "Boomer", label: "Boomer" },
|
||||
{ value: "Crown", label: "Crown" },
|
||||
];
|
||||
|
||||
const batteryType: any = [
|
||||
{ value: "leadAcid", label: "Lead Acid" },
|
||||
{ value: "lithium", label: "Lithium" },
|
||||
{ value: "12v", label: "12v" },
|
||||
];
|
||||
|
||||
const engineType: any = [
|
||||
{ value: "electric", label: "Electric" },
|
||||
{ value: "propane", label: "Propane" },
|
||||
];
|
||||
|
||||
const pfc: any = [
|
||||
{ value: "20", label: "EBM" },
|
||||
{ value: "30", label: "SBM" },
|
||||
{ value: "40", label: "PET" },
|
||||
{ value: "50", label: "CAPS" },
|
||||
];
|
||||
export default function NewForklift({ setOpenDialog }: { setOpenDialog: any }) {
|
||||
//const search = useSearch({ from: "/_app/(auth)/login" });
|
||||
const { data: s, isLoading: es } = useQuery(getServers());
|
||||
const {
|
||||
data: leases,
|
||||
isLoading: leaseError,
|
||||
refetch,
|
||||
} = useQuery(getLeases());
|
||||
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
serialNumber: "",
|
||||
model: "",
|
||||
plant: "",
|
||||
profitCenter: "",
|
||||
manufacturer: "",
|
||||
manufacturerYear: "",
|
||||
engine: "",
|
||||
batteryType: "lead acid",
|
||||
leaseId: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
// get the glcode
|
||||
const glCode = s.filter((n: any) => n.name === value.plant);
|
||||
const data = {
|
||||
serialNumber: value.serialNumber,
|
||||
model: value.model.toUpperCase(),
|
||||
plant: value.plant,
|
||||
glCode: Number(glCode[0].greatPlainsPlantCode),
|
||||
profitCenter: Number(value.profitCenter),
|
||||
manufacturer: value.manufacturer,
|
||||
manufacturerYear: value.manufacturerYear,
|
||||
engine: value.engine,
|
||||
batteryType: value.batteryType,
|
||||
leaseId: value.leaseId.trimStart().trimEnd(),
|
||||
};
|
||||
console.log(data);
|
||||
try {
|
||||
await axios.post("/lst/api/forklifts", data);
|
||||
form.reset();
|
||||
setOpenDialog(false);
|
||||
refetch();
|
||||
toast.success(`${value.serialNumber} was just created `);
|
||||
} catch (error) {
|
||||
// @ts-ignore
|
||||
if (!error.response.data.success) {
|
||||
// @ts-ignore
|
||||
toast.error(error?.response?.data.message);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
toast.error(error?.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//const currentYear = new Date().getFullYear();
|
||||
|
||||
if (es) return <div>...Loading Servers</div>;
|
||||
if (leaseError) return <div>...Loading Leases</div>;
|
||||
|
||||
const serverMap = s.map((i: any) => {
|
||||
return { value: i.name, label: i.name };
|
||||
});
|
||||
|
||||
const leaseMap = leases.map((i: any) => {
|
||||
return { value: i.id, label: i.leaseNumber };
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Create New Forklift</DialogTitle>
|
||||
<DialogDescription>Create a new forklift</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-row gap-2 mt-2 mb-2">
|
||||
<form.AppField
|
||||
name="serialNumber"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Forklift SN"
|
||||
inputType="string"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<form.AppField
|
||||
name="model"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Model"
|
||||
inputType="string"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 mt-2 mb-2">
|
||||
<form.AppField
|
||||
name="manufacturer"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Forklift Manufacturer"
|
||||
placeholder="Manufacturer"
|
||||
options={forkliftManufacturer}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<form.AppField
|
||||
name="manufacturerYear"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Year Made"
|
||||
inputType="string"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 mt-2 mb-2">
|
||||
<form.AppField
|
||||
name="engine"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Engine Type"
|
||||
placeholder="Engine Type"
|
||||
options={engineType}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<form.AppField
|
||||
name="batteryType"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select battery type"
|
||||
placeholder="Battery type"
|
||||
options={batteryType}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<form.AppField
|
||||
name="profitCenter"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select profit center"
|
||||
placeholder="Profit Center"
|
||||
options={pfc}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row gap-2 mt-2 mb-2">
|
||||
<form.AppField
|
||||
name="plant"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Plant"
|
||||
placeholder="Plant"
|
||||
options={serverMap}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<form.AppField
|
||||
name="leaseId"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Lease"
|
||||
placeholder="Plant"
|
||||
options={leaseMap}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button type="submit">Submit</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
213
frontend/src/routes/_app/_forklifts/forklifts/forklifts.tsx
Normal file
213
frontend/src/routes/_app/_forklifts/forklifts/forklifts.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { createColumnHelper } from "@tanstack/react-table";
|
||||
import { ArrowDown, ArrowUp } from "lucide-react";
|
||||
//import { useRef } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getForklifts } from "@/lib/querys/forklifts/getForklifts";
|
||||
import TableNoExpand from "@/lib/tableStuff/TableNoExpand";
|
||||
|
||||
type Forklifts = {
|
||||
forklift_id: string;
|
||||
forkliftNumber: number;
|
||||
serialNumber: string;
|
||||
model: string;
|
||||
plant: string;
|
||||
forkliftStatus: boolean;
|
||||
glCode: number;
|
||||
profitCenter: number;
|
||||
manufacturer: string;
|
||||
manufacturerYear: string;
|
||||
engine: string;
|
||||
batteryType: string;
|
||||
};
|
||||
|
||||
export const Route = createFileRoute("/_app/_forklifts/forklifts/forklifts")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const { data: leaseData = [], isLoading } = useQuery(getForklifts());
|
||||
|
||||
const columnHelper = createColumnHelper<Forklifts>();
|
||||
//const submitting = useRef(false);
|
||||
|
||||
const columns = [
|
||||
columnHelper.accessor("plant", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Plant</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("profitCenter", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">PFC</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("forkliftNumber", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Forklift Number</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("serialNumber", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">SN Number</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("model", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Model</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("manufacturer", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Manufacturer</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("manufacturerYear", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Year</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("engine", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Engine</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor("batteryType", {
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
<span className="flex flex-row gap-2">Battery Type</span>
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ getValue }) => {
|
||||
return <span>{getValue()}</span>;
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
if (isLoading) {
|
||||
return <div className="m-auto">Loading user data</div>;
|
||||
}
|
||||
return <TableNoExpand data={leaseData} columns={columns} />;
|
||||
}
|
||||
Reference in New Issue
Block a user