Skip to content

Commit

Permalink
feat(mobile): Significantly improving mobile UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotcourant committed Nov 6, 2022
1 parent 304eec1 commit ea6557e
Show file tree
Hide file tree
Showing 21 changed files with 241 additions and 55 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"bfj": "7.0.2",
"camelcase": "6.3.0",
"classnames": "2.3.1",
"clsx": "^1.2.1",
"css-what": "6.1.0",
"formik": "2.2.9",
"fs-extra": "10.1.0",
Expand Down
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

/** @type {import('tailwindcss').Config} */
module.exports = {
important: true,
darkMode: 'class',
content: [
'./ui/**/*.tsx',
'./ui/**/*.jsx',
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"target": "ES2022"
},
"include": [
"ui/**/*"
"ui/**/*",
"../tailwind.config.js"
],
"exclude": [
"pkg/ui/static"
Expand Down
2 changes: 1 addition & 1 deletion ui/AuthenticatedApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const AuthenticatedApp = (): JSX.Element => {
onToggleSidebar={ toggleSidebar }
closeSidebar={ () => setSidebarClosed(true) }
/>
<div className="relative flex flex-col flex-1 w-0 min-w-0 mb-8 lg:ml-64">
<div className="relative flex flex-col flex-1 w-0 min-w-0 mb-0 lg:ml-64">
<NavigationBar onToggleSidebar={ toggleSidebar } />
<Routes>
<Route path="/register" element={ <Navigate replace to="/" /> } />
Expand Down
43 changes: 24 additions & 19 deletions ui/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import clsx from 'clsx';
import React from 'react';
import {
QueryClient,
Expand Down Expand Up @@ -60,24 +61,28 @@ export default function Root(): JSX.Element {
});

return (
<React.StrictMode>
<Sentry.ErrorBoundary>
<QueryClientProvider client={ queryClient }>
<Router>
<ThemeProvider theme={ theme }>
<LocalizationProvider dateAdapter={ AdapterMoment }>
<SnackbarProvider maxSnack={ 5 } iconVariant={ snackbarIcons }>
<NiceModal.Provider>
<CssBaseline />
<Application />
<GlobalFooter />
</NiceModal.Provider>
</SnackbarProvider>
</LocalizationProvider>
</ThemeProvider>
</Router>
</QueryClientProvider>
</Sentry.ErrorBoundary>
</React.StrictMode>
<div className={ clsx({
'dark': theme.palette.mode === 'dark',
})}>
<React.StrictMode>
<Sentry.ErrorBoundary>
<QueryClientProvider client={ queryClient }>
<Router>
<ThemeProvider theme={ theme }>
<LocalizationProvider dateAdapter={ AdapterMoment }>
<SnackbarProvider maxSnack={ 5 } iconVariant={ snackbarIcons }>
<NiceModal.Provider>
<CssBaseline />
<Application />
<GlobalFooter />
</NiceModal.Provider>
</SnackbarProvider>
</LocalizationProvider>
</ThemeProvider>
</Router>
</QueryClientProvider>
</Sentry.ErrorBoundary>
</React.StrictMode>
</div>
);
}
4 changes: 3 additions & 1 deletion ui/components/Expenses/CreateExpenseDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Science } from '@mui/icons-material';
import { useSpendingForecast } from 'hooks/forecast';
import { useFundingSchedules } from 'hooks/fundingSchedules';
import useIsMobile from 'hooks/useIsMobile';
import React, { useRef, useState } from 'react';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { DatePicker } from '@mui/lab';
Expand Down Expand Up @@ -43,6 +44,7 @@ function CreateExpenseDialog(): JSX.Element {
const createSpending = useCreateSpending();
const fundingSchedules = useFundingSchedules();
const spendingForecast = useSpendingForecast();
const isMobile = useIsMobile();
const { enqueueSnackbar } = useSnackbar();
const [estimatedCost, setEstimatedCost] = useState<string | null>(null);

Expand Down Expand Up @@ -145,7 +147,7 @@ function CreateExpenseDialog(): JSX.Element {
isValid,
}) => (
<form onSubmit={ handleSubmit }>
<Dialog open={ modal.visible } maxWidth="sm" ref={ ref }>
<Dialog open={ modal.visible } maxWidth="sm" ref={ ref } fullScreen={ isMobile }>
<DialogTitle>
Create A New Expense
</DialogTitle>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useIsMobile from 'hooks/useIsMobile';
import React, { Fragment, useRef, useState } from 'react';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { Science } from '@mui/icons-material';
Expand All @@ -22,6 +23,7 @@ interface CreateFundingScheduleForm {

function CreateFundingScheduleDialog(): JSX.Element {
const modal = useModal();
const isMobile = useIsMobile();
const selectedBankAccountId = useSelectedBankAccountId();
const createFundingSchedule = useCreateFundingSchedule();
const ref = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -80,7 +82,7 @@ function CreateFundingScheduleDialog(): JSX.Element {
submitForm,
}) => (
<form onSubmit={ handleSubmit }>
<Dialog open={ modal.visible } maxWidth="xs" ref={ ref }>
<Dialog open={ modal.visible } maxWidth="xs" ref={ ref } fullScreen={ isMobile }>
<DialogTitle>
Create A New Funding Schedule
</DialogTitle>
Expand Down
32 changes: 32 additions & 0 deletions ui/components/MButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ButtonBase, ButtonBaseProps } from '@mui/material';
import clsx from 'clsx';
import React from 'react';

export interface MButtonProps extends ButtonBaseProps {

}

export default function MButton(props: MButtonProps): JSX.Element {
const classNames = clsx(
'bg-purple-700',
'dark:bg-purple-600',
'dark:focus:ring-purple-800',
'dark:hover:bg-purple-700',
'focus:outline-none',
'font-medium',
'hover:bg-purple-800',
'mb-2',
'mr-2',
'px-5',
'py-2.5',
'rounded-lg',
'text-sm',
'text-white',
'w-full',
)

return <ButtonBase
{ ...props }
className={ classNames }
/>;
}
5 changes: 3 additions & 2 deletions ui/components/Plaid/PlaidButton.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import MButton from 'components/MButton';
import React, { Fragment, useEffect, useState } from 'react';
import {
PlaidLinkOnEvent,
PlaidLinkOnExit, PlaidLinkOnLoad,
PlaidLinkOnSuccess,
PlaidLinkOptionsWithLinkToken,
usePlaidLink } from 'react-plaid-link';
import { Button, ButtonProps, CircularProgress } from '@mui/material';
import { Button, ButtonBase, ButtonProps, CircularProgress } from '@mui/material';
import * as Sentry from '@sentry/react';
import classnames from 'classnames';
import { useSnackbar } from 'notistack';
Expand Down Expand Up @@ -135,7 +136,7 @@ const HookedPlaidButton = (props: HookedPropTypes) => {
};

return (
<Button { ...newProps } />
<MButton { ...newProps } />
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { AccessTime } from '@mui/icons-material';
import classnames from 'classnames';
import { useSpending } from 'hooks/spending';
import React, { Fragment } from 'react';
import { Chip, Divider, ListItem, ListItemAvatar, ListItemButton, ListItemText, Skeleton } from '@mui/material';

import TransactionIcon from 'components/Transactions/components/TransactionIcon';
import Transaction from 'models/Transaction';

import 'components/Transactions/TransactionsView/styles/TransactionItem.scss';

interface Props {
transaction: Transaction;
}

export default function TransactionItemMobile(props: Props): JSX.Element {
const spending = useSpending(props.transaction.spendingId)

function SpentFromLine(): JSX.Element {
if (props.transaction.getIsAddition()) {
return (
<span className="text-ellipsis overflow-hidden">
Deposit
</span>
);
}

if (props.transaction.spendingId && !spending) {
return (
<span className="text-ellipsis overflow-hidden">
Spent From <span className="opacity-75">...</span>
</span>
)
}

const name = spending ?
<span className="text-black font-medium dark:text-white text-ellipsis overflow-hidden">
{ spending?.name }
</span> : 'Safe-To-Spend';

return (
<span className="text-ellipsis overflow-hidden">
Spent From { name }
</span>
);
}

return (
<Fragment>
<ListItemButton className="pr-0">
<ListItemAvatar>
<TransactionIcon transaction={ props.transaction }/>
</ListItemAvatar>
<ListItemText
className="flex-initial w-7/12"
primary={ props.transaction.getName() }
secondaryTypographyProps={{
className: "text-ellipsis overflow-hidden truncate"
}}
secondary={ <SpentFromLine /> }
/>
<div className="flex-1 flex justify-start">
{ props.transaction.isPending && <AccessTime />
}
</div>
<span className={ classnames('h-full flex-none amount align-middle self-center justify-end place-self-center text-sm', {
'text-green-600': props.transaction.getIsAddition(),
'text-red-600': !props.transaction.getIsAddition(),
}) }>
<b>{ props.transaction.getAmountString() }</b>
</span>
</ListItemButton>
<Divider />
</Fragment>
);
}
48 changes: 28 additions & 20 deletions ui/components/Transactions/TransactionsView/TransactionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import TransactionItemMobile from 'components/Transactions/TransactionsView/TransactionItem.mobile';
import useIsMobile from 'hooks/useIsMobile';
import React, { Fragment } from 'react';
import { AccessTime } from '@mui/icons-material';
import { Chip, Divider, ListItem } from '@mui/material';
import { AccessTime, Work } from '@mui/icons-material';
import { Avatar, Chip, Divider, ListItem, ListItemAvatar, ListItemText, useMediaQuery } from '@mui/material';
import classnames from 'classnames';

import TransactionIcon from 'components/Transactions/components/TransactionIcon';
Expand All @@ -15,26 +17,32 @@ interface Props {
}

function TransactionItem(props: Props): JSX.Element {
return (
<Fragment>
<ListItem className="flex flex-row transactions-item pl-3 pr-1 md:pr-2.5">
<div className="flex flex-col md:flex-row basis-9/12 md:basis-10/12">
<TransactionIcon transaction={ props.transaction } />
<TransactionNameEditor transaction={ props.transaction } />
<TransactionSpentFromSelection transaction={ props.transaction } />
</div>
<div className="basis-3/12 md:basis-2/12 flex justify-end w-full items-center">
{ props.transaction.isPending && <Chip icon={ <AccessTime /> } label="Pending" className="mr-auto" /> }
<span className={ classnames('h-full amount align-middle self-center place-self-center', {
'addition': props.transaction.getIsAddition(),
}) }>
const isMobile = useIsMobile();
if (!isMobile) {
return (
<Fragment>
<ListItem className="flex flex-row transactions-item pl-3 pr-1 md:pr-2.5">
<div className="flex flex-col md:flex-row basis-9/12 md:basis-10/12">
<TransactionIcon transaction={ props.transaction } />
<TransactionNameEditor transaction={ props.transaction } />
<TransactionSpentFromSelection transaction={ props.transaction } />
</div>
<div className="basis-3/12 md:basis-2/12 flex justify-end w-full items-center">
{ props.transaction.isPending && <Chip icon={ <AccessTime /> } label="Pending" className="mr-auto" /> }
<span className={ classnames('h-full amount align-middle self-center place-self-center', {
'text-green-600': props.transaction.getIsAddition(),
'text-red-600': !props.transaction.getIsAddition(),
}) }>
<b>{ props.transaction.getAmountString() }</b>
</span>
</div>
</ListItem>
<Divider />
</Fragment>
);
</div>
</ListItem>
<Divider />
</Fragment>
);
}

return <TransactionItemMobile transaction={ props.transaction } />
}

export default React.memo(TransactionItem);
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { darken, lighten } from '@mui/material';
import { useTheme } from '@mui/styles';
import React, { useState } from 'react';
import { ActionMeta, OnChangeValue, Theme } from 'react-select';
import { FormatOptionLabelMeta } from 'react-select/base';
import CreatableSelect from 'react-select/creatable';

import { useUpdateTransaction } from 'hooks/transactions';
import Transaction from 'models/Transaction';
import theme from 'theme';

interface Props {
transaction: Transaction;
Expand Down Expand Up @@ -81,13 +84,22 @@ const TransactionNameEditor = (props: Props): JSX.Element => {

const value = customTransactionName || originalTransactionName;

const uiTheme = theme;

return (
<CreatableSelect
theme={ (theme: Theme): Theme => ({
...theme,
colors: {
...theme.colors,
primary: '#4E1AA0',
primary: uiTheme.palette.primary.main,
...( uiTheme.palette.mode === 'dark' && {
neutral0: uiTheme.palette.background.default,
primary25: lighten(uiTheme.palette.background.default, 0.1),
primary50: lighten(uiTheme.palette.background.default, 0.5),
neutral80: 'white',
neutral90: 'white',
}), // Text
},
}) }
classNamePrefix="transaction-select"
Expand Down
Loading

0 comments on commit ea6557e

Please sign in to comment.