diff --git a/package-lock.json b/package-lock.json index 33c4815..499d9e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "react-day-picker": "^9.4.4", "react-dom": "^18", "react-hook-form": "^7.53.0", + "react-joyride": "^2.9.3", "react-loader-spinner": "^6.1.6", "react-qr-code": "^2.0.15", "react-syntax-highlighter": "^15.6.1", @@ -1447,6 +1448,11 @@ "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", "license": "MIT" }, + "node_modules/@gilbarbara/deep-equal": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@gilbarbara/deep-equal/-/deep-equal-0.3.1.tgz", + "integrity": "sha512-I7xWjLs2YSVMc5gGx1Z3ZG1lgFpITPndpi8Ku55GeEIKpACCPQNS/OTqQbxgTCfq0Ncvcc+CrFov96itVh6Qvw==" + }, "node_modules/@grpc/grpc-js": { "version": "1.9.15", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", @@ -4594,14 +4600,12 @@ "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", - "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", - "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -6640,6 +6644,11 @@ "node": ">=0.10" } }, + "node_modules/deep-diff": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.2.tgz", + "integrity": "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6647,6 +6656,14 @@ "dev": true, "license": "MIT" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -8842,6 +8859,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-lite": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-lite/-/is-lite-1.2.1.tgz", + "integrity": "sha512-pgF+L5bxC+10hLBgf6R2P4ZZUBOQIIacbdo8YvuCP8/JvsWxG7aZ9p10DYuLtifFci4l3VITphhMlMV4Y+urPw==" + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -10133,6 +10155,16 @@ "node": ">=10.13.0" } }, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -10684,6 +10716,41 @@ "react": "^18.3.1" } }, + "node_modules/react-floater": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/react-floater/-/react-floater-0.7.9.tgz", + "integrity": "sha512-NXqyp9o8FAXOATOEo0ZpyaQ2KPb4cmPMXGWkx377QtJkIXHlHRAGer7ai0r0C1kG5gf+KJ6Gy+gdNIiosvSicg==", + "dependencies": { + "deepmerge": "^4.3.1", + "is-lite": "^0.8.2", + "popper.js": "^1.16.0", + "prop-types": "^15.8.1", + "tree-changes": "^0.9.1" + }, + "peerDependencies": { + "react": "15 - 18", + "react-dom": "15 - 18" + } + }, + "node_modules/react-floater/node_modules/@gilbarbara/deep-equal": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@gilbarbara/deep-equal/-/deep-equal-0.1.2.tgz", + "integrity": "sha512-jk+qzItoEb0D0xSSmrKDDzf9sheQj/BAPxlgNxgmOaA3mxpUa6ndJLYGZKsJnIVEQSD8zcTbyILz7I0HcnBCRA==" + }, + "node_modules/react-floater/node_modules/is-lite": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/is-lite/-/is-lite-0.8.2.tgz", + "integrity": "sha512-JZfH47qTsslwaAsqbMI3Q6HNNjUuq6Cmzzww50TdP5Esb6e1y2sK2UAaZZuzfAzpoI2AkxoPQapZdlDuP6Vlsw==" + }, + "node_modules/react-floater/node_modules/tree-changes": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/tree-changes/-/tree-changes-0.9.3.tgz", + "integrity": "sha512-vvvS+O6kEeGRzMglTKbc19ltLWNtmNt1cpBoSYLj/iEcPVvpJasemKOlxBrmZaCtDJoF+4bwv3m01UKYi8mukQ==", + "dependencies": { + "@gilbarbara/deep-equal": "^0.1.1", + "is-lite": "^0.8.2" + } + }, "node_modules/react-hook-form": { "version": "7.54.2", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.2.tgz", @@ -10700,12 +10767,54 @@ "react": "^16.8.0 || ^17 || ^18 || ^19" } }, + "node_modules/react-innertext": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/react-innertext/-/react-innertext-1.1.5.tgz", + "integrity": "sha512-PWAqdqhxhHIv80dT9znP2KvS+hfkbRovFp4zFYHFFlOoQLRiawIic81gKb3U1wEyJZgMwgs3JoLtwryASRWP3Q==", + "peerDependencies": { + "@types/react": ">=0.0.0 <=99", + "react": ">=0.0.0 <=99" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/react-joyride": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/react-joyride/-/react-joyride-2.9.3.tgz", + "integrity": "sha512-1+Mg34XK5zaqJ63eeBhqdbk7dlGCFp36FXwsEvgpjqrtyywX2C6h9vr3jgxP0bGHCw8Ilsp/nRDzNVq6HJ3rNw==", + "dependencies": { + "@gilbarbara/deep-equal": "^0.3.1", + "deep-diff": "^1.0.2", + "deepmerge": "^4.3.1", + "is-lite": "^1.2.1", + "react-floater": "^0.7.9", + "react-innertext": "^1.1.5", + "react-is": "^16.13.1", + "scroll": "^3.0.1", + "scrollparent": "^2.1.0", + "tree-changes": "^0.11.2", + "type-fest": "^4.27.0" + }, + "peerDependencies": { + "react": "15 - 18", + "react-dom": "15 - 18" + } + }, + "node_modules/react-joyride/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react-loader-spinner": { "version": "6.1.6", "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-6.1.6.tgz", @@ -11378,6 +11487,16 @@ "loose-envify": "^1.1.0" } }, + "node_modules/scroll": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scroll/-/scroll-3.0.1.tgz", + "integrity": "sha512-pz7y517OVls1maEzlirKO5nPYle9AXsFzTMNJrRGmT951mzpIBy7sNHOg5o/0MQd/NqliCiWnAi0kZneMPFLcg==" + }, + "node_modules/scrollparent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.1.0.tgz", + "integrity": "sha512-bnnvJL28/Rtz/kz2+4wpBjHzWoEzXhVg/TE8BeVGJHUqE8THNIRnDxDWMktwM+qahvlRdvlLdsQfYe+cuqfZeA==" + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -12252,6 +12371,15 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/tree-changes": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/tree-changes/-/tree-changes-0.11.3.tgz", + "integrity": "sha512-r14mvDZ6tqz8PRQmlFKjhUVngu4VZ9d92ON3tp0EGpFBE6PAHOq8Bx8m8ahbNoGE3uI/npjYcJiqVydyOiYXag==", + "dependencies": { + "@gilbarbara/deep-equal": "^0.3.1", + "is-lite": "^1.2.1" + } + }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", diff --git a/package.json b/package.json index 40091dc..ea293a7 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-day-picker": "^9.4.4", "react-dom": "^18", "react-hook-form": "^7.53.0", + "react-joyride": "^2.9.3", "react-loader-spinner": "^6.1.6", "react-qr-code": "^2.0.15", "react-syntax-highlighter": "^15.6.1", diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx index 0685b49..5c48b75 100644 --- a/src/components/layout/header/Header.tsx +++ b/src/components/layout/header/Header.tsx @@ -45,6 +45,7 @@ const Header = () => {
+
- - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - + {activeMode === "table" ? ( + + + + ) : ( + + )} + - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - + {activeMode === "table" ? ( + + + + ) : ( + + )} + - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - + {activeMode === "table" ? ( + + + + ) : ( + + )} + - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - + {activeMode === "table" ? ( + + + + ) : ( + + )} + - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - + {activeMode === "table" ? ( + + + + ) : ( + + )} + - - - - - - - {activeMode === "table" ? ( + - + + + - ) : ( - - )} - - - + {activeMode === "table" ? ( + + + + ) : ( + + )} + + + + )} ); diff --git a/src/components/modules/escrow/ui/tables/MyEscrowsTable.tsx b/src/components/modules/escrow/ui/tables/MyEscrowsTable.tsx index 2321db2..e58e6b1 100644 --- a/src/components/modules/escrow/ui/tables/MyEscrowsTable.tsx +++ b/src/components/modules/escrow/ui/tables/MyEscrowsTable.tsx @@ -94,7 +94,7 @@ const MyEscrowsTable = ({ type }: MyEscrowsTableProps) => { const { formatDateFromFirebase, formatAddress } = useFormatUtils(); return ( -
+
{loadingEscrows ? ( ) : currentData.length !== 0 ? ( diff --git a/src/components/utils/ui/Create.tsx b/src/components/utils/ui/Create.tsx index 03a16b4..40be606 100644 --- a/src/components/utils/ui/Create.tsx +++ b/src/components/utils/ui/Create.tsx @@ -5,11 +5,12 @@ interface CreateButtonProps { label: string; url: string; className?: string; + id?: string; } -const CreateButton = ({ label, url, className }: CreateButtonProps) => { +const CreateButton = ({ label, url, className, id }: CreateButtonProps) => { return ( - + ); diff --git a/src/constants/steps/steps.tsx b/src/constants/steps/steps.tsx new file mode 100644 index 0000000..8fb259c --- /dev/null +++ b/src/constants/steps/steps.tsx @@ -0,0 +1,41 @@ +import { Placement } from "react-joyride"; + +export const steps = [ + { + title: Welcome to Trustless Work!, + content:

Here you can understand how to use our API!

, + placement: "center" as Placement, + target: "body", + }, + { + title: Roles in Trustless Work, + content:

Here you'll find all the roles in each Escrow.

, + placement: "auto" as Placement, + target: "#step-1", + }, + { + title: Initialize an Escrow, + content: ( +

+ Start by setting up a new escrow agreement. This includes specifying the + terms, amounts, and parties involved. +

+ ), + placement: "auto" as Placement, + target: "#step-2", + }, + { + title: Your Escrows, + content: ( +

+ Here you can see all the escrows you've created or are involved in + depending on your role. See more details about a specific escrow by + clicking on it. There you'll be able to see the status, parties + involved, the current balance and also do some actions like Fund, + Release, etc. +

+ ), + placement: "auto" as Placement, + target: "#step-3", + }, +]; diff --git a/src/core/store/ui/@types/tutorial.entity.ts b/src/core/store/ui/@types/tutorial.entity.ts new file mode 100644 index 0000000..d15b2b8 --- /dev/null +++ b/src/core/store/ui/@types/tutorial.entity.ts @@ -0,0 +1,4 @@ +export interface TutorialGlobalUIStore { + run: boolean; + setRun: (run: boolean) => void; +} diff --git a/src/core/store/ui/index.ts b/src/core/store/ui/index.ts index 403791e..050ec26 100644 --- a/src/core/store/ui/index.ts +++ b/src/core/store/ui/index.ts @@ -11,10 +11,13 @@ import { LoaderGlobalUIStore } from "./@types/loader.entity"; import { useLoaderSlice } from "./slices/loader.slice"; import { StepsGlobalUIStore } from "./@types/steps.entity"; import { useStepsSlice } from "./slices/steps.slice"; +import { useTutorialSlice } from "./slices/tutorial.slice"; +import { TutorialGlobalUIStore } from "./@types/tutorial.entity"; type GlobalUIState = ThemeGlobalUIStore & LoaderGlobalUIStore & - StepsGlobalUIStore; + StepsGlobalUIStore & + TutorialGlobalUIStore; const devtoolsOptions: DevtoolsOptions = { name: "Global UI State", @@ -51,6 +54,7 @@ export const useGlobalUIBoundedStore = create()( ...useThemeSlice(...a), ...useLoaderSlice(...a), ...useStepsSlice(...a), + ...useTutorialSlice(...a), }), devtoolsOptions, ), diff --git a/src/core/store/ui/slices/tutorial.slice.ts b/src/core/store/ui/slices/tutorial.slice.ts new file mode 100644 index 0000000..c77a5f3 --- /dev/null +++ b/src/core/store/ui/slices/tutorial.slice.ts @@ -0,0 +1,19 @@ +import { StateCreator } from "zustand"; +import { TutorialGlobalUIStore } from "../@types/tutorial.entity"; + +export const useTutorialSlice: StateCreator< + TutorialGlobalUIStore, + [["zustand/devtools", never]], + [], + TutorialGlobalUIStore +> = (set) => { + return { + // Stores + run: false, + + // Modifiers + setRun: (run: boolean) => { + set({ run }); + }, + }; +};