feat(frontend): migrated old > new silo adjustments
moved the apps around so we can use 1 url for cors bs
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
meta {
|
||||
name: Machine Connections
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: {{url}}/lst/old/api/logistics/siloconnection
|
||||
body: json
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"siloID": "35010",
|
||||
"connectionType": "connected"
|
||||
}
|
||||
}
|
||||
|
||||
settings {
|
||||
encodeUrl: true
|
||||
timeout: 0
|
||||
}
|
||||
16
LogisticsSupportTool_API_DOCS/LstV2/Warehouse/PPOO.bru
Normal file
16
LogisticsSupportTool_API_DOCS/LstV2/Warehouse/PPOO.bru
Normal file
@@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: PPOO
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{url}}/lst/old/api/logistics/getppoo
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
settings {
|
||||
encodeUrl: true
|
||||
timeout: 0
|
||||
}
|
||||
8
LogisticsSupportTool_API_DOCS/LstV2/Warehouse/folder.bru
Normal file
8
LogisticsSupportTool_API_DOCS/LstV2/Warehouse/folder.bru
Normal file
@@ -0,0 +1,8 @@
|
||||
meta {
|
||||
name: Warehouse
|
||||
seq: 5
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
@@ -32,4 +32,5 @@ script:post-response {
|
||||
|
||||
settings {
|
||||
encodeUrl: true
|
||||
timeout: 0
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ body:json {
|
||||
"printerId": 22, // 457=22, 458=23
|
||||
"layoutId": 7,
|
||||
"numberOfCopies": 0,
|
||||
"qtyToPrint": 3
|
||||
"qtyToPrint": 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
meta {
|
||||
name: warehouse
|
||||
seq: 2
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
16
LogisticsSupportTool_API_DOCS/app/system/Settings.bru
Normal file
16
LogisticsSupportTool_API_DOCS/app/system/Settings.bru
Normal file
@@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: Settings
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{url}}/lst/api/system/settings
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
settings {
|
||||
encodeUrl: true
|
||||
timeout: 0
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
vars {
|
||||
url: http://localhost:5500
|
||||
url: https://usmcd1vms036.alpla.net
|
||||
session_cookie:
|
||||
urlv2: http://localhost:3000
|
||||
jwtV2:
|
||||
|
||||
28
app/main.ts
28
app/main.ts
@@ -4,6 +4,7 @@ import { toNodeHandler } from "better-auth/node";
|
||||
import cors from "cors";
|
||||
import express from "express";
|
||||
import { createServer } from "http";
|
||||
import { createProxyMiddleware, fixRequestBody } from "http-proxy-middleware";
|
||||
import morgan from "morgan";
|
||||
import os from "os";
|
||||
import { dirname, join } from "path";
|
||||
@@ -81,6 +82,24 @@ const main = async () => {
|
||||
);
|
||||
}
|
||||
|
||||
// old app prox temp stuff
|
||||
app.use(
|
||||
basePath + "/old",
|
||||
createProxyMiddleware({
|
||||
target: `http://localhost:3000`,
|
||||
changeOrigin: true,
|
||||
pathRewrite: (path, req) => {
|
||||
// Remove the basePath + '/old' prefix from the path dynamically
|
||||
return path.replace(`${basePath}/old`, "");
|
||||
},
|
||||
|
||||
headers: {
|
||||
// forward auth headers if needed
|
||||
"X-Forwarded-By": "express-proxy",
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
// global middleware
|
||||
app.set("trust proxy", true);
|
||||
app.use(apiHitMiddleware);
|
||||
@@ -93,6 +112,8 @@ const main = async () => {
|
||||
/^https?:\/\/.*\.alpla\.net$/,
|
||||
"http://localhost:4173",
|
||||
"http://localhost:4200",
|
||||
"http://localhost:3000",
|
||||
"http://localhost:4000",
|
||||
env.BETTER_AUTH_URL, // prod
|
||||
];
|
||||
|
||||
@@ -124,7 +145,12 @@ const main = async () => {
|
||||
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
||||
credentials: true,
|
||||
exposedHeaders: ["set-cookie"],
|
||||
allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
|
||||
allowedHeaders: [
|
||||
"Content-Type",
|
||||
"Authorization",
|
||||
"X-Requested-With",
|
||||
"XMLHttpRequest",
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* When we pass over the edi data we want to now store it so we can see the day to day
|
||||
* id
|
||||
* itemNumber // customer code
|
||||
* date requested
|
||||
* qty requested
|
||||
* av - what av this is linked to
|
||||
* add_date
|
||||
*/
|
||||
|
||||
type IncomingForecastData = {
|
||||
CustomerArticleNumber: number;
|
||||
};
|
||||
|
||||
export const forecastData = async (data: IncomingForecastData) => {};
|
||||
@@ -12,5 +12,19 @@
|
||||
"description": "What is the db server",
|
||||
"moduleName": "system",
|
||||
"roles": ["systemAdmin"]
|
||||
},
|
||||
{
|
||||
"name": "v1Server",
|
||||
"value": "localhost",
|
||||
"description": "What is the port the v1app is on",
|
||||
"moduleName": "system",
|
||||
"roles": ["systemAdmin"]
|
||||
},
|
||||
{
|
||||
"name": "v1Port",
|
||||
"value": "3000",
|
||||
"description": "What is the port the v1app is on",
|
||||
"moduleName": "system",
|
||||
"roles": ["systemAdmin"]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
import { Router } from "express";
|
||||
import { and, asc, eq } from "drizzle-orm";
|
||||
import type { Request, Response } from "express";
|
||||
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||
import { Router } from "express";
|
||||
import { db } from "../../../../pkg/db/db.js";
|
||||
import { serverData } from "../../../../pkg/db/schema/servers.js";
|
||||
import { and, asc, eq } from "drizzle-orm";
|
||||
import { settings } from "../../../../pkg/db/schema/settings.js";
|
||||
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", async (req: Request, res: Response) => {
|
||||
const token = req.query.token;
|
||||
const token = req.query.token;
|
||||
|
||||
const conditions = [];
|
||||
const conditions = [];
|
||||
|
||||
if (token !== undefined) {
|
||||
conditions.push(eq(serverData.plantToken, `${token}`));
|
||||
}
|
||||
if (token !== undefined) {
|
||||
conditions.push(eq(serverData.plantToken, `${token}`));
|
||||
}
|
||||
|
||||
conditions.push(eq(serverData.active, true));
|
||||
conditions.push(eq(serverData.active, true));
|
||||
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.select()
|
||||
.from(serverData)
|
||||
.where(and(...conditions))
|
||||
.orderBy(asc(serverData.name))
|
||||
);
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.select()
|
||||
.from(settings)
|
||||
//.where(and(...conditions))
|
||||
.orderBy(asc(settings.name)),
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return res.status(400).json({ error: error });
|
||||
}
|
||||
res.status(200).json({ message: "Current Active server", data: data });
|
||||
if (error) {
|
||||
return res.status(400).json({ error: error });
|
||||
}
|
||||
res.status(200).json({ message: "Current Active server", data: data });
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
29
app/src/pkg/db/schema/forecastEDIData.ts
Normal file
29
app/src/pkg/db/schema/forecastEDIData.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
boolean,
|
||||
integer,
|
||||
jsonb,
|
||||
pgTable,
|
||||
real,
|
||||
text,
|
||||
timestamp,
|
||||
uuid,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
export const forecastData = pgTable("forecast_Data", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
customerArticleNumber: text("customer_article_number"),
|
||||
dateRequested: timestamp("date_requested").defaultNow(),
|
||||
quantity: real("quantity"),
|
||||
requestDate: timestamp("request_date").notNull(),
|
||||
article: integer("article"),
|
||||
customerID: integer("customer_id").notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const forecastDataSchema = createSelectSchema(forecastData);
|
||||
export const newForecastDataSchema = createInsertSchema(forecastData);
|
||||
|
||||
export type ForecastData = z.infer<typeof forecastDataSchema>;
|
||||
export type NewForecastData = z.infer<typeof newForecastDataSchema>;
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/_old')({
|
||||
component: RouteComponent,
|
||||
})
|
||||
|
||||
function RouteComponent() {
|
||||
return <div>Hello "/_old"!</div>
|
||||
}
|
||||
421
frontend/package-lock.json
generated
421
frontend/package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
@@ -41,6 +42,7 @@
|
||||
"react-calendar-timeline": "^0.30.0-beta.3",
|
||||
"react-day-picker": "^9.11.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"recharts": "^2.15.4",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
@@ -96,6 +98,7 @@
|
||||
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.3",
|
||||
@@ -480,6 +483,15 @@
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
@@ -1268,8 +1280,7 @@
|
||||
"version": "1.10.27",
|
||||
"resolved": "https://registry.npmjs.org/@interactjs/types/-/types-1.10.27.tgz",
|
||||
"integrity": "sha512-BUdv0cvs4H5ODuwft2Xp4eL8Vmi3LcihK42z0Ft/FbVJZoRioBsxH+LlsBdK4tAie7PqlKGy+1oyOncu1nQ6eA==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/fs-minipass": {
|
||||
"version": "4.0.1",
|
||||
@@ -1644,6 +1655,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz",
|
||||
"integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.1"
|
||||
},
|
||||
"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-collection": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
|
||||
@@ -3314,6 +3355,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.131.36.tgz",
|
||||
"integrity": "sha512-9tglm3Rf9qkANBIyYLbGlOjNj7GDBr0jOEOaADfwiGV3Ua3P562MGn7nHUOrfRfA6u2MCg0EKJ+LH7AeWxAqkg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.131.2",
|
||||
"@tanstack/react-store": "^0.7.0",
|
||||
@@ -3398,6 +3440,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.131.36.tgz",
|
||||
"integrity": "sha512-faGrKwrJBjJDxbcyeaOXgQcyccmzIGkwk+tnFeJuMTnH5OMfArykYnTZ9BxIrlOY2Mori9DXmYKMlig6mVqmGA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.131.2",
|
||||
"@tanstack/store": "^0.7.0",
|
||||
@@ -3581,6 +3624,69 @@
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-array": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
|
||||
"integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-color": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
|
||||
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-ease": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
|
||||
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-interpolate": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
|
||||
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-color": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-path": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
|
||||
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-scale": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
|
||||
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-time": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-shape": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
|
||||
"integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-path": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-time": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
|
||||
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-timer": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
|
||||
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
@@ -3607,6 +3713,7 @@
|
||||
"integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.10.0"
|
||||
}
|
||||
@@ -3616,6 +3723,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz",
|
||||
"integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
@@ -3636,6 +3744,7 @@
|
||||
"integrity": "sha512-xG7xaBMJCpcK0RpN8jDbAACQo54ycO6h4dSSmgv8+fu6ZIAdANkx/WsawASUjVXYfy+J9AbUpRMNNEsXCDfDBQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0"
|
||||
}
|
||||
@@ -3686,6 +3795,7 @@
|
||||
"integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.41.0",
|
||||
"@typescript-eslint/types": "8.41.0",
|
||||
@@ -3921,6 +4031,7 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -4218,6 +4329,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001737",
|
||||
"electron-to-chromium": "^1.5.211",
|
||||
@@ -4437,7 +4549,129 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/d3-array": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
||||
"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"internmap": "1 - 2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
||||
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-ease": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
||||
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-format": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
||||
"integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-interpolate": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
||||
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-color": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-path": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
|
||||
"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-scale": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
||||
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "2.10.0 - 3",
|
||||
"d3-format": "1 - 3",
|
||||
"d3-interpolate": "1.2.0 - 3",
|
||||
"d3-time": "2.1.1 - 3",
|
||||
"d3-time-format": "2 - 4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-shape": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
||||
"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-path": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-time": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
|
||||
"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "2 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-time-format": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
|
||||
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-time": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-timer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
||||
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
@@ -4480,6 +4714,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decimal.js-light": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
|
||||
"integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/decode-formdata": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-formdata/-/decode-formdata-0.9.0.tgz",
|
||||
@@ -4539,6 +4779,16 @@
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-helpers": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.7",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@@ -4736,6 +4986,7 @@
|
||||
"integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -4922,6 +5173,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
@@ -4929,6 +5186,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-equals": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.2.tgz",
|
||||
"integrity": "sha512-6rxyATwPCkaFIL3JLqw8qXqMpIZ942pTX/tbQFkRsDGblS8tNGtlUauA/+mt6RUfqn/4MoEr+WDkYoIQbibWuQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||
@@ -5331,6 +5597,15 @@
|
||||
"@interactjs/types": "1.10.27"
|
||||
}
|
||||
},
|
||||
"node_modules/internmap": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
|
||||
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
@@ -5430,7 +5705,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
@@ -5783,6 +6057,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
@@ -5992,6 +6278,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
@@ -6148,6 +6443,23 @@
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
@@ -6216,6 +6528,7 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
||||
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -6264,6 +6577,7 @@
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
||||
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
@@ -6271,6 +6585,12 @@
|
||||
"react": "^19.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
|
||||
@@ -6318,6 +6638,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-smooth": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
|
||||
"integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-equals": "^5.0.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
||||
@@ -6340,6 +6675,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"dom-helpers": "^5.0.1",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.6.0",
|
||||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -6380,6 +6731,38 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/recharts": {
|
||||
"version": "2.15.4",
|
||||
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz",
|
||||
"integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clsx": "^2.0.0",
|
||||
"eventemitter3": "^4.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"react-is": "^18.3.1",
|
||||
"react-smooth": "^4.0.4",
|
||||
"recharts-scale": "^0.4.4",
|
||||
"tiny-invariant": "^1.3.1",
|
||||
"victory-vendor": "^36.6.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/recharts-scale": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
|
||||
"integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"decimal.js-light": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect-metadata": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
|
||||
@@ -6510,6 +6893,7 @@
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz",
|
||||
"integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@@ -6742,7 +7126,8 @@
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
|
||||
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
@@ -6788,6 +7173,7 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -6894,6 +7280,7 @@
|
||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -7074,11 +7461,34 @@
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/victory-vendor": {
|
||||
"version": "36.9.2",
|
||||
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
|
||||
"integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==",
|
||||
"license": "MIT AND ISC",
|
||||
"dependencies": {
|
||||
"@types/d3-array": "^3.0.3",
|
||||
"@types/d3-ease": "^3.0.0",
|
||||
"@types/d3-interpolate": "^3.0.1",
|
||||
"@types/d3-scale": "^4.0.2",
|
||||
"@types/d3-shape": "^3.1.0",
|
||||
"@types/d3-time": "^3.0.0",
|
||||
"@types/d3-timer": "^3.0.0",
|
||||
"d3-array": "^3.1.6",
|
||||
"d3-ease": "^3.0.1",
|
||||
"d3-interpolate": "^3.0.1",
|
||||
"d3-scale": "^4.0.2",
|
||||
"d3-shape": "^3.1.0",
|
||||
"d3-time": "^3.0.0",
|
||||
"d3-timer": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz",
|
||||
"integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -7170,6 +7580,7 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
@@ -43,6 +44,7 @@
|
||||
"react-calendar-timeline": "^0.30.0-beta.3",
|
||||
"react-day-picker": "^9.11.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"recharts": "^2.15.4",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
|
||||
@@ -49,6 +49,9 @@ export default function Nav() {
|
||||
<DropdownMenuItem>
|
||||
<Link to="/user/profile">Profile</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link to="/old">LST-Old</Link>
|
||||
</DropdownMenuItem>
|
||||
{/* <DropdownMenuItem>Billing</DropdownMenuItem>
|
||||
<DropdownMenuItem>Team</DropdownMenuItem>
|
||||
<DropdownMenuItem>Subscription</DropdownMenuItem> */}
|
||||
|
||||
355
frontend/src/components/ui/chart.tsx
Normal file
355
frontend/src/components/ui/chart.tsx
Normal file
@@ -0,0 +1,355 @@
|
||||
import * as React from "react"
|
||||
import * as RechartsPrimitive from "recharts"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
// Format: { THEME_NAME: CSS_SELECTOR }
|
||||
const THEMES = { light: "", dark: ".dark" } as const
|
||||
|
||||
export type ChartConfig = {
|
||||
[k in string]: {
|
||||
label?: React.ReactNode
|
||||
icon?: React.ComponentType
|
||||
} & (
|
||||
| { color?: string; theme?: never }
|
||||
| { color?: never; theme: Record<keyof typeof THEMES, string> }
|
||||
)
|
||||
}
|
||||
|
||||
type ChartContextProps = {
|
||||
config: ChartConfig
|
||||
}
|
||||
|
||||
const ChartContext = React.createContext<ChartContextProps | null>(null)
|
||||
|
||||
function useChart() {
|
||||
const context = React.useContext(ChartContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useChart must be used within a <ChartContainer />")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
function ChartContainer({
|
||||
id,
|
||||
className,
|
||||
children,
|
||||
config,
|
||||
...props
|
||||
}: React.ComponentProps<"div"> & {
|
||||
config: ChartConfig
|
||||
children: React.ComponentProps<
|
||||
typeof RechartsPrimitive.ResponsiveContainer
|
||||
>["children"]
|
||||
}) {
|
||||
const uniqueId = React.useId()
|
||||
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
|
||||
|
||||
return (
|
||||
<ChartContext.Provider value={{ config }}>
|
||||
<div
|
||||
data-slot="chart"
|
||||
data-chart={chartId}
|
||||
className={cn(
|
||||
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChartStyle id={chartId} config={config} />
|
||||
<RechartsPrimitive.ResponsiveContainer>
|
||||
{children}
|
||||
</RechartsPrimitive.ResponsiveContainer>
|
||||
</div>
|
||||
</ChartContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
|
||||
const colorConfig = Object.entries(config).filter(
|
||||
([, config]) => config.theme || config.color
|
||||
)
|
||||
|
||||
if (!colorConfig.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: Object.entries(THEMES)
|
||||
.map(
|
||||
([theme, prefix]) => `
|
||||
${prefix} [data-chart=${id}] {
|
||||
${colorConfig
|
||||
.map(([key, itemConfig]) => {
|
||||
const color =
|
||||
itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
|
||||
itemConfig.color
|
||||
return color ? ` --color-${key}: ${color};` : null
|
||||
})
|
||||
.join("\n")}
|
||||
}
|
||||
`
|
||||
)
|
||||
.join("\n"),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const ChartTooltip = RechartsPrimitive.Tooltip
|
||||
|
||||
function ChartTooltipContent({
|
||||
active,
|
||||
payload,
|
||||
className,
|
||||
indicator = "dot",
|
||||
hideLabel = false,
|
||||
hideIndicator = false,
|
||||
label,
|
||||
labelFormatter,
|
||||
labelClassName,
|
||||
formatter,
|
||||
color,
|
||||
nameKey,
|
||||
labelKey,
|
||||
}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
|
||||
React.ComponentProps<"div"> & {
|
||||
hideLabel?: boolean
|
||||
hideIndicator?: boolean
|
||||
indicator?: "line" | "dot" | "dashed"
|
||||
nameKey?: string
|
||||
labelKey?: string
|
||||
}) {
|
||||
const { config } = useChart()
|
||||
|
||||
const tooltipLabel = React.useMemo(() => {
|
||||
if (hideLabel || !payload?.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [item] = payload
|
||||
const key = `${labelKey || item?.dataKey || item?.name || "value"}`
|
||||
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
||||
const value =
|
||||
!labelKey && typeof label === "string"
|
||||
? config[label as keyof typeof config]?.label || label
|
||||
: itemConfig?.label
|
||||
|
||||
if (labelFormatter) {
|
||||
return (
|
||||
<div className={cn("font-medium", labelClassName)}>
|
||||
{labelFormatter(value, payload)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <div className={cn("font-medium", labelClassName)}>{value}</div>
|
||||
}, [
|
||||
label,
|
||||
labelFormatter,
|
||||
payload,
|
||||
hideLabel,
|
||||
labelClassName,
|
||||
config,
|
||||
labelKey,
|
||||
])
|
||||
|
||||
if (!active || !payload?.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const nestLabel = payload.length === 1 && indicator !== "dot"
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{!nestLabel ? tooltipLabel : null}
|
||||
<div className="grid gap-1.5">
|
||||
{payload
|
||||
.filter((item) => item.type !== "none")
|
||||
.map((item, index) => {
|
||||
const key = `${nameKey || item.name || item.dataKey || "value"}`
|
||||
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
||||
const indicatorColor = color || item.payload.fill || item.color
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.dataKey}
|
||||
className={cn(
|
||||
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
|
||||
indicator === "dot" && "items-center"
|
||||
)}
|
||||
>
|
||||
{formatter && item?.value !== undefined && item.name ? (
|
||||
formatter(item.value, item.name, item, index, item.payload)
|
||||
) : (
|
||||
<>
|
||||
{itemConfig?.icon ? (
|
||||
<itemConfig.icon />
|
||||
) : (
|
||||
!hideIndicator && (
|
||||
<div
|
||||
className={cn(
|
||||
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
|
||||
{
|
||||
"h-2.5 w-2.5": indicator === "dot",
|
||||
"w-1": indicator === "line",
|
||||
"w-0 border-[1.5px] border-dashed bg-transparent":
|
||||
indicator === "dashed",
|
||||
"my-0.5": nestLabel && indicator === "dashed",
|
||||
}
|
||||
)}
|
||||
style={
|
||||
{
|
||||
"--color-bg": indicatorColor,
|
||||
"--color-border": indicatorColor,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-1 justify-between leading-none",
|
||||
nestLabel ? "items-end" : "items-center"
|
||||
)}
|
||||
>
|
||||
<div className="grid gap-1.5">
|
||||
{nestLabel ? tooltipLabel : null}
|
||||
<span className="text-muted-foreground">
|
||||
{itemConfig?.label || item.name}
|
||||
</span>
|
||||
</div>
|
||||
{item.value && (
|
||||
<span className="text-foreground font-mono font-medium tabular-nums">
|
||||
{item.value.toLocaleString()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ChartLegend = RechartsPrimitive.Legend
|
||||
|
||||
function ChartLegendContent({
|
||||
className,
|
||||
hideIcon = false,
|
||||
payload,
|
||||
verticalAlign = "bottom",
|
||||
nameKey,
|
||||
}: React.ComponentProps<"div"> &
|
||||
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
|
||||
hideIcon?: boolean
|
||||
nameKey?: string
|
||||
}) {
|
||||
const { config } = useChart()
|
||||
|
||||
if (!payload?.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center gap-4",
|
||||
verticalAlign === "top" ? "pb-3" : "pt-3",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{payload
|
||||
.filter((item) => item.type !== "none")
|
||||
.map((item) => {
|
||||
const key = `${nameKey || item.dataKey || "value"}`
|
||||
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.value}
|
||||
className={cn(
|
||||
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
|
||||
)}
|
||||
>
|
||||
{itemConfig?.icon && !hideIcon ? (
|
||||
<itemConfig.icon />
|
||||
) : (
|
||||
<div
|
||||
className="h-2 w-2 shrink-0 rounded-[2px]"
|
||||
style={{
|
||||
backgroundColor: item.color,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{itemConfig?.label}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Helper to extract item config from a payload.
|
||||
function getPayloadConfigFromPayload(
|
||||
config: ChartConfig,
|
||||
payload: unknown,
|
||||
key: string
|
||||
) {
|
||||
if (typeof payload !== "object" || payload === null) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const payloadPayload =
|
||||
"payload" in payload &&
|
||||
typeof payload.payload === "object" &&
|
||||
payload.payload !== null
|
||||
? payload.payload
|
||||
: undefined
|
||||
|
||||
let configLabelKey: string = key
|
||||
|
||||
if (
|
||||
key in payload &&
|
||||
typeof payload[key as keyof typeof payload] === "string"
|
||||
) {
|
||||
configLabelKey = payload[key as keyof typeof payload] as string
|
||||
} else if (
|
||||
payloadPayload &&
|
||||
key in payloadPayload &&
|
||||
typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
|
||||
) {
|
||||
configLabelKey = payloadPayload[
|
||||
key as keyof typeof payloadPayload
|
||||
] as string
|
||||
}
|
||||
|
||||
return configLabelKey in config
|
||||
? config[configLabelKey]
|
||||
: config[key as keyof typeof config]
|
||||
}
|
||||
|
||||
export {
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartStyle,
|
||||
}
|
||||
31
frontend/src/components/ui/collapsible.tsx
Normal file
31
frontend/src/components/ui/collapsible.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
|
||||
|
||||
function Collapsible({
|
||||
...props
|
||||
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
|
||||
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
|
||||
}
|
||||
|
||||
function CollapsibleTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
|
||||
return (
|
||||
<CollapsiblePrimitive.CollapsibleTrigger
|
||||
data-slot="collapsible-trigger"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function CollapsibleContent({
|
||||
...props
|
||||
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
|
||||
return (
|
||||
<CollapsiblePrimitive.CollapsibleContent
|
||||
data-slot="collapsible-content"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
|
||||
141
frontend/src/components/ui/dialog.tsx
Normal file
141
frontend/src/components/ui/dialog.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import * as React from "react"
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import { XIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Dialog({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
||||
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
||||
}
|
||||
|
||||
function DialogTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
||||
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
||||
}
|
||||
|
||||
function DialogPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
||||
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
||||
}
|
||||
|
||||
function DialogClose({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
||||
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
||||
}
|
||||
|
||||
function DialogOverlay({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
||||
return (
|
||||
<DialogPrimitive.Overlay
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogContent({
|
||||
className,
|
||||
children,
|
||||
showCloseButton = true,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
||||
showCloseButton?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
||||
>
|
||||
<XIcon />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="dialog-header"
|
||||
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="dialog-footer"
|
||||
className={cn(
|
||||
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
||||
return (
|
||||
<DialogPrimitive.Title
|
||||
data-slot="dialog-title"
|
||||
className={cn("text-lg leading-none font-semibold", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
||||
return (
|
||||
<DialogPrimitive.Description
|
||||
data-slot="dialog-description"
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
}
|
||||
18
frontend/src/components/ui/textarea.tsx
Normal file
18
frontend/src/components/ui/textarea.tsx
Normal 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 }
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { redirect, useNavigate, useRouter } from "@tanstack/react-router";
|
||||
import { createAuthClient } from "better-auth/client";
|
||||
import { usernameClient } from "better-auth/client/plugins";
|
||||
import { create } from "zustand";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useEffect } from "react";
|
||||
import { redirect, useNavigate, useRouter } from "@tanstack/react-router";
|
||||
import { create } from "zustand";
|
||||
import { api } from "./axiosAPI";
|
||||
|
||||
// ---- TYPES ----
|
||||
@@ -11,184 +11,190 @@ export type Session = typeof authClient.$Infer.Session | null;
|
||||
|
||||
// Zustand store type
|
||||
type SessionState = {
|
||||
session: Session;
|
||||
setSession: (session: Session) => void;
|
||||
clearSession: () => void;
|
||||
session: Session;
|
||||
setSession: (session: Session) => void;
|
||||
clearSession: () => void;
|
||||
};
|
||||
|
||||
export type UserRoles = {
|
||||
userRoleId: string;
|
||||
userId: string;
|
||||
module: string;
|
||||
role: "systemAdmin" | "admin" | "manager" | "user" | "viewer";
|
||||
userRoleId: string;
|
||||
userId: string;
|
||||
module: string;
|
||||
role:
|
||||
| "viewer"
|
||||
| "technician"
|
||||
| "supervisor"
|
||||
| "manager"
|
||||
| "admin"
|
||||
| "systemAdmin";
|
||||
};
|
||||
|
||||
type UserRoleState = {
|
||||
userRoles: UserRoles[] | null;
|
||||
fetchRoles: () => Promise<void>;
|
||||
clearRoles: () => void;
|
||||
userRoles: UserRoles[] | null;
|
||||
fetchRoles: () => Promise<void>;
|
||||
clearRoles: () => void;
|
||||
};
|
||||
|
||||
// ---- ZUSTAND STORE ----
|
||||
export const useAuth = create<SessionState>((set) => ({
|
||||
session: null,
|
||||
setSession: (session) => set({ session }),
|
||||
clearSession: () => set({ session: null }),
|
||||
session: null,
|
||||
setSession: (session) => set({ session }),
|
||||
clearSession: () => set({ session: null }),
|
||||
}));
|
||||
|
||||
export const useUserRoles = create<UserRoleState>((set) => ({
|
||||
userRoles: null,
|
||||
fetchRoles: async () => {
|
||||
try {
|
||||
const res = await api.get("/api/user/roles");
|
||||
const roles = res.data;
|
||||
set({ userRoles: roles.data });
|
||||
} catch (err) {
|
||||
console.error("Error fetching roles:", err);
|
||||
set({ userRoles: null });
|
||||
}
|
||||
},
|
||||
clearRoles: () => set({ userRoles: null }),
|
||||
userRoles: null,
|
||||
fetchRoles: async () => {
|
||||
try {
|
||||
const res = await api.get("/api/user/roles");
|
||||
const roles = res.data;
|
||||
set({ userRoles: roles.data });
|
||||
} catch (err) {
|
||||
console.error("Error fetching roles:", err);
|
||||
set({ userRoles: null });
|
||||
}
|
||||
},
|
||||
clearRoles: () => set({ userRoles: null }),
|
||||
}));
|
||||
|
||||
export function userAccess(
|
||||
moduleName: string | null,
|
||||
roles: UserRoles["role"] | UserRoles["role"][]
|
||||
moduleName: string | null,
|
||||
roles: UserRoles["role"] | UserRoles["role"][],
|
||||
): boolean {
|
||||
const { userRoles } = useUserRoles();
|
||||
const { userRoles } = useUserRoles();
|
||||
|
||||
if (!userRoles) return false;
|
||||
if (!userRoles) return false;
|
||||
|
||||
const roleArray = Array.isArray(roles) ? roles : [roles];
|
||||
const roleArray = Array.isArray(roles) ? roles : [roles];
|
||||
|
||||
return userRoles.some(
|
||||
(m) =>
|
||||
(moduleName ? m.module === moduleName : true) &&
|
||||
roleArray.includes(m.role)
|
||||
);
|
||||
return userRoles.some(
|
||||
(m) =>
|
||||
(moduleName ? m.module === moduleName : true) &&
|
||||
roleArray.includes(m.role),
|
||||
);
|
||||
}
|
||||
|
||||
export async function checkUserAccess({
|
||||
allowedRoles,
|
||||
moduleName,
|
||||
allowedRoles,
|
||||
moduleName,
|
||||
}: {
|
||||
allowedRoles: UserRoles["role"][];
|
||||
moduleName?: string;
|
||||
//location: { pathname: string; search: string };
|
||||
allowedRoles: UserRoles["role"][];
|
||||
moduleName?: string;
|
||||
//location: { pathname: string; search: string };
|
||||
}) {
|
||||
try {
|
||||
// fetch roles from your API (credentials required)
|
||||
const res = await api.get("/api/user/roles", { withCredentials: true });
|
||||
const roles = res.data.data as UserRoles[];
|
||||
try {
|
||||
// fetch roles from your API (credentials required)
|
||||
const res = await api.get("/api/user/roles", { withCredentials: true });
|
||||
const roles = res.data.data as UserRoles[];
|
||||
|
||||
const hasAccess = roles.some(
|
||||
(r) =>
|
||||
(moduleName ? r.module === moduleName : true) &&
|
||||
allowedRoles.includes(r.role)
|
||||
);
|
||||
const hasAccess = roles.some(
|
||||
(r) =>
|
||||
(moduleName ? r.module === moduleName : true) &&
|
||||
allowedRoles.includes(r.role),
|
||||
);
|
||||
|
||||
if (!hasAccess) {
|
||||
throw redirect({
|
||||
to: "/",
|
||||
search: { from: location.pathname + location.search },
|
||||
});
|
||||
}
|
||||
if (!hasAccess) {
|
||||
throw redirect({
|
||||
to: "/",
|
||||
search: { from: location.pathname + location.search },
|
||||
});
|
||||
}
|
||||
|
||||
// return roles so the route component can use them if needed
|
||||
return roles;
|
||||
} catch {
|
||||
throw redirect({
|
||||
to: "/login",
|
||||
search: { redirect: location.pathname + location.search },
|
||||
});
|
||||
}
|
||||
// return roles so the route component can use them if needed
|
||||
return roles;
|
||||
} catch {
|
||||
throw redirect({
|
||||
to: "/login",
|
||||
search: { redirect: location.pathname + location.search },
|
||||
});
|
||||
}
|
||||
}
|
||||
// ---- BETTER AUTH CLIENT ----
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: `${window.location.origin}/lst/api/auth`,
|
||||
plugins: [usernameClient()],
|
||||
callbacks: {
|
||||
callbacks: {
|
||||
onUpdate: (res: any) => {
|
||||
// res has strong type
|
||||
// res.data is `Session | null`
|
||||
useAuth.getState().setSession(res?.data ?? null);
|
||||
},
|
||||
onSignIn: (res: any) => {
|
||||
console.log("Setting session to ", res?.data);
|
||||
useAuth.getState().setSession(res?.data ?? null);
|
||||
},
|
||||
onSignOut: () => {
|
||||
useAuth.getState().clearSession();
|
||||
},
|
||||
},
|
||||
},
|
||||
baseURL: `${window.location.origin}/lst/api/auth`,
|
||||
plugins: [usernameClient()],
|
||||
callbacks: {
|
||||
callbacks: {
|
||||
onUpdate: (res: any) => {
|
||||
// res has strong type
|
||||
// res.data is `Session | null`
|
||||
useAuth.getState().setSession(res?.data ?? null);
|
||||
},
|
||||
onSignIn: (res: any) => {
|
||||
console.log("Setting session to ", res?.data);
|
||||
useAuth.getState().setSession(res?.data ?? null);
|
||||
},
|
||||
onSignOut: () => {
|
||||
useAuth.getState().clearSession();
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ---- AUTH API HELPERS ----
|
||||
export async function signin(data: { username: string; password: string }) {
|
||||
const res = await authClient.signIn.username(data);
|
||||
const res = await authClient.signIn.username(data);
|
||||
|
||||
if (res.error) throw res.error;
|
||||
await authClient.getSession();
|
||||
return res.data;
|
||||
if (res.error) throw res.error;
|
||||
await authClient.getSession();
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export const useLogout = () => {
|
||||
const { clearSession } = useAuth();
|
||||
const { clearRoles } = useUserRoles();
|
||||
const navigate = useNavigate();
|
||||
const { clearSession } = useAuth();
|
||||
const { clearRoles } = useUserRoles();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const router = useRouter();
|
||||
const logout = async () => {
|
||||
await authClient.signOut();
|
||||
const router = useRouter();
|
||||
const logout = async () => {
|
||||
await authClient.signOut();
|
||||
|
||||
router.invalidate();
|
||||
router.clearCache();
|
||||
clearSession();
|
||||
clearRoles();
|
||||
navigate({ to: "/" });
|
||||
window.location.reload();
|
||||
};
|
||||
router.invalidate();
|
||||
router.clearCache();
|
||||
clearSession();
|
||||
clearRoles();
|
||||
navigate({ to: "/" });
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return logout;
|
||||
return logout;
|
||||
};
|
||||
|
||||
export async function getSession() {
|
||||
const res = await authClient.getSession({
|
||||
query: { disableCookieCache: true },
|
||||
});
|
||||
if (res.error) return null;
|
||||
return res.data;
|
||||
const res = await authClient.getSession({
|
||||
query: { disableCookieCache: true },
|
||||
});
|
||||
if (res.error) return null;
|
||||
return res.data;
|
||||
}
|
||||
|
||||
// ---- REACT QUERY INTEGRATION ----
|
||||
export function useSession() {
|
||||
const { setSession, clearSession } = useAuth();
|
||||
const qc = useQueryClient();
|
||||
const { setSession, clearSession } = useAuth();
|
||||
const qc = useQueryClient();
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ["session"],
|
||||
queryFn: getSession,
|
||||
refetchInterval: 60_000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
const query = useQuery({
|
||||
queryKey: ["session"],
|
||||
queryFn: getSession,
|
||||
refetchInterval: 60_000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
|
||||
//console.log("Auth Check", query.data);
|
||||
// react to data change
|
||||
useEffect(() => {
|
||||
if (query.data !== undefined) {
|
||||
setSession(query.data);
|
||||
}
|
||||
}, [query.data, setSession]);
|
||||
//console.log("Auth Check", query.data);
|
||||
// react to data change
|
||||
useEffect(() => {
|
||||
if (query.data !== undefined) {
|
||||
setSession(query.data);
|
||||
}
|
||||
}, [query.data, setSession]);
|
||||
|
||||
// react to error
|
||||
useEffect(() => {
|
||||
if (query.error) {
|
||||
clearSession();
|
||||
qc.removeQueries({ queryKey: ["session"] });
|
||||
}
|
||||
}, [query.error, qc, clearSession]);
|
||||
// react to error
|
||||
useEffect(() => {
|
||||
if (query.error) {
|
||||
clearSession();
|
||||
qc.removeQueries({ queryKey: ["session"] });
|
||||
}
|
||||
}, [query.error, qc, clearSession]);
|
||||
|
||||
return query;
|
||||
return query;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
import { useRouter } from "@tanstack/react-router";
|
||||
import { useEffect } from "react";
|
||||
import { useModuleStore } from "../../routes/_old/old/-lib/store/useModuleStore";
|
||||
import { useSettingStore } from "../../routes/_old/old/-lib/store/useSettings";
|
||||
import { useSubModuleStore } from "../../routes/_old/old/-lib/store/useSubModuleStore";
|
||||
import { useSession, useUserRoles } from "../authClient";
|
||||
|
||||
export function SessionGuard({ children }: { children: React.ReactNode }) {
|
||||
const { data: session, isLoading } = useSession();
|
||||
const { fetchRoles } = useUserRoles();
|
||||
const { data: session, isLoading } = useSession();
|
||||
const { fetchRoles } = useUserRoles();
|
||||
const { fetchModules } = useModuleStore();
|
||||
const { fetchSettings } = useSettingStore();
|
||||
const { fetchSubModules } = useSubModuleStore();
|
||||
const router = useRouter();
|
||||
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
// if (!isLoading && !session) {
|
||||
// router.navigate({ to: "/" }); // redirect if not logged in
|
||||
// }
|
||||
fetchModules();
|
||||
fetchSettings();
|
||||
fetchSubModules();
|
||||
//if (session) {
|
||||
fetchRoles();
|
||||
//}
|
||||
}, [isLoading, session, router]);
|
||||
|
||||
useEffect(() => {
|
||||
// if (!isLoading && !session) {
|
||||
// router.navigate({ to: "/" }); // redirect if not logged in
|
||||
// }
|
||||
if (session) {
|
||||
fetchRoles();
|
||||
}
|
||||
}, [isLoading, session, router]);
|
||||
|
||||
if (isLoading) return <div>App Loading</div>;
|
||||
return <>{children}</>;
|
||||
if (isLoading) return <div>App Loading</div>;
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
@@ -11,199 +11,251 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as AdminLayoutRouteRouteImport } from './routes/_adminLayout/route'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
import { Route as authLoginRouteImport } from './routes/(auth)/login'
|
||||
import { Route as mobileStuffMobileLayoutRouteRouteImport } from './routes/(mobileStuff)/_mobileLayout/route'
|
||||
import { Route as authUserIndexRouteImport } from './routes/(auth)/user/index'
|
||||
import { Route as AdminLayoutAdminSettingsRouteImport } from './routes/_adminLayout/admin/settings'
|
||||
import { Route as AdminLayoutAdminServersRouteImport } from './routes/_adminLayout/admin/servers'
|
||||
import { Route as logisticsLogisticsDeliveryScheduleRouteImport } from './routes/(logistics)/logistics/deliverySchedule'
|
||||
import { Route as authUserSignupRouteImport } from './routes/(auth)/user/signup'
|
||||
import { Route as authUserResetpasswordRouteImport } from './routes/(auth)/user/resetpassword'
|
||||
import { Route as authUserProfileRouteImport } from './routes/(auth)/user/profile'
|
||||
import { Route as AdminLayoutAdminUsersRouteRouteImport } from './routes/_adminLayout/admin/_users/route'
|
||||
import { Route as mobileStuffMobileLayoutMIndexRouteImport } from './routes/(mobileStuff)/_mobileLayout/m/index'
|
||||
import { Route as AdminLayoutAdminUsersUsersRouteImport } from './routes/_adminLayout/admin/_users/users'
|
||||
import { Route as AdminLayoutAdminUsersProdUsersRouteImport } from './routes/_adminLayout/admin/_users/prodUsers'
|
||||
import { Route as mobileStuffMobileLayoutMRelocateRouteImport } from './routes/(mobileStuff)/_mobileLayout/m/relocate'
|
||||
import { Route as mobileStuffMobileLayoutMDeliveryRouteImport } from './routes/(mobileStuff)/_mobileLayout/m/delivery'
|
||||
import { Route as mobileStuffMobileLayoutMCyclecountsRouteImport } from './routes/(mobileStuff)/_mobileLayout/m/cyclecounts'
|
||||
import { Route as AppRouteRouteImport } from './routes/_app/route'
|
||||
import { Route as AppIndexRouteImport } from './routes/_app/index'
|
||||
import { Route as OldOldRouteRouteImport } from './routes/_old/old/route'
|
||||
import { Route as MobileMobileLayoutRouteRouteImport } from './routes/_mobile/_mobileLayout/route'
|
||||
import { Route as AppAdminLayoutRouteRouteImport } from './routes/_app/_adminLayout/route'
|
||||
import { Route as OldOldIndexRouteImport } from './routes/_old/old/index'
|
||||
import { Route as AppauthLoginRouteImport } from './routes/_app/(auth)/login'
|
||||
import { Route as MobileMobileLayoutMIndexRouteImport } from './routes/_mobile/_mobileLayout/m/index'
|
||||
import { Route as AppauthUserIndexRouteImport } from './routes/_app/(auth)/user/index'
|
||||
import { Route as MobileMobileLayoutMRelocateRouteImport } from './routes/_mobile/_mobileLayout/m/relocate'
|
||||
import { Route as MobileMobileLayoutMDeliveryRouteImport } from './routes/_mobile/_mobileLayout/m/delivery'
|
||||
import { Route as MobileMobileLayoutMCyclecountsRouteImport } from './routes/_mobile/_mobileLayout/m/cyclecounts'
|
||||
import { Route as AppAdminLayoutAdminSettingsRouteImport } from './routes/_app/_adminLayout/admin/settings'
|
||||
import { Route as AppAdminLayoutAdminServersRouteImport } from './routes/_app/_adminLayout/admin/servers'
|
||||
import { Route as ApplogisticsLogisticsDeliveryScheduleRouteImport } from './routes/_app/(logistics)/logistics/deliverySchedule'
|
||||
import { Route as AppauthUserSignupRouteImport } from './routes/_app/(auth)/user/signup'
|
||||
import { Route as AppauthUserResetpasswordRouteImport } from './routes/_app/(auth)/user/resetpassword'
|
||||
import { Route as AppauthUserProfileRouteImport } from './routes/_app/(auth)/user/profile'
|
||||
import { Route as AppAdminLayoutAdminUsersRouteRouteImport } from './routes/_app/_adminLayout/admin/_users/route'
|
||||
import { Route as OldOldlogisticsSiloAdjustmentsIndexRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/index'
|
||||
import { Route as OldOldlogisticsSiloAdjustmentsHistRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/$hist'
|
||||
import { Route as AppAdminLayoutAdminUsersUsersRouteImport } from './routes/_app/_adminLayout/admin/_users/users'
|
||||
import { Route as AppAdminLayoutAdminUsersProdUsersRouteImport } from './routes/_app/_adminLayout/admin/_users/prodUsers'
|
||||
import { Route as OldOldlogisticsSiloAdjustmentsCommentCommentRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/comment/$comment'
|
||||
|
||||
const mobileStuffRouteImport = createFileRoute('/(mobileStuff)')()
|
||||
const AdminLayoutAdminRouteImport = createFileRoute('/_adminLayout/admin')()
|
||||
const AppAdminLayoutAdminRouteImport = createFileRoute(
|
||||
'/_app/_adminLayout/admin',
|
||||
)()
|
||||
|
||||
const mobileStuffRoute = mobileStuffRouteImport.update({
|
||||
id: '/(mobileStuff)',
|
||||
const AppRouteRoute = AppRouteRouteImport.update({
|
||||
id: '/_app',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AdminLayoutRouteRoute = AdminLayoutRouteRouteImport.update({
|
||||
id: '/_adminLayout',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
const AppIndexRoute = AppIndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const OldOldRouteRoute = OldOldRouteRouteImport.update({
|
||||
id: '/_old/old',
|
||||
path: '/old',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AdminLayoutAdminRoute = AdminLayoutAdminRouteImport.update({
|
||||
const MobileMobileLayoutRouteRoute = MobileMobileLayoutRouteRouteImport.update({
|
||||
id: '/_mobile/_mobileLayout',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AppAdminLayoutRouteRoute = AppAdminLayoutRouteRouteImport.update({
|
||||
id: '/_adminLayout',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminRoute = AppAdminLayoutAdminRouteImport.update({
|
||||
id: '/admin',
|
||||
path: '/admin',
|
||||
getParentRoute: () => AdminLayoutRouteRoute,
|
||||
getParentRoute: () => AppAdminLayoutRouteRoute,
|
||||
} as any)
|
||||
const authLoginRoute = authLoginRouteImport.update({
|
||||
const OldOldIndexRoute = OldOldIndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => OldOldRouteRoute,
|
||||
} as any)
|
||||
const AppauthLoginRoute = AppauthLoginRouteImport.update({
|
||||
id: '/(auth)/login',
|
||||
path: '/login',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const mobileStuffMobileLayoutRouteRoute =
|
||||
mobileStuffMobileLayoutRouteRouteImport.update({
|
||||
id: '/_mobileLayout',
|
||||
getParentRoute: () => mobileStuffRoute,
|
||||
} as any)
|
||||
const authUserIndexRoute = authUserIndexRouteImport.update({
|
||||
id: '/(auth)/user/',
|
||||
path: '/user/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AdminLayoutAdminSettingsRoute =
|
||||
AdminLayoutAdminSettingsRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
getParentRoute: () => AdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const AdminLayoutAdminServersRoute = AdminLayoutAdminServersRouteImport.update({
|
||||
id: '/servers',
|
||||
path: '/servers',
|
||||
getParentRoute: () => AdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const logisticsLogisticsDeliveryScheduleRoute =
|
||||
logisticsLogisticsDeliveryScheduleRouteImport.update({
|
||||
id: '/(logistics)/logistics/deliverySchedule',
|
||||
path: '/logistics/deliverySchedule',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const authUserSignupRoute = authUserSignupRouteImport.update({
|
||||
id: '/(auth)/user/signup',
|
||||
path: '/user/signup',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const authUserResetpasswordRoute = authUserResetpasswordRouteImport.update({
|
||||
id: '/(auth)/user/resetpassword',
|
||||
path: '/user/resetpassword',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const authUserProfileRoute = authUserProfileRouteImport.update({
|
||||
id: '/(auth)/user/profile',
|
||||
path: '/user/profile',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AdminLayoutAdminUsersRouteRoute =
|
||||
AdminLayoutAdminUsersRouteRouteImport.update({
|
||||
id: '/_users',
|
||||
getParentRoute: () => AdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const mobileStuffMobileLayoutMIndexRoute =
|
||||
mobileStuffMobileLayoutMIndexRouteImport.update({
|
||||
const MobileMobileLayoutMIndexRoute =
|
||||
MobileMobileLayoutMIndexRouteImport.update({
|
||||
id: '/m/',
|
||||
path: '/m/',
|
||||
getParentRoute: () => mobileStuffMobileLayoutRouteRoute,
|
||||
getParentRoute: () => MobileMobileLayoutRouteRoute,
|
||||
} as any)
|
||||
const AdminLayoutAdminUsersUsersRoute =
|
||||
AdminLayoutAdminUsersUsersRouteImport.update({
|
||||
id: '/users',
|
||||
path: '/users',
|
||||
getParentRoute: () => AdminLayoutAdminUsersRouteRoute,
|
||||
} as any)
|
||||
const AdminLayoutAdminUsersProdUsersRoute =
|
||||
AdminLayoutAdminUsersProdUsersRouteImport.update({
|
||||
id: '/prodUsers',
|
||||
path: '/prodUsers',
|
||||
getParentRoute: () => AdminLayoutAdminUsersRouteRoute,
|
||||
} as any)
|
||||
const mobileStuffMobileLayoutMRelocateRoute =
|
||||
mobileStuffMobileLayoutMRelocateRouteImport.update({
|
||||
const AppauthUserIndexRoute = AppauthUserIndexRouteImport.update({
|
||||
id: '/(auth)/user/',
|
||||
path: '/user/',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const MobileMobileLayoutMRelocateRoute =
|
||||
MobileMobileLayoutMRelocateRouteImport.update({
|
||||
id: '/m/relocate',
|
||||
path: '/m/relocate',
|
||||
getParentRoute: () => mobileStuffMobileLayoutRouteRoute,
|
||||
getParentRoute: () => MobileMobileLayoutRouteRoute,
|
||||
} as any)
|
||||
const mobileStuffMobileLayoutMDeliveryRoute =
|
||||
mobileStuffMobileLayoutMDeliveryRouteImport.update({
|
||||
const MobileMobileLayoutMDeliveryRoute =
|
||||
MobileMobileLayoutMDeliveryRouteImport.update({
|
||||
id: '/m/delivery',
|
||||
path: '/m/delivery',
|
||||
getParentRoute: () => mobileStuffMobileLayoutRouteRoute,
|
||||
getParentRoute: () => MobileMobileLayoutRouteRoute,
|
||||
} as any)
|
||||
const mobileStuffMobileLayoutMCyclecountsRoute =
|
||||
mobileStuffMobileLayoutMCyclecountsRouteImport.update({
|
||||
const MobileMobileLayoutMCyclecountsRoute =
|
||||
MobileMobileLayoutMCyclecountsRouteImport.update({
|
||||
id: '/m/cyclecounts',
|
||||
path: '/m/cyclecounts',
|
||||
getParentRoute: () => mobileStuffMobileLayoutRouteRoute,
|
||||
getParentRoute: () => MobileMobileLayoutRouteRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminSettingsRoute =
|
||||
AppAdminLayoutAdminSettingsRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
getParentRoute: () => AppAdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminServersRoute =
|
||||
AppAdminLayoutAdminServersRouteImport.update({
|
||||
id: '/servers',
|
||||
path: '/servers',
|
||||
getParentRoute: () => AppAdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const ApplogisticsLogisticsDeliveryScheduleRoute =
|
||||
ApplogisticsLogisticsDeliveryScheduleRouteImport.update({
|
||||
id: '/(logistics)/logistics/deliverySchedule',
|
||||
path: '/logistics/deliverySchedule',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const AppauthUserSignupRoute = AppauthUserSignupRouteImport.update({
|
||||
id: '/(auth)/user/signup',
|
||||
path: '/user/signup',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const AppauthUserResetpasswordRoute =
|
||||
AppauthUserResetpasswordRouteImport.update({
|
||||
id: '/(auth)/user/resetpassword',
|
||||
path: '/user/resetpassword',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const AppauthUserProfileRoute = AppauthUserProfileRouteImport.update({
|
||||
id: '/(auth)/user/profile',
|
||||
path: '/user/profile',
|
||||
getParentRoute: () => AppRouteRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminUsersRouteRoute =
|
||||
AppAdminLayoutAdminUsersRouteRouteImport.update({
|
||||
id: '/_users',
|
||||
getParentRoute: () => AppAdminLayoutAdminRoute,
|
||||
} as any)
|
||||
const OldOldlogisticsSiloAdjustmentsIndexRoute =
|
||||
OldOldlogisticsSiloAdjustmentsIndexRouteImport.update({
|
||||
id: '/(logistics)/siloAdjustments/',
|
||||
path: '/siloAdjustments/',
|
||||
getParentRoute: () => OldOldRouteRoute,
|
||||
} as any)
|
||||
const OldOldlogisticsSiloAdjustmentsHistRoute =
|
||||
OldOldlogisticsSiloAdjustmentsHistRouteImport.update({
|
||||
id: '/(logistics)/siloAdjustments/$hist',
|
||||
path: '/siloAdjustments/$hist',
|
||||
getParentRoute: () => OldOldRouteRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminUsersUsersRoute =
|
||||
AppAdminLayoutAdminUsersUsersRouteImport.update({
|
||||
id: '/users',
|
||||
path: '/users',
|
||||
getParentRoute: () => AppAdminLayoutAdminUsersRouteRoute,
|
||||
} as any)
|
||||
const AppAdminLayoutAdminUsersProdUsersRoute =
|
||||
AppAdminLayoutAdminUsersProdUsersRouteImport.update({
|
||||
id: '/prodUsers',
|
||||
path: '/prodUsers',
|
||||
getParentRoute: () => AppAdminLayoutAdminUsersRouteRoute,
|
||||
} as any)
|
||||
const OldOldlogisticsSiloAdjustmentsCommentCommentRoute =
|
||||
OldOldlogisticsSiloAdjustmentsCommentCommentRouteImport.update({
|
||||
id: '/(logistics)/siloAdjustments/comment/$comment',
|
||||
path: '/siloAdjustments/comment/$comment',
|
||||
getParentRoute: () => OldOldRouteRoute,
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof mobileStuffMobileLayoutRouteRouteWithChildren
|
||||
'/login': typeof authLoginRoute
|
||||
'/admin': typeof AdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/user/profile': typeof authUserProfileRoute
|
||||
'/user/resetpassword': typeof authUserResetpasswordRoute
|
||||
'/user/signup': typeof authUserSignupRoute
|
||||
'/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AdminLayoutAdminServersRoute
|
||||
'/admin/settings': typeof AdminLayoutAdminSettingsRoute
|
||||
'/user': typeof authUserIndexRoute
|
||||
'/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
|
||||
'/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
|
||||
'/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
|
||||
'/admin/prodUsers': typeof AdminLayoutAdminUsersProdUsersRoute
|
||||
'/admin/users': typeof AdminLayoutAdminUsersUsersRoute
|
||||
'/m': typeof mobileStuffMobileLayoutMIndexRoute
|
||||
'/old': typeof OldOldRouteRouteWithChildren
|
||||
'/': typeof AppIndexRoute
|
||||
'/login': typeof AppauthLoginRoute
|
||||
'/old/': typeof OldOldIndexRoute
|
||||
'/admin': typeof AppAdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/user/profile': typeof AppauthUserProfileRoute
|
||||
'/user/resetpassword': typeof AppauthUserResetpasswordRoute
|
||||
'/user/signup': typeof AppauthUserSignupRoute
|
||||
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/admin/settings': typeof AppAdminLayoutAdminSettingsRoute
|
||||
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
'/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
|
||||
'/m/relocate': typeof MobileMobileLayoutMRelocateRoute
|
||||
'/user': typeof AppauthUserIndexRoute
|
||||
'/m': typeof MobileMobileLayoutMIndexRoute
|
||||
'/admin/prodUsers': typeof AppAdminLayoutAdminUsersProdUsersRoute
|
||||
'/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute
|
||||
'/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
|
||||
'/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
|
||||
'/old/siloAdjustments/comment/$comment': typeof OldOldlogisticsSiloAdjustmentsCommentCommentRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof mobileStuffMobileLayoutRouteRouteWithChildren
|
||||
'/login': typeof authLoginRoute
|
||||
'/admin': typeof AdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/user/profile': typeof authUserProfileRoute
|
||||
'/user/resetpassword': typeof authUserResetpasswordRoute
|
||||
'/user/signup': typeof authUserSignupRoute
|
||||
'/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AdminLayoutAdminServersRoute
|
||||
'/admin/settings': typeof AdminLayoutAdminSettingsRoute
|
||||
'/user': typeof authUserIndexRoute
|
||||
'/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
|
||||
'/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
|
||||
'/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
|
||||
'/admin/prodUsers': typeof AdminLayoutAdminUsersProdUsersRoute
|
||||
'/admin/users': typeof AdminLayoutAdminUsersUsersRoute
|
||||
'/m': typeof mobileStuffMobileLayoutMIndexRoute
|
||||
'/': typeof AppIndexRoute
|
||||
'/login': typeof AppauthLoginRoute
|
||||
'/old': typeof OldOldIndexRoute
|
||||
'/admin': typeof AppAdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/user/profile': typeof AppauthUserProfileRoute
|
||||
'/user/resetpassword': typeof AppauthUserResetpasswordRoute
|
||||
'/user/signup': typeof AppauthUserSignupRoute
|
||||
'/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/admin/settings': typeof AppAdminLayoutAdminSettingsRoute
|
||||
'/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
'/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
|
||||
'/m/relocate': typeof MobileMobileLayoutMRelocateRoute
|
||||
'/user': typeof AppauthUserIndexRoute
|
||||
'/m': typeof MobileMobileLayoutMIndexRoute
|
||||
'/admin/prodUsers': typeof AppAdminLayoutAdminUsersProdUsersRoute
|
||||
'/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute
|
||||
'/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
|
||||
'/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
|
||||
'/old/siloAdjustments/comment/$comment': typeof OldOldlogisticsSiloAdjustmentsCommentCommentRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
'/_adminLayout': typeof AdminLayoutRouteRouteWithChildren
|
||||
'/(mobileStuff)': typeof mobileStuffRouteWithChildren
|
||||
'/(mobileStuff)/_mobileLayout': typeof mobileStuffMobileLayoutRouteRouteWithChildren
|
||||
'/(auth)/login': typeof authLoginRoute
|
||||
'/_adminLayout/admin': typeof AdminLayoutAdminRouteWithChildren
|
||||
'/_adminLayout/admin/_users': typeof AdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/(auth)/user/profile': typeof authUserProfileRoute
|
||||
'/(auth)/user/resetpassword': typeof authUserResetpasswordRoute
|
||||
'/(auth)/user/signup': typeof authUserSignupRoute
|
||||
'/(logistics)/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
|
||||
'/_adminLayout/admin/servers': typeof AdminLayoutAdminServersRoute
|
||||
'/_adminLayout/admin/settings': typeof AdminLayoutAdminSettingsRoute
|
||||
'/(auth)/user/': typeof authUserIndexRoute
|
||||
'/(mobileStuff)/_mobileLayout/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
|
||||
'/(mobileStuff)/_mobileLayout/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
|
||||
'/(mobileStuff)/_mobileLayout/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
|
||||
'/_adminLayout/admin/_users/prodUsers': typeof AdminLayoutAdminUsersProdUsersRoute
|
||||
'/_adminLayout/admin/_users/users': typeof AdminLayoutAdminUsersUsersRoute
|
||||
'/(mobileStuff)/_mobileLayout/m/': typeof mobileStuffMobileLayoutMIndexRoute
|
||||
'/_app': typeof AppRouteRouteWithChildren
|
||||
'/_app/_adminLayout': typeof AppAdminLayoutRouteRouteWithChildren
|
||||
'/_mobile/_mobileLayout': typeof MobileMobileLayoutRouteRouteWithChildren
|
||||
'/_old/old': typeof OldOldRouteRouteWithChildren
|
||||
'/_app/': typeof AppIndexRoute
|
||||
'/_app/(auth)/login': typeof AppauthLoginRoute
|
||||
'/_old/old/': typeof OldOldIndexRoute
|
||||
'/_app/_adminLayout/admin': typeof AppAdminLayoutAdminRouteWithChildren
|
||||
'/_app/_adminLayout/admin/_users': typeof AppAdminLayoutAdminUsersRouteRouteWithChildren
|
||||
'/_app/(auth)/user/profile': typeof AppauthUserProfileRoute
|
||||
'/_app/(auth)/user/resetpassword': typeof AppauthUserResetpasswordRoute
|
||||
'/_app/(auth)/user/signup': typeof AppauthUserSignupRoute
|
||||
'/_app/(logistics)/logistics/deliverySchedule': typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
'/_app/_adminLayout/admin/servers': typeof AppAdminLayoutAdminServersRoute
|
||||
'/_app/_adminLayout/admin/settings': typeof AppAdminLayoutAdminSettingsRoute
|
||||
'/_mobile/_mobileLayout/m/cyclecounts': typeof MobileMobileLayoutMCyclecountsRoute
|
||||
'/_mobile/_mobileLayout/m/delivery': typeof MobileMobileLayoutMDeliveryRoute
|
||||
'/_mobile/_mobileLayout/m/relocate': typeof MobileMobileLayoutMRelocateRoute
|
||||
'/_app/(auth)/user/': typeof AppauthUserIndexRoute
|
||||
'/_mobile/_mobileLayout/m/': typeof MobileMobileLayoutMIndexRoute
|
||||
'/_app/_adminLayout/admin/_users/prodUsers': typeof AppAdminLayoutAdminUsersProdUsersRoute
|
||||
'/_app/_adminLayout/admin/_users/users': typeof AppAdminLayoutAdminUsersUsersRoute
|
||||
'/_old/old/(logistics)/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
|
||||
'/_old/old/(logistics)/siloAdjustments/': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
|
||||
'/_old/old/(logistics)/siloAdjustments/comment/$comment': typeof OldOldlogisticsSiloAdjustmentsCommentCommentRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths:
|
||||
| '/old'
|
||||
| '/'
|
||||
| '/login'
|
||||
| '/old/'
|
||||
| '/admin'
|
||||
| '/user/profile'
|
||||
| '/user/resetpassword'
|
||||
@@ -211,17 +263,21 @@ export interface FileRouteTypes {
|
||||
| '/logistics/deliverySchedule'
|
||||
| '/admin/servers'
|
||||
| '/admin/settings'
|
||||
| '/user'
|
||||
| '/m/cyclecounts'
|
||||
| '/m/delivery'
|
||||
| '/m/relocate'
|
||||
| '/user'
|
||||
| '/m'
|
||||
| '/admin/prodUsers'
|
||||
| '/admin/users'
|
||||
| '/m'
|
||||
| '/old/siloAdjustments/$hist'
|
||||
| '/old/siloAdjustments'
|
||||
| '/old/siloAdjustments/comment/$comment'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to:
|
||||
| '/'
|
||||
| '/login'
|
||||
| '/old'
|
||||
| '/admin'
|
||||
| '/user/profile'
|
||||
| '/user/resetpassword'
|
||||
@@ -229,283 +285,347 @@ export interface FileRouteTypes {
|
||||
| '/logistics/deliverySchedule'
|
||||
| '/admin/servers'
|
||||
| '/admin/settings'
|
||||
| '/user'
|
||||
| '/m/cyclecounts'
|
||||
| '/m/delivery'
|
||||
| '/m/relocate'
|
||||
| '/user'
|
||||
| '/m'
|
||||
| '/admin/prodUsers'
|
||||
| '/admin/users'
|
||||
| '/m'
|
||||
| '/old/siloAdjustments/$hist'
|
||||
| '/old/siloAdjustments'
|
||||
| '/old/siloAdjustments/comment/$comment'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/_adminLayout'
|
||||
| '/(mobileStuff)'
|
||||
| '/(mobileStuff)/_mobileLayout'
|
||||
| '/(auth)/login'
|
||||
| '/_adminLayout/admin'
|
||||
| '/_adminLayout/admin/_users'
|
||||
| '/(auth)/user/profile'
|
||||
| '/(auth)/user/resetpassword'
|
||||
| '/(auth)/user/signup'
|
||||
| '/(logistics)/logistics/deliverySchedule'
|
||||
| '/_adminLayout/admin/servers'
|
||||
| '/_adminLayout/admin/settings'
|
||||
| '/(auth)/user/'
|
||||
| '/(mobileStuff)/_mobileLayout/m/cyclecounts'
|
||||
| '/(mobileStuff)/_mobileLayout/m/delivery'
|
||||
| '/(mobileStuff)/_mobileLayout/m/relocate'
|
||||
| '/_adminLayout/admin/_users/prodUsers'
|
||||
| '/_adminLayout/admin/_users/users'
|
||||
| '/(mobileStuff)/_mobileLayout/m/'
|
||||
| '/_app'
|
||||
| '/_app/_adminLayout'
|
||||
| '/_mobile/_mobileLayout'
|
||||
| '/_old/old'
|
||||
| '/_app/'
|
||||
| '/_app/(auth)/login'
|
||||
| '/_old/old/'
|
||||
| '/_app/_adminLayout/admin'
|
||||
| '/_app/_adminLayout/admin/_users'
|
||||
| '/_app/(auth)/user/profile'
|
||||
| '/_app/(auth)/user/resetpassword'
|
||||
| '/_app/(auth)/user/signup'
|
||||
| '/_app/(logistics)/logistics/deliverySchedule'
|
||||
| '/_app/_adminLayout/admin/servers'
|
||||
| '/_app/_adminLayout/admin/settings'
|
||||
| '/_mobile/_mobileLayout/m/cyclecounts'
|
||||
| '/_mobile/_mobileLayout/m/delivery'
|
||||
| '/_mobile/_mobileLayout/m/relocate'
|
||||
| '/_app/(auth)/user/'
|
||||
| '/_mobile/_mobileLayout/m/'
|
||||
| '/_app/_adminLayout/admin/_users/prodUsers'
|
||||
| '/_app/_adminLayout/admin/_users/users'
|
||||
| '/_old/old/(logistics)/siloAdjustments/$hist'
|
||||
| '/_old/old/(logistics)/siloAdjustments/'
|
||||
| '/_old/old/(logistics)/siloAdjustments/comment/$comment'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
AdminLayoutRouteRoute: typeof AdminLayoutRouteRouteWithChildren
|
||||
mobileStuffRoute: typeof mobileStuffRouteWithChildren
|
||||
authLoginRoute: typeof authLoginRoute
|
||||
authUserProfileRoute: typeof authUserProfileRoute
|
||||
authUserResetpasswordRoute: typeof authUserResetpasswordRoute
|
||||
authUserSignupRoute: typeof authUserSignupRoute
|
||||
logisticsLogisticsDeliveryScheduleRoute: typeof logisticsLogisticsDeliveryScheduleRoute
|
||||
authUserIndexRoute: typeof authUserIndexRoute
|
||||
AppRouteRoute: typeof AppRouteRouteWithChildren
|
||||
MobileMobileLayoutRouteRoute: typeof MobileMobileLayoutRouteRouteWithChildren
|
||||
OldOldRouteRoute: typeof OldOldRouteRouteWithChildren
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {
|
||||
'/(mobileStuff)': {
|
||||
id: '/(mobileStuff)'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof mobileStuffRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_adminLayout': {
|
||||
id: '/_adminLayout'
|
||||
'/_app': {
|
||||
id: '/_app'
|
||||
path: ''
|
||||
fullPath: ''
|
||||
preLoaderRoute: typeof AdminLayoutRouteRouteImport
|
||||
preLoaderRoute: typeof AppRouteRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/': {
|
||||
id: '/'
|
||||
'/_app/': {
|
||||
id: '/_app/'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof IndexRouteImport
|
||||
preLoaderRoute: typeof AppIndexRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_old/old': {
|
||||
id: '/_old/old'
|
||||
path: '/old'
|
||||
fullPath: '/old'
|
||||
preLoaderRoute: typeof OldOldRouteRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_adminLayout/admin': {
|
||||
id: '/_adminLayout/admin'
|
||||
'/_mobile/_mobileLayout': {
|
||||
id: '/_mobile/_mobileLayout'
|
||||
path: ''
|
||||
fullPath: ''
|
||||
preLoaderRoute: typeof MobileMobileLayoutRouteRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_app/_adminLayout': {
|
||||
id: '/_app/_adminLayout'
|
||||
path: ''
|
||||
fullPath: ''
|
||||
preLoaderRoute: typeof AppAdminLayoutRouteRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin': {
|
||||
id: '/_app/_adminLayout/admin'
|
||||
path: '/admin'
|
||||
fullPath: '/admin'
|
||||
preLoaderRoute: typeof AdminLayoutAdminRouteImport
|
||||
parentRoute: typeof AdminLayoutRouteRoute
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminRouteImport
|
||||
parentRoute: typeof AppAdminLayoutRouteRoute
|
||||
}
|
||||
'/(auth)/login': {
|
||||
id: '/(auth)/login'
|
||||
'/_old/old/': {
|
||||
id: '/_old/old/'
|
||||
path: '/'
|
||||
fullPath: '/old/'
|
||||
preLoaderRoute: typeof OldOldIndexRouteImport
|
||||
parentRoute: typeof OldOldRouteRoute
|
||||
}
|
||||
'/_app/(auth)/login': {
|
||||
id: '/_app/(auth)/login'
|
||||
path: '/login'
|
||||
fullPath: '/login'
|
||||
preLoaderRoute: typeof authLoginRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
preLoaderRoute: typeof AppauthLoginRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/(mobileStuff)/_mobileLayout': {
|
||||
id: '/(mobileStuff)/_mobileLayout'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof mobileStuffMobileLayoutRouteRouteImport
|
||||
parentRoute: typeof mobileStuffRoute
|
||||
}
|
||||
'/(auth)/user/': {
|
||||
id: '/(auth)/user/'
|
||||
path: '/user'
|
||||
fullPath: '/user'
|
||||
preLoaderRoute: typeof authUserIndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_adminLayout/admin/settings': {
|
||||
id: '/_adminLayout/admin/settings'
|
||||
path: '/settings'
|
||||
fullPath: '/admin/settings'
|
||||
preLoaderRoute: typeof AdminLayoutAdminSettingsRouteImport
|
||||
parentRoute: typeof AdminLayoutAdminRoute
|
||||
}
|
||||
'/_adminLayout/admin/servers': {
|
||||
id: '/_adminLayout/admin/servers'
|
||||
path: '/servers'
|
||||
fullPath: '/admin/servers'
|
||||
preLoaderRoute: typeof AdminLayoutAdminServersRouteImport
|
||||
parentRoute: typeof AdminLayoutAdminRoute
|
||||
}
|
||||
'/(logistics)/logistics/deliverySchedule': {
|
||||
id: '/(logistics)/logistics/deliverySchedule'
|
||||
path: '/logistics/deliverySchedule'
|
||||
fullPath: '/logistics/deliverySchedule'
|
||||
preLoaderRoute: typeof logisticsLogisticsDeliveryScheduleRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/(auth)/user/signup': {
|
||||
id: '/(auth)/user/signup'
|
||||
path: '/user/signup'
|
||||
fullPath: '/user/signup'
|
||||
preLoaderRoute: typeof authUserSignupRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/(auth)/user/resetpassword': {
|
||||
id: '/(auth)/user/resetpassword'
|
||||
path: '/user/resetpassword'
|
||||
fullPath: '/user/resetpassword'
|
||||
preLoaderRoute: typeof authUserResetpasswordRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/(auth)/user/profile': {
|
||||
id: '/(auth)/user/profile'
|
||||
path: '/user/profile'
|
||||
fullPath: '/user/profile'
|
||||
preLoaderRoute: typeof authUserProfileRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_adminLayout/admin/_users': {
|
||||
id: '/_adminLayout/admin/_users'
|
||||
path: '/admin'
|
||||
fullPath: '/admin'
|
||||
preLoaderRoute: typeof AdminLayoutAdminUsersRouteRouteImport
|
||||
parentRoute: typeof AdminLayoutAdminRoute
|
||||
}
|
||||
'/(mobileStuff)/_mobileLayout/m/': {
|
||||
id: '/(mobileStuff)/_mobileLayout/m/'
|
||||
'/_mobile/_mobileLayout/m/': {
|
||||
id: '/_mobile/_mobileLayout/m/'
|
||||
path: '/m'
|
||||
fullPath: '/m'
|
||||
preLoaderRoute: typeof mobileStuffMobileLayoutMIndexRouteImport
|
||||
parentRoute: typeof mobileStuffMobileLayoutRouteRoute
|
||||
preLoaderRoute: typeof MobileMobileLayoutMIndexRouteImport
|
||||
parentRoute: typeof MobileMobileLayoutRouteRoute
|
||||
}
|
||||
'/_adminLayout/admin/_users/users': {
|
||||
id: '/_adminLayout/admin/_users/users'
|
||||
path: '/users'
|
||||
fullPath: '/admin/users'
|
||||
preLoaderRoute: typeof AdminLayoutAdminUsersUsersRouteImport
|
||||
parentRoute: typeof AdminLayoutAdminUsersRouteRoute
|
||||
'/_app/(auth)/user/': {
|
||||
id: '/_app/(auth)/user/'
|
||||
path: '/user'
|
||||
fullPath: '/user'
|
||||
preLoaderRoute: typeof AppauthUserIndexRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_adminLayout/admin/_users/prodUsers': {
|
||||
id: '/_adminLayout/admin/_users/prodUsers'
|
||||
path: '/prodUsers'
|
||||
fullPath: '/admin/prodUsers'
|
||||
preLoaderRoute: typeof AdminLayoutAdminUsersProdUsersRouteImport
|
||||
parentRoute: typeof AdminLayoutAdminUsersRouteRoute
|
||||
}
|
||||
'/(mobileStuff)/_mobileLayout/m/relocate': {
|
||||
id: '/(mobileStuff)/_mobileLayout/m/relocate'
|
||||
'/_mobile/_mobileLayout/m/relocate': {
|
||||
id: '/_mobile/_mobileLayout/m/relocate'
|
||||
path: '/m/relocate'
|
||||
fullPath: '/m/relocate'
|
||||
preLoaderRoute: typeof mobileStuffMobileLayoutMRelocateRouteImport
|
||||
parentRoute: typeof mobileStuffMobileLayoutRouteRoute
|
||||
preLoaderRoute: typeof MobileMobileLayoutMRelocateRouteImport
|
||||
parentRoute: typeof MobileMobileLayoutRouteRoute
|
||||
}
|
||||
'/(mobileStuff)/_mobileLayout/m/delivery': {
|
||||
id: '/(mobileStuff)/_mobileLayout/m/delivery'
|
||||
'/_mobile/_mobileLayout/m/delivery': {
|
||||
id: '/_mobile/_mobileLayout/m/delivery'
|
||||
path: '/m/delivery'
|
||||
fullPath: '/m/delivery'
|
||||
preLoaderRoute: typeof mobileStuffMobileLayoutMDeliveryRouteImport
|
||||
parentRoute: typeof mobileStuffMobileLayoutRouteRoute
|
||||
preLoaderRoute: typeof MobileMobileLayoutMDeliveryRouteImport
|
||||
parentRoute: typeof MobileMobileLayoutRouteRoute
|
||||
}
|
||||
'/(mobileStuff)/_mobileLayout/m/cyclecounts': {
|
||||
id: '/(mobileStuff)/_mobileLayout/m/cyclecounts'
|
||||
'/_mobile/_mobileLayout/m/cyclecounts': {
|
||||
id: '/_mobile/_mobileLayout/m/cyclecounts'
|
||||
path: '/m/cyclecounts'
|
||||
fullPath: '/m/cyclecounts'
|
||||
preLoaderRoute: typeof mobileStuffMobileLayoutMCyclecountsRouteImport
|
||||
parentRoute: typeof mobileStuffMobileLayoutRouteRoute
|
||||
preLoaderRoute: typeof MobileMobileLayoutMCyclecountsRouteImport
|
||||
parentRoute: typeof MobileMobileLayoutRouteRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin/settings': {
|
||||
id: '/_app/_adminLayout/admin/settings'
|
||||
path: '/settings'
|
||||
fullPath: '/admin/settings'
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminSettingsRouteImport
|
||||
parentRoute: typeof AppAdminLayoutAdminRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin/servers': {
|
||||
id: '/_app/_adminLayout/admin/servers'
|
||||
path: '/servers'
|
||||
fullPath: '/admin/servers'
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminServersRouteImport
|
||||
parentRoute: typeof AppAdminLayoutAdminRoute
|
||||
}
|
||||
'/_app/(logistics)/logistics/deliverySchedule': {
|
||||
id: '/_app/(logistics)/logistics/deliverySchedule'
|
||||
path: '/logistics/deliverySchedule'
|
||||
fullPath: '/logistics/deliverySchedule'
|
||||
preLoaderRoute: typeof ApplogisticsLogisticsDeliveryScheduleRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_app/(auth)/user/signup': {
|
||||
id: '/_app/(auth)/user/signup'
|
||||
path: '/user/signup'
|
||||
fullPath: '/user/signup'
|
||||
preLoaderRoute: typeof AppauthUserSignupRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_app/(auth)/user/resetpassword': {
|
||||
id: '/_app/(auth)/user/resetpassword'
|
||||
path: '/user/resetpassword'
|
||||
fullPath: '/user/resetpassword'
|
||||
preLoaderRoute: typeof AppauthUserResetpasswordRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_app/(auth)/user/profile': {
|
||||
id: '/_app/(auth)/user/profile'
|
||||
path: '/user/profile'
|
||||
fullPath: '/user/profile'
|
||||
preLoaderRoute: typeof AppauthUserProfileRouteImport
|
||||
parentRoute: typeof AppRouteRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin/_users': {
|
||||
id: '/_app/_adminLayout/admin/_users'
|
||||
path: '/admin'
|
||||
fullPath: '/admin'
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminUsersRouteRouteImport
|
||||
parentRoute: typeof AppAdminLayoutAdminRoute
|
||||
}
|
||||
'/_old/old/(logistics)/siloAdjustments/': {
|
||||
id: '/_old/old/(logistics)/siloAdjustments/'
|
||||
path: '/siloAdjustments'
|
||||
fullPath: '/old/siloAdjustments'
|
||||
preLoaderRoute: typeof OldOldlogisticsSiloAdjustmentsIndexRouteImport
|
||||
parentRoute: typeof OldOldRouteRoute
|
||||
}
|
||||
'/_old/old/(logistics)/siloAdjustments/$hist': {
|
||||
id: '/_old/old/(logistics)/siloAdjustments/$hist'
|
||||
path: '/siloAdjustments/$hist'
|
||||
fullPath: '/old/siloAdjustments/$hist'
|
||||
preLoaderRoute: typeof OldOldlogisticsSiloAdjustmentsHistRouteImport
|
||||
parentRoute: typeof OldOldRouteRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin/_users/users': {
|
||||
id: '/_app/_adminLayout/admin/_users/users'
|
||||
path: '/users'
|
||||
fullPath: '/admin/users'
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminUsersUsersRouteImport
|
||||
parentRoute: typeof AppAdminLayoutAdminUsersRouteRoute
|
||||
}
|
||||
'/_app/_adminLayout/admin/_users/prodUsers': {
|
||||
id: '/_app/_adminLayout/admin/_users/prodUsers'
|
||||
path: '/prodUsers'
|
||||
fullPath: '/admin/prodUsers'
|
||||
preLoaderRoute: typeof AppAdminLayoutAdminUsersProdUsersRouteImport
|
||||
parentRoute: typeof AppAdminLayoutAdminUsersRouteRoute
|
||||
}
|
||||
'/_old/old/(logistics)/siloAdjustments/comment/$comment': {
|
||||
id: '/_old/old/(logistics)/siloAdjustments/comment/$comment'
|
||||
path: '/siloAdjustments/comment/$comment'
|
||||
fullPath: '/old/siloAdjustments/comment/$comment'
|
||||
preLoaderRoute: typeof OldOldlogisticsSiloAdjustmentsCommentCommentRouteImport
|
||||
parentRoute: typeof OldOldRouteRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface AdminLayoutAdminUsersRouteRouteChildren {
|
||||
AdminLayoutAdminUsersProdUsersRoute: typeof AdminLayoutAdminUsersProdUsersRoute
|
||||
AdminLayoutAdminUsersUsersRoute: typeof AdminLayoutAdminUsersUsersRoute
|
||||
interface AppAdminLayoutAdminUsersRouteRouteChildren {
|
||||
AppAdminLayoutAdminUsersProdUsersRoute: typeof AppAdminLayoutAdminUsersProdUsersRoute
|
||||
AppAdminLayoutAdminUsersUsersRoute: typeof AppAdminLayoutAdminUsersUsersRoute
|
||||
}
|
||||
|
||||
const AdminLayoutAdminUsersRouteRouteChildren: AdminLayoutAdminUsersRouteRouteChildren =
|
||||
const AppAdminLayoutAdminUsersRouteRouteChildren: AppAdminLayoutAdminUsersRouteRouteChildren =
|
||||
{
|
||||
AdminLayoutAdminUsersProdUsersRoute: AdminLayoutAdminUsersProdUsersRoute,
|
||||
AdminLayoutAdminUsersUsersRoute: AdminLayoutAdminUsersUsersRoute,
|
||||
AppAdminLayoutAdminUsersProdUsersRoute:
|
||||
AppAdminLayoutAdminUsersProdUsersRoute,
|
||||
AppAdminLayoutAdminUsersUsersRoute: AppAdminLayoutAdminUsersUsersRoute,
|
||||
}
|
||||
|
||||
const AdminLayoutAdminUsersRouteRouteWithChildren =
|
||||
AdminLayoutAdminUsersRouteRoute._addFileChildren(
|
||||
AdminLayoutAdminUsersRouteRouteChildren,
|
||||
const AppAdminLayoutAdminUsersRouteRouteWithChildren =
|
||||
AppAdminLayoutAdminUsersRouteRoute._addFileChildren(
|
||||
AppAdminLayoutAdminUsersRouteRouteChildren,
|
||||
)
|
||||
|
||||
interface AdminLayoutAdminRouteChildren {
|
||||
AdminLayoutAdminUsersRouteRoute: typeof AdminLayoutAdminUsersRouteRouteWithChildren
|
||||
AdminLayoutAdminServersRoute: typeof AdminLayoutAdminServersRoute
|
||||
AdminLayoutAdminSettingsRoute: typeof AdminLayoutAdminSettingsRoute
|
||||
interface AppAdminLayoutAdminRouteChildren {
|
||||
AppAdminLayoutAdminUsersRouteRoute: typeof AppAdminLayoutAdminUsersRouteRouteWithChildren
|
||||
AppAdminLayoutAdminServersRoute: typeof AppAdminLayoutAdminServersRoute
|
||||
AppAdminLayoutAdminSettingsRoute: typeof AppAdminLayoutAdminSettingsRoute
|
||||
}
|
||||
|
||||
const AdminLayoutAdminRouteChildren: AdminLayoutAdminRouteChildren = {
|
||||
AdminLayoutAdminUsersRouteRoute: AdminLayoutAdminUsersRouteRouteWithChildren,
|
||||
AdminLayoutAdminServersRoute: AdminLayoutAdminServersRoute,
|
||||
AdminLayoutAdminSettingsRoute: AdminLayoutAdminSettingsRoute,
|
||||
const AppAdminLayoutAdminRouteChildren: AppAdminLayoutAdminRouteChildren = {
|
||||
AppAdminLayoutAdminUsersRouteRoute:
|
||||
AppAdminLayoutAdminUsersRouteRouteWithChildren,
|
||||
AppAdminLayoutAdminServersRoute: AppAdminLayoutAdminServersRoute,
|
||||
AppAdminLayoutAdminSettingsRoute: AppAdminLayoutAdminSettingsRoute,
|
||||
}
|
||||
|
||||
const AdminLayoutAdminRouteWithChildren =
|
||||
AdminLayoutAdminRoute._addFileChildren(AdminLayoutAdminRouteChildren)
|
||||
const AppAdminLayoutAdminRouteWithChildren =
|
||||
AppAdminLayoutAdminRoute._addFileChildren(AppAdminLayoutAdminRouteChildren)
|
||||
|
||||
interface AdminLayoutRouteRouteChildren {
|
||||
AdminLayoutAdminRoute: typeof AdminLayoutAdminRouteWithChildren
|
||||
interface AppAdminLayoutRouteRouteChildren {
|
||||
AppAdminLayoutAdminRoute: typeof AppAdminLayoutAdminRouteWithChildren
|
||||
}
|
||||
|
||||
const AdminLayoutRouteRouteChildren: AdminLayoutRouteRouteChildren = {
|
||||
AdminLayoutAdminRoute: AdminLayoutAdminRouteWithChildren,
|
||||
const AppAdminLayoutRouteRouteChildren: AppAdminLayoutRouteRouteChildren = {
|
||||
AppAdminLayoutAdminRoute: AppAdminLayoutAdminRouteWithChildren,
|
||||
}
|
||||
|
||||
const AdminLayoutRouteRouteWithChildren =
|
||||
AdminLayoutRouteRoute._addFileChildren(AdminLayoutRouteRouteChildren)
|
||||
const AppAdminLayoutRouteRouteWithChildren =
|
||||
AppAdminLayoutRouteRoute._addFileChildren(AppAdminLayoutRouteRouteChildren)
|
||||
|
||||
interface mobileStuffMobileLayoutRouteRouteChildren {
|
||||
mobileStuffMobileLayoutMCyclecountsRoute: typeof mobileStuffMobileLayoutMCyclecountsRoute
|
||||
mobileStuffMobileLayoutMDeliveryRoute: typeof mobileStuffMobileLayoutMDeliveryRoute
|
||||
mobileStuffMobileLayoutMRelocateRoute: typeof mobileStuffMobileLayoutMRelocateRoute
|
||||
mobileStuffMobileLayoutMIndexRoute: typeof mobileStuffMobileLayoutMIndexRoute
|
||||
interface AppRouteRouteChildren {
|
||||
AppAdminLayoutRouteRoute: typeof AppAdminLayoutRouteRouteWithChildren
|
||||
AppIndexRoute: typeof AppIndexRoute
|
||||
AppauthLoginRoute: typeof AppauthLoginRoute
|
||||
AppauthUserProfileRoute: typeof AppauthUserProfileRoute
|
||||
AppauthUserResetpasswordRoute: typeof AppauthUserResetpasswordRoute
|
||||
AppauthUserSignupRoute: typeof AppauthUserSignupRoute
|
||||
ApplogisticsLogisticsDeliveryScheduleRoute: typeof ApplogisticsLogisticsDeliveryScheduleRoute
|
||||
AppauthUserIndexRoute: typeof AppauthUserIndexRoute
|
||||
}
|
||||
|
||||
const mobileStuffMobileLayoutRouteRouteChildren: mobileStuffMobileLayoutRouteRouteChildren =
|
||||
const AppRouteRouteChildren: AppRouteRouteChildren = {
|
||||
AppAdminLayoutRouteRoute: AppAdminLayoutRouteRouteWithChildren,
|
||||
AppIndexRoute: AppIndexRoute,
|
||||
AppauthLoginRoute: AppauthLoginRoute,
|
||||
AppauthUserProfileRoute: AppauthUserProfileRoute,
|
||||
AppauthUserResetpasswordRoute: AppauthUserResetpasswordRoute,
|
||||
AppauthUserSignupRoute: AppauthUserSignupRoute,
|
||||
ApplogisticsLogisticsDeliveryScheduleRoute:
|
||||
ApplogisticsLogisticsDeliveryScheduleRoute,
|
||||
AppauthUserIndexRoute: AppauthUserIndexRoute,
|
||||
}
|
||||
|
||||
const AppRouteRouteWithChildren = AppRouteRoute._addFileChildren(
|
||||
AppRouteRouteChildren,
|
||||
)
|
||||
|
||||
interface MobileMobileLayoutRouteRouteChildren {
|
||||
MobileMobileLayoutMCyclecountsRoute: typeof MobileMobileLayoutMCyclecountsRoute
|
||||
MobileMobileLayoutMDeliveryRoute: typeof MobileMobileLayoutMDeliveryRoute
|
||||
MobileMobileLayoutMRelocateRoute: typeof MobileMobileLayoutMRelocateRoute
|
||||
MobileMobileLayoutMIndexRoute: typeof MobileMobileLayoutMIndexRoute
|
||||
}
|
||||
|
||||
const MobileMobileLayoutRouteRouteChildren: MobileMobileLayoutRouteRouteChildren =
|
||||
{
|
||||
mobileStuffMobileLayoutMCyclecountsRoute:
|
||||
mobileStuffMobileLayoutMCyclecountsRoute,
|
||||
mobileStuffMobileLayoutMDeliveryRoute:
|
||||
mobileStuffMobileLayoutMDeliveryRoute,
|
||||
mobileStuffMobileLayoutMRelocateRoute:
|
||||
mobileStuffMobileLayoutMRelocateRoute,
|
||||
mobileStuffMobileLayoutMIndexRoute: mobileStuffMobileLayoutMIndexRoute,
|
||||
MobileMobileLayoutMCyclecountsRoute: MobileMobileLayoutMCyclecountsRoute,
|
||||
MobileMobileLayoutMDeliveryRoute: MobileMobileLayoutMDeliveryRoute,
|
||||
MobileMobileLayoutMRelocateRoute: MobileMobileLayoutMRelocateRoute,
|
||||
MobileMobileLayoutMIndexRoute: MobileMobileLayoutMIndexRoute,
|
||||
}
|
||||
|
||||
const mobileStuffMobileLayoutRouteRouteWithChildren =
|
||||
mobileStuffMobileLayoutRouteRoute._addFileChildren(
|
||||
mobileStuffMobileLayoutRouteRouteChildren,
|
||||
const MobileMobileLayoutRouteRouteWithChildren =
|
||||
MobileMobileLayoutRouteRoute._addFileChildren(
|
||||
MobileMobileLayoutRouteRouteChildren,
|
||||
)
|
||||
|
||||
interface mobileStuffRouteChildren {
|
||||
mobileStuffMobileLayoutRouteRoute: typeof mobileStuffMobileLayoutRouteRouteWithChildren
|
||||
interface OldOldRouteRouteChildren {
|
||||
OldOldIndexRoute: typeof OldOldIndexRoute
|
||||
OldOldlogisticsSiloAdjustmentsHistRoute: typeof OldOldlogisticsSiloAdjustmentsHistRoute
|
||||
OldOldlogisticsSiloAdjustmentsIndexRoute: typeof OldOldlogisticsSiloAdjustmentsIndexRoute
|
||||
OldOldlogisticsSiloAdjustmentsCommentCommentRoute: typeof OldOldlogisticsSiloAdjustmentsCommentCommentRoute
|
||||
}
|
||||
|
||||
const mobileStuffRouteChildren: mobileStuffRouteChildren = {
|
||||
mobileStuffMobileLayoutRouteRoute:
|
||||
mobileStuffMobileLayoutRouteRouteWithChildren,
|
||||
const OldOldRouteRouteChildren: OldOldRouteRouteChildren = {
|
||||
OldOldIndexRoute: OldOldIndexRoute,
|
||||
OldOldlogisticsSiloAdjustmentsHistRoute:
|
||||
OldOldlogisticsSiloAdjustmentsHistRoute,
|
||||
OldOldlogisticsSiloAdjustmentsIndexRoute:
|
||||
OldOldlogisticsSiloAdjustmentsIndexRoute,
|
||||
OldOldlogisticsSiloAdjustmentsCommentCommentRoute:
|
||||
OldOldlogisticsSiloAdjustmentsCommentCommentRoute,
|
||||
}
|
||||
|
||||
const mobileStuffRouteWithChildren = mobileStuffRoute._addFileChildren(
|
||||
mobileStuffRouteChildren,
|
||||
const OldOldRouteRouteWithChildren = OldOldRouteRoute._addFileChildren(
|
||||
OldOldRouteRouteChildren,
|
||||
)
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
AdminLayoutRouteRoute: AdminLayoutRouteRouteWithChildren,
|
||||
mobileStuffRoute: mobileStuffRouteWithChildren,
|
||||
authLoginRoute: authLoginRoute,
|
||||
authUserProfileRoute: authUserProfileRoute,
|
||||
authUserResetpasswordRoute: authUserResetpasswordRoute,
|
||||
authUserSignupRoute: authUserSignupRoute,
|
||||
logisticsLogisticsDeliveryScheduleRoute:
|
||||
logisticsLogisticsDeliveryScheduleRoute,
|
||||
authUserIndexRoute: authUserIndexRoute,
|
||||
AppRouteRoute: AppRouteRouteWithChildren,
|
||||
MobileMobileLayoutRouteRoute: MobileMobileLayoutRouteRouteWithChildren,
|
||||
OldOldRouteRoute: OldOldRouteRouteWithChildren,
|
||||
}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import { LstCard } from "../../../components/ui/lstCard";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import { useAppForm } from "../../../lib/formStuff";
|
||||
import { api } from "../../../lib/axiosAPI";
|
||||
import { toast } from "sonner";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
export default function RequestResetPassword() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
try {
|
||||
const res = await api.post("api/user/resetpassword", {
|
||||
email: value.email,
|
||||
});
|
||||
|
||||
console.log(res);
|
||||
|
||||
if (res.status === 200) {
|
||||
toast.success(
|
||||
res.data.message
|
||||
? res.data.message
|
||||
: "If this email exists in our system, check your email for the reset link"
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Reset your password</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your email address and we’ll send you a reset link
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<form.AppField
|
||||
name="email"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Email address"
|
||||
inputType="email"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>
|
||||
Send Reset Link
|
||||
</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Remembered your password?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
import { useAppForm } from "../../../lib/formStuff";
|
||||
import { LstCard } from "../../../components/ui/lstCard";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import { api } from "../../../lib/axiosAPI";
|
||||
import { toast } from "sonner";
|
||||
import { Link, useNavigate } from "@tanstack/react-router";
|
||||
|
||||
export default function ResetPasswordForm({ token }: { token: string }) {
|
||||
const navigate = useNavigate();
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
if (value.password != value.confirmPassword) {
|
||||
toast.error("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await api.post("/api/auth/reset-password", {
|
||||
newPassword: value.password,
|
||||
token: token,
|
||||
});
|
||||
if (res.status === 200) {
|
||||
toast.success("Password has been reset");
|
||||
form.reset();
|
||||
navigate({ to: "/login" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// @ts-ignore
|
||||
toast.error(error?.response.data.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Set a new password</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your new password below and confirm it to continue
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<form.AppField
|
||||
name="password"
|
||||
children={(field) => (
|
||||
<field.InputPasswordField
|
||||
label="New Password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<form.AppField
|
||||
name="confirmPassword"
|
||||
// validators={{
|
||||
// onChangeListenTo: ["password"],
|
||||
// onChange: ({ value, fieldApi }) => {
|
||||
// if (
|
||||
// value !==
|
||||
// fieldApi.form.getFieldValue("password")
|
||||
// ) {
|
||||
// return "Passwords do not match";
|
||||
// }
|
||||
// return undefined;
|
||||
// },
|
||||
// }}
|
||||
children={(field) => (
|
||||
<field.InputPasswordField
|
||||
label="Confirm Password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>
|
||||
Reset Password
|
||||
</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Remembered your account?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import { LstCard } from "../../../components/ui/lstCard";
|
||||
import { api } from "../../../lib/axiosAPI";
|
||||
import { useAppForm } from "../../../lib/formStuff";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
export default function SignupForm() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
if (value.password != value.confirmPassword) {
|
||||
toast.error("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await api.post("/api/user/register", {
|
||||
username: value.username,
|
||||
name: value.username,
|
||||
email: value.email,
|
||||
password: value.password,
|
||||
});
|
||||
|
||||
if (res.status === 200) {
|
||||
toast.success(`Welcome ${value.username}, to lst.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// @ts-ignore
|
||||
toast.error(error?.response.data.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Create an account</CardTitle>
|
||||
<CardDescription>
|
||||
Fill in your details to get started
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
{/* Username */}
|
||||
<form.AppField
|
||||
name="username"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Username"
|
||||
inputType="text"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Email */}
|
||||
<form.AppField
|
||||
name="email"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Email address"
|
||||
inputType="email"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Password */}
|
||||
<form.AppField
|
||||
name="password"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Password"
|
||||
inputType="password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Confirm Password */}
|
||||
<form.AppField
|
||||
name="confirmPassword"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Confirm Password"
|
||||
inputType="password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Sign Up</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Already have an account?{" "}
|
||||
<Link
|
||||
to={"/login"}
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Log in
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { z } from "zod";
|
||||
import { authClient } from "../../lib/authClient";
|
||||
import LoginForm from "./-components/LoginForm";
|
||||
|
||||
export const Route = createFileRoute("/(auth)/login")({
|
||||
component: RouteComponent,
|
||||
validateSearch: z.object({
|
||||
redirect: z.string().optional(),
|
||||
}),
|
||||
beforeLoad: async () => {
|
||||
const result = await authClient.getSession({
|
||||
query: { disableCookieCache: true }, // force DB/Server lookup
|
||||
});
|
||||
|
||||
//console.log("session check:", result.data);
|
||||
|
||||
if (result.data) {
|
||||
throw redirect({ to: "/" });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div className="ml-[25%] mt-[0.5%]">
|
||||
<LoginForm />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,12 +6,8 @@ import {
|
||||
} from "@tanstack/react-router";
|
||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
import mobile from "is-mobile";
|
||||
import Cookies from "js-cookie";
|
||||
import { useEffect } from "react";
|
||||
import { Toaster } from "sonner";
|
||||
import Nav from "../components/navBar/Nav";
|
||||
import SideBarNav from "../components/navBar/SideBarNav";
|
||||
import { SidebarProvider } from "../components/ui/sidebar";
|
||||
import { userAccess } from "../lib/authClient";
|
||||
import { SessionGuard } from "../lib/providers/SessionProvider";
|
||||
import { ThemeProvider } from "../lib/providers/theme-provider";
|
||||
@@ -26,7 +22,7 @@ interface RootRouteContext {
|
||||
|
||||
const RootLayout = () => {
|
||||
//const { logout, login } = Route.useRouteContext();
|
||||
const defaultOpen = Cookies.get("sidebar_state") === "true";
|
||||
|
||||
const router = useRouter();
|
||||
// console.log(mobile({ featureDetect: true, tablet: true }));
|
||||
|
||||
@@ -54,22 +50,13 @@ const RootLayout = () => {
|
||||
<div>
|
||||
<SessionGuard>
|
||||
<ThemeProvider>
|
||||
<div className="flex flex-col h-screen overflow-hidden">
|
||||
<Nav />
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<SidebarProvider defaultOpen={defaultOpen}>
|
||||
<SideBarNav />
|
||||
|
||||
<div className="flex-2 overflow-y-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
<Toaster expand richColors closeButton />
|
||||
{userAccess(null, ["systemAdmin"]) && (
|
||||
<TanStackRouterDevtools position="bottom-right" />
|
||||
)}
|
||||
<div className="flex-2 overflow-y-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
<Toaster expand richColors closeButton />
|
||||
{userAccess(null, ["systemAdmin"]) && (
|
||||
<TanStackRouterDevtools position="bottom-right" />
|
||||
)}
|
||||
</ThemeProvider>
|
||||
</SessionGuard>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { createFileRoute, Outlet } from "@tanstack/react-router";
|
||||
import { checkUserAccess } from "../../lib/authClient";
|
||||
|
||||
export const Route = createFileRoute("/_adminLayout")({
|
||||
beforeLoad: async () =>
|
||||
checkUserAccess({
|
||||
allowedRoles: ["admin", "systemAdmin"],
|
||||
moduleName: "admin", // optional
|
||||
}),
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,14 +6,14 @@ import {
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import { LstCard } from "../../../components/ui/lstCard";
|
||||
import { getSession, useAuth, useUserRoles } from "../../../lib/authClient";
|
||||
import { useAppForm } from "../../../lib/formStuff";
|
||||
} from "../../../../components/ui/card";
|
||||
import { LstCard } from "../../../../components/ui/lstCard";
|
||||
import { getSession, useAuth, useUserRoles } from "../../../../lib/authClient";
|
||||
import { useAppForm } from "../../../../lib/formStuff";
|
||||
|
||||
export default function LoginForm() {
|
||||
const router = useRouter();
|
||||
const search = useSearch({ from: "/(auth)/login" });
|
||||
const search = useSearch({ from: "/_app/(auth)/login" });
|
||||
const username = localStorage.getItem("username") || "";
|
||||
const rememberMe = localStorage.getItem("rememberMe") === "true";
|
||||
const { setSession } = useAuth();
|
||||
@@ -0,0 +1,86 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { api } from "@/lib/axiosAPI";
|
||||
import { useAppForm } from "@/lib/formStuff";
|
||||
import { LstCard } from "@/routes/_old/old/-components/extendedUi/LstCard";
|
||||
|
||||
export default function RequestResetPassword() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
try {
|
||||
const res = await api.post("api/user/resetpassword", {
|
||||
email: value.email,
|
||||
});
|
||||
|
||||
console.log(res);
|
||||
|
||||
if (res.status === 200) {
|
||||
toast.success(
|
||||
res.data.message
|
||||
? res.data.message
|
||||
: "If this email exists in our system, check your email for the reset link",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Reset your password</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your email address and we’ll send you a reset link
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<form.AppField
|
||||
name="email"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Email address"
|
||||
inputType="email"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Send Reset Link</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Remembered your password?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { Link, useNavigate } from "@tanstack/react-router";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { LstCard } from "@/components/ui/lstCard";
|
||||
import { api } from "@/lib/axiosAPI";
|
||||
import { useAppForm } from "@/lib/formStuff";
|
||||
|
||||
export default function ResetPasswordForm({ token }: { token: string }) {
|
||||
const navigate = useNavigate();
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
if (value.password != value.confirmPassword) {
|
||||
toast.error("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await api.post("/api/auth/reset-password", {
|
||||
newPassword: value.password,
|
||||
token: token,
|
||||
});
|
||||
if (res.status === 200) {
|
||||
toast.success("Password has been reset");
|
||||
form.reset();
|
||||
navigate({ to: "/login" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// @ts-ignore
|
||||
toast.error(error?.response.data.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Set a new password</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your new password below and confirm it to continue
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<form.AppField
|
||||
name="password"
|
||||
children={(field) => (
|
||||
<field.InputPasswordField
|
||||
label="New Password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<form.AppField
|
||||
name="confirmPassword"
|
||||
// validators={{
|
||||
// onChangeListenTo: ["password"],
|
||||
// onChange: ({ value, fieldApi }) => {
|
||||
// if (
|
||||
// value !==
|
||||
// fieldApi.form.getFieldValue("password")
|
||||
// ) {
|
||||
// return "Passwords do not match";
|
||||
// }
|
||||
// return undefined;
|
||||
// },
|
||||
// }}
|
||||
children={(field) => (
|
||||
<field.InputPasswordField
|
||||
label="Confirm Password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Reset Password</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Remembered your account?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
127
frontend/src/routes/_app/(auth)/-components/SignupForm.tsx
Normal file
127
frontend/src/routes/_app/(auth)/-components/SignupForm.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { api } from "@/lib/axiosAPI";
|
||||
import { useAppForm } from "@/lib/formStuff";
|
||||
import { LstCard } from "@/routes/_old/old/-components/extendedUi/LstCard";
|
||||
|
||||
export default function SignupForm() {
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
if (value.password != value.confirmPassword) {
|
||||
toast.error("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await api.post("/api/user/register", {
|
||||
username: value.username,
|
||||
name: value.username,
|
||||
email: value.email,
|
||||
password: value.password,
|
||||
});
|
||||
|
||||
if (res.status === 200) {
|
||||
toast.success(`Welcome ${value.username}, to lst.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// @ts-ignore
|
||||
toast.error(error?.response.data.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard className="p-6 w-96">
|
||||
<CardHeader>
|
||||
<CardTitle>Create an account</CardTitle>
|
||||
<CardDescription>Fill in your details to get started</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
{/* Username */}
|
||||
<form.AppField
|
||||
name="username"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Username"
|
||||
inputType="text"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Email */}
|
||||
<form.AppField
|
||||
name="email"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Email address"
|
||||
inputType="email"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Password */}
|
||||
<form.AppField
|
||||
name="password"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Password"
|
||||
inputType="password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Confirm Password */}
|
||||
<form.AppField
|
||||
name="confirmPassword"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Confirm Password"
|
||||
inputType="password"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Sign Up</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-sm text-gray-600">
|
||||
Already have an account?{" "}
|
||||
<Link
|
||||
to={"/login"}
|
||||
className="text-primary underline underline-offset-4 hover:text-primary/80"
|
||||
>
|
||||
Log in
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
30
frontend/src/routes/_app/(auth)/login.tsx
Normal file
30
frontend/src/routes/_app/(auth)/login.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { z } from "zod";
|
||||
import { authClient } from "../../../lib/authClient";
|
||||
import LoginForm from "./-components/LoginForm";
|
||||
|
||||
export const Route = createFileRoute("/_app/(auth)/login")({
|
||||
component: RouteComponent,
|
||||
validateSearch: z.object({
|
||||
redirect: z.string().optional(),
|
||||
}),
|
||||
beforeLoad: async () => {
|
||||
const result = await authClient.getSession({
|
||||
query: { disableCookieCache: true }, // force DB/Server lookup
|
||||
});
|
||||
|
||||
//console.log("session check:", result.data);
|
||||
|
||||
if (result.data) {
|
||||
throw redirect({ to: "/" });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div className="ml-[25%] mt-[0.5%]">
|
||||
<LoginForm />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/(auth)/user/")({
|
||||
export const Route = createFileRoute("/_app/(auth)/user/")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -9,5 +9,5 @@ function RouteComponent() {
|
||||
<div>
|
||||
<span>Nothing here </span>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { authClient, useAuth } from "../../../lib/authClient";
|
||||
import { authClient, useAuth } from "../../../../lib/authClient";
|
||||
|
||||
export const Route = createFileRoute("/(auth)/user/profile")({
|
||||
export const Route = createFileRoute("/_app/(auth)/user/profile")({
|
||||
beforeLoad: async () => {
|
||||
const result = await authClient.getSession({
|
||||
query: { disableCookieCache: true }, // force DB/Server lookup
|
||||
@@ -3,7 +3,7 @@ import z from "zod";
|
||||
import RequestResetPassword from "../-components/RequestResetPassword";
|
||||
import ResetPasswordForm from "../-components/ResetPasswordForm";
|
||||
|
||||
export const Route = createFileRoute("/(auth)/user/resetpassword")({
|
||||
export const Route = createFileRoute("/_app/(auth)/user/resetpassword")({
|
||||
// beforeLoad: ({ search }) => {
|
||||
// return { token: search.token };
|
||||
// },
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import SignupForm from "../-components/SignupForm";
|
||||
|
||||
export const Route = createFileRoute("/(auth)/user/signup")({
|
||||
export const Route = createFileRoute("/_app/(auth)/user/signup")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// src/routes/traffic/Grid.tsx
|
||||
import { format } from "date-fns";
|
||||
import React from "react";
|
||||
import { ScrollArea, ScrollBar } from "../../../components/ui/scroll-area";
|
||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||
|
||||
export const days = Array.from(
|
||||
{ length: 5 },
|
||||
@@ -1,19 +1,19 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
import { coreSocket } from "../../../lib/socket.io/socket";
|
||||
import "../-components/style.css";
|
||||
import { coreSocket } from "../../../../lib/socket.io/socket";
|
||||
|
||||
export const Route = createFileRoute("/(logistics)/logistics/deliverySchedule")(
|
||||
{
|
||||
beforeLoad: async () => {
|
||||
coreSocket.emit("joinScheduler", "scheduler");
|
||||
// coreSocket.on("scheduler", (p) => {
|
||||
// console.log(`[scheduler] received:`, p);
|
||||
// });
|
||||
},
|
||||
component: RouteComponent,
|
||||
export const Route = createFileRoute(
|
||||
"/_app/(logistics)/logistics/deliverySchedule",
|
||||
)({
|
||||
beforeLoad: async () => {
|
||||
coreSocket.emit("joinScheduler", "scheduler");
|
||||
// coreSocket.on("scheduler", (p) => {
|
||||
// console.log(`[scheduler] received:`, p);
|
||||
// })
|
||||
},
|
||||
);
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
// connect to the channel
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "../../../components/ui/select";
|
||||
import { api } from "../../../lib/axiosAPI";
|
||||
} from "../../../../components/ui/select";
|
||||
import { api } from "../../../../lib/axiosAPI";
|
||||
|
||||
const modules: string[] = [
|
||||
"users",
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/_adminLayout/admin/_users/prodUsers')({
|
||||
export const Route = createFileRoute('/_app/_adminLayout/admin/_users/prodUsers')({
|
||||
component: RouteComponent,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute, Link, Outlet } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/_adminLayout/admin/_users")({
|
||||
export const Route = createFileRoute("/_app/_adminLayout/admin/_users")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import { Button } from "../../../../../components/ui/button";
|
||||
|
||||
import {
|
||||
Table,
|
||||
@@ -28,8 +28,8 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../../../components/ui/table";
|
||||
import { getUsers } from "../../../../lib/querys/admin/getUsers";
|
||||
} from "../../../../../components/ui/table";
|
||||
import { getUsers } from "../../../../../lib/querys/admin/getUsers";
|
||||
import ExpandedRow from "../../-components/ExpandedRow";
|
||||
|
||||
type User = {
|
||||
@@ -38,7 +38,7 @@ type User = {
|
||||
roles: string | null;
|
||||
};
|
||||
|
||||
export const Route = createFileRoute("/_adminLayout/admin/_users/users")({
|
||||
export const Route = createFileRoute("/_app/_adminLayout/admin/_users/users")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -147,7 +147,7 @@ function RouteComponent() {
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<div>
|
||||
<div className="w-1/2">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
@@ -195,24 +195,24 @@ function RouteComponent() {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/_adminLayout/admin/servers')({
|
||||
export const Route = createFileRoute('/_app/_adminLayout/admin/servers')({
|
||||
component: RouteComponent,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/_adminLayout/admin/settings')({
|
||||
export const Route = createFileRoute('/_app/_adminLayout/admin/settings')({
|
||||
component: RouteComponent,
|
||||
})
|
||||
|
||||
19
frontend/src/routes/_app/_adminLayout/route.tsx
Normal file
19
frontend/src/routes/_app/_adminLayout/route.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createFileRoute, Outlet } from "@tanstack/react-router";
|
||||
import { checkUserAccess } from "../../../lib/authClient";
|
||||
|
||||
export const Route = createFileRoute("/_app/_adminLayout")({
|
||||
beforeLoad: async () =>
|
||||
checkUserAccess({
|
||||
allowedRoles: ["admin", "systemAdmin"],
|
||||
moduleName: "admin", // optional
|
||||
}),
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
16
frontend/src/routes/_app/index.tsx
Normal file
16
frontend/src/routes/_app/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
|
||||
export const Route = createFileRoute("/_app/")({
|
||||
component: Index,
|
||||
});
|
||||
|
||||
function Index() {
|
||||
return (
|
||||
<div>
|
||||
<div className="h-screen flex flex-col items-center justify-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
29
frontend/src/routes/_app/route.tsx
Normal file
29
frontend/src/routes/_app/route.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { createFileRoute, Outlet } from "@tanstack/react-router";
|
||||
import Cookies from "js-cookie";
|
||||
import Nav from "../../components/navBar/Nav";
|
||||
import SideBarNav from "../../components/navBar/SideBarNav";
|
||||
import { SidebarProvider } from "../../components/ui/sidebar";
|
||||
|
||||
export const Route = createFileRoute("/_app")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const defaultOpen = Cookies.get("sidebar_state") === "true";
|
||||
return (
|
||||
<div className="flex flex-col h-screen overflow-hidden">
|
||||
<div className="flex flex-col h-screen overflow-hidden">
|
||||
<Nav />
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<SidebarProvider defaultOpen={defaultOpen}>
|
||||
<SideBarNav />
|
||||
|
||||
<div className="flex-2 overflow-y-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute(
|
||||
'/(mobileStuff)/_mobileLayout/m/cyclecounts',
|
||||
'/_mobile/_mobileLayout/m/cyclecounts',
|
||||
)({
|
||||
component: RouteComponent,
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/(mobileStuff)/_mobileLayout/m/delivery')(
|
||||
export const Route = createFileRoute('/_mobile/_mobileLayout/m/delivery')(
|
||||
{
|
||||
component: RouteComponent,
|
||||
},
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import { cn } from "../../../../lib/utils";
|
||||
|
||||
export const Route = createFileRoute("/(mobileStuff)/_mobileLayout/m/")({
|
||||
export const Route = createFileRoute("/_mobile/_mobileLayout/m/")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/(mobileStuff)/_mobileLayout/m/relocate')(
|
||||
export const Route = createFileRoute('/_mobile/_mobileLayout/m/relocate')(
|
||||
{
|
||||
component: RouteComponent,
|
||||
},
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute, Outlet } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/(mobileStuff)/_mobileLayout")({
|
||||
export const Route = createFileRoute("/_mobile/_mobileLayout")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { checkUserAccess } from "@/lib/authClient";
|
||||
import HistoricalData from "../../-components/logistics/siloAdjustments/HistoricalData";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_old/old/(logistics)/siloAdjustments/$hist",
|
||||
)({
|
||||
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,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// In a loader
|
||||
loader: ({ params }) => params.hist,
|
||||
// Or in a component
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const { hist } = Route.useParams();
|
||||
return (
|
||||
<div>
|
||||
<HistoricalData laneId={hist} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { checkUserAccess } from "@/lib/authClient";
|
||||
import Comment from "../../../-components/logistics/siloAdjustments/Comment";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_old/old/(logistics)/siloAdjustments/comment/$comment",
|
||||
)({
|
||||
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,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
// In a loader
|
||||
loader: ({ params }) => params.comment,
|
||||
// Or in a component
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const { comment } = Route.useParams();
|
||||
return (
|
||||
<div className="ml-20 mt-20">
|
||||
<Comment id={comment} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
|
||||
import { checkUserAccess } from "../../../../../lib/authClient";
|
||||
import SiloPage from "../../-components/logistics/siloAdjustments/SiloPage";
|
||||
|
||||
export const Route = createFileRoute("/_old/old/(logistics)/siloAdjustments/")({
|
||||
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 (
|
||||
<div>
|
||||
<SiloPage />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Button } from "../../../../../components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../../../../components/ui/dialog";
|
||||
import Cards from "./Cards";
|
||||
//import { toast } from "sonner";
|
||||
|
||||
export function AddCards() {
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline">Add Cards</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="min-w-fit ">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Cards</DialogTitle>
|
||||
<DialogDescription>
|
||||
Manage Cards and there settings.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="flex flex-row">
|
||||
<div className="">
|
||||
<Cards name={"ppoo"} inventory />
|
||||
<Cards name={"inv-empty"} rowType={"empty"} />
|
||||
<Cards name={"inv-fg"} rowType={"fg"} />
|
||||
</div>
|
||||
<div className="">
|
||||
<Cards name={"inv-materials"} rowType={"materials"} />
|
||||
<Cards name={"inv-packaging"} rowType={"packaging"} />
|
||||
<Cards name={"inv-waste"} rowType={"waste"} />
|
||||
<Cards name={"openOrder"} inventory />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <DialogFooter>
|
||||
<Button type="submit">Save changes</Button>
|
||||
</DialogFooter> */}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
104
frontend/src/routes/_old/old/-components/dashboard/Cards.tsx
Normal file
104
frontend/src/routes/_old/old/-components/dashboard/Cards.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Button } from "../../../../../components/ui/button";
|
||||
import { Checkbox } from "../../../../../components/ui/checkbox";
|
||||
import { Label } from "../../../../../components/ui/label";
|
||||
import { useAppForm } from "../../../../../lib/formStuff";
|
||||
import { useCardStore } from "../../-lib/store/useCardStore";
|
||||
|
||||
export default function Cards(card: any) {
|
||||
const { addCard, removeCard, cards } = useCardStore();
|
||||
let existing: any = cards.filter((n: any) => n.name === card.name);
|
||||
|
||||
//console.log(existing);
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
name: existing[0]?.name || card.name,
|
||||
rowType: existing[0]?.type ?? card.rowType,
|
||||
age: existing[0]?.age ?? 90,
|
||||
active: existing[0]?.active ?? false,
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
console.log(value);
|
||||
const testCard: any = cards.filter((i: any) => i.name === value.name);
|
||||
|
||||
if (value.active) {
|
||||
const newCard = {
|
||||
name: `${value.name}`,
|
||||
rowType: value.rowType,
|
||||
age: value.age ?? 90,
|
||||
active: value.active,
|
||||
};
|
||||
if (testCard.length > 0) {
|
||||
removeCard(value.name);
|
||||
addCard(newCard);
|
||||
return;
|
||||
}
|
||||
// change the name for a type card
|
||||
|
||||
addCard(newCard);
|
||||
} else {
|
||||
removeCard(value.name);
|
||||
}
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className="border-solid border-2 m-2">
|
||||
<p>{card.name}</p>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
className="flex flex-row"
|
||||
>
|
||||
<form.AppField
|
||||
name="active"
|
||||
// validators={{
|
||||
// // We can choose between form-wide and field-specific validators
|
||||
// onChange: ({ value }) =>
|
||||
// value.length > 3
|
||||
// ? undefined
|
||||
// : "Username must be longer than 3 letters",
|
||||
// }}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 p-2 flex flex-row">
|
||||
<div>
|
||||
<Label htmlFor="active">
|
||||
<span>Active</span>
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
<Checkbox
|
||||
className="ml-2"
|
||||
name={field.name}
|
||||
onBlur={field.handleBlur}
|
||||
checked={field.state.value}
|
||||
onCheckedChange={(e) => field.handleChange(e)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
{!card.inventory && (
|
||||
<>
|
||||
<form.AppField
|
||||
name="age"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Age"
|
||||
inputType="number"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="mt-7">
|
||||
<Button type="submit" onClick={() => form.handleSubmit()}>
|
||||
Save Card
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { useCardStore } from "../../-lib/store/useCardStore";
|
||||
import INVCheckCard from "../logistics/warehouse/InventoryCard";
|
||||
import OpenOrders from "../logistics/warehouse/openOrders";
|
||||
import PPOO from "../logistics/warehouse/PPOOCard";
|
||||
|
||||
const componentsMap: any = {
|
||||
ppoo: PPOO,
|
||||
inv: INVCheckCard,
|
||||
openOrder: OpenOrders,
|
||||
//QualityRequest,
|
||||
};
|
||||
|
||||
export default function DashBoard() {
|
||||
const { cards } = useCardStore();
|
||||
|
||||
//console.log(cards);
|
||||
return (
|
||||
<div className="ml-5 w-11/12 h-9/10 grid grid-cols-12 gap-1">
|
||||
{cards.map((a: any) => {
|
||||
const name = a.name; //.filter((c) => c.i === card.i)[0].i || "name";
|
||||
|
||||
const Component = componentsMap[name.split("-")[0]];
|
||||
if (name === "openOrder") {
|
||||
return (
|
||||
<div key={a.name} className="col-span-6">
|
||||
<Component age={a.age} type={a.rowType} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
//console.log(name.split("-")[0], a);
|
||||
return (
|
||||
<div key={a.name} className="col-span-3">
|
||||
<Component data={a} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
|
||||
interface LstCardProps {
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export function LstCard({
|
||||
children,
|
||||
className = "",
|
||||
style = {},
|
||||
}: LstCardProps) {
|
||||
return (
|
||||
<Card
|
||||
className={`border-solid border-1 border-[#00659c] ${className}`}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarTrigger,
|
||||
} from "../../../../../components/ui/sidebar";
|
||||
import {
|
||||
useAuth,
|
||||
userAccess,
|
||||
useUserRoles,
|
||||
} from "../../../../../lib/authClient";
|
||||
import { useModuleStore } from "../../-lib/store/useModuleStore";
|
||||
import { AdminSideBar } from "./side-components/admin";
|
||||
import { EomSideBar } from "./side-components/eom";
|
||||
import { ForkliftSideBar } from "./side-components/forklift";
|
||||
import { Header } from "./side-components/header";
|
||||
import { LogisticsSideBar } from "./side-components/logistics";
|
||||
import { ProductionSideBar } from "./side-components/production";
|
||||
import { QualitySideBar } from "./side-components/quality";
|
||||
|
||||
export function AppSidebar() {
|
||||
const { session } = useAuth();
|
||||
const { userRoles } = useUserRoles();
|
||||
const { modules } = useModuleStore();
|
||||
|
||||
return (
|
||||
<Sidebar collapsible="icon">
|
||||
<SidebarContent>
|
||||
<Header />
|
||||
|
||||
<ProductionSideBar
|
||||
user={session?.user as any}
|
||||
moduleID={
|
||||
modules.filter((n) => n.name === "production")[0]
|
||||
?.module_id as string
|
||||
}
|
||||
/>
|
||||
|
||||
{/* userAccess("logistics", ["systemAdmin", "admin","manager","viewer"]) */}
|
||||
<LogisticsSideBar user={session?.user as any} userRoles={userRoles} />
|
||||
{userAccess(null, ["systemAdmin"]) && (
|
||||
<>
|
||||
<ForkliftSideBar />
|
||||
<EomSideBar />
|
||||
<QualitySideBar />
|
||||
<AdminSideBar />
|
||||
</>
|
||||
)}
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<SidebarTrigger />
|
||||
</SidebarFooter>
|
||||
</Sidebar>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import {
|
||||
AlignJustify,
|
||||
Atom,
|
||||
Logs,
|
||||
Minus,
|
||||
Plus,
|
||||
Server,
|
||||
Settings,
|
||||
ShieldCheck,
|
||||
Users,
|
||||
Webhook,
|
||||
} from "lucide-react";
|
||||
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "../../../../../../components/ui/collapsible";
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSub,
|
||||
SidebarMenuSubButton,
|
||||
SidebarMenuSubItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
import { useSettingStore } from "../../../-lib/store/useSettings";
|
||||
import { useSubModuleStore } from "../../../-lib/store/useSubModuleStore";
|
||||
|
||||
const iconMap: any = {
|
||||
ShieldCheck: ShieldCheck,
|
||||
AlignJustify: AlignJustify,
|
||||
Settings: Settings,
|
||||
Atom: Atom,
|
||||
Logs: Logs,
|
||||
Users: Users,
|
||||
Webhook: Webhook,
|
||||
Server: Server,
|
||||
};
|
||||
|
||||
export function AdminSideBar() {
|
||||
const { subModules } = useSubModuleStore();
|
||||
const { settings } = useSettingStore();
|
||||
|
||||
const plantToken = settings.filter((n) => n.name === "plantToken");
|
||||
|
||||
const items = subModules.filter((m) => m.moduleName === "admin");
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Admin section</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
{items.map((item: any, index) => {
|
||||
const Icon = iconMap[item.icon] || AlignJustify;
|
||||
// drop down menu setup
|
||||
return (
|
||||
<SidebarMenu key={item.name}>
|
||||
{item.link === "#" ? (
|
||||
<Collapsible
|
||||
key={item.name}
|
||||
defaultOpen={index === 1}
|
||||
className="group/collapsible"
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton>
|
||||
<Icon />
|
||||
{item.name}{" "}
|
||||
<Plus className="ml-auto group-data-[state=open]/collapsible:hidden" />
|
||||
<Minus className="ml-auto group-data-[state=closed]/collapsible:hidden" />
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
{item.subSubModule?.length > 0 ? (
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
{item.subSubModule.map((i: any) => {
|
||||
const SubIcon = iconMap[i.icon] || AlignJustify;
|
||||
return (
|
||||
<SidebarMenuSubItem key={i.name}>
|
||||
{i.isActive && (
|
||||
<SidebarMenuSubButton asChild>
|
||||
<a
|
||||
href={
|
||||
i.name === "Swagger"
|
||||
? `https://${plantToken[0].value}prod.alpla.net/application/swagger/index.html`
|
||||
: i.link
|
||||
}
|
||||
target={i.newWindow ? "_blank" : "_self"}
|
||||
>
|
||||
<SubIcon />
|
||||
<span>{i.name}</span>
|
||||
</a>
|
||||
</SidebarMenuSubButton>
|
||||
)}
|
||||
</SidebarMenuSubItem>
|
||||
);
|
||||
})}
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
) : null}
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
) : (
|
||||
<SidebarMenu>
|
||||
{items.map((item) => {
|
||||
if (item.link === "#") return;
|
||||
return (
|
||||
<SidebarMenuItem key={item.name}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.link}>
|
||||
<Icon />
|
||||
<span>{item.name}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
);
|
||||
})}
|
||||
</SidebarMenu>
|
||||
)}
|
||||
</SidebarMenu>
|
||||
);
|
||||
})}
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
/* <SidebarMenu>
|
||||
{data.navMain.map((item, index) => (
|
||||
<Collapsible
|
||||
key={item.title}
|
||||
defaultOpen={index === 1}
|
||||
className="group/collapsible"
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton>
|
||||
<item.icon />
|
||||
{item.title}{" "}
|
||||
<Plus className="ml-auto group-data-[state=open]/collapsible:hidden" />
|
||||
<Minus className="ml-auto group-data-[state=closed]/collapsible:hidden" />
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
{item.items?.length ? (
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
{item.items.map((item) => (
|
||||
<SidebarMenuSubItem
|
||||
key={item.title}
|
||||
>
|
||||
{item.isActive && (
|
||||
<SidebarMenuSubButton
|
||||
asChild
|
||||
>
|
||||
<a
|
||||
href={item.url}
|
||||
target={
|
||||
item.newWindow
|
||||
? "_blank"
|
||||
: "_self"
|
||||
}
|
||||
>
|
||||
<item.icon />
|
||||
<span>
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
</SidebarMenuSubButton>
|
||||
)}
|
||||
</SidebarMenuSubItem>
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
) : null}
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu> */
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { FileText } from "lucide-react";
|
||||
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "End Of Month",
|
||||
url: "/eom",
|
||||
icon: FileText,
|
||||
},
|
||||
];
|
||||
|
||||
export function EomSideBar() {
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>End of month</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Forklift, Hourglass, Minus, Plus, Signature } from "lucide-react";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "../../../../../../components/ui/collapsible";
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSub,
|
||||
SidebarMenuSubButton,
|
||||
SidebarMenuSubItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "Gemone",
|
||||
url: "#",
|
||||
icon: Forklift,
|
||||
isActive: false,
|
||||
},
|
||||
];
|
||||
|
||||
const data = {
|
||||
navMain: [
|
||||
{
|
||||
title: "Forklift Management",
|
||||
url: "#",
|
||||
icon: Forklift,
|
||||
items: [
|
||||
{
|
||||
title: "All Forklifts",
|
||||
url: "#",
|
||||
icon: Forklift,
|
||||
},
|
||||
{
|
||||
title: "Leasing data",
|
||||
url: "#",
|
||||
isActive: false,
|
||||
icon: Signature,
|
||||
},
|
||||
{
|
||||
title: "Forklift Hours",
|
||||
url: "#",
|
||||
isActive: false,
|
||||
icon: Hourglass,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function ForkliftSideBar() {
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Forklift Section</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{data.navMain.map((item, index) => (
|
||||
<Collapsible
|
||||
key={item.title}
|
||||
defaultOpen={index === 1}
|
||||
className="group/collapsible"
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton>
|
||||
<item.icon />
|
||||
{item.title}{" "}
|
||||
<Plus className="ml-auto group-data-[state=open]/collapsible:hidden" />
|
||||
<Minus className="ml-auto group-data-[state=closed]/collapsible:hidden" />
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
{item.items?.length ? (
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
{item.items.map((item) => (
|
||||
<SidebarMenuSubItem key={item.title}>
|
||||
<SidebarMenuSubButton
|
||||
asChild
|
||||
isActive={item.isActive}
|
||||
>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuSubButton>
|
||||
</SidebarMenuSubItem>
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
) : null}
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import {
|
||||
SidebarHeader,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
|
||||
export function Header() {
|
||||
return (
|
||||
<SidebarHeader>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<Link to="/old">
|
||||
<SidebarMenuButton size="lg" asChild>
|
||||
<div className="flex flex-row">
|
||||
<img
|
||||
src={"/lst/app/imgs/dkLst.png"}
|
||||
alt="Description"
|
||||
className="size-8"
|
||||
/>
|
||||
|
||||
<div className="flex flex-col gap-0.5 leading-none">
|
||||
<span className="font-semibold">Logistics Support Tool</span>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarHeader>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Barcode, Command, Cylinder, Package, Truck } from "lucide-react";
|
||||
import { useSubModuleStore } from "@/lib/store/useSubModuleStore";
|
||||
import { User } from "@/types/users";
|
||||
import { hasPageAccess } from "@/utils/userAccess";
|
||||
import type { UserRoles } from "@/lib/authClient";
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
@@ -9,7 +7,10 @@ import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../ui/sidebar";
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
import { useSubModuleStore } from "../../../-lib/store/useSubModuleStore";
|
||||
import type { User } from "../../../-types/users";
|
||||
import { hasPageAccess } from "../../../-utils/userAccess";
|
||||
|
||||
const iconMap: any = {
|
||||
Package: Package,
|
||||
@@ -19,10 +20,17 @@ const iconMap: any = {
|
||||
Command: Command,
|
||||
};
|
||||
|
||||
export function LogisticsSideBar({ user }: { user: User | null }) {
|
||||
export function LogisticsSideBar({
|
||||
user,
|
||||
userRoles,
|
||||
}: {
|
||||
user: User | null;
|
||||
userRoles: UserRoles[] | null;
|
||||
}) {
|
||||
const { subModules } = useSubModuleStore();
|
||||
|
||||
const items = subModules.filter((m) => m.moduleName === "logistics");
|
||||
const items = subModules?.filter((m) => m.moduleName === "logistics");
|
||||
const userUpdate = { ...user, roles: userRoles };
|
||||
|
||||
return (
|
||||
<SidebarGroup>
|
||||
@@ -33,16 +41,20 @@ export function LogisticsSideBar({ user }: { user: User | null }) {
|
||||
const Icon = iconMap[item.icon];
|
||||
return (
|
||||
<SidebarMenuItem key={item.submodule_id}>
|
||||
<>
|
||||
{hasPageAccess(user, item.roles, item.name) && (
|
||||
{hasPageAccess(
|
||||
userUpdate as any,
|
||||
item.roles,
|
||||
item.moduleName,
|
||||
) && (
|
||||
<>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.link}>
|
||||
<a href={item?.link}>
|
||||
<Icon />
|
||||
<span>{item.name}</span>
|
||||
<span>{item?.name}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
)}
|
||||
</>
|
||||
</>
|
||||
)}
|
||||
</SidebarMenuItem>
|
||||
);
|
||||
})}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { Printer, Tag } from "lucide-react";
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
import type { User } from "../../../-types/users";
|
||||
import { hasPageAccess } from "../../../-utils/userAccess";
|
||||
|
||||
export function ProductionSideBar({
|
||||
user,
|
||||
moduleID,
|
||||
}: {
|
||||
user: User | null;
|
||||
moduleID: string;
|
||||
}) {
|
||||
const url: string = window.location.host.split(":")[0];
|
||||
const items = [
|
||||
{
|
||||
title: "One Click Print",
|
||||
url: "/lst/app/old/ocp",
|
||||
icon: Printer,
|
||||
role: ["viewer"],
|
||||
module: "ocp",
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
title: "Rfid Readers",
|
||||
url: "/lst/app/old/rfid",
|
||||
icon: Tag,
|
||||
role: ["viewer"],
|
||||
module: "production",
|
||||
active: url === "usday1vms006" || url === "localhost" ? true : false,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Production</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<>
|
||||
{hasPageAccess(user, item.role, moduleID) && item.active && (
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
)}
|
||||
</>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Printer } from "lucide-react";
|
||||
import {
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../../../../../components/ui/sidebar";
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "Qaulity Request",
|
||||
url: "#",
|
||||
icon: Printer,
|
||||
},
|
||||
];
|
||||
|
||||
export function QualitySideBar() {
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Quality</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../../../../../../components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../../../../../components/ui/dialog";
|
||||
import { useAppForm } from "../../../../../../lib/formStuff";
|
||||
import { getMachineConnected } from "../../../-utils/querys/logistics/machineConnected";
|
||||
import { getMachineNotConnected } from "../../../-utils/querys/logistics/notConnected";
|
||||
|
||||
export function AttachSilo(props: any) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const { data, isError, isLoading, refetch } = useQuery(
|
||||
getMachineNotConnected({
|
||||
siloID: props.silo.LocationID,
|
||||
connectionType: "detached",
|
||||
}),
|
||||
);
|
||||
const { refetch: attached } = useQuery(
|
||||
getMachineConnected({
|
||||
siloID: props.silo.LocationID,
|
||||
connectionType: "connected",
|
||||
}),
|
||||
);
|
||||
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
laneId: props.silo.LocationID,
|
||||
productionLotId: "",
|
||||
machineId: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"/lst/old/api/logistics/attachsilo",
|
||||
value,
|
||||
);
|
||||
|
||||
if (res.data.success) {
|
||||
toast.success(res.data.message);
|
||||
refetch();
|
||||
attached();
|
||||
form.reset();
|
||||
setOpen(!open);
|
||||
} else {
|
||||
console.log(res.data);
|
||||
toast.error(res.data.message);
|
||||
refetch();
|
||||
form.reset();
|
||||
setOpen(!open);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error(
|
||||
"There was an error attaching the silo please try again, if persist please enter a helpdesk ticket.",
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (isError)
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error loading data</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div>
|
||||
<p>Loading....</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
// convert the array that comes over to label and value
|
||||
const tranMachine = data.map((i: any) => ({
|
||||
value: i.machineId.toString(),
|
||||
label: i.name,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Dialog open={open}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline" onClick={() => setOpen(!open)}>
|
||||
Attach Silo
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Attach silo for: {props.silo.Description}</DialogTitle>
|
||||
<DialogDescription>
|
||||
Enter the new lotnumber, select the machine you would like to
|
||||
attach.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div>
|
||||
<p className="text-sm">
|
||||
NOTE: If the machine you are trying to attach is not showing in
|
||||
the drop down this means it is already attached to this silo.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<form.AppField
|
||||
name="productionLotId"
|
||||
children={(field) => (
|
||||
<field.InputField
|
||||
label="Lot Number"
|
||||
inputType="number"
|
||||
required={true}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<form.AppField
|
||||
name="machineId"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Machine"
|
||||
options={tranMachine}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="mt-2">
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline" onClick={() => setOpen(!open)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Attach</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { format } from "date-fns";
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
|
||||
import { CardContent } from "../../../../../../components/ui/card";
|
||||
import {
|
||||
type ChartConfig,
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from "../../../../../../components/ui/chart";
|
||||
import { LstCard } from "../../../../../../components/ui/lstCard";
|
||||
import { getAdjustments } from "../../../-utils/querys/logistics/siloAdjustments/getAdjustments";
|
||||
|
||||
export default function ChartData(props: any) {
|
||||
const { data, isError, isLoading } = useQuery(getAdjustments());
|
||||
const chartConfig = {
|
||||
stock: {
|
||||
label: "Stock",
|
||||
color: "rgb(255, 99, 132)",
|
||||
},
|
||||
actual: {
|
||||
label: "Actual",
|
||||
color: "rgb(53, 162, 235)",
|
||||
},
|
||||
} satisfies ChartConfig;
|
||||
|
||||
if (isLoading) return <div>Loading chart data</div>;
|
||||
if (isError) return <div>Error in loading chart data</div>;
|
||||
|
||||
let adjustments: any = data.filter((l: any) => l.locationID === props.laneId);
|
||||
adjustments = adjustments.splice(0, 10).map((s: any) => {
|
||||
return {
|
||||
date: format(s.dateAdjusted.replace("Z", ""), "M/d/yyyy hh:mm"),
|
||||
stock: s.currentStockLevel,
|
||||
actual: s.newLevel,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<LstCard className="w-[425px] h-[250px] m-1">
|
||||
<CardContent>
|
||||
{adjustments.length === 0 ? (
|
||||
<span>No silo data has been entered for this silo.</span>
|
||||
) : (
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={adjustments}
|
||||
margin={{
|
||||
left: 35,
|
||||
right: 45,
|
||||
bottom: 50,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={14}
|
||||
angle={-45}
|
||||
textAnchor="end"
|
||||
dy={10}
|
||||
tickFormatter={(value) => format(value, "M/d/yyyy")}
|
||||
/>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="dot" />}
|
||||
/>
|
||||
<Area
|
||||
dataKey="stock"
|
||||
type="natural"
|
||||
fill="rgba(53, 162, 235, 0.5)"
|
||||
fillOpacity={0.4}
|
||||
stroke="rgba(53, 162, 235, 0.5)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="actual"
|
||||
type="natural"
|
||||
fill="rgba(255, 99, 132, 0.5)"
|
||||
fillOpacity={0.4}
|
||||
stroke="rgba(255, 99, 132, 0.5)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
)}
|
||||
</CardContent>
|
||||
{/* <CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month{" "}
|
||||
<TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter> */}
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { useForm } from "@tanstack/react-form";
|
||||
import { useRouter } from "@tanstack/react-router";
|
||||
import axios from "axios";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { LstCard } from "../../extendedUi/LstCard";
|
||||
|
||||
export default function Comment(data: any) {
|
||||
const token = localStorage.getItem("auth_token");
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
comment: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
const res = await axios.post(
|
||||
`/lst/old/api/logistics/postcomment/${data.id.split("&")[0]}`,
|
||||
{
|
||||
comment: value.comment,
|
||||
key: data.id.split("&")[1].replace("amp;", ""),
|
||||
},
|
||||
{ headers: { Authorization: `Bearer ${token}` } },
|
||||
);
|
||||
|
||||
if (res.data.success) {
|
||||
toast.success(res.data.message);
|
||||
form.reset();
|
||||
router.navigate({ to: "/old/siloAdjustments" });
|
||||
}
|
||||
|
||||
if (!res.data.success) {
|
||||
toast.error(res.data.message);
|
||||
form.reset();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error(`There was an error posting your comment.`);
|
||||
}
|
||||
setIsSubmitting(false);
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className="">
|
||||
<LstCard>
|
||||
<CardHeader>Please enter your comment for the silo adjust</CardHeader>
|
||||
<CardContent>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<form.Field
|
||||
name="comment"
|
||||
validators={{
|
||||
// We can choose between form-wide and field-specific validators
|
||||
onChange: ({ value }) =>
|
||||
value.length > 10
|
||||
? undefined
|
||||
: "Comment must be longer than 10 characters.",
|
||||
}}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||
<Label htmlFor="comment" className="mb-2">
|
||||
Comment
|
||||
</Label>
|
||||
<Textarea
|
||||
name={field.name}
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
//type="number"
|
||||
onChange={(e) => field.handleChange(e.target.value)}
|
||||
/>
|
||||
{field.state.meta.errors.length ? (
|
||||
<em>{field.state.meta.errors.join(",")}</em>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={form.handleSubmit} disabled={isSubmitting}>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../../../../../../components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../../../../../components/ui/dialog";
|
||||
import { useAppForm } from "../../../../../../lib/formStuff";
|
||||
import { getMachineConnected } from "../../../-utils/querys/logistics/machineConnected";
|
||||
import { getMachineNotConnected } from "../../../-utils/querys/logistics/notConnected";
|
||||
|
||||
export function DetachSilo(props: any) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const { data, isError, isLoading, refetch } = useQuery(
|
||||
getMachineConnected({
|
||||
siloID: props.silo.LocationID,
|
||||
connectionType: "connected",
|
||||
}),
|
||||
);
|
||||
|
||||
const { refetch: notConnected } = useQuery(
|
||||
getMachineNotConnected({
|
||||
siloID: props.silo.LocationID,
|
||||
connectionType: "detached",
|
||||
}),
|
||||
);
|
||||
|
||||
const form = useAppForm({
|
||||
defaultValues: {
|
||||
laneId: props.silo.LocationID,
|
||||
machineId: 0,
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"/lst/old/api/logistics/detachsilo",
|
||||
value,
|
||||
);
|
||||
|
||||
if (res.status === 200) {
|
||||
console.log(res.data.data);
|
||||
toast.success(res.data.message);
|
||||
|
||||
refetch();
|
||||
notConnected();
|
||||
form.reset();
|
||||
setOpen(!open);
|
||||
} else {
|
||||
console.log(res.data);
|
||||
toast.error(res.data.message);
|
||||
refetch();
|
||||
form.reset();
|
||||
setOpen(!open);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error(
|
||||
"There was an error detaching the silo please try again, if persist please enter a helpdesk ticket.",
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (isError)
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error loading data</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div>
|
||||
<p>Loading....</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
// convert the array that comes over to label and value
|
||||
const tranMachine = data.map((i: any) => ({
|
||||
value: i.machineId.toString(),
|
||||
label: i.name,
|
||||
}));
|
||||
return (
|
||||
<Dialog open={open}>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setOpen(!open)}
|
||||
disabled={data.length === 0}
|
||||
>
|
||||
Detach Silo
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
form.handleSubmit();
|
||||
}}
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Attach silo for: {props.silo.Description}</DialogTitle>
|
||||
<DialogDescription>
|
||||
Select the machine you would like to detach.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="grid gap-4">
|
||||
<div className="grid gap-3">
|
||||
<div className="mt-2">
|
||||
<form.AppField
|
||||
name="machineId"
|
||||
children={(field) => (
|
||||
<field.SelectField
|
||||
label="Select Machine"
|
||||
options={tranMachine}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline" onClick={() => setOpen(!open)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<form.AppForm>
|
||||
<form.SubmitButton>Detach</form.SubmitButton>
|
||||
</form.AppForm>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getAdjustments } from "../../../-utils/querys/logistics/siloAdjustments/getAdjustments";
|
||||
import { columns } from "../../../-utils/tableData/siloAdjustmentHist/siloAdjHistColumns";
|
||||
import { SiloTable } from "../../../-utils/tableData/siloAdjustmentHist/siloData";
|
||||
|
||||
export default function HistoricalData(props: any) {
|
||||
const { data, isError, isLoading } = useQuery(getAdjustments());
|
||||
|
||||
if (isLoading) return <div>Loading adjustmnet data...</div>;
|
||||
if (isError) {
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error getting the adjustments.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
//console.log(data[0].locationID, parseInt(props.laneId));
|
||||
const adjustments: any = data.filter(
|
||||
(l: any) => l.locationID === parseInt(props.laneId),
|
||||
);
|
||||
return (
|
||||
<div className="container mx-auto py-10">
|
||||
<SiloTable columns={columns} data={adjustments} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,21 +6,20 @@ import { format } from "date-fns";
|
||||
import { CircleAlert } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { CardHeader } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
||||
import { Button } from "../../../../../../components/ui/button";
|
||||
import { CardHeader } from "../../../../../../components/ui/card";
|
||||
import { Input } from "../../../../../../components/ui/input";
|
||||
import { Label } from "../../../../../../components/ui/label";
|
||||
import { LstCard } from "../../../../../../components/ui/lstCard";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useSessionStore } from "@/lib/store/sessionStore";
|
||||
import { useGetUserRoles } from "@/lib/store/useGetRoles";
|
||||
import { useModuleStore } from "@/lib/store/useModuleStore";
|
||||
import { getStockSilo } from "@/utils/querys/logistics/siloAdjustments/getStockSilo";
|
||||
} from "../../../../../../components/ui/tooltip";
|
||||
import { useAuth, userAccess } from "../../../../../../lib/authClient";
|
||||
import { getStockSilo } from "../../../-utils/querys/logistics/siloAdjustments/getStockSilo";
|
||||
import { AttachSilo } from "./AttachSilo";
|
||||
import ChartData from "./ChartData";
|
||||
import { DetachSilo } from "./DetachSilo";
|
||||
@@ -28,19 +27,11 @@ import { DetachSilo } from "./DetachSilo";
|
||||
export default function SiloCard(data: any) {
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const { refetch } = useQuery(getStockSilo());
|
||||
const { user } = useSessionStore();
|
||||
const { userRoles } = useGetUserRoles();
|
||||
const { modules } = useModuleStore();
|
||||
const { session } = useAuth();
|
||||
|
||||
const silo = data.silo;
|
||||
|
||||
// roles that can do the silo adjustments
|
||||
const roles = ["systemAdmin", "technician", "admin", "manager"];
|
||||
|
||||
const module = modules.filter((n) => n.name === "logistics");
|
||||
|
||||
const accessRoles = userRoles.filter(
|
||||
(n: any) => n.module === module[0]?.name,
|
||||
) as any;
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
@@ -56,7 +47,7 @@ export default function SiloCard(data: any) {
|
||||
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"/api/logistics/createsiloadjustment",
|
||||
"/lst/old/api/logistics/createsiloadjustment",
|
||||
dataToSubmit,
|
||||
{ withCredentials: true },
|
||||
);
|
||||
@@ -76,7 +67,7 @@ export default function SiloCard(data: any) {
|
||||
}
|
||||
setSubmitting(false);
|
||||
} catch (error: any) {
|
||||
//console.log(error);
|
||||
console.log(error);
|
||||
if (error.status === 401) {
|
||||
toast.error(error.response.statusText);
|
||||
setSubmitting(false);
|
||||
@@ -123,65 +114,71 @@ export default function SiloCard(data: any) {
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{user && roles.includes(accessRoles[0]?.role) && (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<form.Field
|
||||
name="newLevel"
|
||||
validators={{
|
||||
// We can choose between form-wide and field-specific validators
|
||||
onChange: ({ value }) =>
|
||||
value.length > 1
|
||||
? undefined
|
||||
: "You must enter a value greate than 1",
|
||||
{session?.user &&
|
||||
userAccess("logistics", [
|
||||
"supervisor",
|
||||
"manager",
|
||||
"admin",
|
||||
"systemAdmin",
|
||||
]) && (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||
<div className="flex flex-row">
|
||||
<Label htmlFor="newLevel">New level</Label>
|
||||
<div>
|
||||
<Disclaimer />
|
||||
>
|
||||
<form.Field
|
||||
name="newLevel"
|
||||
validators={{
|
||||
// We can choose between form-wide and field-specific validators
|
||||
onChange: ({ value }) =>
|
||||
value.length > 1
|
||||
? undefined
|
||||
: "You must enter a value greate than 1",
|
||||
}}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||
<div className="flex flex-row">
|
||||
<Label htmlFor="newLevel">New level</Label>
|
||||
<div>
|
||||
<Disclaimer />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row">
|
||||
<Input
|
||||
name={field.name}
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
type="decimal"
|
||||
onChange={(e) =>
|
||||
field.handleChange(e.target.value)
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
className="ml-1"
|
||||
variant="outline"
|
||||
type="submit"
|
||||
onClick={form.handleSubmit}
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? (
|
||||
<span className="w-24">Submitting...</span>
|
||||
) : (
|
||||
<span className="w-24">Submit</span>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row">
|
||||
<Input
|
||||
name={field.name}
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
type="decimal"
|
||||
onChange={(e) =>
|
||||
field.handleChange(e.target.value)
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
className="ml-1"
|
||||
variant="outline"
|
||||
type="submit"
|
||||
onClick={form.handleSubmit}
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? (
|
||||
<span className="w-24">Submitting...</span>
|
||||
) : (
|
||||
<span className="w-24">Submit</span>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{field.state.meta.errors.length ? (
|
||||
<em>{field.state.meta.errors.join(",")}</em>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
)}
|
||||
{field.state.meta.errors.length ? (
|
||||
<em>{field.state.meta.errors.join(",")}</em>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -194,7 +191,7 @@ export default function SiloCard(data: any) {
|
||||
<DetachSilo silo={silo} />
|
||||
<Button variant="outline">
|
||||
<Link
|
||||
to={"/siloAdjustments/$hist"}
|
||||
to={"/old/siloAdjustments/$hist"}
|
||||
params={{ hist: silo.LocationID }}
|
||||
>
|
||||
Historical Data
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getStockSilo } from "../../../-utils/querys/logistics/siloAdjustments/getStockSilo";
|
||||
import SiloCard from "./SiloCard";
|
||||
|
||||
export default function SiloPage() {
|
||||
const { data, isError, error, isLoading } = useQuery(getStockSilo());
|
||||
|
||||
if (isLoading) return;
|
||||
|
||||
if (isError) return;
|
||||
|
||||
if (error)
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
There was an error getting the silos please notify your admin if this
|
||||
continues to be an issue
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap">
|
||||
{data?.map((s: any) => (
|
||||
<div key={s.LocationID} className="grow m-2 max-w-[800px]">
|
||||
<SiloCard silo={s} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getinventoryCheck } from "../../../-utils/querys/logistics/getInventoryCheck";
|
||||
import { invColumns } from "../../../-utils/tableData/InventoryCards/inventoryColumns";
|
||||
import { InvTable } from "../../../-utils/tableData/InventoryCards/inventoryData";
|
||||
//import { CircleX } from "lucide-react";
|
||||
//import { Suspense } from "react";
|
||||
//import { toast } from "sonner";
|
||||
|
||||
export default function INVCheckCard(props: any) {
|
||||
const { age, rowType } = props.data;
|
||||
|
||||
//console.log(props.data);
|
||||
const { data, isError, isLoading } = useQuery(
|
||||
getinventoryCheck({ age: age }),
|
||||
);
|
||||
|
||||
if (isLoading) return <div>Loading inventory data...</div>;
|
||||
if (isError) {
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error getting the inv.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
let laneData: any = data;
|
||||
if (props.type != "") {
|
||||
laneData = laneData.filter((l: any) => l.rowType === rowType.toUpperCase());
|
||||
|
||||
// age
|
||||
laneData = laneData.filter((l: any) => l.DaysSinceLast >= age);
|
||||
}
|
||||
|
||||
// const handleCloseCard = () => {
|
||||
// //removeCard("PPOO");
|
||||
|
||||
// toast.success("card removed");
|
||||
// };
|
||||
|
||||
return <InvTable columns={invColumns} data={laneData} info={props.data} />;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getPPOO } from "../../../-utils/querys/logistics/getPPOO";
|
||||
import { columns } from "../../../-utils/tableData/ppoo/ppooColumns";
|
||||
import { PPOOTable } from "../../../-utils/tableData/ppoo/ppooData";
|
||||
//import { CircleX } from "lucide-react";
|
||||
//import { Suspense } from "react";
|
||||
//import { toast } from "sonner";
|
||||
|
||||
export default function PPOO() {
|
||||
//{ style = {} }
|
||||
const { data, isError, isLoading } = useQuery(getPPOO());
|
||||
|
||||
if (isLoading) return <div>Loading adjustmnet data...</div>;
|
||||
if (isError) {
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error getting the adjustments.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// const handleCloseCard = () => {
|
||||
// //removeCard("PPOO");
|
||||
|
||||
// toast.success("card removed");
|
||||
// };
|
||||
|
||||
return (
|
||||
<PPOOTable
|
||||
columns={columns}
|
||||
data={data}
|
||||
//style={style}
|
||||
/>
|
||||
);
|
||||
// return (
|
||||
// <div style={style}>
|
||||
// <LstCard style={style}>
|
||||
// <Suspense fallback={<p>Loading PPOO...</p>}>
|
||||
// <div className={`flex justify-center`}>
|
||||
// <p
|
||||
// className={`drag-handle w-fit`}
|
||||
// style={{ cursor: "move", padding: "5px" }}
|
||||
// >
|
||||
// PPOO
|
||||
// </p>
|
||||
|
||||
// <button onClick={handleCloseCard}>
|
||||
// <CircleX />
|
||||
// </button>
|
||||
// </div>
|
||||
// <PPOOTable
|
||||
// columns={columns}
|
||||
// data={data}
|
||||
// //style={style}
|
||||
// />
|
||||
// </Suspense>
|
||||
// </LstCard>
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getOpenOrders } from "../../../-utils/querys/logistics/getOpenOrders";
|
||||
import { openOrderColumns } from "../../../-utils/tableData/openorders/ooColumns";
|
||||
import { OpenOrderTable } from "../../../-utils/tableData/openorders/ooData";
|
||||
//import { CircleX } from "lucide-react";
|
||||
//import { Suspense } from "react";
|
||||
//import { toast } from "sonner";
|
||||
|
||||
export default function OpenOrders() {
|
||||
//{ style = {} }
|
||||
const { data, isError, isLoading } = useQuery(getOpenOrders());
|
||||
|
||||
if (isLoading) return <div>Loading openOrder data...</div>;
|
||||
if (isError) {
|
||||
return (
|
||||
<div>
|
||||
<p>There was an error getting the openorders.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
let openOrders: any = data;
|
||||
|
||||
// const handleCloseCard = () => {
|
||||
// //removeCard("PPOO");
|
||||
|
||||
// toast.success("card removed");
|
||||
// };
|
||||
|
||||
return <OpenOrderTable columns={openOrderColumns} data={openOrders} />;
|
||||
}
|
||||
46
frontend/src/routes/_old/old/-lib/store/useCardStore.ts
Normal file
46
frontend/src/routes/_old/old/-lib/store/useCardStore.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { create } from "zustand";
|
||||
import { devtools, persist } from "zustand/middleware";
|
||||
|
||||
// interface CardSettings {
|
||||
// daysSinceLast?: number;
|
||||
// rowType?: string;
|
||||
// }
|
||||
|
||||
export interface Card {
|
||||
name: string;
|
||||
rowType: string;
|
||||
age: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
interface CardStore {
|
||||
cards: Card[]; // Array of card objects
|
||||
addCard: (card: Card) => void;
|
||||
updateCard: (name: string, updatedCard: Partial<Card>) => void;
|
||||
removeCard: (name: string) => void;
|
||||
}
|
||||
|
||||
export const useCardStore = create<CardStore>()(
|
||||
devtools(
|
||||
persist<CardStore>(
|
||||
(set) => ({
|
||||
cards: [],
|
||||
|
||||
addCard: (card) => set((state) => ({ cards: [...state.cards, card] })),
|
||||
|
||||
updateCard: (name, updatedCard) =>
|
||||
set((state) => ({
|
||||
cards: state.cards.map((card) =>
|
||||
card.name === name ? { ...card, ...updatedCard } : card,
|
||||
),
|
||||
})),
|
||||
|
||||
removeCard: (name) =>
|
||||
set((state) => ({
|
||||
cards: state.cards.filter((card) => card.name !== name),
|
||||
})),
|
||||
}),
|
||||
{ name: "cards" },
|
||||
),
|
||||
),
|
||||
);
|
||||
30
frontend/src/routes/_old/old/-lib/store/useModuleStore.ts
Normal file
30
frontend/src/routes/_old/old/-lib/store/useModuleStore.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import axios from "axios";
|
||||
import { create } from "zustand";
|
||||
import type { Modules } from "../../-types/modules";
|
||||
|
||||
interface SettingState {
|
||||
modules: Modules[];
|
||||
|
||||
fetchModules: () => Promise<void>;
|
||||
setModules: (modules: Modules[]) => void;
|
||||
}
|
||||
interface FetchModulesResponse {
|
||||
data: Modules[];
|
||||
}
|
||||
|
||||
export const useModuleStore = create<SettingState>()((set) => ({
|
||||
modules: [],
|
||||
setModules: (modules) => set({ modules }),
|
||||
fetchModules: async () => {
|
||||
try {
|
||||
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
|
||||
const response = await axios.get(`/lst/old/api/server/modules`, {});
|
||||
const data: FetchModulesResponse = response.data; //await response.json();
|
||||
//console.log(data);
|
||||
set({ modules: data.data });
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch modules:", error);
|
||||
set({ modules: [] });
|
||||
}
|
||||
},
|
||||
}));
|
||||
28
frontend/src/routes/_old/old/-lib/store/useSettings.ts
Normal file
28
frontend/src/routes/_old/old/-lib/store/useSettings.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
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(`/lst/api/system/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: [] });
|
||||
}
|
||||
},
|
||||
}));
|
||||
30
frontend/src/routes/_old/old/-lib/store/useSubModuleStore.ts
Normal file
30
frontend/src/routes/_old/old/-lib/store/useSubModuleStore.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import axios from "axios";
|
||||
import { create } from "zustand";
|
||||
import type { SubModules } from "../../-types/modules";
|
||||
|
||||
interface SettingState {
|
||||
subModules: SubModules[];
|
||||
|
||||
fetchSubModules: () => Promise<void>;
|
||||
setSubModules: (modules: SubModules[]) => void;
|
||||
}
|
||||
interface FetchModulesResponse {
|
||||
data: SubModules[];
|
||||
}
|
||||
|
||||
export const useSubModuleStore = create<SettingState>()((set) => ({
|
||||
subModules: [],
|
||||
setSubModules: (subModules) => set({ subModules }),
|
||||
fetchSubModules: async () => {
|
||||
try {
|
||||
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
|
||||
const response = await axios.get(`/lst/old/api/server/submodules`, {});
|
||||
const data: FetchModulesResponse = response.data; //await response.json();
|
||||
//console.log(data);
|
||||
set({ subModules: data.data });
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch settings:", error);
|
||||
set({ subModules: [] });
|
||||
}
|
||||
},
|
||||
}));
|
||||
19
frontend/src/routes/_old/old/-types/lots.ts
Normal file
19
frontend/src/routes/_old/old/-types/lots.ts
Normal 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;
|
||||
};
|
||||
20
frontend/src/routes/_old/old/-types/modules.ts
Normal file
20
frontend/src/routes/_old/old/-types/modules.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export interface Modules {
|
||||
module_id: string;
|
||||
name: string;
|
||||
active: boolean;
|
||||
roles: string;
|
||||
add_user: string;
|
||||
add_date: Date;
|
||||
upd_user: string;
|
||||
upd_date: Date;
|
||||
}
|
||||
|
||||
export interface SubModules {
|
||||
submodule_id: string;
|
||||
name: string;
|
||||
link: string;
|
||||
icon: string;
|
||||
moduleName: string;
|
||||
active: boolean;
|
||||
roles: string[];
|
||||
}
|
||||
4
frontend/src/routes/_old/old/-types/roles.ts
Normal file
4
frontend/src/routes/_old/old/-types/roles.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface Roles {
|
||||
role: string;
|
||||
module_id: string;
|
||||
}
|
||||
10
frontend/src/routes/_old/old/-types/users.ts
Normal file
10
frontend/src/routes/_old/old/-types/users.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { type Roles } from "./roles";
|
||||
|
||||
export type User = {
|
||||
user_id: string;
|
||||
email: string;
|
||||
username: string;
|
||||
roles: Roles[];
|
||||
role: string;
|
||||
prod?: string;
|
||||
};
|
||||
25
frontend/src/routes/_old/old/-utils/moduleActive.ts
Normal file
25
frontend/src/routes/_old/old/-utils/moduleActive.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// type Feature = string;
|
||||
// interface Module {
|
||||
// id: number;
|
||||
// name: string;
|
||||
// features: Feature[];
|
||||
// active: boolean;
|
||||
// }
|
||||
|
||||
import { useModuleStore } from "../-lib/store/useModuleStore";
|
||||
|
||||
// const modules: Module[] = [
|
||||
// {id: 1, name: "production", active: true, features: ["view", "edit", "approve"]},
|
||||
// {id: 2, name: "logistics", active: true, features: ["view", "assign", "track"]},
|
||||
// {id: 3, name: "quality", active: false, features: ["view", "audit", "approve"]},
|
||||
// {id: 4, name: "forklift", active: true, features: ["view", "request", "operate"]},
|
||||
// {id: 5, name: "admin", active: true, features: ["view", "manage_users", "view_logs", "settings"]},
|
||||
// ];
|
||||
|
||||
export function moduleActive(moduleName: string): boolean {
|
||||
const { modules } = useModuleStore();
|
||||
const module = modules?.find(
|
||||
(m: any) => m.name === moduleName && m.active === true,
|
||||
);
|
||||
return module ? true : false;
|
||||
}
|
||||
14
frontend/src/routes/_old/old/-utils/oldAppUrl.tsx
Normal file
14
frontend/src/routes/_old/old/-utils/oldAppUrl.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const oldServerUrl = async () => {
|
||||
const res = await axios.get("/lst/api/system/settings");
|
||||
const settings = res.data.data;
|
||||
|
||||
console.log("Settings", settings);
|
||||
const server = settings.filter((n: any) => n.name === "v1Server");
|
||||
const port = settings.filter((n: any) => n.name === "v1Port");
|
||||
const url = `http://${server[0]?.value}:${port[0]?.value}`;
|
||||
|
||||
console.log(url);
|
||||
return url;
|
||||
};
|
||||
25
frontend/src/routes/_old/old/-utils/querys/admin/modules.tsx
Normal file
25
frontend/src/routes/_old/old/-utils/querys/admin/modules.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getModules(token: string) {
|
||||
return queryOptions({
|
||||
queryKey: ["modules"],
|
||||
queryFn: () => fetchSettings(token),
|
||||
enabled: !!token,
|
||||
//staleTime: 1000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
const fetchSettings = async (token: string) => {
|
||||
const { data } = await axios.get("/api/server/modules", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
// if we are not localhost ignore the devDir setting.
|
||||
const url: string = window.location.host.split(":")[0];
|
||||
let settingsData = data.data;
|
||||
if (url != "localhost") {
|
||||
settingsData.filter((n: any) => n.name === "devDir");
|
||||
}
|
||||
return settingsData;
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getnotifications() {
|
||||
const token = localStorage.getItem("auth_token");
|
||||
return queryOptions({
|
||||
queryKey: ["getNotifications"],
|
||||
queryFn: () => fetchUsers(token),
|
||||
enabled: !!token, // Prevents query if token is null
|
||||
staleTime: 1000,
|
||||
refetchInterval: 2 * 2000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
const fetchUsers = async (token: string | null) => {
|
||||
const { data } = await axios.get(`/api/notify/notifications`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
// if we are not localhost ignore the devDir setting.
|
||||
//const url: string = window.location.host.split(":")[0];
|
||||
return data.data ?? [];
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user