From 979f803d7586984fe231000ae4cfab2bf470eba7 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Mon, 19 Jan 2026 14:05:08 +0700 Subject: [PATCH 01/16] chore: rename title --- src/config/constant.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/constant.ts b/src/config/constant.ts index b3621c8f..8c9175db 100644 --- a/src/config/constant.ts +++ b/src/config/constant.ts @@ -94,7 +94,7 @@ export const MAIN_DRAWER_LINKS: SidebarMenuItem[] = [ permission: ['lti.production.recording.list'], }, { - text: 'Transfer to Laying', + text: 'Transfer ke Laying', link: '/production/transfer-to-laying', }, { From 876d564f267f33887f88914666b9b99c09419091 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Mon, 19 Jan 2026 14:06:04 +0700 Subject: [PATCH 02/16] fix: refactor confirmationModalDeleteClickHandler function --- .../TransferToLayingsTable.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx index 860c4616..727d49cd 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx @@ -31,7 +31,7 @@ import RequirePermission from '@/components/helper/RequirePermission'; import { TransferToLaying } from '@/types/api/production/transfer-to-laying'; import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying'; import { cn, formatDate } from '@/lib/helper'; -import { isResponseSuccess } from '@/lib/api-helper'; +import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { ROWS_OPTIONS } from '@/config/constant'; import { Flock } from '@/types/api/master-data/flock'; @@ -397,17 +397,21 @@ const TransferToLayingsTable = () => { const confirmationModalDeleteClickHandler = async () => { setIsDeleteLoading(true); - try { - await TransferToLayingApi.delete(selectedTransferToLaying?.id as number); + const deleteResponse = await TransferToLayingApi.delete( + selectedTransferToLaying?.id as number + ); - toast.success('Berhasil menghapus data transfer ke laying!'); - refreshTransferToLayings(); - } catch (error) { - toast.success('Gagal menghapus data transfer ke laying!'); - } finally { - deleteModal.closeModal(); + if (isResponseError(deleteResponse)) { + toast.error(deleteResponse.message); setIsDeleteLoading(false); + return; } + + refreshTransferToLayings(); + + deleteModal.closeModal(); + toast.success('Berhasil menghapus data transfer ke laying!'); + setIsDeleteLoading(false); }; const confirmationModalApproveClickHandler = async (notes: string) => { From 6ece591d2b9ceb8e9438e50e037f52255ad03254 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:11:45 +0700 Subject: [PATCH 03/16] chore: update daisyUI version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61da9724..d418eb73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "daisyui": "^5.5.8", + "daisyui": "^5.5.14", "eslint": "^9", "eslint-config-next": "^15.5.7", "husky": "^9.1.7", @@ -5855,9 +5855,9 @@ } }, "node_modules/daisyui": { - "version": "5.5.8", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.8.tgz", - "integrity": "sha512-6psL9jIEOFOw68V10j/BKCWcRgx8dh81mmNxShr+g7HDM6UHNoPharlp9zq/PQkHNuGU1ZQsajR3HgpvavbRKQ==", + "version": "5.5.14", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.14.tgz", + "integrity": "sha512-L47rvw7I7hK68TA97VB8Ee0woHew+/ohR6Lx6Ah/krfISOqcG4My7poNpX5Mo5/ytMxiR40fEaz6njzDi7cuSg==", "dev": true, "license": "MIT", "funding": { diff --git a/package.json b/package.json index 981413b3..68b78aae 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "daisyui": "^5.5.8", + "daisyui": "^5.5.14", "eslint": "^9", "eslint-config-next": "^15.5.7", "husky": "^9.1.7", From 572e5233b454e09b16bbaade96c7684f60894732 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:13:29 +0700 Subject: [PATCH 04/16] chore: add roboto font --- src/app/globals.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/globals.css b/src/app/globals.css index 0e3d1e43..eda1deab 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -57,6 +57,7 @@ @theme { --font-inter: var(--font-inter); + --font-roboto: var(--font-roboto); --container-sm: 40rem; --container-md: 48rem; From 1a3ea5be8cf99d424b101906e1cd82312b370074 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:15:38 +0700 Subject: [PATCH 05/16] chore: add roboto font --- src/app/layout.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 91e9d624..a580cc53 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata, Viewport } from 'next'; -import { Inter } from 'next/font/google'; +import { Inter, Roboto } from 'next/font/google'; import '@/app/globals.css'; import { Toaster } from 'react-hot-toast'; @@ -12,6 +12,12 @@ const inter = Inter({ subsets: ['latin'], }); +const roboto = Roboto({ + variable: '--font-roboto', + subsets: ['latin'], + weight: ['200', '300', '400', '500', '600', '700', '900'], +}); + export const viewport: Viewport = { themeColor: '#1f74bf', colorScheme: 'light', @@ -30,7 +36,9 @@ export default function RootLayout({ }>) { return ( - + {children} From 7a2bdb25e48581210bb60ed8d970b68ae83a6215 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:29:03 +0700 Subject: [PATCH 06/16] chore: change className.drawerContent to className.drawerSidebarContent --- src/components/Drawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Drawer.tsx b/src/components/Drawer.tsx index 7b5e2374..bbc36782 100644 --- a/src/components/Drawer.tsx +++ b/src/components/Drawer.tsx @@ -162,7 +162,7 @@ const Drawer = ({
From 876217d1af177102fed002ec2a3f47324cafd12e Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:30:04 +0700 Subject: [PATCH 07/16] chore: adjust MainDrawer styling --- src/components/MainDrawer.tsx | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/components/MainDrawer.tsx b/src/components/MainDrawer.tsx index eaf1e2c1..056d67a4 100644 --- a/src/components/MainDrawer.tsx +++ b/src/components/MainDrawer.tsx @@ -26,29 +26,34 @@ const MainDrawerContent = () => { }; return ( -
-
- MBU Logo +
+
+
+ LTI Logo -

LTI ERP

+
+

LTI ERP

+

Lumbung Telur Indonesia

+
+
@@ -121,6 +126,10 @@ const MainDrawer = ({ setOpen={setMainDrawerOpen} openOnLarge sidebarContent={} + className={{ + drawerSide: 'border-r border-base-content/10', + drawerSidebarContent: 'min-w-[244px] lg:w-[244px]', + }} >
From 324b6b69e25cf2331fa6b87c925b555cbee3d913 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:31:05 +0700 Subject: [PATCH 08/16] chore: use TABLE_DEFAULT_STYLING for default styling --- src/components/Table.tsx | 75 ++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/src/components/Table.tsx b/src/components/Table.tsx index 9791dd59..37bc118a 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -86,7 +86,7 @@ export const TABLE_DEFAULT_STYLING = { tableHeaderClassName: '', headerRowClassName: '', headerColumnClassName: - 'px-4 py-3 border-base-content/10 text-base-content/50', + 'px-4 py-3 border-base-content/10 text-base-content/50 text-sm font-medium', tableBodyClassName: '', bodyRowClassName: 'border-t border-base-content/10', bodyColumnClassName: 'px-4 py-3 text-base-content', @@ -222,14 +222,37 @@ const Table = ({ }, [pageSize, setPageSize]); return ( -
-
- - +
+
+
+ {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const columnRelativeDepth = @@ -262,6 +285,7 @@ const Table = ({ { 'border-b': header.colSpan > 1, }, + TABLE_DEFAULT_STYLING.headerColumnClassName, tableClassNames.headerColumnClassName )} > @@ -311,7 +335,12 @@ const Table = ({ ))} - + {table.getRowModel().rows.map((row) => { const customRowContent = renderCustomRow?.(row); @@ -320,12 +349,19 @@ const Table = ({ } return ( - + {row.getVisibleCells().map((cell) => ( - + {renderFooter && ( - + {table.getAllLeafColumns().map((column) => (
@@ -342,14 +378,25 @@ const Table = ({ ); })}
@@ -372,7 +419,13 @@ const Table = ({ emptyContent} {data.length > 0 && table.getRowModel().rows.length > 0 && !isLoading && ( -
+
Date: Tue, 20 Jan 2026 16:33:35 +0700 Subject: [PATCH 09/16] chore: adjust SidebarMenu styling --- src/components/molecules/SidebarMenu.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/molecules/SidebarMenu.tsx b/src/components/molecules/SidebarMenu.tsx index 4b85c2c8..66f522f9 100644 --- a/src/components/molecules/SidebarMenu.tsx +++ b/src/components/molecules/SidebarMenu.tsx @@ -39,16 +39,15 @@ const SidebarMenuItem = ({ item, activeLink }: SidebarMenuItemProps) => {
  • {item.icon && } - {item.text} + {item.text}
  • ); @@ -62,12 +61,13 @@ const SidebarMenuItem = ({ item, activeLink }: SidebarMenuItemProps) => {
    {item.icon && } - {item.text} + {item.text}
      @@ -88,7 +88,7 @@ const SidebarMenuItem = ({ item, activeLink }: SidebarMenuItemProps) => { const SidebarMenu = ({ menu, activeLink }: SidebarMenuProps) => { return ( - + {menu.map((menuItem, menuIdx) => { return ( Date: Tue, 20 Jan 2026 16:35:12 +0700 Subject: [PATCH 10/16] feat: add total average weight and total sales price in table footer --- .../pages/report/DailyMarketingsTable.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/components/pages/report/DailyMarketingsTable.tsx b/src/components/pages/report/DailyMarketingsTable.tsx index d270d6d7..b9906e53 100644 --- a/src/components/pages/report/DailyMarketingsTable.tsx +++ b/src/components/pages/report/DailyMarketingsTable.tsx @@ -123,6 +123,13 @@ const DailyMarketingsTable = ({ accessorKey: 'average_weight', header: 'Bobot Rata-Rata (Kg)', cell: (props) => formatNumber(props.row.original.average_weight_kg), + footer: () => { + const totalAverageWeightKg = isResponseSuccess(dailyMarketings) + ? dailyMarketings?.total?.total_average_weight + : 0; + + return totalAverageWeightKg ? formatNumber(totalAverageWeightKg) : '-'; + }, }, { accessorKey: 'total_weight', @@ -140,6 +147,13 @@ const DailyMarketingsTable = ({ accessorKey: 'sales_price', header: 'Harga Jual (Rp)', cell: (props) => formatCurrency(props.row.original.sales_price_per_kg), + footer: () => { + const totalSalesPrice = isResponseSuccess(dailyMarketings) + ? dailyMarketings?.total?.total_sales_price + : 0; + + return totalSalesPrice ? formatNumber(totalSalesPrice) : '-'; + }, }, { accessorKey: 'hpp_price', From 0439c21ec645cf68c54c47287fa2aeb90f118836 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 16:44:42 +0700 Subject: [PATCH 11/16] chore: change button variant --- src/components/table/RowCollapseOptions.tsx | 2 +- src/components/table/RowDropdownOptions.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/table/RowCollapseOptions.tsx b/src/components/table/RowCollapseOptions.tsx index ce90314c..532a96b4 100644 --- a/src/components/table/RowCollapseOptions.tsx +++ b/src/components/table/RowCollapseOptions.tsx @@ -12,7 +12,7 @@ const RowCollapseOptions = ({ children }: RowCollapseOptionsProps) => { return ( + } diff --git a/src/components/table/RowDropdownOptions.tsx b/src/components/table/RowDropdownOptions.tsx index 1f1bc81b..a2535c2b 100644 --- a/src/components/table/RowDropdownOptions.tsx +++ b/src/components/table/RowDropdownOptions.tsx @@ -21,7 +21,7 @@ const RowDropdownOptions = ({ 'dropdown-end': isLast2Rows, })} > - From 7a45926c493c23aef9d2933f14e169ff5186c802 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 17:04:41 +0700 Subject: [PATCH 12/16] feat: adjust SalesSummary type --- src/types/api/report/marketing.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types/api/report/marketing.d.ts b/src/types/api/report/marketing.d.ts index 4a0ab306..925707eb 100644 --- a/src/types/api/report/marketing.d.ts +++ b/src/types/api/report/marketing.d.ts @@ -41,7 +41,9 @@ export type DailyMarketingRow = BaseMetadata & BaseDailyMarketingRow; export interface SalesSummary { total_qty: number; + total_average_weight: number; total_weight_kg: number; + total_sales_price: number; total_sales_amount: number; total_hpp_amount: number; total_hpp_price_per_kg: number; From 26d89c35a5ded831d833c7c2fc6a2b1d700abaec Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 17:07:24 +0700 Subject: [PATCH 13/16] chore: adjust TransferToLayingsTable styling --- .../TransferToLayingsTable.tsx | 309 ++++++++---------- 1 file changed, 145 insertions(+), 164 deletions(-) diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx index 727d49cd..309c42b2 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ChangeEventHandler, useState } from 'react'; +import { ChangeEventHandler, useEffect, useState } from 'react'; import useSWR from 'swr'; import { CellContext, @@ -20,33 +20,32 @@ import SelectInput, { OptionType, useSelect, } from '@/components/input/SelectInput'; -import RowDropdownOptions from '@/components/table/RowDropdownOptions'; -import RowCollapseOptions from '@/components/table/RowCollapseOptions'; -import TextInput from '@/components/input/TextInput'; import CheckboxInput from '@/components/input/CheckboxInput'; -import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper'; import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes'; import RequirePermission from '@/components/helper/RequirePermission'; +import DateInput from '@/components/input/DateInput'; +import PopoverButton from '@/components/popover/PopoverButton'; import { TransferToLaying } from '@/types/api/production/transfer-to-laying'; import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying'; import { cn, formatDate } from '@/lib/helper'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import { useTableFilter } from '@/services/hooks/useTableFilter'; -import { ROWS_OPTIONS } from '@/config/constant'; import { Flock } from '@/types/api/master-data/flock'; -import { FlockApi } from '@/services/api/master-data'; -import PillBadge from '@/components/PillBadge'; +import { ProjectFlockApi } from '@/services/api/production'; +import Badge from '@/components/Badge'; +import { Color } from '@/types/theme'; +import PopoverContent from '@/components/popover/PopoverContent'; const RowOptionsMenu = ({ - type = 'dropdown', props, + popoverPosition = 'bottom', approveClickHandler, rejectClickHandler, deleteClickHandler, }: { - type: 'dropdown' | 'collapse'; props: CellContext; + popoverPosition: 'bottom' | 'top'; approveClickHandler: () => void; rejectClickHandler: () => void; deleteClickHandler: () => void; @@ -60,80 +59,99 @@ const RowOptionsMenu = ({ const showApproveButton = showEditButton; const showRejectButton = showEditButton; + const popoverId = `transferToLaying#${props.row.original.id}`; + const popoverAnchorName = `--anchor-transferToLaying#${props.row.original.id}`; + return ( - - - - +
      + + + - {showEditButton && ( - - - - )} + +
      + + + - {/* TODO: apply RBAC */} - {showApproveButton && ( - - - - )} - {showRejectButton && ( - - - - )} - {showDeleteButton && ( - - - - )} - + {showEditButton && ( + + + + )} + + {showApproveButton && ( + + + + )} + + {showRejectButton && ( + + + + )} + + {showDeleteButton && ( + +
      + +
      + )} +
      +
      +
      ); }; @@ -150,6 +168,8 @@ const TransferToLayingsTable = () => { transferDate: '', flockSource: '', flockDestination: '', + filter_by: '', + sort_by: '', }, paramMap: { page: 'page', @@ -157,6 +177,8 @@ const TransferToLayingsTable = () => { transferDate: 'transfer_date', flockSource: 'flock_source', flockDestination: 'flock_destination', + filter_by: 'filter_by', + sort_by: 'sort_by', }, }); @@ -181,7 +203,7 @@ const TransferToLayingsTable = () => { isLoadingOptions: isLoadingFlockSourceOptions, loadMore: loadMoreFlockSource, hasMore: hasMoreFlockSource, - } = useSelect(FlockApi.basePath, 'id', 'name'); + } = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name'); const { setInputValue: setFlockDestinationInputValue, @@ -189,7 +211,7 @@ const TransferToLayingsTable = () => { isLoadingOptions: isLoadingFlockDestinationOptions, loadMore: loadMoreFlockDestination, hasMore: hasMoreFlockDestination, - } = useSelect(FlockApi.basePath, 'id', 'name'); + } = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name'); // Flocks value const [selectedFlockSource, setSelectedFlockSource] = @@ -244,13 +266,6 @@ const TransferToLayingsTable = () => { ); }, }, - { - header: '#', - cell: (props) => - tableFilterState.pageSize * (tableFilterState.page - 1) + - props.row.index + - 1, - }, { accessorKey: 'transfer_date', header: 'Tanggal Transfer', @@ -274,6 +289,7 @@ const TransferToLayingsTable = () => { { accessorKey: 'notes', header: 'Alasan Transfer', + enableSorting: false, }, { header: 'Status', @@ -282,34 +298,39 @@ const TransferToLayingsTable = () => { props.row.original.approval.action === 'REJECTED'; let latestApprovalStepName = props.row.original.approval.step_name; - let pillBadgeColor: 'yellow' | 'green' | 'gray' | 'red' = 'gray'; + let badgeColor: Color = 'neutral'; switch (latestApprovalStepName.toLowerCase()) { case 'pengajuan': - pillBadgeColor = 'yellow'; + badgeColor = 'neutral'; break; case 'disetujui': - pillBadgeColor = 'green'; + badgeColor = 'success'; break; } if (isLatestApprovalRejected) { - pillBadgeColor = 'red'; + badgeColor = 'error'; latestApprovalStepName = 'Ditolak'; } return ( - + + + {latestApprovalStepName} + ); }, }, { - header: 'Aksi', + id: 'actions', cell: (props) => { const currentPageSize = props.table.getPaginationRowModel().rows.length; const currentPageRows = props.table.getPaginationRowModel().flatRows; @@ -346,31 +367,13 @@ const TransferToLayingsTable = () => { }; return ( - <> - {currentPageSize > 3 && ( - - - - )} - - {currentPageSize <= 3 && ( - - - - )} - + ); }, }, @@ -503,20 +506,19 @@ const TransferToLayingsTable = () => { ); }; - // track sorting - // useEffect(() => { - // const isNameSorted = sorting.find((sortItem) => sortItem.id === 'name'); - - // if (!isNameSorted) { - // updateFilter('nameSort', ''); - // } else { - // updateFilter('nameSort', isNameSorted.desc ? 'desc' : 'asc'); - // } - // }, [sorting, updateFilter]); + useEffect(() => { + if (sorting.length === 1) { + updateFilter('filter_by', sorting[0].id); + updateFilter('sort_by', sorting[0].desc ? 'desc' : 'asc'); + } else { + updateFilter('filter_by', ''); + updateFilter('sort_by', ''); + } + }, [sorting]); return ( <> -
      +
      @@ -583,12 +585,10 @@ const TransferToLayingsTable = () => {
      - { wrapper: 'col-span-12 sm:col-span-3', }} /> - -
      @@ -657,26 +643,21 @@ const TransferToLayingsTable = () => { : 0 } onPageChange={setPage} + onPageSizeChange={setPageSize} isLoading={isLoading} sorting={sorting} setSorting={setSorting} rowSelection={rowSelection} setRowSelection={setRowSelection} enableRowSelection={tableEnableRowSelectionHandler} + withCheckbox className={{ containerClassName: cn({ - 'mb-20': + 'w-full mb-20': isResponseSuccess(transferToLayings) && transferToLayings?.data?.length === 0, }), - tableWrapperClassName: 'overflow-x-auto min-h-full!', - tableClassName: 'font-inter w-full table-auto min-h-full!', - headerRowClassName: 'border-b border-b-gray-200', - headerColumnClassName: - 'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end', - bodyRowClassName: 'border-b border-b-gray-200', - bodyColumnClassName: - 'px-6 py-3 last:flex last:flex-row last:justify-end', + headerColumnClassName: 'text-nowrap', }} />
      From e13f3358f4cfee5fead6659ea179351c0a15f9b3 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 17:09:57 +0700 Subject: [PATCH 14/16] chore: set maxQuantity min to 0 --- .../transfer-to-laying/form/TransferToLayingForm.schema.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/pages/production/transfer-to-laying/form/TransferToLayingForm.schema.ts b/src/components/pages/production/transfer-to-laying/form/TransferToLayingForm.schema.ts index 42387992..6e47c0ca 100644 --- a/src/components/pages/production/transfer-to-laying/form/TransferToLayingForm.schema.ts +++ b/src/components/pages/production/transfer-to-laying/form/TransferToLayingForm.schema.ts @@ -80,7 +80,7 @@ export const TransferToLayingFormSchema: Yup.ObjectSchema Date: Tue, 20 Jan 2026 17:11:18 +0700 Subject: [PATCH 15/16] feat: create PopoverButton component --- src/components/popover/PopoverButton.tsx | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/components/popover/PopoverButton.tsx diff --git a/src/components/popover/PopoverButton.tsx b/src/components/popover/PopoverButton.tsx new file mode 100644 index 00000000..ad72e24e --- /dev/null +++ b/src/components/popover/PopoverButton.tsx @@ -0,0 +1,29 @@ +import Button, { ButtonProps } from '@/components/Button'; + +export interface PopoverButtonProps extends ButtonProps { + popoverTarget: string; + anchorName: string; +} + +const PopoverButton = ({ + children, + popoverTarget, + anchorName, + ...props +}: PopoverButtonProps) => { + return ( + + ); +}; + +export default PopoverButton; From 43fe8ad1b3bf1deb26bf8bee9d5a8973f26f05af Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 20 Jan 2026 17:33:38 +0700 Subject: [PATCH 16/16] feat: create PopoverContent component --- src/components/popover/PopoverContent.tsx | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/components/popover/PopoverContent.tsx diff --git a/src/components/popover/PopoverContent.tsx b/src/components/popover/PopoverContent.tsx new file mode 100644 index 00000000..9a634abb --- /dev/null +++ b/src/components/popover/PopoverContent.tsx @@ -0,0 +1,71 @@ +import { cn } from '@/lib/helper'; + +export interface PopoverContentProps { + children: React.ReactNode; + id: string; + anchorName: string; // Must include `--` like "--menu-anchor" + popover?: 'auto' | 'hint' | 'manual'; + position?: + | 'top' + | 'bottom' + | 'left' + | 'right' + | 'top-start' + | 'top-end' + | 'bottom-start' + | 'bottom-end' + | 'left-start' + | 'left-end' + | 'right-start' + | 'right-end'; + className?: string; +} + +const positionAreaMap: Record< + NonNullable, + string +> = { + top: 'top center', + bottom: 'bottom center', + left: 'left center', + right: 'right center', + + 'top-start': 'top left', + 'top-end': 'top right', + 'bottom-start': 'bottom left', + 'bottom-end': 'bottom right', + + 'left-start': 'left top', + 'left-end': 'left bottom', + + 'right-start': 'right top', + 'right-end': 'right bottom', +}; + +const PopoverContent = ({ + children, + id, + anchorName, + popover = 'auto', + position = 'bottom-start', + className, +}: PopoverContentProps) => { + return ( +
      + {children} +
      + ); +}; + +export default PopoverContent;