Compare commits

...

37 Commits

Author SHA1 Message Date
e597968777 feat(settings): more seed settings 2025-03-19 17:18:13 -05:00
bbd7a17144 feat(servers): added dayton in 2025-03-19 17:17:54 -05:00
5945ace9f2 refactor(settings): removed the need to login to get the settings 2025-03-19 17:17:36 -05:00
316b27e3e0 refactor(settings): used the common response function created 2025-03-19 17:17:18 -05:00
7165c959b9 feat(ocp): added in service plus manual print log 2025-03-19 17:16:39 -05:00
ae7e3fd54e feat(ocme): added in ocme service so we can utlize 2 ports 2025-03-19 17:16:14 -05:00
7ec5c5beb0 feat(logger): logger service created with its endpoints 2025-03-19 17:15:33 -05:00
c9aa41ab00 refactor(login): removed roles from the login to shrink the jwt 2025-03-19 17:15:02 -05:00
4696835c65 feat(installer): added a check for lstv2 already installed 2025-03-19 17:14:33 -05:00
2d3f308877 feat(server): ocpService and loggerService added 2025-03-19 17:13:52 -05:00
3d083986ae feat(admincheck): this check is so we dont use stuff on the wrong servers 2025-03-19 17:13:21 -05:00
92b47f03d9 style(types): added in prod? so we dont get type errors 2025-03-19 17:12:51 -05:00
3b8f18093e refactor(stores): added in axios 2025-03-19 17:12:27 -05:00
1cd1d3a3e9 feat(settings): added in setting store 2025-03-19 17:12:09 -05:00
8324fffeb6 test(ocp): more work on the dashboard 2025-03-19 17:11:00 -05:00
354f3260a5 refactor(consume materail): get token from localstorage as the store isnt wokring properly 2025-03-19 17:09:57 -05:00
ab5af4deac refactor(production): changes ocp to viewwer 2025-03-19 17:09:16 -05:00
7a15b160ac refactor(auth): moved prod back to server as we run 2 instances during migration 2025-03-19 17:08:51 -05:00
ca0ba7fe59 refactor(settings): refactored the admincheck so we can reuse it 2025-03-19 17:08:22 -05:00
0914b53341 feat(db): logs, manualprints added 2025-03-19 17:07:37 -05:00
34b80cf236 chore: bump build number to 43 2025-03-19 16:18:04 -05:00
196ea00972 chore: bump build number to 42 2025-03-19 13:30:10 -05:00
807a4ca699 chore: bump build number to 41 2025-03-19 11:32:58 -05:00
d98a659262 chore: bump build number to 40 2025-03-19 11:23:35 -05:00
6dd5f4b61f chore: bump build number to 39 2025-03-19 11:22:04 -05:00
751b9d5701 chore: bump build number to 38 2025-03-19 08:47:27 -05:00
b0634d9427 chore: bump build number to 37 2025-03-19 08:41:27 -05:00
8a143fbb19 chore: bump build number to 36 2025-03-19 08:23:56 -05:00
8b72a1b47e chore: bump build number to 35 2025-03-19 08:09:14 -05:00
f4c44fb02b chore: bump build number to 34 2025-03-18 22:29:52 -05:00
03aa7e5aee chore: bump build number to 33 2025-03-18 22:07:51 -05:00
f035e6f14a chore: bump build number to 32 2025-03-18 22:01:10 -05:00
227e2aa00c chore: bump build number to 31 2025-03-18 21:53:44 -05:00
4a48dd2bb5 chore: bump build number to 30 2025-03-18 18:37:43 -05:00
9796947db5 chore: bump build number to 29 2025-03-18 18:03:39 -05:00
1e02d4fa4f chore: bump build number to 28 2025-03-18 17:58:04 -05:00
26ea8d5e89 chore: bump build number to 27 2025-03-18 16:46:08 -05:00
55 changed files with 3731 additions and 161 deletions

1
.gitignore vendored
View File

@@ -148,3 +148,4 @@ dist
.yarn/install-state.gz .yarn/install-state.gz
.pnp.* .pnp.*
backend-0.1.3.zip

View File

@@ -0,0 +1,2 @@
ALTER TABLE "logs" ADD COLUMN "checked" boolean DEFAULT false;--> statement-breakpoint
ALTER TABLE "logs" ADD COLUMN "checkedAt" timestamp;

View File

@@ -0,0 +1,9 @@
CREATE TABLE "manualPrinting" (
"print_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"line" integer,
"printReason" text NOT NULL,
"initials" text NOT NULL,
"additionalComments" text NOT NULL,
"add_date" timestamp DEFAULT now(),
"add_user" text
);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -162,6 +162,20 @@
"when": 1742156466912, "when": 1742156466912,
"tag": "0022_amused_true_believers", "tag": "0022_amused_true_believers",
"breakpoints": true "breakpoints": true
},
{
"idx": 23,
"version": "7",
"when": 1742346003832,
"tag": "0023_wealthy_marvel_boy",
"breakpoints": true
},
{
"idx": 24,
"version": "7",
"when": 1742408812383,
"tag": "0024_curved_venom",
"breakpoints": true
} }
] ]
} }

View File

