mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
172 lines
5.6 KiB
TypeScript
172 lines
5.6 KiB
TypeScript
'use client';
|
|
|
|
import Button from '@/components/Button';
|
|
import Tooltip from '@/components/Tooltip';
|
|
import { cn } from '@/lib/helper';
|
|
import { Icon } from '@iconify/react';
|
|
|
|
import { useAuth } from '@/services/hooks/useAuth';
|
|
|
|
type FloatingActionsButtonProps = {
|
|
actions: {
|
|
action: 'DETAIL' | 'EDIT' | 'DELETE';
|
|
icon: string;
|
|
label?: string;
|
|
onClick?: () => void;
|
|
hidden?: boolean;
|
|
disabled?: boolean;
|
|
permissions?: string | string[];
|
|
}[];
|
|
approvals: {
|
|
action: 'APPROVED' | 'REJECTED';
|
|
icon: string;
|
|
label?: string;
|
|
onClick?: () => void;
|
|
disabled?: boolean;
|
|
permissions?: string | string[];
|
|
}[];
|
|
selectedRowIds: number[];
|
|
onClose: () => void;
|
|
};
|
|
|
|
const FloatingActionsButton = ({
|
|
actions,
|
|
approvals,
|
|
selectedRowIds,
|
|
onClose,
|
|
}: FloatingActionsButtonProps) => {
|
|
const { permissionCheck } = useAuth();
|
|
// Jika tidak ada baris yang dipilih, jangan tampilkan FAB
|
|
const positionStyles =
|
|
selectedRowIds.length > 0
|
|
? 'bottom-[10%] opacity-100'
|
|
: 'bottom-[-10%] opacity-0';
|
|
|
|
// Helper untuk menentukan gaya warna tombol approval
|
|
const getApprovalColor = (action: 'APPROVED' | 'REJECTED') => {
|
|
if (action === 'APPROVED') return 'success';
|
|
if (action === 'REJECTED') return 'error';
|
|
return 'primary';
|
|
};
|
|
|
|
const getActionColor = (action: 'DETAIL' | 'EDIT' | 'DELETE') => {
|
|
if (action === 'DETAIL') return 'white';
|
|
if (action === 'EDIT') return 'warning';
|
|
if (action === 'DELETE') return 'error';
|
|
return 'primary';
|
|
};
|
|
|
|
return (
|
|
// Container utama FAB
|
|
<div
|
|
className={cn(
|
|
`absolute ${positionStyles} inset-x-1/2 -translate-x-1/2 z-50`,
|
|
'mx-auto w-full max-w-sm sm:mx-0 bg-base-300 p-4 rounded-xl shadow-md transition-all duration-300 transform',
|
|
'bg-slate-950 backdrop-blur-md'
|
|
)}
|
|
>
|
|
<div className='flex flex-col gap-3'>
|
|
{/* === BARIS ATAS: Status Seleksi dan Actions (Termasuk Close) === */}
|
|
<div className='flex justify-between items-center text-white'>
|
|
<h4 className='text-base font-semibold'>
|
|
{selectedRowIds.length} Selected
|
|
</h4>
|
|
|
|
<div className='flex flex-row gap-1 items-stretch'>
|
|
<div className='flex gap-4 items-center'>
|
|
{/* Render Aksi dari props.actions */}
|
|
{actions
|
|
.filter((action) => {
|
|
if (action.hidden) return false;
|
|
if (action.permissions) {
|
|
if (typeof action.permissions === 'string') {
|
|
return permissionCheck(action.permissions);
|
|
}
|
|
return action.permissions.some((permission) =>
|
|
permissionCheck(permission)
|
|
);
|
|
}
|
|
return true;
|
|
})
|
|
.map((action, index) => {
|
|
return (
|
|
<Button
|
|
key={index}
|
|
onClick={action.onClick}
|
|
className='text-white hover:text-gray-400 tooltip tooltip-bottom p-0'
|
|
variant='link'
|
|
disabled={action.disabled}
|
|
>
|
|
<Tooltip content={action.label || action.action}>
|
|
<Icon
|
|
icon={action.icon}
|
|
width={20}
|
|
height={20}
|
|
className={`text-${getActionColor(action.action)} font-thin`}
|
|
/>
|
|
</Tooltip>
|
|
</Button>
|
|
);
|
|
})}
|
|
|
|
<div className='border-[0.5px] border-white/30 h-full'></div>
|
|
|
|
{/* Tombol Close */}
|
|
<Button
|
|
onClick={onClose}
|
|
className='text-white hover:text-gray-400 p-0'
|
|
variant='link'
|
|
>
|
|
<Tooltip content='Close'>
|
|
<Icon icon='mdi:close' width={20} height={20} />
|
|
</Tooltip>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* === BARIS BAWAH: Approval Buttons (Approve/Reject) === */}
|
|
<div className={`grid grid-cols-${approvals.length} gap-3`}>
|
|
{approvals
|
|
.filter((approval) => {
|
|
if (approval.permissions) {
|
|
if (typeof approval.permissions === 'string') {
|
|
return permissionCheck(approval.permissions);
|
|
}
|
|
return approval.permissions.some((permission) =>
|
|
permissionCheck(permission)
|
|
);
|
|
}
|
|
return true;
|
|
})
|
|
.map((approval, index) => (
|
|
<Button
|
|
key={index}
|
|
onClick={approval.onClick}
|
|
className={cn(
|
|
'btn btn-lg w-full',
|
|
'bg-white/20 border-white/30',
|
|
'text-white/50 font-semibold flex items-center gap-2 rounded-lg transition-all duration-200',
|
|
approval.disabled
|
|
? 'cursor-not-allowed'
|
|
: 'hover:text-white/100 hover:bg-white/40 hover:border-white/50'
|
|
)}
|
|
disabled={approval.disabled}
|
|
>
|
|
<Icon
|
|
icon={approval.icon}
|
|
width={20}
|
|
height={20}
|
|
className={`text-${getApprovalColor(approval.action)}`}
|
|
/>
|
|
{approval.label || approval.action}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FloatingActionsButton;
|