diff --git a/client/src/App.jsx b/client/src/App.jsx index cc8a57a..9935035 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,4 +1,6 @@ import Dashboard from './components/layout/Dashboard.jsx' +import 'leaflet/dist/leaflet.css'; + function App() { return ( diff --git a/client/src/components/layout/Canvas/Canvas.jsx b/client/src/components/layout/Canvas/Canvas.jsx index 7c02fd1..5e20a67 100644 --- a/client/src/components/layout/Canvas/Canvas.jsx +++ b/client/src/components/layout/Canvas/Canvas.jsx @@ -12,7 +12,7 @@ import SettingsCanvas from "./views/SettingsCanvas" import { DashboardCanvas } from "./views/DashboardCanvas"; import { DASHBOARD_VIEWS } from "@/constants/viewKeys"; -export default function Canvas({ view, setView, layout, setLayout, onLayoutChange, darkMode }) { +export default function Canvas({ onCancel, isEditable, setIsEditable, isDelete, setIsDelete, view, setView, layout, setLayout, originalLayout, setOriginalLayout, onLayoutChange, onChangeView, darkMode }) { const recipe = useRecipe({ key: "canvas" }); const styles = recipe(); @@ -21,11 +21,20 @@ export default function Canvas({ view, setView, layout, setLayout, onLayoutChang {/* Check if view is a tab inside the Canvas Header */} { DASHBOARD_VIEWS.includes(view) && ( )} {view === "global" && } diff --git a/client/src/components/layout/Canvas/views/DashboardCanvas.jsx b/client/src/components/layout/Canvas/views/DashboardCanvas.jsx index 38e7ea0..008d0d5 100644 --- a/client/src/components/layout/Canvas/views/DashboardCanvas.jsx +++ b/client/src/components/layout/Canvas/views/DashboardCanvas.jsx @@ -29,42 +29,37 @@ export function DashboardCanvas({ view, setView, layout, setLayout, onLayoutChan static: false } ]); + onEditWidgets(); }; - useEffect(() => { - console.log("static change effect"); - setLayout(prevLayout => - prevLayout.map(item => ({ - ...item, - static: !isEditable // static false means resizable/editable - })) - ); - }, [isEditable]); - const onEditWidgets = () => { console.log("widgets are now editable"); setOriginalLayout(layout); // Backup layout before editing + + // Set all widgets to editable, static: false + setLayout(prevLayout => + prevLayout.map(item => ({ + ...item, + static: false + })) + ); setIsEditable(true); // Enable edit mode } const onSave = () => { console.log("saving widgets..."); - setIsEditable(false); - setIsDelete(false); - setOriginalLayout([]) // Clear backup layout - } - const onCancel = () => { - console.log("canceling changes..."); - if (originalLayout.length) { - setLayout(originalLayout.map(item => ({ - ...item, + // Set all widgets back to static: true + setLayout(prevLayout => + prevLayout.map(item => ({ + ...item, static: true - }))); - }; + })) + ); + setIsEditable(false); setIsDelete(false); - setOriginalLayout([]); + setOriginalLayout([]); // Clear backup layout } const onDeleteWidgets = () => { @@ -101,15 +96,7 @@ export function DashboardCanvas({ view, setView, layout, setLayout, onLayoutChan // Prevent navigation away from 'My Dashboard' while in Edit mode onValueChange={(e) => { const nextView = e.value; - - if (view === "widget" && isEditable && nextView !== "widget") { - const confirmed = window.confirm( - "You have unsaved changes. Do you wish to discard them and continue?" - ); - if (!confirmed) return; - onCancel(); - } - setView(nextView); + onChangeView(nextView); }} > + - - - Regional Map Canvas coming soon! - - - - ); +export default function GlobalMapCanvas() { + const position = [45.61142478054226, -122.49630033167544]; // [latitude, longitude] + return ( + + + + + CVO — Home of the volcanoligists + + + + ); } \ No newline at end of file diff --git a/client/src/components/layout/Dashboard.jsx b/client/src/components/layout/Dashboard.jsx index 00a38b6..2fdd67d 100644 --- a/client/src/components/layout/Dashboard.jsx +++ b/client/src/components/layout/Dashboard.jsx @@ -10,15 +10,43 @@ export default function Dashboard() { const styles = recipe(); const [darkMode, setDarkMode] = useState(false); - // Lifted State - defaults to widget dashboard + const [isEditable, setIsEditable] = useState(false); // editable=true means static=false (vice versa) + const [isDelete, setIsDelete] = useState(false); + const [originalLayout, setOriginalLayout] = useState([]); const [view, setView] = useState("widget"); const [layout, setLayout] = useState([]); + const onCancel = () => { + console.log("canceling changes..."); + if (originalLayout.length) { + setLayout(originalLayout.map(item => ({ + ...item, + static: true + }))); + }; + setIsEditable(false); + setIsDelete(false); + setOriginalLayout([]); + } + + // Prevent navigation while in Edit mode without saving or cancelling + const handleViewChange = (nextView) => { + if (view === "widget" && isEditable) { + const confirmed = window.confirm( + "You have unsaved changes. Discard them and continue?" + ); + if (!confirmed) return; + onCancel(); // Discards the layout + } + setView(nextView); + }; + return ( <> @@ -26,6 +54,7 @@ export default function Dashboard() {
@@ -33,7 +62,8 @@ export default function Dashboard() { darkMode={ darkMode } setDarkMode={ setDarkMode } view={ view } - onChangeView={ setView } + onChangeView={ handleViewChange } + isEditabe={ isEditable } /> @@ -43,7 +73,15 @@ export default function Dashboard() { setView={ setView } layout={ layout } setLayout={ setLayout } + originalLayout={ originalLayout } + setOriginalLayout={ setOriginalLayout } onLayoutChange={( newLayout ) => setLayout( newLayout )} + onChangeView={ handleViewChange } + onCancel={ onCancel } + isEditable={ isEditable } + setIsEditable={ setIsEditable } + isDelete={ isDelete } + setIsDelete={ setIsDelete } /> diff --git a/client/src/components/layout/Header/Header.jsx b/client/src/components/layout/Header/Header.jsx index 79c5f41..1c127a7 100644 --- a/client/src/components/layout/Header/Header.jsx +++ b/client/src/components/layout/Header/Header.jsx @@ -8,7 +8,7 @@ const user = { // avatar: "src\\assets\\user_profile.svg" } -export default function Header({ view, setView }) { +export default function Header({ onChangeView }) { const recipe = useRecipe({ key: "header" }); const styles = recipe(); @@ -23,8 +23,7 @@ export default function Header({ view, setView }) { diff --git a/client/src/components/layout/Header/UserAvatarMenu.jsx b/client/src/components/layout/Header/UserAvatarMenu.jsx index 250542c..b7d29bc 100644 --- a/client/src/components/layout/Header/UserAvatarMenu.jsx +++ b/client/src/components/layout/Header/UserAvatarMenu.jsx @@ -1,7 +1,7 @@ import { Avatar, Menu, Portal, Box } from "@chakra-ui/react" -export default function UserAvatarMenu({ view, setView, name, avatar }) { +export default function UserAvatarMenu({ onChangeView, name, avatar }) { return ( @@ -21,10 +21,10 @@ export default function UserAvatarMenu({ view, setView, name, avatar }) { {/* zIndex: overlay = 1300 */} - setView("account")}> + onChangeView("account")}> Account - setView("settings")}> + onChangeView("settings")}> Settings console.log("Log out triggered")}> diff --git a/client/src/components/layout/Sidebar/Sidebar.jsx b/client/src/components/layout/Sidebar/Sidebar.jsx index 4d7ee4b..9af13a2 100644 --- a/client/src/components/layout/Sidebar/Sidebar.jsx +++ b/client/src/components/layout/Sidebar/Sidebar.jsx @@ -1,6 +1,5 @@ import { useSlotRecipe, Box, Button, IconButton } from "@chakra-ui/react"; import { ColorModeButton, useColorMode } from "@/components/ui/color-mode"; -// import { Tooltip } from "@/components/ui/tooltip"; import Tooltip from "../Canvas/components/Tooltip.jsx"; import { FaVolcano } from "react-icons/fa6"; import { FaHome } from "react-icons/fa"; @@ -9,7 +8,6 @@ import { FaMapMarkerAlt } from "react-icons/fa"; import { HiUsers } from "react-icons/hi2"; import { VscThreeBars } from "react-icons/vsc"; import { useState, useEffect } from "react"; -import { Seismic } from "../Canvas/views/DashboardCanvasNav/Seismic"; import { DASHBOARD_VIEWS } from "@/constants/viewKeys"; export default function Sidebar({ view, onChangeView, darkMode, setDarkMode }) { @@ -35,14 +33,13 @@ export default function Sidebar({ view, onChangeView, darkMode, setDarkMode }) { // Track currrent view from both Sidebar and Canvas when 'view' changes useEffect(() => { - // console.log("typeof view =", typeof view); console.log("Current view = ", view); const newIndex = buttons.findIndex((btn) => { if (btn.view === "widget") { - return DASHBOARD_VIEWS.includes(view); // Group match + return DASHBOARD_VIEWS.includes(view); } - return btn.view === view; // Exact match + return btn.view === view; }); if (newIndex !== -1 ) { @@ -52,7 +49,6 @@ export default function Sidebar({ view, onChangeView, darkMode, setDarkMode }) { return ( { - // setActiveButton(idx); onChangeView(button.view); // Trigger state change in Dashboard }} bg={activeButton === idx ? "primary":undefined}