test(reporting): more reporting tables for different reports

This commit is contained in:
2025-04-13 08:27:28 -05:00
parent 17b6c0ac66
commit 9325e58551
17 changed files with 434 additions and 122 deletions

View File

@@ -1,6 +1,6 @@
import {useQuery} from "@tanstack/react-query";
import {useSessionStore} from "../lib/store/sessionStore";
import {useEffect} from "react";
import { useQuery } from "@tanstack/react-query";
import { useSessionStore } from "../lib/store/sessionStore";
import { useEffect } from "react";
const fetchSession = async () => {
const token = localStorage.getItem("auth_token");
@@ -23,9 +23,6 @@ const fetchSession = async () => {
localStorage.removeItem("auth-storage");
localStorage.removeItem("nextauth.message");
localStorage.removeItem("prod");
localStorage.removeItem("cards");
localStorage.removeItem("rememberMe");
localStorage.removeItem("username");
throw new Error("Session not found");
}
@@ -34,10 +31,10 @@ const fetchSession = async () => {
};
export const useSession = () => {
const {setSession, clearSession, token} = useSessionStore();
const { setSession, clearSession, token } = useSessionStore();
// Fetch session only if token is available
const {data, status, error} = useQuery({
const { data, status, error } = useQuery({
queryKey: ["session"],
queryFn: fetchSession,
enabled: !!token, // Prevents query if token is null
@@ -55,5 +52,9 @@ export const useSession = () => {
}
}, [data, error]);
return {session: data && token ? {user: data.user, token: data.token} : null, status, error};
return {
session: data && token ? { user: data.user, token: data.token } : null,
status,
error,
};
};

View File

@@ -0,0 +1,55 @@
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
interface CardSettings {
daysSinceLast?: number;
rowType?: string;
}
export interface Card {
i: string;
x: number;
y: number;
w: number;
h: number;
minW?: number;
maxW?: number;
minH?: number;
maxH?: number;
isResizable: boolean;
isDraggable: boolean;
cardSettings?: CardSettings;
}
interface CardStore {
cards: Card[]; // Array of card objects
addCard: (card: Card) => void;
updateCard: (id: string, updatedCard: Partial<Card>) => void;
removeCard: (id: string) => void;
}
export const useCardStore = create<CardStore>()(
devtools(
persist<CardStore>(
(set) => ({
cards: [],
addCard: (card) =>
set((state) => ({ cards: [...state.cards, card] })),
updateCard: (id, updatedCard) =>
set((state) => ({
cards: state.cards.map((card) =>
card.i === id ? { ...card, ...updatedCard } : card
),
})),
removeCard: (id) =>
set((state) => ({
cards: state.cards.filter((card) => card.i !== id),
})),
}),
{ name: "card-storage" }
)
)
);

View File

@@ -7,12 +7,12 @@ import { ModeToggle } from "../components/layout/mode-toggle";
import { AppSidebar } from "../components/layout/lst-sidebar";
import { Avatar, AvatarFallback, AvatarImage } from "../components/ui/avatar";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../components/ui/dropdown-menu";
import { SessionProvider } from "../components/providers/Providers";
import { Toaster } from "sonner";
@@ -21,74 +21,83 @@ import { Toaster } from "sonner";
import { useSessionStore } from "../lib/store/sessionStore";
import { useSession } from "@/hooks/useSession";
import { useLogout } from "@/hooks/useLogout";
import { AddCards } from "@/components/dashboard/AddCards";
// same as the layout
export const Route = createRootRoute({
component: () => {
const sidebarState = Cookies.get("sidebar_state") === "true";
const { session } = useSession();
const { user } = useSessionStore();
const logout = useLogout();
component: () => {
const sidebarState = Cookies.get("sidebar_state") === "true";
const { session } = useSession();
const { user } = useSessionStore();
const logout = useLogout();
return (
<>
<SessionProvider>
<ThemeProvider>
<nav className="flex justify-end">
<div className="m-2 flex flex-row">
<div className="m-auto pr-2">
<p>Add Card</p>
</div>
<div className="m-1">
<ModeToggle />
</div>
{session ? (
<div className="m-1">
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar>
<AvatarImage
src="https://github.com/shadcn.png"
alt="@shadcn"
/>
<AvatarFallback>CN</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>
Hello {user?.username}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{/* <DropdownMenuItem>Profile</DropdownMenuItem>
return (
<>
<SessionProvider>
<ThemeProvider>
<nav className="flex justify-end">
<div className="m-2 flex flex-row">
<div className="m-auto pr-2">
<AddCards />
</div>
<div className="m-1">
<ModeToggle />
</div>
{session ? (
<div className="m-1">
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar>
<AvatarImage
src="https://github.com/shadcn.png"
alt="@shadcn"
/>
<AvatarFallback>
CN
</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>
Hello {user?.username}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{/* <DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem> */}
<hr className="solid"></hr>
<DropdownMenuItem>
<div className="m-auto">
<button onClick={() => logout()}>Logout</button>
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
) : (
<div>
<Link to="/login">Login</Link>
</div>
)}
</div>
</nav>
<SidebarProvider defaultOpen={sidebarState}>
<AppSidebar />
<Toaster expand={true} richColors closeButton />
<Outlet />
</SidebarProvider>
</ThemeProvider>
</SessionProvider>
<hr className="solid"></hr>
<DropdownMenuItem>
<div className="m-auto">
<button
onClick={() =>
logout()
}
>
Logout
</button>
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
) : (
<div>
<Link to="/login">Login</Link>
</div>
)}
</div>
</nav>
<SidebarProvider defaultOpen={sidebarState}>
<AppSidebar />
<Toaster expand={true} richColors closeButton />
<Outlet />
</SidebarProvider>
</ThemeProvider>
</SessionProvider>
{/* <TanStackRouterDevtools position="bottom-right" /> */}
</>
);
},
{/* <TanStackRouterDevtools position="bottom-right" /> */}
</>
);
},
});

