feat(forklifts): added backend forklift stuff and frontend companies

This commit is contained in:
2025-11-02 16:16:35 -06:00
parent a6cc17ccb1
commit 50cde2d8d2
52 changed files with 20619 additions and 32 deletions

View File

@@ -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 (
<SidebarGroup>
<SidebarGroupLabel>Forklifts</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<>
{userAccess(item.module, item.role) && item.active && (
<SidebarMenuButton asChild>
<Link to={item.url}>
<item.icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
)}
</>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
);
}

View File

@@ -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 (
<nav className="flex justify-end w-full shadow ">
<div className="m-2 flex flex-row gap-1">
@@ -33,6 +37,37 @@ export default function Nav() {
<Button className="m-1">
<Link to="/old">Old Version</Link>
</Button>
<div className="m-1">
{location.pathname.includes("forklifts") && (
<>
<DropdownMenu>
<DropdownMenuTrigger>
<Button>Forklifts</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Forklift links</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
onSelect={() => {
// just open the dialog when clicked
setOpenDialog(true);
}}
>
New Company
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Dialog mounted outside the menu */}
{openDialog && (
<Dialog open={openDialog} onOpenChange={setOpenDialog}>
<DialogContent className="sm:max-w-[425px]">
<NewCompanyForm setOpenDialog={setOpenDialog} />
</DialogContent>
</Dialog>
)}
</>
)}
</div>
{session ? (
<div className="m-1">
<DropdownMenu>

View File

@@ -1,5 +1,6 @@
import { Link } from "@tanstack/react-router";
import { userAccess } from "../../lib/authClient";
import type { LucideIcon } from "lucide-react";
import { type UserRoles, userAccess } from "@/lib/authClient";
import {
Sidebar,
SidebarContent,
@@ -8,17 +9,32 @@ import {
SidebarTrigger,
} from "../ui/sidebar";
import Admin from "./Admin";
import ForkliftSideBar from "./ForkliftSideBar";
import { Header } from "./Header";
export type Items = {
title: string;
url: string;
icon: LucideIcon;
role: UserRoles["role"][];
module: string;
active: boolean;
};
export default function SideBarNav() {
return (
<div className="flex min-h-screen">
<Sidebar collapsible="icon">
<Header />
<SidebarContent>
{userAccess(null, [
"systemAdmin",
"admin",
"manager",
"supervisor",
]) && <ForkliftSideBar />}
{userAccess(null, ["systemAdmin", "admin"]) && <Admin />}
</SidebarContent>
<SidebarFooter>
<SidebarMenuItem>
<Link to={"/changelog"}>Changelog</Link>

View File

@@ -16,16 +16,19 @@ import { Route as AppIndexRouteImport } from './routes/_app/index'
import { Route as AppChangelogRouteImport } from './routes/_app/changelog'
import { Route as OldOldRouteRouteImport } from './routes/_old/old/route'
import { Route as MobileMobileLayoutRouteRouteImport } from './routes/_mobile/_mobileLayout/route'
import { Route as AppForkliftsRouteRouteImport } from './routes/_app/_forklifts/route'
import { Route as AppAdminLayoutRouteRouteImport } from './routes/_app/_adminLayout/route'
import { Route as OldOldIndexRouteImport } from './routes/_old/old/index'
import { Route as AppauthLoginRouteImport } from './routes/_app/(auth)/login'
import { Route as OldOldRfidIndexRouteImport } from './routes/_old/old/rfid/index'
import { Route as OldOldOcpIndexRouteImport } from './routes/_old/old/ocp/index'
import { Route as MobileMobileLayoutMIndexRouteImport } from './routes/_mobile/_mobileLayout/m/index'
import { Route as AppForkliftsForkliftsIndexRouteImport } from './routes/_app/_forklifts/forklifts/index'
import { Route as AppauthUserIndexRouteImport } from './routes/_app/(auth)/user/index'
import { Route as MobileMobileLayoutMRelocateRouteImport } from './routes/_mobile/_mobileLayout/m/relocate'
import { Route as MobileMobileLayoutMDeliveryRouteImport } from './routes/_mobile/_mobileLayout/m/delivery'
import { Route as MobileMobileLayoutMCyclecountsRouteImport } from './routes/_mobile/_mobileLayout/m/cyclecounts'
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'
import { Route as AppauthUserSignupRouteImport } from './routes/_app/(auth)/user/signup'
@@ -74,6 +77,10 @@ const MobileMobileLayoutRouteRoute = MobileMobileLayoutRouteRouteImport.update({
id: '/_mobile/_mobileLayout',
getParentRoute: () => rootRouteImport,
} as any)
const AppForkliftsRouteRoute = AppForkliftsRouteRouteImport.update({
id: '/_forklifts',
getParentRoute: () => AppRouteRoute,
} as any)
const AppAdminLayoutRouteRoute = AppAdminLayoutRouteRouteImport.update({
id: '/_adminLayout',
getParentRoute: () => AppRouteRoute,
@@ -109,6 +116,12 @@ const MobileMobileLayoutMIndexRoute =
path: '/m/',
getParentRoute: () => MobileMobileLayoutRouteRoute,
} as any)
const AppForkliftsForkliftsIndexRoute =
AppForkliftsForkliftsIndexRouteImport.update({
id: '/forklifts/',
path: '/forklifts/',
getParentRoute: () => AppForkliftsRouteRoute,
} as any)
const AppauthUserIndexRoute = AppauthUserIndexRouteImport.update({
id: '/(auth)/user/',
path: '/user/',
@@ -132,6 +145,12 @@ const MobileMobileLayoutMCyclecountsRoute =
path: '/m/cyclecounts',
getParentRoute: () => MobileMobileLayoutRouteRoute,
} as any)
const AppForkliftsForkliftsCompaniesRoute =
AppForkliftsForkliftsCompaniesRouteImport.update({
id: '/forklifts/companies',
path: '/forklifts/companies',
getParentRoute: () => AppForkliftsRouteRoute,
} as any)
const AppAdminLayoutAdminServersRoute =
AppAdminLayoutAdminServersRouteImport.update({
id: '/servers',
@@ -260,10 +279,12 @@ export interface FileRoutesByFullPath {
'/user/signup': typeof AppauthUserSignupRoute
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
'/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
'/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
'/m/relocate': typeof MobileMobileLayoutMRelocateRoute
'/user': typeof AppauthUserIndexRoute
'/forklifts': typeof AppForkliftsForkliftsIndexRoute
'/m': typeof MobileMobileLayoutMIndexRoute
'/old/ocp': typeof OldOldOcpIndexRoute
'/old/rfid': typeof OldOldRfidIndexRoute
@@ -292,10 +313,12 @@ export interface FileRoutesByTo {
'/user/signup': typeof AppauthUserSignupRoute
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
'/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
'/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
'/m/relocate': typeof MobileMobileLayoutMRelocateRoute
'/user': typeof AppauthUserIndexRoute
'/forklifts': typeof AppForkliftsForkliftsIndexRoute
'/m': typeof MobileMobileLayoutMIndexRoute
'/old/ocp': typeof OldOldOcpIndexRoute
'/old/rfid': typeof OldOldRfidIndexRoute
@@ -317,6 +340,7 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/_app': typeof AppRouteRouteWithChildren
'/_app/_adminLayout': typeof AppAdminLayoutRouteRouteWithChildren
'/_app/_forklifts': typeof AppForkliftsRouteRouteWithChildren
'/_mobile/_mobileLayout': typeof MobileMobileLayoutRouteRouteWithChildren
'/_old/old': typeof OldOldRouteRouteWithChildren
'/_app/changelog': typeof AppChangelogRoute
@@ -331,10 +355,12 @@ export interface FileRoutesById {
'/_app/(auth)/user/signup': typeof AppauthUserSignupRoute
'/_app/(logistics)/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
'/_app/_adminLayout/admin/servers': typeof AppAdminLayoutAdminServersRoute
'/_app/_forklifts/forklifts/companies': typeof AppForkliftsForkliftsCompaniesRoute
'/_mobile/_mobileLayout/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
'/_mobile/_mobileLayout/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
'/_mobile/_mobileLayout/m/relocate': typeof MobileMobileLayoutMRelocateRoute
'/_app/(auth)/user/': typeof AppauthUserIndexRoute
'/_app/_forklifts/forklifts/': typeof AppForkliftsForkliftsIndexRoute
'/_mobile/_mobileLayout/m/': typeof MobileMobileLayoutMIndexRoute
'/_old/old/ocp/': typeof OldOldOcpIndexRoute
'/_old/old/rfid/': typeof OldOldRfidIndexRoute
@@ -366,10 +392,12 @@ export interface FileRouteTypes {
| '/user/signup'
| '/logistics/deliverySchedule'
| '/admin/servers'
| '/forklifts/companies'
| '/m/cyclecounts'
| '/m/delivery'
| '/m/relocate'
| '/user'
| '/forklifts'
| '/m'
| '/old/ocp'
| '/old/rfid'
@@ -398,10 +426,12 @@ export interface FileRouteTypes {
| '/user/signup'
| '/logistics/deliverySchedule'
| '/admin/servers'
| '/forklifts/companies'
| '/m/cyclecounts'
| '/m/delivery'
| '/m/relocate'
| '/user'
| '/forklifts'
| '/m'
| '/old/ocp'
| '/old/rfid'
@@ -422,6 +452,7 @@ export interface FileRouteTypes {
| '__root__'
| '/_app'
| '/_app/_adminLayout'
| '/_app/_forklifts'
| '/_mobile/_mobileLayout'
| '/_old/old'
| '/_app/changelog'
@@ -436,10 +467,12 @@ export interface FileRouteTypes {
| '/_app/(auth)/user/signup'
| '/_app/(logistics)/logistics/deliverySchedule'
| '/_app/_adminLayout/admin/servers'
| '/_app/_forklifts/forklifts/companies'
| '/_mobile/_mobileLayout/m/cyclecounts'
| '/_mobile/_mobileLayout/m/delivery'
| '/_mobile/_mobileLayout/m/relocate'
| '/_app/(auth)/user/'
| '/_app/_forklifts/forklifts/'
| '/_mobile/_mobileLayout/m/'
| '/_old/old/ocp/'
| '/_old/old/rfid/'
@@ -501,6 +534,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof MobileMobileLayoutRouteRouteImport
parentRoute: typeof rootRouteImport
}
'/_app/_forklifts': {
id: '/_app/_forklifts'
path: ''
fullPath: ''
preLoaderRoute: typeof AppForkliftsRouteRouteImport
parentRoute: typeof AppRouteRoute
}
'/_app/_adminLayout': {
id: '/_app/_adminLayout'
path: ''
@@ -550,6 +590,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof MobileMobileLayoutMIndexRouteImport
parentRoute: typeof MobileMobileLayoutRouteRoute
}
'/_app/_forklifts/forklifts/': {
id: '/_app/_forklifts/forklifts/'
path: '/forklifts'
fullPath: '/forklifts'
preLoaderRoute: typeof AppForkliftsForkliftsIndexRouteImport
parentRoute: typeof AppForkliftsRouteRoute
}
'/_app/(auth)/user/': {
id: '/_app/(auth)/user/'
path: '/user'
@@ -578,6 +625,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof MobileMobileLayoutMCyclecountsRouteImport
parentRoute: typeof MobileMobileLayoutRouteRoute
}
'/_app/_forklifts/forklifts/companies': {
id: '/_app/_forklifts/forklifts/companies'
path: '/forklifts/companies'
fullPath: '/forklifts/companies'
preLoaderRoute: typeof AppForkliftsForkliftsCompaniesRouteImport
parentRoute: typeof AppForkliftsRouteRoute
}
'/_app/_adminLayout/admin/servers': {
id: '/_app/_adminLayout/admin/servers'
path: '/servers'
@@ -784,8 +838,22 @@ const AppAdminLayoutRouteRouteChildren: AppAdminLayoutRouteRouteChildren = {
const AppAdminLayoutRouteRouteWithChildren =
AppAdminLayoutRouteRoute._addFileChildren(AppAdminLayoutRouteRouteChildren)
interface AppForkliftsRouteRouteChildren {
AppForkliftsForkliftsCompaniesRoute: typeof AppForkliftsForkliftsCompaniesRoute
AppForkliftsForkliftsIndexRoute: typeof AppForkliftsForkliftsIndexRoute
}
const AppForkliftsRouteRouteChildren: AppForkliftsRouteRouteChildren = {
AppForkliftsForkliftsCompaniesRoute: AppForkliftsForkliftsCompaniesRoute,
AppForkliftsForkliftsIndexRoute: AppForkliftsForkliftsIndexRoute,
}
const AppForkliftsRouteRouteWithChildren =
AppForkliftsRouteRoute._addFileChildren(AppForkliftsRouteRouteChildren)
interface AppRouteRouteChildren {
AppAdminLayoutRouteRoute: typeof AppAdminLayoutRouteRouteWithChildren
AppForkliftsRouteRoute: typeof AppForkliftsRouteRouteWithChildren
AppChangelogRoute: typeof AppChangelogRoute
AppIndexRoute: typeof AppIndexRoute
AppauthLoginRoute: typeof AppauthLoginRoute
@@ -798,6 +866,7 @@ interface AppRouteRouteChildren {
const AppRouteRouteChildren: AppRouteRouteChildren = {
AppAdminLayoutRouteRoute: AppAdminLayoutRouteRouteWithChildren,
AppForkliftsRouteRoute: AppForkliftsRouteRouteWithChildren,
AppChangelogRoute: AppChangelogRoute,
AppIndexRoute: AppIndexRoute,
AppauthLoginRoute: AppauthLoginRoute,

View File

@@ -159,16 +159,25 @@ function RouteComponent() {
updateServer.mutate({ token, field, value: newValue });
}
};
let submitting = false;
return (
<Input
value={localValue}
onChange={(e) => setLocalValue(e.currentTarget.value)}
onBlur={(e) => handleSubmit(e.currentTarget.value.trim())}
onBlur={(e) => {
if (!submitting) {
submitting = true;
handleSubmit(e.currentTarget.value.trim());
setTimeout(() => (submitting = false), 100); // reset after slight delay
}
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
handleSubmit(e.currentTarget.value.trim());
e.currentTarget.blur(); // exit edit mode
setTimeout(() => (submitting = false), 100);
}
}}
/>

View File

@@ -0,0 +1,80 @@
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 { getCompanies } from "@/lib/querys/forklifts/getModules";
import { useAppForm } from "../../../../lib/formStuff";
export default function NewCompanyForm({
setOpenDialog,
}: {
setOpenDialog: any;
}) {
//const search = useSearch({ from: "/_app/(auth)/login" });
const { refetch } = useQuery(getCompanies());
const form = useAppForm({
defaultValues: {
name: "",
},
onSubmit: async ({ value }) => {
try {
await axios.post("/lst/api/forklifts/companies", {
name: value.name,
});
form.reset();
setOpenDialog(false);
refetch();
toast.success(`${value.name} 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);
}
}
},
});
return (
<>
<DialogHeader>
<DialogTitle>Create New Company</DialogTitle>
<DialogDescription>Add the new Leasing company</DialogDescription>
</DialogHeader>
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<form.AppField
name="name"
children={(field) => (
<field.InputField
label="Company Name"
inputType="string"
required={true}
/>
)}
/>
</form>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button type="submit">Submit</Button>
</DialogFooter>
</>
);
}

View File

@@ -0,0 +1,282 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import {
createColumnHelper,
flexRender,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
type SortingState,
useReactTable,
} from "@tanstack/react-table";
import axios from "axios";
import { Activity, ArrowDown, ArrowUp } from "lucide-react";
import React, { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { getCompanies } from "@/lib/querys/forklifts/getModules";
import { cn } from "@/lib/utils";
type Company = {
id: string;
name: string;
active: boolean;
};
export const Route = createFileRoute("/_app/_forklifts/forklifts/companies")({
component: RouteComponent,
});
const updateCompanyItem = async (
id: string,
data: Record<string, string | number | boolean | null>,
) => {
try {
const res = await axios.patch(`/lst/api/forklifts/companies/${id}`, data, {
withCredentials: true,
});
toast.success(`Company just updated`);
return res;
} catch (err) {
toast.error("Error in updating company");
return err;
}
};
function RouteComponent() {
const {
data: companyData = [],
isLoading,
refetch,
} = useQuery(getCompanies());
const [sorting, setSorting] = useState<SortingState>([]);
const columnHelper = createColumnHelper<Company>();
const submitting = useRef(false);
const updateCompany = useMutation({
mutationFn: ({
id,
field,
value,
}: {
id: string;
field: string;
value: string | number | boolean | null;
}) => updateCompanyItem(id, { [field]: value }),
onSuccess: () => {
// refetch or update cache
refetch();
},
});
const columns = [
columnHelper.accessor("name", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">Name</span>
{column.getIsSorted() === "asc" ? (
<ArrowUp className="ml-2 h-4 w-4" />
) : (
<ArrowDown className="ml-2 h-4 w-4" />
)}
</Button>
);
},
cell: ({ row, getValue }) => {
const initialValue = String(getValue() ?? "");
const [localValue, setLocalValue] = useState(initialValue);
const id = row.original.id;
const field = "name";
useEffect(() => setLocalValue(initialValue), [initialValue]);
const handleSubmit = (newValue: string) => {
if (newValue !== initialValue) {
setLocalValue(newValue);
updateCompany.mutate({ id, field, value: newValue });
}
};
return (
<Input
value={localValue}
onChange={(e) => setLocalValue(e.currentTarget.value)}
onBlur={(e) => {
if (!submitting.current) {
submitting.current = true;
handleSubmit(e.currentTarget.value.trim());
setTimeout(() => (submitting.current = false), 100); // reset after slight delay
}
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
submitting.current = true;
handleSubmit(e.currentTarget.value.trim());
e.currentTarget.blur(); // will trigger blur, but we ignore it
setTimeout(() => (submitting.current = false), 100);
}
}}
/>
);
},
}),
columnHelper.accessor("active", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">
<Activity />
Active
</span>
{column.getIsSorted() === "asc" ? (
<ArrowUp className="ml-2 h-4 w-4" />
) : (
<ArrowDown className="ml-2 h-4 w-4" />
)}
</Button>
);
},
cell: ({ row, getValue }) => {
const active = getValue<boolean>();
const id = row.original.id;
const field = "active";
return (
<Select
value={active ? "true" : "false"}
onValueChange={(value) => {
const newValue = value === "true";
updateCompany.mutate({ id, field, value: newValue });
}}
>
<SelectTrigger
className={cn(
"w-[100px]",
active
? "border-green-500 text-green-600"
: "border-gray-400 text-gray-500",
)}
>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="true">True</SelectItem>
<SelectItem value="false">False</SelectItem>
</SelectContent>
</Select>
);
},
}),
];
const table = useReactTable({
data: companyData,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
//renderSubComponent: ({ row }: { row: any }) => <ExpandedRow row={row} />,
//getRowCanExpand: () => true,
state: {
sorting,
},
});
if (isLoading) {
return <div className="m-auto">Loading user data</div>;
}
return (
<div className="p-4">
<div className="w-fit">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows.map((row) => (
<React.Fragment key={row.id}>
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
))}
</TableRow>
{/* {row.getIsExpanded() && (
<TableRow>
<TableCell colSpan={row.getVisibleCells().length}>
{renderSubComponent({ row })}
</TableCell>
</TableRow>
)} */}
</React.Fragment>
))}
</TableBody>
</Table>
<div className="flex items-center justify-end space-x-2 py-4">
<Button
variant="outline"
size="sm"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
Previous
</Button>
<Button
variant="outline"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Next
</Button>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/_app/_forklifts/forklifts/')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/_app/_forklifts/"!</div>
}

View File

@@ -0,0 +1,19 @@
import { createFileRoute, Outlet } from "@tanstack/react-router";
import { checkUserAccess } from "@/lib/authClient";
export const Route = createFileRoute("/_app/_forklifts")({
beforeLoad: async () =>
checkUserAccess({
allowedRoles: ["admin", "systemAdmin", "manager", "supervisor"],
moduleName: "forklifts", // optional
}),
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<Outlet />
</div>
);
}

View File

@@ -14,12 +14,9 @@ import {
} from "../../../../../lib/authClient";
import { AdminSideBar } from "./side-components/admin";
import { EomSideBar } from "./side-components/eom";
import { ForkliftSideBar } from "./side-components/forklift";
import { Header } from "./side-components/header";
import { LogisticsSideBar } from "./side-components/logistics";
import { ProductionSideBar } from "./side-components/production";
import { QualitySideBar } from "./side-components/quality";
export function AppSidebar() {
const { session } = useAuth();
@@ -36,9 +33,9 @@ export function AppSidebar() {
<LogisticsSideBar user={session?.user as any} userRoles={userRoles} />
{userAccess(null, ["systemAdmin"]) && (
<>
<ForkliftSideBar />
{/* <ForkliftSideBar />
<EomSideBar />
<QualitySideBar />
<QualitySideBar /> */}
<AdminSideBar />
</>
)}