From 6cc5e5e931fb5d8153cac5e5bd55d1a2f0a50ab0 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 22:59:44 +0700 Subject: [PATCH 01/28] chore: adjust color variable and add shadow-button-soft custom shadow --- src/app/globals.css | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index eda1deab..0eb04a09 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,5 +1,6 @@ @import 'tailwindcss'; @plugin "daisyui"; +@import '../styles/tailwind.css'; @import '../styles/daisyui.css'; @import '../figma-make/styles/theme.css'; @@ -34,11 +35,11 @@ /* Status/Utility Colors */ --color-info: oklch(67.4% 0.176 238.9); --color-info-content: oklch(0% 0 0); /* #000000 */ - --color-success: oklch(62.3% 0.147 149); + --color-success: #00d390; --color-success-content: oklch(100% 0 0); /* #ffffff */ --color-warning: oklch(82.2% 0.165 91.9); --color-warning-content: oklch(0% 0 0); /* #000000 */ - --color-error: oklch(61.8% 0.203 27.8); + --color-error: #ff3a3a; --color-error-content: oklch(100% 0 0); /* #fffffff */ --radius-selector: 0rem; @@ -52,7 +53,7 @@ } :root { - --color-primary: #1f74bf; + --color-primary: #0069e0; } @theme { @@ -64,6 +65,9 @@ --container-lg: 64rem; --container-xl: 80rem; --container-2xl: 96rem; + + --shadow-button-soft: + 0 3px 2px -2px var(--color-base-200), 0 4px 3px -2px var(--color-base-200); } html { From b46f06a739e6d96ce1687466349f59f9838b0f73 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 22:59:54 +0700 Subject: [PATCH 02/28] chore: remove padding --- src/app/production/transfer-to-laying/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/production/transfer-to-laying/page.tsx b/src/app/production/transfer-to-laying/page.tsx index 84513542..1555dc38 100644 --- a/src/app/production/transfer-to-laying/page.tsx +++ b/src/app/production/transfer-to-laying/page.tsx @@ -2,7 +2,7 @@ import TransferToLayingsTable from '@/components/pages/production/transfer-to-la const TransferToLaying = () => { return ( -
+
); From d46652cb68560db1900c8239402e60bd6a7a809e Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:00:15 +0700 Subject: [PATCH 03/28] feat: add Breadcrumb component --- src/components/Breadcrumb.tsx | 263 ++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 src/components/Breadcrumb.tsx diff --git a/src/components/Breadcrumb.tsx b/src/components/Breadcrumb.tsx new file mode 100644 index 00000000..e5a4ef63 --- /dev/null +++ b/src/components/Breadcrumb.tsx @@ -0,0 +1,263 @@ +import React, { useId } from 'react'; +import Link from 'next/link'; +import { Icon } from '@iconify/react'; +import { cn, findMenuPath } from '@/lib/helper'; +import { Size } from '@/types/theme'; +import Button from '@/components/Button'; +import { MAIN_DRAWER_LINKS } from '@/config/constant'; + +interface BreadcrumbItem { + label: string; + href?: string; + icon?: React.ReactNode; + isActive?: boolean; + isDisabled?: boolean; +} + +interface BreadcrumbsProps extends React.HTMLAttributes { + items: BreadcrumbItem[]; + size?: Size; + maxVisibleItems?: number; + showEllipsisDropdown?: boolean; +} + +export function buildBreadcrumbs(pathname: string): BreadcrumbItem[] { + const menuPath = findMenuPath(MAIN_DRAWER_LINKS, pathname); + + if (!menuPath) return []; + + return menuPath.map((menu, index) => { + const isLast = index === menuPath.length - 1; + + return { + label: menu.text, + href: isLast ? menu.link : undefined, + isActive: isLast, + icon: menu.icon ? ( + + ) : undefined, + }; + }); +} + +const EllipsisDropdown = ({ + hiddenItems, +}: { + hiddenItems: BreadcrumbItem[]; +}) => { + const dropdownId = useId(); + const anchorId = useId(); + + return ( +
  • + {/* Ellipsis Button */} + + + {/* Dropdown Menu using popover API */} +
      + {hiddenItems.map((item, index) => { + const itemStyles = cn( + '[&]:flex [&]:items-center [&]:justify-start py-1 text-sm', + // Disabled state + item.isDisabled && 'text-base-content/40 opacity-50', + // Active/Last state + (item.isActive || item.isDisabled) && 'text-primary', + // Regular clickable state + !item.isDisabled && 'text-base-content/50' + ); + + const itemContent = ( +
      + {item.icon && ( + {item.icon} + )} + {item.label} +
      + ); + + return ( +
    • + {item.href && !item.isDisabled ? ( + e.stopPropagation()} + > + {itemContent} + + ) : ( +
      + {itemContent} +
      + )} +
    • + ); + })} +
    +
  • + ); +}; + +const Breadcrumb = ({ + items, + size = 'md', + maxVisibleItems = 3, + showEllipsisDropdown = true, + className, + ...props +}: BreadcrumbsProps) => { + const sizeClasses = { + xs: 'text-xs', + sm: 'text-sm', + md: 'text-base', + lg: 'text-lg', + xl: 'text-xl', + }; + + const getItemStyles = ( + item: BreadcrumbItem, + position: 'first' | 'middle' | 'last' = 'middle' + ) => { + const baseClasses = 'inline-flex items-center gap-2'; + + // Disabled state + if (item.isDisabled) { + return `${baseClasses} text-base-content/40 !cursor-default opacity-50 hover:!no-underline`; + } + + // Active/Last state (no underline) + if (item.isActive || position === 'last') { + return `${baseClasses} text-primary !cursor-pointer hover:!no-underline`; + } + + // Regular clickable state + return `${baseClasses} text-base-content/60`; + }; + + const renderItem = ( + item: BreadcrumbItem, + position: 'first' | 'middle' | 'last' = 'middle' + ) => { + const styles = getItemStyles(item, position); + + // Disabled items + if (item.isDisabled) { + return ( + + {item.icon && item.icon} + {item.label} + + ); + } + + // Active/Last items + if (item.isActive || position === 'last') { + if (item.href) { + return ( + + {item.icon && ( + {item.icon} + )} + {item.label} + + ); + } + return ( + + {item.icon && item.icon} + {item.label} + + ); + } + + // Regular items + if (item.href) { + return ( + + {item.icon && {item.icon}} + {item.label} + + ); + } + + return ( + + {item.icon && item.icon} + {item.label} + + ); + }; + + const renderBreadcrumbList = () => { + // Show all items if within limit + if (items.length <= maxVisibleItems) { + return items.map((item, index) => { + const position = + index === 0 + ? 'first' + : index === items.length - 1 + ? 'last' + : 'middle'; + return
  • {renderItem(item, position)}
  • ; + }); + } + + // Collapsed items indexing when exceeding limit + const firstItem = items[0]; + const lastItem = items[items.length - 1]; + const visibleMiddleItems = items.slice(1, -1).slice(-(maxVisibleItems - 2)); + const hiddenItems = items.slice(1, -1).slice(0, -(maxVisibleItems - 2)); + const showEllipsis = showEllipsisDropdown && hiddenItems.length > 0; + + return ( + <> +
  • {renderItem(firstItem, 'first')}
  • + + {/* Ellipsis for hidden items with dropdown */} + {showEllipsis && } + + {/* Middle items */} + {visibleMiddleItems.map((item, index) => ( +
  • {renderItem(item, 'middle')}
  • + ))} + +
  • {renderItem(lastItem, 'last')}
  • + + ); + }; + + return ( + + ); +}; + +export default Breadcrumb; From 146a63fc7050be3fc857dc327d85f1df85b3b506 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:00:44 +0700 Subject: [PATCH 04/28] chore: remove unnecessary code and remove title from Navbar prop --- src/components/MainDrawer.tsx | 36 +---------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/src/components/MainDrawer.tsx b/src/components/MainDrawer.tsx index 056d67a4..fdb65c38 100644 --- a/src/components/MainDrawer.tsx +++ b/src/components/MainDrawer.tsx @@ -78,40 +78,6 @@ const MainDrawer = ({ permissionCheck(permission) ); - const getPageTitle = useCallback(() => { - let title = ''; - - const activeMenu = MAIN_DRAWER_LINKS.find((item) => - isPathActive(pathname, item.link) - ); - - const traverseMenuTitle = (menu: typeof activeMenu) => { - if (!menu) return; - - const hasSubmenu = menu?.submenu && menu?.submenu.length > 0; - - if (!title) { - title += menu?.text; - } else { - title += ' - ' + menu?.text; - } - - if (!hasSubmenu || !menu.submenu) return; - - const activeSubmenu = menu.submenu?.find((item) => - isPathActive(pathname, item.link) - ); - - traverseMenuTitle(activeSubmenu); - }; - - traverseMenuTitle(activeMenu); - - return title; - }, [pathname]); - - const pageTitle = getPageTitle(); - const toggleSidebar = () => { setMainDrawerOpen(!mainDrawerOpen); }; @@ -132,7 +98,7 @@ const MainDrawer = ({ }} >
    - + {children}
    From abc35314a08398c6fa8fee0f8c5bb09603c96c26 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:01:07 +0700 Subject: [PATCH 05/28] chore: adjust Navbar styling and add breadcrumb to navbar --- src/components/Navbar.tsx | 72 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 280217a0..4998ca66 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,26 +1,26 @@ 'use client'; import toast from 'react-hot-toast'; -import { useRouter } from 'next/navigation'; +import { usePathname, useRouter } from 'next/navigation'; import { Icon } from '@iconify/react'; -import Menu from '@/components/menu/Menu'; -import MenuItem from '@/components/menu/MenuItem'; import Button from '@/components/Button'; -import Dropdown from '@/components/Dropdown'; +import Breadcrumb, { buildBreadcrumbs } from '@/components/Breadcrumb'; +import PopoverButton from '@/components/popover/PopoverButton'; +import PopoverContent from '@/components/popover/PopoverContent'; import { useAuth } from '@/services/hooks/useAuth'; import { AuthApi } from '@/services/api/auth'; import { isResponseError } from '@/lib/api-helper'; interface NavbarProps { - title: string; toggleSidebar?: () => void; } -const Navbar = ({ title, toggleSidebar }: NavbarProps) => { +const Navbar = ({ toggleSidebar }: NavbarProps) => { const { setUser } = useAuth(); const router = useRouter(); + const pathname = usePathname(); const logoutClickHandler = async () => { const logoutRes = await AuthApi.logout(); @@ -35,42 +35,52 @@ const Navbar = ({ title, toggleSidebar }: NavbarProps) => { }; return ( -
    +
    {toggleSidebar && ( - )} - {title} +
    - -
    - -
    -
    - } - className={{ - content: 'w-52 mt-3', - }} + - - - - + + + + + +
    ); From 51c3277b6c5f6609644fc81c51e3dd3cea885708 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:01:33 +0700 Subject: [PATCH 06/28] feat: add selectedBodyRowClassName class name --- src/components/Table.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/Table.tsx b/src/components/Table.tsx index 37bc118a..0e095c1f 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -31,6 +31,7 @@ interface TableClassNames { headerColumnClassName?: string; tableBodyClassName?: string; bodyRowClassName?: string; + selectedBodyRowClassName?: string; bodyColumnClassName?: string; tableFooterClassName?: string; footerRowClassName?: string; @@ -88,9 +89,11 @@ export const TABLE_DEFAULT_STYLING = { headerColumnClassName: 'px-4 py-3 border-base-content/10 text-base-content/50 text-sm font-medium', tableBodyClassName: '', - bodyRowClassName: 'border-t border-base-content/10', + bodyRowClassName: + 'transition-all duration-200 border-t border-base-content/10 bg-transparent', + selectedBodyRowClassName: 'bg-primary/5', bodyColumnClassName: 'px-4 py-3 text-base-content', - paginationClassName: '', + paginationClassName: 'px-3', tableFooterClassName: 'font-semibold border-base-content/10', footerRowClassName: 'bg-base-200 border-t-2 border-base-content/10', footerColumnClassName: 'p-4 text-base-content whitespace-nowrap', @@ -353,7 +356,11 @@ const Table = ({ key={row.id} className={cn( TABLE_DEFAULT_STYLING.bodyRowClassName, - tableClassNames.bodyRowClassName + tableClassNames.bodyRowClassName, + { + [tableClassNames.selectedBodyRowClassName]: + row.getIsSelected(), + } )} > {row.getVisibleCells().map((cell) => ( From 196db657e8bdce502b8112080212716103f4c3f8 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:01:43 +0700 Subject: [PATCH 07/28] feat: create StatusBadge component --- src/components/helper/StatusBadge.tsx | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/components/helper/StatusBadge.tsx diff --git a/src/components/helper/StatusBadge.tsx b/src/components/helper/StatusBadge.tsx new file mode 100644 index 00000000..fa15812e --- /dev/null +++ b/src/components/helper/StatusBadge.tsx @@ -0,0 +1,44 @@ +import Badge from '@/components/Badge'; +import { cn } from '@/lib/helper'; +import { Color } from '@/types/theme'; + +interface StatusBadgeProps { + color: Color; + text: string; +} + +const StatusBadge = ({ color = 'neutral', text }: StatusBadgeProps) => { + return ( + + + + + + {text} + + ); +}; + +export default StatusBadge; From d1a0cdc1b99e2b72c1043a2ef3bbd7263c183a43 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:01:59 +0700 Subject: [PATCH 08/28] chore: adjust DateInput styling --- src/components/input/DateInput.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/input/DateInput.tsx b/src/components/input/DateInput.tsx index a424d723..c1d87afd 100644 --- a/src/components/input/DateInput.tsx +++ b/src/components/input/DateInput.tsx @@ -231,7 +231,7 @@ const DateInput = ({
    )} handleClick(e as unknown as React.MouseEvent) } From 5a88718454b97e16853b8b8fa59d87a29f549b31 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:02:12 +0700 Subject: [PATCH 09/28] chore: adjust SelectInput styling --- src/components/input/SelectInput.tsx | 40 +++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/components/input/SelectInput.tsx b/src/components/input/SelectInput.tsx index 2571efc5..1eb3ccd8 100644 --- a/src/components/input/SelectInput.tsx +++ b/src/components/input/SelectInput.tsx @@ -95,7 +95,7 @@ const CustomControl = < return ( -
    +
    {shouldShowAdornment && startAdornment} {children}
    @@ -118,7 +118,7 @@ const CustomMenuList = < {children} {options.length > 0 && isLoading && ( -
    +
    )} @@ -204,16 +204,11 @@ const SelectInput = (props: SelectInputProps) => { }; return ( -
    +
    {label && ( (props: SelectInputProps) => { ...(!startAdornment && { control: ({ isFocused, isDisabled }) => cn( - 'w-full min-h-12! rounded border bg-white transition-shadow cursor-pointer!', + 'w-full min-h-12! rounded-lg! border bg-white transition-shadow cursor-pointer!', { 'border-red-500! ring-2 ring-red-200': isError, 'border-indigo-500 ring-2 ring-indigo-200': isFocused, - 'border-gray-300': !isError && !isFocused, + 'border-base-content/10!': !isError && !isFocused, 'bg-gray-100 text-gray-400 cursor-not-allowed': isDisabled, } ), - valueContainer: () => cn('flex-1 px-4! py-2! gap-1'), + valueContainer: () => cn('flex-1 p-3! py-2! gap-1'), }), placeholder: () => cn({ 'text-gray-400': !isError, 'text-red-300!': isError }), singleValue: () => cn({ 'text-gray-900': !isError, 'text-error!': isError }), - input: () => cn('text-gray-900'), + input: () => cn('text-gray-900 m-0! p-0!'), indicatorsContainer: () => cn('flex items-center gap-1 pr-2'), dropdownIndicator: ({ isFocused }) => - cn('p-1 rounded hover:bg-gray-100', { + cn('p-1! rounded hover:bg-gray-100', { 'text-gray-900': isFocused, 'text-gray-500': !isFocused, 'text-error!': isError, }), + clearIndicator: () => cn('p-1! rounded hover:bg-gray-100'), menu: () => - cn('border border-gray-200 rounded! bg-base-100 shadow-lg!'), - menuList: () => cn('p-2! max-h-60 overflow-auto'), + cn( + 'border border-base-content/5 rounded-xl! bg-base-100 shadow-lg! my-1.5!' + ), + menuList: () => cn('p-0! max-h-60 overflow-auto'), option: ({ isFocused, isSelected }) => - cn('mt-1 px-3 py-2 rounded-md cursor-pointer!', { + cn('px-3 py-2 rounded-md cursor-pointer!', { 'bg-indigo-600 text-white': isFocused, 'bg-blue-500!': isSelected, 'text-gray-700': !isFocused && !isSelected, @@ -287,13 +285,17 @@ const SelectInput = (props: SelectInputProps) => { multiValue: ({ getValue, index }) => { const selectedValues = getValue() as T[]; return cn( - 'bg-indigo-50 rounded py-0.5 pl-2 pr-1 flex items-center gap-1!', + 'bg-base-200! rounded-lg! py-[3px] px-2.5 m-0! flex items-center gap-1! w-fit gap-2!', selectedValues[index]?.className ); }, + multiValueRemove: () => cn('p-0! w-3 h-3'), multiValueLabel: ({ getValue, index }) => { const selectedValues = getValue() as T[]; - return cn('text-indigo-700', selectedValues[index]?.labelClassName); + return cn( + 'p-0! text-base-content! text-xs!', + selectedValues[index]?.labelClassName + ); }, }} components={{ From af9c4bbdb9b3d8d4dfa2dd06635ccb8bccef3d29 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:02:25 +0700 Subject: [PATCH 10/28] chore: adjust SelectInputCheckbox styling --- src/components/input/SelectInputCheckbox.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/input/SelectInputCheckbox.tsx b/src/components/input/SelectInputCheckbox.tsx index 24125204..a334d133 100644 --- a/src/components/input/SelectInputCheckbox.tsx +++ b/src/components/input/SelectInputCheckbox.tsx @@ -25,14 +25,18 @@ const CheckboxOption = < >( props: OptionProps ) => { - const { isSelected, label, innerRef, innerProps, className } = props; + const { isSelected, label, innerRef, innerProps, className, isFocused } = + props; return (
    @@ -40,9 +44,12 @@ const CheckboxOption = < type='checkbox' checked={isSelected} onChange={() => null} - className='checkbox checkbox-sm rounded checkbox-primary pointer-events-none' + className='checkbox checkbox-sm rounded-md checkbox-primary pointer-events-none border-base-content/10' /> - + +
    ); }; From ed3d525c06173e2f4fd8e02229d5d9aa42929dbc Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:02:49 +0700 Subject: [PATCH 11/28] chore: adjust ConfirmationModal component styling --- src/components/modal/ConfirmationModal.tsx | 86 +++++++++++----------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/src/components/modal/ConfirmationModal.tsx b/src/components/modal/ConfirmationModal.tsx index 9cf17008..98a0b51d 100644 --- a/src/components/modal/ConfirmationModal.tsx +++ b/src/components/modal/ConfirmationModal.tsx @@ -35,29 +35,29 @@ const iconConfig = { info: { icon: 'material-symbols:info-outline-rounded', iconClassName: 'text-info-content', - bgClassName: 'bg-info', - outerRingClassName: 'bg-info/20', - borderClassName: 'border-info', + innerRingClassName: 'bg-info', + middleRingClassName: 'bg-info/12', + outerRingClassName: 'border-info/12 bg-info/8', }, success: { icon: 'heroicons:check', iconClassName: 'text-white', - bgClassName: 'bg-[#00D390]', - outerRingClassName: 'bg-[#00D3901F]', - borderClassName: 'border-[#CCF7EB]', + innerRingClassName: 'bg-success', + middleRingClassName: 'bg-success/12', + outerRingClassName: 'border-success/12 bg-success/8', }, error: { - icon: 'solar:danger-triangle-linear', + icon: 'heroicons:exclamation-triangle', iconClassName: 'text-error-content', - bgClassName: 'bg-[#f03338]', - outerRingClassName: 'bg-[#f3cdcd]', - borderClassName: 'border-[#fff0ef]', + innerRingClassName: 'bg-error', + middleRingClassName: 'bg-error/12', + outerRingClassName: 'border-error/12 bg-error/8', }, } as const; const ConfirmationModalIcon = ({ type, - size = 24, + size = 16, }: { type: 'info' | 'success' | 'error'; size?: number; @@ -65,28 +65,22 @@ const ConfirmationModalIcon = ({ const config = iconConfig[type]; return ( -
    -
    -
    -
    - -
    +
    +
    +
    +
    @@ -103,7 +97,7 @@ const ConfirmationModal = ({ secondaryButton, className, children, - iconSize = 32, + iconSize = 16, iconPosition = 'center', }: ConfirmationModalProps) => { const [isPrimaryButtonLoading, setIsPrimaryButtonLoading] = useState(false); @@ -123,7 +117,14 @@ const ConfirmationModal = ({ }; return ( - +
    {iconPosition === 'center' ? ( <> @@ -143,7 +144,7 @@ const ConfirmationModal = ({ ) : (
    -

    +

    {text ?? 'Apakah anda yakin ingin melakukan hal ini?'}

    {subtitleText && ( -

    {subtitleText}

    +

    {subtitleText}

    )}
    @@ -166,7 +167,7 @@ const ConfirmationModal = ({ {children &&
    {children}
    } -
    +
    {secondaryButton && secondaryButton.text && ( @@ -200,7 +204,7 @@ const ConfirmationModal = ({ ? primaryButton?.isLoading : isPrimaryButtonLoading } - className='grow' + className={cn('p-2 rounded-xl text-sm', primaryButton?.className)} > {primaryButton?.text ?? 'Ya'} From 6c70dc93ce80691cc63c3f3bd7c50004c98db135 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Fri, 23 Jan 2026 23:03:13 +0700 Subject: [PATCH 12/28] chore: pass the rest of the props to ConfirmationModal --- src/components/modal/ConfirmationModalWithNotes.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/modal/ConfirmationModalWithNotes.tsx b/src/components/modal/ConfirmationModalWithNotes.tsx index f3403abf..a5551571 100644 --- a/src/components/modal/ConfirmationModalWithNotes.tsx +++ b/src/components/modal/ConfirmationModalWithNotes.tsx @@ -32,6 +32,7 @@ const ConfirmationModalWithNotes: React.FC = ({ className, rows = 3, placeholder = 'Catatan...', + ...props }) => { const randomId = useId(); const [notes, setNotes] = useState(''); @@ -55,6 +56,7 @@ const ConfirmationModalWithNotes: React.FC = ({ }} secondaryButton={secondaryButton} className={className} + {...props} >