From 9325e58551729acfda9042cf5fb0daacb1f901f1 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Sun, 13 Apr 2025 08:27:28 -0500 Subject: [PATCH] test(reporting): more reporting tables for different reports --- frontend/src/hooks/useSession.ts | 19 +-- frontend/src/lib/store/useCardStore.ts | 55 +++++++ frontend/src/routes/__root.tsx | 145 ++++++++++-------- frontend/src/routes/index.tsx | 44 +----- frontend/src/routes/ocp/index.tsx | 8 +- .../src/utils/querys/logistics/getPPOO.tsx | 20 +++ .../siloAdjustments/getStockSilo.tsx | 2 +- .../src/utils/tableData/ppoo/ppooColumns.tsx | 46 ++++++ .../src/utils/tableData/ppoo/ppooData.tsx | 124 +++++++++++++++ ...siloAdjHist.tsx => siloAdjHistColumns.tsx} | 0 .../{siloDate.tsx => siloData.tsx} | 2 +- .../cycleCountChecks/cyclecountCheck.ts | 12 +- .../controller/warehouse/ppoo/getPPOO.ts | 13 ++ server/services/logistics/logisticsService.ts | 3 + server/services/logistics/route/getPPOO.ts | 53 +++++++ server/services/ocp/controller/lots/lots.ts | 8 + server/services/ocp/ocpService.ts | 2 +- 17 files changed, 434 insertions(+), 122 deletions(-) create mode 100644 frontend/src/lib/store/useCardStore.ts create mode 100644 frontend/src/utils/querys/logistics/getPPOO.tsx create mode 100644 frontend/src/utils/tableData/ppoo/ppooColumns.tsx create mode 100644 frontend/src/utils/tableData/ppoo/ppooData.tsx rename frontend/src/utils/tableData/siloAdjustmentHist/{siloAdjHist.tsx => siloAdjHistColumns.tsx} (100%) rename frontend/src/utils/tableData/siloAdjustmentHist/{siloDate.tsx => siloData.tsx} (98%) create mode 100644 server/services/logistics/controller/warehouse/ppoo/getPPOO.ts create mode 100644 server/services/logistics/route/getPPOO.ts diff --git a/frontend/src/hooks/useSession.ts b/frontend/src/hooks/useSession.ts index f564432..7c30b88 100644 --- a/frontend/src/hooks/useSession.ts +++ b/frontend/src/hooks/useSession.ts @@ -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, + }; }; diff --git a/frontend/src/lib/store/useCardStore.ts b/frontend/src/lib/store/useCardStore.ts new file mode 100644 index 0000000..9224b14 --- /dev/null +++ b/frontend/src/lib/store/useCardStore.ts @@ -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) => void; + removeCard: (id: string) => void; +} + +export const useCardStore = create()( + devtools( + persist( + (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" } + ) + ) +); diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index 3568c2e..6245bb3 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -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 ( - <> - - - + + + + + + + - {/* */} - - ); - }, + {/* */} + + ); + }, }); diff --git a/frontend/src/routes/index.tsx b/frontend/src/routes/index.tsx index 3b68380..1293fec 100644 --- a/frontend/src/routes/index.tsx +++ b/frontend/src/routes/index.tsx @@ -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 ( - <> - {/* */} - {/* -
- a -
-
- b -
-
- c -
-
*/} -
- Empty Space why dont you add some cards? -
- +
+ +
); } diff --git a/frontend/src/routes/ocp/index.tsx b/frontend/src/routes/ocp/index.tsx index 99be454..0c6c901 100644 --- a/frontend/src/routes/ocp/index.tsx +++ b/frontend/src/routes/ocp/index.tsx @@ -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 ; + return ( +
+ +
+ ); } diff --git a/frontend/src/utils/querys/logistics/getPPOO.tsx b/frontend/src/utils/querys/logistics/getPPOO.tsx new file mode 100644 index 0000000..1f63b5c --- /dev/null +++ b/frontend/src/utils/querys/logistics/getPPOO.tsx @@ -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 ?? []; +}; diff --git a/frontend/src/utils/querys/logistics/siloAdjustments/getStockSilo.tsx b/frontend/src/utils/querys/logistics/siloAdjustments/getStockSilo.tsx index 6cd43b2..090928f 100644 --- a/frontend/src/utils/querys/logistics/siloAdjustments/getStockSilo.tsx +++ b/frontend/src/utils/querys/logistics/siloAdjustments/getStockSilo.tsx @@ -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, diff --git a/frontend/src/utils/tableData/ppoo/ppooColumns.tsx b/frontend/src/utils/tableData/ppoo/ppooColumns.tsx new file mode 100644 index 0000000..6fb97f0 --- /dev/null +++ b/frontend/src/utils/tableData/ppoo/ppooColumns.tsx @@ -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[] = [ + { + accessorKey: "MachineLocation", + header: () =>
Line
, + }, + { + 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 ( +
{correctDate}
+ ); + } + }, + }, +]; diff --git a/frontend/src/utils/tableData/ppoo/ppooData.tsx b/frontend/src/utils/tableData/ppoo/ppooData.tsx new file mode 100644 index 0000000..3534239 --- /dev/null +++ b/frontend/src/utils/tableData/ppoo/ppooData.tsx @@ -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 { + columns: ColumnDef[]; + data: TData[]; + style: any; +} + +export function PPOOTable({ + columns, + data, + style, +}: DataTableProps) { + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + }); + + console.log(parseInt(style.height.replace("px", "")) - 50); + return ( +
+
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef + .header, + header.getContext() + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+
+ + +
+
+ ); +} diff --git a/frontend/src/utils/tableData/siloAdjustmentHist/siloAdjHist.tsx b/frontend/src/utils/tableData/siloAdjustmentHist/siloAdjHistColumns.tsx similarity index 100% rename from frontend/src/utils/tableData/siloAdjustmentHist/siloAdjHist.tsx rename to frontend/src/utils/tableData/siloAdjustmentHist/siloAdjHistColumns.tsx diff --git a/frontend/src/utils/tableData/siloAdjustmentHist/siloDate.tsx b/frontend/src/utils/tableData/siloAdjustmentHist/siloData.tsx similarity index 98% rename from frontend/src/utils/tableData/siloAdjustmentHist/siloDate.tsx rename to frontend/src/utils/tableData/siloAdjustmentHist/siloData.tsx index 2426ad7..18f439c 100644 --- a/frontend/src/utils/tableData/siloAdjustmentHist/siloDate.tsx +++ b/frontend/src/utils/tableData/siloAdjustmentHist/siloData.tsx @@ -21,7 +21,7 @@ interface DataTableProps { data: TData[]; } -export function DataTable({ +export function SiloTable({ columns, data, }: DataTableProps) { diff --git a/server/services/logistics/controller/warehouse/cycleCountChecks/cyclecountCheck.ts b/server/services/logistics/controller/warehouse/cycleCountChecks/cyclecountCheck.ts index 30a91d6..af6b2ff 100644 --- a/server/services/logistics/controller/warehouse/cycleCountChecks/cyclecountCheck.ts +++ b/server/services/logistics/controller/warehouse/cycleCountChecks/cyclecountCheck.ts @@ -14,13 +14,23 @@ export const lanes: any = []; export const getLanesToCycleCount = async () => { const currentTime: any = timeZoneFix(); // store the lanes in memeory - createLog("info", "warehouse", "logistics", "Empty lane triggered update."); + createLog("info", "warehouse", "logistics", "Lane triggered update."); lastCheck = currentTime; const ageQuery = cycleCountCheck.replaceAll("[ageOfRow]", `1000`); const { data: prodLanes, error: pl } = await tryCatch( query(ageQuery, "Get Stock lane date.") ); + if (pl) { + createLog( + "error", + "warehouse", + "logistics", + `There was an error getting lanes: ${pl}` + ); + return; + } + // run the update on the lanes for (let i = 0; i < prodLanes.length; i++) { const createLane = { diff --git a/server/services/logistics/controller/warehouse/ppoo/getPPOO.ts b/server/services/logistics/controller/warehouse/ppoo/getPPOO.ts new file mode 100644 index 0000000..713d37b --- /dev/null +++ b/server/services/logistics/controller/warehouse/ppoo/getPPOO.ts @@ -0,0 +1,13 @@ +import { tryCatch } from "../../../../../globalUtils/tryCatch.js"; +import { query } from "../../../../sqlServer/prodSqlServer.js"; +import { ppooQuery } from "../../../../sqlServer/querys/warehouse/ppooQuery.js"; + +export const getPPOO = async () => { + const { data, error } = await tryCatch(query(ppooQuery, "Get PPOO")); + + if (error) { + return { success: false, message: "Error getting ppoo", data: error }; + } + + return { success: true, message: "Current pallets in PPOO.", data: data }; +}; diff --git a/server/services/logistics/logisticsService.ts b/server/services/logistics/logisticsService.ts index 7f96445..6dc97ad 100644 --- a/server/services/logistics/logisticsService.ts +++ b/server/services/logistics/logisticsService.ts @@ -9,6 +9,7 @@ import { migrateAdjustments } from "./controller/siloAdjustments/migrateAdjustme import getSiloAdjustments from "./route/siloAdjustments/getSiloAdjustments.js"; import { getLanesToCycleCount } from "./controller/warehouse/cycleCountChecks/cyclecountCheck.js"; import getCycleCountCheck from "./route/getCycleCountChecks.js"; +import getPPOO from "./route/getPPOO.js"; const app = new OpenAPIHono(); @@ -23,6 +24,8 @@ const routes = [ getSiloAdjustments, //lanes getCycleCountCheck, + //warehouse + getPPOO, ] as const; // app.route("/server", modules); diff --git a/server/services/logistics/route/getPPOO.ts b/server/services/logistics/route/getPPOO.ts new file mode 100644 index 0000000..78a8890 --- /dev/null +++ b/server/services/logistics/route/getPPOO.ts @@ -0,0 +1,53 @@ +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { responses } from "../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../globalUtils/tryCatch.js"; +import { getCycleCountCheck } from "../controller/warehouse/cycleCountChecks/getCycleCountCheck.js"; +import { getPPOO } from "../controller/warehouse/ppoo/getPPOO.js"; + +const app = new OpenAPIHono(); + +// const Body = z +// .object({ +// age: z.number().optional().openapi({ example: 90 }), +// //email: z.string().optional().openapi({example: "s.smith@example.com"}), +// type: z.string().optional().openapi({ example: "fg" }), +// }) +// .openapi("User"); +app.openapi( + createRoute({ + tags: ["logistics"], + summary: "Returns pallets currently in ppoo", + method: "get", + path: "/getppoo", + // request: { + // body: { + // content: { + // "application/json": { schema: Body }, + // }, + // }, + // }, + // description: + // "Provided a running number and lot number you can consume material.", + responses: responses(), + }), + async (c) => { + //apiHit(c, { endpoint: "api/sqlProd/close" }); + + const { data: ppoo, error } = await tryCatch(getPPOO()); + + if (error) { + return c.json({ + success: false, + message: "Error getting lane data.", + data: error, + }); + } + + return c.json({ + success: ppoo.success, + message: ppoo.message, + data: ppoo.data, + }); + } +); +export default app; diff --git a/server/services/ocp/controller/lots/lots.ts b/server/services/ocp/controller/lots/lots.ts index a56351e..a4719a9 100644 --- a/server/services/ocp/controller/lots/lots.ts +++ b/server/services/ocp/controller/lots/lots.ts @@ -15,6 +15,14 @@ export const getLots = async () => { }; } + // if (!lotInfo.data.success) { + // return { + // success: false, + // message: "There was an error getting the lots", + // data: lotInfo.data.message, + // }; + // } + return { success: true, message: "Current active lots that are technically released.", diff --git a/server/services/ocp/ocpService.ts b/server/services/ocp/ocpService.ts index db7cc3b..e4bd19f 100644 --- a/server/services/ocp/ocpService.ts +++ b/server/services/ocp/ocpService.ts @@ -81,7 +81,7 @@ setTimeout(async () => { await updatePrinters(); await assignedPrinters(); printerCycle(); - printerCycleAutoLabelers(); + // printerCycleAutoLabelers(); } }, 10 * 1000);