View File

@@ -1,51 +1,17 @@
import {createFileRoute} from "@tanstack/react-router";
import { createFileRoute } from "@tanstack/react-router";
//import GridLayout from "react-grid-layout";
import "../../node_modules/react-grid-layout/css/styles.css";
import "../../node_modules/react-resizable/css/styles.css";
import DashBoard from "@/components/dashboard/DashBoard";
export const Route = createFileRoute("/")({
component: Index,
});
function Index() {
// const [layout, setLayout] = useState([
// {
// i: "PPOO",
// x: 0,
// y: 0,
// w: 5,
// h: 3,
// minW: 2,
// maxW: 6,
// minH: 2,
// maxH: 4,
// isResizable: true,
// isDraggable: true,
// },
// {i: "OCPLogs", x: 2, y: 0, w: 5, h: 3, isResizable: true, isDraggable: true},
// ]);
// const [cardData, setCardData] = useState([
// {i: "card1", name: "PPOO"},
// {i: "card2", name: "OCPLogs"},
// ]);
return (
<>
{/* <AddCards addCard={addCard} cards={cards} /> */}
{/* <GridLayout className="layout" cols={12} rowHeight={30} width={window.innerWidth}>
<div className="bg-blue-400" key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}>
a
</div>
<div className="bg-blue-400" key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}>
b
</div>
<div className="bg-blue-400" key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}>
c
</div>
</GridLayout> */}
<div className="m-auto">
<span>Empty Space why dont you add some cards?</span>
</div>
</>
<div className="h-dvh w-dvw">
<DashBoard />
</div>
);
}

View File

@@ -1,10 +1,14 @@
import OCPPage from "@/components/production/ocp/OcpPage";
import {createFileRoute} from "@tanstack/react-router";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/ocp/")({
component: RouteComponent,
});
function RouteComponent() {
return <OCPPage />;
return (
<div className="h-dvh w-dvw">
<OCPPage />
</div>
);
}

View File

@@ -0,0 +1,20 @@
import { queryOptions } from "@tanstack/react-query";
import axios from "axios";
export function getPPOO() {
return queryOptions({
queryKey: ["getPPOO"],
queryFn: () => fetchStockSilo(),
//enabled:
staleTime: 1000,
refetchInterval: 2 * 2000,
refetchOnWindowFocus: true,
});
}
const fetchStockSilo = async () => {
const { data } = await axios.get(`/api/logistics/getppoo`);
// if we are not localhost ignore the devDir setting.
//const url: string = window.location.host.split(":")[0];
return data.data ?? [];
};

View File

@@ -4,7 +4,7 @@ import axios from "axios";
export function getStockSilo() {
const token = localStorage.getItem("auth_token");
return queryOptions({
queryKey: ["getUsers"],
queryKey: ["getSiloData"],
queryFn: () => fetchStockSilo(token),
enabled: !!token, // Prevents query if token is null
staleTime: 1000,

View File

@@ -0,0 +1,46 @@
import { ColumnDef } from "@tanstack/react-table";
import { format } from "date-fns";
// This type is used to define the shape of our data.
// You can use a Zod schema here if you want.
export type Adjustmnets = {
siloAdjust_id: string;
currentStockLevel: string;
newLevel: number;
dateAdjusted: string;
lastDateAdjusted: string;
comment: string;
commentAddedBy: string;
commentDate: string;
add_user: string;
};
export const columns: ColumnDef<Adjustmnets>[] = [
{
accessorKey: "MachineLocation",
header: () => <div className="text-left">Line</div>,
},
{
accessorKey: "ArticleHumanReadableId",
header: "AV",
},
{
accessorKey: "RunningNumber",
header: "Running Number",
},
{
accessorKey: "ProductionDate",
header: "Booked in",
cell: ({ row }) => {
if (row.getValue("ProductionDate")) {
const correctDate = format(
row.getValue("ProductionDate"),
"M/d/yyyy hh:mm"
);
return (
<div className="text-left font-medium">{correctDate}</div>
);
}
},
},
];

View File

@@ -0,0 +1,124 @@
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
getPaginationRowModel,
} from "@tanstack/react-table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
style: any;
}
export function PPOOTable<TData, TValue>({
columns,
data,
style,
}: DataTableProps<TData, TValue>) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
});
console.log(parseInt(style.height.replace("px", "")) - 50);
return (
<div
style={{
width: `${parseInt(style.width.replace("px", "")) - 50}px`,
height: `${parseInt(style.height.replace("px", "")) - 150}px`,
cursor: "move",
}}
>
<div>
<Table
style={{
width: `${parseInt(style.width.replace("px", "")) - 50}px`,
height: `${parseInt(style.height.replace("px", "")) - 200}px`,
cursor: "move",
}}
>
<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?.length ? (
table.getRowModel().rows.map((row) => (
<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>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<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>
);
}

View File

@@ -21,7 +21,7 @@ interface DataTableProps<TData, TValue> {
data: TData[];
}
export function DataTable<TData, TValue>({
export function SiloTable<TData, TValue>({
columns,
data,
}: DataTableProps<TData, TValue>) {