refactor: move onboarding app to react
This commit is contained in:
parent
06145abfa4
commit
15f7534995
|
@ -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",
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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: <Content />,
|
||||
handle: {
|
||||
page: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const router = createHashRouter([{ ...rootRoute, children: childRoutes }]);
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<header>
|
||||
<img src={lumeLogo} alt="Lume" />
|
||||
</header>
|
||||
<RouterProvider router={router} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<main className={classNames({ started: handle.page > 0 })}>
|
||||
{Array(contentPages.length)
|
||||
.fill(0)
|
||||
.map((_, index) => (
|
||||
<div
|
||||
className={classNames("art", `art-${index + 1}`, {
|
||||
visible: handle.page === index,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
|
||||
<div className="content">
|
||||
<div>
|
||||
<Page
|
||||
heading={contentPages[handle.page].heading}
|
||||
content={contentPages[handle.page].content}
|
||||
start={start}
|
||||
skip={skip}
|
||||
back={back}
|
||||
next={next}
|
||||
getStarted={getStarted}
|
||||
/>
|
||||
</div>
|
||||
<GrantInfo />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
function GrantInfo() {
|
||||
return (
|
||||
<div className="grant-info">
|
||||
Lume is a 503c Grant recipient,
|
||||
<a href="https://lumeweb.com">learn more</a> about the work we’re doing to
|
||||
provide accessible access to the open web for everyone.
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { Link } from "react-router-dom";
|
||||
|
||||
export default function Page({
|
||||
heading,
|
||||
content,
|
||||
start,
|
||||
skip,
|
||||
next,
|
||||
back,
|
||||
getStarted,
|
||||
}) {
|
||||
return (
|
||||
<div className="page">
|
||||
<h1>{heading}</h1>
|
||||
<p>{content}</p>
|
||||
<div className="btn-wrapper">
|
||||
{start && (
|
||||
<Link to={start}>
|
||||
<button className="btn-main">Begin</button>
|
||||
</Link>
|
||||
)}
|
||||
{skip && (
|
||||
<a href={skip} className="btn-main btn-black">
|
||||
<button>Skip</button>
|
||||
</a>
|
||||
)}
|
||||
{back && (
|
||||
<Link to={back} className="btn-main btn-black">
|
||||
<button>Back</button>
|
||||
</Link>
|
||||
)}
|
||||
{next && (
|
||||
<Link to={next} className="btn-main">
|
||||
<button>Next</button>
|
||||
</Link>
|
||||
)}
|
||||
{getStarted && (
|
||||
<a href={getStarted} className="btn-main btn-green">
|
||||
<button>Get started</button>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -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));
|
||||
|
|
Reference in New Issue