239 lines
7.4 KiB
TypeScript
239 lines
7.4 KiB
TypeScript
import { Badge, Box, Button, Image, Text, Tooltip } from "@mantine/core";
|
|
import { useDisclosure } from "@mantine/hooks";
|
|
import moment from "moment";
|
|
import { useEffect, useState } from "react";
|
|
import { Socket } from "socket.io-client";
|
|
import { getImagesWorking } from "../../apis/bid";
|
|
import { useStatusToolStore } from "../../lib/zustand/use-status-tool-store";
|
|
import { IBid, IWebBid } from "../../system/type";
|
|
import { cn, extractDomainSmart, findNearestClosingChild, isTimeReached, stringToColor, subtractSeconds } from "../../utils";
|
|
import ShowImageModal from "./show-image-modal";
|
|
export interface IWorkingPageProps {
|
|
data: (IBid | IWebBid) & { type: string };
|
|
socket: Socket;
|
|
}
|
|
|
|
export default function WorkingPage({ data, socket }: IWorkingPageProps) {
|
|
const fallbackSrc =
|
|
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRGh5WFH8TOIfRKxUrIgJZoDCs1yvQ4hIcppw&s";
|
|
|
|
const [opened, { open, close }] = useDisclosure(false);
|
|
|
|
const [imageSrc, setImageSrc] = useState<string | null>(null);
|
|
|
|
const [lastUpdate, setLastUpdate] = useState<Date | null>(null);
|
|
|
|
const [payloadLoginStatus, setPayloadLoginStatus] = useState<{
|
|
data: IWebBid;
|
|
login_status: boolean;
|
|
} | null>(null);
|
|
|
|
const { statusTool } = useStatusToolStore();
|
|
|
|
function isIBid(obj: IBid | IWebBid): obj is IBid {
|
|
return "name" in obj;
|
|
}
|
|
|
|
const renderUrl = (
|
|
{ type, id }: (IBid | IWebBid) & { type: string },
|
|
name: string
|
|
) => {
|
|
return `${import.meta.env.VITE_BASE_URL}bids/status-working/${type
|
|
.replace("_", "-")
|
|
.toLowerCase()}/${id}/${name}`;
|
|
};
|
|
|
|
const extractTime = (filename: string) => {
|
|
return Number(filename.split("-")[0]) || 0;
|
|
};
|
|
|
|
const statusLabel = () => {
|
|
if (
|
|
statusTool &&
|
|
statusTool === "online" &&
|
|
payloadLoginStatus?.login_status
|
|
) {
|
|
return "logined";
|
|
}
|
|
return !statusTool || statusTool !== "online" ? "Unknown" : "logout";
|
|
};
|
|
|
|
useEffect(() => {
|
|
const updateImage = ({
|
|
type,
|
|
id,
|
|
filename,
|
|
}: {
|
|
type: string;
|
|
filename: string;
|
|
id: IBid["id"];
|
|
}) => {
|
|
if (type == data.type && id == data.id) {
|
|
setLastUpdate(new Date(extractTime(filename)));
|
|
setImageSrc(renderUrl(data, filename));
|
|
}
|
|
};
|
|
|
|
socket.on("working", updateImage);
|
|
|
|
return () => {
|
|
socket.off("working", updateImage);
|
|
};
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [socket, data.id, data.type]);
|
|
|
|
useEffect(() => {
|
|
const onLoginStatus = (data: { data: IWebBid; login_status: boolean }) => {
|
|
setPayloadLoginStatus(data);
|
|
};
|
|
|
|
const origin_url = isIBid(data) ? data.web_bid.origin_url : data.origin_url;
|
|
|
|
socket.on(`login-status.${origin_url}`, onLoginStatus);
|
|
|
|
return () => {
|
|
socket.off(`login-status.${origin_url}`, onLoginStatus);
|
|
};
|
|
}, [data, socket]);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
const result = await getImagesWorking(data);
|
|
|
|
if (!result || !result.data) return;
|
|
|
|
const filename = result.data[0];
|
|
|
|
setImageSrc(renderUrl(data, filename));
|
|
setLastUpdate(new Date(extractTime(filename)));
|
|
})();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
|
|
if(!isIBid(data)){
|
|
console.log(data)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Box
|
|
className={cn("rounded-md overflow-hidden relative shadow-lg", {
|
|
["border border-green-800"]: payloadLoginStatus?.login_status,
|
|
["border border-red-800"]: !payloadLoginStatus?.login_status,
|
|
})}
|
|
>
|
|
<Image
|
|
radius="md"
|
|
h={300}
|
|
style={{
|
|
objectFit: "cover",
|
|
}}
|
|
fallbackSrc={fallbackSrc}
|
|
src={imageSrc}
|
|
/>
|
|
|
|
<Box className="absolute bg-black/60 inset-0 flex items-center justify-center text-white font-bold flex-col gap-2 p-4 rounded-lg transition duration-300 hover:bg-opacity-70">
|
|
<Text className="text-lg tracking-wide text-center font-bold">
|
|
{isIBid(data) ? data.name : "Tracking page"}
|
|
</Text>
|
|
{isIBid(data) && (
|
|
<Text className="text-xs tracking-wide">{`Max price: $${data.max_price}`}</Text>
|
|
)}
|
|
{isIBid(data) && (
|
|
<Text className="text-xs tracking-wide">{`Current price: $${data.current_price}`}</Text>
|
|
)}
|
|
|
|
|
|
|
|
<Text className="text-sm italic opacity-80">
|
|
{moment(lastUpdate).format("HH:mm:ss DD/MM/YYYY")}
|
|
</Text>
|
|
|
|
|
|
{!isIBid(data) && <Tooltip label={'Time to tracking'}><Text>{`TT: ${moment(subtractSeconds(findNearestClosingChild(data)?.close_time || '', data.early_tracking_seconds)).format(
|
|
"HH:mm:ss DD/MM/YYYY"
|
|
)}`}</Text></Tooltip>}
|
|
|
|
<Box className="flex items-center gap-3">
|
|
{isIBid(data) && (
|
|
<Tooltip label={'Close time'}>
|
|
<Text
|
|
style={{ fontSize: "12px" }}
|
|
className="tracking-wide"
|
|
>{`CLT: ${moment(data.close_time).format(
|
|
"HH:mm:ss DD/MM/YYYY"
|
|
)}`}</Text>
|
|
</Tooltip>
|
|
)}
|
|
{isIBid(data) &&
|
|
data.close_time &&
|
|
!isTimeReached(
|
|
subtractSeconds(
|
|
data.close_time,
|
|
data.web_bid?.early_tracking_seconds || 0
|
|
)
|
|
) && (
|
|
<Tooltip label={'Time to tracking'}>
|
|
<Text
|
|
style={{ fontSize: "12px" }}
|
|
className="tracking-wide"
|
|
>{`TT: ${moment(
|
|
subtractSeconds(
|
|
data.close_time,
|
|
data.web_bid?.early_tracking_seconds || 0
|
|
)
|
|
).format("HH:mm:ss DD/MM/YYYY")}`}</Text>
|
|
</Tooltip>
|
|
)}
|
|
</Box>
|
|
<Box className="flex items-center gap-4">
|
|
<Button
|
|
size="xs"
|
|
color="green"
|
|
onClick={open}
|
|
className="bg-white text-black px-4 py-2 rounded-md shadow-md hover:bg-gray-200 transition"
|
|
>
|
|
Show
|
|
</Button>
|
|
<Button
|
|
target="_blank"
|
|
component="a"
|
|
size="xs"
|
|
href={data.url || "/"}
|
|
className="bg-white text-black px-4 py-2 rounded-md shadow-md hover:bg-gray-200 transition"
|
|
>
|
|
Link
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
|
|
<Box className="absolute top-2.5 left-2.5 flex items-center gap-2">
|
|
<Badge
|
|
color={payloadLoginStatus?.login_status ? "green" : "red"}
|
|
size="xs"
|
|
>
|
|
{statusLabel()}
|
|
</Badge>
|
|
|
|
<Badge
|
|
color={stringToColor(
|
|
isIBid(data) ? extractDomainSmart(data.web_bid.origin_url) : extractDomainSmart(data.origin_url)
|
|
)}
|
|
size="xs"
|
|
>
|
|
{isIBid(data) ? extractDomainSmart(data.web_bid.origin_url) : extractDomainSmart(data.origin_url)}
|
|
</Badge>
|
|
</Box>
|
|
</Box>
|
|
|
|
<ShowImageModal
|
|
src={imageSrc || fallbackSrc}
|
|
fallbackSrc={fallbackSrc}
|
|
opened={opened}
|
|
onClose={close}
|
|
/>
|
|
</>
|
|
);
|
|
}
|