diff --git a/app/src/internal/forklifts/routes/hours/addHours.ts b/app/src/internal/forklifts/routes/hours/addHours.ts new file mode 100644 index 0000000..cc0fdf0 --- /dev/null +++ b/app/src/internal/forklifts/routes/hours/addHours.ts @@ -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; diff --git a/app/src/internal/forklifts/routes/hours/getHours.ts b/app/src/internal/forklifts/routes/hours/getHours.ts new file mode 100644 index 0000000..2c5d8e1 --- /dev/null +++ b/app/src/internal/forklifts/routes/hours/getHours.ts @@ -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; diff --git a/app/src/internal/forklifts/routes/hours/leaseRoutes.ts b/app/src/internal/forklifts/routes/hours/leaseRoutes.ts new file mode 100644 index 0000000..83ed1fb --- /dev/null +++ b/app/src/internal/forklifts/routes/hours/leaseRoutes.ts @@ -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; diff --git a/frontend/src/components/navBar/ForkliftSideBar.tsx b/frontend/src/components/navBar/ForkliftSideBar.tsx index af5fe19..d4940db 100644 --- a/frontend/src/components/navBar/ForkliftSideBar.tsx +++ b/frontend/src/components/navBar/ForkliftSideBar.tsx @@ -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", diff --git a/frontend/src/components/navBar/Nav.tsx b/frontend/src/components/navBar/Nav.tsx index 6b485c1..63030f8 100644 --- a/frontend/src/components/navBar/Nav.tsx +++ b/frontend/src/components/navBar/Nav.tsx @@ -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 (