Mobile create account (#1853)

* Mobile create account

* Release notes

* Update add button style

* Add back desktop page header padding

* Empty accounts handling

* decimal keyboard on CreateLocalAccount balance input

* VRT updates
This commit is contained in:
Joel Jeremy Marquez
2023-11-18 20:21:41 -08:00
committed by GitHub
parent 9ec82d52c9
commit b5530085bb
12 changed files with 217 additions and 156 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -6,13 +6,21 @@ import { theme, styles, type CSSProperties } from '../style';
import Text from './common/Text';
import View from './common/View';
function PageTitle({
name,
style,
}: {
type PageHeaderProps = {
name: ReactNode;
style?: CSSProperties;
}) {
leftContent?: ReactNode;
rightContent?: ReactNode;
};
const HEADER_HEIGHT = 50;
function PageHeader({
name,
style,
leftContent,
rightContent,
}: PageHeaderProps) {
const { isNarrowWidth } = useResponsive();
if (isNarrowWidth) {
@@ -23,16 +31,42 @@ function PageTitle({
backgroundColor: theme.mobilePageBackground,
color: theme.mobileModalText,
flexDirection: 'row',
flex: '1 0 auto',
fontSize: 18,
fontWeight: 500,
height: 50,
justifyContent: 'center',
overflowY: 'auto',
flexShrink: 0,
height: HEADER_HEIGHT,
...style,
}}
>
{name}
<View
style={{
flexBasis: '25%',
justifyContent: 'flex-start',
flexDirection: 'row',
}}
>
{leftContent}
</View>
<View
style={{
alignItems: 'center',
flexDirection: 'row',
flexBasis: '50%',
fontSize: 18,
fontWeight: 500,
justifyContent: 'center',
overflowY: 'auto',
}}
>
{name}
</View>
<View
style={{
flexBasis: '25%',
justifyContent: 'flex-end',
flexDirection: 'row',
}}
>
{rightContent}
</View>
</View>
);
}
@@ -51,25 +85,33 @@ function PageTitle({
);
}
type PageProps = {
title: ReactNode;
titleStyle?: CSSProperties;
headerLeftContent?: ReactNode;
headerRightContent?: ReactNode;
children: ReactNode;
};
export function Page({
title,
children,
titleStyle,
}: {
title: ReactNode;
children: ReactNode;
titleStyle?: CSSProperties;
}) {
headerLeftContent,
headerRightContent,
children,
}: PageProps) {
let { isNarrowWidth } = useResponsive();
let HORIZONTAL_PADDING = isNarrowWidth ? 10 : 20;
return (
<View style={isNarrowWidth ? undefined : styles.page}>
<PageTitle
<PageHeader
name={title}
leftContent={headerLeftContent}
rightContent={headerRightContent}
style={{
...titleStyle,
paddingInline: HORIZONTAL_PADDING,
...(!isNarrowWidth && { paddingInline: HORIZONTAL_PADDING }),
}}
/>
<View

View File

@@ -106,109 +106,7 @@ export default function AccountDetails({
top: 0,
}}
>
<View
style={{
flexDirection: 'row',
flexShrink: 0,
height: BUDGET_HEADER_HEIGHT,
width: '100%',
backgroundColor: theme.mobileHeaderBackground,
}}
>
<View
style={{
width: LEFT_RIGHT_FLEX_WIDTH,
flexDirection: 'row',
}}
>
<Button
type="bare"
style={{
color: theme.mobileHeaderText,
justifyContent: 'center',
margin: 10,
paddingLeft: 5,
paddingRight: 3,
}}
hoveredStyle={{
color: theme.mobileHeaderText,
background: theme.mobileHeaderTextHover,
}}
>
<Link
to={-1}
style={{
alignItems: 'center',
display: 'flex',
textDecoration: 'none',
}}
>
<CheveronLeft
style={{ width: 30, height: 30, margin: -10, marginLeft: -5 }}
/>
<Text
style={{
...styles.text,
fontWeight: 500,
marginLeft: 5,
marginRight: 5,
}}
>
Back
</Text>
</Link>
</Button>
<View
style={{
flex: 1,
}}
/>
</View>
<View
style={{
flex: 1,
fontSize: 16,
fontWeight: 500,
alignItems: 'center',
justifyContent: 'center',
color: theme.mobileHeaderText,
}}
role="heading"
>
{account.name}
</View>
<View
style={{
width: LEFT_RIGHT_FLEX_WIDTH,
flexDirection: 'row',
}}
>
<View
style={{
flex: 1,
}}
/>
<ButtonLink
to="transactions/new"
type="bare"
aria-label="Add Transaction"
style={{
justifyContent: 'center',
padding: 10,
margin: 10,
color: theme.mobileHeaderText,
}}
hoveredStyle={{
color: theme.mobileHeaderText,
background: theme.mobileHeaderTextHover,
}}
activeStyle={{ background: 'transparent' }}
>
<Add width={20} height={20} style={{ margin: -5 }} />
</ButtonLink>
</View>
</View>
<AccountDetailsHeader account={account} />
<Label title="BALANCE" style={{ marginTop: 10 }} />
<CellValue
binding={balance}
@@ -245,3 +143,112 @@ export default function AccountDetails({
</View>
);
}
function AccountDetailsHeader({ account }) {
return (
<View
style={{
flexDirection: 'row',
flexShrink: 0,
height: BUDGET_HEADER_HEIGHT,
width: '100%',
backgroundColor: theme.mobileHeaderBackground,
}}
>
<View
style={{
width: LEFT_RIGHT_FLEX_WIDTH,
flexDirection: 'row',
}}
>
<Button
type="bare"
style={{
color: theme.mobileHeaderText,
justifyContent: 'center',
margin: 10,
paddingLeft: 5,
paddingRight: 3,
}}
hoveredStyle={{
color: theme.mobileHeaderText,
background: theme.mobileHeaderTextHover,
}}
>
<Link
to={-1}
style={{
...styles.noTapHighlight,
alignItems: 'center',
display: 'flex',
textDecoration: 'none',
}}
>
<CheveronLeft
style={{ width: 30, height: 30, margin: -10, marginLeft: -5 }}
/>
<Text
style={{
...styles.text,
fontWeight: 500,
marginLeft: 5,
marginRight: 5,
}}
>
Back
</Text>
</Link>
</Button>
<View
style={{
flex: 1,
}}
/>
</View>
<View
style={{
flex: 1,
fontSize: 16,
fontWeight: 500,
alignItems: 'center',
justifyContent: 'center',
color: theme.mobileHeaderText,
}}
role="heading"
>
{account.name}
</View>
<View
style={{
width: LEFT_RIGHT_FLEX_WIDTH,
flexDirection: 'row',
}}
>
<View
style={{
flex: 1,
}}
/>
<ButtonLink
to="transactions/new"
type="bare"
aria-label="Add Transaction"
style={{
justifyContent: 'center',
padding: 10,
margin: 10,
color: theme.mobileHeaderText,
}}
hoveredStyle={{
color: theme.mobileHeaderText,
background: theme.mobileHeaderTextHover,
}}
activeStyle={{ background: 'transparent' }}
>
<Add width={20} height={20} style={{ margin: -5 }} />
</ButtonLink>
</View>
</View>
);
}

View File

@@ -7,6 +7,7 @@ import { useActions } from '../../hooks/useActions';
import useCategories from '../../hooks/useCategories';
import useNavigate from '../../hooks/useNavigate';
import { useSetThemeColor } from '../../hooks/useSetThemeColor';
import Add from '../../icons/v1/Add';
import { theme, styles } from '../../style';
import Button from '../common/Button';
import Text from '../common/Text';
@@ -124,7 +125,7 @@ function AccountCard({ account, updated, getBalanceQuery, onSelect }) {
);
}
function EmptyMessage({ onAdd }) {
function EmptyMessage() {
return (
<View style={{ flex: 1, padding: 30 }}>
<Text style={styles.text}>
@@ -132,22 +133,6 @@ function EmptyMessage({ onAdd }) {
account to automatically download transactions, or manage it locally
yourself.
</Text>
<Button
type="primary"
style={{ marginTop: 20, alignSelf: 'center' }}
onClick={() =>
alert(
'Account creation is not supported on mobile on the self-hosted service yet',
)
}
>
Add Account
</Button>
<Text style={{ marginTop: 20, color: theme.pageTextLight }}>
In the future, you can add accounts using the add button in the header.
</Text>
</View>
);
}
@@ -160,16 +145,14 @@ function AccountList({
getOffBudgetBalance,
onAddAccount,
onSelectAccount,
onSync,
}) {
const { syncAndDownload } = useActions();
const budgetedAccounts = accounts.filter(account => account.offbudget === 0);
const offbudgetAccounts = accounts.filter(account => account.offbudget === 1);
// If there are no accounts, show a helpful message
if (accounts.length === 0) {
return <EmptyMessage onAdd={onAddAccount} />;
}
const noBackgroundColorStyle = {
backgroundColor: 'transparent',
color: 'white',
};
return (
<View style={{ flex: 1, backgroundColor: theme.mobilePageBackground }}>
@@ -180,9 +163,27 @@ function AccountList({
color: theme.mobileHeaderText,
fontSize: 16,
}}
headerRightContent={
<Button
type="bare"
style={{
paddingLeft: 12,
paddingRight: 12,
...noBackgroundColorStyle,
}}
activeStyle={noBackgroundColorStyle}
hoveredStyle={noBackgroundColorStyle}
onClick={onAddAccount}
>
<Add width={20} height={20} />
</Button>
}
>
<PullToRefresh onRefresh={syncAndDownload}>
<AccountHeader name="For Budget" amount={getOnBudgetBalance()} />
{accounts.length === 0 && <EmptyMessage />}
<PullToRefresh onRefresh={onSync}>
{budgetedAccounts.length > 0 && (
<AccountHeader name="For Budget" amount={getOnBudgetBalance()} />
)}
{budgetedAccounts.map(acct => (
<AccountCard
account={acct}
@@ -193,11 +194,13 @@ function AccountList({
/>
))}
<AccountHeader
name="Off budget"
amount={getOffBudgetBalance()}
style={{ marginTop: 30 }}
/>
{offbudgetAccounts.length > 0 && (
<AccountHeader
name="Off budget"
amount={getOffBudgetBalance()}
style={{ marginTop: 30 }}
/>
)}
{offbudgetAccounts.map(acct => (
<AccountCard
account={acct}
@@ -225,7 +228,7 @@ export default function Accounts() {
);
const { list: categories } = useCategories();
let { getAccounts } = useActions();
let { getAccounts, replaceModal, syncAndDownload } = useActions();
const transactions = useState({});
const navigate = useNavigate();
@@ -258,9 +261,10 @@ export default function Accounts() {
getBalanceQuery={queries.accountBalance}
getOnBudgetBalance={queries.budgetedAccountBalance}
getOffBudgetBalance={queries.offbudgetAccountBalance}
onAddAccount={() => {}} // () => navigate('AddAccountModal')
onAddAccount={() => replaceModal('add-account')}
onSelectAccount={onSelectAccount}
onSelectTransaction={onSelectTransaction}
onSync={syncAndDownload}
/>
</View>
);

View File

@@ -132,6 +132,7 @@ function CreateLocalAccount({ modalProps, actions }: CreateLocalAccountProps) {
<InlineField label="Balance" width="75%">
<Input
name="balance"
inputMode="decimal"
value={balance}
onChange={event => setBalance(event.target.value)}
onBlur={event => {

View File

@@ -362,6 +362,7 @@ class TransactionEditInner extends PureComponent {
<Button
type="bare"
style={{
...styles.noTapHighlight,
color: theme.mobileHeaderText,
justifyContent: 'center',
margin: 10,

View File

@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [joel-jeremy]
---
Mobile create account.