mirror of
https://github.com/joinmarket-webui/jam.git
synced 2026-08-16 13:01:05 +02:00
chore(ui): improve footer on small screens (#1243)
* chore(footer): align blockheight * ui(footer): improve footer on small screens * chore(storybook): add BetaWarningDialog story * review: remove flex container of footer warning
This commit is contained in:
parent
0eea853109
commit
ee5770eeeb
5 changed files with 125 additions and 54 deletions
|
|
@ -1,16 +1,15 @@
|
|||
import { useState, type ComponentProps } from 'react'
|
||||
import { BlocksIcon, BookOpenIcon, FileQuestionMarkIcon, ScrollTextIcon } from 'lucide-react'
|
||||
import { useTranslation, Trans } from 'react-i18next'
|
||||
import { useStore } from 'zustand'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { JmWebsocketInfo } from '@/components/ui/jam/JmWebsocketInfo'
|
||||
import type { JmWebsocket } from '@/hooks/useJmWebsocket'
|
||||
import { jmSessionStore } from '@/store/jmSessionStore'
|
||||
import { BetaWarningDialog } from './footer/BetaWarningDialog'
|
||||
|
||||
type JmWebsocketInfo = Pick<JmWebsocket, 'isOpen' | 'isAuthenticated'>
|
||||
|
||||
type AppFooterProps = Pick<ComponentProps<typeof BetaWarningDialog>, 'jamVersion' | 'joinmarketVersion'> & {
|
||||
blockHeight?: number
|
||||
websocketInfo?: JmWebsocketInfo
|
||||
onClickCheatsheet: () => void
|
||||
onClickOrderbook: () => void
|
||||
|
|
@ -18,6 +17,7 @@ type AppFooterProps = Pick<ComponentProps<typeof BetaWarningDialog>, 'jamVersion
|
|||
}
|
||||
|
||||
export function AppFooter({
|
||||
blockHeight,
|
||||
websocketInfo,
|
||||
jamVersion,
|
||||
joinmarketVersion,
|
||||
|
|
@ -27,7 +27,6 @@ export function AppFooter({
|
|||
}: AppFooterProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const blockHeight = useStore(jmSessionStore, (state) => state.state?.block_height)
|
||||
const [isShowBetaWarning, setShowBetaWarning] = useState(false)
|
||||
|
||||
return (
|
||||
|
|
@ -38,57 +37,65 @@ export function AppFooter({
|
|||
joinmarketVersion={joinmarketVersion}
|
||||
jamVersion={jamVersion}
|
||||
/>
|
||||
<footer className="flex items-center justify-between gap-2 p-4">
|
||||
<div className="hidden flex-1 text-xs sm:block">
|
||||
<Trans i18nKey="footer.warning">
|
||||
This is pre-alpha software.
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
className="h-auto p-0 text-xs font-semibold"
|
||||
onClick={() => setShowBetaWarning(true)}
|
||||
>
|
||||
Read this before using.
|
||||
<footer>
|
||||
<div className="flex flex-col items-center justify-between gap-8 px-4 py-12 sm:flex-row sm:gap-2 sm:p-4">
|
||||
<div
|
||||
className="flex flex-col justify-start gap-2 sm:flex-row sm:items-center sm:justify-center"
|
||||
data-tour-id="footer-tools"
|
||||
>
|
||||
<Button variant="outline" size="sm" onClick={onClickCheatsheet} title={t('footer.cheatsheet')}>
|
||||
<FileQuestionMarkIcon />
|
||||
<span className="">{t('footer.cheatsheet')}</span>
|
||||
</Button>
|
||||
</Trans>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-start gap-2 sm:justify-center" data-tour-id="footer-tools">
|
||||
<Button variant="outline" size="sm" onClick={onClickCheatsheet} title={t('footer.cheatsheet')}>
|
||||
<FileQuestionMarkIcon />
|
||||
<span className="hidden sm:inline-block">{t('footer.cheatsheet')}</span>
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" onClick={onClickOrderbook} title={t('footer.orderbook')}>
|
||||
<BookOpenIcon />
|
||||
<span className="hidden sm:inline-block">{t('footer.orderbook')}</span>
|
||||
</Button>
|
||||
{onClickLogs && (
|
||||
<Button variant="outline" size="sm" onClick={onClickLogs} title={t('footer.logs')}>
|
||||
<ScrollTextIcon />
|
||||
<span className="hidden sm:inline-block">{t('footer.logs')}</span>
|
||||
<Button variant="outline" size="sm" onClick={onClickOrderbook} title={t('footer.orderbook')}>
|
||||
<BookOpenIcon />
|
||||
<span className="">{t('footer.orderbook')}</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 items-center justify-end gap-4 text-xs">
|
||||
{websocketInfo !== undefined && (
|
||||
<div className="flex flex-col gap-1">
|
||||
<JmWebsocketInfo isOpen={websocketInfo.isOpen} isAuthenticated={websocketInfo.isAuthenticated} />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-1">
|
||||
{blockHeight && (
|
||||
<span className="flex items-center gap-1">
|
||||
<BlocksIcon className="size-4" /> {blockHeight}
|
||||
</span>
|
||||
{onClickLogs && (
|
||||
<Button variant="outline" size="sm" onClick={onClickLogs} title={t('footer.logs')}>
|
||||
<ScrollTextIcon />
|
||||
<span className="">{t('footer.logs')}</span>
|
||||
</Button>
|
||||
)}
|
||||
<a
|
||||
href="https://github.com/joinmarket-webui/jam/tags"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-right underline opacity-80"
|
||||
>
|
||||
v{jamVersion?.raw}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col items-center justify-end gap-4 break-normal sm:flex-row">
|
||||
{websocketInfo !== undefined && (
|
||||
<div className="order-first flex flex-col sm:order-last">
|
||||
<JmWebsocketInfo isOpen={websocketInfo.isOpen} isAuthenticated={websocketInfo.isAuthenticated} />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col items-center gap-0.25 text-end text-xs sm:items-end">
|
||||
{blockHeight && (
|
||||
<span className="flex items-center gap-1">
|
||||
<BlocksIcon className="size-3" />
|
||||
<span className="break-keep slashed-zero tabular-nums select-all">
|
||||
{blockHeight.toLocaleString()}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
<a
|
||||
href="https://github.com/joinmarket-webui/jam/tags"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-muted-foreground underline"
|
||||
>
|
||||
v{jamVersion?.raw}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order-last flex-1 text-xs sm:order-first">
|
||||
<Trans i18nKey="footer.warning">
|
||||
This is pre-alpha software.
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
className="h-auto p-0 text-xs font-semibold"
|
||||
onClick={() => setShowBetaWarning(true)}
|
||||
>
|
||||
Read this before using.
|
||||
</Button>
|
||||
</Trans>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ export function LayoutInner({ onLogout, onLockWallet, children }: LayoutInnerPro
|
|||
<main className="flex-1">{children}</main>
|
||||
<AppFooter
|
||||
websocketInfo={websocket}
|
||||
blockHeight={jmSession?.block_height}
|
||||
jamVersion={APP_DISPLAY_VERSION}
|
||||
joinmarketVersion={joinmarketVersion}
|
||||
onClickCheatsheet={() => cheatsheet.onOpenChange(true)}
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ export const BetaWarningDialog = ({ jamVersion, joinmarketVersion, ...dialogProp
|
|||
</DialogHeader>
|
||||
<div className="items-end-safe text-sm">
|
||||
<span className="text-muted-foreground">JoinMarket: </span>
|
||||
<span className="font-mono font-semibold">v{joinmarketVersion?.raw || '_unknown'}</span>
|
||||
<span className="font-mono font-semibold select-all">v{joinmarketVersion?.raw || '_unknown'}</span>
|
||||
<br />
|
||||
<span className="text-muted-foreground">Jam: </span>
|
||||
<span className="font-mono font-semibold">v{jamVersion.raw || '_unknown'}</span>
|
||||
<span className="font-mono font-semibold select-all">v{jamVersion.raw || '_unknown'}</span>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button onClick={() => dialogProps.onOpenChange(false)}>{t('footer.warning_alert_button_ok')}</Button>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ export const Default: Story = {
|
|||
render: () => (
|
||||
<AppFooter
|
||||
websocketInfo={{ isOpen: true, isAuthenticated: true }}
|
||||
jamVersion={APP_DISPLAY_VERSION}
|
||||
blockHeight={21_000_000}
|
||||
jamVersion={parseSemanticVersion('1.2.3')}
|
||||
joinmarketVersion={parseSemanticVersion('0.9.12')}
|
||||
onClickCheatsheet={() => alert('Cheatsheet clicked!')}
|
||||
onClickOrderbook={() => alert('Orderbook clicked!')}
|
||||
|
|
@ -24,3 +25,28 @@ export const Default: Story = {
|
|||
/>
|
||||
),
|
||||
}
|
||||
|
||||
export const WithoutLogs: Story = {
|
||||
render: () => (
|
||||
<AppFooter
|
||||
websocketInfo={{ isOpen: true, isAuthenticated: false }}
|
||||
blockHeight={21_000_000}
|
||||
jamVersion={APP_DISPLAY_VERSION}
|
||||
joinmarketVersion={parseSemanticVersion('0.9.12')}
|
||||
onClickCheatsheet={() => alert('Cheatsheet clicked!')}
|
||||
onClickOrderbook={() => alert('Orderbook clicked!')}
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
||||
export const Minimal: Story = {
|
||||
render: () => (
|
||||
<AppFooter
|
||||
websocketInfo={{ isOpen: false, isAuthenticated: false }}
|
||||
blockHeight={21_000_000}
|
||||
jamVersion={parseSemanticVersion('99.99.99-SNAPSHOT')}
|
||||
onClickCheatsheet={() => alert('Cheatsheet clicked!')}
|
||||
onClickOrderbook={() => alert('Orderbook clicked!')}
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
|
|
|||
37
src/stories/jam/dialogs/BetaWarningDialog.stories.tsx
Normal file
37
src/stories/jam/dialogs/BetaWarningDialog.stories.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { useState } from 'react'
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite'
|
||||
import { BetaWarningDialog } from '@/components/layout/footer/BetaWarningDialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { APP_DISPLAY_VERSION } from '@/constants/jam'
|
||||
import { parseSemanticVersion } from '@/lib/utils'
|
||||
|
||||
const meta: Meta<typeof BetaWarningDialog> = {
|
||||
title: 'Dialog/BetaWarningDialog',
|
||||
component: BetaWarningDialog,
|
||||
tags: ['autodocs'],
|
||||
render: (args) => {
|
||||
const [open, setOpen] = useState(args.defaultOpen || false)
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => setOpen(true)}>Open</Button>
|
||||
<BetaWarningDialog {...args} open={open} onOpenChange={() => setOpen(false)} />
|
||||
</>
|
||||
)
|
||||
},
|
||||
}
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof BetaWarningDialog>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
jamVersion: APP_DISPLAY_VERSION,
|
||||
joinmarketVersion: parseSemanticVersion('0.9.12'),
|
||||
},
|
||||
}
|
||||
|
||||
export const UnknownBackendVersion: Story = {
|
||||
args: {
|
||||
jamVersion: APP_DISPLAY_VERSION,
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue