test(dock schedule fail): failed attempt ad doing a dock schedule but leaving in here

This commit is contained in:
2025-10-15 14:52:48 -05:00
parent 705f29e908
commit 817a5c6876
44 changed files with 10377 additions and 161 deletions

View File

@@ -0,0 +1,24 @@
// src/routes/traffic/DropCell.tsx
import { useDroppable } from "@dnd-kit/core";
export function DropCell({ day, hour, children }: any) {
const { setNodeRef, isOver } = useDroppable({
id: `${day.toDateString()}-${hour}`,
data: { day, hour },
});
return (
<div
ref={setNodeRef}
className={`relative border h-20 p-1 ${
isOver ? "bg-blue-400" : ""
} overflow-visible`}
style={{
maxWidth: 340, // your allotted width
alignContent: "flex-start",
}}
>
{children}
</div>
);
}

View File

@@ -0,0 +1,69 @@
// src/routes/traffic/Grid.tsx
import { format } from "date-fns";
import React from "react";
import { ScrollArea, ScrollBar } from "../../../components/ui/scroll-area";
export const days = Array.from(
{ length: 5 },
(_, i) => new Date(Date.now() + i * 24 * 60 * 60 * 1000),
);
// the layout of the hours
const hoursBefore = 3;
const totalHours = 24;
// get the current hour
const currentHour = new Date().getHours();
const startHour = (currentHour - hoursBefore + 24) % 24;
// generate the hours array
const hours = Array.from(
{ length: totalHours },
(_, i) => (startHour + i) % 24,
);
export function Grid({
days,
children,
}: {
days: any;
children?: (day: Date, hour: number) => React.ReactNode;
}) {
return (
<ScrollArea className={`h-[80vh]`}>
<div
className="grid"
style={{
display: "grid",
gridTemplateColumns: `100px repeat(${days.length}, 350px)`, // each day = 180px wide
//minWidth: `${100 + days.length * 350}px`,
}}
>
{/* Empty top-left corner */}
<div className="sticky top-0 left-0 bg-background z-30"></div>
{/* Date headers */}
{days.map((d: any) => (
<div
key={d.toDateString()}
className="sticky top-0 bg-background z-20 p-2 font-semibold text-center"
>
{format(d, "EEEE M/d/yyyy")}
</div>
))}
{hours.map((hour) => (
<React.Fragment key={hour}>
<div className="border p-1 text-right text-sm">{hour}:00</div>
{days.map((d: any) => (
<div key={`${d}-${hour}`} className="relative border h-20">
{children && children(d, hour)}
</div>
))}
</React.Fragment>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
);
}

View File

@@ -0,0 +1,34 @@
import React from "react";
// GridBody.tsx
export function GridBody({ days, children }: { days: Date[]; children: any }) {
const hours = Array.from({ length: 24 }, (_, i) => i);
return (
<div
className="grid overflow-x-auto"
style={{
display: "grid",
gridTemplateColumns: `100px repeat(${days.length},340px)`,
}}
>
{hours.map((hour) => (
<React.Fragment key={hour}>
{/* time label, sticky left */}
<div className="sticky left-0 bg-background border p-1 text-right text-sm z-10">
{hour}:00
</div>
{days.map((day) => (
<div
key={`${day}-${hour}`}
className="border h-20 relative"
>
{children && children(day, hour)}
</div>
))}
</React.Fragment>
))}
</div>
);
}

View File

@@ -0,0 +1,24 @@
// GridHeader.tsx
import { format } from "date-fns";
export function GridHeader({ days }: { days: Date[] }) {
return (
<div
className="grid sticky top-0 z-30 bg-background"
style={{
display: "grid",
gridTemplateColumns: `100px repeat(${days.length},340px)`,
}}
>
<div /> {/* Empty corner for time labels */}
{days.map((d) => (
<div
key={d.toDateString()}
className="p-2 font-semibold text-center border-b"
>
{format(d, "EEE M/d/yyyy")}
</div>
))}
</div>
);
}

View File

@@ -0,0 +1,44 @@
// ShipmentItem.tsx
import { useDraggable } from "@dnd-kit/core";
interface ShipmentItemProps {
shipment: any;
index?: number;
perm?: boolean;
}
export function ShipmentItem({
shipment,
index = 0,
perm = true,
}: ShipmentItemProps) {
const { setNodeRef, listeners, attributes, transform } = useDraggable({
id: shipment.orderNumber,
data: shipment,
});
const offsetX = index * 10;
const style: React.CSSProperties = {
transform: transform
? `translate(${transform.x}px, ${transform.y}px)`
: `translateX(${offsetX}px)`,
transition: transform ? "none" : "transform 0.2s ease",
zIndex: 10 + index,
position: "absolute",
top: 0,
left: 0,
cursor: "grab",
};
return (
<div
ref={setNodeRef}
{...listeners}
{...attributes}
style={style}
className="w-[160px] p-2 text-xs rounded shadow select-none "
>
{shipment.orderNumber}
</div>
);
}

View File

@@ -0,0 +1,125 @@
.react-calendar-timeline * {
box-sizing: border-box;
}
.react-calendar-timeline .rct-outer {
display: block;
overflow: hidden;
white-space: nowrap;
}
.react-calendar-timeline .rct-scroll {
display: inline-block;
white-space: normal;
vertical-align: top;
overflow-x: scroll;
overflow-y: hidden;
-ms-touch-action: none;
touch-action: none;
}
.react-calendar-timeline .rct-item:hover {
z-index: 88;
}
.react-calendar-timeline .rct-item .rct-item-content {
position: sticky;
position: -webkit-sticky; /* still fine — helps with drag display */
left: 0;
/* Let multiple lines render */
display: block;
white-space: normal; /* ⬅ allow wrapping */
overflow: visible; /* ⬅ don't clip longer content */
height: auto; /* ⬅ expand with content */
padding: 4px 6px; /* ⬅ spacing inside item */
line-height: 1.3; /* ⬅ readable multi-line spacing */
border-radius: 2px;
box-sizing: border-box; /* consistent height/padding */
}
.react-calendar-timeline .rct-sidebar {
overflow: hidden;
white-space: normal;
display: inline-block;
vertical-align: top;
position: relative;
box-sizing: border-box;
border-right: 1px solid #bbb;
}
.react-calendar-timeline .rct-sidebar.rct-sidebar-right {
border-right: 0;
border-left: 1px solid #bbb;
}
.react-calendar-timeline .rct-sidebar .rct-sidebar-row {
padding: 0 4px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
box-sizing: border-box;
margin: 0;
border-bottom: 1px solid #bbb;
}
.react-calendar-timeline .rct-sidebar .rct-sidebar-row.rct-sidebar-row-odd {
background: #0000000d;
}
.react-calendar-timeline .rct-sidebar .rct-sidebar-row.rct-sidebar-row-even {
background: transparent;
}
.react-calendar-timeline .rct-vertical-lines .rct-vl {
position: absolute;
border-left: 1px solid #bbb;
z-index: 30;
}
.react-calendar-timeline .rct-vertical-lines .rct-vl.rct-vl-first {
border-left-width: 2px;
}
.react-calendar-timeline .rct-vertical-lines .rct-vl.rct-day-6,
.react-calendar-timeline .rct-vertical-lines .rct-vl.rct-day-0 {
background: #faf6e180;
}
.react-calendar-timeline .rct-horizontal-lines {
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.react-calendar-timeline .rct-horizontal-lines .rct-hl-even,
.react-calendar-timeline .rct-horizontal-lines .rct-hl-odd {
border-bottom: 1px solid #bbb;
box-sizing: border-box;
z-index: 40;
}
.react-calendar-timeline .rct-horizontal-lines .rct-hl-odd {
background: #0000000d;
}
.react-calendar-timeline .rct-horizontal-lines .rct-hl-even {
background: transparent;
}
.react-calendar-timeline .rct-cursor-line {
position: absolute;
width: 2px;
background: #2196f3;
z-index: 51;
}
.react-calendar-timeline .rct-dateHeader {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
border-bottom: 1px solid #bbb;
cursor: pointer;
font-size: 14px;
background-color: #f0f0f0;
border-left: 2px solid #bbb;
}
.react-calendar-timeline .rct-dateHeader-primary {
background-color: initial;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
color: #fff;
}
.react-calendar-timeline .rct-header-root {
background: #c52020;
border-bottom: 1px solid #bbb;
}
.react-calendar-timeline .rct-calendar-header {
border: 1px solid #bbb;
}

View File

@@ -0,0 +1,35 @@
import { useMemo, useState } from "react";
export function useDateWindow(initialStart = new Date()) {
const [startDate, setStartDate] = useState(initialStart);
const [endDayCount, setEndDayCount] = useState<string>(
localStorage.getItem("endDayCount") || "5",
);
const [startDayCount, startEndDayCount] = useState<string>(
localStorage.getItem("startDayCount") || "0",
);
const days = useMemo(() => {
const startOffset = parseInt(startDayCount, 10);
const endOffset = parseInt(endDayCount, 10);
const start = new Date(startDate);
start.setDate(start.getDate() - startOffset);
return Array.from({ length: endOffset + startOffset + 1 }, (_, i) => {
const d = new Date(start);
d.setDate(start.getDate() + i);
return d;
});
}, [startDate, startDayCount, endDayCount]);
return {
days,
startDate,
setStartDate,
endDayCount,
setEndDayCount,
startDayCount,
startEndDayCount,
};
}

View File

@@ -0,0 +1,66 @@
import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { coreSocket } from "../../../lib/socket.io/socket";
import "../-components/style.css";
import moment from "moment";
import Timeline from "react-calendar-timeline";
export const Route = createFileRoute("/(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
const [shipments, setShipments] = useState([]) as any;
//const [perm] = useState(true); // will check this for sure with a user permissions
const [loaded, setLoaded] = useState(false);
// useEffect(() => {
// const handleConnect = () => {
// console.log("✅ Socket connected, joining scheduler");
// coreSocket.emit("joinScheduler");
// };
// coreSocket.on("connect", handleConnect);
// //const handler = (msg: any) => console.log("💓", msg);
// const onUpdate = (msg: any) => {
// console.log(msg.data);
// setShipments(() => {
// return msg.data.map((i: any) => ({
// id: i.schedule_id,
// title: i.orderNumber,
// group: i.dock === "" ? 1 : 1, // this will just toss everything here for now will go to the actual dock id later
// start_time: moment(parseISO(i.lstDateCheck)),
// end_time: moment(addHours(parseISO(i.lstDateCheck), 1)),
// data: i,
// }));
// });
// if (!loaded) setLoaded(true);
// };
// //coreSocket.on("data", onData);
// coreSocket.on("scheduler:update", onUpdate);
// return () => {
// // cleanup on unmount
// //coreSocket.off("data", onData);
// coreSocket.off("scheduler:update", onUpdate);
// coreSocket.off("connect", handleConnect);
// };
// }, []);
// if (shipments.length === 0) {
// return <div>Loading.....</div>;
// }
return <div className="p-4 "></div>;
}

View File

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

View File

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

View File

@@ -0,0 +1,78 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { LstCard } from "../../../../components/ui/lstCard";
import {
CardContent,
CardHeader,
CardTitle,
} from "../../../../components/ui/card";
import { Button } from "../../../../components/ui/button";
import { cn } from "../../../../lib/utils";
export const Route = createFileRoute("/(mobileStuff)/_mobileLayout/m/")({
component: RouteComponent,
});
const commands = [
{
title: "Relocate",
description: "Moves a pallet from one location to another",
link: "/lst/app/m/relocate",
},
{
title: "Cycle Counts",
description: "Will do a cycle count on a specific lane",
link: "/lst/app/m/cyclecounts",
},
{
title: "Delivery",
description:
"Scan pallets to a delivery that has already been drag down in stock",
link: "/lst/app/m/delivery",
},
];
function RouteComponent() {
return (
<div className="p-3 space-y-3">
<LstCard>
<CardHeader>
<CardTitle className="flex justify-center">
Commands
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex flex-wrap justify-center gap-3">
{commands.map((cmd) => {
return (
<Link
key={cmd.title}
to={cmd.link}
className="block"
>
<Button
variant="outline"
className={cn(
"flex flex-col justify-center items-center",
"w-36 h-28 p-3 text-center", // fixed width/height for uniform grid
"border-muted bg-background hover:bg-accent/40",
"transition-all active:scale-95"
)}
>
<span className="text-base font-semibold leading-tight">
{cmd.title}
</span>
{/* <div className="max-w-[75px]">
<span className="text-xs text-wrap">
{cmd.description}
</span>
</div> */}
</Button>
</Link>
);
})}
</div>
</CardContent>
</LstCard>
</div>
);
}

View File

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

View File

@@ -0,0 +1,13 @@
import { createFileRoute, Outlet } from "@tanstack/react-router";
export const Route = createFileRoute("/(mobileStuff)/_mobileLayout")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<Outlet />
</div>
);
}

View File

@@ -1,4 +1,8 @@
import { createRootRouteWithContext, Outlet } from "@tanstack/react-router";
import {
createRootRouteWithContext,
Outlet,
useRouter,
} from "@tanstack/react-router";
import type { QueryClient } from "@tanstack/react-query";
import { Toaster } from "sonner";
@@ -10,6 +14,9 @@ import { SidebarProvider } from "../components/ui/sidebar";
import SideBarNav from "../components/navBar/SideBarNav";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { userAccess } from "../lib/authClient";
import mobile from "is-mobile";
import { useEffect } from "react";
import { coreSocket } from "../lib/socket.io/socket";
interface RootRouteContext {
queryClient: QueryClient;
@@ -21,6 +28,29 @@ 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 }));
// if mobile lets move to the mobile section.
useEffect(() => {
if (mobile({ featureDetect: true, tablet: true })) {
router.navigate({ to: "/m" });
}
coreSocket.on("connect", () => {
console.log("✅ Connected:", coreSocket.id);
});
coreSocket.on("disconnect", () => {
console.log("🔴 Disconnected");
});
return () => {
coreSocket.off("connect");
coreSocket.off("disconnect");
};
}, []);
return (
<div>
<SessionGuard>