diff --git a/src/app/marketing/sales-orders/add/page.tsx b/src/app/marketing/sales-orders/add/page.tsx new file mode 100644 index 00000000..ed193137 --- /dev/null +++ b/src/app/marketing/sales-orders/add/page.tsx @@ -0,0 +1,9 @@ +const AddSalesOrder = () => { + return ( +
+

Tambah Sales Order

+
+ ); +}; + +export default AddSalesOrder; diff --git a/src/app/marketing/sales-orders/detail/edit/page.tsx b/src/app/marketing/sales-orders/detail/edit/page.tsx new file mode 100644 index 00000000..cc0722ea --- /dev/null +++ b/src/app/marketing/sales-orders/detail/edit/page.tsx @@ -0,0 +1,8 @@ +const EditSalesOrder = () => { + return ( +
+

Edit Sales Order

+
+ ); +}; +export default EditSalesOrder; diff --git a/src/app/marketing/sales-orders/detail/layout.tsx b/src/app/marketing/sales-orders/detail/layout.tsx new file mode 100644 index 00000000..7220dfa1 --- /dev/null +++ b/src/app/marketing/sales-orders/detail/layout.tsx @@ -0,0 +1,11 @@ +import SuspenseHelper from '@/components/helper/SuspenseHelper'; + +const Layout = ({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) => { + return {children}; +}; + +export default Layout; diff --git a/src/app/marketing/sales-orders/detail/page.tsx b/src/app/marketing/sales-orders/detail/page.tsx new file mode 100644 index 00000000..ee377cfa --- /dev/null +++ b/src/app/marketing/sales-orders/detail/page.tsx @@ -0,0 +1,9 @@ +const DetailSalesOrder = () => { + return ( +
+

Detail Sales Order

+
+ ); +}; + +export default DetailSalesOrder; diff --git a/src/app/marketing/sales-orders/page.tsx b/src/app/marketing/sales-orders/page.tsx new file mode 100644 index 00000000..3494b6a1 --- /dev/null +++ b/src/app/marketing/sales-orders/page.tsx @@ -0,0 +1,10 @@ +import SalesOrderTable from '@/components/pages/marketing/sales-orders/SalesOrderTable'; + +const SalesOrder = () => { + return ( +
+ +
+ ); +}; +export default SalesOrder; diff --git a/src/components/pages/marketing/sales-orders/SalesOrderTable.tsx b/src/components/pages/marketing/sales-orders/SalesOrderTable.tsx new file mode 100644 index 00000000..eb35e666 --- /dev/null +++ b/src/components/pages/marketing/sales-orders/SalesOrderTable.tsx @@ -0,0 +1,166 @@ +'use client'; + +import Button from '@/components/Button'; +import { OptionType } from '@/components/input/SelectInput'; +import Table from '@/components/Table'; +import { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector'; +import { TableToolbar } from '@/components/table/TableToolbar'; +import { ROWS_OPTIONS } from '@/config/constant'; +import { cn } from '@/lib/helper'; +import { SalesOrder } from '@/types/api/marketing/marketing'; +import { Icon } from '@iconify/react'; +import { CellContext } from '@tanstack/react-table'; +import { useCallback, useState } from 'react'; + +const RowsOptionsMenu = ({ + type = 'dropdown', + props, + deleteClickHandler, +}: { + type: 'dropdown' | 'collapse'; + props: CellContext; + deleteClickHandler: () => void; +}) => { + return ( +
+
+ + + +
+
+ ); +}; +const SalesOrderTable = () => { + const [search, setSearch] = useState(''); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + + const searchChangeHandler = useCallback( + (e: React.ChangeEvent) => { + setSearch(e.target.value); + setPage(1); + }, + [] + ); + const pageSizeChangeHandler = useCallback( + (val: OptionType | OptionType[] | null) => { + const newVal = val as OptionType; + setPageSize(newVal.value as number); + setPage(1); + }, + [] + ); + + return ( +
+
+ + +
+ pageSize * (page - 1) + props.row.index + 1, + }, + { + accessorKey: 'so_number', + header: 'No. Order', + }, + { + accessorKey: 'tanggal', + header: 'Tanggal', + }, + { + accessorKey: 'approval.step_name', + header: 'Status', + }, + { + accessorKey: 'customer', + header: 'Customer', + }, + { + accessorKey: 'grand_total', + header: 'Grand Total', + }, + { + accessorKey: 'product_details', + header: 'Product Details', + }, + { + header: 'Aksi', + cell: (props) => {}, + }, + ]} + pageSize={pageSize} + page={page} + onPageChange={setPage} + className={{ + 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', + }} + /> + + ); +}; +export default SalesOrderTable; diff --git a/src/components/pages/marketing/sales-orders/form/SalesForm.schema.ts b/src/components/pages/marketing/sales-orders/form/SalesForm.schema.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/components/pages/marketing/sales-orders/form/SalesForm.tsx b/src/components/pages/marketing/sales-orders/form/SalesForm.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/pages/marketing/sales-orders/form/SalesFormRepeater.ts b/src/components/pages/marketing/sales-orders/form/SalesFormRepeater.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/components/pages/marketing/sales-orders/form/SalesFromRepeater.tsx b/src/components/pages/marketing/sales-orders/form/SalesFromRepeater.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/config/constant.ts b/src/config/constant.ts index 2e9d3832..840f5c32 100644 --- a/src/config/constant.ts +++ b/src/config/constant.ts @@ -42,7 +42,7 @@ export const MAIN_DRAWER_LINKS: MAIN_DRAWER_MENU[] = [ { title: 'Penjualan', - link: '/sale', + link: '/marketing/sales-orders', icon: 'mdi:attach-money', }, diff --git a/src/types/api/marketing/marketing.d.ts b/src/types/api/marketing/marketing.d.ts new file mode 100644 index 00000000..b577802a --- /dev/null +++ b/src/types/api/marketing/marketing.d.ts @@ -0,0 +1,39 @@ +import { Customer } from '@/types/api/master-data/customer'; +import { + BaseApproval, + BaseMetadata, + CreatedUser, +} from '@/types/api/api-general'; +import { ProductWarehouse } from '../inventory/product-warehouse'; + +export type BaseMarketing = { + id: number; + status?: string; + so_number: string; + customer: Customer; + so_docs: string; + so_date: string; + sales_person: CreatedUser; + notes: string; +}; + +export type MarketingProducts = { + id: number; + qty: number; + unit_price: number; + avg_weigth: number; + total_price: number; + product_warehouse: ProductWarehouse; + delivery_date?: string; + vehicle_number?: string; +}; + +export type SalesOrder = BaseMetadata & BaseMarketing; + +export type CreateSalesOrderPayload = { + customer_id: number; + date: string; + notes: string; +}; + +export type UpdateSalesOrderPayload = CreateSalesOrderPayload;