Updated register UI (#300)

This commit is contained in:
OdinsBadEye 2024-04-05 15:09:35 +01:00 committed by Tobias Merkle
parent 7c05d3568d
commit a497d886df
10 changed files with 283 additions and 99 deletions

View File

@ -1,7 +1,7 @@
{
"files": {
"main.css": "/static/css/main.eb8419e6.css",
"main.js": "/static/js/main.7fd4ad77.js",
"main.css": "/static/css/main.6c087b1c.css",
"main.js": "/static/js/main.48b36a2c.js",
"static/media/OpenSans-CondBold.ttf": "/static/media/OpenSans-CondBold.6293057f8484b6c0da03.ttf",
"static/media/BarlowCondensed-Black.ttf": "/static/media/BarlowCondensed-Black.3ba02bbdeb04e17f34bf.ttf",
"static/media/Futura-Heavy.ttf": "/static/media/Futura-Heavy.af72c25a6945b0f48abb.ttf",
@ -11,7 +11,7 @@
"static/media/kinode.svg": "/static/media/kinode.6b178bc9164b31d90099844a82d04497.svg"
},
"entrypoints": [
"static/css/main.eb8419e6.css",
"static/js/main.7fd4ad77.js"
"static/css/main.6c087b1c.css",
"static/js/main.48b36a2c.js"
]
}

View File

@ -1 +1,27 @@
<!doctype html><html lang="en"><head><title>Welcome - Kinode</title><meta charset="utf-8"/><meta http-equiv="pragma" content="no-cache"/><meta http-equiv="cache-control" content="no-cache"/><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"><link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc5IiBoZWlnaHQ9IjUxNCIgdmlld0JveD0iMCAwIDc3OSA1MTQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8c3R5bGU+CiAgICAgICAgQG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgewogICAgICAgICAgICBzdmcgeyBmaWxsOiB3aGl0ZTsgfQogICAgICAgIH0KICAgICAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkgewogICAgICAgICAgICBzdmcgeyBmaWxsOiBibGFjazsgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8cGF0aCBkPSJNNzUzLjA5MiA1LjkxOTMyQzc1Ni41NTcgNS4wOTk3NiA3NTUuOTYyIC0wLjAwMDEyMjA3IDc1Mi40MDEgLTAuMDAwMTIyMDdINDI2LjAwMUM0MjQuNzU1IC0wLjAwMDEyMjA3IDQyMy42MzkgMC43NzAyNyA0MjMuMTk3IDEuOTM1MzVMMjM2Ljk2OCA0OTIuNkMyMzUuNzI5IDQ5NS44NjUgMjQwLjEyMyA0OTguMjU1IDI0Mi4xOTEgNDk1LjQ0MUw1NjkuMzU3IDUwLjExMzJDNTY5Ljc3OCA0OS41MzkyIDU3MC4zOTEgNDkuMTMzOSA1NzEuMDg0IDQ4Ljk3TDc1My4wOTIgNS45MTkzMloiLz4KICAgIDxwYXRoIGQ9Ik0xMS45NjY1IDQwLjIyODhDOS4xMDk0OSAzOC43NzcgMTAuMjEzNSAzNC40NTgzIDEzLjQxNjcgMzQuNTU1N0w0MDQuMjczIDQ2LjQzNjdDNDA2LjMzNCA0Ni40OTkzIDQwNy43MTkgNDguNTc0OSA0MDYuOTg2IDUwLjUwMjNMMzQ3LjQzOCAyMDYuOTgxQzM0Ni44MDQgMjA4LjY0NyAzNDQuODY1IDIwOS4zOTYgMzQzLjI3NSAyMDguNTg4TDExLjk2NjUgNDAuMjI4OFoiLz4KPC9zdmc+Cg=="><meta httpequiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"/><script defer="defer" src="/static/js/main.7fd4ad77.js"></script><link href="/static/css/main.eb8419e6.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html>
<html lang="en">
<head>
<title>Welcome - Kinode</title>
<meta charset="utf-8" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet">
<link rel="icon"
href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc5IiBoZWlnaHQ9IjUxNCIgdmlld0JveD0iMCAwIDc3OSA1MTQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8c3R5bGU+CiAgICAgICAgQG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgewogICAgICAgICAgICBzdmcgeyBmaWxsOiB3aGl0ZTsgfQogICAgICAgIH0KICAgICAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkgewogICAgICAgICAgICBzdmcgeyBmaWxsOiBibGFjazsgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8cGF0aCBkPSJNNzUzLjA5MiA1LjkxOTMyQzc1Ni41NTcgNS4wOTk3NiA3NTUuOTYyIC0wLjAwMDEyMjA3IDc1Mi40MDEgLTAuMDAwMTIyMDdINDI2LjAwMUM0MjQuNzU1IC0wLjAwMDEyMjA3IDQyMy42MzkgMC43NzAyNyA0MjMuMTk3IDEuOTM1MzVMMjM2Ljk2OCA0OTIuNkMyMzUuNzI5IDQ5NS44NjUgMjQwLjEyMyA0OTguMjU1IDI0Mi4xOTEgNDk1LjQ0MUw1NjkuMzU3IDUwLjExMzJDNTY5Ljc3OCA0OS41MzkyIDU3MC4zOTEgNDkuMTMzOSA1NzEuMDg0IDQ4Ljk3TDc1My4wOTIgNS45MTkzMloiLz4KICAgIDxwYXRoIGQ9Ik0xMS45NjY1IDQwLjIyODhDOS4xMDk0OSAzOC43NzcgMTAuMjEzNSAzNC40NTgzIDEzLjQxNjcgMzQuNTU1N0w0MDQuMjczIDQ2LjQzNjdDNDA2LjMzNCA0Ni40OTkzIDQwNy43MTkgNDguNTc0OSA0MDYuOTg2IDUwLjUwMjNMMzQ3LjQzOCAyMDYuOTgxQzM0Ni44MDQgMjA4LjY0NyAzNDQuODY1IDIwOS4zOTYgMzQzLjI3NSAyMDguNTg4TDExLjk2NjUgNDAuMjI4OFoiLz4KPC9zdmc+Cg==">
<meta httpequiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover" />
<script defer="defer" src="/static/js/main.7fd4ad77.js"></script>
<link href="/static/css/main.eb8419e6.css" rel="stylesheet">
</head>
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,143 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*!
Copyright (c) 2015 Jed Watson.
Based on code that is Copyright 2013-2015, Facebook, Inc.
All rights reserved.
*/
/*!
* Adapted from jQuery UI core
*
* http://jqueryui.com
*
* Copyright 2014 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/ui-core/
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim/with-selector.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @remix-run/router v1.15.3
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router DOM v6.22.3
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router v6.22.3
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* [js-sha3]{@link https://github.com/emn178/js-sha3}
*
* @version 0.5.7
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2015-2016
* @license MIT
*/
/**
* [js-sha3]{@link https://github.com/emn178/js-sha3}
*
* @version 0.8.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2015-2018
* @license MIT
*/

File diff suppressed because one or more lines are too long

View File

@ -1,25 +1,23 @@
import React, { useEffect, useRef } from "react";
import { hooks } from "../connectors/metamask";
import { DotOsRegistrar } from "../abis/types";
import isValidDomain from 'is-valid-domain'
import { hash } from 'eth-ens-namehash'
import { toAscii } from 'idna-uts46-hx'
import isValidDomain from "is-valid-domain";
import { hash } from "eth-ens-namehash";
import { toAscii } from "idna-uts46-hx";
global.Buffer = global.Buffer || require('buffer').Buffer;
global.Buffer = global.Buffer || require("buffer").Buffer;
const {
useChainId,
useProvider,
} = hooks;
const { useChainId, useProvider } = hooks;
type ClaimOsNameProps = {
name: string,
setName: React.Dispatch<React.SetStateAction<string>>
nameValidities: string[],
setNameValidities: React.Dispatch<React.SetStateAction<string[]>>,
dotOs: DotOsRegistrar,
triggerNameCheck: boolean
}
name: string;
setName: React.Dispatch<React.SetStateAction<string>>;
nameValidities: string[];
setNameValidities: React.Dispatch<React.SetStateAction<string[]>>;
dotOs: DotOsRegistrar;
triggerNameCheck: boolean;
isReset?: boolean;
};
function EnterKnsName({
name,
@ -27,67 +25,65 @@ function EnterKnsName({
nameValidities,
setNameValidities,
dotOs,
triggerNameCheck
triggerNameCheck,
isReset = false,
}: ClaimOsNameProps) {
const NAME_URL =
"Name must be a valid URL without subdomains (A-Z, a-z, 0-9, and punycode)";
const NAME_LENGTH = "Name must be 9 characters or more";
const NAME_CLAIMED = "Name is already claimed";
const NAME_INVALID_PUNY = "Unsupported punycode character";
const NAME_URL = "Name must be a valid URL without subdomains (A-Z, a-z, 0-9, and punycode)"
const NAME_LENGTH = "Name must be 9 characters or more"
const NAME_CLAIMED = "Name is already claimed"
const NAME_INVALID_PUNY = "Unsupported punycode character"
const debouncer = useRef<NodeJS.Timeout | null>(null)
const debouncer = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
if (isReset) return;
if (debouncer.current)
clearTimeout(debouncer.current);
if (debouncer.current) clearTimeout(debouncer.current);
debouncer.current = setTimeout(async () => {
let index: number;
let validities = [...nameValidities];
let index: number
let validities = [...nameValidities]
const len = [...name].length;
index = validities.indexOf(NAME_LENGTH);
if (len < 9 && len !== 0) {
if (index === -1) validities.push(NAME_LENGTH);
} else if (index !== -1) validities.splice(index, 1);
const len = [...name].length
index = validities.indexOf(NAME_LENGTH)
if (len < 9 && len != 0) {
if (index == -1) validities.push(NAME_LENGTH)
} else if (index != -1) validities.splice(index, 1)
let normalized: string
index = validities.indexOf(NAME_INVALID_PUNY)
let normalized: string;
index = validities.indexOf(NAME_INVALID_PUNY);
try {
normalized = toAscii(name + ".os")
if (index != -1) validities.splice(index, 1)
normalized = toAscii(name + ".os");
if (index !== -1) validities.splice(index, 1);
} catch (e) {
if (index == -1) validities.push(NAME_INVALID_PUNY)
if (index === -1) validities.push(NAME_INVALID_PUNY);
}
// only check if name is valid punycode
if (normalized! !== undefined) {
index = validities.indexOf(NAME_URL);
if (name !== "" && !isValidDomain(normalized)) {
if (index === -1) validities.push(NAME_URL);
} else if (index !== -1) validities.splice(index, 1);
index = validities.indexOf(NAME_URL)
if (name != "" && !isValidDomain(normalized)) {
if (index == -1) validities.push(NAME_URL)
} else if (index != -1) validities.splice(index, 1)
index = validities.indexOf(NAME_CLAIMED)
if (validities.length == 0 || index != -1) {
index = validities.indexOf(NAME_CLAIMED);
if (validities.length === 0 || index !== -1) {
try {
await dotOs.ownerOf(hash(normalized))
if (index == -1) validities.push(NAME_CLAIMED)
await dotOs.ownerOf(hash(normalized));
if (index === -1) validities.push(NAME_CLAIMED);
} catch (e) {
if (index != -1) validities.splice(index, 1)
if (index !== -1) validities.splice(index, 1);
}
}
}
setNameValidities(validities)
setNameValidities(validities);
}, 500);
}, [name, triggerNameCheck, isReset]);
}, 500)
}, [name, triggerNameCheck])
const noDots = (e: any) => e.target.value.indexOf('.') == -1
&& setName(e.target.value)
const noDots = (e: any) =>
e.target.value.indexOf(".") === -1 && setName(e.target.value);
return (
<div className="flex flex-col w-full place-items-center place-content-center">
@ -103,10 +99,14 @@ function EnterKnsName({
/>
<div className="ml-2 text-lg">.os</div>
</div>
{nameValidities.map((x, i) => <div key={i}><br /><span className="text-red-500">{x}</span></div>)}
{nameValidities.map((x, i) => (
<div key={i}>
<br />
<span className="text-red-500">{x}</span>
</div>
))}
</div>
)
);
}
export default EnterKnsName;