@@ -10,6 +10,8 @@ export const logs = pgTable(
username: text("username").default("LST_Serivce"), username: text("username").default("LST_Serivce"),
service: text("service").notNull().default("system"), service: text("service").notNull().default("system"),
message: text("message").notNull(), message: text("message").notNull(),
checked: boolean("checked").default(false),
checkedAt: timestamp("checkedAt"),
created_at: timestamp("add_Date").defaultNow(), created_at: timestamp("add_Date").defaultNow(),
}, },
(table) => [ (table) => [

View File

@@ -0,0 +1,20 @@
import {text, pgTable, timestamp, uuid, integer} from "drizzle-orm/pg-core";
import {createInsertSchema, createSelectSchema} from "drizzle-zod";
import {z} from "zod";
export const manualPrinting = pgTable("manualPrinting", {
print_id: uuid("print_id").defaultRandom().primaryKey(),
line: integer("line"),
printReason: text("printReason").notNull(),
initials: text("initials").notNull(),
additionalComments: text("additionalComments").notNull(),
add_date: timestamp("add_date").defaultNow(),
add_user: text("add_user"),
});
// Schema for inserting a user - can be used to validate API requests
// export const insertRolesSchema = createInsertSchema(roles, {
// name: z.string().min(3, {message: "Role name must be more than 3 letters"}),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectRolesSchema = createSelectSchema(manualPrinting);

View File

@@ -16,6 +16,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6",
"@radix-ui/react-label": "^2.1.2", "@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-popover": "^1.1.6", "@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-tabs": "^1.1.3",
@@ -1152,6 +1153,12 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@radix-ui/number": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz",
"integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==",
"license": "MIT"
},
"node_modules/@radix-ui/primitive": { "node_modules/@radix-ui/primitive": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
@@ -1722,6 +1729,49 @@
} }
} }
}, },
"node_modules/@radix-ui/react-select": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz",
"integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==",
"license": "MIT",
"dependencies": {
"@radix-ui/number": "1.1.0",
"@radix-ui/primitive": "1.1.1",
"@radix-ui/react-collection": "1.1.2",
"@radix-ui/react-compose-refs": "1.1.1",
"@radix-ui/react-context": "1.1.1",
"@radix-ui/react-direction": "1.1.0",
"@radix-ui/react-dismissable-layer": "1.1.5",
"@radix-ui/react-focus-guards": "1.1.1",
"@radix-ui/react-focus-scope": "1.1.2",
"@radix-ui/react-id": "1.1.0",
"@radix-ui/react-popper": "1.2.2",
"@radix-ui/react-portal": "1.1.4",
"@radix-ui/react-primitive": "2.0.2",
"@radix-ui/react-slot": "1.1.2",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0",
"@radix-ui/react-use-previous": "1.1.0",
"@radix-ui/react-visually-hidden": "1.1.2",
"aria-hidden": "^1.2.4",
"react-remove-scroll": "^2.6.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-separator": { "node_modules/@radix-ui/react-separator": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.2.tgz",

View File

@@ -20,6 +20,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6",
"@radix-ui/react-label": "^2.1.2", "@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-popover": "^1.1.6", "@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-tabs": "^1.1.3",

View File

@@ -9,6 +9,7 @@ import {useQuery} from "@tanstack/react-query";
import {useRouter} from "@tanstack/react-router"; import {useRouter} from "@tanstack/react-router";
import {format} from "date-fns"; import {format} from "date-fns";
import UpdateServer from "./UpdateServer"; import UpdateServer from "./UpdateServer";
import {adminUrlCheck} from "@/utils/adminUrlCheck";
export type Servers = { export type Servers = {
server_id?: string; server_id?: string;
@@ -85,9 +86,7 @@ export default function ServerPage() {
{format(server.lastUpdated, "MM/dd/yyyy hh:mm")} {format(server.lastUpdated, "MM/dd/yyyy hh:mm")}
</TableCell> </TableCell>
<TableCell className="font-medium"> <TableCell className="font-medium">
{window.location.host.split(":")[0] === "localhost" && ( {adminUrlCheck() && <UpdateServer server={server} token={token as string} />}
<UpdateServer server={server} token={token as string} />
)}
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))}

View File

@@ -37,7 +37,7 @@ export default function SettingsPage() {
} }
return ( return (
<LstCard className="m-2 flex place-content-center w-dvh"> <LstCard className="m-2 flex place-content-center w-fit">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>

View File

@@ -61,8 +61,10 @@ const LoginForm = () => {
// Store token in localStorage // Store token in localStorage
// localStorage.setItem("auth_token", data.data.token); // localStorage.setItem("auth_token", data.data.token);
const prod = btoa(`${value.username.toLowerCase()}:${value.password}`);
const prodUser = {...data.user, prod: prod};
setSession(data.user, data.token); setSession(prodUser, data.token);
toast.success(`You are logged in as ${data.user.username}`); toast.success(`You are logged in as ${data.user.username}`);
router.navigate({to: "/"}); router.navigate({to: "/"});
} catch (err) { } catch (err) {

View File

@@ -15,7 +15,7 @@ const items = [
title: "One Click Print", title: "One Click Print",
url: "/ocp", url: "/ocp",
icon: Printer, icon: Printer,
role: ["systemAdmin"], role: ["viwer"],
module: "ocp", module: "ocp",
active: true, active: true,
}, },

View File

@@ -3,6 +3,7 @@ import {Button} from "@/components/ui/button";
import {CardHeader} from "@/components/ui/card"; import {CardHeader} from "@/components/ui/card";
import {Input} from "@/components/ui/input"; import {Input} from "@/components/ui/input";
import {Label} from "@/components/ui/label"; import {Label} from "@/components/ui/label";
import {useSessionStore} from "@/lib/store/sessionStore";
import axios from "axios"; import axios from "axios";
import {useState} from "react"; import {useState} from "react";
@@ -12,7 +13,7 @@ import {toast} from "sonner";
export default function ConsumeMaterial() { export default function ConsumeMaterial() {
const {register: register1, handleSubmit: handleSubmit1, reset} = useForm(); const {register: register1, handleSubmit: handleSubmit1, reset} = useForm();
const [submitting, setSubmitting] = useState(false); const [submitting, setSubmitting] = useState(false);
const token = localStorage.getItem("auth_token"); const {token} = useSessionStore();
const handleConsume = async (data: any) => { const handleConsume = async (data: any) => {
setSubmitting(!submitting); setSubmitting(!submitting);

View File

@@ -1,5 +1,92 @@
import {LstCard} from "@/components/extendedUI/LstCard"; 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() { export default function LabelLog() {
return <LstCard className="m-2 p-2"> label logs here</LstCard>; 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 (
<div>
<LstCard>
<CardHeader>There was an error loading the lots</CardHeader>
{JSON.stringify(error)}
</LstCard>
</div>
);
}
return (
<LstCard className="m-2 p-2 min-h-2/5">
<Table>
<TableHeader>
<TableRow>
{labelLogs.map((l) => (
<TableHead key={l.key}>{l.label}</TableHead>
))}
</TableRow>
</TableHeader>
{isLoading ? (
<>
<TableBody>
{Array(7)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
</TableRow>
))}
</TableBody>
</>
) : (
<TableBody>
{data?.map((label: any) => (
<TableRow key={label.runningNr}>
<TableCell className="font-medium">{label.line}</TableCell>
<TableCell className="font-medium">{label.printerName}</TableCell>
<TableCell className="font-medium">{label.runningNr}</TableCell>
<TableCell className="font-medium">
{format(label.upd_date, "M/d/yyyy hh:mm")}
</TableCell>
<TableCell className="font-medium">{label.status}</TableCell>
</TableRow>
))}
</TableBody>
)}
</Table>
</LstCard>
);
} }

View File

@@ -1,9 +1,177 @@
import {LstCard} from "@/components/extendedUI/LstCard"; 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() { 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 (
<div>
<LstCard>
<CardHeader>There was an error loading the lots</CardHeader>
{JSON.stringify(error)}
</LstCard>
</div>
);
}
return ( return (
<LstCard className="m-2 p-2 min-h-2/5"> <LstCard className="m-2 p-2 min-h-2/5">
<h1>Lots</h1> <Table>
<TableHeader>
<TableRow>
{lotColumns.map((l) => (
<TableHead key={l.key}>{l.label}</TableHead>
))}
</TableRow>
</TableHeader>
{isLoading ? (
<>
<TableBody>
{Array(10)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
</TableRow>
))}
</TableBody>
</>
) : (
<TableBody>
{data?.map((lot: LotType) => (
<TableRow key={lot.LabelOnlineID}>
<TableCell className="font-medium">{lot.MachineLocation}</TableCell>
<TableCell className="font-medium">{lot.AV}</TableCell>
<TableCell className="font-medium">{lot.Alias}</TableCell>
<TableCell className="font-medium">{lot.LOT}</TableCell>
<TableCell className="font-medium">{lot.ProlinkLot}</TableCell>
<TableCell className="font-medium">{lot.PlannedQTY}</TableCell>
<TableCell className="font-medium">{lot.Produced}</TableCell>
<TableCell className="font-medium">{lot.Remaining}</TableCell>
<TableCell className="font-medium">{lot.overPrinting}</TableCell>
{user && roles.includes(user.role) && (
<>
{server === "usday1vms006" || server === "localhost" ? (
<>
<TableCell className="flex justify-center">
<ManualPrintForm lot={lot} />
</TableCell>
</>
) : (
<TableCell className="flex justify-center">
<ManualPrint lot={lot} />
</TableCell>
)}
</>
)}
</TableRow>
))}
</TableBody>
)}
</Table>
</LstCard> </LstCard>
); );
} }

