feat: add basic settings page

This commit is contained in:
Roland Bewick
2023-08-26 22:26:49 +07:00
parent 7cba67e4c1
commit afd3c9a232
10 changed files with 270 additions and 3 deletions

View File

@ -5,9 +5,10 @@ import { Icon } from "./icon";
export interface CopyProps {
text: string;
maxSize?: number;
hideText?: boolean;
className?: string;
}
export default function Copy({ text, maxSize = 32, className }: CopyProps) {
export default function Copy({ text, maxSize = 32, className, hideText }: CopyProps) {
const { copy, copied } = useCopy();
const sliceLength = maxSize / 2;
const trimmed =
@ -20,7 +21,7 @@ export default function Copy({ text, maxSize = 32, className }: CopyProps) {
className={`copy${className ? ` ${className}` : ""}`}
onClick={() => copy(text)}
>
<span className="body">{trimmed}</span>
{!hideText && <span className="body">{trimmed}</span>}
<span
className="icon"
style={{ color: copied ? "var(--success)" : "var(--highlight)" }}

View File

@ -11,6 +11,7 @@ import Copy from "./copy";
import { hexToBech32, openFile } from "utils";
import { VoidApi } from "@void-cat/api";
import { LoginType } from "login";
import { bech32 } from "@scure/base";
enum Stage {
Login = 0,
@ -41,6 +42,26 @@ export function LoginSignup({ close }: { close: () => void }) {
}
}
}
function doLoginNsec() {
try {
const nsec = prompt("nsec");
if (!nsec) {
throw new Error("no nsec provided");
}
const {words} = bech32.decode(nsec, 5000);
const data = new Uint8Array(bech32.fromWords(words));
Login.loginWithPrivateKey(bytesToHex(data));
close();
} catch (e) {
console.error(e);
if (e instanceof Error) {
setError(e.message);
} else {
setError(e as string);
}
}
}
function createAccount() {
const newKey = bytesToHex(schnorr.utils.randomPrivateKey());
@ -108,6 +129,13 @@ export function LoginSignup({ close }: { close: () => void }) {
>
Create Account
</button>
<button
type="button"
className="btn btn-primary"
onClick={doLoginNsec}
>
Enter Nsec (INSECURE)
</button>
{error && <b className="error">{error}</b>}
</>
);

View File

@ -17,6 +17,7 @@ import { LoginStore } from "login";
import { StreamProvidersPage } from "pages/providers";
import { defaultRelays } from "const";
import { CatchAllRoutePage } from "pages/catch-all";
import { SettingsPage } from "pages/settings-page";
export enum StreamState {
Live = "live",
@ -60,6 +61,10 @@ const router = createBrowserRouter([
path: "/providers/:id?",
element: <StreamProvidersPage />,
},
{
path: "/settings",
element: <SettingsPage />,
},
{
path: "*",
element: <CatchAllRoutePage />,

View File

@ -48,6 +48,10 @@ export function LayoutPage() {
<Icon name="user" size={24} />
Profile
</MenuItem>
<MenuItem onClick={() => navigate("/settings")}>
<Icon name="settings" size={24} />
Settings
</MenuItem>
<MenuItem onClick={() => Login.logout()}>
<Icon name="logout" size={24} />
Logout

View File

@ -0,0 +1,16 @@
.profile-page {
display: flex;
justify-content: center;
}
.public-key {
display: flex;
align-items: center;
gap: 8px;
}
.private-key {
display: flex;
align-items: center;
gap: 8px;
}

View File

@ -0,0 +1,36 @@
import { useLogin } from "hooks/login";
import { useNavigate } from "react-router-dom";
import "./settings-page.css";
import React from "react";
import { Button } from "@getalby/bitcoin-connect-react";
import Copy from "element/copy";
export function SettingsPage() {
const navigate = useNavigate();
const login = useLogin();
React.useEffect(() => {
if (!login) {
navigate("/");
}
}, [login])
return (
<div className="settings-page">
<h1>Account</h1>
{login?.pubkey && <div className="public-key">
<p>Logged in as</p>
<Copy text={login?.pubkey} maxSize={64} />
</div>}
{login?.privateKey && <div className="private-key">
<p>Private key</p>
<Copy text={login.privateKey} hideText />
</div>}
<h1>Zaps</h1>
<Button/>
</div>
);
}