Merge branch 'v2-ui' of http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev into v2-ui
This commit is contained in:
commit
0f41f3f845
|
@ -3,23 +3,20 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import Project from "./pages/Project";
|
import Project from "./pages/Project";
|
||||||
import UserAuth from "./pages/UserAuth";
|
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 = () => {
|
const App: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<ToastProvider>
|
<LoggerProvider>
|
||||||
<Router>
|
<Router>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route path="/" element={<UserAuth />} />
|
||||||
path="/"
|
|
||||||
element={<UserAuth />}
|
|
||||||
/>
|
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
<Route path="/project" element={<Project />} />
|
<Route path="/project" element={<Project />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
</ToastProvider>
|
</LoggerProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -814,3 +814,136 @@ export const SpeedIcon = () => {
|
||||||
</svg>
|
</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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React from "react";
|
||||||
|
import { HelpIcon } from "../../icons/DashboardIcon";
|
||||||
|
import { useLogger } from "../log/LoggerContext";
|
||||||
|
import {
|
||||||
|
LogInfoIcon,
|
||||||
|
ErrorIcon,
|
||||||
|
WarningIcon,
|
||||||
|
} from "../../icons/ExportCommonIcons"; // Adjust path as needed
|
||||||
|
|
||||||
|
const getLogIcon = (type: string) => {
|
||||||
|
switch (type) {
|
||||||
|
case "info":
|
||||||
|
return <LogInfoIcon />;
|
||||||
|
case "error":
|
||||||
|
return <ErrorIcon />;
|
||||||
|
case "warning":
|
||||||
|
return <WarningIcon />;
|
||||||
|
case "log":
|
||||||
|
default:
|
||||||
|
return <LogInfoIcon />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 ? (
|
||||||
|
<>
|
||||||
|
<span className="log-icon">{getLogIcon(lastLog.type)}</span>
|
||||||
|
<span className="log-message">{lastLog.message}</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
"No logs yet."
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="version">
|
||||||
|
V 0.01
|
||||||
|
<div className="icon">
|
||||||
|
<HelpIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Footer;
|
|
@ -0,0 +1,88 @@
|
||||||
|
// LogList.tsx
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
LogListIcon,
|
||||||
|
TickIcon,
|
||||||
|
LogInfoIcon,
|
||||||
|
WarningIcon,
|
||||||
|
ErrorIcon,
|
||||||
|
CloseIcon,
|
||||||
|
} 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)}>
|
||||||
|
{/* <CloseIcon /> */}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();
|
|
@ -27,9 +27,15 @@ import Scene from "../modules/scene/scene";
|
||||||
import { createHandleDrop } from "../modules/visualization/functions/handleUiDrop";
|
import { createHandleDrop } from "../modules/visualization/functions/handleUiDrop";
|
||||||
import { useSelectedZoneStore } from "../store/visualization/useZoneStore";
|
import { useSelectedZoneStore } from "../store/visualization/useZoneStore";
|
||||||
import { useFloatingWidget } from "../store/visualization/useDroppedObjectsStore";
|
import { useFloatingWidget } from "../store/visualization/useDroppedObjectsStore";
|
||||||
|
import { useLogger } from "../components/ui/log/LoggerContext";
|
||||||
|
import Footer from "../components/ui/footer/Footer";
|
||||||
|
import RenderOverlay from "../components/templates/Overlay";
|
||||||
|
import LogList from "../components/ui/log/LogList";
|
||||||
|
|
||||||
const Project: React.FC = () => {
|
const Project: React.FC = () => {
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
|
const echo = useLogger();
|
||||||
|
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
const { loadingProgress } = useLoadingProgress();
|
const { loadingProgress } = useLoadingProgress();
|
||||||
const { setUserName } = useUserName();
|
const { setUserName } = useUserName();
|
||||||
|
@ -52,6 +58,7 @@ const Project: React.FC = () => {
|
||||||
setOrganization(Organization);
|
setOrganization(Organization);
|
||||||
setUserName(name);
|
setUserName(name);
|
||||||
}
|
}
|
||||||
|
echo.info("Log in success full");
|
||||||
} else {
|
} else {
|
||||||
navigate("/");
|
navigate("/");
|
||||||
}
|
}
|
||||||
|
@ -66,6 +73,7 @@ const Project: React.FC = () => {
|
||||||
|
|
||||||
// collaboration store
|
// collaboration store
|
||||||
const { selectedUser } = useSelectedUserStore();
|
const { selectedUser } = useSelectedUserStore();
|
||||||
|
const { isLogListVisible } = useLogger();
|
||||||
|
|
||||||
// real-time visualization store
|
// real-time visualization store
|
||||||
const { widgetSubOption } = useWidgetSubOption();
|
const { widgetSubOption } = useWidgetSubOption();
|
||||||
|
@ -117,6 +125,12 @@ const Project: React.FC = () => {
|
||||||
<Scene />
|
<Scene />
|
||||||
</div>
|
</div>
|
||||||
{selectedUser && <FollowPerson />}
|
{selectedUser && <FollowPerson />}
|
||||||
|
{isLogListVisible && (
|
||||||
|
<RenderOverlay>
|
||||||
|
<LogList />
|
||||||
|
</RenderOverlay>
|
||||||
|
)}
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
.footer-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 24px;
|
||||||
|
|
||||||
|
.selection-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.selector-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--background-color);
|
||||||
|
padding: 3px 6px;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: var(--text-color);
|
||||||
|
|
||||||
|
.selector {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.logs-detail,
|
||||||
|
.version {
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--background-color);
|
||||||
|
padding: 3px 6px;
|
||||||
|
color: var(--text-color);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs-detail {
|
||||||
|
// background-color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
.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;
|
||||||
|
backdrop-filter: blur(50px);
|
||||||
|
|
||||||
|
.log-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.log-header-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
// transform: scale(1.5);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -314,6 +314,22 @@
|
||||||
font-size: var(--font-size-tiny);
|
font-size: var(--font-size-tiny);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timmer {
|
||||||
|
width: auto;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
font-size: var(--font-size-tiny);
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-displayer {
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-displayer {
|
||||||
|
width: auto;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.start-displayer {
|
.start-displayer {
|
||||||
bottom: 4px;
|
bottom: 4px;
|
||||||
left: 16px;
|
left: 16px;
|
||||||
|
@ -354,6 +370,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.simulation-player-container.open {
|
.simulation-player-container.open {
|
||||||
|
|
||||||
|
.start-displayer,
|
||||||
|
.end-displayer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.timmer {
|
.timmer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,7 +416,7 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
path {
|
path {
|
||||||
stroke: var(--text-button-color);
|
stroke: var(--text-button-color);
|
||||||
stroke-width: 1.3;
|
strokeWidth: 1.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,7 +682,7 @@
|
||||||
|
|
||||||
path {
|
path {
|
||||||
stroke: var(--accent-color);
|
stroke: var(--accent-color);
|
||||||
stroke-width: 1.5px;
|
strokeWidth: 1.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
@use 'components/confirmationPopUp';
|
@use 'components/confirmationPopUp';
|
||||||
@use 'components/analysis/analysis';
|
@use 'components/analysis/analysis';
|
||||||
@use 'components/analysis/ROISummary.scss';
|
@use 'components/analysis/ROISummary.scss';
|
||||||
|
@use 'components/logs/logs';
|
||||||
|
@use 'components/footer/footer.scss';
|
||||||
|
|
||||||
// layout
|
// layout
|
||||||
@use 'layout/loading';
|
@use 'layout/loading';
|
||||||
|
|
|
@ -423,7 +423,7 @@
|
||||||
|
|
||||||
path {
|
path {
|
||||||
stroke: #f65648;
|
stroke: #f65648;
|
||||||
stroke-width: 1.3;
|
strokeWidth: 1.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue