diff --git a/frontend/src/components/production/ocp/LabelLog.tsx b/frontend/src/components/production/ocp/LabelLog.tsx
index 421f82c..91bc1ee 100644
--- a/frontend/src/components/production/ocp/LabelLog.tsx
+++ b/frontend/src/components/production/ocp/LabelLog.tsx
@@ -1,5 +1,92 @@
import {LstCard} from "@/components/extendedUI/LstCard";
+import {CardHeader} from "@/components/ui/card";
+import {Skeleton} from "@/components/ui/skeleton";
+import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
+// import {useSessionStore} from "@/lib/store/sessionStore";
+// import {useSettingStore} from "@/lib/store/useSettings";
+import {useQuery} from "@tanstack/react-query";
+import {getlabels} from "@/utils/querys/production/labels";
+import {format} from "date-fns";
+const labelLogs = [
+ {key: "line", label: "Line"},
+ {key: "printerName", label: "Printer"},
+ {key: "runningNr", label: "Running #"},
+ {key: "upd_date", label: "Label date"},
+ {key: "status", label: "Label Status"},
+ //{key: "reprint", label: "Reprint"}, // removing the reprint button for now until repritning is working as intended
+];
export default function LabelLog() {
- return label logs here;
+ const {data, isError, error, isLoading} = useQuery(getlabels("4"));
+ //const {user} = useSessionStore();
+ //const {settings} = useSettingStore();
+ //const server = settings.filter((n) => n.name === "server")[0]?.value || "";
+
+ //const roles = ["admin", "manager", "operator"];
+
+ if (isError) {
+ return (
+
+
+ There was an error loading the lots
+ {JSON.stringify(error)}
+
+
+ );
+ }
+
+ return (
+
+
+
+
+ {labelLogs.map((l) => (
+ {l.label}
+ ))}
+
+
+ {isLoading ? (
+ <>
+
+ {Array(7)
+ .fill(0)
+ .map((_, i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+ >
+ ) : (
+
+ {data?.map((label: any) => (
+
+ {label.line}
+ {label.printerName}
+ {label.runningNr}
+
+ {format(label.upd_date, "M/d/yyyy hh:mm")}
+
+ {label.status}
+
+ ))}
+
+ )}
+
+
+ );
}
diff --git a/frontend/src/components/production/ocp/Lots.tsx b/frontend/src/components/production/ocp/Lots.tsx
index 6b3cc9d..2af4ac7 100644
--- a/frontend/src/components/production/ocp/Lots.tsx
+++ b/frontend/src/components/production/ocp/Lots.tsx
@@ -1,9 +1,177 @@
import {LstCard} from "@/components/extendedUI/LstCard";
+import {CardHeader} from "@/components/ui/card";
+import {Skeleton} from "@/components/ui/skeleton";
+import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
+import {useSessionStore} from "@/lib/store/sessionStore";
+import {useSettingStore} from "@/lib/store/useSettings";
+import {LotType} from "@/types/lots";
+import {getlots} from "@/utils/querys/production/lots";
+import {useQuery} from "@tanstack/react-query";
+import ManualPrint from "./ManualPrinting/ManualPrint";
+import ManualPrintForm from "./ManualPrinting/ManualPrintForm";
+let lotColumns = [
+ {
+ key: "MachineDescription",
+ label: "Machine",
+ },
+ {
+ key: "AV",
+ label: "AV",
+ },
+ {
+ key: "Alias",
+ label: "AvDescription",
+ },
+ {
+ key: "LOT",
+ label: "LotNumber",
+ },
+ {
+ key: "ProlinkLot",
+ label: "ProlinkLot",
+ },
+ {
+ key: "PlannedQTY",
+ label: "PlannedQTY",
+ },
+ {
+ key: "Produced",
+ label: "Produced",
+ },
+ {
+ key: "Remaining",
+ label: "Remaining",
+ },
+ {
+ key: "overPrinting",
+ label: "Overprinting",
+ },
+ // {
+ // key: "lastProlinkUpdate",
+ // label: "Last ProlinkCheck",
+ // },
+ // {
+ // key: "printLabel",
+ // label: "Print Label",
+ // },
+];
export default function Lots() {
+ const {data, isError, error, isLoading} = useQuery(getlots());
+ const {user} = useSessionStore();
+ const {settings} = useSettingStore();
+ const server = settings.filter((n) => n.name === "server")[0]?.value || "";
+
+ console.log(server);
+
+ const roles = ["admin", "manager", "operator"];
+
+ if (user && roles.includes(user.role)) {
+ //width = 1280;
+ const checkCol = lotColumns.some((l) => l.key === "printLabel");
+ if (!checkCol) {
+ lotColumns = [
+ ...lotColumns,
+ {
+ key: "printLabel",
+ label: "Print Label",
+ },
+ ];
+ }
+ }
+
+ if (isError) {
+ return (
+
+
+ There was an error loading the lots
+ {JSON.stringify(error)}
+
+
+ );
+ }
+
return (
- Lots
+
+
+
+ {lotColumns.map((l) => (
+ {l.label}
+ ))}
+
+
+ {isLoading ? (
+ <>
+
+ {Array(10)
+ .fill(0)
+ .map((_, i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+ >
+ ) : (
+
+ {data?.map((lot: LotType) => (
+
+ {lot.MachineLocation}
+ {lot.AV}
+ {lot.Alias}
+ {lot.LOT}
+ {lot.ProlinkLot}
+ {lot.PlannedQTY}
+ {lot.Produced}
+ {lot.Remaining}
+ {lot.overPrinting}
+ {user && roles.includes(user.role) && (
+ <>
+ {server === "usday1vms006" || server === "localhost" ? (
+ <>
+
+
+
+ >
+ ) : (
+
+
+
+ )}
+ >
+ )}
+
+ ))}
+
+ )}
+
);
}
diff --git a/frontend/src/components/production/ocp/ManualPrinting/ManualPrint.tsx b/frontend/src/components/production/ocp/ManualPrinting/ManualPrint.tsx
new file mode 100644
index 0000000..59daf69
--- /dev/null
+++ b/frontend/src/components/production/ocp/ManualPrinting/ManualPrint.tsx
@@ -0,0 +1,32 @@
+import {Button} from "@/components/ui/button";
+import {useSessionStore} from "@/lib/store/sessionStore";
+//import {useSettingStore} from "@/lib/store/useSettings";
+import {LotType} from "@/types/lots";
+import {Tag} from "lucide-react";
+import {toast} from "sonner";
+import {manualPrintLabels} from "./ManualPrintLabel";
+
+export default function ManualPrint({lot}: {lot: LotType}) {
+ const {user} = useSessionStore();
+ //const {settings} = useSettingStore();
+ //const server = settings.filter((n) => n.name === "server")[0]?.value;
+ //const serverPort = settings.filter((n) => n.name === "serverPort")[0]?.value;
+ //const serverUrl = `http://${server}:${serverPort}`;
+
+ const handlePrintLabel = async (lot: LotType) => {
+ //console.log(lot);
+
+ const labels: any = await manualPrintLabels(lot, user);
+
+ if (labels.success) {
+ toast.success(labels.message);
+ } else {
+ toast.error(labels.message);
+ }
+ };
+ return (
+
+ );
+}
diff --git a/frontend/src/components/production/ocp/ManualPrinting/ManualPrintForm.tsx b/frontend/src/components/production/ocp/ManualPrinting/ManualPrintForm.tsx
new file mode 100644
index 0000000..2336302
--- /dev/null
+++ b/frontend/src/components/production/ocp/ManualPrinting/ManualPrintForm.tsx
@@ -0,0 +1,217 @@
+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 {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import {Textarea} from "@/components/ui/textarea";
+import {useSessionStore} from "@/lib/store/sessionStore";
+import {useSettingStore} from "@/lib/store/useSettings";
+import {LotType} from "@/types/lots";
+import axios from "axios";
+import {Tag} from "lucide-react";
+import {useState} from "react";
+import {Controller, useForm} from "react-hook-form";
+import {toast} from "sonner";
+import {manualPrintLabels} from "./ManualPrintLabel";
+
+const printReason = [
+ {key: "printerIssue", label: "Printer Related"},
+ {key: "strapper", label: "Strapper Error"},
+ {key: "manualCheck", label: "20th pallet check"},
+ {key: "outOfSync", label: "Labeler Out of Sync"},
+];
+
+export default function ManualPrintForm({lot}: {lot: LotType}) {
+ const {user} = useSessionStore();
+ const token = localStorage.getItem("auth_token");
+ const {settings} = useSettingStore();
+ const [open, setOpen] = useState(false);
+ const server = settings.filter((n) => n.name === "server")[0]?.value;
+ // const serverPort = settings.filter((n) => n.name === "serverPort")[0]?.value;
+ // const serverUrl = `http://${server}:${serverPort}`;
+ const {
+ register,
+ handleSubmit,
+ //watch,
+ formState: {errors},
+ reset,
+ control,
+ } = useForm();
+
+ const handlePrintLabel = async (lot: LotType) => {
+ //console.log(lot);
+ const labels: any = await manualPrintLabels(lot, user);
+
+ if (labels.success) {
+ toast.success(labels.message);
+ } else {
+ toast.error(labels.message);
+ }
+ };
+
+ const handleManualPrintLog = async (logData: any, lot: LotType) => {
+ // toast.success(`A new label was sent to printer: ${lot.PrinterName} for line ${lot.MachineDescription} `);
+ const logdataUrl = `/api/ocp/manualLabelLog`;
+ axios
+ .post(logdataUrl, logData, {headers: {Authorization: `Bearer ${token}`}})
+ .then((d) => {
+ //console.log(d);
+ toast.success(d.data.message);
+ handlePrintLabel(lot);
+ reset();
+ })
+ .catch((e) => {
+ if (e.response.status === 500) {
+ toast.error(`Internal Server error please try again.`);
+ return {sucess: false};
+ }
+
+ if (e.response.status === 401) {
+ //console.log(e.response);
+ toast.error(`You are not authorized to do this.`);
+ return {sucess: false};
+ }
+ });
+ };
+
+ const onSubmit = (data: any) => {
+ console.log(data);
+
+ handleManualPrintLog(data, lot);
+ };
+ return (
+
+ );
+}
diff --git a/frontend/src/components/production/ocp/ManualPrinting/ManualPrintLabel.ts b/frontend/src/components/production/ocp/ManualPrinting/ManualPrintLabel.ts
new file mode 100644
index 0000000..b3f9b77
--- /dev/null
+++ b/frontend/src/components/production/ocp/ManualPrinting/ManualPrintLabel.ts
@@ -0,0 +1,44 @@
+import {LotType} from "@/types/lots";
+import axios from "axios";
+
+export const manualPrintLabels = async (lot: LotType, user: any) => {
+ //console.log(lot);
+ const labelUrl = `/ocp/manualPrintAndFollow`;
+
+ try {
+ const res = await axios.post(
+ labelUrl,
+ {line: lot.MachineLocation, printerName: lot.PrinterName},
+ {headers: {Authorization: `Basic ${user?.prod}`}}
+ );
+
+ if (res.data.success) {
+ return {
+ success: true,
+ message: `A new label was printed for ${lot.MachineDescription} to printer: ${lot.PrinterName}`,
+ };
+ } else {
+ return {
+ success: true,
+ message: `Line ${lot.MachineDescription} encountered an error printing labels: ${res.data.message}`,
+ };
+ }
+ } catch (error: any) {
+ if (error.response.status === 500) {
+ //toast.error(`Internal Server error please try again.`);
+ return {
+ success: false,
+ message: `Internal Server error please try again.`,
+ };
+ }
+
+ if (error.response.status === 401) {
+ //console.log(e.response);
+ //toast.error(`You are not authorized to do this.`);
+ return {
+ success: false,
+ message: `You are not authorized to do this.`,
+ };
+ }
+ }
+};
diff --git a/frontend/src/components/providers/Providers.tsx b/frontend/src/components/providers/Providers.tsx
index fffefc5..0bd34a5 100644
--- a/frontend/src/components/providers/Providers.tsx
+++ b/frontend/src/components/providers/Providers.tsx
@@ -1,16 +1,19 @@
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
import {useModuleStore} from "../../lib/store/useModuleStore";
import {useEffect} from "react";
+import {useSettingStore} from "@/lib/store/useSettings";
//import {useGetUserRoles} from "@/lib/store/useGetRoles";
const queryClient = new QueryClient();
export const SessionProvider = ({children}: {children: React.ReactNode}) => {
const {fetchModules} = useModuleStore();
+ const {fetchSettings} = useSettingStore();
//const {fetchUserRoles} = useGetUserRoles();
useEffect(() => {
fetchModules();
+ fetchSettings();
//fetchUserRoles();
}, []);
return {children};
diff --git a/frontend/src/components/ui/select.tsx b/frontend/src/components/ui/select.tsx
new file mode 100644
index 0000000..51f466e
--- /dev/null
+++ b/frontend/src/components/ui/select.tsx
@@ -0,0 +1,183 @@
+import * as React from "react"
+import * as SelectPrimitive from "@radix-ui/react-select"
+import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function Select({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectGroup({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectValue({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectTrigger({
+ className,
+ size = "default",
+ children,
+ ...props
+}: React.ComponentProps & {
+ size?: "sm" | "default"
+}) {
+ return (
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectContent({
+ className,
+ children,
+ position = "popper",
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectLabel({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectItem({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function SelectSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectScrollUpButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function SelectScrollDownButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+export {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectScrollDownButton,
+ SelectScrollUpButton,
+ SelectSeparator,
+ SelectTrigger,
+ SelectValue,
+}
diff --git a/frontend/src/components/ui/textarea.tsx b/frontend/src/components/ui/textarea.tsx
new file mode 100644
index 0000000..7f21b5e
--- /dev/null
+++ b/frontend/src/components/ui/textarea.tsx
@@ -0,0 +1,18 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
+ return (
+
+ )
+}
+
+export { Textarea }
diff --git a/frontend/src/routes/ocp/lots.tsx b/frontend/src/routes/ocp/lots.tsx
deleted file mode 100644
index 4011f02..0000000
--- a/frontend/src/routes/ocp/lots.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { createFileRoute } from '@tanstack/react-router'
-
-export const Route = createFileRoute('/ocp/lots')({
- component: RouteComponent,
-})
-
-function RouteComponent() {
- return Hello "/ocp/lots"!
-}
diff --git a/frontend/src/types/lots.ts b/frontend/src/types/lots.ts
new file mode 100644
index 0000000..15d6f21
--- /dev/null
+++ b/frontend/src/types/lots.ts
@@ -0,0 +1,19 @@
+export type LotType = {
+ AV: number;
+ Alias: string;
+ LOT: number;
+ LabelOnlineID: number;
+ MachineDescription: string;
+ MachineID: number;
+ MachineLocation: number;
+ PlannedQTY: number;
+ PrinterName: string;
+ Produced: number;
+ ProlinkLot: number;
+ Remaining: number;
+ machineID: number;
+ overPrinting: string;
+ pallerCopies: number;
+ palletLabel: string;
+ printerID: number;
+};
diff --git a/frontend/src/utils/querys/production/labels.tsx b/frontend/src/utils/querys/production/labels.tsx
new file mode 100644
index 0000000..b93e2d3
--- /dev/null
+++ b/frontend/src/utils/querys/production/labels.tsx
@@ -0,0 +1,20 @@
+import {queryOptions} from "@tanstack/react-query";
+import axios from "axios";
+
+export function getlabels(hours: string) {
+ return queryOptions({
+ queryKey: ["labels"],
+ queryFn: () => fetchSettings(hours),
+
+ staleTime: 1000,
+ refetchInterval: 2500,
+ refetchOnWindowFocus: true,
+ });
+}
+
+const fetchSettings = async (hours: string) => {
+ const {data} = await axios.get(`/api/v1/ocp/labels?hours=${hours}`);
+ // 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/production/lots.tsx b/frontend/src/utils/querys/production/lots.tsx
new file mode 100644
index 0000000..1b3adbb
--- /dev/null
+++ b/frontend/src/utils/querys/production/lots.tsx
@@ -0,0 +1,21 @@
+import {queryOptions} from "@tanstack/react-query";
+import axios from "axios";
+
+export function getlots() {
+ return queryOptions({
+ queryKey: ["lots"],
+ queryFn: () => fetchSettings(),
+
+ staleTime: 10 * 1000,
+ refetchInterval: 10 * 1000,
+ refetchOnWindowFocus: true,
+ });
+}
+
+const fetchSettings = async () => {
+ const {data} = await axios.get("/api/v1/ocp/lots");
+ // if we are not localhost ignore the devDir setting.
+ //const url: string = window.location.host.split(":")[0];
+ let lotData = data.data;
+ return lotData;
+};