mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2026-01-19 22:24:27 +01:00
backup and restore prompts
This commit is contained in:
@@ -6,6 +6,7 @@ import ReloadPrompt from "~/components/Reload";
|
||||
import { A } from 'solid-start';
|
||||
import { Activity } from './Activity';
|
||||
import settings from '~/assets/icons/settings.svg';
|
||||
import { OnboardWarning } from './OnboardWarning';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
@@ -16,6 +17,7 @@ export default function App() {
|
||||
<img src={logo} class="h-10" alt="logo" />
|
||||
<A class="md:hidden p-2 hover:bg-white/5 rounded-lg active:bg-m-blue" href="/settings"><img src={settings} alt="Settings" /></A>
|
||||
</header>
|
||||
<OnboardWarning />
|
||||
<ReloadPrompt />
|
||||
<BalanceBox />
|
||||
<Activity />
|
||||
|
||||
@@ -17,54 +17,26 @@ function SyncingIndicator() {
|
||||
}
|
||||
|
||||
export default function BalanceBox() {
|
||||
const [state, _] = useMegaStore();
|
||||
|
||||
const fetchOnchainBalance = async () => {
|
||||
console.log("Refetching onchain balance");
|
||||
await state.node_manager?.sync();
|
||||
const balance = await state.node_manager?.get_balance();
|
||||
return balance
|
||||
};
|
||||
|
||||
// TODO: it's hacky to do these separately, but ln doesn't need the sync so I don't want to wait
|
||||
const fetchLnBalance = async () => {
|
||||
console.log("Refetching ln balance");
|
||||
const balance = await state.node_manager?.get_balance();
|
||||
return balance
|
||||
};
|
||||
|
||||
const [onChainBalance, { refetch: refetchOnChainBalance }] = createResource(fetchOnchainBalance);
|
||||
const [lnBalance, { refetch: refetchLnBalance }] = createResource(fetchLnBalance);
|
||||
|
||||
function refetchBalance() {
|
||||
refetchLnBalance();
|
||||
refetchOnChainBalance();
|
||||
}
|
||||
const [state, actions] = useMegaStore();
|
||||
|
||||
return (
|
||||
<>
|
||||
<FancyCard title="Lightning">
|
||||
<Suspense fallback={<Amount amountSats={0} showFiat loading={true} />}>
|
||||
<Show when={lnBalance()}>
|
||||
<Amount amountSats={lnBalance()?.lightning} showFiat />
|
||||
</Show>
|
||||
</Suspense>
|
||||
<Amount amountSats={state.balance?.lightning || 0} showFiat />
|
||||
</FancyCard>
|
||||
|
||||
<FancyCard title="On-Chain" tag={onChainBalance.loading && <SyncingIndicator />}>
|
||||
<Suspense fallback={<Amount amountSats={0} showFiat loading={true} />}>
|
||||
<div onClick={refetchBalance}>
|
||||
<Amount amountSats={onChainBalance()?.confirmed} showFiat loading={onChainBalance.loading} />
|
||||
</div>
|
||||
</Suspense>
|
||||
<FancyCard title="On-Chain" tag={state.is_syncing && <SyncingIndicator />}>
|
||||
<div onClick={actions.sync}>
|
||||
<Amount amountSats={state.balance?.confirmed} showFiat />
|
||||
</div>
|
||||
<Suspense>
|
||||
<Show when={onChainBalance()?.unconfirmed}>
|
||||
<Show when={state.balance?.unconfirmed}>
|
||||
<div class="flex flex-col gap-2">
|
||||
<header class='text-sm font-semibold uppercase text-white/50'>
|
||||
Unconfirmed Balance
|
||||
</header>
|
||||
<div class="text-white/50">
|
||||
{prettyPrintAmount(onChainBalance()?.unconfirmed)} <span class='text-sm'>SATS</span>
|
||||
{prettyPrintAmount(state.balance?.unconfirmed)} <span class='text-sm'>SATS</span>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
48
src/components/OnboardWarning.tsx
Normal file
48
src/components/OnboardWarning.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Show, createSignal, onMount } from "solid-js";
|
||||
import { Button, ButtonLink, SmallHeader, VStack } from "./layout";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function OnboardWarning() {
|
||||
const [state, actions] = useMegaStore();
|
||||
const [dismissedBackup, setDismissedBackup] = createSignal(false);
|
||||
|
||||
onMount(() => {
|
||||
actions.sync()
|
||||
})
|
||||
|
||||
function hasMoney() {
|
||||
return state.balance?.confirmed || state.balance?.lightning || state.balance?.unconfirmed
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* TODO: show this once we have a restore flow */}
|
||||
<Show when={!state.dismissed_restore_prompt && false}>
|
||||
<div class='rounded-xl p-4 flex flex-col gap-2 bg-neutral-950 overflow-x-hidden'>
|
||||
<SmallHeader>Welcome!</SmallHeader>
|
||||
<VStack>
|
||||
<p class="text-2xl font-light">
|
||||
Do you want to restore an existing Mutiny Wallet?
|
||||
</p>
|
||||
<div class="w-full flex gap-2">
|
||||
<Button intent="green" onClick={() => { }}>Restore</Button>
|
||||
<Button onClick={actions.dismissRestorePrompt}>Nope</Button>
|
||||
</div>
|
||||
</VStack>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={!state.has_backed_up && hasMoney() && !dismissedBackup()}>
|
||||
<div class='rounded-xl p-4 flex flex-col gap-2 bg-neutral-950 overflow-x-hidden'>
|
||||
<SmallHeader>Secure your funds</SmallHeader>
|
||||
<p class="text-2xl font-light">
|
||||
You have money stored in this browser. Let's make sure you have a backup.
|
||||
</p>
|
||||
<div class="w-full flex gap-2">
|
||||
<ButtonLink intent="blue" href="/backup">Backup</ButtonLink>
|
||||
<Button onClick={() => { setDismissedBackup(true) }}>Nope</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,27 +1,36 @@
|
||||
import { Match, Switch, createSignal } from "solid-js"
|
||||
import { For, Match, Switch, createMemo, createSignal } from "solid-js"
|
||||
|
||||
export function SeedWords(props: { words: string }) {
|
||||
export function SeedWords(props: { words: string, setHasSeen?: (hasSeen: boolean) => void }) {
|
||||
const [shouldShow, setShouldShow] = createSignal(false)
|
||||
|
||||
function toggleShow() {
|
||||
setShouldShow(!shouldShow())
|
||||
if (shouldShow()) {
|
||||
props.setHasSeen?.(true)
|
||||
}
|
||||
}
|
||||
|
||||
return (<pre class="flex items-center gap-4 bg-m-red p-4 rounded-xl overflow-hidden">
|
||||
const splitWords = createMemo(() => props.words.split(" "))
|
||||
|
||||
return (<button class="flex items-center gap-4 bg-m-red p-4 rounded-xl overflow-hidden" onClick={toggleShow}>
|
||||
<Switch>
|
||||
<Match when={!shouldShow()}>
|
||||
<div onClick={toggleShow} class="cursor-pointer">
|
||||
<div class="cursor-pointer">
|
||||
<code class="text-red">TAP TO REVEAL SEED WORDS</code>
|
||||
</div>
|
||||
</Match>
|
||||
|
||||
<Match when={shouldShow()}>
|
||||
<div onClick={toggleShow} class="cursor-pointer overflow-hidden">
|
||||
<p class="font-mono w-full whitespace-pre-wrap">
|
||||
{props.words}
|
||||
</p>
|
||||
</div>
|
||||
<ol class="cursor-pointer overflow-hidden grid grid-cols-2 w-full list-decimal list-inside">
|
||||
<For each={splitWords()}>
|
||||
{(word) => (
|
||||
<li class="font-mono text-left">
|
||||
{word}
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ol>
|
||||
</Match>
|
||||
</Switch>
|
||||
</pre >)
|
||||
</button >)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export function ToastItem(props: { toastId: number, title: string, description:
|
||||
return (
|
||||
<Toast.Root toastId={props.toastId} class={`w-[80vw] max-w-[400px] mx-auto p-4 bg-neutral-900/80 backdrop-blur-md shadow-xl rounded-xl border ${props.isError ? "border-m-red/50" : "border-white/10"} `}>
|
||||
<div class="flex gap-4 w-full justify-between items-start">
|
||||
<div>
|
||||
<div class="flex-1">
|
||||
<Toast.Title>
|
||||
<SmallHeader>
|
||||
{props.title}
|
||||
@@ -43,7 +43,7 @@ export function ToastItem(props: { toastId: number, title: string, description:
|
||||
</p>
|
||||
</Toast.Description>
|
||||
</div>
|
||||
<Toast.CloseButton class="hover:bg-white/10 rounded-lg active:bg-m-blue w-[5rem]">
|
||||
<Toast.CloseButton class="hover:bg-white/10 rounded-lg active:bg-m-blue w-[5rem] flex-0">
|
||||
<img src={close} alt="Close" />
|
||||
</Toast.CloseButton>
|
||||
</div>
|
||||
|
||||
@@ -103,6 +103,10 @@ const SmallAmount: ParentComponent<{ amount: number | bigint }> = (props) => {
|
||||
return (<h2 class="font-light text-lg">{props.amount.toLocaleString()} <span class="text-sm">SATS</span></h2>)
|
||||
}
|
||||
|
||||
export const NiceP: ParentComponent = (props) => {
|
||||
return (<p class="text-2xl font-light">{props.children}</p>)
|
||||
}
|
||||
|
||||
export {
|
||||
SmallHeader,
|
||||
Card,
|
||||
|
||||
Reference in New Issue
Block a user