View File

@@ -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 (
<Button variant="outline" size="icon" onClick={() => handlePrintLabel(lot)}>
<Tag className="h-[16px] w-[16px]" />
</Button>
);
}

View File

@@ -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 (
<Dialog
open={open}
onOpenChange={(isOpen) => {
if (!open) {
reset();
}
setOpen(isOpen);
// toast.message("Model was something", {
// description: isOpen ? "Modal is open" : "Modal is closed",
// });
}}
>
<DialogTrigger asChild>
<Button variant="outline" size="icon">
<Tag className="h-[16px] w-[16px]" />
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>
Make changes to your profile here. Click save when you're done.
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit(onSubmit)}>
<p>
To manually print a label you must complete all the required fields below.
<br />
If you clicked this in error just click close
</p>
<hr className="mt-2 mb-2" />
{server == "usday1vms006" ? (
<Controller
control={control}
name="printReason"
defaultValue={""}
render={({
field: {onChange},
fieldState: {},
//formState,
}) => (
<Select onValueChange={onChange}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select Reason" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Print Reasons</SelectLabel>
{printReason.map((printReason: any) => (
<SelectItem value={printReason.key}>{printReason.label}</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
)}
/>
) : (
<div>
<Label htmlFor="printRason" className="m-1">
Why are you manually printing?
</Label>
<Input
type="text"
className={errors.printReason ? "border-red-500" : ""}
aria-invalid={!!errors.printReason}
{...register("printReason", {
required: true,
minLength: {
value: 5,
message: "To short of a reason please try again!",
},
})}
/>
</div>
)}
<div>
<Label htmlFor="line" className="m-1">
"What is the line number you are printing?"
</Label>
<Input
//variant="underlined"
type="number"
className={errors.line ? "border-red-500" : ""}
aria-invalid={!!errors.line}
{...register("line", {required: true})}
/>
</div>
<div>
<Label htmlFor="initials" className="m-1">
Enter intials
</Label>
<Input
//variant="underlined"
//label="Enter intials"
{...register("initials", {required: true})}
/>
</div>
<Textarea
//label="Comments"
placeholder="add more info as needed."
{...register("additionalComments")}
/>
<DialogFooter>
<Button color="danger" variant="default" onClick={() => setOpen(!open)}>
Close
</Button>
<Button color="primary" type="submit">
Print
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}

View File

@@ -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.`,
};
}
}
};

View File

@@ -1,16 +1,19 @@
import {QueryClient, QueryClientProvider} from "@tanstack/react-query"; import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
import {useModuleStore} from "../../lib/store/useModuleStore"; import {useModuleStore} from "../../lib/store/useModuleStore";
import {useEffect} from "react"; import {useEffect} from "react";
import {useSettingStore} from "@/lib/store/useSettings";
//import {useGetUserRoles} from "@/lib/store/useGetRoles"; //import {useGetUserRoles} from "@/lib/store/useGetRoles";
const queryClient = new QueryClient(); const queryClient = new QueryClient();
export const SessionProvider = ({children}: {children: React.ReactNode}) => { export const SessionProvider = ({children}: {children: React.ReactNode}) => {
const {fetchModules} = useModuleStore(); const {fetchModules} = useModuleStore();
const {fetchSettings} = useSettingStore();
//const {fetchUserRoles} = useGetUserRoles(); //const {fetchUserRoles} = useGetUserRoles();
useEffect(() => { useEffect(() => {
fetchModules(); fetchModules();
fetchSettings();
//fetchUserRoles(); //fetchUserRoles();
}, []); }, []);
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>; return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;

View File

@@ -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<typeof SelectPrimitive.Root>) {
return <SelectPrimitive.Root data-slot="select" {...props} />
}
function SelectGroup({
...props
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
return <SelectPrimitive.Group data-slot="select-group" {...props} />
}
function SelectValue({
...props
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
return <SelectPrimitive.Value data-slot="select-value" {...props} />
}
function SelectTrigger({
className,
size = "default",
children,
...props
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
size?: "sm" | "default"
}) {
return (
<SelectPrimitive.Trigger
data-slot="select-trigger"
data-size={size}
className={cn(
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDownIcon className="size-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
)
}
function SelectContent({
className,
children,
position = "popper",
...props
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
return (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
data-slot="select-content"
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
)
}
function SelectLabel({
className,
...props
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
return (
<SelectPrimitive.Label
data-slot="select-label"
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
{...props}
/>
)
}
function SelectItem({
className,
children,
...props
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
return (
<SelectPrimitive.Item
data-slot="select-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
className
)}
{...props}
>
<span className="absolute right-2 flex size-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<CheckIcon className="size-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
)
}
function SelectSeparator({
className,
...props
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
return (
<SelectPrimitive.Separator
data-slot="select-separator"
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
{...props}
/>
)
}
function SelectScrollUpButton({
className,
...props
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
return (
<SelectPrimitive.ScrollUpButton
data-slot="select-scroll-up-button"
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUpIcon className="size-4" />
</SelectPrimitive.ScrollUpButton>
)
}
function SelectScrollDownButton({
className,
...props
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
return (
<SelectPrimitive.ScrollDownButton
data-slot="select-scroll-down-button"
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDownIcon className="size-4" />
</SelectPrimitive.ScrollDownButton>
)
}
export {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
SelectTrigger,
SelectValue,
}

View File

@@ -0,0 +1,18 @@
import * as React from "react"
import { cn } from "@/lib/utils"
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
return (
<textarea
data-slot="textarea"
className={cn(
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
{...props}
/>
)
}
export { Textarea }

View File

@@ -1,4 +1,5 @@
import {User} from "@/types/users"; import {User} from "@/types/users";
import axios from "axios";
import {create} from "zustand"; import {create} from "zustand";
export type SessionState = { export type SessionState = {
@@ -16,9 +17,14 @@ export const useSessionStore = create<SessionState>((set) => {
user: null, // User is NOT stored in localStorage user: null, // User is NOT stored in localStorage
token: storedToken || null, token: storedToken || null,
setSession: (user, token) => { setSession: async (user: any, token) => {
if (token) { if (token) {
localStorage.setItem("auth_token", token); localStorage.setItem("auth_token", token);
const response = await axios.get("/api/auth/getuseraccess", {
headers: {Authorization: `Bearer ${token}`},
});
const data = response.data; //await response.json();
user = {...user, roles: data.data};
} else { } else {
localStorage.removeItem("auth_token"); localStorage.removeItem("auth_token");
} }

View File

@@ -1,6 +1,7 @@
import {create} from "zustand"; import {create} from "zustand";
import {useSessionStore} from "./sessionStore"; import {useSessionStore} from "./sessionStore";
import {Modules} from "@/types/modules"; import {Modules} from "@/types/modules";
import axios from "axios";
interface SettingState { interface SettingState {
userRoles: Modules[]; userRoles: Modules[];
@@ -19,15 +20,8 @@ export const useGetUserRoles = create<SettingState>()((set) => ({
try { try {
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`); //const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
const {token} = useSessionStore(); const {token} = useSessionStore();
const response = await fetch(`/api/auth/getuseraccess`, { const response = await axios.get("/api/auth/getuseraccess", {headers: {Authorization: `Bearer ${token}`}});
method: "GET", const data: FetchModulesResponse = response.data; //await response.json();
headers: {
"Content-Type": "application/json",
Authentication: `Beaer ${token}`,
// You can add other headers here if necessary
},
});
const data: FetchModulesResponse = await response.json();
//console.log(data); //console.log(data);
set({userRoles: data.data}); set({userRoles: data.data});
} catch (error) { } catch (error) {

View File

@@ -1,4 +1,5 @@
import {Modules} from "@/types/modules"; import {Modules} from "@/types/modules";
import axios from "axios";
import {create} from "zustand"; import {create} from "zustand";
interface SettingState { interface SettingState {
@@ -17,14 +18,8 @@ export const useModuleStore = create<SettingState>()((set) => ({
fetchModules: async () => { fetchModules: async () => {
try { try {
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`); //const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
const response = await fetch(`/api/server/modules`, { const response = await axios.get(`/api/server/modules`, {});
method: "GET", const data: FetchModulesResponse = response.data; //await response.json();
headers: {
"Content-Type": "application/json",
// You can add other headers here if necessary
},
});
const data: FetchModulesResponse = await response.json();
//console.log(data); //console.log(data);
set({modules: data.data}); set({modules: data.data});
} catch (error) { } catch (error) {

View File

@@ -0,0 +1,29 @@
import axios from "axios";
import {create} from "zustand";
interface SettingState {
settings: any[];
fetchSettings: () => Promise<void>;
setSettings: (settings: any[]) => void;
}
interface FetchModulesResponse {
data: any[];
}
export const useSettingStore = create<SettingState>()((set) => ({
settings: [],
setSettings: (settings) => set({settings}),
fetchSettings: async () => {
try {
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
const response = await axios.get(`/api/server/settings`, {});
const data: FetchModulesResponse = response.data; //await response.json();
//console.log(data);
set({settings: data.data});
} catch (error) {
console.error("Failed to fetch settings:", error);
set({settings: []});
}
},
}));

View File

@@ -18,7 +18,6 @@ import { Route as AuthImport } from './routes/_auth'
import { Route as AdminImport } from './routes/_admin' import { Route as AdminImport } from './routes/_admin'
import { Route as IndexImport } from './routes/index' import { Route as IndexImport } from './routes/index'
import { Route as OcpIndexImport } from './routes/ocp/index' import { Route as OcpIndexImport } from './routes/ocp/index'
import { Route as OcpLotsImport } from './routes/ocp/lots'
import { Route as EomEomImport } from './routes/_eom/eom' import { Route as EomEomImport } from './routes/_eom/eom'
import { Route as AuthProfileImport } from './routes/_auth/profile' import { Route as AuthProfileImport } from './routes/_auth/profile'
import { Route as AdminSettingsImport } from './routes/_admin/settings' import { Route as AdminSettingsImport } from './routes/_admin/settings'
@@ -70,12 +69,6 @@ const OcpIndexRoute = OcpIndexImport.update({
getParentRoute: () => rootRoute, getParentRoute: () => rootRoute,
} as any) } as any)
const OcpLotsRoute = OcpLotsImport.update({
id: '/ocp/lots',
path: '/ocp/lots',
getParentRoute: () => rootRoute,
} as any)
const EomEomRoute = EomEomImport.update({ const EomEomRoute = EomEomImport.update({
id: '/eom', id: '/eom',
path: '/eom', path: '/eom',
@@ -214,13 +207,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof EomEomImport preLoaderRoute: typeof EomEomImport
parentRoute: typeof EomImport parentRoute: typeof EomImport
} }
'/ocp/lots': {
id: '/ocp/lots'
path: '/ocp/lots'
fullPath: '/ocp/lots'
preLoaderRoute: typeof OcpLotsImport
parentRoute: typeof rootRoute
}
'/ocp/': { '/ocp/': {
id: '/ocp/' id: '/ocp/'
path: '/ocp' path: '/ocp'
@@ -307,7 +293,6 @@ export interface FileRoutesByFullPath {
'/settings': typeof AdminSettingsRoute '/settings': typeof AdminSettingsRoute
'/profile': typeof AuthProfileRoute '/profile': typeof AuthProfileRoute
'/eom': typeof EomEomRoute '/eom': typeof EomEomRoute
'/ocp/lots': typeof OcpLotsRoute
'/ocp': typeof OcpIndexRoute '/ocp': typeof OcpIndexRoute
'/article/$av': typeof EomArticleAvRoute '/article/$av': typeof EomArticleAvRoute
'/materialHelper': typeof logisticsMaterialHelperIndexRoute '/materialHelper': typeof logisticsMaterialHelperIndexRoute
@@ -325,7 +310,6 @@ export interface FileRoutesByTo {
'/settings': typeof AdminSettingsRoute '/settings': typeof AdminSettingsRoute
'/profile': typeof AuthProfileRoute '/profile': typeof AuthProfileRoute
'/eom': typeof EomEomRoute '/eom': typeof EomEomRoute
'/ocp/lots': typeof OcpLotsRoute
'/ocp': typeof OcpIndexRoute '/ocp': typeof OcpIndexRoute
'/article/$av': typeof EomArticleAvRoute '/article/$av': typeof EomArticleAvRoute
'/materialHelper': typeof logisticsMaterialHelperIndexRoute '/materialHelper': typeof logisticsMaterialHelperIndexRoute
@@ -346,7 +330,6 @@ export interface FileRoutesById {
'/_admin/settings': typeof AdminSettingsRoute '/_admin/settings': typeof AdminSettingsRoute
'/_auth/profile': typeof AuthProfileRoute '/_auth/profile': typeof AuthProfileRoute
'/_eom/eom': typeof EomEomRoute '/_eom/eom': typeof EomEomRoute
'/ocp/lots': typeof OcpLotsRoute
'/ocp/': typeof OcpIndexRoute '/ocp/': typeof OcpIndexRoute
'/_eom/article/$av': typeof EomArticleAvRoute '/_eom/article/$av': typeof EomArticleAvRoute
'/(logistics)/materialHelper/': typeof logisticsMaterialHelperIndexRoute '/(logistics)/materialHelper/': typeof logisticsMaterialHelperIndexRoute
@@ -366,7 +349,6 @@ export interface FileRouteTypes {
| '/settings' | '/settings'
| '/profile' | '/profile'
| '/eom' | '/eom'
| '/ocp/lots'
| '/ocp' | '/ocp'
| '/article/$av' | '/article/$av'
| '/materialHelper' | '/materialHelper'
@@ -383,7 +365,6 @@ export interface FileRouteTypes {
| '/settings' | '/settings'
| '/profile' | '/profile'
| '/eom' | '/eom'
| '/ocp/lots'
| '/ocp' | '/ocp'
| '/article/$av' | '/article/$av'
| '/materialHelper' | '/materialHelper'
@@ -402,7 +383,6 @@ export interface FileRouteTypes {
| '/_admin/settings' | '/_admin/settings'
| '/_auth/profile' | '/_auth/profile'
| '/_eom/eom' | '/_eom/eom'
| '/ocp/lots'
| '/ocp/' | '/ocp/'
| '/_eom/article/$av' | '/_eom/article/$av'
| '/(logistics)/materialHelper/' | '/(logistics)/materialHelper/'
@@ -418,7 +398,6 @@ export interface RootRouteChildren {
EomRoute: typeof EomRouteWithChildren EomRoute: typeof EomRouteWithChildren
AboutRoute: typeof AboutRoute AboutRoute: typeof AboutRoute
LoginRoute: typeof LoginRoute LoginRoute: typeof LoginRoute
OcpLotsRoute: typeof OcpLotsRoute
OcpIndexRoute: typeof OcpIndexRoute OcpIndexRoute: typeof OcpIndexRoute
logisticsMaterialHelperIndexRoute: typeof logisticsMaterialHelperIndexRoute logisticsMaterialHelperIndexRoute: typeof logisticsMaterialHelperIndexRoute
logisticsMaterialHelperConsumptionIndexRoute: typeof logisticsMaterialHelperConsumptionIndexRoute logisticsMaterialHelperConsumptionIndexRoute: typeof logisticsMaterialHelperConsumptionIndexRoute
@@ -432,7 +411,6 @@ const rootRouteChildren: RootRouteChildren = {
EomRoute: EomRouteWithChildren, EomRoute: EomRouteWithChildren,
AboutRoute: AboutRoute, AboutRoute: AboutRoute,
LoginRoute: LoginRoute, LoginRoute: LoginRoute,
OcpLotsRoute: OcpLotsRoute,
OcpIndexRoute: OcpIndexRoute, OcpIndexRoute: OcpIndexRoute,
logisticsMaterialHelperIndexRoute: logisticsMaterialHelperIndexRoute, logisticsMaterialHelperIndexRoute: logisticsMaterialHelperIndexRoute,
logisticsMaterialHelperConsumptionIndexRoute: logisticsMaterialHelperConsumptionIndexRoute:
@@ -457,7 +435,6 @@ export const routeTree = rootRoute
"/_eom", "/_eom",
"/about", "/about",
"/login", "/login",
"/ocp/lots",
"/ocp/", "/ocp/",
"/(logistics)/materialHelper/", "/(logistics)/materialHelper/",
"/(logistics)/materialHelper/consumption/", "/(logistics)/materialHelper/consumption/",
@@ -514,9 +491,6 @@ export const routeTree = rootRoute
"filePath": "_eom/eom.tsx", "filePath": "_eom/eom.tsx",
"parent": "/_eom" "parent": "/_eom"
}, },
"/ocp/lots": {
"filePath": "ocp/lots.tsx"
},
"/ocp/": { "/ocp/": {
"filePath": "ocp/index.tsx" "filePath": "ocp/index.tsx"
}, },

View File

@@ -1,9 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/ocp/lots')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/ocp/lots"!</div>
}

View File

@@ -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;
};

View File

@@ -6,4 +6,5 @@ export type User = {
username: string; username: string;
roles: Roles[]; roles: Roles[];
role: string; role: string;
prod?: string;
}; };

View File

@@ -0,0 +1,8 @@
export const adminUrlCheck = () => {
const host = window.location.host.split(":")[0];
const okHost = ["localhost", "usmcd1vms036"];
if (okHost.includes(host)) {
return true;
}
return false;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -73,7 +73,7 @@
} }
}, },
"admConfig": { "admConfig": {
"build": 26, "build": 43,
"oldBuild": "backend-0.1.2.zip" "oldBuild": "backend-0.1.3.zip"
} }
} }

View File

@@ -1,11 +1,11 @@
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
import {serve} from "@hono/node-server"; import {serve} from "@hono/node-server";
import {OpenAPIHono} from "@hono/zod-openapi"; import {OpenAPIHono} from "@hono/zod-openapi";
import {proxy} from "hono/proxy";
import {serveStatic} from "@hono/node-server/serve-static"; import {serveStatic} from "@hono/node-server/serve-static";
import {logger} from "hono/logger"; import {logger} from "hono/logger";
import {cors} from "hono/cors"; import {cors} from "hono/cors";
import {createLog} from "./services/logger/logger.js"; import {createLog} from "./services/logger/logger.js";
import {closePool} from "./services/sqlServer/prodSqlServer.js";
// custom routes // custom routes
import scalar from "./services/general/route/scalar.js"; import scalar from "./services/general/route/scalar.js";
@@ -17,7 +17,8 @@ import sqlService from "./services/sqlServer/sqlService.js";
import logistics from "./services/logistics/logisticsService.js"; import logistics from "./services/logistics/logisticsService.js";
import rfid from "./services/rfid/rfidService.js"; import rfid from "./services/rfid/rfidService.js";
import printers from "./services/printers/printerService.js"; import printers from "./services/printers/printerService.js";
import loggerService from "./services/logger/loggerService.js";
import ocpService from "./services/ocp/ocpService.js";
import {db} from "../database/dbclient.js"; import {db} from "../database/dbclient.js";
import {settings} from "../database/schema/settings.js"; import {settings} from "../database/schema/settings.js";
import {count, eq} from "drizzle-orm"; import {count, eq} from "drizzle-orm";
@@ -32,32 +33,26 @@ const serverIntialized = await db.select({count: count()}).from(settings);
export const installed = serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development" ? false : true; export const installed = serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development" ? false : true;
createLog("info", "LST", "server", `Server is installed: ${installed}`); createLog("info", "LST", "server", `Server is installed: ${installed}`);
const allowedOrigins = [ const app = new OpenAPIHono({strict: false});
"http://localhost:3000",
"http://localhost:4000",
"http://localhost:5173",
`http://usmcd1vms006:4000`,
];
const app = new OpenAPIHono();
// middle ware // middle ware
app.use("*", logger()); app.use("*", logger());
app.use( app.use(
"*", "*",
cors({ cors({
origin: allowedOrigins, origin: "*", // Allow all origins
allowHeaders: ["X-Custom-Header", "Upgrade-Insecure-Requests"], allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
allowMethods: ["POST", "GET", "OPTIONS"], allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
exposeHeaders: ["Content-Length", "X-Kuma-Revision"], exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
credentials: true, // Allow credentials if needed
maxAge: 600, maxAge: 600,
credentials: true,
}) })
); );
// Middleware to normalize route case // Middleware to normalize route case
app.use("*", async (c, next) => { app.use("*", async (c, next) => {
const lowercasedUrl = c.req.url.toLowerCase(); const lowercasedUrl = c.req.url.toLowerCase();
//console.log("Incoming Request:", c.req.url, c.req.method);
// If the URL is already lowercase, continue as usual // If the URL is already lowercase, continue as usual
if (c.req.url === lowercasedUrl) { if (c.req.url === lowercasedUrl) {
return next(); return next();
@@ -85,22 +80,46 @@ const routes = [
logistics, logistics,
rfid, rfid,
printers, printers,
loggerService,
ocpService,
] as const; ] as const;
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/api/", route); app.route("/api/", route);
}); });
app.route("/ocme/*", ocme);
//--------------- lst v1 proxy ----------------------\\
app.all("/api/v1/*", (c) => {
const path = c.req.path.replace("/api/v1/", ""); // Extract the subpath
const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params
return proxy(`http://localhost:4900/${path}${query}`, {
headers: {
...c.req.header(),
"X-Forwarded-For": "127.0.0.1",
"X-Forwarded-Host": c.req.header("host"),
},
});
});
app.all("/system/*", (c) => {
const path = c.req.path.replace("/system/", ""); // Extract the subpath
const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params
return proxy(`http://localhost:4200/${path}${query}`, {
headers: {
...c.req.header(),
"X-Forwarded-For": "127.0.0.1",
"X-Forwarded-Host": c.req.header("host"),
},
});
});
//---------------------------------------------------\\
// the catch all api route // the catch all api route
app.all("/api/*", (c) => c.json({error: "API route not found"}, 404)); app.all("/api/*", (c) => c.json({error: "API route not found"}, 404));
app.route("/ocme/", ocme);
// async (c) => {
// //return ocmeService(c);
// c.json({error: "Ocme route not found"}, 404);
// });
// front end static files // front end static files
app.use("/*", serveStatic({root: "./frontend/dist"})); app.use("/*", serveStatic({root: "./frontend/dist"}));
app.use("*", serveStatic({path: "./frontend/dist/index.html"})); app.use("*", serveStatic({path: "./frontend/dist/index.html"}));

View File

@@ -172,21 +172,28 @@ $plantFunness = {
Write-Host "Removing services that are no longer used." Write-Host "Removing services that are no longer used."
& $nssmPath remove "LogisticsSupportTool" confirm & $nssmPath remove "LogisticsSupportTool" confirm
& $nssmPath remove $serviceAuth confirm & $nssmPath remove $serviceAuth confirm
# & $nssmPath remove $serviceGateway confirm
# if($token -eq "usday1"){
# & $nssmPath remove $serviceOcme confirm
# }
Start-Sleep -Seconds 5 Start-Sleep -Seconds 5
## adding in lstAdm $service = Get-Service -Name $serviceLstV2 -ErrorAction SilentlyContinue
Write-Host "Adding $($serviceLstV2)... incase its missing."
$commandToRun = "run start"
$description = "logistics Support Tool"
& $nssmPath install $serviceLstV2 $npmPath $commandToRun
Write-Host "Setting the app directory"
& $nssmPath set $serviceLstV2 AppDirectory $appPath
Write-Host "Setting the description"
& $nssmPath set $serviceLstV2 Description $description
Write-Host "Setting recovery options"
# Set recovery options
sc.exe failure $serviceLstV2 reset= 0 actions= restart/5000/restart/5000/restart/5000
if(-not $service){
## adding in lstAdm
Write-Host "Adding $($serviceLstV2)... incase its missing."
$commandToRun = "run start"
$description = "logistics Support Tool"
& $nssmPath install $serviceLstV2 $npmPath $commandToRun
Write-Host "Setting the app directory"
& $nssmPath set $serviceLstV2 AppDirectory $appPath
Write-Host "Setting the description"
& $nssmPath set $serviceLstV2 Description $description
Write-Host "Setting recovery options"
# Set recovery options
sc.exe failure $serviceLstV2 reset= 0 actions= restart/5000/restart/5000/restart/5000
}
# Doing an install # Doing an install
Write-Host "Running the install to make sure everything is updated." Write-Host "Running the install to make sure everything is updated."
Set-Location $serverPath Set-Location $serverPath
@@ -235,10 +242,9 @@ $plantFunness = {
Start-Service -DisplayName $serviceLstV2 Start-Service -DisplayName $serviceLstV2
Start-Sleep -Seconds 1 Start-Sleep -Seconds 1
Write-Host "$($server) finished updating" Write-Host "$($server) finished updating"
if($token -eq "usday1"){ if($token -eq "usday1"){
Write-Host "Starting $($serviceOcme)" Write-Host "Starting $($serviceOcme)"
Start-Service -DisplayName $serviceOcme Start-Service -DisplayName $serviceOcme
} }
} }

View File

@@ -39,7 +39,7 @@ export async function login(
user_id: user[0].user_id, user_id: user[0].user_id,
username: user[0].username, username: user[0].username,
email: user[0].email, email: user[0].email,
roles: roles || null, //roles: roles || null,
role: user[0].role || null, // this should be removed onces full migration to v2 is completed role: user[0].role || null, // this should be removed onces full migration to v2 is completed
prod: btoa(`${username.toLowerCase()}:${password}`), prod: btoa(`${username.toLowerCase()}:${password}`),
}; };

View File

@@ -0,0 +1,22 @@
import {eq, sql} from "drizzle-orm";
import {db} from "../../../../database/dbclient.js";
import {logs} from "../../../../database/schema/logs.js";
import {createLog} from "../logger.js";
export const clearLog = async (id: string) => {
/**
* mark the log as cleared
*/
try {
const clear = await db
.update(logs)
.set({checked: true, checkedAt: sql`NOW()`})
.where(eq(logs.log_id, id));
createLog("info", "lst", "logger", "Log just cleared.");
return {success: true, message: "Log was just cleared."};
} catch (error) {
createLog("error", "lst", "logger", "There was an error clearing the log.");
return {success: false, message: "There was an error clearing the log."};
}
};

View File

@@ -0,0 +1,28 @@
import {and, eq, inArray, lte, sql} from "drizzle-orm";
import {db} from "../../../../database/dbclient.js";
import {logs} from "../../../../database/schema/logs.js";
import {createLog} from "../logger.js";
export const getLogs = async (data: any) => {
try {
// clear all remaining logs ne to info.
const checked = data.checked && data.checked[0] === "true" ? true : false || false;
const logData = await db
.select()
.from(logs)
.where(
and(
lte(logs.created_at, sql.raw(`NOW() - INTERVAL '${data.hours} hours'`)),
inArray(logs.service, data.service),
inArray(logs.level, data.level),
eq(logs.checked, checked)
)
);
return {success: true, message: "logs returned", data: logData};
} catch (error) {
console.log(error);
createLog("error", "lst", "logger", `There was an error deleteing server logs. ${error}`);
return {success: false, message: "An error occured while trying to get the logs", error};
}
};

View File

@@ -0,0 +1,55 @@
import {and, eq, inArray, lte, ne, sql} from "drizzle-orm";
import {db} from "../../../../database/dbclient.js";
import {logs} from "../../../../database/schema/logs.js";
import {createLog} from "../logger.js";
export const logCleanup = async () => {
/**
* We will run the clean logger where we have aged logs that do not need to be here flooding the db
*/
// clear the server logs older than 3 days
try {
// clear info logs older than 3 days
const delLogs = await db
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '3 days'`),
inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils"]),
eq(logs.level, "30")
)
)
.returning({name: logs.message});
createLog(
"info",
"lst",
"logger",
`${delLogs.length} Server logs were just deleted that were older than 3 days`
);
} catch (error) {
createLog("error", "lst", "logger", `There was an error deleteing server logs. ${error}`);
}
try {
// clear all remaining logs ne to info.
const delLogs = await db
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '7 days'`),
inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils"]),
ne(logs.level, "30")
)
)
.returning({name: logs.message});
createLog(
"info",
"lst",
"logger",
`${delLogs.length} Server logs were just deleted that were older than 7 days`
);
} catch (error) {
createLog("error", "lst", "logger", `There was an error deleteing server logs. ${error}`);
}
};

View File

@@ -0,0 +1,30 @@
import {OpenAPIHono} from "@hono/zod-openapi";
// routes
import clearLog from "./routes/clearLog.js";
import {db} from "../../../database/dbclient.js";
import {settings} from "../../../database/schema/settings.js";
import {logCleanup} from "./controller/logCleanup.js";
import createNewLog from "./routes/createLog.js";
import getLogs from "./routes/getLogs.js";
const app = new OpenAPIHono();
const routes = [clearLog, createNewLog, getLogs] as const;
const setting = await db.select().from(settings);
const appRoutes = routes.forEach((route) => {
app.route("/logger", route);
});
app.all("/logger/*", (c) => {
return c.json({success: false, message: "You have encounters a log route that dose not exist."});
});
// run the clean up job ones on server restart/crash/update and then once a date
logCleanup();
setInterval(async () => {
logCleanup();
}, 60 * 1000 * 60 * 24);
export default app;

View File

@@ -0,0 +1,44 @@
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {apiHit} from "../../../globalUtils/apiHits.js";
import {responses} from "../../../globalUtils/routeDefs/responses.js";
import {clearLog} from "../controller/clearLog.js";
const app = new OpenAPIHono({strict: false});
const ParamsSchema = z.object({
id: z
.string()
.min(3)
.openapi({
param: {
name: "id",
in: "path",
},
example: "1212121",
}),
});
app.openapi(
createRoute({
tags: ["server:logger"],
summary: "Marks the select log id as cleared out.",
method: "patch",
path: "/logs/{id}",
request: {
params: ParamsSchema,
},
responses: responses(),
}),
async (c) => {
const {id} = c.req.valid("param");
//const body = await c.req.json();
// make sure we have a vaid user being accessed thats really logged in
apiHit(c, {endpoint: `api/logger/logs/id`});
try {
const clear = await clearLog(id);
return c.json({success: clear.success, message: clear.message, data: []}, 200);
} catch (error) {
return c.json({success: false, message: "There was an error clearing the log.", data: error}, 400);
}
}
);
export default app;

View File

@@ -0,0 +1,38 @@
// an external way to creating logs
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {apiHit} from "../../../globalUtils/apiHits.js";
import {responses} from "../../../globalUtils/routeDefs/responses.js";
import {createLog} from "../logger.js";
const app = new OpenAPIHono({strict: false});
const CreateLog = z.object({
level: z.string().openapi({example: "info"}),
service: z.string().openapi({example: "server"}),
message: z.string().openapi({example: "This is a new log posted"}),
});
app.openapi(
createRoute({
tags: ["server:logger"],
summary: "Post a log to the db.",
method: "post",
path: "/logs",
description: "This might be a temp soltuin during the transtion between versions",
request: {
body: {content: {"application/json": {schema: CreateLog}}},
},
responses: responses(),
}),
async (c) => {
const body = await c.req.json();
apiHit(c, {endpoint: `api/logger/logs/id`});
try {
createLog(body.level, "logger", body.service, body.message);
return c.json({success: true, message: "A new log was created.", data: []}, 200);
} catch (error) {
return c.json({success: false, message: "There was an error clearing the log.", data: error}, 400);
}
}
);
export default app;

View File

@@ -0,0 +1,39 @@
// an external way to creating logs
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {apiHit} from "../../../globalUtils/apiHits.js";
import {responses} from "../../../globalUtils/routeDefs/responses.js";
import {createLog} from "../logger.js";
import {getLogs} from "../controller/getLogs.js";
const app = new OpenAPIHono({strict: false});
const CreateLog = z.object({
level: z.string().openapi({example: "info"}),
service: z.string().openapi({example: "server"}),
message: z.string().openapi({example: "This is a new log posted"}),
});
app.openapi(
createRoute({
tags: ["server:logger"],
summary: "Gets logs.",
method: "get",
path: "/logs",
description: "This might be a temp soltuin during the transtion between versions",
request: {
body: {content: {"application/json": {schema: CreateLog}}},
},
responses: responses(),
}),
async (c) => {
const query = await c.req.queries();
apiHit(c, {endpoint: `api/logger/logs`});
try {
const logData = await getLogs(query);
return c.json({success: logData?.success, message: logData?.message, data: logData?.data}, 200);
} catch (error) {
return c.json({success: false, message: "There was an error clearing the log.", data: error}, 400);
}
}
);
export default app;

View File

@@ -6,12 +6,17 @@ import postRunningNr from "./route/postRunningNumber.js";
import pickedup from "./route/pickedUp.js"; import pickedup from "./route/pickedUp.js";
import postsscc from "./route/postSSCC.js"; import postsscc from "./route/postSSCC.js";
import getShipments from "./route/getShipmentPallets.js"; import getShipments from "./route/getShipmentPallets.js";
import {serve} from "@hono/node-server";
import {createLog} from "../logger/logger.js";
import {db} from "../../../database/dbclient.js";
import {settings} from "../../../database/schema/settings.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
const port = process.env.OCME_PORT;
const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments] as const; const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments] as const;
const setting = await db.select().from(settings);
// app.route("/server", modules); const isActive = setting.filter((n) => n.name === "ocmeService");
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/api/v1", route); app.route("/api/v1", route);
}); });
@@ -19,5 +24,17 @@ const appRoutes = routes.forEach((route) => {
app.all("/api/v1/*", (c) => { app.all("/api/v1/*", (c) => {
return c.json({success: false, message: "you have encounted an ocme route that dose not exist."}); return c.json({success: false, message: "you have encounted an ocme route that dose not exist."});
}); });
if (port && isActive[0]?.value === "1") {
serve(
{
fetch: app.fetch,
port: Number(port),
hostname: "0.0.0.0",
},
(info) => {
createLog("info", "LST", "server", `Ocme section is listening on http://${info.address}:${info.port}`);
}
);
}
export default app; export default app;

View File

@@ -2,7 +2,7 @@ import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {getInfo} from "../controller/getInfo.js"; import {getInfo} from "../controller/getInfo.js";
import {apiHit} from "../../../globalUtils/apiHits.js"; import {apiHit} from "../../../globalUtils/apiHits.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono({strict: false});
const AddSetting = z.object({ const AddSetting = z.object({
name: z.string().openapi({example: "server"}), name: z.string().openapi({example: "server"}),

View File

@@ -0,0 +1,20 @@
import {db} from "../../../../database/dbclient.js";
import {manualPrinting} from "../../../../database/schema/ocpManualPrint.js";
export const manualPrint = async (data: any) => {
/**
* add the reason we did a manual print.
*/
const manualPrintData = {
line: data.line,
printReason: data.printReason,
initials: data.initials,
additionalComments: data?.additionalComments,
add_user: "lst",
};
try {
const manualPrint = await db.insert(manualPrinting).values(manualPrintData);
} catch (error) {}
};

View File

@@ -0,0 +1,22 @@
import {OpenAPIHono} from "@hono/zod-openapi";
// routes
import manualLabelLog from "./routes/manualPrintLog.js";
import {db} from "../../../database/dbclient.js";
import {settings} from "../../../database/schema/settings.js";
const app = new OpenAPIHono();
const routes = [manualLabelLog] as const;
const setting = await db.select().from(settings);
const appRoutes = routes.forEach((route) => {
app.route("/ocp", route);
});
app.all("/ocp/*", (c) => {
return c.json({success: false, message: "You have encounters a ocp route that dose not exist."});
});
export default app;

View File

@@ -0,0 +1,56 @@
// an external way to creating logs
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {apiHit} from "../../../globalUtils/apiHits.js";
import {responses} from "../../../globalUtils/routeDefs/responses.js";
import type {User} from "../../../types/users.js";
import {verify} from "hono/jwt";
import {manualPrint} from "../controller/manualLabelLog.js";
import {authMiddleware} from "../../auth/middleware/authMiddleware.js";
const app = new OpenAPIHono({strict: false});
const CreateLog = z.object({
line: z.string().openapi({example: "info"}),
initials: z.string().openapi({example: "server"}),
printReason: z.string().openapi({example: "This is a new log posted"}),
additionalComments: z.string().optional().openapi({example: "Some reason why we did this."}),
});
app.openapi(
createRoute({
tags: ["ocp"],
summary: "Post the log for manaulprinting.",
method: "post",
path: "/manuallabellog",
//middleware: authMiddleware,
//description: "This might be a temp soltuin during the transtion between versions",
request: {
body: {content: {"application/json": {schema: CreateLog}}},
},
responses: responses(),
}),
async (c) => {
const body = await c.req.json();
apiHit(c, {endpoint: `api/logger/logs/id`});
// const authHeader = c.req.header("Authorization");
// const token = authHeader?.split("Bearer ")[1] || "";
// let user: User;
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// user = payload.user as User;
// } catch (error) {
// console.log(error);
// return c.json({message: "Unauthorized"}, 401);
// }
try {
//const data = {...body, add_user: user.username};
await manualPrint(body);
return c.json({success: true, message: "Manual Print was added.", data: []}, 200);
} catch (error) {
return c.json({success: false, message: "There was an error clearing the log.", data: error}, 400);
}
}
);
export default app;

View File

@@ -0,0 +1,52 @@
// an external way to creating logs
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
import {apiHit} from "../../../globalUtils/apiHits.js";
import {responses} from "../../../globalUtils/routeDefs/responses.js";
const app = new OpenAPIHono({strict: false});
const CreateLog = z.object({
line: z.string().openapi({example: "info"}),
initials: z.string().openapi({example: "server"}),
printReason: z.string().openapi({example: "This is a new log posted"}),
additionalComments: z.string().optional().openapi({example: "Some reason why we did this."}),
});
app.openapi(
createRoute({
tags: ["ocp"],
summary: "Prints a label.",
method: "post",
path: "/printlabel",
//middleware: authMiddleware,
//description: "This might be a temp soltuin during the transtion between versions",
request: {
body: {content: {"application/json": {schema: CreateLog}}},
},
responses: responses(),
}),
async (c) => {
const body = await c.req.json();
apiHit(c, {endpoint: `api/logger/logs/id`});
// const authHeader = c.req.header("Authorization");
// const token = authHeader?.split("Bearer ")[1] || "";
// let user: User;
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// user = payload.user as User;
// } catch (error) {
// console.log(error);
// return c.json({message: "Unauthorized"}, 401);
// }
try {
//const data = {...body, add_user: user.username};
return c.json({success: true, message: "Label was printed.", data: []}, 200);
} catch (error) {
return c.json({success: false, message: "There was an error printing a label.", data: error}, 400);
}
}
);
export default app;

View File

@@ -4,6 +4,7 @@ import {addSetting} from "../../controller/settings/addSetting.js";
import {verify} from "hono/jwt"; import {verify} from "hono/jwt";
import type {User} from "../../../../types/users.js"; import type {User} from "../../../../types/users.js";
import {authMiddleware} from "../../../auth/middleware/authMiddleware.js"; import {authMiddleware} from "../../../auth/middleware/authMiddleware.js";
import {responses} from "../../../../globalUtils/routeDefs/responses.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
@@ -29,43 +30,7 @@ app.openapi(
}, },
}, },
}, },
responses: { responses: responses(),
200: {
content: {
"application/json": {
schema: z.object({
success: z.boolean().openapi({example: true}),
message: z.string().openapi({example: "Starter"}),
}),
},
},
description: "Response message",
},
400: {
content: {
"application/json": {
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
},
},
description: "Internal Server Error",
},
401: {
content: {
"application/json": {
schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
},
},
description: "Unauthorized",
},
500: {
content: {
"application/json": {
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
},
},
description: "Internal Server Error",
},
},
}), }),
async (c) => { async (c) => {
// make sure we have a vaid user being accessed thats really logged in // make sure we have a vaid user being accessed thats really logged in

View File

@@ -52,25 +52,6 @@ app.openapi(
}), }),
async (c) => { async (c) => {
// make sure we have a vaid user being accessed thats really logged in // make sure we have a vaid user being accessed thats really logged in
const authHeader = c.req.header("Authorization");
if (authHeader?.includes("Basic")) {
return c.json({message: "You are a Basic user! Please login to get a token"}, 401);
}
if (!authHeader) {
return c.json({message: "Unauthorized"}, 401);
}
const token = authHeader?.split("Bearer ")[1] || "";
let user: User;
try {
const payload = await verify(token, process.env.JWT_SECRET!);
user = payload.user as User;
} catch (error) {
return c.json({message: "Unauthorized"}, 401);
}
// now pass all the data over to update the user info // now pass all the data over to update the user info
try { try {

View File

@@ -173,7 +173,7 @@
"contactPhone": "6366970253", "contactPhone": "6366970253",
"customerTiAcc": "ALPL01DAYTONINT", "customerTiAcc": "ALPL01DAYTONINT",
"lstServerPort": "4000", "lstServerPort": "4000",
"active": false, "active": true,
"serverLoc": "E:\\LST\\lstv2", "serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend", "oldVersion": "E:\\LST\\lst_backend",
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]", "shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",

View File

@@ -56,6 +56,12 @@ const newSettings = [
description: "Dose the plant have 2 machines that go to 1?", description: "Dose the plant have 2 machines that go to 1?",
moduleName: "ocp", moduleName: "ocp",
}, },
{
name: "ocmeService",
value: "0",
description: "Is the ocme service enabled. this is gernerally only for Dayton.",
moduleName: "ocme",
},
{ {
name: "fifoCheck", name: "fifoCheck",
value: "45", value: "45",
@@ -80,12 +86,40 @@ const newSettings = [
description: "What address is monitored to be limited to the amount of lots that can be added to a truck.", description: "What address is monitored to be limited to the amount of lots that can be added to a truck.",
moduleName: "ocme", moduleName: "ocme",
}, },
{
name: "ocmeCycleCount",
value: "1",
description: "Are we allowing ocme cycle counts?",
roles: "admin",
module: "ocme",
},
{ {
name: "devDir", name: "devDir",
value: "C:\\Users\\matthes01\\Documents\\lstv2", value: "C:\\Users\\matthes01\\Documents\\lstv2",
description: "This is the dev dir and strictly only for updating the servers.", description: "This is the dev dir and strictly only for updating the servers.",
moduleName: "server", moduleName: "server",
}, },
{
name: "demandMGTActivated",
value: "0",
description: "Do we allow for new fake edi?",
roles: "admin",
module: "logistics",
},
{
name: "qualityRequest",
value: "0",
description: "quality request module?",
roles: "admin",
module: "logistics",
},
{
name: "ocpLogsCheck",
value: "4",
description: "How long do we want to allow logs to show that have not been cleared?",
roles: "admin",
module: "ocp",
},
]; ];
export const areSettingsIn = async () => { export const areSettingsIn = async () => {
// get the roles // get the roles