Rename and Restructure

+ took out extra 'layout' directory.
+ 'Canvas' postfix removed from all files in the views directory.
+ "WidgetCanvas" renamed to "MyDashboard"
This commit is contained in:
2025-08-05 12:57:18 -07:00
parent 03a335710f
commit ff95f2cbc0
27 changed files with 20 additions and 20 deletions
@@ -0,0 +1,75 @@
import { Box, Flex, Field, Input, Stack, Heading, Button } from "@chakra-ui/react"
import { useForm } from 'react-hook-form';
export default function AccountCanvas() {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm();
const onSubmit = (data) => {
console.log("Form submitted:", data);
}
console.log(watch("example")); // watch input value by passing the name of it
return (
<Flex
height="100vh"
direction="column"
align="start"
justify="start"
bg="gray.50"
pt={6}
pl={6}
>
<Heading as="h1" mb={2}>Account</Heading>
<Box
as="form"
onSubmit={handleSubmit(onSubmit)}
border="1px solid"
borderColor="gray.300"
borderRadius="md"
padding={4}
bg="white"
boxShadow="md"
width="100%"
maxW="sm"
>
{/* <Text fontSize="xl" fontWeight="bold" mb={6}>
Account
</Text> */}
<Stack gap="6" maxW="sm" css={{ "--field-label-width": "96px" }}>
<Field.Root orientation="horizontal">
<Field.Label>User Name</Field.Label>
<Input {...register("username")} placeholder="David Johnston" flex="1" />
</Field.Root>
<Field.Root orientation="horizontal">
<Field.Label> First Name</Field.Label>
<Input {...register("firstname")} placeholder="David" flex="1" />
</Field.Root>
<Field.Root orientation="horizontal">
<Field.Label>Last Name</Field.Label>
<Input {...register("lastname")} placeholder="Johnston" flex="1" />
</Field.Root>
<Field.Root orientation="horizontal">
<Field.Label>Email</Field.Label>
<Input {...register("email")} placeholder="djohntson@usgs.gov" flex="1" />
</Field.Root>
<Button type="submit">
Save
</Button>
</Stack>
</Box>
</Flex>
)
}
@@ -0,0 +1,24 @@
import { Box, Text } from '@chakra-ui/react';
export default function AdminCanvas() {
return (
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">
Admin Canvas coming soon!
</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,19 @@
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
export default function GlobalMapCanvas() {
const position = [45.61142478054226, -122.49630033167544]; // [latitude, longitude]
return (
<MapContainer center={position} zoom={3} style={{ height: "100%", width: "100%" }}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; OpenStreetMap contributors'
/>
<Marker position={position}>
<Popup>
CVO Home of the volcanoligists
</Popup>
</Marker>
</MapContainer>
);
}
+170
View File
@@ -0,0 +1,170 @@
import { HStack, Flex, Tabs } from "@chakra-ui/react";
import { useState } from "react";
import WidgetCanvas from "./HomeTabs/MyDashboard";
import { SearchBar } from "../CanvasComponents/SearchBar";
import { SettingsButton } from "../CanvasComponents/SettingsButton";
import { DailyActivity } from "./HomeTabs/DailyActivity";
import { Gas } from "./HomeTabs/Gas";
import { Seismic } from "./HomeTabs/Seismic";
import { RemoteSensing } from "./HomeTabs/RemoteSensing";
import { CancelButton } from "../CanvasComponents/CancelButton";
import { SaveButton } from "../CanvasComponents/SaveButton";
import DeleteAllButton from "../CanvasComponents/DeleteAllButton";
export function HomeCanvas({...props}) {
// deconstructing props
const { width, height, view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView, onCancel,
isDelete, setIsDelete, isEditable, setIsEditable, widgetArray, setWidgetArray } = props;
const onAddWidget = (ID) => {
setLayout(prev => [
...prev,
{
i: ID,
x: (prev.length * 3) % 12,
y: Infinity,
w: 3,
h: 3,
static: false
}
]);
onEditWidgets();
};
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...");
// Set all widgets back to static: true
setLayout(prevLayout =>
prevLayout.map(item => ({
...item,
static: true
}))
);
setIsEditable(false);
setIsDelete(false);
setOriginalLayout([]); // Clear backup layout
}
const onDeleteWidgets = () => {
console.log("Start deleting widgets...");
setOriginalLayout(layout);
setIsEditable(true);
setIsDelete(true);
}
const DeleteWidget = (ID) => {
console.log("Deleting widget with id: ", ID);
setLayout(layout => layout.filter(w => w.i !== ID));
// add removal for widgetArray here
}
const DeleteAll = () => {
const confirm = window.confirm(
"Are you sure you want to delete all widgets?"
);
if (confirm) {
setLayout([]);
setWidgetArray([]);
onSave();
}
else return;
}
// Prop Forwarding
const widgetCanvasProps = { layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray };
const settingsButtonProps = { onAddWidget, onEditWidgets, onDeleteWidgets, setWidgetArray, widgetArray };
return (
/* HEADER */
<Tabs.Root
width={width}
height={height}
lazyMount
value={ view }
variant="line"
// Prevent navigation away from 'My Dashboard' while in Edit mode
onValueChange={(e) => {
const nextView = e.value;
onChangeView(nextView);
}}
>
<Flex
as="header"
position="sticky"
top="0"
zIndex="dropdown" // zIndex: 1100
bg="base200"
px={6}
pt={3}
align="center"
justify="space-between"
>
<Tabs.List>
<Tabs.Trigger value="widget" fontSize="lg">
My Dashboard
</Tabs.Trigger>
<Tabs.Trigger value="gas" fontSize="lg">
Gas
</Tabs.Trigger>
<Tabs.Trigger value="seismic" fontSize="lg">
Seismic
</Tabs.Trigger>
<Tabs.Trigger value="remote" fontSize="lg">
Remote Sensing
</Tabs.Trigger>
<Tabs.Trigger value="daily" fontSize="lg">
Daily Activity
</Tabs.Trigger>
</Tabs.List>
<HStack >
{isEditable ? (
<>
<SaveButton onSave={ onSave } />
<CancelButton onCancel={ onCancel } />
{isDelete ? (
<DeleteAllButton onDeleteAll={ DeleteAll } />
):(null)
}
</>
):(
<>
<SearchBar />
<SettingsButton {...settingsButtonProps}/>
</>
)}
</HStack>
</Flex>
{/* CANVAS */}
<Tabs.Content value="widget">
<WidgetCanvas {...widgetCanvasProps}/>
</Tabs.Content>
<Tabs.Content value="gas">
<Gas />
</Tabs.Content>
<Tabs.Content value="seismic">
<Seismic />
</Tabs.Content>
<Tabs.Content value="remote">
<RemoteSensing />
</Tabs.Content>
<Tabs.Content value="daily">
<DailyActivity />
</Tabs.Content>
</Tabs.Root>
);
}
@@ -0,0 +1,22 @@
import { Box, Text } from "@chakra-ui/react";
export function DailyActivity() {
return(
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">Daily Activity dashboard coming soon.</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,22 @@
import { Box, Text } from "@chakra-ui/react";
export function Gas() {
return(
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">Gas dashboard coming soon.</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,50 @@
import GridLayout, { WidthProvider } from 'react-grid-layout';
import { useSlotRecipe, chakra, Flex } from '@chakra-ui/react';
export default function WidgetCanvas({layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray}) {
console.log("rendering MyDashboard");
const recipe = useSlotRecipe({ key: "widget" });
const styles = recipe(); // using root recipe for widget below
const ResponsiveGridLayout = WidthProvider(GridLayout); // canvas width now adjusts to window size
const handleDragStart = () => { document.body.style.userSelect = "none"; }; // don't allow text highlighting when dragging
const handleDragStop = () => { document.body.style.userSelect = ""; }; // allow text highlighting all other times
let merged = [];
console.log("widgetArray: ", widgetArray);
console.log("layout: ", layout);
if (widgetArray.length && layout.length) {
const widgetMap = new Map(widgetArray.map(item => [item.i, item]));
merged = layout.map(item => {
return {
...item,
...widgetMap.get(item.i)
};
});
};
return (
<chakra.div width="100%">
<ResponsiveGridLayout
className="layout"
layout={layout}
cols={12} // Total columns in grid
rowHeight={30} //Height of a single row in px
isBounded={true} // Total width of the grid
margin={[10, 10]} // [horizontal, vertical] gap
onLayoutChange={onLayoutChange}
draggableHandle=".widget-handle" // Make only the header draggable
onDragStart={handleDragStart}
onDragStop={handleDragStop}
>
{merged.map((item) => {
const Widget = item.widget;
return (
<Flex key={item.i} css={styles.root} height="100%" >
<Widget id={item.i} isEditable={isEditable} isDelete={isDelete} DeleteWidget={DeleteWidget}/>
</Flex>
)
})}
</ResponsiveGridLayout>
</chakra.div>
);
}
@@ -0,0 +1,22 @@
import { Box, Text } from "@chakra-ui/react";
export function RemoteSensing() {
return(
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">Remote Sensing dashboard coming soon.</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,22 @@
import { Box, Text } from "@chakra-ui/react";
export function Seismic() {
return(
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">Seismic dashboard coming soon.</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,19 @@
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
export default function GlobalMapCanvas() {
const position = [45.61142478054226, -122.49630033167544]; // [latitude, longitude]
return (
<MapContainer center={position} zoom={13} style={{ height: "100%", width: "100%" }}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; OpenStreetMap contributors'
/>
<Marker position={position}>
<Popup>
CVO Home of the volcanoligists
</Popup>
</Marker>
</MapContainer>
);
}
@@ -0,0 +1,24 @@
import { Box, Text } from '@chakra-ui/react';
export default function SettingsCanvas() {
return (
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">
Settings Canvas coming soon!
</Text>
</Box>
</Box>
);
}
@@ -0,0 +1,24 @@
import { Box, Text } from '@chakra-ui/react';
export default function VolcanoCanvas() {
return (
<Box p={8} mt={4} ml="auto" mr="auto" width="600px">
<Box
bg="bg"
shadow="md"
borderRadius="md"
p={8}
width="600px"
height="100px"
textAlign="center"
display="flex"
alignItems="center"
justifyContent="center"
>
<Text fontsize="2xl" fontWeight="bold" color="gray.700">
Volcano Canvas coming soon!
</Text>
</Box>
</Box>
);
}