From 206ad0c528f559fd31f983f9e6abab6ee26e09cd Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 17 Mar 2024 00:42:01 +0100 Subject: [PATCH 1/4] N-FIN-33: create useMediaQuery hook --- src/lib/hooks/useMediaQuery.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/lib/hooks/useMediaQuery.ts diff --git a/src/lib/hooks/useMediaQuery.ts b/src/lib/hooks/useMediaQuery.ts new file mode 100644 index 0000000..0d7a61d --- /dev/null +++ b/src/lib/hooks/useMediaQuery.ts @@ -0,0 +1,16 @@ +import { useEffect, useMemo, useState } from 'react'; + +export function useMediaQuery(mq: string) { + + const mql = useMemo(() => matchMedia(mq), [mq]); + const [matches, setMatch] = useState(mql.matches); + + useEffect(() => { + const listener = (e: any) => setMatch(e.matches); + mql.addEventListener('change', listener); + + return () => mql.removeEventListener('change', listener); + }, [mq, mql]); + + return matches; +} From ebf174e9a2ac24900084439abbc14d3b12c6d25d Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 17 Mar 2024 00:42:19 +0100 Subject: [PATCH 2/4] N-FIN-33: move forms to drawers on mobile devices --- .../categoryPageClientComponents.tsx | 68 ++++++++++++----- src/components/entityPageClientComponents.tsx | 68 ++++++++++++----- .../paymentPageClientComponents.tsx | 74 +++++++++++++------ 3 files changed, 148 insertions(+), 62 deletions(-) diff --git a/src/components/categoryPageClientComponents.tsx b/src/components/categoryPageClientComponents.tsx index ac8b908..74b1ff4 100644 --- a/src/components/categoryPageClientComponents.tsx +++ b/src/components/categoryPageClientComponents.tsx @@ -23,6 +23,8 @@ import { } from '@/components/ui/alert-dialog'; import { categoryFormSchema } from '@/lib/form-schemas/categoryFormSchema'; import CategoryForm from '@/components/form/categoryForm'; +import { useMediaQuery } from '@/lib/hooks/useMediaQuery'; +import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/components/ui/drawer'; export default function CategoryPageClientContent({categories, onSubmit, onDelete, className}: { categories: Category[], @@ -31,6 +33,7 @@ export default function CategoryPageClientContent({categories, onSubmit, onDelet className: string, }) { + const isDesktop = useMediaQuery('(min-width: 768px)'); const router = useRouter(); const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); @@ -97,26 +100,51 @@ export default function CategoryPageClientContent({categories, onSubmit, onDelet

Categories

{/* Edit dialog */} - - - - - - - {selectedCategory?.id ? 'Update Category' : 'Create Category'} - - - - + { + isDesktop ? ( + + + + + + + {selectedCategory?.id ? 'Update Category' : 'Create Category'} + + + + + ) : ( + + + + + + + {selectedCategory?.id ? 'Update Category' : 'Create Category'} + + + + + ) + } {/* Data Table */} diff --git a/src/components/entityPageClientComponents.tsx b/src/components/entityPageClientComponents.tsx index 4f4a8bd..12697be 100644 --- a/src/components/entityPageClientComponents.tsx +++ b/src/components/entityPageClientComponents.tsx @@ -24,6 +24,8 @@ import { AlertDialogFooter, AlertDialogHeader, } from '@/components/ui/alert-dialog'; +import { useMediaQuery } from '@/lib/hooks/useMediaQuery'; +import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/components/ui/drawer'; export default function EntityPageClientContent({entities, onSubmit, onDelete, className}: { entities: Entity[], @@ -32,6 +34,7 @@ export default function EntityPageClientContent({entities, onSubmit, onDelete, c className: string, }) { + const isDesktop = useMediaQuery('(min-width: 768px)'); const router = useRouter(); const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); @@ -125,26 +128,51 @@ export default function EntityPageClientContent({entities, onSubmit, onDelete, c

Entities