View File

@ -13,7 +13,7 @@ export const Tooltip: React.FC<TooltipProps> = ({ text, button, className, posit
const [showTooltip, setShowTooltip] = useState(false)
return <div className={classNames("flex place-items-center place-content-center text-sm relative cursor-pointer shrink", className)}>
<div onClick={() => setShowTooltip(!showTooltip)}>
{button || <button
{button || <button
className="icon ml-4"
type='button'
>
@ -30,7 +30,7 @@ export const Tooltip: React.FC<TooltipProps> = ({ text, button, className, posit
})}>
{text}
</div>
<button className={classNames("absolute bg-black icon right-0 top-0", {
<button type="button" className={classNames("absolute bg-black icon right-0 top-0", {
"hidden": !showTooltip,
})} onClick={() => setShowTooltip(false)}>
<FaX />

View File

@ -1093,4 +1093,4 @@ button:disabled {
width: 3rem;
--tw-grayscale: grayscale(100%);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
}

View File

@ -16,9 +16,7 @@ import KinodeHeader from "../components/KnsHeader";
import { NetworkingInfo, PageProps } from "../lib/types";
import { ipToNumber } from "../utils/ipToNumber";
import { getNetworkName, setChain } from "../utils/chain";
import { ReactComponent as NameLogo } from "../assets/kinode.svg"
import { Tooltip } from "../components/Tooltip";
import { DirectTooltip } from "../components/DirectTooltip";
import DirectCheckbox from "../components/DirectCheckbox";
import EnterKnsName from "../components/EnterKnsName";
import { KinodeTitle } from "../components/KinodeTitle";
@ -231,7 +229,7 @@ function Reset({
Choose a name for your kinode
<Tooltip text={`Kinodes use a .os name in order to identify themselves to other nodes in the network.`} />
</label>
<EnterKnsName {...{ name, setName, nameVets, dotOs, triggerNameCheck, nameValidities, setNameValidities }} />
<EnterKnsName {...{ name, setName, nameVets, dotOs, triggerNameCheck, nameValidities, setNameValidities, isReset: true }} />
</h3>
<DirectCheckbox {...{ direct, setDirect }} />

View File

@ -97,6 +97,7 @@ function SetPassword({
res.status < 300 &&
Number(res.headers.get("content-length")) !== appSizeOnLoad
) {
console.log("WE GOOD, ROUTING")
clearInterval(interval);
window.location.replace("/");
}
@ -121,40 +122,44 @@ function SetPassword({
{loading ? (
<Loader msg="Setting up node..." />
) : (
<form id="signup-form" className="flex flex-col max-w-[450px] w-full" onSubmit={handleSubmit}>
<div className="w-full flex flex-col">
<div className="flex self-stretch mb-2 place-items-center">
<label htmlFor="password">New Password</label>
<Tooltip text="This password will be used to log in if you restart your node or switch browsers." />
<form id="signup-form" className="flex flex-col w-full max-w-[450px] gap-4" onSubmit={handleSubmit}>
<div className="flex flex-col w-full place-items-center place-content-center">
<div className="flex w-full place-items-center mb-2">
<label className="flex leading-6 place-items-center mt-2 cursor-pointer mb-2" style={{ fontSize: 20 }} htmlFor="password">New Password</label>
<Tooltip text={`This password will be used to log in if you restart your node or switch browsers.`} />
</div>
<div className="flex w-full place-items-center">
<input
className="grow"
type="password"
id="password"
required
minLength={6}
name="password"
placeholder="Min 6 characters"
value={pw}
onChange={(e) => setPw(e.target.value)}
autoFocus
/>
</div>
<input
type="password"
id="password"
required
minLength={6}
name="password"
placeholder="Min 6 characters"
value={pw}
onChange={(e) => setPw(e.target.value)}
autoFocus
className="mb-2 self-stretch"
/>
</div>
<div className="w-full flex flex-col mb-2">
<div className="flex">
<label htmlFor="confirm-password">Confirm Password</label>
<div className="flex flex-col w-full place-items-center place-content-center">
<div className="flex w-full place-items-center">
<label className="flex leading-6 place-items-center mt-2 cursor-pointer mb-4" style={{ fontSize: 20 }} htmlFor="confirm-password">Confirm Password</label>
</div>
<div className="flex w-full place-items-center">
<input
className="grow"
type="password"
id="confirm-password"
required
minLength={6}
name="confirm-password"
placeholder="Min 6 characters"
value={pw2}
onChange={(e) => setPw2(e.target.value)}
/>
</div>
<input
type="password"
id="confirm-password"
required
minLength={6}
name="confirm-password"
placeholder="Min 6 characters"
value={pw2}
onChange={(e) => setPw2(e.target.value)}
className="mb-2 self-stretch"
/>
{Boolean(error) && <p style={{ color: "red" }}>{error}</p>}
</div>
<button type="submit">Submit</button>