// React Imports import { useState, useEffect } 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' import Switch from '@mui/material/Switch' import FormControlLabel from '@mui/material/FormControlLabel' import Chip from '@mui/material/Chip' import InputAdornment from '@mui/material/InputAdornment' import Select from '@mui/material/Select' import FormControl from '@mui/material/FormControl' import InputLabel from '@mui/material/InputLabel' // Third-party Imports import { useForm, Controller } from 'react-hook-form' // Component Imports import CustomTextField from '@core/components/mui/TextField' import { Tier, TierRequest } from '@/types/services/tier' import { useTiersMutation } from '@/services/mutations/tier' type Props = { open: boolean handleClose: () => void data?: Tier // Data tier untuk edit (jika ada) } // Static benefit keys with their configurations const STATIC_BENEFIT_KEYS = { birthday_bonus: { label: 'Birthday Bonus', type: 'boolean' as const, description: 'Bonus ulang tahun khusus member' }, exclusive_discounts: { label: 'Exclusive Discounts', type: 'boolean' as const, description: 'Akses diskon eksklusif' }, point_multiplier: { label: 'Point Multiplier', type: 'number' as const, description: 'Pengali poin (contoh: 1.1 = +10%)', suffix: 'x' }, priority_support: { label: 'Priority Support', type: 'boolean' as const, description: 'Dukungan pelanggan prioritas' }, special_discount: { label: 'Special Discount', type: 'number' as const, description: 'Diskon khusus dalam persen', suffix: '%' } } as const // Benefit item type type BenefitItem = { key: keyof typeof STATIC_BENEFIT_KEYS value: any type: 'boolean' | 'number' | 'string' } type FormValidateType = { name: string min_points: number benefits: BenefitItem[] } // Initial form data const initialData: FormValidateType = { name: '', min_points: 0, benefits: [] } const AddEditTierDrawer = (props: Props) => { // Props const { open, handleClose, data } = props // States const [showMore, setShowMore] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const { createTier, updateTier } = useTiersMutation() // Determine if this is edit mode const isEditMode = Boolean(data?.id) // Hooks const { control, reset: resetForm, handleSubmit, watch, setValue, formState: { errors } } = useForm({ defaultValues: initialData }) const watchedBenefits = watch('benefits') // Helper function to convert benefits object to BenefitItem array const convertBenefitsToArray = (benefits: Record): BenefitItem[] => { if (!benefits) return [] return Object.entries(benefits) .filter(([key]) => key in STATIC_BENEFIT_KEYS) .map(([key, value]) => ({ key: key as keyof typeof STATIC_BENEFIT_KEYS, value, type: STATIC_BENEFIT_KEYS[key as keyof typeof STATIC_BENEFIT_KEYS].type })) } // Helper function to convert BenefitItem array to benefits object const convertBenefitsToObject = (benefits: BenefitItem[]): Record => { const benefitsObj: Record = {} benefits.forEach(benefit => { let value = benefit.value // Convert string values to appropriate types if (benefit.type === 'boolean') { value = value === true || value === 'true' || value === 'yes' } else if (benefit.type === 'number') { value = Number(value) } benefitsObj[benefit.key] = value }) return benefitsObj } // Helper function to format benefit display const formatBenefitDisplay = (item: BenefitItem): string => { const config = STATIC_BENEFIT_KEYS[item.key] if (item.type === 'boolean') { return `${config.label}: ${item.value ? 'Ya' : 'Tidak'}` } else if (item.type === 'number') { const suffix = config.suffix || '' return `${config.label}: ${item.value}${suffix}` } return `${config.label}: ${item.value}` } // Get available benefit keys (not already added) const getAvailableBenefitKeys = () => { const usedKeys = watchedBenefits?.map(b => b.key) || [] return Object.entries(STATIC_BENEFIT_KEYS) .filter(([key]) => !usedKeys.includes(key as keyof typeof STATIC_BENEFIT_KEYS)) .map(([key, config]) => ({ key: key as keyof typeof STATIC_BENEFIT_KEYS, ...config })) } // Effect to populate form when editing useEffect(() => { if (isEditMode && data) { // Convert benefits object to array for form handling const benefitsArray = convertBenefitsToArray(data.benefits) // Populate form with existing data const formData: FormValidateType = { name: data.name || '', min_points: data.min_points || 0, benefits: benefitsArray } resetForm(formData) setShowMore(true) // Always show more for edit mode } else { // Reset to initial data for add mode resetForm(initialData) setShowMore(false) } }, [data, isEditMode, resetForm]) const handleFormSubmit = async (formData: FormValidateType) => { try { setIsSubmitting(true) // Convert benefits array back to object format const benefitsObj = convertBenefitsToObject(formData.benefits) // Create TierRequest object const tierRequest: TierRequest = { name: formData.name, min_points: formData.min_points, benefits: benefitsObj } console.log('Submitting tier data:', tierRequest) if (isEditMode && data?.id) { // Update existing tier updateTier.mutate( { id: data.id, payload: tierRequest }, { onSuccess: () => { handleReset() handleClose() } } ) } else { // Create new tier createTier.mutate(tierRequest, { onSuccess: () => { handleReset() handleClose() } }) } } catch (error) { console.error('Error submitting tier:', error) // Handle error (show toast, etc.) } finally { setIsSubmitting(false) } } const handleReset = () => { handleClose() resetForm(initialData) setShowMore(false) } // Get placeholder and validation info based on selected benefit key const getBenefitInputInfo = () => { return { placeholder: 'Tidak diperlukan lagi', type: 'text' } } const formatNumber = (value: number) => { return new Intl.NumberFormat('id-ID').format(value) } return ( {/* Sticky Header */}
{isEditMode ? 'Edit Tier' : 'Tambah Tier Baru'}
{/* Scrollable Content */}
{/* Nama Tier */}
Nama Tier * ( )} />
{/* Minimum Points */}
Minimum Poin * ( 0 ? `${formatNumber(field.value)} poin` : '') } InputProps={{ endAdornment: poin }} onChange={e => field.onChange(Number(e.target.value))} /> )} />
{/* Benefits */}
Manfaat Tier * {/* All Benefits in Horizontal Layout */}
{Object.entries(STATIC_BENEFIT_KEYS).map(([key, config]) => { const benefitKey = key as keyof typeof STATIC_BENEFIT_KEYS const existingBenefit = watchedBenefits?.find(b => b.key === benefitKey) const isActive = Boolean(existingBenefit) return (
{config.label} {config.description}
{ if (e.target.checked) { // Add default benefit const defaultValue = config.type === 'boolean' ? true : config.type === 'number' ? benefitKey === 'point_multiplier' ? 1.1 : benefitKey === 'special_discount' ? 5 : 1 : '' const newBenefit: BenefitItem = { key: benefitKey, value: defaultValue, type: config.type } const currentBenefits = watchedBenefits || [] setValue('benefits', [...currentBenefits, newBenefit]) } else { // Remove benefit const currentBenefits = watchedBenefits || [] const newBenefits = currentBenefits.filter(b => b.key !== benefitKey) setValue('benefits', newBenefits) } }} size='small' /> } label='' sx={{ margin: 0 }} />
{/* Value Input - Only show when active */} {isActive && (
{config.type === 'boolean' ? ( ) : ( { const newValue = Number(e.target.value) if (!isNaN(newValue)) { const currentBenefits = watchedBenefits || [] const updatedBenefits = currentBenefits.map(b => b.key === benefitKey ? { ...b, value: newValue } : b ) setValue('benefits', updatedBenefits) } }} placeholder={ benefitKey === 'point_multiplier' ? 'Contoh: 1.1, 1.5, 2.0' : benefitKey === 'special_discount' ? 'Contoh: 5, 10, 15' : 'Masukkan angka' } InputProps={{ endAdornment: config.suffix && ( {config.suffix} ), inputProps: { step: benefitKey === 'point_multiplier' ? '0.1' : '1', min: benefitKey === 'point_multiplier' ? '0.1' : '0', max: benefitKey === 'special_discount' ? '100' : undefined } }} /> )}
)}
) })}
{(!watchedBenefits || watchedBenefits.length === 0) && ( Minimal satu manfaat harus diaktifkan )}
{/* Sticky Footer */}
) } export default AddEditTierDrawer