{/* Edit dialog */} - - - - - - - {selectedEntity?.id ? 'Update Entity' : 'Create Entity'} - - - - + { + isDesktop ? ( + + + + + + + {selectedEntity?.id ? 'Update Entity' : 'Create Entity'} + + + + + ) : ( + + + + + + + {selectedEntity?.id ? 'Update Entity' : 'Create Entity'} + + + + + ) + } {/* Filter input */} diff --git a/src/components/paymentPageClientComponents.tsx b/src/components/paymentPageClientComponents.tsx index d25f5df..60a21fd 100644 --- a/src/components/paymentPageClientComponents.tsx +++ b/src/components/paymentPageClientComponents.tsx @@ -23,6 +23,8 @@ import { paymentFormSchema } from '@/lib/form-schemas/paymentFormSchema'; import { Category, Entity, Payment } from '@prisma/client'; import PaymentForm from '@/components/form/paymentForm'; import { columns } from '@/app/payments/columns'; +import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/components/ui/drawer'; +import { useMediaQuery } from '@/lib/hooks/useMediaQuery'; export default function PaymentPageClientContent({ payments, @@ -40,6 +42,7 @@ export default function PaymentPageClientContent({ className: string, }) { + const isDesktop = useMediaQuery('(min-width: 768px)'); const router = useRouter(); const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); @@ -106,28 +109,55 @@ export default function PaymentPageClientContent({

Payments

{/* Edit dialog */} - - - - - - - {selectedPayment?.id ? 'Update Payment' : 'Create Payment'} - - - - + { + isDesktop ? ( + + + + + + + {selectedPayment?.id ? 'Update Payment' : 'Create Payment'} + + + + + ) : ( + + + + + + + {selectedPayment?.id ? 'Update Payment' : 'Create Payment'} + + + + + ) + } {/* Data Table */} From f0ee68beb2515ca4b7fb8aa4f3aaced9e88360bb Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 17 Mar 2024 01:22:58 +0100 Subject: [PATCH 3/4] N-FIN-33: fix button texts --- src/components/categoryPageClientComponents.tsx | 2 +- src/components/entityPageClientComponents.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/categoryPageClientComponents.tsx b/src/components/categoryPageClientComponents.tsx index 74b1ff4..f59b3f0 100644 --- a/src/components/categoryPageClientComponents.tsx +++ b/src/components/categoryPageClientComponents.tsx @@ -130,7 +130,7 @@ export default function CategoryPageClientContent({categories, onSubmit, onDelet setSelectedCategory(undefined); setIsEditDialogOpen(true); }}> - Create Payment + Create Category diff --git a/src/components/entityPageClientComponents.tsx b/src/components/entityPageClientComponents.tsx index 12697be..3845ee1 100644 --- a/src/components/entityPageClientComponents.tsx +++ b/src/components/entityPageClientComponents.tsx @@ -158,7 +158,7 @@ export default function EntityPageClientContent({entities, onSubmit, onDelete, c setSelectedEntity(undefined); setIsEditDialogOpen(true); }}> - Create Payment + Create Entity From 34a76cf93ba3730f24c97c6451a4ab4a1893f0d5 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 17 Mar 2024 01:23:21 +0100 Subject: [PATCH 4/4] N-FIN-33: fix hook accessing matchMedia while undefined --- src/lib/hooks/useMediaQuery.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/lib/hooks/useMediaQuery.ts b/src/lib/hooks/useMediaQuery.ts index 0d7a61d..9b9b3dd 100644 --- a/src/lib/hooks/useMediaQuery.ts +++ b/src/lib/hooks/useMediaQuery.ts @@ -1,16 +1,21 @@ -import { useEffect, useMemo, useState } from 'react'; +'use client'; + +import { useEffect, useState } from 'react'; export function useMediaQuery(mq: string) { - const mql = useMemo(() => matchMedia(mq), [mq]); - const [matches, setMatch] = useState(mql.matches); + const [matches, setMatch] = useState( + () => typeof window !== 'undefined' ? window.matchMedia(mq).matches : false, + ); useEffect(() => { - const listener = (e: any) => setMatch(e.matches); - mql.addEventListener('change', listener); - - return () => mql.removeEventListener('change', listener); - }, [mq, mql]); + if (typeof window !== 'undefined') { + const mql = window.matchMedia(mq); + const listener = (e: any) => setMatch(e.matches); + mql.addEventListener('change', listener); + return () => mql.removeEventListener('change', listener); + } + }, [mq]); return matches; }