From 85b9b1c9e0fdc6908ec2327e0b40d307268fb6ef Mon Sep 17 00:00:00 2001 From: Albert Folch Date: Wed, 18 Dec 2024 11:27:01 +0100 Subject: [PATCH 01/12] wip --- package-lock.json | 187 ++++++++--- package.json | 4 +- public/index.html | 1 + public/scripts/commit-button-example.html | 1 + public/scripts/commit-button.js | 23 +- public/scripts/roblox-example.html | 195 ++++++++++++ public/scripts/roblox.js | 150 +++++++++ src/App.tsx | 2 + src/components/Index.tsx | 2 + src/components/widgets/commit/Commit.tsx | 3 +- .../widgets/commitButton/CommitButton.tsx | 74 ++--- src/components/widgets/finance/Finance.tsx | 1 - .../purchaseOverview/PurchaseOverview.tsx | 2 +- src/components/widgets/redeem/Redeem.tsx | 1 - src/components/widgets/roblox/Roblox.tsx | 296 ++++++++++++++++++ .../widgets/roblox/RobloxDisplay.tsx | 37 +++ src/components/widgets/styles.tsx | 17 +- src/hooks/useProps.ts | 13 + 18 files changed, 915 insertions(+), 94 deletions(-) create mode 100644 public/scripts/roblox-example.html create mode 100644 public/scripts/roblox.js create mode 100644 src/components/widgets/roblox/Roblox.tsx create mode 100644 src/components/widgets/roblox/RobloxDisplay.tsx create mode 100644 src/hooks/useProps.ts diff --git a/package-lock.json b/package-lock.json index 99a7117..2d25b97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,13 +23,15 @@ "crypto-browserify": "^3.12.0", "react": "^18.2.0", "react-codecopy": "^5.0.1", + "react-cookie": "^7.2.2", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0", "react-scripts": "5.0.1", "stream-browserify": "^3.0.0", "styled-components": "^5.3.9", "typescript": "^4.9.5", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "yup": "^1.6.0" }, "devDependencies": { "@fleekhq/fleek-cli": "^0.1.8", @@ -2156,6 +2158,24 @@ "yup": "^0.32.11" } }, + "node_modules/@bosonprotocol/chat-sdk/node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@bosonprotocol/common": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/@bosonprotocol/common/-/common-1.29.0.tgz", @@ -2171,6 +2191,24 @@ "yup": "^0.32.11" } }, + "node_modules/@bosonprotocol/common/node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@bosonprotocol/core-sdk": { "version": "1.41.0", "resolved": "https://registry.npmjs.org/@bosonprotocol/core-sdk/-/core-sdk-1.41.0.tgz", @@ -2207,6 +2245,24 @@ "graphql": "14 - 16" } }, + "node_modules/@bosonprotocol/core-sdk/node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@bosonprotocol/ethers-sdk": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/@bosonprotocol/ethers-sdk/-/ethers-sdk-1.15.0.tgz", @@ -2723,6 +2779,24 @@ } } }, + "node_modules/@bosonprotocol/react-kit/node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@coinbase/wallet-sdk": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-3.7.2.tgz", @@ -7913,6 +7987,12 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/debug": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", @@ -7983,9 +8063,10 @@ } }, "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -8078,9 +8159,10 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/lodash": { - "version": "4.14.196", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.196.tgz", - "integrity": "sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ==" + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "license": "MIT" }, "node_modules/@types/long": { "version": "4.0.2", @@ -22852,7 +22934,8 @@ "node_modules/nanoclone": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", - "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.6", @@ -25665,6 +25748,20 @@ "styled-components": ">=5" } }, + "node_modules/react-cookie": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.2.2.tgz", + "integrity": "sha512-e+hi6axHcw9VODoeVu8WyMWyoosa1pzpyjfvrLdF7CexfU+WSGZdDuRfHa4RJgTpfv3ZjdIpHE14HpYBieHFhg==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.5", + "hoist-non-react-statics": "^3.3.2", + "universal-cookie": "^7.0.0" + }, + "peerDependencies": { + "react": ">= 16.3.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -27657,30 +27754,6 @@ "yup": "^1.0.0" } }, - "node_modules/schema-to-yup/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/schema-to-yup/node_modules/yup": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", - "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", - "license": "MIT", - "dependencies": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - } - }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -29927,6 +30000,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/universal-cookie": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.2.2.tgz", + "integrity": "sha512-fMiOcS3TmzP2x5QV26pIH3mvhexLIT0HmPa3V7Q7knRfT9HG6kTwq02HZGLPw0sAOXrAmotElGRvTLCMbJsvxQ==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.7.2" + } + }, + "node_modules/universal-cookie/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -31891,20 +31983,27 @@ } }, "node_modules/yup": { - "version": "0.32.11", - "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", - "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.6.0.tgz", + "integrity": "sha512-/dny6arMf5CV6ZPAGpXYVw0wR8qcDF15H8zILTQWoRf6jHN1nJNFL1IAlFfUMlO7QGifMVHZle/l8YJdxtWfxg==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/lodash": "^4.14.175", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "nanoclone": "^0.2.1", - "property-expr": "^2.0.4", - "toposort": "^2.0.2" - }, + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=10" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zustand": { diff --git a/package.json b/package.json index 91494ac..71c1d9c 100644 --- a/package.json +++ b/package.json @@ -58,13 +58,15 @@ "crypto-browserify": "^3.12.0", "react": "^18.2.0", "react-codecopy": "^5.0.1", + "react-cookie": "^7.2.2", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0", "react-scripts": "5.0.1", "stream-browserify": "^3.0.0", "styled-components": "^5.3.9", "typescript": "^4.9.5", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "yup": "^1.6.0" }, "devDependencies": { "@fleekhq/fleek-cli": "^0.1.8", diff --git a/public/index.html b/public/index.html index 63967cf..8fc273b 100644 --- a/public/index.html +++ b/public/index.html @@ -31,6 +31,7 @@ Boson widgets + diff --git a/public/scripts/commit-button-example.html b/public/scripts/commit-button-example.html index f11ed67..95e0878 100644 --- a/public/scripts/commit-button-example.html +++ b/public/scripts/commit-button-example.html @@ -4,6 +4,7 @@ + + + + +
+

roundness

+
+
+

min

+
+
+

mid

+
+
+

high

+
+
+

products layout

+
+
+

A

+
+
+

B

+
+
+

show products pre-login

+
+
+

no

+
+
+

yes

+
+
+

color

+
+
+
+
+
+
+ +
+ + + diff --git a/public/scripts/roblox.js b/public/scripts/roblox.js new file mode 100644 index 0000000..fd07e24 --- /dev/null +++ b/public/scripts/roblox.js @@ -0,0 +1,150 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable no-undef */ +const robloxScriptOrigin = getRobloxScriptOrigin(); +// const scriptOrigin = "http://localhost:3006/#"; +function getRobloxScriptOrigin() { + const scriptElCommitButton = document.querySelector( + 'script[src$="/roblox.js"]' + ); + const src = scriptElCommitButton.getAttribute("src"); + if (src.startsWith(".")) { + return `${window.location.origin}/#`; + } + const url = new URL(src); + return `${url.origin}/#`; +} + +function destroyElement(element) { + if (element && element.parentNode) { + element.parentNode.removeChild(element); + } +} +function containerTemplate( + { uid, frame, prerenderFrame, doc, props, event, dimensions }, + { uidStyles } = {} +) { + const EVENT = { + RENDER: "zoid-render", + RENDERED: "zoid-rendered", + PRERENDER: "zoid-prerender", + PRERENDERED: "zoid-prerendered", + DISPLAY: "zoid-display", + ERROR: "zoid-error", + CLOSE: "zoid-close", + DESTROY: "zoid-destroy", + PROPS: "zoid-props", + RESIZE: "zoid-resize", + FOCUS: "zoid-focus" + }; + const CLASS = { + VISIBLE: "zoid-visible", + INVISIBLE: "zoid-invisible" + }; + const { width, height } = dimensions; + + if (!frame || !prerenderFrame) { + return; + } + + const div = doc.createElement("div"); + div.setAttribute("id", uid); + const style = doc.createElement("style"); + if (props.cspNonce) { + style.setAttribute("nonce", props.cspNonce); + } + + style.appendChild( + doc.createTextNode(` + #${uid} { + display: inline-block; + width: ${width}; + height: ${height}; + ${uidStyles} + } + + #${uid} > iframe { + display: inline-block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + transition: opacity .2s ease-in-out; + } + + #${uid} > iframe.${CLASS.INVISIBLE} { + opacity: 0; + } + + #${uid} > iframe.${CLASS.VISIBLE} { + opacity: 1; + } + `) + ); + + div.appendChild(prerenderFrame); + div.appendChild(frame); + div.appendChild(style); + + prerenderFrame.classList.add(CLASS.VISIBLE); + frame.classList.add(CLASS.INVISIBLE); + + event.on(EVENT.RENDERED, () => { + prerenderFrame.classList.remove(CLASS.VISIBLE); + prerenderFrame.classList.add(CLASS.INVISIBLE); + + frame.classList.remove(CLASS.INVISIBLE); + frame.classList.add(CLASS.VISIBLE); + + setTimeout(() => { + destroyElement(prerenderFrame); + }, 1); + }); + function isPerc(str) { + return "string" == typeof str && /^[0-9]+%$/.test(str); + } + function toNum(val) { + if ("number" == typeof val) return val; + var match = val.match(/^([0-9]+)(px|%)$/); + if (!match) throw new Error("Could not match css value from " + val); + return parseInt(match[1], 10); + } + function toPx(val) { + return toNum(val) + "px"; + } + function toCSS(val) { + return "number" == typeof val ? toPx(val) : isPerc(val) ? val : toPx(val); + } + event.on(EVENT.RESIZE, ({ width: newWidth, height: newHeight }) => { + if (typeof newWidth === "number") { + div.style.width = toCSS(newWidth); + } + + if (typeof newHeight === "number") { + div.style.height = toCSS(newHeight); + } + }); + + return div; +} + +var RobloxWidget = zoid.create({ + tag: "boson-roblox-widget", + url: `${robloxScriptOrigin}/roblox`, + dimensions: { width: "100%", height: "500px" }, + containerTemplate: function (args) { + return containerTemplate( + { + ...args, + dimensions: { + ...args.dimensions, + height: + args.props.buttonStyle && typeof args.props.buttonStyle === "object" + ? args.props.buttonStyle.minHeight || "inherit" + : args.dimensions.height + } + }, + { uidStyles: `position: relative;min-height: 100%;` } + ); + } +}); diff --git a/src/App.tsx b/src/App.tsx index b8def57..af66a0c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,6 +17,7 @@ import { purchaseOverviewPath } from "./components/widgets/purchaseOverview/PurchaseOverview"; import { Redeem, redeemPath } from "./components/widgets/redeem/Redeem"; +import { Roblox, robloxPath } from "./components/widgets/roblox/Roblox"; import { GlobalStyle } from "./globalStyles"; function App() { @@ -35,6 +36,7 @@ function App() { element={} > }> + }> diff --git a/src/components/Index.tsx b/src/components/Index.tsx index 0ee3b2d..f923f0d 100644 --- a/src/components/Index.tsx +++ b/src/components/Index.tsx @@ -4,6 +4,7 @@ import { CONFIG } from "../config"; import { CommitDisplay } from "./widgets/commit/CommitDisplay"; import { FinanceDisplay } from "./widgets/finance/FinanceDisplay"; import { RedeemDisplay } from "./widgets/redeem/RedeemDisplay"; +import { RobloxDisplay } from "./widgets/roblox/RobloxDisplay"; const envConfigs = getEnvConfigs(CONFIG.envName); @@ -14,6 +15,7 @@ export function Index() { + Widget Integration Example diff --git a/src/components/widgets/commit/Commit.tsx b/src/components/widgets/commit/Commit.tsx index a511917..13c0423 100644 --- a/src/components/widgets/commit/Commit.tsx +++ b/src/components/widgets/commit/Commit.tsx @@ -64,6 +64,8 @@ export function Commit() { <> } walletConnectProjectId={CONFIG.walletConnectProjectId as string} fairExchangePolicyRules={CONFIG.fairExchangePolicyRules as string} closeWidgetClick={() => { diff --git a/src/components/widgets/commitButton/CommitButton.tsx b/src/components/widgets/commitButton/CommitButton.tsx index 471fe24..4d803de 100644 --- a/src/components/widgets/commitButton/CommitButton.tsx +++ b/src/components/widgets/commitButton/CommitButton.tsx @@ -3,15 +3,14 @@ import { CommitButtonView } from "@bosonprotocol/react-kit"; import { ElementRef, useCallback, useEffect, useMemo, useRef } from "react"; -import { useState } from "react"; import { createGlobalStyle, css, CSSProperties } from "styled-components"; import * as yup from "yup"; +import { useProps } from "../../../hooks/useProps"; import { GlobalStyle } from "../styles"; export const commitButtonPath = "/commit-button"; declare const CommitWidgetModal: (props: Record) => any; -declare const PurchaseOverviewModal: (props: Record) => any; const yupStringOrNumber = yup .mixed() @@ -47,7 +46,7 @@ const CommitButtonGlobalStyle = createGlobalStyle<{ `; export function CommitButton() { const ref = useRef>(null); - const [props, setProps] = useState(window.xprops ?? {}); + const { props } = useProps(); const { renderToSelector, buttonStyle, @@ -55,13 +54,7 @@ export function CommitButton() { context, ...commitWidgetProps } = props; - useEffect(() => { - if ("xprops" in window && typeof window.xprops.onProps === "function") { - window.xprops.onProps((newProps: typeof props) => { - setProps({ ...newProps }); - }); - } - }, []); + const modalMargin = props.modalMargin || "2%"; const sendDimensions = useCallback(() => { if ( @@ -97,9 +90,18 @@ export function CommitButton() { .object({ minWidth: yupStringOrNumber, minHeight: yupStringOrNumber, - shape: yup.mixed().oneOf(["sharp", "rounded", "pill"]).optional(), - color: yup.mixed().oneOf(["green", "black", "white"]).optional(), - layout: yup.mixed().oneOf(["vertical", "horizontal"]).optional() + shape: yup + .mixed<"sharp" | "rounded" | "pill">() + .oneOf(["sharp", "rounded", "pill"]) + .optional(), + color: yup + .mixed<"green" | "black" | "white">() + .oneOf(["green", "black", "white"]) + .optional(), + layout: yup + .mixed<"vertical" | "horizontal">() + .oneOf(["vertical", "horizontal"]) + .optional() }) .validateSync(buttonStyle); if (typeof buttonStyle === "object") { @@ -111,7 +113,15 @@ export function CommitButton() { const containerStyleValidated = yup .object({ justifyContent: yup - .mixed() + .mixed< + | "initial" + | "flex-start" + | "flex-end" + | "center" + | "space-between" + | "space-around" + | "space-evenly" + >() .oneOf([ "initial", "flex-start", @@ -123,7 +133,14 @@ export function CommitButton() { ]) .optional(), alignItems: yup - .mixed() + .mixed< + | "initial" + | "flex-start" + | "flex-end" + | "center" + | "baseline" + | "stretch" + >() .oneOf([ "initial", "flex-start", @@ -145,7 +162,12 @@ export function CommitButton() { return "iframe"; } - if (yup.mixed().oneOf(["iframe", "popup"]).isValidSync(context)) { + if ( + yup + .mixed<"iframe" | "popup">() + .oneOf(["iframe", "popup"]) + .isValidSync(context) + ) { return context; } throw new Error( @@ -192,26 +214,6 @@ export function CommitButton() { props.onClickCommitButton(); } }} - onTaglineClick={() => { - PurchaseOverviewModal({ - bodyOverflow, - onClose: () => { - if ( - typeof props.onCloseTagline === "function" && - props.onCloseTagline - ) { - props.onCloseTagline(); - } - }, - modalMargin - }).renderTo(window.parent, renderToValue, validatedContext); - if ( - typeof props.onClickTagline === "function" && - props.onClickTagline - ) { - props.onClickTagline(); - } - }} /> ); diff --git a/src/components/widgets/finance/Finance.tsx b/src/components/widgets/finance/Finance.tsx index f83ae8f..fc844b9 100644 --- a/src/components/widgets/finance/Finance.tsx +++ b/src/components/widgets/finance/Finance.tsx @@ -41,7 +41,6 @@ export function Finance() { licenseTemplate={CONFIG.licenseTemplate as string} defaultCurrencyTicker="USD" defaultCurrencySymbol="$" - children={<>} walletConnectProjectId={CONFIG.walletConnectProjectId as string} fairExchangePolicyRules={CONFIG.fairExchangePolicyRules as string} > diff --git a/src/components/widgets/purchaseOverview/PurchaseOverview.tsx b/src/components/widgets/purchaseOverview/PurchaseOverview.tsx index 7d2e579..6bb0036 100644 --- a/src/components/widgets/purchaseOverview/PurchaseOverview.tsx +++ b/src/components/widgets/purchaseOverview/PurchaseOverview.tsx @@ -20,7 +20,7 @@ export const PurchaseOverview = () => { return yup .object({ modalMargin: yup.string().optional(), - bodyOverflow: yup.string().optional().nullable(true) + bodyOverflow: yup.string().optional().nullable() }) .validateSync(props); }, [props]); diff --git a/src/components/widgets/redeem/Redeem.tsx b/src/components/widgets/redeem/Redeem.tsx index e5fa987..bff460c 100644 --- a/src/components/widgets/redeem/Redeem.tsx +++ b/src/components/widgets/redeem/Redeem.tsx @@ -150,7 +150,6 @@ export function Redeem() { ipfsGateway={CONFIG.ipfsGateway as string} ipfsProjectId={CONFIG.ipfsProjectId} ipfsProjectSecret={CONFIG.ipfsProjectSecret} - children={<>} walletConnectProjectId={CONFIG.walletConnectProjectId as string} fairExchangePolicyRules={CONFIG.fairExchangePolicyRules as string} raiseDisputeForExchangeUrl={CONFIG.raiseDisputeForExchange as string} diff --git a/src/components/widgets/roblox/Roblox.tsx b/src/components/widgets/roblox/Roblox.tsx new file mode 100644 index 0000000..a65b96c --- /dev/null +++ b/src/components/widgets/roblox/Roblox.tsx @@ -0,0 +1,296 @@ +import { + bosonButtonThemes, + RobloxWidget, + RobloxWidgetProps, + theme +} from "@bosonprotocol/react-kit"; +import { useMemo } from "react"; +import { css } from "styled-components"; +import * as yup from "yup"; + +import { useProps } from "../../../hooks/useProps"; +import { GlobalStyle } from "../styles"; + +const colors = theme.colors.light; + +export const robloxPath = "/roblox"; + +const roundnessObj = { + min: "min", + mid: "mid", + high: "high" +} as const; +const roundnessValues = Object.values(roundnessObj); +const colorObj = { + green: "green", + white: "white", + black: "black" +} as const; +const colorValues = Object.values(colorObj); + +export function Roblox() { + const { props } = useProps(); + const { roundness, color, configProps } = props; + const validatedRoundness = useMemo(() => { + const validatedRoundness = yup + .mixed<(typeof roundnessValues)[number]>() + .oneOf(roundnessValues) + .validateSync(roundness); + if (!validatedRoundness) { + throw new Error( + `roundness should be one of ${JSON.stringify(roundnessValues)}` + ); + } + return validatedRoundness; + }, [roundness]); + const validatedColor = useMemo(() => { + const validatedColor = yup + .mixed<(typeof colorValues)[number]>() + .oneOf(colorValues) + .validateSync(color); + if (!validatedColor) { + throw new Error(`color should be one of ${JSON.stringify(colorValues)}`); + } + return validatedColor; + }, [color]); + const productsGridProps = useMemo(() => { + const productsStyle = { + title: { + style: { + margin: 0 + } + }, + subtitle: { + style: { + color: validatedColor === "black" ? "inherit" : colors.darkGrey + } + } + } satisfies NonNullable< + RobloxWidgetProps["productsGridProps"]["theme"] + >["unavailabeProducts"]; + return { + theme: { + style: { + background: validatedColor === "black" ? "black" : colors.white, + paddingTop: "5rem", + paddingBottom: "5rem" + }, + currencyColor: validatedColor === "black" ? "inherit" : undefined, + commitButton: { + color: validatedColor, + layout: "horizontal", + shape: + validatedRoundness === "min" + ? "sharp" + : validatedRoundness === "mid" + ? "rounded" + : "pill" + }, + purchasedProducts: { + title: productsStyle["title"] + }, + availableProducts: { + ...productsStyle + }, + unavailabeProducts: { + ...productsStyle + } + } + } satisfies RobloxWidgetProps["productsGridProps"]; + }, [validatedRoundness, validatedColor]); + const connectProps = useMemo(() => { + const borderRadius = + validatedRoundness === "min" + ? "0px" + : validatedRoundness === "mid" + ? "4px" + : "9999px"; + type CardThemeProps = + RobloxWidgetProps["connectProps"]["theme"]["signUpCard"]; + const cardThemeProps = { + title: { + color: validatedColor === "black" ? colors.white : "#1e1e1e" + }, + subtitle: { + color: validatedColor === "black" ? colors.white : colors.darkGrey + }, + check: { + color: + validatedColor === "green" + ? colors.green + : validatedColor === "white" + ? "#1e1e1e" + : colors.white + }, + number: { + active: { + backgroundColor: + validatedColor === "green" + ? colors.green + : validatedColor === "white" + ? "#1e1e1e" + : colors.white, + stroke: + validatedColor === "green" + ? "#1e1e1e" + : validatedColor === "white" + ? colors.white + : "#1e1e1e" + }, + inactive: { + backgroundColor: + validatedColor === "green" + ? colors.lightGrey + : validatedColor === "white" + ? colors.lightGrey + : "black", + stroke: + validatedColor === "green" + ? "#1e1e1e" + : validatedColor === "white" + ? "#1e1e1e" + : colors.white + } + }, + button: { + active: { + ...(validatedColor === "black" + ? { + color: "#1e1e1e", + background: colors.white, + borderWidth: 1, + borderColor: "#1e1e1e", + hover: { + color: colors.white, + background: "#1e1e1e", + borderColor: colors.white + } + } + : validatedColor === "white" + ? { + color: colors.white, + background: "#1e1e1e", + borderWidth: 1, + borderColor: colors.white, + hover: { + color: "#1e1e1e", + borderColor: "#1e1e1e", + background: colors.white + } + } + : { + ...bosonButtonThemes({ withBosonStyle: true })["bosonPrimary"], + borderWidth: 1 + }), + borderRadius: borderRadius + }, + inactive: { + ...(validatedColor === "black" + ? { + color: colors.white, + background: "#1e1e1e", + borderWidth: 1, + borderColor: colors.white, + hover: { + color: "#1e1e1e", + borderColor: "#1e1e1e", + background: colors.white + } + } + : validatedColor === "white" + ? { + color: "#1e1e1e", + background: colors.white, + borderWidth: 1, + borderColor: "#1e1e1e", + hover: { + color: colors.white, + background: "#1e1e1e", + borderColor: colors.white + } + } + : { + color: colors.black, + background: colors.white, + borderWidth: 1, + borderColor: "#1e1e1e", + hover: { + color: colors.white, + background: colors.black + } + }), + borderRadius: borderRadius + } + }, + padding: "24px" + } satisfies CardThemeProps; + return { + brand: "GYMSHARK", + theme: { + backgroundColor: validatedColor === "black" ? "#1e1e1e" : colors.white, + lineBetweenStepsColor: + validatedColor === "black" ? "black" : colors.lightGrey, + stepsBackgroundSides: + validatedColor === "black" ? "#1e1e1e" : colors.white, + robloxCard: cardThemeProps, + walletCard: cardThemeProps, + walletPanel: { + backgroundColor: "white", + buyCryptoTheme: bosonButtonThemes({ withBosonStyle: true })[ + "bosonPrimary" + ], + disconnectBorderRadius: borderRadius, + disconnectBackgroundColor: colors.green, + disconnectColor: "black", + optionProps: { + backgroundColor: colors.accent, + borderRadius: borderRadius, + color: colors.white, + hoverColor: colors.white, + hoverFocusBackgroundColor: "#1e1e1e", + iconBorderRadius: borderRadius + }, + connectionErrorProps: { + backToWalletSelectionTheme: bosonButtonThemes({ + withBosonStyle: true + })["orangeInverse"], + tryAgainTheme: bosonButtonThemes({ withBosonStyle: true })[ + "orangeInverse" + ] + } + }, + signUpCard: cardThemeProps + } + } satisfies RobloxWidgetProps["connectProps"]; + }, [validatedRoundness, validatedColor]); + return ( + <> + + + + ); +} diff --git a/src/components/widgets/roblox/RobloxDisplay.tsx b/src/components/widgets/roblox/RobloxDisplay.tsx new file mode 100644 index 0000000..7782327 --- /dev/null +++ b/src/components/widgets/roblox/RobloxDisplay.tsx @@ -0,0 +1,37 @@ +import { getEnvConfigs } from "@bosonprotocol/react-kit"; +import CodeCopy from "react-codecopy"; +import { Link } from "react-router-dom"; + +import { CONFIG } from "../../../config"; +import { Pre, Widget } from "../styles"; +import { robloxPath } from "./Roblox"; + +export function RobloxDisplay() { + const robloxQPobj = { + configId: getEnvConfigs(CONFIG.envName)[0].configId + }; + const robloxQP = new URLSearchParams(Object.entries(robloxQPobj)).toString(); + const title = "Roblox widget"; + const width = "100%"; + const height = "800px"; + const iframeText = `