diff --git a/frontend/src/components/EngineOverviewDiagram.js b/frontend/src/components/EngineOverviewDiagram.js
new file mode 100644
index 00000000..8167da57
--- /dev/null
+++ b/frontend/src/components/EngineOverviewDiagram.js
@@ -0,0 +1,320 @@
+import { React, useRef } from "react";
+import {
+ chakra,
+ Grid,
+ GridItem,
+ Flex,
+ Center,
+ VStack,
+ Text,
+ Icon,
+ Popover,
+ PopoverTrigger,
+ PopoverBody,
+ PopoverContent,
+ useBreakpointValue,
+} from "@chakra-ui/react";
+import CloudSVG from "./SVGGraphics/Cloud";
+import RectangleSVG from "./SVGGraphics/Rectangle";
+import RoundedRectSVG from "./SVGGraphics/RoundedRect";
+// import { AiFillFile } from "react-icons/ai";
+import { BsFillPersonFill } from "react-icons/bs";
+import { BsFillFileEarmarkCodeFill } from "react-icons/bs";
+// import { MODAL_TYPES } from "../core/providers/OverlayProvider/constants";
+import Xarrow from "react-xarrows";
+import ExampleCode from "./ExampleCode";
+
+const _EngineOverviewDiagram = () => {
+ // const scaleWidth = (width) => {
+ // return [width * 0.65, width, width, width, width, width * 1.2].map(
+ // (val) => {
+ // return val + "px";
+ // }
+ // );
+ // };
+
+ const smartContract = useRef(null);
+ const gameClient = useRef(null);
+ const adminDashboard = useRef(null);
+ const gameServer = useRef(null);
+ const user = useRef(null);
+
+ // const { toggleModal } = useModals();
+
+ const xarrowStyle = {
+ color: "#212990",
+ showHead: true,
+ headSize: 6,
+ };
+
+ const smallDiagram = useBreakpointValue({
+ base: true,
+ sm: true,
+ md: false,
+ lg: false,
+ xl: false,
+ "2xl": false,
+ });
+
+ // const collapseLayout = useBreakpointValue({
+ // base: true,
+ // sm: true,
+ // md: false,
+ // lg: false,
+ // xl: false,
+ // "2xl": false,
+ // });
+
+ return (
+ <>
+ {/*
+
+
+
+
+
+
+ */}
+
+
+
+
+
+
+
+ Moonstream Smart Contracts
+
+ {!smallDiagram && (
+
+ Your backend for lootboxes, crafting recipes, items,
+ minigames
+
+ )}
+
+
+
+
+
+
+
+
+
+ Game Client
+
+
+
+
+
+
+
+
+ Admin Dashboard
+ {!smallDiagram && (
+
+ Choose mechanics at engine.moonstream.to
+
+ )}
+
+
+
+
+
+
+
+ {/* toggleModal({ type: MODAL_TYPES.EXAMPLE_CODE })}
+ > */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Game Server
+
+
+
+
+
+
+ Game Designer
+
+
+
+ {!smallDiagram && (
+ <>
+
+
+
+
+ >
+ )}
+ {smallDiagram && (
+ <>
+
+
+
+
+ >
+ )}
+ >
+ );
+};
+
+const EngineOverviewDiagram = chakra(_EngineOverviewDiagram);
+
+export default EngineOverviewDiagram;
diff --git a/frontend/src/components/ExampleCode.js b/frontend/src/components/ExampleCode.js
new file mode 100644
index 00000000..5eea9a36
--- /dev/null
+++ b/frontend/src/components/ExampleCode.js
@@ -0,0 +1,153 @@
+import React from "react";
+// import { MODAL_TYPES } from "../core/providers/OverlayProvider/constants";
+import { Flex, Heading } from "@chakra-ui/react";
+import showdown from "showdown";
+import showdownHighlight from "showdown-highlight";
+
+const ExampleCode = (props) => {
+ const converter = new showdown.Converter({
+ ghCompatibleHeaderId: true,
+ parseImgDimensions: true,
+ simplifiedAutoLink: true,
+ literalMidWordUnderscores: true,
+ strikethrough: true,
+ tables: true,
+ tasklists: true,
+ openLinksInNewWindow: true,
+ emoji: true,
+ smartIndentationFix: true,
+ extensions: [showdownHighlight({ pre: true })],
+ disableForced4SpacesIndentedSublists: true,
+ ghCodeBlocks: true,
+ });
+ const code = `
+ \`\`\`js
+ async function startRandomLootboxOpening(lootboxId) {
+ let userAddress = window.ethereum.selectedAddress;
+ \tlet activeOpening = await checkUsersActiveLootboxOpeningStatus(userAddress);
+ if (activeOpening != null) {
+ console.log("User already has active opening");
+ return;
+ }
+
+ const count = 1; // you can open only 1 random lootbox at a time
+ await openOrdinaryLootbox(lootboxId, count);
+ }
+ \`\`\`
+ `;
+ let formattedCode = converter.makeHtml(code);
+ console.log(formattedCode);
+
+ const HtmlCode = () => {
+ return (
+ <>
+
+
+ {"async"}{" "}
+
+ function{" "}
+ startRandomLootboxOpening
+ {"("}
+ lootboxId
+ {")"}{" "}
+
+ {"{"}
+
+
+ {"let"} {"userAddress ="}{" "}
+ {"window"}
+ {".ethereum.selectedAddress;"}
+
+
+ {"let"} activeOpening ={" "}
+ {"await"}{" "}
+ {"checkUsersActiveLootboxOpeningStatus(userAddress);"}
+
+
+ {"if"} (activeOpening !={" "}
+ null
+ {") {"}
+
+
+ {"console"}
+ {".log"}(
+
+ "User already has active opening"
+
+ {");"}
+
+
+ {"return"};
+
+ {"}"}
+
+
+ const count ={" "}
+ 1;{" "}
+
+ {"// you can open only 1 random lootbox at a time"}
+
+
+
+ await{" "}
+ openOrdinaryLootbox(lootboxId, count);
+
+ {"}"}
+
+
+ >
+ );
+ };
+
+ return (
+
+
+ We make sure our code is easy to use. Here’s an example:
+
+ {/* */}
+ {/* {formattedCode} */}
+
+
+
+ {/*
+ {"async function startRandomLootboxOpening( lootboxId ) {"}
+
+
+ {" "}
+
+ {"let userAddress = window.ethereum.selectedAddress;"}
+
+
+ {" "}
+
+ {
+ "let activeOpening = await checkUsersActiveLootboxOpeningStatus( userAddress );"
+ }
+
+ {"if ( activeOpening != null ) {"}
+
+
+ {"console.log('User already has active opening');"}
+
+ {"return;"}
+ {"}"}
+
+
+ {"const count = 1; // you can open only 1 random lootbox at a time"}
+
+
+ {"await openOrdinaryLootbox( lootboxId, count );"}
+
+ {"}"} */}
+
+ );
+};
+
+export default ExampleCode;
diff --git a/frontend/src/components/FAQCard.js b/frontend/src/components/FAQCard.js
new file mode 100644
index 00000000..e38dd4f8
--- /dev/null
+++ b/frontend/src/components/FAQCard.js
@@ -0,0 +1,47 @@
+import { React } from "react";
+import {
+ chakra,
+ AccordionButton,
+ AccordionPanel,
+ Heading,
+ Box,
+ AccordionItem,
+} from "@chakra-ui/react";
+import { AddIcon, MinusIcon } from "@chakra-ui/icons";
+
+const _FAQCard = ({ heading, headingProps, panelContent }) => {
+ return (
+
+ {({ isExpanded }) => (
+ <>
+
+
+
+ {heading}
+
+
+ {isExpanded ? (
+
+ ) : (
+
+ )}
+
+
+ {panelContent}
+
+ >
+ )}
+
+ );
+};
+
+const FAQCard = chakra(_FAQCard);
+
+export default FAQCard;
diff --git a/frontend/src/components/SVGGraphics/Cloud.js b/frontend/src/components/SVGGraphics/Cloud.js
new file mode 100644
index 00000000..21683fed
--- /dev/null
+++ b/frontend/src/components/SVGGraphics/Cloud.js
@@ -0,0 +1,39 @@
+import { React } from "react";
+import { chakra } from "@chakra-ui/react";
+
+const _CloudSVG = (scale) => {
+ scale = scale || 1.0;
+ return (
+
+ );
+};
+
+const CloudSVG = chakra(_CloudSVG);
+
+export default CloudSVG;
diff --git a/frontend/src/components/SVGGraphics/Rectangle.js b/frontend/src/components/SVGGraphics/Rectangle.js
new file mode 100644
index 00000000..0efae5c4
--- /dev/null
+++ b/frontend/src/components/SVGGraphics/Rectangle.js
@@ -0,0 +1,38 @@
+import { React } from "react";
+import { chakra } from "@chakra-ui/react";
+
+const _RectangleSVG = (scale) => {
+ scale = scale || 1.0;
+ return (
+
+ );
+};
+
+const RectangleSVG = chakra(_RectangleSVG);
+
+export default RectangleSVG;
diff --git a/frontend/src/components/SVGGraphics/RoundedRect.js b/frontend/src/components/SVGGraphics/RoundedRect.js
new file mode 100644
index 00000000..7b9f67f1
--- /dev/null
+++ b/frontend/src/components/SVGGraphics/RoundedRect.js
@@ -0,0 +1,39 @@
+import { React } from "react";
+import { chakra } from "@chakra-ui/react";
+
+const _RoundedRectSVG = (scale) => {
+ scale = scale || 1.0;
+ console.log(scale);
+ return (
+
+ );
+};
+
+const RoundedRectSVG = chakra(_RoundedRectSVG);
+
+export default RoundedRectSVG;
diff --git a/frontend/src/core/providers/OverlayProvider/constants.js b/frontend/src/core/providers/OverlayProvider/constants.js
index b4466f21..e3e913f6 100644
--- a/frontend/src/core/providers/OverlayProvider/constants.js
+++ b/frontend/src/core/providers/OverlayProvider/constants.js
@@ -10,6 +10,7 @@ export const MODAL_TYPES = {
UPLOAD_ABI: 8,
NEW_DASHBOARD_FLOW: 9,
MOBILE_INPUT_FIELD: 10,
+ EXAMPLE_CODE: 11,
};
export const DRAWER_TYPES = {
diff --git a/frontend/src/core/providers/OverlayProvider/index.js b/frontend/src/core/providers/OverlayProvider/index.js
index bd2583ad..5803333d 100644
--- a/frontend/src/core/providers/OverlayProvider/index.js
+++ b/frontend/src/core/providers/OverlayProvider/index.js
@@ -56,6 +56,8 @@ const NewSubscription = React.lazy(() =>
const UploadABI = React.lazy(() => import("../../../components/UploadABI"));
+// const ExampleCode = React.lazy(() => import("../../../components/ExampleCode"));
+
const OverlayProvider = ({ children }) => {
const { params } = useRouter();
const { dashboardId } = params;
@@ -322,6 +324,9 @@ const OverlayProvider = ({ children }) => {
{modal.type === MODAL_TYPES.MOBILE_INPUT_FIELD && (
)}
+ {/* {modal.type === MODAL_TYPES.EXAMPLE_CODE && (
+
+ )} */}