feat(leases): added in leases and move table to reuseable component

This commit is contained in:
2025-11-04 20:16:14 -06:00
parent b1c56ee4bb
commit bd7bea8db6
30 changed files with 5788 additions and 601 deletions

View File

@@ -0,0 +1,128 @@
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import { format } from "date-fns";
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/getCompanies";
import { getLeases } from "@/lib/querys/forklifts/getLeases";
import { useAppForm } from "../../../../lib/formStuff";
type CompanyData = {
id: string;
name: string;
};
export default function NewLeaseForm({
setOpenDialog,
}: {
setOpenDialog: any;
}) {
//const search = useSearch({ from: "/_app/(auth)/login" });
const { data, isLoading } = useQuery(getCompanies());
const { refetch } = useQuery(getLeases());
const form = useAppForm({
defaultValues: {
companyId: "",
leaseNumber: "",
startDate: "",
endDate: "",
},
onSubmit: async ({ value }) => {
const data = {
leaseNumber: value.leaseNumber.trimStart().trimEnd(),
startDate: format(value.startDate, "MM/dd/yyyy"),
endDate: format(value.endDate, "MM/dd/yyyy"),
companyId: value.companyId,
};
console.log(data);
try {
await axios.post("/lst/api/forklifts/leases", data);
form.reset();
setOpenDialog(false);
refetch();
toast.success(`${value.leaseNumber} 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);
}
}
},
});
if (isLoading) return <div>Loading Companies</div>;
// remap the companies to fit out select field
const companyMap = data.map((i: CompanyData) => {
return { value: i.id, label: i.name };
});
//const currentYear = new Date().getFullYear();
return (
<>
<DialogHeader>
<DialogTitle>Create New Lease</DialogTitle>
<DialogDescription>
Select the company this lease will be for, lease number, start and end
date
</DialogDescription>
</DialogHeader>
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<form.AppField
name="companyId"
children={(field) => (
<field.SelectField
label="Select Company"
placeholder="Companies"
options={companyMap}
/>
)}
/>
<form.AppField
name="leaseNumber"
children={(field) => (
<field.InputField
label="Lease Number"
inputType="string"
required={false}
/>
)}
/>
<div className="flex flex-row gap-2 mt-2 mb-2">
<form.AppField
name="startDate"
children={(field) => <field.DateField label="Start Date" />}
/>
<form.AppField
name="endDate"
children={(field) => <field.DateField label="End Date" />}
/>
</div>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button type="submit">Submit</Button>
</DialogFooter>
</form>
</>
);
}

View File

@@ -1,17 +1,9 @@
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 { createColumnHelper } from "@tanstack/react-table";
import axios from "axios";
import { Activity, ArrowDown, ArrowUp } from "lucide-react";
import React, { useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -22,15 +14,9 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { getCompanies } from "@/lib/querys/forklifts/getCompanies";
import TableNoExpand from "@/lib/tableStuff/TableNoExpand";
import { cn } from "@/lib/utils";
type Company = {
@@ -64,7 +50,6 @@ function RouteComponent() {
isLoading,
refetch,
} = useQuery(getCompanies());
const [sorting, setSorting] = useState<SortingState>([]);
const columnHelper = createColumnHelper<Company>();
const submitting = useRef(false);
@@ -192,91 +177,8 @@ function RouteComponent() {
}),
];
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>
);
return <TableNoExpand data={companyData} columns={columns} />;
}

View File

@@ -0,0 +1,124 @@
import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { createColumnHelper } from "@tanstack/react-table";
import { format } from "date-fns";
import { ArrowDown, ArrowUp } from "lucide-react";
//import { useRef } from "react";
import { Button } from "@/components/ui/button";
import { getLeases } from "@/lib/querys/forklifts/getLeases";
import TableNoExpand from "@/lib/tableStuff/TableNoExpand";
type Leases = {
id: string;
leaseNumber: string;
startDate: Date;
endDate: Date;
leaseLink: string | null;
companyName: string;
add_user: string;
add_date: Date;
upd_user: string;
upd_date: Date;
};
export const Route = createFileRoute("/_app/_forklifts/forklifts/leases")({
component: RouteComponent,
});
function RouteComponent() {
const { data: leaseData = [], isLoading } = useQuery(getLeases());
const columnHelper = createColumnHelper<Leases>();
//const submitting = useRef(false);
const columns = [
columnHelper.accessor("companyName", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">Company</span>
{column.getIsSorted() === "asc" ? (
<ArrowUp className="ml-2 h-4 w-4" />
) : (
<ArrowDown className="ml-2 h-4 w-4" />
)}
</Button>
);
},
}),
columnHelper.accessor("leaseNumber", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">Lease 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("startDate", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">Start Date</span>
{column.getIsSorted() === "asc" ? (
<ArrowUp className="ml-2 h-4 w-4" />
) : (
<ArrowDown className="ml-2 h-4 w-4" />
)}
</Button>
);
},
cell: ({ getValue }) => {
const raw = getValue() as string | Date;
const date = typeof raw === "string" ? new Date(raw) : (raw as Date);
if (isNaN(date.getTime())) return "Invalid date";
return <span>{format(date, "MM/dd/yyyy")}</span>;
},
}),
columnHelper.accessor("endDate", {
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
<span className="flex flex-row gap-2">End Date</span>
{column.getIsSorted() === "asc" ? (
<ArrowUp className="ml-2 h-4 w-4" />
) : (
<ArrowDown className="ml-2 h-4 w-4" />
)}
</Button>
);
},
cell: ({ getValue }) => {
const raw = getValue() as string | Date;
const date = typeof raw === "string" ? new Date(raw) : (raw as Date);
if (isNaN(date.getTime())) return "Invalid date";
return <span>{format(date, "MM/dd/yyyy")}</span>;
},
}),
];
if (isLoading) {
return <div className="m-auto">Loading user data</div>;
}
return <TableNoExpand data={leaseData} columns={columns} />;
}