From 5a77d3c2ea2c0c4c034b1f64beb14fc5faf10edd Mon Sep 17 00:00:00 2001 From: efrilm Date: Thu, 11 Sep 2025 16:22:05 +0700 Subject: [PATCH] Ingredient Detail --- .../detail/IngedientUnitConversionDrawer.tsx | 370 ++++++++++++++++++ .../detail/IngredientDetailUnit.tsx | 91 +++-- 2 files changed, 431 insertions(+), 30 deletions(-) create mode 100644 src/views/apps/ecommerce/products/ingredient/detail/IngedientUnitConversionDrawer.tsx diff --git a/src/views/apps/ecommerce/products/ingredient/detail/IngedientUnitConversionDrawer.tsx b/src/views/apps/ecommerce/products/ingredient/detail/IngedientUnitConversionDrawer.tsx new file mode 100644 index 0000000..2d23725 --- /dev/null +++ b/src/views/apps/ecommerce/products/ingredient/detail/IngedientUnitConversionDrawer.tsx @@ -0,0 +1,370 @@ +'use client' +// React Imports +import { useState } from 'react' + +// MUI Imports +import Button from '@mui/material/Button' +import Drawer from '@mui/material/Drawer' +import IconButton from '@mui/material/IconButton' +import MenuItem from '@mui/material/MenuItem' +import Typography from '@mui/material/Typography' +import Divider from '@mui/material/Divider' +import Grid from '@mui/material/Grid2' +import Box from '@mui/material/Box' + +// Third-party Imports +import { useForm, Controller } from 'react-hook-form' + +// Component Imports +import CustomTextField from '@core/components/mui/TextField' + +type Props = { + open: boolean + handleClose: () => void + setData?: (data: any) => void +} + +type UnitConversionType = { + satuan: string + quantity: number + unit: string + hargaBeli: number + hargaJual: number + isDefault: boolean +} + +type FormValidateType = { + conversions: UnitConversionType[] +} + +// Vars +const initialConversion: UnitConversionType = { + satuan: 'Box', + quantity: 12, + unit: 'Pcs', + hargaBeli: 3588000, + hargaJual: 5988000, + isDefault: false +} + +const IngedientUnitConversionDrawer = (props: Props) => { + // Props + const { open, handleClose, setData } = props + + // States + const [conversions, setConversions] = useState([initialConversion]) + + // Hooks + const { + control, + reset: resetForm, + handleSubmit, + formState: { errors } + } = useForm({ + defaultValues: { + conversions: [initialConversion] + } + }) + + // Functions untuk konversi unit + const handleTambahBaris = () => { + const newConversion: UnitConversionType = { + satuan: '', + quantity: 0, + unit: '', + hargaBeli: 0, + hargaJual: 0, + isDefault: false + } + setConversions([...conversions, newConversion]) + } + + const handleHapusBaris = (index: number) => { + if (conversions.length > 1) { + const newConversions = conversions.filter((_, i) => i !== index) + setConversions(newConversions) + } + } + + const handleChangeConversion = (index: number, field: keyof UnitConversionType, value: any) => { + const newConversions = [...conversions] + newConversions[index] = { ...newConversions[index], [field]: value } + setConversions(newConversions) + } + + const handleToggleDefault = (index: number) => { + const newConversions = conversions.map((conversion, i) => ({ + ...conversion, + isDefault: i === index + })) + setConversions(newConversions) + } + + const onSubmit = (data: FormValidateType) => { + console.log('Unit conversions:', conversions) + if (setData) { + setData(conversions) + } + handleClose() + } + + const handleReset = () => { + handleClose() + setConversions([initialConversion]) + resetForm({ conversions: [initialConversion] }) + } + + const formatNumber = (value: number) => { + return new Intl.NumberFormat('id-ID').format(value) + } + + const parseNumber = (value: string) => { + return parseInt(value.replace(/\./g, '')) || 0 + } + + return ( + + {/* Sticky Header */} + +
+ Konversi Unit Bahan + + + +
+
+ + {/* Scrollable Content */} + +
onSubmit(data))}> +
+ {/* Header Kolom */} + + + + Satuan + + + + + = + + + + + Jumlah + + + + + Unit + + + + + Harga Beli + + + + + Harga Jual + + + + + Default + + + + + Action + + + + + {/* Baris Konversi */} + {conversions.map((conversion, index) => ( + + + + {index + 1} + + + + {/* Satuan */} + + handleChangeConversion(index, 'satuan', e.target.value)} + > + Box + Kg + Liter + Pack + Pcs + + + + {/* Tanda sama dengan */} + + = + + + {/* Quantity */} + + handleChangeConversion(index, 'quantity', parseInt(e.target.value) || 0)} + /> + + + {/* Unit */} + + handleChangeConversion(index, 'unit', e.target.value)} + > + Pcs + Kg + Gram + Liter + ML + + + + {/* Harga Beli */} + + handleChangeConversion(index, 'hargaBeli', parseNumber(e.target.value))} + /> + + + {/* Harga Jual */} + + handleChangeConversion(index, 'hargaJual', parseNumber(e.target.value))} + /> + + + {/* Default Star */} + + handleToggleDefault(index)} + sx={{ + color: conversion.isDefault ? 'warning.main' : 'grey.400' + }} + > + + + + + {/* Delete Button */} + + {conversions.length > 1 && ( + handleHapusBaris(index)} + sx={{ + color: 'error.main', + border: 1, + borderColor: 'error.main', + '&:hover': { + backgroundColor: 'error.light', + borderColor: 'error.main' + } + }} + > + + + )} + + + ))} + + {/* Tambah Baris Button */} +
+ +
+
+ +
+ + {/* Sticky Footer */} + +
+ + +
+
+
+ ) +} + +export default IngedientUnitConversionDrawer diff --git a/src/views/apps/ecommerce/products/ingredient/detail/IngredientDetailUnit.tsx b/src/views/apps/ecommerce/products/ingredient/detail/IngredientDetailUnit.tsx index 823b0d2..05f4784 100644 --- a/src/views/apps/ecommerce/products/ingredient/detail/IngredientDetailUnit.tsx +++ b/src/views/apps/ecommerce/products/ingredient/detail/IngredientDetailUnit.tsx @@ -1,37 +1,68 @@ -import React from 'react' +'use client' +import React, { useState } from 'react' import { Card, CardContent, CardHeader, Typography, Button, Box, Stack } from '@mui/material' +import IngedientUnitConversionDrawer from './IngedientUnitConversionDrawer' // Sesuaikan dengan path file Anda const IngredientDetailUnit = () => { - return ( - - - - - - - Satuan Dasar - - - : Pcs - - - + // State untuk mengontrol drawer + const [openConversionDrawer, setOpenConversionDrawer] = useState(false) - - - + // Function untuk membuka drawer + const handleOpenConversionDrawer = () => { + setOpenConversionDrawer(true) + } + + // Function untuk menutup drawer + const handleCloseConversionDrawer = () => { + setOpenConversionDrawer(false) + } + + // Function untuk handle data dari drawer (opsional) + const handleSetConversionData = (data: any) => { + console.log('Conversion data received:', data) + // Anda bisa menambahkan logic untuk mengupdate state atau API call di sini + } + + return ( + <> + + + + + + + Satuan Dasar + + + : Pcs + + + + + + + + + {/* Ingredient Unit Conversion Drawer */} + + ) }