feat(FE-331): implement permission guard in marketing

This commit is contained in:
ValdiANS
2025-12-24 15:43:45 +07:00
parent 42a56a08d7
commit df6c1ae49d
3 changed files with 165 additions and 119 deletions
@@ -26,6 +26,8 @@ import { useRouter } from 'next/navigation';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import useSWR from 'swr'; import useSWR from 'swr';
import RequirePermission from '@/components/helper/RequirePermission';
import { useAuth } from '@/services/hooks/useAuth';
const RowsOptionsMenu = ({ const RowsOptionsMenu = ({
type = 'dropdown', type = 'dropdown',
@@ -50,6 +52,7 @@ const RowsOptionsMenu = ({
)} )}
> >
<div className='flex flex-col gap-1'> <div className='flex flex-col gap-1'>
<RequirePermission permissions='lti.marketing.delivery_order.detail'>
<Button <Button
href={`/marketing/detail?marketingId=${props.row.original.id}`} href={`/marketing/detail?marketingId=${props.row.original.id}`}
variant='ghost' variant='ghost'
@@ -59,7 +62,15 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:eye-outline' width={16} height={16} /> <Icon icon='mdi:eye-outline' width={16} height={16} />
Detail Detail
</Button> </Button>
</RequirePermission>
{props.row.original.latest_approval.step_number != 1 && ( {props.row.original.latest_approval.step_number != 1 && (
<RequirePermission
permissions={
props.row.original.latest_approval.step_number == 3
? 'lti.marketing.delivery_order.update'
: 'lti.marketing.delivery_order.create'
}
>
<Button <Button
href={ href={
props.row.original.latest_approval.step_number == 3 props.row.original.latest_approval.step_number == 3
@@ -80,8 +91,10 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:truck' width={16} height={16} /> <Icon icon='mdi:truck' width={16} height={16} />
Deliver Deliver
</Button> </Button>
</RequirePermission>
)} )}
{props.row.original.latest_approval.step_number != 3 && ( {props.row.original.latest_approval.step_number != 3 && (
<RequirePermission permissions='lti.marketing.sales_order.update'>
<Button <Button
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`} href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
variant='ghost' variant='ghost'
@@ -91,7 +104,9 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:pencil-outline' width={16} height={16} /> <Icon icon='mdi:pencil-outline' width={16} height={16} />
Edit Edit
</Button> </Button>
</RequirePermission>
)} )}
<RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button <Button
onClick={deleteClickHandler} onClick={deleteClickHandler}
variant='ghost' variant='ghost'
@@ -101,6 +116,7 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:delete-outline' width={16} height={16} /> <Icon icon='mdi:delete-outline' width={16} height={16} />
Delete Delete
</Button> </Button>
</RequirePermission>
</div> </div>
</div> </div>
); );
@@ -116,6 +132,7 @@ const MarketingTable = () => {
); );
const [selectedItem, setSelectedItem] = useState<Marketing | null>(null); const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({}); const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
const { permissionCheck } = useAuth();
const router = useRouter(); const router = useRouter();
@@ -270,10 +287,14 @@ const MarketingTable = () => {
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<div className='flex flex-col gap-2 mb-4'> <div className='flex flex-col gap-2 mb-4'>
<TableToolbar <TableToolbar
addButton={{ addButton={
permissionCheck('lti.marketing.sales_order.create')
? {
href: '/marketing/add/sales-orders', href: '/marketing/add/sales-orders',
label: 'Tambah Sales Order', label: 'Tambah Sales Order',
}} }
: undefined
}
search={{ search={{
value: search, value: search,
onChange: searchChangeHandler, onChange: searchChangeHandler,
@@ -281,6 +302,7 @@ const MarketingTable = () => {
}} }}
/> />
<div className='flex flex-row gap-2'> <div className='flex flex-row gap-2'>
<RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='success' color='success'
onClick={approveClickHandler} onClick={approveClickHandler}
@@ -290,7 +312,9 @@ const MarketingTable = () => {
<Icon icon='material-symbols:check' width={24} height={24} /> <Icon icon='material-symbols:check' width={24} height={24} />
Approve Approve
</Button> </Button>
</RequirePermission>
<RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='error' color='error'
onClick={rejectClickHandler} onClick={rejectClickHandler}
@@ -300,6 +324,7 @@ const MarketingTable = () => {
<Icon icon='material-symbols:close' width={24} height={24} /> <Icon icon='material-symbols:close' width={24} height={24} />
Reject Reject
</Button> </Button>
</RequirePermission>
</div> </div>
<TableRowSizeSelector <TableRowSizeSelector
value={pageSize} value={pageSize}
@@ -33,6 +33,7 @@ import { useState } from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport'; import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport';
import DeliveryOrderExport from '@/components/pages/marketing/pdf/DeliveryOrderExport'; import DeliveryOrderExport from '@/components/pages/marketing/pdf/DeliveryOrderExport';
import RequirePermission from '@/components/helper/RequirePermission';
const MarketingDetail = ({ const MarketingDetail = ({
initialValues, initialValues,
@@ -134,6 +135,7 @@ const MarketingDetail = ({
<div className='flex-row flex gap-3'> <div className='flex-row flex gap-3'>
{initialValues?.latest_approval?.step_number == 1 && ( {initialValues?.latest_approval?.step_number == 1 && (
<> <>
<RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='success' color='success'
onClick={approveClickHandler} onClick={approveClickHandler}
@@ -145,6 +147,9 @@ const MarketingDetail = ({
<Icon icon='mdi:check' width={24} height={24} /> <Icon icon='mdi:check' width={24} height={24} />
Approve Approve
</Button> </Button>
</RequirePermission>
<RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='error' color='error'
onClick={rejectClickHandler} onClick={rejectClickHandler}
@@ -156,9 +161,17 @@ const MarketingDetail = ({
<Icon icon='mdi:close' width={24} height={24} /> <Icon icon='mdi:close' width={24} height={24} />
Reject Reject
</Button> </Button>
</RequirePermission>
</> </>
)} )}
{initialValues?.latest_approval?.step_number != 1 && ( {initialValues?.latest_approval?.step_number != 1 && (
<RequirePermission
permissions={
initialValues?.latest_approval?.step_number == 3
? 'lti.marketing.delivery_order.update'
: 'lti.marketing.delivery_order.create'
}
>
<Button <Button
color='success' color='success'
href={ href={
@@ -173,6 +186,7 @@ const MarketingDetail = ({
: 'Tambah '} : 'Tambah '}
Delivery Order Delivery Order
</Button> </Button>
</RequirePermission>
)} )}
</div> </div>
@@ -413,6 +427,7 @@ const MarketingDetail = ({
)} )}
<div className='flex flex-row gap-3'> <div className='flex flex-row gap-3'>
{initialValues?.latest_approval?.step_number != 3 && ( {initialValues?.latest_approval?.step_number != 3 && (
<RequirePermission permissions='lti.marketing.sales_order.update'>
<Button <Button
color='warning' color='warning'
type='button' type='button'
@@ -421,11 +436,14 @@ const MarketingDetail = ({
<Icon icon='mdi:pencil' width={24} height={24} /> <Icon icon='mdi:pencil' width={24} height={24} />
Edit Edit
</Button> </Button>
</RequirePermission>
)} )}
<RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button color='error' onClick={deleteClickHandler}> <Button color='error' onClick={deleteClickHandler}>
<Icon icon='mdi:delete' width={24} height={24} /> <Icon icon='mdi:delete' width={24} height={24} />
Hapus Hapus
</Button> </Button>
</RequirePermission>
</div> </div>
</div> </div>
<ConfirmationModal <ConfirmationModal
@@ -47,6 +47,7 @@ import DeliveryOrderProductTable from '@/components/pages/marketing/form/table-v
import DeliveryOrderProductForm from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct'; import DeliveryOrderProductForm from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct';
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema'; import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema'; import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
import RequirePermission from '@/components/helper/RequirePermission';
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable); const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm); const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
@@ -689,6 +690,7 @@ const MarketingForm = ({
{/* Actions button */} {/* Actions button */}
{formType == 'edit' && ( {formType == 'edit' && (
<div className='flex flex-row justify-start'> <div className='flex flex-row justify-start'>
<RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button <Button
type='button' type='button'
color='error' color='error'
@@ -698,6 +700,7 @@ const MarketingForm = ({
<Icon icon='mdi:trash' width={24} height={24} /> <Icon icon='mdi:trash' width={24} height={24} />
Hapus Hapus
</Button> </Button>
</RequirePermission>
</div> </div>
)} )}