Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
tklein1801 committed Jan 24, 2024
2 parents 9d79a58 + 6097640 commit 8afbeab
Show file tree
Hide file tree
Showing 30 changed files with 244 additions and 59 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.code-workspace
.env
build/

Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"preview": "vite preview"
},
"dependencies": {
"@budgetbuddyde/types": "^1.0.4",
"@budgetbuddyde/types": "^1.0.6",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.15",
Expand Down
71 changes: 49 additions & 22 deletions src/components/Drawer/FormDrawer/FormDrawer.component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useScreenSize } from '@/hooks';
import { useKeyPress, useScreenSize } from '@/hooks';
import { drawerWidth } from '@/style/theme/theme';
import {
Box,
Expand All @@ -9,11 +9,13 @@ import {
IconButton,
Alert,
CircularProgress,
ButtonProps,
} from '@mui/material';
import React from 'react';
import { ActionPaper } from '../../Base';
import { CloseRounded, DoneRounded, ErrorRounded } from '@mui/icons-material';
import { type TFormDrawerState } from './FormDrawer.reducer';
import { HotkeyBadge } from '@/components/HotkeyBadge.component';

export type TFormDrawerProps = {
state?: TFormDrawerState;
Expand All @@ -22,6 +24,7 @@ export type TFormDrawerProps = {
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
onClose: () => void;
closeOnBackdropClick?: boolean;
withHotkey?: boolean;
};

export const FormDrawer: React.FC<React.PropsWithChildren<TFormDrawerProps>> = ({
Expand All @@ -32,8 +35,21 @@ export const FormDrawer: React.FC<React.PropsWithChildren<TFormDrawerProps>> = (
closeOnBackdropClick = false,
heading = 'Drawer',
children,
withHotkey = false,
}) => {
const screenSize = useScreenSize();
const saveBtnRef = React.createRef<HTMLButtonElement>();

useKeyPress(
'S',
(event) => {
event.preventDefault();
if (!withHotkey) return;
if (!saveBtnRef.current) return console.error('saveBtnRef is null');
saveBtnRef.current.click();
},
{ requiresCtrl: true }
);

const DrawerAnchor: DrawerProps['anchor'] = React.useMemo(() => {
return screenSize === 'small' ? 'bottom' : 'right';
Expand Down Expand Up @@ -100,34 +116,45 @@ export const FormDrawer: React.FC<React.PropsWithChildren<TFormDrawerProps>> = (
pt: 0,
}}
>
<Button onClick={onClose} sx={{ mr: 1 }}>
<Button onClick={onClose} sx={{ mr: 2 }}>
Cancel
</Button>
{state !== undefined ? (
<Button
type="submit"
variant="contained"
startIcon={
state.loading ? (
<CircularProgress color="inherit" size={16} />
) : state.success ? (
<DoneRounded color="inherit" fontSize="inherit" />
) : !state.success && state.error !== null ? (
<ErrorRounded color="inherit" fontSize="inherit" />
) : null
}
disabled={state.loading}
>
Save
</Button>

{withHotkey ? (
<HotkeyBadge hotkey="s">
<SaveButton ref={saveBtnRef} />
</HotkeyBadge>
) : (
<Button type="submit" variant="contained">
Save
</Button>
<SaveButton ref={saveBtnRef} />
)}
</Box>
</Box>
</form>
</Drawer>
);
};

const SaveButton: React.FC<{ state?: TFormDrawerState } & Pick<ButtonProps, 'ref'>> =
React.forwardRef(({ state }, ref) => {
return (
<Button
type="submit"
variant="contained"
{...(state !== undefined
? {
startIcon: state.loading ? (
<CircularProgress color="inherit" size={16} />
) : state.success ? (
<DoneRounded color="inherit" fontSize="inherit" />
) : !state.success && state.error !== null ? (
<ErrorRounded color="inherit" fontSize="inherit" />
) : null,
disabled: state.loading,
}
: {})}
ref={ref}
>
Save
</Button>
);
});
32 changes: 32 additions & 0 deletions src/components/HotkeyBadge.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { Badge, Box, type BadgeProps } from '@mui/material';
import { KeyboardCommandKeyRounded } from '@mui/icons-material';
import { useWindowDimensions } from '@/hooks';

export type THotKeyBadgeProps = { hotkey: string } & BadgeProps;

export const HotkeyBadge: React.FC<THotKeyBadgeProps> = ({ hotkey, ...props }) => {
const { breakpoint } = useWindowDimensions();
if (breakpoint === 'xs' || breakpoint === 'sm') {
return <React.Fragment>{props.children}</React.Fragment>;
}
return (
<Badge
color="primary"
overlap="circular"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
badgeContent={
<Box sx={{ display: 'flex', flexDirection: 'row' }}>
<KeyboardCommandKeyRounded fontSize="inherit" />
{hotkey.toUpperCase()}
</Box>
}
{...props}
>
{props.children}
</Badge>
);
};
10 changes: 6 additions & 4 deletions src/components/Layout/Drawer/DrawerHamburger.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { MenuRounded as MenuIcon, MenuOpenRounded as MenuOpenIcon } from '@mui/i
import { IconButton, type IconButtonProps } from '@mui/material';
import { useScreenSize } from '@/hooks';
import { useDrawerStore } from './Drawer.store';
import { HotkeyBadge } from '@/components/HotkeyBadge.component';

export type TDrawerHeaderProps = IconButtonProps;

export const DrawerHamburger: React.FC<TDrawerHeaderProps> = ({ ...iconButtonProps }) => {
const screenSize = useScreenSize();
const { open, toggle } = useDrawerStore();

return (
<IconButton onClick={() => toggle()} {...iconButtonProps}>
<Icon open={open} screenSize={screenSize} />
</IconButton>
<HotkeyBadge hotkey="b">
<IconButton onClick={() => toggle()} {...iconButtonProps}>
<Icon open={open} screenSize={screenSize} />
</IconButton>
</HotkeyBadge>
);
};

Expand Down
13 changes: 12 additions & 1 deletion src/core/Auth/Layout/Auth.layout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import React from 'react';
import { Box, Container } from '@mui/material';
import { AppBar, Footer } from '@/components/Layout';
import { Drawer } from '@/components/Layout/Drawer';
import { Drawer, useDrawerStore } from '@/components/Layout/Drawer';
import { Main } from '@/components/Base';
import { FilterDrawer } from '@/core/Filter';
import { useKeyPress } from '@/hooks';

export type TAuthLayout = React.PropsWithChildren;

export const AuthLayout: React.FC<TAuthLayout> = ({ children }) => {
const { toggle } = useDrawerStore();
useKeyPress(
'b',
(event) => {
event.preventDefault();
toggle();
},
{ requiresCtrl: true }
);

return (
<Box sx={{ display: 'flex' }}>
<Drawer />
Expand Down
14 changes: 11 additions & 3 deletions src/core/Budget/BudgetList.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { BudgetService, CreateBudgetDrawer, EditBudgetDrawer, useFetchBudgetProg
import { useSnackbarContext } from '../Snackbar';
import { useAuthContext } from '../Auth';
import { TBudget } from '@budgetbuddyde/types';
import { useKeyPress } from '@/hooks';
import { HotkeyBadge } from '@/components/HotkeyBadge.component';

export type TBudgetListProps = {};

Expand All @@ -24,6 +26,10 @@ export const BudgetList: React.FC<TBudgetListProps> = () => {
const [showCreateBudgetDrawer, setShowCreateBudgetDrawer] = React.useState(false);
const [showEditBudgetDrawer, setShowEditBudgetDrawer] = React.useState(false);
const [editBudget, setEditBudget] = React.useState<TBudget | null>(null);
useKeyPress('a', (event) => {
event.preventDefault();
setShowCreateBudgetDrawer(true);
});

const handler: Pick<TCategoryBudgetProps, 'onEdit' | 'onDelete'> = {
async onEdit(budget) {
Expand Down Expand Up @@ -70,9 +76,11 @@ export const BudgetList: React.FC<TBudgetListProps> = () => {
<Card.HeaderActions>
<ActionPaper>
<Tooltip title="Set Budget">
<IconButton color="primary" onClick={() => setShowCreateBudgetDrawer(true)}>
<AddRounded />
</IconButton>
<HotkeyBadge hotkey="a">
<IconButton color="primary" onClick={() => setShowCreateBudgetDrawer(true)}>
<AddRounded />
</IconButton>
</HotkeyBadge>
</Tooltip>
</ActionPaper>
</Card.HeaderActions>
Expand Down
1 change: 1 addition & 0 deletions src/core/Budget/CreateBudgetDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const CreateBudgetDrawer: React.FC<TCreateBudgetDrawerProps> = ({ open, o
heading="Set Budget"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<CategoryAutocomplete
onChange={(event, value) =>
Expand Down
1 change: 1 addition & 0 deletions src/core/Budget/EditBudgetDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export const EditBudgetDrawer: React.FC<TEditBudgetDrawerProps> = ({
heading="Set Budget"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<CategoryAutocomplete
onChange={(event, value) =>
Expand Down
1 change: 1 addition & 0 deletions src/core/Category/CreateCategoryDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const CreateCategoryDrawer: React.FC<TCreateCategoryDrawerProps> = ({
heading="Create Category"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<TextField
id="category-name"
Expand Down
1 change: 1 addition & 0 deletions src/core/Category/EditCategoryDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const EditCategoryDrawer: React.FC<TEditCategoryDrawerProps> = ({
setDrawerState({ type: 'RESET' });
}}
closeOnBackdropClick
withHotkey
>
<TextField
id="category-name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const CreatePaymentMethodDrawer: React.FC<TCreatePaymentMethodProps> = ({
heading="Create Payment-Method"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
{(['name', 'address', 'provider'] as Partial<keyof TCreatePaymentMethodPayload>[]).map(
(name) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const EditPaymentMethodDrawer: React.FC<TEditPaymentMethodProps> = ({
heading="Edit Payment-Method"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
{(['name', 'address', 'provider'] as Partial<keyof TUpdatePaymentMethodPayload>[]).map(
(name) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export const CreateSubscriptionDrawer: React.FC<TCreateSubscriptionDrawerProps>
heading="Create Subscription"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{screenSize === 'small' ? (
Expand Down
1 change: 1 addition & 0 deletions src/core/Subscription/EditSubscriptionDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export const EditSubscriptionDrawer: React.FC<TEditSubscriptionDrawerProps> = ({
heading="Edit Subscription"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{screenSize === 'small' ? (
Expand Down
1 change: 1 addition & 0 deletions src/core/Transaction/CreateTransactionDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export const CreateTransactionDrawer: React.FC<TCreateTransactionDrawerProps> =
heading="Create Transaction"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{screenSize === 'small' ? (
Expand Down
1 change: 1 addition & 0 deletions src/core/Transaction/EditTransactionDrawer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export const EditTransactionDrawer: React.FC<TEditTransactionDrawerProps> = ({
heading="Create Transaction"
onClose={handler.onClose}
closeOnBackdropClick
withHotkey
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{screenSize === 'small' ? (
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './useWindowDimensions.hook';
export * from './useScreenSize.hook';
export * from './useEntityDrawer.reducer';
export * from './useKeyPress.hook';
31 changes: 31 additions & 0 deletions src/hooks/useKeyPress.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useEffect } from 'react';
import { useScreenSize } from './useScreenSize.hook';

export const useKeyPress = (
targetKey: string,
callback: (event: KeyboardEvent) => void,
options?: {
requiresCtrl?: boolean;
}
) => {
const screenSize = useScreenSize();

const handleKeyPress = (event: KeyboardEvent) => {
if (event.key === targetKey.toLowerCase()) {
if (options?.requiresCtrl && !event.ctrlKey) {
return;
}
callback(event);
}
};

useEffect(() => {
if (screenSize === 'small') return;

window.addEventListener('keydown', handleKeyPress);

return () => {
window.removeEventListener('keydown', handleKeyPress);
};
}, [targetKey, callback, screenSize, options]);
};
Loading

0 comments on commit 8afbeab

Please sign in to comment.