added logs list
This commit is contained in:
parent
66d8196537
commit
4b7a868d1a
|
@ -4,23 +4,23 @@ import Dashboard from "./pages/Dashboard";
|
|||
import Project from "./pages/Project";
|
||||
import UserAuth from "./pages/UserAuth";
|
||||
import ToastProvider from "./components/templates/ToastProvider";
|
||||
import "./styles/main.scss"
|
||||
import "./styles/main.scss";
|
||||
import { LoggerProvider } from "./components/ui/log/LoggerContext";
|
||||
|
||||
const App: React.FC = () => {
|
||||
return (
|
||||
<ToastProvider>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/"
|
||||
element={<UserAuth />}
|
||||
/>
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/project" element={<Project />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</ToastProvider>
|
||||
<LoggerProvider>
|
||||
<ToastProvider>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/" element={<UserAuth />} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/project" element={<Project />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</ToastProvider>
|
||||
</LoggerProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
export default App;
|
|
@ -785,21 +785,135 @@ export const SpeedIcon = () => {
|
|||
);
|
||||
};
|
||||
|
||||
// export const DublicateIcon = () => {
|
||||
// return (
|
||||
// <svg
|
||||
// width="20"
|
||||
// height="20"
|
||||
// viewBox="0 0 20 20"
|
||||
// fill="none"
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// >
|
||||
// <path
|
||||
// fillRule="evenodd"
|
||||
// clipRule="evenodd"
|
||||
// d="M14.3125 11.375C14.3125 11.7545 14.0045 12.0625 13.625 12.0625H8.125C7.7455 12.0625 7.4375 11.7545 7.4375 11.375V5.875C7.4375 5.4955 7.7455 5.1875 8.125 5.1875H13.625C14.0045 5.1875 14.3125 5.4955 14.3125 5.875V11.375ZM13.625 4.5H8.125C7.36566 4.5 6.75 5.11566 6.75 5.875V11.375C6.75 12.1343 7.36566 12.75 8.125 12.75H13.625C14.3843 12.75 15 12.1343 15 11.375V5.875C15 5.11566 14.3843 4.5 13.625 4.5ZM11.5625 14.125C11.5625 14.5045 11.2545 14.8125 10.875 14.8125H5.375C4.9955 14.8125 4.6875 14.5045 4.6875 14.125V8.625C4.6875 8.2455 4.9955 7.9375 5.375 7.9375H6.0625V7.25H5.375C4.61566 7.25 4 7.86566 4 8.625V14.125C4 14.8843 4.61566 15.5 5.375 15.5H10.875C11.6343 15.5 12.25 14.8843 12.25 14.125V13.4375H11.5625V14.125Z"
|
||||
// fill="var(--text-color)"
|
||||
// />
|
||||
// </svg>
|
||||
// );
|
||||
// };
|
||||
export const LogListIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="25"
|
||||
viewBox="0 0 24 25"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14.5 18.25H5.5M18.5 21.7272V19.3568H17.3829C16.8245 19.3568 16.375 18.9072 16.375 18.3489V18.08C16.375 17.5216 16.8246 17.0721 17.3829 17.0721H18.5V13.7318H17.2579C16.6995 13.7318 16.25 13.2822 16.25 12.7239V12.4551C16.25 11.8967 16.6996 11.4472 17.2579 11.4472H18.5V7.98185H17.2579C16.6995 7.98185 16.25 7.5323 16.25 6.97395V6.70515C16.25 6.14675 16.6996 5.69725 17.2579 5.69725H18.5V3.27065M14.5 12.75H5.5M12 7.24995H5.5M20.25 3.25H3.75C3.1977 3.25 2.75 3.6977 2.75 4.25V20.75C2.75 21.3023 3.1977 21.75 3.75 21.75H20.25C20.8023 21.75 21.25 21.3023 21.25 20.75V4.25C21.25 3.6977 20.8023 3.25 20.25 3.25Z"
|
||||
stroke="#2B3344"
|
||||
strokeWidth="1.2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const LogTickIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="10"
|
||||
height="10"
|
||||
viewBox="0 0 10 10"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_3962_4223)">
|
||||
<path
|
||||
d="M5.00065 0.835938C2.70482 0.835938 0.833984 2.70677 0.833984 5.0026C0.833984 7.29844 2.70482 9.16927 5.00065 9.16927C7.29648 9.16927 9.16732 7.29844 9.16732 5.0026C9.16732 2.70677 7.29648 0.835938 5.00065 0.835938ZM6.99232 4.04427L4.62982 6.40677C4.57148 6.4651 4.49232 6.49844 4.40898 6.49844C4.32565 6.49844 4.24648 6.4651 4.18815 6.40677L3.00898 5.2276C2.88815 5.10677 2.88815 4.90677 3.00898 4.78594C3.12982 4.6651 3.32982 4.6651 3.45065 4.78594L4.40898 5.74427L6.55065 3.6026C6.67148 3.48177 6.87148 3.48177 6.99232 3.6026C7.11315 3.72344 7.11315 3.91927 6.99232 4.04427Z"
|
||||
fill="#49B841"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_3962_4223">
|
||||
<rect width="10" height="10" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const LogInfoIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0.75 2.64438V7.41438C0.75 7.92094 0.951232 8.40675 1.30943 8.76495C1.66762 9.12314 2.15344 9.32438 2.66 9.32438H3.615V10.7544L6.5 9.32438H9.365C9.87156 9.32438 10.3574 9.12314 10.7156 8.76495C11.0738 8.40675 11.275 7.92094 11.275 7.41438V2.64438C11.275 2.13781 11.0738 1.652 10.7156 1.2938C10.3574 0.935607 9.87156 0.734375 9.365 0.734375H2.66C2.15344 0.734375 1.66762 0.935607 1.30943 1.2938C0.951232 1.652 0.75 2.13781 0.75 2.64438Z"
|
||||
fill="#8E8E93"
|
||||
/>
|
||||
<path
|
||||
d="M5.04492 6.94531H6.95492"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
<path
|
||||
d="M5.04492 4.07812H5.99992V6.94313"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
<path
|
||||
d="M5.52539 2.65625H6.47539"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const WarningIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0.75 2.64438V7.41438C0.75 7.92094 0.951232 8.40675 1.30943 8.76495C1.66762 9.12314 2.15344 9.32438 2.66 9.32438H3.615V10.7544L6.5 9.32438H9.365C9.87156 9.32438 10.3574 9.12314 10.7156 8.76495C11.0738 8.40675 11.275 7.92094 11.275 7.41438V2.64438C11.275 2.13781 11.0738 1.652 10.7156 1.2938C10.3574 0.935607 9.87156 0.734375 9.365 0.734375H2.66C2.15344 0.734375 1.66762 0.935607 1.30943 1.2938C0.951232 1.652 0.75 2.13781 0.75 2.64438Z"
|
||||
fill="#8E8E93"
|
||||
/>
|
||||
<path
|
||||
d="M5.04492 6.94531H6.95492"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
<path
|
||||
d="M5.04492 4.07812H5.99992V6.94313"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
<path
|
||||
d="M5.52539 2.65625H6.47539"
|
||||
stroke="white"
|
||||
strokeWidth="0.955"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ErrorIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M11 6C11 8.7614 8.7614 11 6 11C3.23857 11 1 8.7614 1 6C1 3.23857 3.23857 1 6 1C8.7614 1 11 3.23857 11 6ZM4.48482 4.48483C4.63126 4.33838 4.8687 4.33838 5.01515 4.48483L6 5.46965L6.9848 4.48484C7.13125 4.33839 7.3687 4.33839 7.51515 4.48484C7.6616 4.63128 7.6616 4.86872 7.51515 5.01515L6.5303 6L7.51515 6.9848C7.6616 7.13125 7.6616 7.3687 7.51515 7.51515C7.3687 7.6616 7.13125 7.6616 6.9848 7.51515L6 6.53035L5.01515 7.51515C4.86871 7.6616 4.63127 7.6616 4.48483 7.51515C4.33838 7.3687 4.33838 7.13125 4.48483 6.98485L5.46965 6L4.48482 5.01515C4.33837 4.86871 4.33837 4.63127 4.48482 4.48483Z"
|
||||
fill="#ED5342"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
PointElement,
|
||||
} from "chart.js";
|
||||
import { PowerIcon, ThroughputSummaryIcon } from "../../icons/analysis";
|
||||
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
||||
|
||||
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
|
||||
|
||||
|
@ -142,13 +143,13 @@ const ThroughputSummary = () => {
|
|||
|
||||
<div className="progress-wrapper">
|
||||
{/* Dynamically create progress bars based on shiftUtilization array */}
|
||||
{shiftUtilization.map((shift) => (
|
||||
{shiftUtilization.map((shift, index) => (
|
||||
<div
|
||||
key={shift.shift}
|
||||
className={`progress shift-${shift.shift}`}
|
||||
style={{
|
||||
width: `${shift.percentage}%`,
|
||||
backgroundColor: getRandomColor(),
|
||||
backgroundColor: getAvatarColor(index),
|
||||
}}
|
||||
></div>
|
||||
))}
|
||||
|
@ -156,11 +157,11 @@ const ThroughputSummary = () => {
|
|||
|
||||
<div className="progress-indicator">
|
||||
{/* Dynamically create shift indicators with random colors */}
|
||||
{shiftUtilization.map((shift) => (
|
||||
{shiftUtilization.map((shift, index) => (
|
||||
<div className="shift-wrapper" key={shift.shift}>
|
||||
<span
|
||||
className={`indicator shift-${shift.shift}`}
|
||||
style={{ backgroundColor: getRandomColor() }} // Random color for indicator
|
||||
style={{ backgroundColor: getAvatarColor(index) }} // Random color for indicator
|
||||
></span>
|
||||
<label>Shift {shift.shift}</label>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import React from "react";
|
||||
import { HelpIcon } from "../../icons/DashboardIcon";
|
||||
import { useLogger } from "../log/LoggerContext";
|
||||
|
||||
const Footer = () => {
|
||||
const { logs, setIsLogListVisible } = useLogger();
|
||||
|
||||
const lastLog = logs.length > 0 ? logs[logs.length - 1] : null;
|
||||
|
||||
return (
|
||||
<div className="footer-wrapper">
|
||||
<div className="selection-wrapper">
|
||||
<div className="selector-wrapper">
|
||||
<div className="icon"></div>
|
||||
<div className="selector">Selection</div>
|
||||
</div>
|
||||
<div className="selector-wrapper">
|
||||
<div className="icon"></div>
|
||||
<div className="selector">Rotate/Zoom</div>
|
||||
</div>
|
||||
<div className="selector-wrapper">
|
||||
<div className="icon"></div>
|
||||
<div className="selector">Pan/Context Menu</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="logs-wrapper">
|
||||
<div className="logs-detail" onClick={() => setIsLogListVisible(true)}>
|
||||
{lastLog
|
||||
? `[${lastLog.type.toUpperCase()}] ${lastLog.message}`
|
||||
: "No logs yet."}
|
||||
</div>
|
||||
<div className="version">
|
||||
V 0.01
|
||||
<div className="icon">
|
||||
<HelpIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
|
@ -0,0 +1,87 @@
|
|||
// LogList.tsx
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
LogListIcon,
|
||||
TickIcon,
|
||||
LogInfoIcon,
|
||||
WarningIcon,
|
||||
ErrorIcon,
|
||||
} from "../../icons/ExportCommonIcons"; // Adjust path as needed
|
||||
import { useLogger } from "./LoggerContext";
|
||||
|
||||
const LogList: React.FC = () => {
|
||||
const { logs, clear, setIsLogListVisible } = useLogger();
|
||||
const [selectedTab, setSelectedTab] = useState<
|
||||
"all" | "info" | "warning" | "error" | "log"
|
||||
>("all");
|
||||
|
||||
const getLogIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case "info":
|
||||
return <LogInfoIcon />;
|
||||
case "error":
|
||||
return <ErrorIcon />;
|
||||
case "warning":
|
||||
return <WarningIcon />;
|
||||
case "log":
|
||||
default:
|
||||
return <LogInfoIcon />;
|
||||
}
|
||||
};
|
||||
|
||||
const formatTimestamp = (date: Date) => new Date(date).toLocaleTimeString();
|
||||
|
||||
const filteredLogs =
|
||||
selectedTab === "all"
|
||||
? [...logs].reverse()
|
||||
: [...logs].filter((log) => log.type === selectedTab).reverse();
|
||||
|
||||
return (
|
||||
<div className="log-list-container">
|
||||
<div className="log-list-wrapper">
|
||||
<div className="log-header">
|
||||
<div className="log-header-wrapper">
|
||||
<div className="icon">
|
||||
<LogListIcon />
|
||||
</div>
|
||||
<div className="head">Log List</div>
|
||||
</div>
|
||||
<div className="close" onClick={() => setIsLogListVisible(false)}>
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="log-nav-wrapper">
|
||||
{["all", "info", "warning", "error"].map((type) => (
|
||||
<div
|
||||
key={type}
|
||||
className={`log-nav ${selectedTab === type ? "active" : ""}`}
|
||||
onClick={() => setSelectedTab(type as any)}
|
||||
>
|
||||
{`${type.charAt(0).toUpperCase() + type.slice(1)} Logs`}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Log Entries */}
|
||||
<div className="log-entry-wrapper">
|
||||
{filteredLogs.map((log) => (
|
||||
<div key={log.id} className={`log-entry ${log.type}`}>
|
||||
<div className="tick">
|
||||
<TickIcon />
|
||||
</div>
|
||||
<div className="log-icon">{getLogIcon(log.type)}</div>
|
||||
<div className="log-entry-message">
|
||||
[{formatTimestamp(log.timestamp)}] [{log.type.toUpperCase()}]{" "}
|
||||
{log.message}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogList;
|
|
@ -0,0 +1,77 @@
|
|||
import React, { createContext, useContext, useState, useCallback } from "react";
|
||||
|
||||
export type LogType = "log" | "info" | "warning" | "error";
|
||||
|
||||
export interface LogEntry {
|
||||
id: string;
|
||||
type: LogType;
|
||||
message: string;
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
interface LoggerContextValue {
|
||||
logs: LogEntry[];
|
||||
setLogs: React.Dispatch<React.SetStateAction<LogEntry[]>>;
|
||||
isLogListVisible: boolean;
|
||||
setIsLogListVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
log: (message: string) => void;
|
||||
info: (message: string) => void;
|
||||
warn: (message: string) => void;
|
||||
error: (message: string) => void;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
const LoggerContext = createContext<LoggerContextValue | undefined>(undefined);
|
||||
|
||||
export const LoggerProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [logs, setLogs] = useState<LogEntry[]>([]);
|
||||
const [isLogListVisible, setIsLogListVisible] = useState<boolean>(false);
|
||||
|
||||
const generateId = useCallback(
|
||||
() => Math.random().toString(36).substring(2, 9),
|
||||
[]
|
||||
);
|
||||
|
||||
const addLog = useCallback(
|
||||
(type: LogType, message: string) => {
|
||||
const newLog: LogEntry = {
|
||||
id: generateId(),
|
||||
type,
|
||||
message,
|
||||
timestamp: new Date(),
|
||||
};
|
||||
setLogs((prevLogs) => [...prevLogs, newLog]);
|
||||
},
|
||||
[generateId]
|
||||
);
|
||||
|
||||
const loggerMethods: LoggerContextValue = {
|
||||
logs,
|
||||
setLogs,
|
||||
isLogListVisible,
|
||||
setIsLogListVisible,
|
||||
log: (message: string) => addLog("log", message),
|
||||
info: (message: string) => addLog("info", message),
|
||||
warn: (message: string) => addLog("warning", message),
|
||||
error: (message: string) => addLog("error", message),
|
||||
clear: () => {
|
||||
setLogs([]);
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<LoggerContext.Provider value={loggerMethods}>
|
||||
{children}
|
||||
</LoggerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useLogger = () => {
|
||||
const context = useContext(LoggerContext);
|
||||
if (!context) {
|
||||
throw new Error("useLogger must be used within a LoggerProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
|
@ -0,0 +1,71 @@
|
|||
type LogType = 'log' | 'info' | 'warning' | 'error';
|
||||
|
||||
interface LogEntry {
|
||||
type: LogType;
|
||||
message: string;
|
||||
timestamp: Date;
|
||||
context?: string;
|
||||
}
|
||||
|
||||
class Logger {
|
||||
private static instance: Logger;
|
||||
private logs: LogEntry[] = [];
|
||||
private subscribers: Array<(log: LogEntry) => void> = [];
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): Logger {
|
||||
if (!Logger.instance) {
|
||||
Logger.instance = new Logger();
|
||||
}
|
||||
return Logger.instance;
|
||||
}
|
||||
|
||||
private notifySubscribers(log: LogEntry) {
|
||||
this.subscribers.forEach(callback => callback(log));
|
||||
}
|
||||
|
||||
private addLog(type: LogType, message: string, context?: string) {
|
||||
const log: LogEntry = { type, message, timestamp: new Date(), context };
|
||||
this.logs.push(log);
|
||||
this.notifySubscribers(log);
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const logMessage = context ? `[${context}] ${message}` : message;
|
||||
console[type === 'warning' ? 'warn' : type](logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public log(message: string, context?: string) {
|
||||
this.addLog('log', message, context);
|
||||
}
|
||||
|
||||
public info(message: string, context?: string) {
|
||||
this.addLog('info', message, context);
|
||||
}
|
||||
|
||||
public warning(message: string, context?: string) {
|
||||
this.addLog('warning', message, context);
|
||||
}
|
||||
|
||||
public error(message: string, context?: string) {
|
||||
this.addLog('error', message, context);
|
||||
}
|
||||
|
||||
public getLogs(): LogEntry[] {
|
||||
return [...this.logs];
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.logs = [];
|
||||
}
|
||||
|
||||
public subscribe(callback: (log: LogEntry) => void) {
|
||||
this.subscribers.push(callback);
|
||||
return () => {
|
||||
this.subscribers = this.subscribers.filter(sub => sub !== callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const logger = Logger.getInstance();
|
|
@ -16,6 +16,7 @@ import {
|
|||
SpeedIcon,
|
||||
StartIcon,
|
||||
} from "../../icons/ExportCommonIcons";
|
||||
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
||||
|
||||
const SimulationPlayer: React.FC = () => {
|
||||
const { speed, setSpeed } = useAnimationPlaySpeed();
|
||||
|
@ -110,15 +111,6 @@ const SimulationPlayer: React.FC = () => {
|
|||
return color;
|
||||
};
|
||||
|
||||
// Store colors for each process item
|
||||
const [processColors, setProcessColors] = useState<string[]>([]);
|
||||
|
||||
// Generate colors on mount or when process changes
|
||||
useEffect(() => {
|
||||
const generatedColors = process.map(() => getRandomColor());
|
||||
setProcessColors(generatedColors);
|
||||
}, []);
|
||||
|
||||
const intervals = [10, 20, 30, 40, 50, 60]; // in minutes
|
||||
const totalSegments = intervals.length;
|
||||
const progress = 20; // percent (example)
|
||||
|
@ -328,6 +320,8 @@ const SimulationPlayer: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="processDisplayer">
|
||||
<div className="start-displayer timmer">00:00</div>
|
||||
<div className="end-displayer timmer">24:00</div>
|
||||
<div
|
||||
className="process-player"
|
||||
style={{ left: playerPosition, position: "absolute" }}
|
||||
|
@ -343,7 +337,7 @@ const SimulationPlayer: React.FC = () => {
|
|||
className="process"
|
||||
style={{
|
||||
width: `${item.completed}%`,
|
||||
backgroundColor: processColors[index],
|
||||
backgroundColor: getAvatarColor(index),
|
||||
}}
|
||||
></div>
|
||||
))}
|
||||
|
|
|
@ -25,6 +25,10 @@ import FollowPerson from "../components/templates/FollowPerson";
|
|||
import ProductionCapacity from "../components/ui/analysis/ProductionCapacity";
|
||||
import ThroughputSummary from "../components/ui/analysis/ThroughputSummary";
|
||||
import ROISummary from "../components/ui/analysis/ROISummary";
|
||||
import Footer from "../components/ui/footer/Footer";
|
||||
import RenderOverlay from "../components/templates/Overlay";
|
||||
import LogList from "../components/ui/log/LogList";
|
||||
import { useLogger } from "../components/ui/log/LoggerContext";
|
||||
|
||||
const Project: React.FC = () => {
|
||||
let navigate = useNavigate();
|
||||
|
@ -58,6 +62,7 @@ const Project: React.FC = () => {
|
|||
const { isPlaying } = usePlayButtonStore();
|
||||
const { toggleThreeD } = useThreeDStore();
|
||||
const { selectedUser } = useSelectedUserStore();
|
||||
const { isLogListVisible } = useLogger();
|
||||
|
||||
return (
|
||||
<div className="project-main">
|
||||
|
@ -69,7 +74,7 @@ const Project: React.FC = () => {
|
|||
<ROISummary />
|
||||
</div> */}
|
||||
<KeyPressListener />
|
||||
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
||||
{/* {loadingProgress > 0 && <LoadingPage progress={loadingProgress} />} */}
|
||||
{!isPlaying && (
|
||||
<>
|
||||
{toggleThreeD && <ModuleToggle />}
|
||||
|
@ -85,7 +90,13 @@ const Project: React.FC = () => {
|
|||
{activeModule !== "market" && <Tools />}
|
||||
{isPlaying && activeModule === "simulation" && <SimulationPlayer />}
|
||||
{/* {<SimulationPlayer />} */}
|
||||
{isLogListVisible && (
|
||||
<RenderOverlay>
|
||||
<LogList />
|
||||
</RenderOverlay>
|
||||
)}
|
||||
{selectedUser && <FollowPerson />}
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
.footer-wrapper {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.selection-wrapper {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
||||
.selector-wrapper {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
background: var(--background-color);
|
||||
padding: 4px 6px;
|
||||
border-radius: 12px;
|
||||
color: var(--text-color);
|
||||
|
||||
.selector {
|
||||
color: var(--text-button-color);
|
||||
font-weight: 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logs-wrapper {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
||||
.logs-detail,
|
||||
.version {
|
||||
border-radius: 12px;
|
||||
background: var(--background-color);
|
||||
padding: 4px 6px;
|
||||
color: var(--text-button-color);
|
||||
font-weight: 200;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logs-detail {
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.version {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
.log-list-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: var(--background-color-secondary);
|
||||
backdrop-filter: blur(2px);
|
||||
|
||||
.log-list-wrapper {
|
||||
height: 50%;
|
||||
min-width: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 5;
|
||||
background: var(--background-color);
|
||||
padding: 14px 12px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.log-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.log-header-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.close {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.log-nav-wrapper {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
||||
.log-nav {
|
||||
padding: 8px 16px;
|
||||
border-radius: 19px;
|
||||
}
|
||||
|
||||
.log-nav.active {
|
||||
background-color: var(--accent-color);
|
||||
color: var(--text-button-color);
|
||||
}
|
||||
}
|
||||
|
||||
.log-entry-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
background: var(--background-color);
|
||||
padding: 18px 10px;
|
||||
border-radius: 16px;
|
||||
|
||||
.log-entry {
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
font-size: var(--font-size-small);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background: var(--background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -312,6 +312,22 @@
|
|||
padding: 14px 6px;
|
||||
position: relative;
|
||||
|
||||
.timmer {
|
||||
width: auto;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: var(--font-size-tiny);
|
||||
}
|
||||
|
||||
.start-displayer {
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.end-displayer {
|
||||
width: auto;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.process-player {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
@ -344,6 +360,11 @@
|
|||
|
||||
.simulation-player-container.open {
|
||||
|
||||
.start-displayer,
|
||||
.end-displayer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progresser-wrapper {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@
|
|||
outline: none;
|
||||
path {
|
||||
stroke: var(--text-button-color);
|
||||
stroke-width: 1.3;
|
||||
strokeWidth: 1.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +686,7 @@
|
|||
|
||||
path {
|
||||
stroke: var(--accent-color);
|
||||
stroke-width: 1.5px;
|
||||
strokeWidth: 1.5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
@use 'components/confirmationPopUp';
|
||||
@use 'components/analysis/analysis';
|
||||
@use 'components/analysis/ROISummary.scss';
|
||||
@use 'components/logs/logs';
|
||||
@use 'components/footer/footer.scss';
|
||||
|
||||
// layout
|
||||
@use 'layout/loading';
|
||||
|
|
|
@ -416,7 +416,7 @@
|
|||
|
||||
path {
|
||||
stroke: var(--text-color);
|
||||
stroke-width: 2;
|
||||
strokeWidth: 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@
|
|||
|
||||
path {
|
||||
stroke: #f65648;
|
||||
stroke-width: 1.3;
|
||||
strokeWidth: 1.3;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue