diff --git a/package.json b/package.json
index f58a9ea..2ea3d8a 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"dependencies": {
"@chakra-ui/react": "^3.2.1",
"@emotion/react": "^11.13.5",
+ "@fontsource/ibm-plex-sans": "^5.1.0",
"@turf/bbox": "^7.1.0",
"d3": "^7.9.0",
"jotai": "^2.10.3",
diff --git a/src/App.jsx b/src/App.jsx
index 9a04316..86fe715 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,32 +1,42 @@
-import { Box, Grid } from "@chakra-ui/react";
+import { Box, Grid, Text } from "@chakra-ui/react";
import Providers from "./Providers";
import { ChatInput, ChatOutput, Map } from "./components";
function App() {
return (
-
-
-
-
-
-
-
-
+
+ Land Carbon Lab - Zeno
+
+
+
+
+
+
+
+
+
+
+
+
+
);
diff --git a/src/components/ChatInput.jsx b/src/components/ChatInput.jsx
index 901b256..aeff784 100644
--- a/src/components/ChatInput.jsx
+++ b/src/components/ChatInput.jsx
@@ -1,5 +1,6 @@
import { useState } from "react";
-import { Input } from "@chakra-ui/react";
+import { Box, Button, Input } from "@chakra-ui/react";
+import { MdChevronRight } from "react-icons/md";
import { useSetAtom } from "jotai";
import { addPrompt } from "../atoms";
@@ -17,14 +18,33 @@ function ChatInput() {
};
return (
- setInputValue(e.target.value)}
- onKeyUp={handleKeyUp}
- />
+
+ setInputValue(e.target.value)}
+ onKeyUp={handleKeyUp}
+ />
+
+
);
}
diff --git a/src/components/ChatOutput.jsx b/src/components/ChatOutput.jsx
index f096463..eae1943 100644
--- a/src/components/ChatOutput.jsx
+++ b/src/components/ChatOutput.jsx
@@ -31,7 +31,7 @@ function ChatOutput() {
}, []);
return (
-
+
{chatHistory.map((msg) => {
switch (msg.type) {
case "in":
diff --git a/src/components/LclLogo.jsx b/src/components/LclLogo.jsx
new file mode 100644
index 0000000..5604bb3
--- /dev/null
+++ b/src/components/LclLogo.jsx
@@ -0,0 +1,15 @@
+function LclLogo() {
+ return (
+
+ );
+}
+
+export default LclLogo;
diff --git a/src/components/Map.jsx b/src/components/Map.jsx
index 71f5a01..e551cf7 100644
--- a/src/components/Map.jsx
+++ b/src/components/Map.jsx
@@ -1,5 +1,9 @@
import "maplibre-gl/dist/maplibre-gl.css";
-import MapGl, { Layer, Source, AttributionControl } from "react-map-gl/maplibre";
+import MapGl, {
+ Layer,
+ Source,
+ AttributionControl,
+} from "react-map-gl/maplibre";
import { useEffect } from "react";
import bbox from "@turf/bbox";
import { mapLayersAtom } from "../atoms";
@@ -19,19 +23,28 @@ function Map() {
// each layer is a feature collection, so we need to calculate the bounds of all features
useEffect(() => {
if (mapLayers.length > 0) {
- const bounds = mapLayers.reduce((acc, layer) => {
- const layerBounds = bbox(layer);
- return [
- Math.min(acc[0], layerBounds[0]),
- Math.min(acc[1], layerBounds[1]),
- Math.max(acc[2], layerBounds[2]),
- Math.max(acc[3], layerBounds[3])
- ];
- }, [Infinity, Infinity, -Infinity, -Infinity]);
+ const bounds = mapLayers.reduce(
+ (acc, layer) => {
+ const layerBounds = bbox(layer);
+ return [
+ Math.min(acc[0], layerBounds[0]),
+ Math.min(acc[1], layerBounds[1]),
+ Math.max(acc[2], layerBounds[2]),
+ Math.max(acc[3], layerBounds[3]),
+ ];
+ },
+ [Infinity, Infinity, -Infinity, -Infinity]
+ );
- mapRef.current.fitBounds([[bounds[0], bounds[1]], [bounds[2], bounds[3]]], {
- padding: {top: 100, bottom: 100, left: 450, right: 100}
- });
+ mapRef.current.fitBounds(
+ [
+ [bounds[0], bounds[1]],
+ [bounds[2], bounds[3]],
+ ],
+ {
+ padding: 100,
+ }
+ );
}
}, [mapLayers]);
@@ -48,19 +61,28 @@ function Map() {
- {mapLayers.map((layer, idx) => {
- const layerId = layer?.features[0]?.id || idx;
- return (
-
- );
- })}
+ {mapLayers.map((layer, idx) => {
+ const layerId = layer?.features[0]?.id || idx;
+ return (
+
+ );
+ })}
);
diff --git a/src/components/MessageIn.jsx b/src/components/MessageIn.jsx
index 5c64b3d..de64a02 100644
--- a/src/components/MessageIn.jsx
+++ b/src/components/MessageIn.jsx
@@ -3,7 +3,7 @@ import { Box } from "@chakra-ui/react";
function MessageIn({ message }) {
return (
-
+
{message}
);
diff --git a/src/components/MessageAssistant.jsx b/src/components/MessageOut/MessageAssistant.jsx
similarity index 67%
rename from src/components/MessageAssistant.jsx
rename to src/components/MessageOut/MessageAssistant.jsx
index ec603e4..180c37c 100644
--- a/src/components/MessageAssistant.jsx
+++ b/src/components/MessageOut/MessageAssistant.jsx
@@ -1,32 +1,44 @@
import T from "prop-types";
-import { Box, Button } from "@chakra-ui/react";
+import { Button } from "@chakra-ui/react";
import Markdown from "react-markdown";
import { useSetAtom } from "jotai";
-import { addPrompt } from "../atoms";
+import { addPrompt } from "../../atoms";
+import MessageOutWrapper from "./wrapper";
function MessageAssistant({ message }) {
const submit = useSetAtom(addPrompt);
if (typeof message === "string" || message instanceof String) {
return (
-
+
{message}
-
+
);
} else {
return (
-
+
{message.map((messagePart) => {
const { index, type } = messagePart;
if (type === "text") {
return {messagePart.text};
} else {
const { query } = JSON.parse(messagePart.partial_json);
- return ;
+ return (
+ );
}
})}
-
+
);
}
}
diff --git a/src/components/MessageDefault.jsx b/src/components/MessageOut/MessageDefault.jsx
similarity index 67%
rename from src/components/MessageDefault.jsx
rename to src/components/MessageOut/MessageDefault.jsx
index 9aecd9c..8934ed6 100644
--- a/src/components/MessageDefault.jsx
+++ b/src/components/MessageOut/MessageDefault.jsx
@@ -1,13 +1,13 @@
import T from "prop-types";
-import { Box } from "@chakra-ui/react";
-import { Alert } from "./ui/alert";
+import { Alert } from "../ui/alert";
+import MessageOutWrapper from "./wrapper";
function MessageDefault({message, type}) {
return (
-
+
{message}
-
+
);
}
diff --git a/src/components/MessageTool.jsx b/src/components/MessageOut/MessageTool.jsx
similarity index 92%
rename from src/components/MessageTool.jsx
rename to src/components/MessageOut/MessageTool.jsx
index 3c637e5..adb066d 100644
--- a/src/components/MessageTool.jsx
+++ b/src/components/MessageOut/MessageTool.jsx
@@ -1,10 +1,11 @@
import T from "prop-types";
import { Box, Button } from "@chakra-ui/react";
-import MiniMap from "./MiniMap";
-import BarChart from "./BarChart";
+import MessageOutWrapper from "./wrapper";
+import MiniMap from "../MiniMap";
+import BarChart from "../BarChart";
import { useSetAtom } from "jotai";
-import { mapLayersAtom } from "../atoms";
+import { mapLayersAtom } from "../../atoms";
function ContextLayer({message}) {
return (
@@ -93,9 +94,9 @@ function MessageTool({message, toolName, artifact}) {
}
return (
-
+
{render}
-
+
);
}
diff --git a/src/components/MessageOut/wrapper.jsx b/src/components/MessageOut/wrapper.jsx
new file mode 100644
index 0000000..69103cd
--- /dev/null
+++ b/src/components/MessageOut/wrapper.jsx
@@ -0,0 +1,22 @@
+import T from "prop-types";
+import { Box } from "@chakra-ui/react";
+import { LclLogo } from "..";
+
+function MessageOutWrapper({ children }) {
+ return (
+
+
+
+
+
+ {children}
+
+
+ );
+}
+
+MessageOutWrapper.propTypes = {
+ children: T.node.isRequired
+};
+
+export default MessageOutWrapper;
diff --git a/src/components/MiniMap.jsx b/src/components/MiniMap.jsx
index 4d6fa5e..394c13f 100644
--- a/src/components/MiniMap.jsx
+++ b/src/components/MiniMap.jsx
@@ -4,7 +4,7 @@ import "maplibre-gl/dist/maplibre-gl.css";
import bbox from "@turf/bbox";
/**
- * MiniMap is a static map for the sidebar
+ * MiniMap is a static map for the sidebar
*/
function MiniMap({ artifact }){
let viewState = {
@@ -34,7 +34,7 @@ function MiniMap({ artifact }){
)}
diff --git a/src/components/index.js b/src/components/index.js
index 458c59f..c31e52a 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,14 +1,16 @@
import ChatInput from "./ChatInput";
import ChatOutput from "./ChatOutput";
+import LclLogo from "./LclLogo";
import Map from "./Map";
import MessageIn from "./MessageIn";
-import MessageTool from "./MessageTool";
-import MessageAssistant from "./MessageAssistant";
-import MessageDefault from "./MessageDefault";
+import MessageTool from "./MessageOut/MessageTool";
+import MessageAssistant from "./MessageOut/MessageAssistant";
+import MessageDefault from "./MessageOut/MessageDefault";
export {
ChatInput,
ChatOutput,
+ LclLogo,
Map,
MessageIn,
MessageTool,
diff --git a/src/main.jsx b/src/main.jsx
index b48d3a0..c0577bb 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,6 +1,7 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
+import "@fontsource/ibm-plex-sans/index.css";
createRoot(document.getElementById("root")).render(
diff --git a/src/theme/globalCss.jsx b/src/theme/globalCss.jsx
new file mode 100644
index 0000000..e2c98e7
--- /dev/null
+++ b/src/theme/globalCss.jsx
@@ -0,0 +1,21 @@
+export default {
+ h2: {
+ marginBottom: 4,
+ fontSize: "lg",
+ fontWeight: "bold"
+ },
+ h3: {
+ marginBottom: 4,
+ fontWeight: "bold"
+ },
+ ul: {
+ marginTop: 4,
+ marginBottom: 4,
+ listStyleType: "disc",
+ paddingLeft: 4
+ },
+ p: {
+ marginTop: 4,
+ marginBottom: 4,
+ }
+};
diff --git a/src/theme/index.jsx b/src/theme/index.jsx
index b6722c6..51b8c4a 100644
--- a/src/theme/index.jsx
+++ b/src/theme/index.jsx
@@ -1,5 +1,54 @@
-import { createSystem, defaultConfig } from "@chakra-ui/react";
+import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react";
+import globalCss from "./globalCss";
-const config = {};
+const config = defineConfig({
+ globalCss,
+ theme: {
+ tokens: {
+ fonts: {
+ body: { value: "IBM Plex Sans" },
+ heading: { value: "IBM Plex Sans" },
+ },
+ colors: {
+ blue: {
+ 50: "#ebf9ff",
+ 100: "#d1f1ff",
+ 200: "#aee7ff",
+ 300: "#76dbff",
+ 400: "#35c4ff",
+ 500: "#07a0ff",
+ 600: "#007bff",
+ 700: "#0062ff",
+ 800: "#0051d7",
+ 900: "#0049a8", //primary
+ 950: "#062d65",
+ },
+
+ lime: {
+ 50: "#fcfee7",
+ 100: "#f7fbcc",
+ 200: "#eef89e",
+ 300: "#def066",
+ 400: "#cbe437",
+ 500: "#adca18", //primary
+ 600: "#87a10f",
+ 700: "#667b10",
+ 800: "#516113",
+ 900: "#445215",
+ 950: "#242e05",
+ },
+ cyan: { 500: "#01B9F3" },
+ indigo: { 500: "#6F6FDF" },
+ purple: { 500: "#BA4AFF" },
+ pink: { 500: "#F26798" },
+ red: { 500: "#FF452C" },
+ orange: { 500: "#FF9916" },
+ yellow: { 500: "#FFD80B" },
+ mint: { 500: "#00DCA7" },
+ green: { 500: "#00A651" },
+ },
+ },
+ },
+});
export default createSystem(defaultConfig, config);
diff --git a/yarn.lock b/yarn.lock
index 83aa58e..8795593 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -550,6 +550,11 @@
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz"
integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==
+"@fontsource/ibm-plex-sans@^5.1.0":
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/@fontsource/ibm-plex-sans/-/ibm-plex-sans-5.1.0.tgz#9cd6bcce9817c55565ae2cf92629ce9a9f617a6b"
+ integrity sha512-v2aFHGh33ogG+At6dVNUCX6vWlNAhQ6STWj5WrBKPxVWX1SsAnHNq8sXQBa7WHEt29Irmozuk7GTp6GzFlpwdQ==
+
"@humanfs/core@^0.19.1":
version "0.19.1"
resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz"
@@ -3942,7 +3947,7 @@ react-dom@^18.3.1:
react-icons@^5.4.0:
version "5.4.0"
- resolved "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz"
+ resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.4.0.tgz#443000f6e5123ee1b21ea8c0a716f6e7797f7416"
integrity sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==
react-is@^16.13.1, react-is@^16.7.0: