diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d01051b..814b36b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -35,6 +35,7 @@ "p-defer": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.14.2", "webextension-polyfill": "^0.10.0" }, "devDependencies": { @@ -3109,6 +3110,14 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@remix-run/router": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz", + "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==", + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-inject": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", @@ -18425,6 +18434,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz", + "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==", + "dependencies": { + "@remix-run/router": "1.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz", + "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==", + "dependencies": { + "@remix-run/router": "1.7.2", + "react-router": "6.14.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/package.json b/package.json index 4a0e2ba..1379c9f 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "p-defer": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.14.2", "webextension-polyfill": "^0.10.0" }, "overrides": { diff --git a/ui/apps/onboarding/App.scss b/ui/apps/onboarding/App.scss new file mode 100644 index 0000000..86ac6f0 --- /dev/null +++ b/ui/apps/onboarding/App.scss @@ -0,0 +1,136 @@ +@import "../../styles/global"; +@import "../../styles/mixins"; +@import "../../styles/vars"; + +main { + position: relative; + background: #080808; +} + +.art, +.content { + position: absolute; + top: 0; + bottom: 0; + width: 50%; +} + +.art { + transition: opacity 250ms ease; + opacity: 0; + + &.art-1.visible, &.art-2.visible, &.art-3.visible, &.art-4.visible { + opacity: 1; + } +} + +.art-1 { + left: 0; + background-image: url("../../assets/onboarding-1.jpg"); + background-position: 50%; + background-size: cover; + border-right: 1px solid #363636; +} + +.art-2 { + left: 50%; + background-image: url("../../assets/onboarding-2.jpg"); + background-position: 50%; + background-size: cover; + border-left: 1px solid #363636; +} + +.art-3 { + left: 50%; + background-image: url("../../assets/onboarding-3.jpg"); + background-position: 50%; + background-size: cover; + border-left: 1px solid #363636; +} + +.art-4 { + left: 50%; + background-image: url("../../assets/onboarding-4.jpg"); + background-position: 50%; + background-size: cover; + border-left: 1px solid #363636; +} + +.content { + display: flex; + flex-direction: column; + align-items: center; + left: 50%; + padding: 5.5em 3.75%; + color: #fff; + background: #080808; + transition: left 250ms cubic-bezier(0.34, 1.56, 0.64, 1); + overflow: auto; + + > div:first-child { + flex-grow: 1; + display: flex; + justify-content: center; + align-items: center; + max-width: 43.2em; + } +} + +.page { + display: flex; + flex-direction: column; + justify-content: flex-end; + min-height: 42em; +} + +h1 { + font-family: $font-family-jetbrains-mono; + @include fluid-font-size(3.125rem); + line-height: 110%; +} + +p { + @include fluid-font-size(1.25rem); + margin-top: 1.4em; + line-height: 122%; + color: #808080; +} + +.btn-wrapper { + margin-top: 5.5em; + + a { + text-decoration: none; + color: inherit; + } +} + +.grant-info { + @include fluid-font-size(1rem); + margin-top: 5em; + max-width: 27em; + line-height: 125%; + color: #808080; + + a { + color: #fff; + } +} + +.started { + .content { + left: 0; + } +} + +@media screen and (max-width: 48rem) { + .art { + display: none; + } + + .content { + left: 0; + width: 100%; + transition: none; + } +} diff --git a/ui/apps/onboarding/App.tsx b/ui/apps/onboarding/App.tsx new file mode 100644 index 0000000..c4c1d39 --- /dev/null +++ b/ui/apps/onboarding/App.tsx @@ -0,0 +1,153 @@ +import { + createHashRouter, + RouteObject, + RouterProvider, + useMatches, +} from "react-router-dom"; +import Page from "./components/Page.js"; +// @ts-ignore +import lumeLogo from "../../assets/lume-logo.png"; +// @ts-ignore +import classNames from "classnames"; +import "./App.scss"; +// @ts-ignore +import browser from "webextension-polyfill"; + +const contentPages = [ + { + heading: <>Thank you for supporting an open web., + content: ( + <> + We are an independent, pure organization. We have decided not to take + money from venture capitalists. Nor do we have a large treasury funding + our work. + + ), + }, + { + heading: <>Thank you for supporting an open web., + content: ( + <> + Easy Access to Web3. With native Handshake (HNS) and Ethereum (ENS) + support, you can forget eth.link and hns.is. This is your gateway. + + ), + }, + { + heading: <>Thank you for supporting an open web., + content: ( + <> + We are an independent, pure organization. We have decided not to take + money from venture capitalists. Nor do we have a large treasury funding + our work. + + ), + }, + { + heading: <>Thank you for supporting an open web., + content: ( + <> + Stop worrying about being vendor-locked. Remain flexible and reduce your + storage costs by 50% or more. Lume is affordable storage on-demand. + + ), + }, +] as { + heading: React.ReactElement; + content: React.ReactElement; +}[]; + +contentPages.map((page, index) => { + if (!index) { + return; + } +}); + +const childRoutes = contentPages.slice(1).map((item, index): RouteObject => { + return { + path: `page-${index + 1}`, + handle: { + page: index + 1, + }, + }; +}); + +const rootRoute = { + path: "/", + element: , + handle: { + page: 0, + }, +}; + +const router = createHashRouter([{ ...rootRoute, children: childRoutes }]); + +export default function App() { + return ( + <> +
+ Lume +
+ + + ); +} + +function Content() { + const routeData = useMatches(); + + const accountUrl = browser.runtime.getURL("account.html"); + const handle = routeData.pop().handle as { page: number }; + + const start = handle.page === 0 ? `page-1` : false; + + const next = + !start && contentPages.length - 1 > handle.page + ? `page-${handle.page + 1}` + : false; + const back = handle.page > 1 ? `page-${handle.page - 1}` : false; + + const getStarted = + handle.page + 1 === contentPages.length ? accountUrl : false; + + const skip = handle.page === 1 ? accountUrl : false; + + return ( +
0 })}> + {Array(contentPages.length) + .fill(0) + .map((_, index) => ( +
+ ))} + +
+
+ +
+ +
+
+ ); +} + +function GrantInfo() { + return ( +
+ Lume is a 503c Grant recipient, + learn more about the work we’re doing to + provide accessible access to the open web for everyone. +
+ ); +} diff --git a/ui/apps/onboarding/components/Page.tsx b/ui/apps/onboarding/components/Page.tsx new file mode 100644 index 0000000..7b52ecb --- /dev/null +++ b/ui/apps/onboarding/components/Page.tsx @@ -0,0 +1,45 @@ +import { Link } from "react-router-dom"; + +export default function Page({ + heading, + content, + start, + skip, + next, + back, + getStarted, +}) { + return ( +
+

{heading}

+

{content}

+
+ {start && ( + + + + )} + {skip && ( + + + + )} + {back && ( + + + + )} + {next && ( + + + + )} + {getStarted && ( + + + + )} +
+
+ ); +} diff --git a/ui/onboarding.js b/ui/onboarding.js index 4d824af..fef617a 100644 --- a/ui/onboarding.js +++ b/ui/onboarding.js @@ -1,7 +1,8 @@ -import Onboarding from './components/onboarding/Onboarding.svelte' +import { createRoot } from "react-dom"; +import React from "react"; -const app = new Onboarding({ - target: document.getElementById('app'), -}) +import App from "./apps/onboarding/App.tsx"; -export default app +const root = createRoot(document.getElementById("app")); + +root.render(React.createElement(App));