diff --git a/LogisticsSupportTool_API_DOCS/Controller/folder.bru b/LogisticsSupportTool_API_DOCS/Controller/folder.bru index fbfd47c..13f9c3b 100644 --- a/LogisticsSupportTool_API_DOCS/Controller/folder.bru +++ b/LogisticsSupportTool_API_DOCS/Controller/folder.bru @@ -1,6 +1,6 @@ meta { name: Controller - seq: 1 + seq: 2 } auth { diff --git a/LogisticsSupportTool_API_DOCS/LstV2/folder.bru b/LogisticsSupportTool_API_DOCS/LstV2/folder.bru index f5ce718..2008f5b 100644 --- a/LogisticsSupportTool_API_DOCS/LstV2/folder.bru +++ b/LogisticsSupportTool_API_DOCS/LstV2/folder.bru @@ -1,6 +1,6 @@ meta { name: LstV2 - seq: 3 + seq: 4 } auth { diff --git a/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru b/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru index d6b8f4b..9ce04bd 100644 --- a/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru +++ b/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru @@ -16,13 +16,13 @@ headers { body:json { { - "name": "Dayton", - "serverDNS": "USDAY1VS006", - "plantToken": "usday1", - "ipAddress": "10.44.0.26", - "greatPlainsPlantCode": 55, + "name": "St Peters", + "serverDNS": "USSTP1VMS006", + "plantToken": "usstp1", + "ipAddress": "10.37.0.26", + "greatPlainsPlantCode": 45, "lstServerPort": 4000, - "serverLoc": "E$\\LST" + "serverLoc": "E:\\LST" } } diff --git a/LogisticsSupportTool_API_DOCS/app/folder.bru b/LogisticsSupportTool_API_DOCS/app/folder.bru index 0b09462..3736d8d 100644 --- a/LogisticsSupportTool_API_DOCS/app/folder.bru +++ b/LogisticsSupportTool_API_DOCS/app/folder.bru @@ -1,6 +1,6 @@ meta { name: app - seq: 2 + seq: 3 } auth { diff --git a/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Get Companies.bru b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Get Companies.bru new file mode 100644 index 0000000..cdbba05 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Get Companies.bru @@ -0,0 +1,22 @@ +meta { + name: Get Companies + type: http + seq: 2 +} + +get { + url: {{url}}/lst/api/forklifts/companies + body: none + auth: inherit +} + +body:json { + { + "name":"Delage DLL" + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Update Company.bru b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Update Company.bru new file mode 100644 index 0000000..3f7da67 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/Update Company.bru @@ -0,0 +1,27 @@ +meta { + name: Update Company + type: http + seq: 3 +} + +patch { + url: {{url}}/lst/api/forklifts/companies/:id + body: json + auth: inherit +} + +params:path { + id: fbfba3df-8c0f-4994-adae-c03808cbccdc +} + +body:json { + { + "name":"Delage DLL", + "active": true + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/LogisticsSupportTool_API_DOCS/app/forklifts/companies/add company.bru b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/add company.bru new file mode 100644 index 0000000..dc83a21 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/add company.bru @@ -0,0 +1,22 @@ +meta { + name: add company + type: http + seq: 1 +} + +post { + url: {{url}}/lst/api/forklifts/companies + body: json + auth: inherit +} + +body:json { + { + "name":"Delage DLL" + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/LogisticsSupportTool_API_DOCS/app/forklifts/companies/folder.bru b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/folder.bru new file mode 100644 index 0000000..2a303bb --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/forklifts/companies/folder.bru @@ -0,0 +1,8 @@ +meta { + name: companies + seq: 1 +} + +auth { + mode: inherit +} diff --git a/LogisticsSupportTool_API_DOCS/app/forklifts/folder.bru b/LogisticsSupportTool_API_DOCS/app/forklifts/folder.bru new file mode 100644 index 0000000..cd4725f --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/forklifts/folder.bru @@ -0,0 +1,8 @@ +meta { + name: forklifts + seq: 4 +} + +auth { + mode: inherit +} diff --git a/app/src/internal/forklifts/routes/companies/addCompany.ts b/app/src/internal/forklifts/routes/companies/addCompany.ts new file mode 100644 index 0000000..f5903b3 --- /dev/null +++ b/app/src/internal/forklifts/routes/companies/addCompany.ts @@ -0,0 +1,105 @@ +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 { + forkliftCompanies, + insertForkliftCompanySchema, +} from "../../../../pkg/db/schema/forkliftLeaseCompanys.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 company" }); + const parsed = insertForkliftCompanySchema.safeParse(req.body); + + if (!parsed.success) { + return res.status(400).json({ errors: parsed.error.flatten() }); + } + + const { data, error } = await tryCatch( + db + .insert(forkliftCompanies) + .values({ + ...parsed.data, + add_user: req.user?.username, + add_date: sql`NOW()`, + upd_user: req.user?.username, + upd_date: sql`NOW()`, + }) + //.onConflictDoNothing() + .returning({ + name: forkliftCompanies.name, + }), + ); + + if (error) { + const err: DrizzleError = error; + return res.status(400).json({ + message: `Error adding the server`, + 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/companies`, + 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: `Server ${data[0]?.name} added`, data: data }); +}); + +export default router; diff --git a/app/src/internal/forklifts/routes/companies/companiesRoutes.ts b/app/src/internal/forklifts/routes/companies/companiesRoutes.ts new file mode 100644 index 0000000..e562056 --- /dev/null +++ b/app/src/internal/forklifts/routes/companies/companiesRoutes.ts @@ -0,0 +1,22 @@ +import { Router } from "express"; +import { requireAuth } from "../../../../pkg/middleware/authMiddleware.js"; +import { restrictToHosts } from "../../../../pkg/middleware/restrictToHosts.js"; +import addCompany from "./addCompany.js"; +import getCompanies from "./getCompanies.js"; +import updateCompany from "./updateServer.js"; + +const router = Router(); + +router.use( + "/", + requireAuth("forklifts", ["systemAdmin", "admin"]), + getCompanies, +); +router.use("/", requireAuth("forklifts", ["systemAdmin", "admin"]), addCompany); +router.use( + "/", + requireAuth("forklifts", ["systemAdmin", "admin"]), + updateCompany, +); + +export default router; diff --git a/app/src/internal/forklifts/routes/companies/getCompanies.ts b/app/src/internal/forklifts/routes/companies/getCompanies.ts new file mode 100644 index 0000000..74aae77 --- /dev/null +++ b/app/src/internal/forklifts/routes/companies/getCompanies.ts @@ -0,0 +1,35 @@ +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 { tryCatch } from "../../../../pkg/utils/tryCatch.js"; + +const router = Router(); + +router.get("/", async (req: Request, res: Response) => { + const name = req.query.name; + + const conditions = []; + + if (name !== undefined) { + conditions.push(eq(forkliftCompanies.name, `${name}`)); + } + + //conditions.push(eq(forkliftCompanies.active, true)); + + const { data, error } = await tryCatch( + db + .select() + .from(forkliftCompanies) + .where(and(...conditions)) + .orderBy(asc(forkliftCompanies.name)), + ); + + if (error) { + return res.status(400).json({ error: error }); + } + res.status(200).json({ message: "Current Active Companies", data: data }); +}); + +export default router; diff --git a/app/src/internal/forklifts/routes/companies/updateServer.ts b/app/src/internal/forklifts/routes/companies/updateServer.ts new file mode 100644 index 0000000..4dc5c94 --- /dev/null +++ b/app/src/internal/forklifts/routes/companies/updateServer.ts @@ -0,0 +1,103 @@ +import axios from "axios"; +import { eq, 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 { forkliftCompanies } from "../../../../pkg/db/schema/forkliftLeaseCompanys.js"; +import { serverData } from "../../../../pkg/db/schema/servers.js"; +import { createLogger } from "../../../../pkg/logger/logger.js"; +import { tryCatch } from "../../../../pkg/utils/tryCatch.js"; + +const router = Router(); + +router.patch("/:id", async (req: Request, res: Response) => { + const log = createLogger({ + module: "forklifts", + subModule: "update company", + }); + + // when a server is updated and 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, we want to insert with update on conflict. + const id = req.params.id; + const updates: Record = {}; + console.log(req.body); + if (req.body?.name !== undefined) { + updates.name = req.body.name; + } + + if (req.body?.active !== undefined) { + updates.active = req.body.active; + } + + updates.upd_user = req.user!.username || "lst_user"; + updates.upd_date = sql`NOW()`; + + try { + if (Object.keys(updates).length > 0) { + await db + .update(forkliftCompanies) + .set(updates) + .where(eq(forkliftCompanies.id, id)); + } + + 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, + 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]; + + //console.log(setCookie.split(";")[0].replace("__Secure-", "")); + + if (!setCookie) { + throw new Error("Did not receive a Set-Cookie header from login"); + } + + const { data, error } = await tryCatch( + axios.patch( + `${process.env.MAIN_SERVER}/lst/api/forklifts/companies/${id}`, + updates, + { + headers: { + "Content-Type": "application/json", + Cookie: setCookie.split(";")[0], + }, + withCredentials: true, + }, + ), + ); + + if (error) { + //console.log(error); + log.error( + { stack: error }, + "There was an error updating the company to Main Server", + ); + } + log.info( + { stack: data?.data }, + "A new company was just updated to the server.", + ); + } + res.status(200).json({ message: `${id} was just updated` }); + } catch (error) { + //console.log(error); + res.status(200).json({ message: "Error Server updated", error }); + } +}); + +export default router; diff --git a/app/src/internal/forklifts/routes/routes.ts b/app/src/internal/forklifts/routes/routes.ts new file mode 100644 index 0000000..b0cbb75 --- /dev/null +++ b/app/src/internal/forklifts/routes/routes.ts @@ -0,0 +1,9 @@ +import type { Express, Request, Response } from "express"; +import { requireAuth } from "../../../pkg/middleware/authMiddleware.js"; +import companies from "./companies/companiesRoutes.js"; +export const setupForkliftRoutes = (app: Express, basePath: string) => { + app.use( + basePath + "/api/forklifts/companies", // will pass bc system admin but this is just telling us we need this + companies, + ); +}; diff --git a/app/src/internal/routerHandler/routeHandler.ts b/app/src/internal/routerHandler/routeHandler.ts index 0ad949c..646a35e 100644 --- a/app/src/internal/routerHandler/routeHandler.ts +++ b/app/src/internal/routerHandler/routeHandler.ts @@ -1,23 +1,25 @@ import type { Express, Request, Response } from "express"; -import { setupAuthRoutes } from "../auth/routes/routes.js"; import { setupAdminRoutes } from "../admin/routes.js"; -import { setupSystemRoutes } from "../system/routes.js"; +import { setupAuthRoutes } from "../auth/routes/routes.js"; +import { setupForkliftRoutes } from "../forklifts/routes/routes.js"; import { setupLogisticsRoutes } from "../logistics/routes.js"; +import { setupSystemRoutes } from "../system/routes.js"; export const setupRoutes = (app: Express, basePath: string) => { - // all routes - setupAuthRoutes(app, basePath); - setupAdminRoutes(app, basePath); - setupSystemRoutes(app, basePath); - setupLogisticsRoutes(app, basePath); + // all routes + setupAuthRoutes(app, basePath); + setupAdminRoutes(app, basePath); + setupSystemRoutes(app, basePath); + setupLogisticsRoutes(app, basePath); + setupForkliftRoutes(app, basePath); - // always try to go to the app weather we are in dev or in production. - app.get(basePath + "/", (req: Request, res: Response) => { - res.redirect(basePath + "/app"); - }); + // always try to go to the app weather we are in dev or in production. + app.get(basePath + "/", (req: Request, res: Response) => { + res.redirect(basePath + "/app"); + }); - // Fallback 404 handler - app.use((req: Request, res: Response) => { - res.status(404).json({ error: "Not Found" }); - }); + // Fallback 404 handler + app.use((req: Request, res: Response) => { + res.status(404).json({ error: "Not Found" }); + }); }; diff --git a/app/src/pkg/db/schema/forkliftComments.ts b/app/src/pkg/db/schema/forkliftComments.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/src/pkg/db/schema/forkliftHours.ts b/app/src/pkg/db/schema/forkliftHours.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/src/pkg/db/schema/forkliftLeaseCompanys.ts b/app/src/pkg/db/schema/forkliftLeaseCompanys.ts new file mode 100644 index 0000000..e1d61ba --- /dev/null +++ b/app/src/pkg/db/schema/forkliftLeaseCompanys.ts @@ -0,0 +1,26 @@ +import { boolean, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core"; +import { createInsertSchema, createSelectSchema } from "drizzle-zod"; +import z from "zod"; + +export const forkliftCompanies = pgTable("forklift_companies", { + id: uuid("id").defaultRandom().primaryKey(), + name: text("name").notNull().unique(), + active: boolean("active").default(true), + add_date: timestamp("add_date").defaultNow(), + add_user: text("add_user").default("LST"), + upd_date: timestamp("upd_date").defaultNow(), + upd_user: text("upd_user").default("LST"), +}); + +export const selectForkliftCompanySchema = + createSelectSchema(forkliftCompanies); + +export const insertForkliftCompanySchema = createInsertSchema( + forkliftCompanies, +).extend({ + name: z.string().min(3), + // zipcode: z + // .string() + // .regex(/^\d{5}$/) + // .optional(), +}); diff --git a/app/src/pkg/db/schema/forkliftLeases.ts b/app/src/pkg/db/schema/forkliftLeases.ts new file mode 100644 index 0000000..c616c89 --- /dev/null +++ b/app/src/pkg/db/schema/forkliftLeases.ts @@ -0,0 +1,13 @@ +import { date, pgTable, text, uuid } from "drizzle-orm/pg-core"; +import { createSelectSchema } from "drizzle-zod"; +import { forkliftCompanies } from "./forkliftLeaseCompanys.js"; + +export const leases = pgTable("leases", { + id: uuid("id").defaultRandom().primaryKey(), + leaseNumber: text("lease_number").notNull(), + companyId: uuid("company_id").references(() => forkliftCompanies.id), + startDate: date("start_date"), + endDate: date("end_date"), + leaseLink: text("lease_link"), +}); +export const selectLeasesDataSchema = createSelectSchema(leases); diff --git a/app/src/pkg/db/schema/forkliftLeasesInvoice.ts b/app/src/pkg/db/schema/forkliftLeasesInvoice.ts new file mode 100644 index 0000000..1a920ae --- /dev/null +++ b/app/src/pkg/db/schema/forkliftLeasesInvoice.ts @@ -0,0 +1,14 @@ +import { numeric, pgTable, serial, uuid } from "drizzle-orm/pg-core"; +import { forklifts } from "./forklifts.js"; +import { leaseInvoices } from "./leaseInvoices.js"; + +export const leaseInvoiceForklifts = pgTable("lease_invoice_forklifts", { + id: serial("id").primaryKey(), + invoiceId: uuid("invoice_id") + .notNull() + .references(() => leaseInvoices.id, { onDelete: "cascade" }), + forkliftId: uuid("forklift_id") + .notNull() + .references(() => forklifts.forklift_id, { onDelete: "cascade" }), + amount: numeric("amount"), // optional: amount of invoice allocated to this lift +}); diff --git a/app/src/pkg/db/schema/forkliftRepairs.ts b/app/src/pkg/db/schema/forkliftRepairs.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/src/pkg/db/schema/forklifts.ts b/app/src/pkg/db/schema/forklifts.ts new file mode 100644 index 0000000..aebe4a2 --- /dev/null +++ b/app/src/pkg/db/schema/forklifts.ts @@ -0,0 +1,52 @@ +import { + integer, + pgEnum, + pgTable, + serial, + text, + timestamp, + uuid, +} from "drizzle-orm/pg-core"; +import { createInsertSchema, createSelectSchema } from "drizzle-zod"; +import { z } from "zod"; +import { leases } from "./forkliftLeases.js"; +import { serverData } from "./servers.js"; + +const status = pgEnum("forklift_status", [ + "active", + "inactive", + "sold", + "retired", + "transferred", +]); + +export const forklifts = pgTable("forklifts", { + forklift_id: uuid("forklift_id").defaultRandom().primaryKey(), + forkliftNumber: serial("forklift_number").notNull(), + serialNumber: text("serial_number").notNull(), + model: text("model").notNull(), + plant: text("plant") + .notNull() + .references(() => serverData.name, { onDelete: "set null" }), // what plant the forklift is in. + forkliftStatus: text("forklift_status").default("active"), //["active","inactive","sold","retired","transferred",] + glCode: integer("gl_code").notNull(), // this will be updated on the onconflift update so we dont do anything funny. + profitCenter: integer("profit_center").notNull(), // should be updated if its changing profit centers per request by the plant + manufacturer: text("manufacturer").notNull(), + manufacturerYear: text("manufacturer_year").notNull(), + engine: text("engine").notNull(), + batteryType: text("battery_type").notNull(), + leaseId: uuid("lease_id").references(() => leases.id, { + onDelete: "set null", + }), + dataPlate: text("data_plate"), + add_date: timestamp("add_date").defaultNow(), + add_user: text("add_user").default("LST"), + upd_date: timestamp("add_date").defaultNow(), + upd_user: text("add_user").default("LST"), +}); + +export const forkliftsSchema = createSelectSchema(forklifts); +export const newForkliftsSchema = createInsertSchema(forklifts); + +export type Forklift = z.infer; +export type NewNewForklift = z.infer; diff --git a/app/src/pkg/db/schema/leaseInvoices.ts b/app/src/pkg/db/schema/leaseInvoices.ts new file mode 100644 index 0000000..164c0cd --- /dev/null +++ b/app/src/pkg/db/schema/leaseInvoices.ts @@ -0,0 +1,19 @@ +import { date, numeric, pgTable, text, uuid } from "drizzle-orm/pg-core"; +import { forkliftCompanies } from "./forkliftLeaseCompanys.js"; +import { leases } from "./forkliftLeases.js"; +import { forklifts } from "./forklifts.js"; + +export const leaseInvoices = pgTable("lease_invoices", { + id: uuid("id").defaultRandom().primaryKey(), + leaseId: uuid("lease_id") + .notNull() + .references(() => leases.id, { onDelete: "cascade" }), + companyId: uuid("company_id").references(() => forkliftCompanies.id), + invoiceNumber: text("invoice_number").notNull(), + invoiceDate: date("invoice_date").notNull(), + forkliftId: uuid("forklift_id") + .notNull() + .references(() => forklifts.forklift_id, { onDelete: "cascade" }), + totalAmount: numeric("total_amount"), + uploadedBy: text("uploaded_by"), +}); diff --git a/frontend/src/components/navBar/ForkliftSideBar.tsx b/frontend/src/components/navBar/ForkliftSideBar.tsx new file mode 100644 index 0000000..c494a95 --- /dev/null +++ b/frontend/src/components/navBar/ForkliftSideBar.tsx @@ -0,0 +1,94 @@ +import { Link } from "@tanstack/react-router"; +import { + Building2, + Forklift, + Hourglass, + ReceiptText, + Wrench, +} from "lucide-react"; +import { userAccess } from "@/lib/authClient"; +import { + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "../ui/sidebar"; +import type { Items } from "./SideBarNav"; + +export default function ForkliftSideBar() { + const items: Items[] = [ + { + title: "Lease Companies", + url: "/lst/app/forklifts/companies", + icon: Building2, + role: ["systemAdmin", "admin"], + module: "forklifts", + active: true, + }, + { + title: "Leases", + url: "/lst/app/admin/settings", + icon: ReceiptText, + role: ["systemAdmin", "admin"], + module: "forklifts", + active: true, + }, + { + title: "Invoices", + url: "/lst/app/admin/settings", + icon: ReceiptText, + role: ["systemAdmin", "admin", "manager"], + module: "forklifts", + active: true, + }, + { + title: "Repairs", + url: "/lst/app/admin/settings", + icon: Wrench, + role: ["systemAdmin", "admin", "manager"], + module: "forklifts", + active: true, + }, + { + title: "Hours", + url: "/lst/app/admin/settings", + icon: Hourglass, + role: ["systemAdmin", "admin", "manager", "supervisor"], + module: "forklifts", + active: true, + }, + { + title: "Forklifts", + url: "/lst/app/admin/modules", + icon: Forklift, + role: ["systemAdmin", "admin", "manager", "supervisor"], + module: "forklifts", + active: true, + }, + ]; + return ( + + Forklifts + + + {items.map((item) => ( + + <> + {userAccess(item.module, item.role) && item.active && ( + + + + {item.title} + + + )} + + + ))} + + + + ); +} diff --git a/frontend/src/components/navBar/Nav.tsx b/frontend/src/components/navBar/Nav.tsx index 1c1ef5e..60f5648 100644 --- a/frontend/src/components/navBar/Nav.tsx +++ b/frontend/src/components/navBar/Nav.tsx @@ -1,8 +1,11 @@ import { Link, useRouterState } from "@tanstack/react-router"; +import { useState } from "react"; +import NewCompanyForm from "@/routes/_app/_forklifts/-components/NewCompany"; import { useAuth, useLogout } from "../../lib/authClient"; import { ModeToggle } from "../mode-toggle"; import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"; import { Button } from "../ui/button"; +import { Dialog, DialogContent } from "../ui/dialog"; import { DropdownMenu, DropdownMenuContent, @@ -17,6 +20,7 @@ export default function Nav() { const logout = useLogout(); const router = useRouterState(); const currentPath = router.location.href; + const [openDialog, setOpenDialog] = useState(false); return (