mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: add first channel step to onboarding
This commit is contained in:
parent
ff27c7019e
commit
53d0b68800
7 changed files with 82 additions and 12 deletions
|
|
@ -4,6 +4,7 @@ import { Outlet, useLocation, useNavigate } from "react-router";
|
|||
import { AlbyHubLogo } from "src/components/icons/AlbyHubLogo";
|
||||
import { Button } from "src/components/ui/button.tsx";
|
||||
import { useInfo } from "src/hooks/useInfo";
|
||||
import { cn } from "src/lib/utils";
|
||||
|
||||
import AntonopoulosSVG from "public/images/quotes/antonopoulos.svg";
|
||||
import BackSVG from "public/images/quotes/back.svg";
|
||||
|
|
@ -65,6 +66,7 @@ export default function TwoColumnFullScreenLayout() {
|
|||
const { data: info } = useInfo();
|
||||
const navigate = useNavigate();
|
||||
const { pathname } = useLocation();
|
||||
const anchorFirstChannelExpansion = pathname === "/setup/first-channel";
|
||||
const [quote, setQuote] = useState(
|
||||
// eslint-disable-next-line react-hooks/purity
|
||||
quotes[Math.floor(Math.random() * quotes.length)]
|
||||
|
|
@ -100,9 +102,15 @@ export default function TwoColumnFullScreenLayout() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-center py-12 text-foreground relative">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center py-12 text-foreground relative",
|
||||
anchorFirstChannelExpansion && "overflow-y-auto"
|
||||
)}
|
||||
>
|
||||
{pathname.startsWith("/setup") &&
|
||||
!pathname.startsWith("/setup/finish") && (
|
||||
!pathname.startsWith("/setup/finish") &&
|
||||
!pathname.startsWith("/setup/first-channel") && (
|
||||
// show the back button on setup pages, except the setup finish page
|
||||
<Button
|
||||
type="button"
|
||||
|
|
@ -116,7 +124,13 @@ export default function TwoColumnFullScreenLayout() {
|
|||
Back
|
||||
</Button>
|
||||
)}
|
||||
<Outlet />
|
||||
{anchorFirstChannelExpansion ? (
|
||||
<div className="flex w-full justify-center lg:h-[35rem] lg:items-start">
|
||||
<Outlet />
|
||||
</div>
|
||||
) : (
|
||||
<Outlet />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ export function SetupRedirect() {
|
|||
return;
|
||||
}
|
||||
if (info.setupCompleted && info.running) {
|
||||
if (location.pathname.startsWith("/setup/first-channel")) {
|
||||
return;
|
||||
}
|
||||
if (location.pathname.startsWith("/setup/finish")) {
|
||||
navigate("/setup/first-channel", { replace: true });
|
||||
return;
|
||||
}
|
||||
navigate("/");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,12 @@ export const useOnboardingData = (): UseOnboardingDataResponse => {
|
|||
!!albyMe &&
|
||||
nodeConnectionInfo &&
|
||||
albyMe?.keysend_pubkey === nodeConnectionInfo?.pubkey;
|
||||
const hasChannel =
|
||||
!hasChannelManagement || (hasChannelManagement && channels.length > 0);
|
||||
const hasOpenedChannel =
|
||||
!hasChannelManagement ||
|
||||
channels.some(
|
||||
(channel) =>
|
||||
channel.active || ["online", "offline"].includes(channel.status)
|
||||
);
|
||||
const hasBackedUp =
|
||||
hasMnemonic === true &&
|
||||
info &&
|
||||
|
|
@ -64,7 +68,7 @@ export const useOnboardingData = (): UseOnboardingDataResponse => {
|
|||
title: "Open your first channel",
|
||||
description:
|
||||
"Establish a new Lightning channel to enable fast and low-fee Bitcoin transactions.",
|
||||
checked: hasChannel,
|
||||
checked: hasOpenedChannel,
|
||||
to: "/channels/first",
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -575,6 +575,31 @@ const routes: RouteObject[] = [
|
|||
path: "finish",
|
||||
element: <SetupFinish />,
|
||||
},
|
||||
{
|
||||
path: "first-channel",
|
||||
handle: { crumb: () => "Your First Channel" },
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <FirstChannel variant="setup" />,
|
||||
},
|
||||
{
|
||||
path: "opening",
|
||||
element: (
|
||||
<OpeningFirstChannel openedPath="/setup/first-channel/opened" />
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "opened",
|
||||
element: (
|
||||
<OpenedFirstChannel
|
||||
ctaLabel="Go to dashboard"
|
||||
ctaTo="/home"
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,15 @@ import TickSVG from "public/images/illustrations/tick.svg";
|
|||
import TwoColumnLayoutHeader from "src/components/TwoColumnLayoutHeader";
|
||||
import { LinkButton } from "src/components/ui/custom/link-button";
|
||||
|
||||
export function OpenedFirstChannel() {
|
||||
type OpenedFirstChannelProps = {
|
||||
ctaLabel?: string;
|
||||
ctaTo?: string;
|
||||
};
|
||||
|
||||
export function OpenedFirstChannel({
|
||||
ctaLabel = "Receive Your First Payment",
|
||||
ctaTo = "/wallet/receive",
|
||||
}: OpenedFirstChannelProps) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center gap-10 p-5 w-full max-w-md">
|
||||
<TwoColumnLayoutHeader
|
||||
|
|
@ -13,8 +21,8 @@ export function OpenedFirstChannel() {
|
|||
|
||||
<img src={TickSVG} className="w-48" />
|
||||
|
||||
<LinkButton to="/wallet/receive" className="flex w-full justify-center">
|
||||
Receive Your First Payment
|
||||
<LinkButton to={ctaTo} className="flex w-full justify-center">
|
||||
{ctaLabel}
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@ import { ChannelWaitingForConfirmations } from "src/components/channels/ChannelW
|
|||
import { useChannels } from "src/hooks/useChannels";
|
||||
import { useSyncWallet } from "src/hooks/useSyncWallet";
|
||||
|
||||
export function OpeningFirstChannel() {
|
||||
type OpeningFirstChannelProps = {
|
||||
openedPath?: string;
|
||||
};
|
||||
|
||||
export function OpeningFirstChannel({
|
||||
openedPath = "/channels/first/opened",
|
||||
}: OpeningFirstChannelProps) {
|
||||
useSyncWallet();
|
||||
const { data: channels } = useChannels(true);
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -13,9 +19,9 @@ export function OpeningFirstChannel() {
|
|||
|
||||
React.useEffect(() => {
|
||||
if (firstChannel?.active) {
|
||||
navigate("/channels/first/opened");
|
||||
navigate(openedPath);
|
||||
}
|
||||
}, [firstChannel, navigate]);
|
||||
}, [firstChannel, navigate, openedPath]);
|
||||
|
||||
return <ChannelWaitingForConfirmations channel={firstChannel} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ export function SetupFinish() {
|
|||
};
|
||||
}, [loading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (info?.setupCompleted && info.running) {
|
||||
navigate("/setup/first-channel", { replace: true });
|
||||
}
|
||||
}, [info?.setupCompleted, info?.running, navigate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!info) {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue