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;
onBackdropClick?: () => void;
closeOnBackdropClick?: boolean;
expandedContent?: ReactNode;
expandedWidth?: string;
}
type DrawerClassName = {
@@ -36,6 +38,8 @@ const Drawer = ({
className,
onBackdropClick,
closeOnBackdropClick = true,
expandedContent,
expandedWidth = 'w-[400px]',
}: DrawerProps) => {
const getDrawerClassNames = (): DrawerClassName => {
const baseClassNames = {
@@ -138,14 +142,37 @@ const Drawer = ({
onClick={closeDrawer}
/>
{/* Sidebar Content */}
{/* Sidebar Content - Full height container */}
<div
className={cn(
varianClassName?.drawerSidebarContent,
className?.drawerContent
'flex h-screen bg-base-100 overflow-hidden',
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>
@@ -14,6 +14,7 @@ export default function UniformityPageWrapper({
const pathname = usePathname();
const router = useRouter();
const toggleValidate = useUiStore((s) => s.toggleValidate);
const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen);
const isAdd = pathname.includes('/add');
const isEdit = pathname.includes('/detail/edit');
@@ -25,6 +26,7 @@ export default function UniformityPageWrapper({
const unsub = useUiStore.getState().subscribeIsValid((isValid) => {
if (isValid) {
router.push('/uniformity');
setExpandedDrawerOpen(false);
}
});
@@ -46,13 +48,16 @@ export default function UniformityPageWrapper({
<Drawer
open={isOpen}
setOpen={(v) => {
if (!v) router.push('/uniformity');
if (!v) {
router.push('/uniformity');
setExpandedDrawerOpen(false);
}
}}
closeOnBackdropClick={isDetail ? true : false}
onBackdropClick={handleBackdropClick}
variant='right'
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 DrawerHeader from '@/components/helper/drawer/DrawerHeader';
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 {
formType?: 'add' | 'edit';
@@ -11,6 +14,8 @@ interface UniformityFormProps {
const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
const subscribeValidate = useUiStore((s) => s.subscribeValidate);
const setIsValid = useUiStore((s) => s.setIsValid);
const expandedDrawerOpen = useUiStore((s) => s.expandedDrawerOpen);
const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen);
useEffect(() => {
const unsub = subscribeValidate(() => {
@@ -20,8 +25,13 @@ const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
return unsub;
}, []);
const handleOpenExpandedDrawer = () => {
setExpandedDrawerOpen(true);
};
return (
<>
<div className='flex h-screen'>
{/* Primary Drawer Content */}
<section className='w-full'>
{/* Header */}
<DrawerHeader
@@ -43,10 +53,22 @@ const UniformityForm = ({ formType = 'add' }: UniformityFormProps) => {
onSubmit={(e) => {
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>
</>
{/* Expanded Drawer - shown when open */}
{expandedDrawerOpen && <ExpandedDrawerForm />}
</div>
);
};
+7
View File
@@ -37,4 +37,11 @@ export const createDrawerUISlice: StateCreator<
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;
setIsValid: (v: boolean) => void;
subscribeIsValid: (callback: (isValid: boolean) => void) => () => void;
expandedDrawerOpen: boolean;
setExpandedDrawerOpen: (open: boolean) => void;
toggleExpandedDrawer: () => void;
};
export type UIStore = MainUiSlice & DrawerUISlice;