diff --git a/README.md b/README.md
deleted file mode 100644
index 650bfeb..0000000
--- a/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# website-framework
-
-
-## Add your files
-
-- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
-- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
-
-```
-cd existing_repo
-git remote add origin https://code.usgs.gov/vkuchenik/website-framework.git
-git branch -M main
-git push -uf origin main
-```
-
-## Name
-Basic Webapp Framework
-
-## Description
-Building a foundational webapp framework that can be repurposed.
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index e8ead07..b015727 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -4286,6 +4286,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
+ "license": "MIT",
"peerDependencies": {
"react": "*"
}
diff --git a/client/src/App.jsx b/client/src/App.jsx
index 601f6ea..4f55612 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -3,11 +3,13 @@ import Header from './components/header.jsx';
import Sidebar from './components/sidebar.jsx';
import Widget from './components/Widget.jsx'
import { Grid, GridItem, useRecipe } from "@chakra-ui/react"
+import CanvasHeader from './components/CanvasHeader.jsx'
function App() {
const recipe = useRecipe({ key: "canvas" });
const styles = recipe();
+
return (
-
+ >
+
+
+
+
+
+
@@ -36,3 +43,5 @@ function App() {
}
export default App
+
+
diff --git a/client/src/components/CanvasHeader.jsx b/client/src/components/CanvasHeader.jsx
new file mode 100644
index 0000000..fd0a10b
--- /dev/null
+++ b/client/src/components/CanvasHeader.jsx
@@ -0,0 +1,30 @@
+import { Flex, HStack } from "@chakra-ui/react";
+import { CanvasHeaderNav } from "./CanvasHeaderNav";
+import { SearchBar } from "./SearchBar";
+import { SettingsButton } from "./SettingsButton";
+
+export default function CanvasHeader() {
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/client/src/components/CanvasHeaderNav.jsx b/client/src/components/CanvasHeaderNav.jsx
new file mode 100644
index 0000000..b80d7c5
--- /dev/null
+++ b/client/src/components/CanvasHeaderNav.jsx
@@ -0,0 +1,22 @@
+import { HStack, Link } from "@chakra-ui/react"
+
+const navItems = [
+ { label: "My Dashboard", href: "#dashboard" },
+ { label: "Gas", href: "#gas" },
+ { label: "Seismic", href: "#seismic" },
+ { label: "Remote Sensing", href: "#remote" },
+ { label: "Daily Activity", href: "#daily" },
+];
+
+export function CanvasHeaderNav() {
+ return (
+
+ {navItems.map(({ label, href }) => (
+
+ {label}
+
+ ))}
+
+ );
+}
+
diff --git a/client/src/components/SearchBar.jsx b/client/src/components/SearchBar.jsx
new file mode 100644
index 0000000..93bd743
--- /dev/null
+++ b/client/src/components/SearchBar.jsx
@@ -0,0 +1,10 @@
+import { Input, InputGroup } from "@chakra-ui/react";
+import { FiSearch } from "react-icons/fi"
+
+export function SearchBar({ placeholder="Search...", size="sm", width="200px"}) {
+ return (
+ }>
+
+
+ );
+}
\ No newline at end of file
diff --git a/client/src/components/SettingsButton.jsx b/client/src/components/SettingsButton.jsx
new file mode 100644
index 0000000..afb7936
--- /dev/null
+++ b/client/src/components/SettingsButton.jsx
@@ -0,0 +1,54 @@
+// This component displays a drop down menu when clicked, with custom functionality
+// for 'Add Widget', 'Edit Widgets', and 'Remove Widgets'. This component will
+// control settings related to the Widgets on the main canvas.
+
+import { Button, IconButton, Menu, Portal } from "@chakra-ui/react";
+import { FiSettings } from "react-icons/fi";
+
+export function SettingsButton(props) {
+ const handleAddWidget = () => {
+ console.log("Add Widget clicked");
+ // TODO: Implement widget-adding logic
+ }
+
+ const handleEditWidgdets = () => {
+ console.log("Edit Widgets clicked")
+ // TODO: Implement widget-editing logic
+ }
+
+ const handleDeleteWidgets = () => {
+ console.log("Delete Widgets clicked");
+ // TODO: Implement widget-deletion logic
+ }
+
+ return (
+ // This uses Chakra's built in menu component
+
+
+
+
+
+
+
+
+
+ Add Widget
+ Edit Widgets
+
+ Delete Widgets
+
+
+
+
+
+ );
+}
+
+
+
+
+
diff --git a/client/src/components/Widget.jsx b/client/src/components/Widget.jsx
index a23327d..b3413ad 100644
--- a/client/src/components/Widget.jsx
+++ b/client/src/components/Widget.jsx
@@ -1,8 +1,13 @@
+// This component defines a generic Widget that can be dynamically resized and
+// dragged inside the canvas
+// Content not included, must be populated using custom charts plots and notifications
+
import { useState } from 'react';
import GridLayout from 'react-grid-layout';
export default function Widget() {
- // Define widgets initial position and size
+ // Define widgets initial position and size
+ // TODO Add dynamic adding/deleting of widgets via options button
const [layout, setLayout] = useState([
{ i: 'myWidget1', x: 0, y: 0, w: 3, h: 3, minH: 3, static: false },
{ i: 'myWidget2', x: 3, y: 0, w: 3, h: 3, minH: 3, static: false },
diff --git a/client/src/components/header.jsx b/client/src/components/header.jsx
index e6316b9..7e9261e 100644
--- a/client/src/components/header.jsx
+++ b/client/src/components/header.jsx
@@ -1,22 +1,35 @@
-
-import { chakra, useRecipe, Box, Button, Avatar, HStack, Stack, Text } from "@chakra-ui/react"
+import { chakra, useRecipe, Box, Button, Avatar, Stack, Text, Menu, Portal } from "@chakra-ui/react"
export default function Header() {
const recipe = useRecipe({ key: "header" });
const styles = recipe();
+
return (
-
+
+
+
+
+ Account
+ Settings
+ Logout
+
+
+
+
+ {/* End drop down menu */}
);
}
diff --git a/client/src/components/sidebar.jsx b/client/src/components/sidebar.jsx
index 61b3ca7..05c7f35 100644
--- a/client/src/components/sidebar.jsx
+++ b/client/src/components/sidebar.jsx
@@ -1,5 +1,5 @@
-import { chakra, useRecipe, useSlotRecipe, Box, Button, createIcon, CloseButton, IconButton, Stack } from "@chakra-ui/react";
-import { useColorModeValue, ColorModeButton } from "@/components/ui/color-mode";
+import { chakra, useRecipe, useSlotRecipe, Box, Button, createIcon, CloseButton, IconButton, Stack, useDisclosure, Tooltip } from "@chakra-ui/react";
+import { ColorModeButton } from "@/components/ui/color-mode";
import { FaVolcano } from "react-icons/fa6";
import { RxHamburgerMenu } from "react-icons/rx";
import { useState } from "react";
@@ -57,57 +57,278 @@ export const Users = createIcon({
),
});
-export default function Sidebar () {
- const variant = useColorModeValue("ghost", "solid")
+export default function Sidebar() {
const [isOpen, setIsOpen] = useState(true);
+ const [hasFinishedClosing, setHasFinishedClosing] = useState(true);
+
const [activeButton, setActiveButton] = useState(0)
const recipe = useSlotRecipe({ key: "sidebar" });
const styles = recipe();
+ const toggleSidebar = () => {
+ if (isOpen) {
+ setHasFinishedClosing(false);
+ setTimeout(() => setIsOpen(false), 10); // Kick off transition
+ setTimeout(() => setHasFinishedClosing(true), 400); // Match sidebar transition duration
+ } else {
+ setIsOpen(true);
+ setHasFinishedClosing(true);
+ }
+ };
+
return (
-
- {isOpen ? (
- <>
- setIsOpen(!isOpen)}>
-
-
-
-
-
- >
- ) : (
- <>
- setIsOpen(!isOpen)}>
-
-
- setActiveButton("Dashboard")} bg={activeButton === "Dashboard" ? "#A4B6B6" : "transparent"}>
-
-
- setActiveButton("Global")} bg={activeButton === "Global" ? "#A4B6B6" : "transparent"}>
+
+
+
+
+
+ {/* Dashboard */}
+
+
+ {/* Global Map */}
+
- setActiveButton("Regional")} bg={activeButton === "Regional" ? "#A4B6B6" : "transparent"}>
-
-
- setActiveButton("Volcano")} bg={activeButton === "Volcano" ? "#A4B6B6" : "transparent"}>
+
+ {/* Make text appear gradually instead of popping in */}
+
+ Global Map
+
+ >
+ ) : (
+
+ )}
+
+
+ {/* Regional Map */}
+
+
+ {/* Volcano */}
+
- setActiveButton("Admin")} bg={activeButton === "Admin" ? "#A4B6B6" : "transparent"}>
+ {/* Make text appear gradually instead of popping in */}
+
+ Volcano
+
+ >
+ ) : (
+
+ )}
+
+
+ {/* Admin */}
+
- >
- )}
+
+ {/* Make text appear gradually instead of popping in */}
+
+ Admin
+
+ >
+ ) : (
+
+ )}
+
-
+
);
}
+
+// THIS CODE WORKS, SAVE IN CASE OF EMERGENCY
+// Needed to refactor in order allow transitions to work properly
+
+// export default function Sidebar () {
+// const [isOpen, setIsOpen] = useState(true);
+// const [activeButton, setActiveButton] = useState("Dashboard")
+
+// return (
+// <>
+// {isOpen && (
+//
+// {/* setIsOpen(!isOpen)}> */}
+// {/* setIsOpen(!isOpen)}> */}
+//
+//
+//
+//
+//
+//
+//
+// )}
+
+// {!isOpen && (
+//
+// setIsOpen(!isOpen)}>
+//
+//
+// setActiveButton("Dashboard")} bg={activeButton === "Dashboard" ? "#A4B6B6" : "transparent"}>
+//
+//
+// setActiveButton("Global")} bg={activeButton === "Global" ? "#A4B6B6" : "transparent"}>
+//
+//
+// setActiveButton("Regional")} bg={activeButton === "Regional" ? "#A4B6B6" : "transparent"}>
+//
+//
+// setActiveButton("Volcano")} bg={activeButton === "Volcano" ? "#A4B6B6" : "transparent"}>
+//
+//
+// setActiveButton("Admin")} bg={activeButton === "Admin" ? "#A4B6B6" : "transparent"}>
+//
+//
+//
+// )}
+
+// >
+// );
+// }