diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 0218057..efce702 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -23,6 +23,7 @@
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
+ "@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.0.15",
"@tanstack/react-form": "^1.2.1",
"@tanstack/react-query": "^5.69.0",
@@ -37,6 +38,7 @@
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.483.0",
+ "marked": "^15.0.8",
"next-themes": "^0.4.6",
"npm-check-updates": "^17.1.16",
"react": "^19.0.0",
@@ -2937,6 +2939,21 @@
"node": ">= 10"
}
},
+ "node_modules/@tailwindcss/typography": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
+ "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash.castarray": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "postcss-selector-parser": "6.0.10"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
+ }
+ },
"node_modules/@tailwindcss/vite": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.15.tgz",
@@ -4177,6 +4194,18 @@
"node": ">= 8"
}
},
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -5717,6 +5746,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
+ "node_modules/lodash.castarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
+ "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
+ "license": "MIT"
+ },
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -5757,7 +5792,6 @@
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/lodash.once": {
@@ -5797,6 +5831,18 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
+ "node_modules/marked": {
+ "version": "15.0.8",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.8.tgz",
+ "integrity": "sha512-rli4l2LyZqpQuRve5C0rkn6pj3hT8EWPC+zkAxFTAJLxRbENfTAhEQq9itrmf1Y81QtAX5D/MYlGlIomNgj9lA==",
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -6075,6 +6121,19 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7029,6 +7088,12 @@
"which-typed-array": "^1.1.2"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
"node_modules/victory-vendor": {
"version": "36.9.2",
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index d71f2c6..dafe2de 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -41,6 +41,7 @@
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.483.0",
+ "marked": "^15.0.8",
"next-themes": "^0.4.6",
"npm-check-updates": "^17.1.16",
"react": "^19.0.0",
diff --git a/frontend/src/components/dashboard/AddCards.tsx b/frontend/src/components/dashboard/AddCards.tsx
index 73c7216..037603c 100644
--- a/frontend/src/components/dashboard/AddCards.tsx
+++ b/frontend/src/components/dashboard/AddCards.tsx
@@ -3,55 +3,37 @@ import {
Dialog,
DialogContent,
DialogDescription,
- DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
-
-import { useCardStore } from "@/lib/store/useCardStore";
-import { toast } from "sonner";
+import Cards from "./Cards";
+//import { toast } from "sonner";
export function AddCards() {
- const { cards, addCard } = useCardStore();
-
- const handleAddPPOO = () => {
- const existingCard = cards.filter((c) => c.i === "PPOO");
- //console.log(existingCard.length);
- //console.log(data);
- if (existingCard.length != 0) {
- toast.error(`PPOO already exists no card will be added`);
- return;
- }
- addCard({
- i: "PPOO",
- x: 0,
- y: 0,
- w: 5,
- h: 3,
- isResizable: true,
- isDraggable: true,
- });
- };
return (
);
diff --git a/frontend/src/components/dashboard/Cards.tsx b/frontend/src/components/dashboard/Cards.tsx
new file mode 100644
index 0000000..f2a639c
--- /dev/null
+++ b/frontend/src/components/dashboard/Cards.tsx
@@ -0,0 +1,183 @@
+import { useCardStore } from "@/lib/store/useCardStore";
+import { useForm } from "@tanstack/react-form";
+import { Label } from "../ui/label";
+import { Checkbox } from "../ui/checkbox";
+import { Input } from "../ui/input";
+// import {
+// Select,
+// SelectContent,
+// SelectGroup,
+// SelectItem,
+// SelectLabel,
+// SelectTrigger,
+// SelectValue,
+// } from "../ui/select";
+import { Button } from "../ui/button";
+import { toast } from "sonner";
+
+export default function Cards(card: any) {
+ const { addCard, removeCard, cards } = useCardStore();
+ let existing: any = cards.filter((n: any) => n.name === card.name);
+
+ console.log(existing);
+ const form = useForm({
+ defaultValues: {
+ name: existing?.name || card.name,
+ rowType: existing?.type ?? card.rowType,
+ age: existing?.age ?? 90,
+ active: existing.active ? existing.active : false,
+ },
+ onSubmit: async ({ value }) => {
+ console.log(value);
+ const testCard: any = cards.filter(
+ (i: any) => i.name === value.name
+ );
+
+ if (value.active) {
+ if (testCard.length > 0) {
+ toast.error("Card already exists");
+ return;
+ }
+ // change the name for a type card
+ const newCard = {
+ name: `${value.name}`,
+ rowType: value.rowType,
+ age: value.age ?? 90,
+ active: value.active,
+ };
+ addCard(newCard);
+ } else {
+ removeCard(value.name);
+ }
+ },
+ });
+ return (
+
+
{card.name}
+
+ // value.length > 3
+ // ? undefined
+ // : "Username must be longer than 3 letters",
+ // }}
+ children={(field) => {
+ return (
+
+
+
+
+
+
+ field.handleChange(e)
+ }
+ />
+
+ );
+ }}
+ />
+ {!card.inventory && (
+ <>
+
+ // value.length > 3
+ // ? undefined
+ // : "Username must be longer than 3 letters",
+ // }}
+ children={(field) => {
+ return (
+
+
+
+ field.handleChange(
+ e.target.value
+ )
+ }
+ />
+
+ );
+ }}
+ />
+
+ {/* {}}}
+ children={(field) => {
+ return (
+
+
+
+
+ );
+ }}
+ /> */}
+ >
+ )}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/dashboard/DashBoard.tsx b/frontend/src/components/dashboard/DashBoard.tsx
index 659f2ad..a0a6b38 100644
--- a/frontend/src/components/dashboard/DashBoard.tsx
+++ b/frontend/src/components/dashboard/DashBoard.tsx
@@ -1,68 +1,74 @@
+import { useCardStore } from "@/lib/store/useCardStore";
+import INVCheckCard from "../logistics/warehouse/InventoryCard";
+import PPOO from "../logistics/warehouse/PPOOCard";
+
+const componentsMap: any = {
+ ppoo: PPOO,
+ inv: INVCheckCard,
+ //QualityRequest,
+};
+
export default function DashBoard() {
- // const handleResizeStop = (newLayout: any, newItem: any) => {
- // updateCard(
- // newItem.i,
- // newLayout.filter((n: any) => n.i === newItem.i)[0]
- // ); // Store the new layout in state
- // };
-
- // const handleDragStop = (newLayout: any, newItem: any) => {
- // updateCard(
- // newItem.i,
- // newLayout.filter((n: any) => n.i === newItem.i)[0]
- // ); // Persist the updated layout with custom name
- // };
+ const { cards } = useCardStore();
+ //console.log(cards);
return (
-
-
Comming soon...
- {/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {server[0].value === "usday1vms006" && (
-
-
-
- )}
- {server[0].value === "usday1vms006" && (
-
-
-
- )}
+
+ {cards.map((a: any) => {
+ const name = a.name; //.filter((c) => c.i === card.i)[0].i || "name";
-
-
-
-
-
-
- */}
+ const Component = componentsMap[name.split("-")[0]];
+
+ return (
+
+ {" "}
+
+ );
+ })}
);
+
+ // return (
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ // );
}
+
+/*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+*/
diff --git a/frontend/src/components/logistics/warehouse/CardSettings.tsx b/frontend/src/components/logistics/warehouse/CardSettings.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/components/logistics/warehouse/ExportInventoryData.tsx b/frontend/src/components/logistics/warehouse/ExportInventoryData.tsx
new file mode 100644
index 0000000..5de04c1
--- /dev/null
+++ b/frontend/src/components/logistics/warehouse/ExportInventoryData.tsx
@@ -0,0 +1,153 @@
+import { Button } from "@/components/ui/button";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/components/ui/dialog";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+
+import { useForm } from "@tanstack/react-form";
+import axios from "axios";
+import { format } from "date-fns";
+import { useState } from "react";
+import { toast } from "sonner";
+
+export default function ExportInventoryData() {
+ const [open, setOpen] = useState(false);
+ const [saving, setSaving] = useState(false);
+
+ const form = useForm({
+ defaultValues: {
+ age: "",
+ },
+ onSubmit: async ({ value }) => {
+ setSaving(true);
+ try {
+ const res = await axios.get(
+ `/api/logistics/getcyclecount?age=${value.age}`,
+ {
+ responseType: "blob",
+ }
+ );
+
+ const blob = new Blob([res.data], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+
+ const link = document.createElement("a");
+ link.href = window.URL.createObjectURL(blob);
+ link.download = `CycleCount-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
+ document.body.appendChild(link);
+ link.click();
+
+ // Clean up
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(link.href);
+ toast.success(`File Downloaded`);
+ setSaving(false);
+ setOpen(false);
+ form.reset();
+ } catch (error) {
+ console.log(error);
+ console.log(`There was an error getting cycle counts.`);
+ }
+ },
+ });
+
+ return (
+
+
+
+ );
+}
diff --git a/frontend/src/components/logistics/warehouse/InventoryCard.tsx b/frontend/src/components/logistics/warehouse/InventoryCard.tsx
new file mode 100644
index 0000000..aa49287
--- /dev/null
+++ b/frontend/src/components/logistics/warehouse/InventoryCard.tsx
@@ -0,0 +1,37 @@
+//import { LstCard } from "@/components/extendedUI/LstCard";
+import { getinventoryCheck } from "@/utils/querys/logistics/getInventoryCheck";
+import { invColumns } from "@/utils/tableData/InventoryCards/inventoryColumns";
+import { InvTable } from "@/utils/tableData/InventoryCards/inventoryData";
+
+import { useQuery } from "@tanstack/react-query";
+//import { CircleX } from "lucide-react";
+//import { Suspense } from "react";
+//import { toast } from "sonner";
+
+export default function INVCheckCard(props: any) {
+ //{ style = {} }
+ const { data, isError, isLoading } = useQuery(getinventoryCheck(props));
+
+ if (isLoading) return Loading inventory data...
;
+ if (isError) {
+ return (
+
+
There was an error getting the inv.
+
+ );
+ }
+ let laneData: any = data;
+ if (props.type != "") {
+ laneData = laneData.filter(
+ (l: any) => l.rowType === props.type.toUpperCase()
+ );
+ }
+
+ // const handleCloseCard = () => {
+ // //removeCard("PPOO");
+
+ // toast.success("card removed");
+ // };
+
+ return ;
+}
diff --git a/frontend/src/components/logistics/warehouse/PPOOCard.tsx b/frontend/src/components/logistics/warehouse/PPOOCard.tsx
index 1ec5f61..bcb410c 100644
--- a/frontend/src/components/logistics/warehouse/PPOOCard.tsx
+++ b/frontend/src/components/logistics/warehouse/PPOOCard.tsx
@@ -1,15 +1,14 @@
-import { LstCard } from "@/components/extendedUI/LstCard";
-import { useCardStore } from "@/lib/store/useCardStore";
+//import { LstCard } from "@/components/extendedUI/LstCard";
import { getPPOO } from "@/utils/querys/logistics/getPPOO";
import { columns } from "@/utils/tableData/ppoo/ppooColumns";
import { PPOOTable } from "@/utils/tableData/ppoo/ppooData";
import { useQuery } from "@tanstack/react-query";
-import { CircleX } from "lucide-react";
-import { Suspense } from "react";
-import { toast } from "sonner";
+//import { CircleX } from "lucide-react";
+//import { Suspense } from "react";
+//import { toast } from "sonner";
-export default function PPOO({ style = {} }) {
- const { removeCard } = useCardStore();
+export default function PPOO() {
+ //{ style = {} }
const { data, isError, isLoading } = useQuery(getPPOO());
if (isLoading) return Loading adjustmnet data...
;
@@ -21,30 +20,42 @@ export default function PPOO({ style = {} }) {
);
}
- const handleCloseCard = () => {
- removeCard("PPOO");
+ // const handleCloseCard = () => {
+ // //removeCard("PPOO");
+
+ // toast.success("card removed");
+ // };
- toast.success("card removed");
- };
return (
-
-
- Loading PPOO...}>
-
-
-
-
-
+
);
+ // return (
+ //
+ //
+ // Loading PPOO...}>
+ //
+ //
+ // PPOO
+ //
+
+ //
+ //
+ //
+ //
+ //
+ //
+ // );
}
diff --git a/frontend/src/lib/store/useCardStore.ts b/frontend/src/lib/store/useCardStore.ts
index 9224b14..6987285 100644
--- a/frontend/src/lib/store/useCardStore.ts
+++ b/frontend/src/lib/store/useCardStore.ts
@@ -1,31 +1,23 @@
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
-interface CardSettings {
- daysSinceLast?: number;
- rowType?: string;
-}
+// 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;
+ name: string;
+ rowType: string;
+ age: string;
+ active: boolean;
}
interface CardStore {
cards: Card[]; // Array of card objects
addCard: (card: Card) => void;
- updateCard: (id: string, updatedCard: Partial) => void;
- removeCard: (id: string) => void;
+ updateCard: (name: string, updatedCard: Partial) => void;
+ removeCard: (name: string) => void;
}
export const useCardStore = create()(
@@ -37,16 +29,18 @@ export const useCardStore = create()(
addCard: (card) =>
set((state) => ({ cards: [...state.cards, card] })),
- updateCard: (id, updatedCard) =>
+ updateCard: (name, updatedCard) =>
set((state) => ({
cards: state.cards.map((card) =>
- card.i === id ? { ...card, ...updatedCard } : card
+ card.name === name
+ ? { ...card, ...updatedCard }
+ : card
),
})),
- removeCard: (id) =>
+ removeCard: (name) =>
set((state) => ({
- cards: state.cards.filter((card) => card.i !== id),
+ cards: state.cards.filter((card) => card.name !== name),
})),
}),
{ name: "card-storage" }
diff --git a/frontend/src/styles.css b/frontend/src/styles.css
index 1f613d0..748fe58 100644
--- a/frontend/src/styles.css
+++ b/frontend/src/styles.css
@@ -5,120 +5,120 @@
@custom-variant dark (&:is(.dark *));
:root {
- --background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
- --card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
- --popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
- --primary-foreground: oklch(0.985 0 0);
- --secondary: oklch(0.97 0 0);
- --secondary-foreground: oklch(0.205 0 0);
- --muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
- --accent: oklch(0.97 0 0);
- --accent-foreground: oklch(0.205 0 0);
- --destructive: oklch(0.577 0.245 27.325);
- --destructive-foreground: oklch(0.577 0.245 27.325);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.87 0 0);
- --chart-1: oklch(0.646 0.222 41.116);
- --chart-2: oklch(0.6 0.118 184.704);
- --chart-3: oklch(0.398 0.07 227.392);
- --chart-4: oklch(0.828 0.189 84.429);
- --chart-5: oklch(0.769 0.188 70.08);
- --radius: 0.625rem;
- --sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
- --sidebar-primary: oklch(0.205 0 0);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.97 0 0);
- --sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
- --sidebar-ring: oklch(0.87 0 0);
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.145 0 0);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
+ --primary: oklch(0.205 0 0);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.97 0 0);
+ --secondary-foreground: oklch(0.205 0 0);
+ --muted: oklch(0.97 0 0);
+ --muted-foreground: oklch(0.556 0 0);
+ --accent: oklch(0.97 0 0);
+ --accent-foreground: oklch(0.205 0 0);
+ --destructive: oklch(0.577 0.245 27.325);
+ --destructive-foreground: oklch(0.577 0.245 27.325);
+ --border: oklch(0.922 0 0);
+ --input: oklch(0.922 0 0);
+ --ring: oklch(0.87 0 0);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --radius: 0.625rem;
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-primary: oklch(0.205 0 0);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.97 0 0);
+ --sidebar-accent-foreground: oklch(0.205 0 0);
+ --sidebar-border: oklch(0.922 0 0);
+ --sidebar-ring: oklch(0.87 0 0);
}
.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.145 0 0);
- --card-foreground: oklch(0.985 0 0);
- --popover: oklch(0.145 0 0);
- --popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.985 0 0);
- --primary-foreground: oklch(0.205 0 0);
- --secondary: oklch(0.269 0 0);
- --secondary-foreground: oklch(0.985 0 0);
- --muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.708 0 0);
- --accent: oklch(0.269 0 0);
- --accent-foreground: oklch(0.985 0 0);
- --destructive: oklch(0.396 0.141 25.723);
- --destructive-foreground: oklch(0.637 0.237 25.331);
- --border: oklch(0.269 0 0);
- --input: oklch(0.269 0 0);
- --ring: oklch(0.439 0 0);
- --chart-1: oklch(0.488 0.243 264.376);
- --chart-2: oklch(0.696 0.17 162.48);
- --chart-3: oklch(0.769 0.188 70.08);
- --chart-4: oklch(0.627 0.265 303.9);
- --chart-5: oklch(0.645 0.246 16.439);
- --sidebar: oklch(0.205 0 0);
- --sidebar-foreground: oklch(0.985 0 0);
- --sidebar-primary: oklch(0.488 0.243 264.376);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.269 0 0);
- --sidebar-accent-foreground: oklch(0.985 0 0);
- --sidebar-border: oklch(0.269 0 0);
- --sidebar-ring: oklch(0.439 0 0);
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.145 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.145 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.985 0 0);
+ --primary-foreground: oklch(0.205 0 0);
+ --secondary: oklch(0.269 0 0);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.269 0 0);
+ --muted-foreground: oklch(0.708 0 0);
+ --accent: oklch(0.269 0 0);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.396 0.141 25.723);
+ --destructive-foreground: oklch(0.637 0.237 25.331);
+ --border: oklch(0.269 0 0);
+ --input: oklch(0.269 0 0);
+ --ring: oklch(0.439 0 0);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.205 0 0);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.269 0 0);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(0.269 0 0);
+ --sidebar-ring: oklch(0.439 0 0);
}
@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --color-card: var(--card);
- --color-card-foreground: var(--card-foreground);
- --color-popover: var(--popover);
- --color-popover-foreground: var(--popover-foreground);
- --color-primary: var(--primary);
- --color-primary-foreground: var(--primary-foreground);
- --color-secondary: var(--secondary);
- --color-secondary-foreground: var(--secondary-foreground);
- --color-muted: var(--muted);
- --color-muted-foreground: var(--muted-foreground);
- --color-accent: var(--accent);
- --color-accent-foreground: var(--accent-foreground);
- --color-destructive: var(--destructive);
- --color-destructive-foreground: var(--destructive-foreground);
- --color-border: var(--border);
- --color-input: var(--input);
- --color-ring: var(--ring);
- --color-chart-1: var(--chart-1);
- --color-chart-2: var(--chart-2);
- --color-chart-3: var(--chart-3);
- --color-chart-4: var(--chart-4);
- --color-chart-5: var(--chart-5);
- --radius-sm: calc(var(--radius) - 4px);
- --radius-md: calc(var(--radius) - 2px);
- --radius-lg: var(--radius);
- --radius-xl: calc(var(--radius) + 4px);
- --color-sidebar: var(--sidebar);
- --color-sidebar-foreground: var(--sidebar-foreground);
- --color-sidebar-primary: var(--sidebar-primary);
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
- --color-sidebar-accent: var(--sidebar-accent);
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
- --color-sidebar-border: var(--sidebar-border);
- --color-sidebar-ring: var(--sidebar-ring);
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
}
@layer base {
- * {
- @apply border-border outline-ring/50;
- }
- body {
- @apply bg-background text-foreground;
- }
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
}
diff --git a/frontend/src/utils/querys/logistics/getInventoryCheck.tsx b/frontend/src/utils/querys/logistics/getInventoryCheck.tsx
new file mode 100644
index 0000000..1051619
--- /dev/null
+++ b/frontend/src/utils/querys/logistics/getInventoryCheck.tsx
@@ -0,0 +1,25 @@
+import { queryOptions } from "@tanstack/react-query";
+import axios from "axios";
+
+export function getinventoryCheck(data: any) {
+ return queryOptions({
+ queryKey: ["getInvCheck"],
+ queryFn: () => fetchStockSilo(data),
+ //enabled:
+ staleTime: 1000,
+ refetchInterval: 60 * 1000,
+ refetchOnWindowFocus: true,
+ });
+}
+
+const fetchStockSilo = async (info: any) => {
+ console.log(info);
+ const { data } = await axios.post(`/api/logistics/cyclecountcheck`, {
+ age: info.age ? parseInt(info.age) : null,
+ type: "",
+ });
+
+ // 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/getPPOO.tsx b/frontend/src/utils/querys/logistics/getPPOO.tsx
index 1f63b5c..0d9a648 100644
--- a/frontend/src/utils/querys/logistics/getPPOO.tsx
+++ b/frontend/src/utils/querys/logistics/getPPOO.tsx
@@ -7,7 +7,7 @@ export function getPPOO() {
queryFn: () => fetchStockSilo(),
//enabled:
staleTime: 1000,
- refetchInterval: 2 * 2000,
+ refetchInterval: 60 * 1000,
refetchOnWindowFocus: true,
});
}
diff --git a/frontend/src/utils/tableData/InventoryCards/inventoryColumns.tsx b/frontend/src/utils/tableData/InventoryCards/inventoryColumns.tsx
new file mode 100644
index 0000000..844fa97
--- /dev/null
+++ b/frontend/src/utils/tableData/InventoryCards/inventoryColumns.tsx
@@ -0,0 +1,27 @@
+import { ColumnDef } from "@tanstack/react-table";
+
+// 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 invColumns: ColumnDef[] = [
+ {
+ accessorKey: "Description",
+ header: () => Lane
,
+ },
+ {
+ accessorKey: "DaysSinceLast",
+ header: "Age",
+ //enableSorting: true,
+ },
+];
diff --git a/frontend/src/utils/tableData/InventoryCards/inventoryData.tsx b/frontend/src/utils/tableData/InventoryCards/inventoryData.tsx
new file mode 100644
index 0000000..31248a8
--- /dev/null
+++ b/frontend/src/utils/tableData/InventoryCards/inventoryData.tsx
@@ -0,0 +1,166 @@
+import {
+ ColumnDef,
+ flexRender,
+ getCoreRowModel,
+ useReactTable,
+ getPaginationRowModel,
+ getSortedRowModel,
+} from "@tanstack/react-table";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+//import { Button } from "@/components/ui/button";
+import { useState } from "react";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { LstCard } from "@/components/extendedUI/LstCard";
+
+interface DataTableProps {
+ columns: ColumnDef[];
+ data: TData[];
+ info: any;
+}
+
+type ColumnSort = {
+ id: string;
+ desc: boolean;
+};
+type SortingState = ColumnSort[];
+
+export function InvTable({
+ columns,
+ data,
+ info,
+}: DataTableProps) {
+ const [sorting, setSorting] = useState([]);
+ const [pagination, setPagination] = useState({
+ pageIndex: 0, //initial page index
+ pageSize: 5, //default page size
+ });
+ const table = useReactTable({
+ data,
+ columns,
+ getCoreRowModel: getCoreRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ onPaginationChange: setPagination,
+ getSortedRowModel: getSortedRowModel(),
+ state: {
+ //...
+ pagination,
+ sorting,
+ },
+ manualSorting: true,
+ onSortingChange: setSorting,
+ initialState: {
+ sorting: [
+ {
+ id: "DaysSinceLast",
+ desc: true,
+ },
+ ],
+ },
+ });
+ //console.log(table.getState().sorting);
+ //console.log(parseInt(style.height.replace("px", "")) - 50);
+ return (
+
+
+
+
+ {info.type} {data.length > 0 ? "lanes" : "lane"} older
+ than: {info.age}, needing to be completed
+
+
+
+
+
+ {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/notifications/notifyColumns.tsx b/frontend/src/utils/tableData/notifications/notifyColumns.tsx
new file mode 100644
index 0000000..f640563
--- /dev/null
+++ b/frontend/src/utils/tableData/notifications/notifyColumns.tsx
@@ -0,0 +1,68 @@
+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 notifyColumns: ColumnDef[] = [
+ {
+ accessorKey: "name",
+ header: () => Name
,
+ },
+ {
+ accessorKey: "description",
+ header: "Description",
+ cell: ({ row }) => {
+ return (
+
+
+ {row.getValue("description")}
+
+
+ );
+ },
+ },
+
+ {
+ accessorKey: "checkInterval",
+ header: "Check Interval",
+ },
+ {
+ accessorKey: "timeType",
+ header: "Time tpye",
+ },
+ {
+ accessorKey: "emails",
+ header: "Emails",
+ },
+ {
+ accessorKey: "active",
+ header: "Active",
+ },
+ {
+ accessorKey: "lastRan",
+ header: "Last Ran",
+ cell: ({ row }) => {
+ if (row.getValue("lastRan")) {
+ const correctDate = format(
+ row.getValue("lastRan"),
+ "M/d/yyyy hh:mm"
+ );
+ return (
+ {correctDate}
+ );
+ }
+ },
+ },
+];
diff --git a/frontend/src/utils/tableData/notifications/notifyData.tsx b/frontend/src/utils/tableData/notifications/notifyData.tsx
new file mode 100644
index 0000000..6db143a
--- /dev/null
+++ b/frontend/src/utils/tableData/notifications/notifyData.tsx
@@ -0,0 +1,134 @@
+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";
+import { useState } from "react";
+
+interface DataTableProps {
+ columns: ColumnDef[];
+ data: TData[];
+ //style: any;
+}
+
+export function NotifyTable({
+ columns,
+ data,
+ //style,
+}: DataTableProps) {
+ const [pagination, setPagination] = useState({
+ pageIndex: 0, //initial page index
+ pageSize: 5, //default page size
+ });
+ const table = useReactTable({
+ data,
+ columns,
+ getCoreRowModel: getCoreRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ onPaginationChange: setPagination,
+ state: {
+ //...
+ pagination,
+ },
+ });
+
+ // 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/ppoo/ppooData.tsx b/frontend/src/utils/tableData/ppoo/ppooData.tsx
index 3534239..a96590c 100644
--- a/frontend/src/utils/tableData/ppoo/ppooData.tsx
+++ b/frontend/src/utils/tableData/ppoo/ppooData.tsx
@@ -14,94 +14,147 @@ import {
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
+import { useState } from "react";
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { LstCard } from "@/components/extendedUI/LstCard";
interface DataTableProps {
columns: ColumnDef[];
data: TData[];
- style: any;
+ //style: any;
}
export function PPOOTable({
columns,
data,
- style,
+ //style,
}: DataTableProps) {
+ const [pagination, setPagination] = useState({
+ pageIndex: 0, //initial page index
+ pageSize: 5, //default page size
+ });
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
+ onPaginationChange: setPagination,
+ state: {
+ //...
+ pagination,
+ },
});
- console.log(parseInt(style.height.replace("px", "")) - 50);
+ //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()
- )}
-
- ))}
+
+
PPOO Data
+
+
+
+
+
+ {table.getHeaderGroups().map((headerGroup) => (
+
+ {headerGroup.headers.map((header) => {
+ return (
+
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column
+ .columnDef.header,
+ header.getContext()
+ )}
+
+ );
+ })}
- ))
- ) : (
-
-
- No results.
-
-
- )}
-
-
+ ))}
+
+
+ {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/server/services/logistics/controller/warehouse/cycleCountChecks/getCycleCountCheck.ts b/server/services/logistics/controller/warehouse/cycleCountChecks/getCycleCountCheck.ts
index c3a9ba6..19e8eac 100644
--- a/server/services/logistics/controller/warehouse/cycleCountChecks/getCycleCountCheck.ts
+++ b/server/services/logistics/controller/warehouse/cycleCountChecks/getCycleCountCheck.ts
@@ -1,28 +1,41 @@
import { lanes } from "./cyclecountCheck.js";
-export const getCycleCountCheck = async (
- age: number = 1000,
- type: string = ""
-) => {
+export const getCycleCountCheck = async (age: number = 1000, type: any) => {
/**
* Get the lane data based on the age and type
*/
- let filteredLanes = lanes.filter((t: any) => t.DaysSinceLast >= age);
+ let filteredLanes = lanes;
+
+ if (type === "empty") {
+ let empty = lanes.filter((t: any) => t.rowType === type.toUpperCase());
- if (type != "") {
return {
sucess: true,
- message: `${filteredLanes.length} lanes that are of type ${type} and have not been cycle counted in the last ${age} days.`,
- data: filteredLanes.filter(
- (t: any) => t.rowType === type.toUpperCase()
+ message: `${empty.length} lanes that are of type ${type}.`,
+ data: empty.sort(
+ (a: any, b: any) => b.DaysSinceLast - a.DaysSinceLast
),
};
- } else {
+ }
+
+ if (type != "") {
+ let noType = lanes.filter((t: any) => t.DaysSinceLast >= age);
+
return {
- success: true,
- message: `${filteredLanes.length} lanes grabed that have not been cycle counted in the last ${age} days.`,
- data: filteredLanes,
+ sucess: true,
+ message: `${noType.length} lanes that are of type ${type} and have not been cycle counted in the last ${age} days.`,
+ data: noType
+ .filter((t: any) => t.rowType === type?.toUpperCase())
+ .sort((a: any, b: any) => b.DaysSinceLast - a.DaysSinceLast),
};
}
+
+ return {
+ success: true,
+ message: `${filteredLanes.length} lanes grabed that have not been cycle counted in the last ${age} days.`,
+ data: filteredLanes.sort(
+ (a: any, b: any) => b.DaysSinceLast - a.DaysSinceLast
+ ),
+ };
};
diff --git a/server/services/logistics/route/getCycleCountChecks.ts b/server/services/logistics/route/getCycleCountChecks.ts
index ac53ea2..6d2db34 100644
--- a/server/services/logistics/route/getCycleCountChecks.ts
+++ b/server/services/logistics/route/getCycleCountChecks.ts
@@ -37,7 +37,7 @@ app.openapi(
return c.json({ success: false, message: "Missing Data." });
}
- const check: any = body;
+ const check: any = body ?? { age: 90, type: null };
const { data: lanes, error: le } = await tryCatch(
getCycleCountCheck(check.age, check.type)
);
diff --git a/server/services/logistics/route/getCycleCountLanes.ts b/server/services/logistics/route/getCycleCountLanes.ts
new file mode 100644
index 0000000..161f7e9
--- /dev/null
+++ b/server/services/logistics/route/getCycleCountLanes.ts
@@ -0,0 +1,66 @@
+import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
+import { responses } from "../../../globalUtils/routeDefs/responses.js";
+import { tryCatch } from "../../../globalUtils/tryCatch.js";
+import { lanesToExcel } from "../controller/warehouse/cycleCountChecks/exportCycleCountData.js";
+import { format } from "date-fns";
+
+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 the lanes that need to be counted",
+ method: "get",
+ path: "/getcyclecount",
+ // request: {
+ // body: {
+ // content: {
+ // "application/json": { schema: Body },
+ // },
+ // },
+ // },
+ // description:
+ // "Provided a running number and lot number you can consume material.",
+ responses: responses(),
+ }),
+ async (c: any) => {
+ //apiHit(c, { endpoint: "api/sqlProd/close" });
+ const defaultFilename = `cycleCount-${format(
+ new Date(Date.now()),
+ "M-d-yyyy"
+ )}.xlsx`;
+ const filename = c.req.query("filename") || defaultFilename;
+ const age = c.req.query("age") || null;
+ const { data, error } = await tryCatch(lanesToExcel(age));
+
+ if (error) {
+ return c.json({
+ success: false,
+ message: "Error getting lane data.",
+ data: error,
+ });
+ }
+
+ return new Response(data, {
+ headers: {
+ "Content-Type":
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "Content-Disposition": `attachment; filename="${filename}"`,
+ },
+ });
+
+ // return c.json({
+ // success: data.success,
+ // message: data.message,
+ // data: data.data,
+ // });
+ }
+);
+export default app;