app: merge the Connect page into the Home page

The Home page and the Lightning Node Connect page both existed to get the
user connected, so they are now a single page. The "Create a new session"
button sits alongside the existing "Connect to Terminal" and "Connect with
QR" buttons, with the session list directly below them.

The "What's different?" section and the LNC explainer copy are dropped to
keep the page focused on connecting, along with the two screenshots they
used. The sidebar entry and the ConnectPage component are removed, and the
old /connect route now redirects to /home so existing links keep working.
Cancelling or submitting the custom session form returns to Home.
This commit is contained in:
dstrukt 2026-07-31 11:25:00 -06:00
parent adfe87fbb7
commit 3793ec1698
11 changed files with 48 additions and 117 deletions

View file

@ -1,5 +1,5 @@
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Layout } from 'components/layout';
const LazyAuthPage = React.lazy(() => import('components/auth/AuthPage'));
@ -8,7 +8,6 @@ const LazyHomePage = React.lazy(() => import('components/home/HomePage'));
const LazyHistoryPage = React.lazy(() => import('components/history/HistoryPage'));
const LazyPoolPage = React.lazy(() => import('components/pool/PoolPage'));
const LazySettingsPage = React.lazy(() => import('components/settings/SettingsPage'));
const LazyConnectPage = React.lazy(() => import('components/connect/ConnectPage'));
const LazyCustomSessionPage = React.lazy(
() => import('components/connect/CustomSessionPage'),
);
@ -58,14 +57,6 @@ const AppRoutes: React.FC = () => {
</Layout>
}
/>
<Route
path="connect"
element={
<Layout>
<LazyConnectPage />
</Layout>
}
/>
<Route
path="connect/custom"
element={
@ -74,6 +65,8 @@ const AppRoutes: React.FC = () => {
</Layout>
}
/>
{/* the Connect page was merged into the Home page */}
<Route path="connect" element={<Navigate to="/home" replace />} />
</Route>
</Routes>
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View file

@ -1,38 +0,0 @@
import React, { useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import styled from '@emotion/styled';
import { usePrefixedTranslation } from 'hooks';
import { useStore } from 'store';
import { DisplayLarge } from 'components/base';
import AddSession from './AddSession';
import SessionList from './SessionList';
const Styled = {
Wrapper: styled.section`
padding-top: 80px;
`,
Description: styled.div`
margin-bottom: 32px;
`,
};
const ConnectPage: React.FC = () => {
const { l } = usePrefixedTranslation('cmps.connect.ConnectPage');
const { sessionStore } = useStore();
useEffect(() => {
sessionStore.fetchSessions();
}, []);
const { Wrapper, Description } = Styled;
return (
<Wrapper>
<DisplayLarge space={16}>{l('pageTitle')}</DisplayLarge>
<Description>{l('description')}</Description>
<AddSession primary />
<SessionList />
</Wrapper>
);
};
export default observer(ConnectPage);

View file

@ -101,7 +101,7 @@ const CustomSessionPage: React.FC = () => {
const handleBack = useCallback(() => {
addSessionView.cancel();
appView.goToConnect();
appView.goToHome();
}, [appView]);
const handleSubmit = useCallback(async (event: FormEvent<HTMLFormElement>) => {

View file

@ -1,28 +1,41 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { observer } from 'mobx-react-lite';
import styled from '@emotion/styled';
import DashUX from 'assets/images/home_dash_ss.png';
import LoopUX from 'assets/images/home_loop_ss.png';
import { ReactComponent as Youtube } from 'assets/images/youtube.svg';
import { usePrefixedTranslation } from 'hooks';
import { useStore } from 'store';
import {
BoltOutlined,
Button,
Column,
Display,
Paragraph,
QRCode,
Row,
} from 'components/base';
import { BoltOutlined, Button, Display, Paragraph, QRCode } from 'components/base';
import AddSession from 'components/connect/AddSession';
import PurpleButton from 'components/connect/PurpleButton';
import QRCodeModal from 'components/connect/QRCodeModal';
import SessionList from 'components/connect/SessionList';
import YoutubeModal from './YoutubeModal';
const Styled = {
Wrapper: styled.div`
padding: 72px 0;
`,
Actions: styled.div`
display: flex;
flex-wrap: wrap;
/* stretch so the buttons are all the same height as the tallest one */
align-items: stretch;
margin-bottom: 40px;
/* size the Create a new session button to match the two connect buttons */
> button {
font-size: ${props => props.theme.sizes.s};
line-height: 24px;
padding: 8px 16px;
margin-right: 24px;
}
/* the add session form takes over the full row once it is opened */
> div {
flex: 1 1 100%;
margin-top: 16px;
}
`,
PurpleButton: styled(PurpleButton)`
font-size: ${props => props.theme.sizes.s};
line-height: 24px;
@ -37,13 +50,6 @@ const Styled = {
margin-right: 16px;
}
`,
Column: styled(Column)`
max-width: 480px;
`,
Image: styled.img`
width: 100%;
margin-bottom: 24px;
`,
};
const HomePage: React.FC = () => {
@ -52,6 +58,10 @@ const HomePage: React.FC = () => {
const [showVideo, setShowVideo] = useState(false);
const { sessionStore } = useStore();
useEffect(() => {
sessionStore.fetchSessions();
}, []);
const openQRModal = useCallback(
async () => setQrUrl(await sessionStore.getNewSessionUrl()),
[],
@ -59,14 +69,14 @@ const HomePage: React.FC = () => {
const closeQRModal = useCallback(() => setQrUrl(''), []);
const toggleVideoModal = useCallback(() => setShowVideo(v => !v), []);
const { Wrapper, PurpleButton, YoutubeButton, Column, Image } = Styled;
const { Wrapper, Actions, PurpleButton, YoutubeButton } = Styled;
return (
<Wrapper>
<Display semiBold space={16}>
{l('pageTitle')}
</Display>
<Paragraph space={32}>{l('connectDesc')}</Paragraph>
<Paragraph space={40}>
<Actions>
<PurpleButton onClick={sessionStore.connectToTerminalWeb}>
<BoltOutlined />
{l('connectTerminalBtn')}
@ -75,34 +85,15 @@ const HomePage: React.FC = () => {
<QRCode />
{l('connectQrBtn')}
</PurpleButton>
</Paragraph>
<Paragraph space={32}>{l('learnDesc')}</Paragraph>
<AddSession primary />
</Actions>
<SessionList />
<Paragraph space={40}>
<YoutubeButton ghost borderless compact onClick={toggleVideoModal}>
<Youtube />
Learn More
</YoutubeButton>
</Paragraph>
<Display semiBold space={16}>
{l('whatsDiff')}
</Display>
<Paragraph space={24}>{l('diffDesc')}</Paragraph>
<Row>
<Column>
<Image src={LoopUX} alt={l('loopTitle')} />
<Paragraph semiBold space={8}>
{l('loopTitle')}
</Paragraph>
<Paragraph muted>{l('loopDesc')}</Paragraph>
</Column>
<Column>
<Image src={DashUX} alt={l('dashTitle')} />
<Paragraph semiBold space={8}>
{l('dashTitle')}
</Paragraph>
<Paragraph muted>{l('dashDesc')}</Paragraph>
</Column>
</Row>
<QRCodeModal url={qrUrl} visible={!!qrUrl} onClose={closeQRModal} />
<YoutubeModal
videoId="5kH1ByxjkTM"

View file

@ -90,10 +90,6 @@ const NavMenu: React.FC = () => {
<NavItem page="history" onClick={appView.goToHistory} />
<NavItem page="pool" badge={l('common.preview')} onClick={appView.goToPool} />
</Nav>
<NavHeader>{l('connectHeader')}</NavHeader>
<Nav>
<NavItem page="connect" badge={l('common.beta')} onClick={appView.goToConnect} />
</Nav>
</>
);
};

View file

@ -18,7 +18,6 @@
"common.months": "month",
"common.months_plural": "months",
"common.preview": "preview",
"common.beta": "beta",
"enums.BalanceMode.receive": "Receiving",
"enums.BalanceMode.send": "Sending",
"enums.BalanceMode.routing": "Routing",
@ -87,8 +86,6 @@
"cmps.connect.CustomSessionPage.advanced": "Advanced Options",
"cmps.connect.CustomSessionPage.proxy": "Proxy Server",
"cmps.connect.CustomSessionPage.proxyDesc": "Specify a custom Lightning Node Connect proxy server",
"cmps.connect.ConnectPage.pageTitle": "Lightning Node Connect",
"cmps.connect.ConnectPage.description": "Lightning Node Connect enables you to connect to this node from the web.",
"cmps.connect.SessionRowHeader.label": "Label",
"cmps.connect.SessionRowHeader.type": "Type",
"cmps.connect.SessionRowHeader.state": "State",
@ -102,17 +99,10 @@
"cmps.connect.QRCodeModal.title": "LNC QR",
"cmps.connect.QRCodeModal.desc": "Scan to connect to Terminal from your mobile phone.",
"cmps.home.HomePage.pageTitle": "Home",
"cmps.home.HomePage.connectDesc": "Securely and privately connect your node to Terminal on the web via the link below. For mobile, generate a QR code to connect.",
"cmps.home.HomePage.connectDesc": "Securely and privately connect your node to Terminal on the web via the links below. For mobile, generate a QR code to connect.",
"cmps.home.HomePage.connectTerminalBtn": "Connect to Terminal",
"cmps.home.HomePage.connectQrBtn": "Connect with QR",
"cmps.home.HomePage.learnDesc": "The connection to your node occurs through the Lightning Node Connect protocol.",
"cmps.home.HomePage.learnMore": "Learn More",
"cmps.home.HomePage.whatsDiff": "What's different?",
"cmps.home.HomePage.diffDesc": "In the web based Terminal experience, you can expect new features like:",
"cmps.home.HomePage.loopTitle": "Improved Lightning Loop UX",
"cmps.home.HomePage.loopDesc": "Visually focused loop experience with Autoloop built-in.",
"cmps.home.HomePage.dashTitle": "Lightning Terminal Dashboard",
"cmps.home.HomePage.dashDesc": "Easily monitor routing activity and manage your channels through the dashboard.",
"cmps.home.YoutubeModal.title": "Get Connected",
"cmps.home.YoutubeModal.desc": "Get Connected with Lightning Node Connect",
"cmps.history.HistoryPage.backText": "Lightning Loop",
@ -193,8 +183,6 @@
"cmps.layout.NavMenu.loop": "Loop",
"cmps.layout.NavMenu.history": "Loop History",
"cmps.layout.NavMenu.pool": "Pool",
"cmps.layout.NavMenu.connectHeader": "Connect",
"cmps.layout.NavMenu.connect": "Lightning Node Connect",
"cmps.NodeStatus.title": "Node Status",
"cmps.NodeStatus.offchainTip": "Off-chain Funds",
"cmps.NodeStatus.onchainTip": "On-chain Funds",

View file

@ -263,7 +263,7 @@ export default class AddSessionView {
if (session) {
this.cancel();
this._store.appView.goToConnect();
this._store.appView.goToHome();
}
}

View file

@ -86,13 +86,6 @@ export default class AppView {
this._store.log.info('Go to the Settings page');
}
/** Change to the Connect page */
goToConnect() {
this.goTo(`/connect`);
this._store.settingsStore.autoCollapseSidebar();
this._store.log.info('Go to the Connect page');
}
/** Change to the Connect Custom page */
goToConnectCustom() {
this.goTo(`/connect/custom`);

View file

@ -64,6 +64,14 @@
sub-servers on startup. If the macaroon already exists but has different
permissions, it will be automatically regenerated.
* Merged the Lightning Node Connect page into the Home page: "Create a new
session" now sits alongside the existing "Connect to Terminal" and "Connect
with QR" buttons, with the session list directly below them. The separate
`/connect` page and its sidebar entry have been removed, and the custom
session form at `/connect/custom` now returns to Home. The "What's different?"
section and the Lightning Node Connect explainer copy were dropped to keep the
page focused on connecting.
### Technical and Architectural Updates
* [Report litd's own version for `litd