@aioha/react-ui
Version:
Ready-made React modal for Aioha
68 lines (67 loc) • 4.68 kB
JavaScript
import React, { useEffect, useRef, useState } from 'react';
import { useAioha } from '@aioha/providers/react';
import { ErrorAlert } from './ErrorAlert.js';
import { BackButton } from './BackButton.js';
import { SpinningIcon } from '../Icons.js';
import { RightAngledArrow } from '../TableUtils.js';
export const AccountDiscovery = ({ provider, options, onPrevious, onNext }) => {
const { aioha } = useAioha();
const discovering = useRef(false);
const stopDiscovery = useRef(() => { });
const discovered = useRef({});
const [completed, setCompleted] = useState(false);
const [count, setCount] = useState(0);
const [error, setError] = useState();
const [isPrompt, showPrompt] = useState(false);
useEffect(() => {
const discover = async () => {
if (discovering.current)
return;
discovering.current = true;
const result = await aioha.discoverAccounts(provider, (disc, stop) => {
stopDiscovery.current = stop;
const d = {
pubkey: disc.pubkey,
path: disc.path,
role: disc.role
};
if (!discovered.current[disc.username]) {
discovered.current[disc.username] = [d];
}
else if (!discovered.current[disc.username].find((a) => a.role === d.role)) {
discovered.current[disc.username].push(d);
}
setCount((c) => c + 1);
}, options);
setCompleted(true);
if (!result.success) {
setError(result.error);
}
};
discover();
}, []);
const userSelected = (user) => {
showPrompt(true);
onNext(user, discovered.current[user]);
};
if (isPrompt)
return (React.createElement("div", { className: "flex-col gap-20 my-3" },
React.createElement("svg", { className: "w-20 h-20 ml-auto mr-auto text-gray-900 dark:text-gray-100", "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" },
React.createElement("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M6 15h12M6 6h12m-6 12h.01M7 21h10a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1Z" })),
React.createElement("div", { className: "text-lg my-3 text-gray-900 dark:text-gray-100 text-center" }, "Please approve login request on the device.")));
return (React.createElement("div", { className: "flex-col gap-3" },
React.createElement("div", { className: "mb-3 w-full" },
React.createElement(BackButton, { onPrevious: onPrevious })),
!!error && React.createElement(ErrorAlert, { error: error }),
Object.keys(discovered.current).length > 0 && (React.createElement("div", { className: "w-full overflow-x-auto" },
React.createElement("table", { className: "min-w-full divide-y divide-gray-200 dark:divide-gray-600" },
React.createElement("tbody", { className: "bg-white divide-y divide-gray-200 dark:bg-gray-700 dark:divide-gray-600" }, Object.entries(discovered.current).map(([username, auths]) => (React.createElement("tr", { key: username, className: "hover:bg-gray-50 dark:hover:bg-gray-600 cursor-pointer", onClick: () => userSelected(username) },
React.createElement("td", { className: "px-3 py-4 whitespace-nowrap" },
React.createElement("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100" }, username)),
React.createElement("td", { className: "px-3 py-4 whitespace-nowrap" },
React.createElement("div", { className: "flex flex-wrap gap-2" }, auths.map((auth, index) => (React.createElement("span", { key: index, className: "px-2 inline-flex text-xs leading-5 font-semplify rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200" }, auth.role))))),
React.createElement(RightAngledArrow, null)))))))),
!completed ? (React.createElement("button", { type: "button", className: "flex gap-2 items-center justify-center mt-3 ml-auto mr-auto text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 enabled:hover:cursor-pointer disabled:hover:cursor-not-allowed", onClick: stopDiscovery.current, disabled: count === 0 },
React.createElement(SpinningIcon, { size: 5 }),
"Stop")) : null));
};