refactor(FE-316): Add expandable secondary drawer panel

This commit is contained in:
rstubryan
2025-12-24 17:53:14 +07:00
parent f0eb3fcf52
commit 879702d31d
6 changed files with 106 additions and 9 deletions
+31 -4
View File
@@ -15,6 +15,8 @@ interface DrawerProps {
className?: DrawerClassName; className?: DrawerClassName;
onBackdropClick?: () => void; onBackdropClick?: () => void;
closeOnBackdropClick?: boolean; closeOnBackdropClick?: boolean;
expandedContent?: ReactNode;
expandedWidth?: string;
} }
type DrawerClassName = { type DrawerClassName = {
@@ -36,6 +38,8 @@ const Drawer = ({
className, className,
onBackdropClick, onBackdropClick,
closeOnBackdropClick = true, closeOnBackdropClick = true,
expandedContent,
expandedWidth = 'w-[400px]',
}: DrawerProps) => { }: DrawerProps) => {
const getDrawerClassNames = (): DrawerClassName => { const getDrawerClassNames = (): DrawerClassName => {
const baseClassNames = { const baseClassNames = {
@@ -138,14 +142,37 @@ const Drawer = ({
onClick={closeDrawer} onClick={closeDrawer}
/> />
{/* Sidebar Content */} {/* Sidebar Content - Full height container */}
<div <div
className={cn( className={cn(
varianClassName?.drawerSidebarContent, 'flex h-screen bg-base-100 overflow-hidden',
className?.drawerContent variant === 'right' && 'flex-row'
)} )}
> >
{sidebarContent} {/* Primary Sidebar Content */}
<div
className={cn(
varianClassName?.drawerSidebarContent,
className?.drawerContent,
'overflow-y-auto'
)}
>
{sidebarContent}
</div>
{/* Expanded Drawer (Right side, side-by-side) */}
{expandedContent && (
<div
className={cn(
'border-l border-gray-200 bg-white flex flex-col h-full',
expandedWidth
)}
>
<div className='overflow-y-auto flex-1 h-full'>
{expandedContent}
</div>
</div>
)}
</div> </div>
</div> </div>
</div> </div>
@@ -14,6 +14,7 @@ export default function UniformityPageWrapper({
const pathname = usePathname(); const pathname = usePathname();
const router = useRouter(); const router = useRouter();
const toggleValidate = useUiStore((s) => s.toggleValidate); const toggleValidate = useUiStore((s) => s.toggleValidate);
const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen);
const isAdd = pathname.includes('/add'); const isAdd = pathname.includes('/add');
const isEdit = pathname.includes('/detail/edit'); const isEdit = pathname.includes('/detail/edit');
@@ -25,6 +26,7 @@ export default function UniformityPageWrapper({
const unsub = useUiStore.getState().subscribeIsValid((isValid) => { const unsub = useUiStore.getState().subscribeIsValid((isValid) => {
if (isValid) { if (isValid) {
router.push('/uniformity'); router.push('/uniformity');
setExpandedDrawerOpen(false);
} }
}); });
@@ -46,13 +48,16 @@ export default function UniformityPageWrapper({
<Drawer <Drawer
open={isOpen} open={isOpen}
setOpen={(v) => { setOpen={(v) => {
if (!v) router.push('/uniformity'); if (!v) {
router.push('/uniformity');
setExpandedDrawerOpen(false);
}
}} }}
closeOnBackdropClick={isDetail ? true : false} closeOnBackdropClick={isDetail ? true : false}
onBackdropClick={handleBackdropClick} onBackdropClick={handleBackdropClick}
variant='right' variant='right'
zIndex='99999' zIndex='99999'
sidebarContent={isOpen && <div className=''>{children}</div>} sidebarContent={isOpen ? <div className=''>{children}</div> : null}
/> />
</> </>
); );
@@ -0,0 +1,33 @@
'use client';
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
import { useUiStore } from '@/stores/ui/ui.store';
const ExpandedDrawerForm = () => {
const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen);
const handleClose = () => {
setExpandedDrawerOpen(false);
};
return (
<section className='w-full h-full bg-white border-l border-gray-200'>
{/* Header */}
<DrawerHeader
leftIcon='mdi:arrow-left'
leftIconSize={24}
leftIconOnClick={handleClose}
leftIconClassName='hover:text-gray-400 cursor-pointer'
subtitle='Add Body Weight'
subtitleClassName='text-sm text-neutral'
showDivider
/>
{/* Form Section */}
<div className='divider mt-3'></div>
<section className='w-full px-6'></section>
</section>
);
};
export default ExpandedDrawerForm;
@@ -3,6 +3,9 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import DrawerHeader from '@/components/helper/drawer/DrawerHeader'; import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
import { useUiStore } from '@/stores/ui/ui.store'; import { useUiStore } from '@/stores/ui/ui.store';
import Button from '@/components/Button';
import { Icon } from '@iconify/react';
import ExpandedDrawerForm from '@/components/pages/uniformity/form/ExpandedDrawerForm';
interface UniformityFormProps { interface UniformityFormProps {
formType?: 'add' | 'edit'; formType?: 'add' | 'edit';
@@ -11,6 +14,8 @@ interface UniformityFormProps {
const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => { const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
const subscribeValidate = useUiStore((s) => s.subscribeValidate); const subscribeValidate = useUiStore((s) => s.subscribeValidate);
const setIsValid = useUiStore((s) => s.setIsValid); const setIsValid = useUiStore((s) => s.setIsValid);
const expandedDrawerOpen = useUiStore((s) => s.expandedDrawerOpen);
const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen);
useEffect(() => { useEffect(() => {
const unsub = subscribeValidate(() => { const unsub = subscribeValidate(() => {
@@ -20,8 +25,13 @@ const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
return unsub; return unsub;
}, []); }, []);
const handleOpenExpandedDrawer = () => {
setExpandedDrawerOpen(true);
};
return ( return (
<> <div className='flex h-screen'>
{/* Primary Drawer Content */}
<section className='w-full'> <section className='w-full'>
{/* Header */} {/* Header */}
<DrawerHeader <DrawerHeader
@@ -43,10 +53,22 @@ const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
}} }}
></form> >
<Button
color='primary'
onClick={handleOpenExpandedDrawer}
className='mt-6 w-full'
>
<Icon icon='ic:round-plus' width={18} height={18} />
Expand Drawer
</Button>
</form>
</section> </section>
</section> </section>
</>
{/* Expanded Drawer - shown when open */}
{expandedDrawerOpen && <ExpandedDrawerForm />}
</div>
); );
}; };
+7
View File
@@ -37,4 +37,11 @@ export const createDrawerUISlice: StateCreator<
callback(Boolean(state.isValid)); callback(Boolean(state.isValid));
}); });
}, },
expandedDrawerOpen: false,
setExpandedDrawerOpen: (open: boolean) => set({ expandedDrawerOpen: open }),
toggleExpandedDrawer: () => {
const current = get().expandedDrawerOpen;
set({ expandedDrawerOpen: !current });
},
}); });
+3
View File
@@ -10,6 +10,9 @@ type DrawerUISlice = {
isValid: boolean; isValid: boolean;
setIsValid: (v: boolean) => void; setIsValid: (v: boolean) => void;
subscribeIsValid: (callback: (isValid: boolean) => void) => () => void; subscribeIsValid: (callback: (isValid: boolean) => void) => () => void;
expandedDrawerOpen: boolean;
setExpandedDrawerOpen: (open: boolean) => void;
toggleExpandedDrawer: () => void;
}; };
export type UIStore = MainUiSlice & DrawerUISlice; export type UIStore = MainUiSlice & DrawerUISlice;