mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2026-02-09 08:14:28 +01:00
pick a federation on setup
This commit is contained in:
10
e2e/utils.ts
10
e2e/utils.ts
@@ -13,10 +13,14 @@ export async function loadHome(page: Page) {
|
||||
|
||||
await page.locator("button:has-text('Skip for now')").click();
|
||||
|
||||
await page.getByText("Pick a Federation").waitFor();
|
||||
|
||||
await page.locator("button:has-text('Skip for now')").click();
|
||||
|
||||
await page.locator(`button:has-text('Confirm')`).click();
|
||||
|
||||
// Should have a balance up top now
|
||||
await page.locator(`text=0 sats`).first();
|
||||
// Status light should be ready
|
||||
await page.locator(`title="READY"`).first();
|
||||
await page.locator(`text=0 sats`).first().waitFor();
|
||||
}
|
||||
|
||||
export async function visitSettings(page: Page) {
|
||||
|
||||
@@ -551,13 +551,14 @@
|
||||
"remove": "Remove",
|
||||
"expires": "Expires",
|
||||
"federation_id": "Federation ID",
|
||||
"description": "Mutiny has experimental support for the Fedimint protocol. Store funds in a federation at your own risk!",
|
||||
"learn_more": "Learn more about Fedimint.",
|
||||
"description": "Federations are bitcoin-based networks that make it cheaper, quicker, and easier to use bitcoin.",
|
||||
"learn_more": "Learn more",
|
||||
"discover": "Discover Federations",
|
||||
"manual": "Invite Code",
|
||||
"created_at": "Created At",
|
||||
"recommended_by": "Recommended By",
|
||||
"already_in_fed": "You're already in a federation!"
|
||||
"already_in_fed": "You're already in a federation!",
|
||||
"descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below."
|
||||
},
|
||||
"gift": {
|
||||
"give_sats_link": "Give sats as a gift",
|
||||
@@ -743,13 +744,18 @@
|
||||
},
|
||||
"setup": {
|
||||
"new_profile": {
|
||||
"description": "Mutiny makes payments social."
|
||||
"description": "Mutiny makes payments social.",
|
||||
"title": "Create your profile"
|
||||
},
|
||||
"skip": "Skip for now",
|
||||
"import_profile": "Import existing nostr profile",
|
||||
"import": {
|
||||
"title": "Import nostr profile",
|
||||
"description": "Login with an existing nostr account."
|
||||
},
|
||||
"federation": {
|
||||
"pick": "Pick a federation",
|
||||
"skip_confirm": "You'll need to pay chain and channel fees to use Mutiny, and miss out on advanced features such as lightning address. You can change your mind later in the settings."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,8 +495,8 @@
|
||||
"remove": "Eliminar",
|
||||
"expires": "Expira",
|
||||
"federation_id": "ID federación",
|
||||
"description": "Mutiny tiene soporte experimental para el protocolo Fedimint. ¡Almacene fondos en una federación bajo su propio riesgo!",
|
||||
"learn_more": "Aprenda más sobre Fedimint.",
|
||||
"description": "",
|
||||
"learn_more": "Aprenda más",
|
||||
"created_at": "Creado En",
|
||||
"recommended_by": "Recomendado por"
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import { createSignal, Show } from "solid-js";
|
||||
import { Button, InfoBox, SimpleInput } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function ImportNsecForm() {
|
||||
export function ImportNsecForm(props: { setup?: boolean }) {
|
||||
const [state, _actions] = useMegaStore();
|
||||
const navigate = useNavigate();
|
||||
const [nsec, setNsec] = createSignal("");
|
||||
@@ -29,7 +29,11 @@ export function ImportNsecForm() {
|
||||
undefined
|
||||
);
|
||||
console.log("Changed to new npub: ", new_npub);
|
||||
navigate("/");
|
||||
if (props.setup) {
|
||||
navigate("/addfederation");
|
||||
} else {
|
||||
navigate("/");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setError("Invalid nsec");
|
||||
|
||||
@@ -32,8 +32,10 @@ export const Button: ParentComponent<ButtonProps> = (props) => {
|
||||
<button
|
||||
{...attrs}
|
||||
disabled={props.disabled || props.loading}
|
||||
class="rounded-xl p-3 font-semibold transition active:-mb-[2px] active:mt-[2px] disabled:bg-neutral-400/10 disabled:text-white/20 disabled:shadow-inner-button-disabled"
|
||||
class="rounded-xl p-3 font-semibold transition active:-mb-[2px] active:mt-[2px] "
|
||||
classList={{
|
||||
"disabled:bg-neutral-400/10 disabled:text-white/20 disabled:shadow-inner-button-disabled":
|
||||
local.intent !== "text",
|
||||
"bg-white text-black": local.intent === "active",
|
||||
"bg-m-grey-800 text-white shadow-inner-button text-shadow-button":
|
||||
!local.intent || local.intent === "inactive",
|
||||
|
||||
@@ -54,7 +54,13 @@ import {
|
||||
Servers,
|
||||
Settings
|
||||
} from "~/routes/settings";
|
||||
import { ImportProfile, NewProfile, Setup, SetupRestore } from "~/routes/setup";
|
||||
import {
|
||||
AddFederation,
|
||||
ImportProfile,
|
||||
NewProfile,
|
||||
Setup,
|
||||
SetupRestore
|
||||
} from "~/routes/setup";
|
||||
import { Provider as MegaStoreProvider, useMegaStore } from "~/state/megaStore";
|
||||
|
||||
function GlobalListeners() {
|
||||
@@ -159,6 +165,7 @@ export function Router() {
|
||||
<Route path="/" component={Main} />
|
||||
<Route path="/setup" component={Setup} />
|
||||
<Route path="/setup/restore" component={SetupRestore} />
|
||||
<Route path="/addfederation" component={AddFederation} />
|
||||
<Route path="/newprofile" component={NewProfile} />
|
||||
<Route path="/editprofile" component={EditProfile} />
|
||||
<Route path="/importprofile" component={ImportProfile} />
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
SubmitHandler
|
||||
} from "@modular-forms/solid";
|
||||
import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm";
|
||||
import { A, useSearchParams } from "@solidjs/router";
|
||||
import { A, useNavigate, useSearchParams } from "@solidjs/router";
|
||||
import { BadgeCheck, Scan } from "lucide-solid";
|
||||
import {
|
||||
createResource,
|
||||
@@ -26,12 +26,13 @@ import {
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
DefaultMain,
|
||||
ExternalLink,
|
||||
FancyCard,
|
||||
InfoBox,
|
||||
KeyValue,
|
||||
LabelCircle,
|
||||
LargeHeader,
|
||||
LoadingSpinner,
|
||||
LoadingShimmer,
|
||||
MediumHeader,
|
||||
MiniStringShower,
|
||||
MutinyWalletGuard,
|
||||
@@ -81,9 +82,13 @@ type RefetchType = (
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
function AddFederationForm(props: { refetch?: RefetchType }) {
|
||||
export function AddFederationForm(props: {
|
||||
refetch?: RefetchType;
|
||||
setup?: boolean;
|
||||
}) {
|
||||
const i18n = useI18n();
|
||||
const [state, actions] = useMegaStore();
|
||||
const navigate = useNavigate();
|
||||
const [error, setError] = createSignal<Error>();
|
||||
const [success, setSuccess] = createSignal("");
|
||||
|
||||
@@ -162,6 +167,9 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
|
||||
await props.refetch();
|
||||
}
|
||||
reset(feedbackForm);
|
||||
if (props.setup) {
|
||||
navigate("/");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error submitting federation:", e);
|
||||
setError(eify(e));
|
||||
@@ -171,56 +179,61 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<MediumHeader>
|
||||
{i18n.t("settings.manage_federations.manual")}
|
||||
</MediumHeader>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<VStack>
|
||||
<Field
|
||||
name="federation_code"
|
||||
validate={[
|
||||
required(
|
||||
i18n.t(
|
||||
"settings.manage_federations.federation_code_required"
|
||||
<Show when={!props.setup}>
|
||||
<MediumHeader>
|
||||
{i18n.t("settings.manage_federations.manual")}
|
||||
</MediumHeader>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<VStack>
|
||||
<Field
|
||||
name="federation_code"
|
||||
validate={[
|
||||
required(
|
||||
i18n.t(
|
||||
"settings.manage_federations.federation_code_required"
|
||||
)
|
||||
)
|
||||
)
|
||||
]}
|
||||
>
|
||||
{(field, props) => (
|
||||
<TextField
|
||||
{...props}
|
||||
{...field}
|
||||
error={field.error}
|
||||
placeholder="fed11..."
|
||||
required
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Button
|
||||
loading={feedbackForm.submitting}
|
||||
disabled={feedbackForm.invalid || !feedbackForm.dirty}
|
||||
intent="blue"
|
||||
type="submit"
|
||||
>
|
||||
{i18n.t("settings.manage_federations.add")}
|
||||
</Button>
|
||||
<Show when={error()}>
|
||||
<InfoBox accent="red">{error()?.message}</InfoBox>
|
||||
</Show>
|
||||
<Show when={success()}>
|
||||
<InfoBox accent="green">{success()}</InfoBox>
|
||||
</Show>
|
||||
</VStack>
|
||||
</Form>
|
||||
<MediumHeader>
|
||||
{i18n.t("settings.manage_federations.discover")}
|
||||
</MediumHeader>
|
||||
]}
|
||||
>
|
||||
{(field, props) => (
|
||||
<TextField
|
||||
{...props}
|
||||
{...field}
|
||||
error={field.error}
|
||||
placeholder="fed11..."
|
||||
required
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Button
|
||||
loading={feedbackForm.submitting}
|
||||
disabled={
|
||||
feedbackForm.invalid || !feedbackForm.dirty
|
||||
}
|
||||
intent="blue"
|
||||
type="submit"
|
||||
>
|
||||
{i18n.t("settings.manage_federations.add")}
|
||||
</Button>
|
||||
<Show when={error()}>
|
||||
<InfoBox accent="red">{error()?.message}</InfoBox>
|
||||
</Show>
|
||||
<Show when={success()}>
|
||||
<InfoBox accent="green">{success()}</InfoBox>
|
||||
</Show>
|
||||
</VStack>
|
||||
</Form>
|
||||
<MediumHeader>
|
||||
{i18n.t("settings.manage_federations.discover")}
|
||||
</MediumHeader>
|
||||
</Show>
|
||||
|
||||
<Suspense>
|
||||
<Switch>
|
||||
<Match when={federations.loading}>
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<LoadingSpinner wide />
|
||||
</div>
|
||||
<FancyCard>
|
||||
<LoadingShimmer />
|
||||
</FancyCard>
|
||||
</Match>
|
||||
<Match when={federations.latest}>
|
||||
<For each={federations()}>
|
||||
@@ -247,13 +260,17 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
<KeyValue
|
||||
key={i18n.t(
|
||||
"settings.manage_federations.federation_id"
|
||||
)}
|
||||
>
|
||||
<MiniStringShower text={fed.id} />
|
||||
</KeyValue>
|
||||
<Show when={!props.setup}>
|
||||
<KeyValue
|
||||
key={i18n.t(
|
||||
"settings.manage_federations.federation_id"
|
||||
)}
|
||||
>
|
||||
<MiniStringShower
|
||||
text={fed.id}
|
||||
/>
|
||||
</KeyValue>
|
||||
</Show>
|
||||
<Show when={fed.created_at}>
|
||||
<KeyValue
|
||||
key={i18n.t(
|
||||
@@ -517,13 +534,20 @@ export function ManageFederations() {
|
||||
</A>{" "}
|
||||
</Show>
|
||||
</div>
|
||||
{/* <BackLink href="/settings" title={i18n.t("settings.header")} /> */}
|
||||
<LargeHeader>
|
||||
{i18n.t("settings.manage_federations.title")}
|
||||
</LargeHeader>
|
||||
<NiceP>
|
||||
{i18n.t("settings.manage_federations.description")}{" "}
|
||||
</NiceP>
|
||||
<NiceP>
|
||||
{i18n.t("settings.manage_federations.descriptionpart2")}{" "}
|
||||
</NiceP>
|
||||
<NiceP>
|
||||
<ExternalLink href="https://fedimint.org/docs/intro">
|
||||
{i18n.t("settings.manage_federations.learn_more")}
|
||||
</ExternalLink>
|
||||
</NiceP>
|
||||
<Suspense>
|
||||
<Show when={!state.federations?.length}>
|
||||
<AddFederationForm refetch={refetch} />
|
||||
|
||||
65
src/routes/setup/AddFederation.tsx
Normal file
65
src/routes/setup/AddFederation.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import { useNavigate } from "@solidjs/router";
|
||||
import { createSignal, Suspense } from "solid-js";
|
||||
|
||||
import {
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
DefaultMain,
|
||||
ExternalLink,
|
||||
MutinyWalletGuard,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
import { AddFederationForm } from "../settings";
|
||||
|
||||
export function AddFederation() {
|
||||
const i18n = useI18n();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [confirmOpen, setConfirmOpen] = createSignal(false);
|
||||
|
||||
async function handleSkip() {
|
||||
navigate("/");
|
||||
}
|
||||
|
||||
return (
|
||||
<MutinyWalletGuard>
|
||||
<DefaultMain>
|
||||
<div class="mx-auto flex max-w-[20rem] flex-col items-center gap-4 py-4">
|
||||
<h1 class="text-3xl font-semibold">
|
||||
{i18n.t("setup.federation.pick")}
|
||||
</h1>
|
||||
<p class="text-pretty text-center text-xl font-light text-neutral-200">
|
||||
{i18n.t("settings.manage_federations.description")}
|
||||
</p>
|
||||
<p class="text-pretty text-center text-xl font-light text-neutral-200">
|
||||
{i18n.t("settings.manage_federations.descriptionpart2")}
|
||||
</p>
|
||||
|
||||
<Button onClick={() => setConfirmOpen(true)} intent="text">
|
||||
{i18n.t("setup.skip")}
|
||||
</Button>
|
||||
<ConfirmDialog
|
||||
open={confirmOpen()}
|
||||
loading={false}
|
||||
onConfirm={handleSkip}
|
||||
onCancel={() => setConfirmOpen(false)}
|
||||
>
|
||||
{i18n.t("setup.federation.skip_confirm")}
|
||||
</ConfirmDialog>
|
||||
<VStack>
|
||||
<Suspense>
|
||||
<AddFederationForm setup />
|
||||
</Suspense>
|
||||
</VStack>
|
||||
<p class="text-pretty text-center text-xl font-light text-neutral-200">
|
||||
<ExternalLink href="https://fedimint.org/docs/intro">
|
||||
{i18n.t("settings.manage_federations.learn_more")}
|
||||
</ExternalLink>
|
||||
</p>
|
||||
</div>
|
||||
</DefaultMain>
|
||||
</MutinyWalletGuard>
|
||||
);
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export function NewProfile() {
|
||||
);
|
||||
console.log("profile", profile);
|
||||
localStorage.setItem("profile_setup_stage", "skipped");
|
||||
navigate("/");
|
||||
navigate("/addfederation");
|
||||
setSkipping(false);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export function NewProfile() {
|
||||
);
|
||||
console.log("profile", profile);
|
||||
localStorage.setItem("profile_setup_stage", "saved");
|
||||
navigate("/");
|
||||
navigate("/addfederation");
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -57,7 +57,9 @@ export function NewProfile() {
|
||||
<DefaultMain>
|
||||
<div class="mx-auto flex max-w-[20rem] flex-1 flex-col items-center gap-4">
|
||||
<div class="flex-1" />
|
||||
<h1 class="text-3xl font-semibold">Create your profile</h1>
|
||||
<h1 class="text-3xl font-semibold">
|
||||
{i18n.t("setup.new_profile.title")}
|
||||
</h1>
|
||||
<p class="text-center text-xl font-light text-neutral-200">
|
||||
{i18n.t("setup.new_profile.description")}
|
||||
</p>
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from "./Restore";
|
||||
export * from "./ImportProfile";
|
||||
export * from "./NewProfile";
|
||||
export * from "./Root";
|
||||
export * from "./AddFederation";
|
||||
|
||||
Reference in New Issue
Block a user