diff --git a/frontend/public/imgs/card_ppo_dark.png b/frontend/public/imgs/card_ppo_dark.png new file mode 100644 index 0000000..c6f0ace Binary files /dev/null and b/frontend/public/imgs/card_ppo_dark.png differ diff --git a/frontend/public/imgs/card_ppo_light.png b/frontend/public/imgs/card_ppo_light.png new file mode 100644 index 0000000..1c0ab22 Binary files /dev/null and b/frontend/public/imgs/card_ppo_light.png differ diff --git a/frontend/public/imgs/dkLst copy.png b/frontend/public/imgs/dkLst copy.png new file mode 100644 index 0000000..22ffb87 Binary files /dev/null and b/frontend/public/imgs/dkLst copy.png differ diff --git a/frontend/public/imgs/exampleforecast.png b/frontend/public/imgs/exampleforecast.png new file mode 100644 index 0000000..dc7a2a1 Binary files /dev/null and b/frontend/public/imgs/exampleforecast.png differ diff --git a/frontend/public/imgs/ltLst copy.png b/frontend/public/imgs/ltLst copy.png new file mode 100644 index 0000000..cfd8d4c Binary files /dev/null and b/frontend/public/imgs/ltLst copy.png differ diff --git a/frontend/public/imgs/ordersInExample.png b/frontend/public/imgs/ordersInExample.png new file mode 100644 index 0000000..b91627c Binary files /dev/null and b/frontend/public/imgs/ordersInExample.png differ diff --git a/frontend/public/imgs/web-app-manifest-192x192.png b/frontend/public/imgs/web-app-manifest-192x192.png new file mode 100644 index 0000000..ea9a337 Binary files /dev/null and b/frontend/public/imgs/web-app-manifest-192x192.png differ diff --git a/frontend/public/imgs/web-app-manifest-512x512.png b/frontend/public/imgs/web-app-manifest-512x512.png new file mode 100644 index 0000000..61e9cee Binary files /dev/null and b/frontend/public/imgs/web-app-manifest-512x512.png differ diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index 0067882..fdc8d9b 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -37,6 +37,7 @@ import { Route as OldOldocmeCyclecountIndexRouteImport } from './routes/_old/old import { Route as OldOldlogisticsSiloAdjustmentsIndexRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/index' import { Route as OldOldlogisticsMaterialHelperIndexRouteImport } from './routes/_old/old/(logistics)/materialHelper/index' import { Route as OldOldlogisticsHelperCommandsIndexRouteImport } from './routes/_old/old/(logistics)/helperCommands/index' +import { Route as OldOldlogisticsDmIndexRouteImport } from './routes/_old/old/(logistics)/dm/index' import { Route as OldOldlogisticsBarcodegenIndexRouteImport } from './routes/_old/old/(logistics)/barcodegen/index' import { Route as OldOldlogisticsSiloAdjustmentsHistRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/$hist' import { Route as AppAdminLayoutAdminUsersUsersRouteImport } from './routes/_app/_adminLayout/admin/_users/users' @@ -192,6 +193,11 @@ const OldOldlogisticsHelperCommandsIndexRoute = path: '/helperCommands/', getParentRoute: () => OldOldRouteRoute, } as any) +const OldOldlogisticsDmIndexRoute = OldOldlogisticsDmIndexRouteImport.update({ + id: '/(logistics)/dm/', + path: '/dm/', + getParentRoute: () => OldOldRouteRoute, +} as any) const OldOldlogisticsBarcodegenIndexRoute = OldOldlogisticsBarcodegenIndexRouteImport.update({ id: '/(logistics)/barcodegen/', @@ -253,6 +259,7 @@ export interface FileRoutesByFullPath { '/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute '/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute '/old/barcodegen': typeof OldOldlogisticsBarcodegenIndexRoute + '/old/dm': typeof OldOldlogisticsDmIndexRoute '/old/helperCommands': typeof OldOldlogisticsHelperCommandsIndexRoute '/old/materialHelper': typeof OldOldlogisticsMaterialHelperIndexRoute '/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute @@ -283,6 +290,7 @@ export interface FileRoutesByTo { '/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute '/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute '/old/barcodegen': typeof OldOldlogisticsBarcodegenIndexRoute + '/old/dm': typeof OldOldlogisticsDmIndexRoute '/old/helperCommands': typeof OldOldlogisticsHelperCommandsIndexRoute '/old/materialHelper': typeof OldOldlogisticsMaterialHelperIndexRoute '/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute @@ -319,6 +327,7 @@ export interface FileRoutesById { '/_app/_adminLayout/admin/_users/users': typeof AppAdminLayoutAdminUsersUsersRoute '/_old/old/(logistics)/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute '/_old/old/(logistics)/barcodegen/': typeof OldOldlogisticsBarcodegenIndexRoute + '/_old/old/(logistics)/dm/': typeof OldOldlogisticsDmIndexRoute '/_old/old/(logistics)/helperCommands/': typeof OldOldlogisticsHelperCommandsIndexRoute '/_old/old/(logistics)/materialHelper/': typeof OldOldlogisticsMaterialHelperIndexRoute '/_old/old/(logistics)/siloAdjustments/': typeof OldOldlogisticsSiloAdjustmentsIndexRoute @@ -352,6 +361,7 @@ export interface FileRouteTypes { | '/admin/users' | '/old/siloAdjustments/$hist' | '/old/barcodegen' + | '/old/dm' | '/old/helperCommands' | '/old/materialHelper' | '/old/siloAdjustments' @@ -382,6 +392,7 @@ export interface FileRouteTypes { | '/admin/users' | '/old/siloAdjustments/$hist' | '/old/barcodegen' + | '/old/dm' | '/old/helperCommands' | '/old/materialHelper' | '/old/siloAdjustments' @@ -417,6 +428,7 @@ export interface FileRouteTypes { | '/_app/_adminLayout/admin/_users/users' | '/_old/old/(logistics)/siloAdjustments/$hist' | '/_old/old/(logistics)/barcodegen/' + | '/_old/old/(logistics)/dm/' | '/_old/old/(logistics)/helperCommands/' | '/_old/old/(logistics)/materialHelper/' | '/_old/old/(logistics)/siloAdjustments/' @@ -622,6 +634,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof OldOldlogisticsHelperCommandsIndexRouteImport parentRoute: typeof OldOldRouteRoute } + '/_old/old/(logistics)/dm/': { + id: '/_old/old/(logistics)/dm/' + path: '/dm' + fullPath: '/old/dm' + preLoaderRoute: typeof OldOldlogisticsDmIndexRouteImport + parentRoute: typeof OldOldRouteRoute + } '/_old/old/(logistics)/barcodegen/': { id: '/_old/old/(logistics)/barcodegen/' path: '/barcodegen' @@ -766,6 +785,7 @@ interface OldOldRouteRouteChildren { OldOldRfidIndexRoute: typeof OldOldRfidIndexRoute OldOldlogisticsSiloAdjustmentsHistRoute: typeof OldOldlogisticsSiloAdjustmentsHistRoute OldOldlogisticsBarcodegenIndexRoute: typeof OldOldlogisticsBarcodegenIndexRoute + OldOldlogisticsDmIndexRoute: typeof OldOldlogisticsDmIndexRoute OldOldlogisticsHelperCommandsIndexRoute: typeof OldOldlogisticsHelperCommandsIndexRoute OldOldlogisticsMaterialHelperIndexRoute: typeof OldOldlogisticsMaterialHelperIndexRoute OldOldlogisticsSiloAdjustmentsIndexRoute: typeof OldOldlogisticsSiloAdjustmentsIndexRoute @@ -781,6 +801,7 @@ const OldOldRouteRouteChildren: OldOldRouteRouteChildren = { OldOldlogisticsSiloAdjustmentsHistRoute: OldOldlogisticsSiloAdjustmentsHistRoute, OldOldlogisticsBarcodegenIndexRoute: OldOldlogisticsBarcodegenIndexRoute, + OldOldlogisticsDmIndexRoute: OldOldlogisticsDmIndexRoute, OldOldlogisticsHelperCommandsIndexRoute: OldOldlogisticsHelperCommandsIndexRoute, OldOldlogisticsMaterialHelperIndexRoute: diff --git a/frontend/src/routes/_old/old/(logistics)/dm/index.tsx b/frontend/src/routes/_old/old/(logistics)/dm/index.tsx new file mode 100644 index 0000000..0cb6769 --- /dev/null +++ b/frontend/src/routes/_old/old/(logistics)/dm/index.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, redirect } from "@tanstack/react-router"; +import { checkUserAccess } from "@/lib/authClient"; +import DmPage from "../../-components/logistics/dm/dmPage"; + +export const Route = createFileRoute("/_old/old/(logistics)/dm/")({ + component: RouteComponent, + beforeLoad: async () => { + const auth = await checkUserAccess({ + allowedRoles: ["systemAdmin", "technician", "admin", "manager"], + moduleName: "siloAdjustments", // optional + }); + + if (!auth) { + throw redirect({ + to: "/login", + search: { + // Use the current location to power a redirect after login + // (Do not use `router.state.resolvedLocation` as it can + // potentially lag behind the actual current location) + redirect: location.pathname + location.search, + }, + }); + } + }, +}); + +function RouteComponent() { + return ( +
+ +
+ ); +} diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/DMButtons.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/DMButtons.tsx index e592320..440ae2c 100644 --- a/frontend/src/routes/_old/old/-components/logistics/dm/DMButtons.tsx +++ b/frontend/src/routes/_old/old/-components/logistics/dm/DMButtons.tsx @@ -1,73 +1,55 @@ +import { useSettingStore } from "../../../-lib/store/useSettings"; import ForecastImport from "./ForecastImport"; import OrderImport from "./OrderImport"; -import { useSettingStore } from "@/lib/store/useSettings"; export default function DMButtons() { - const { settings } = useSettingStore(); - const testServers = ["test1", "test2", "test3"]; - const plantToken = settings.filter((n) => n.name === "plantToken"); - //console.log(plantToken); - return ( -
- - {/* dev and testserver sees all */} - {testServers.includes(plantToken[0]?.value) && ( -
- - - - - -
- )} - {plantToken[0]?.value === "usday1" && ( -
- - - -
- )} - {plantToken[0]?.value === "usflo1" && ( -
- -
- )} - {plantToken[0]?.value === "usstp1" && ( -
- )} - {plantToken[0]?.value === "usiow1" && ( -
- -
- )} - {plantToken[0]?.value === "usiow2" && ( -
- -
- )} - {plantToken[0]?.value === "usksc1" && ( -
- -
- )} -
- ); + const { settings } = useSettingStore(); + const testServers = ["test1", "test2", "test3"]; + const plantToken = settings.filter((n) => n.name === "plantToken"); + //console.log(plantToken); + return ( +
+ + {/* dev and testserver sees all */} + {testServers.includes(plantToken[0]?.value) && ( +
+ + + + + +
+ )} + {plantToken[0]?.value === "usday1" && ( +
+ + + +
+ )} + {plantToken[0]?.value === "usflo1" && ( +
+ +
+ )} + {plantToken[0]?.value === "usstp1" && ( +
+ )} + {plantToken[0]?.value === "usiow1" && ( +
+ +
+ )} + {plantToken[0]?.value === "usiow2" && ( +
+ +
+ )} + {plantToken[0]?.value === "usksc1" && ( +
+ +
+ )} +
+ ); } diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/ForecastImport.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/ForecastImport.tsx new file mode 100644 index 0000000..27b910e --- /dev/null +++ b/frontend/src/routes/_old/old/-components/logistics/dm/ForecastImport.tsx @@ -0,0 +1,69 @@ +import axios from "axios"; +import { useRef, useState } from "react"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; + +export default function ForecastImport(props: any) { + const fileInputRef: any = useRef(null); + const [posting, setPosting] = useState(false); + const token = localStorage.getItem("auth_token"); + //const [fileType, setFileType] = useState(""); + const importOrders = async (e: any) => { + const file = e.target.files[0]; + if (!file) { + toast.error("Missing file please try again"); + setPosting(false); + return; + } + + // create the form data with the correct fileType + const formData = new FormData(); + formData.append("postForecast", e.target.files[0]); + formData.append("fileType", props.fileType); // extra field + // console.log(formData); + toast.success("Import started."); + try { + const response = await axios.post( + "/lst/old/api/logistics/postforecastin", + formData, + { + headers: { + "Content-Type": "multipart/form-data", + Authorization: `Bearer ${token}`, + }, + }, + ); + //console.log("Upload successful:", response.data); + toast.success(response?.data?.message); + fileInputRef.current.value = null; + setPosting(false); + // toast.success( + // "File Uploaded, please validate processing in alplaprod 2.0" + // ); + setPosting(false); + } catch (error) { + console.log(error); + toast.error("Upload failed"); + } + setPosting(false); + }; + + const handleButtonClick = () => { + setPosting(true); + fileInputRef.current.click(); + }; + return ( +
+ + +
+ ); +} diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/OrderImport.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/OrderImport.tsx new file mode 100644 index 0000000..af3853f --- /dev/null +++ b/frontend/src/routes/_old/old/-components/logistics/dm/OrderImport.tsx @@ -0,0 +1,64 @@ +import axios from "axios"; +import { useRef, useState } from "react"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; + +export default function OrderImport(props: any) { + const fileInputRef: any = useRef(null); + const [posting, setPosting] = useState(false); + const token = localStorage.getItem("auth_token"); + //const [fileType, setFileType] = useState(""); + const importOrders = async (e: any) => { + const file = e.target.files[0]; + if (!file) { + toast.error("Missing file please try again"); + setPosting(false); + return; + } + + // create the form data with the correct fileType + const formData = new FormData(); + formData.append("postOrders", e.target.files[0]); + formData.append("fileType", props.fileType); // extra field + + try { + const response = await axios.post( + "/lst/old/api/logistics/postbulkorders", + formData, + { + headers: { + "Content-Type": "multipart/form-data", + Authorization: `Bearer ${token}`, + }, + }, + ); + //console.log("Upload successful:", response.data); + toast.success(response?.data?.message); + fileInputRef.current.value = null; + setPosting(false); + } catch (error) { + console.log(error); + toast.error("Upload failed"); + } + setPosting(false); + }; + + const handleButtonClick = () => { + setPosting(true); + fileInputRef.current.click(); + }; + return ( +
+ + +
+ ); +} diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/StandardForecastTemplate.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/StandardForecastTemplate.tsx new file mode 100644 index 0000000..b4fcb36 --- /dev/null +++ b/frontend/src/routes/_old/old/-components/logistics/dm/StandardForecastTemplate.tsx @@ -0,0 +1,44 @@ +import axios from "axios"; +import { format } from "date-fns"; +import { useState } from "react"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; + +export default function StandardForecastTemplate() { + const [template, setTemplate] = useState(false); + const getTemplate = async () => { + setTemplate(true); + try { + const res = await axios.get( + `/lst/old/api/logistics/bulkforcasttemplate`, + { + 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 = `ForecastTemplate-${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(`Forecast template`); + setTemplate(false); + } catch (error) { + setTemplate(false); + toast.error("There was an error getting the template"); + } + }; + return ( + + ); +} diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/StandardOrderTemplate.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/StandardOrderTemplate.tsx new file mode 100644 index 0000000..7b812b5 --- /dev/null +++ b/frontend/src/routes/_old/old/-components/logistics/dm/StandardOrderTemplate.tsx @@ -0,0 +1,41 @@ +import axios from "axios"; +import { format } from "date-fns"; +import { useState } from "react"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; + +export default function StandardOrderTemplate() { + const [template, setTemplate] = useState(false); + const getTemplate = async () => { + setTemplate(true); + try { + const res = await axios.get(`/lst/old/api/logistics/bulkorderstemplate`, { + 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 = `BulkOrderTemplate-${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(`Bulk Order template`); + setTemplate(false); + } catch (error) { + setTemplate(false); + toast.error("There was an error getting the tempalte"); + } + }; + return ( + + ); +} diff --git a/frontend/src/routes/_old/old/-components/logistics/dm/dmPage.tsx b/frontend/src/routes/_old/old/-components/logistics/dm/dmPage.tsx new file mode 100644 index 0000000..fdb0901 --- /dev/null +++ b/frontend/src/routes/_old/old/-components/logistics/dm/dmPage.tsx @@ -0,0 +1,133 @@ +import { Separator } from "@/components/ui/separator"; +import { LstCard } from "../../extendedUi/LstCard"; +import ForecastImport from "./ForecastImport"; +import OrderImport from "./OrderImport"; +import StandardForecastTemplate from "./StandardForecastTemplate"; +import StandardOrderTemplate from "./StandardOrderTemplate"; + +export default function DmPage() { + return ( +
+ +
+

+ Simple instructions for creating/updating orders +

+
+ + +
+ +
+ + + + +
+

+ Some notes to consider +

+ +
    +
  • + No longer need to add in the invoice id, we take the default one. +
  • +
  • + You can have as many customers you want in the file and in any + order. +
  • +
  • + Orders created Manually, can not be updated with this process. +
  • +
  • + If you desire you can send up to 1000 orders at one time... or + more.... +
  • +
  • + Customer mappings can be added, this means that you can upload + your customer file and it will parse onces mapped, you need to + request this. +
  • +
  • + Custom imports will be at the top right under custom, here you + will just upload the customer file once mapped. +
  • +
+
+ +

Example order

+
+ orders in example +
+
+ +
+

+ Simple instructions for creating forecast +

+
+ + + +
+
+
+
    +
  • Download the template if you have not yet done so.
  • +
  • Add in the forecast like you see in the example below.
  • + +
  • + Once you have all the forecast enters click the upload button on + the top right +
  • +
+
+ +
+

+ Some notes to consider. +

+
    +
  • You can only use one customer at a time.
  • + +
  • If you desire you can send up to 1000 orders at one time...
  • +
  • + The customer MUST be set as default address in order for the + system to validate the av. +
  • +
+
+ +

Example forecast

+
+ orders in example +
+
+
+ ); +} diff --git a/lstV2/frontend/src/routes/(logistics)/barcodegen/index.tsx b/lstV2/frontend/src/routes/(logistics)/barcodegen/index.tsx deleted file mode 100644 index 7efb739..0000000 --- a/lstV2/frontend/src/routes/(logistics)/barcodegen/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import BGPage from "@/components/logistics/barcodeGenerator/BGPage"; -import { createFileRoute } from "@tanstack/react-router"; - -export const Route = createFileRoute("/(logistics)/barcodegen/")({ - component: RouteComponent, -}); - -function RouteComponent() { - return ( -
- -
- ); -} diff --git a/lstV2/frontend/src/routes/(logistics)/dm/index.tsx b/lstV2/frontend/src/routes/(logistics)/dm/index.tsx deleted file mode 100644 index 4234de0..0000000 --- a/lstV2/frontend/src/routes/(logistics)/dm/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import DmPage from "@/components/logistics/dm/dmPage"; -import { createFileRoute, redirect } from "@tanstack/react-router"; - -export const Route = createFileRoute("/(logistics)/dm/")({ - component: RouteComponent, - beforeLoad: async () => { - const auth = localStorage.getItem("auth_token"); - if (!auth) { - throw redirect({ - to: "/login", - search: { - // Use the current location to power a redirect after login - // (Do not use `router.state.resolvedLocation` as it can - // potentially lag behind the actual current location) - redirect: location.pathname + location.search, - }, - }); - } - }, -}); - -function RouteComponent() { - return ( -
- -
- ); -} diff --git a/lstV2/frontend/src/routes/(logistics)/openOrders/index.tsx b/lstV2/frontend/src/routes/(logistics)/openOrders/index.tsx deleted file mode 100644 index c0d2930..0000000 --- a/lstV2/frontend/src/routes/(logistics)/openOrders/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import OpenOrders from "@/components/logistics/warehouse/openOrders"; -import { createFileRoute } from "@tanstack/react-router"; - -export const Route = createFileRoute("/(logistics)/openOrders/")({ - component: RouteComponent, -}); - -function RouteComponent() { - return ( -
- -
- ); -}