// 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' // Third-party Imports import { useForm, Controller, useFieldArray } from 'react-hook-form' // Component Imports import CustomTextField from '@core/components/mui/TextField' // Types export interface Campaign { id: string name: string description?: string minimumPurchase: number rewardType: 'point' | 'voucher' | 'discount' rewardValue: number startDate: Date endDate: Date isActive: boolean createdAt: Date updatedAt: Date } export interface CampaignRequest { name: string description?: string minimumPurchase: number rewardType: 'point' | 'voucher' | 'discount' rewardValue: number startDate: Date endDate: Date isActive: boolean } type Props = { open: boolean handleClose: () => void data?: Campaign // Data campaign untuk edit (jika ada) } type FormValidateType = { name: string description: string minimumPurchase: number rewardType: 'point' | 'voucher' | 'discount' rewardValue: number startDate: string endDate: string isActive: boolean } // Initial form data const initialData: FormValidateType = { name: '', description: '', minimumPurchase: 0, rewardType: 'point', rewardValue: 0, startDate: '', endDate: '', isActive: true } // Mock mutation hooks (replace with actual hooks) const useCampaignMutation = () => { const createCampaign = { mutate: (data: CampaignRequest, options?: { onSuccess?: () => void }) => { console.log('Creating campaign:', data) setTimeout(() => options?.onSuccess?.(), 1000) } } const updateCampaign = { mutate: (data: { id: string; payload: CampaignRequest }, options?: { onSuccess?: () => void }) => { console.log('Updating campaign:', data) setTimeout(() => options?.onSuccess?.(), 1000) } } return { createCampaign, updateCampaign } } const AddEditCampaignDrawer = (props: Props) => { // Props const { open, handleClose, data } = props // States const [showMore, setShowMore] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const { createCampaign, updateCampaign } = useCampaignMutation() // 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 watchedRewardType = watch('rewardType') const watchedStartDate = watch('startDate') const watchedEndDate = watch('endDate') // Effect to populate form when editing useEffect(() => { if (isEditMode && data) { // Populate form with existing data const formData: FormValidateType = { name: data.name || '', description: data.description || '', minimumPurchase: data.minimumPurchase || 0, rewardType: data.rewardType || 'point', rewardValue: data.rewardValue || 0, startDate: data.startDate ? new Date(data.startDate).toISOString().split('T')[0] : '', endDate: data.endDate ? new Date(data.endDate).toISOString().split('T')[0] : '', isActive: data.isActive ?? true } 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) // Create CampaignRequest object const campaignRequest: CampaignRequest = { name: formData.name, description: formData.description || undefined, minimumPurchase: formData.minimumPurchase, rewardType: formData.rewardType, rewardValue: formData.rewardValue, startDate: new Date(formData.startDate), endDate: new Date(formData.endDate), isActive: formData.isActive } if (isEditMode && data?.id) { // Update existing campaign updateCampaign.mutate( { id: data.id, payload: campaignRequest }, { onSuccess: () => { handleReset() handleClose() } } ) } else { // Create new campaign createCampaign.mutate(campaignRequest, { onSuccess: () => { handleReset() handleClose() } }) } } catch (error) { console.error('Error submitting campaign:', error) // Handle error (show toast, etc.) } finally { setIsSubmitting(false) } } const handleReset = () => { handleClose() resetForm(initialData) setShowMore(false) } const formatCurrency = (value: number) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }).format(value) } const getRewardTypeLabel = (type: 'point' | 'voucher' | 'discount') => { switch (type) { case 'point': return 'Poin' case 'voucher': return 'Voucher' case 'discount': return 'Diskon' default: return type } } const getRewardValuePlaceholder = (type: 'point' | 'voucher' | 'discount') => { switch (type) { case 'point': return 'Jumlah poin yang diberikan' case 'voucher': return 'Nilai voucher dalam Rupiah' case 'discount': return 'Persentase diskon (1-100)' default: return 'Nilai reward' } } const getRewardValueRules = (type: 'point' | 'voucher' | 'discount') => { const baseRules = { required: 'Nilai reward wajib diisi', min: { value: 1, message: 'Nilai reward minimal 1' } } if (type === 'discount') { return { ...baseRules, max: { value: 100, message: 'Persentase diskon maksimal 100%' } } } return baseRules } return ( {/* Sticky Header */}
{isEditMode ? 'Edit Kampanye' : 'Tambah Kampanye Baru'}
{/* Scrollable Content */}
{/* Nama Kampanye */}
Nama Kampanye * ( )} />
{/* Minimum Purchase */}
Minimum Pembelian * ( 0 ? formatCurrency(field.value) : '')} InputProps={{ startAdornment: Rp }} onChange={e => field.onChange(Number(e.target.value))} /> )} />
{/* Jenis Reward */}
Jenis Reward * (
Poin
Voucher
Diskon
)} />
{/* Nilai Reward */}
Nilai {getRewardTypeLabel(watchedRewardType)} * ( Rp ) : undefined, endAdornment: watchedRewardType === 'discount' ? ( % ) : watchedRewardType === 'point' ? ( Poin ) : undefined }} onChange={e => field.onChange(Number(e.target.value))} /> )} />
{/* Tanggal Mulai */}
Tanggal Mulai * ( )} />
{/* Tanggal Berakhir */}
Tanggal Berakhir * { if (watchedStartDate && value) { return ( new Date(value) >= new Date(watchedStartDate) || 'Tanggal berakhir harus setelah tanggal mulai' ) } return true } }} render={({ field }) => ( )} />
{/* Status Aktif */}
( } label='Kampanye Aktif' /> )} />
{/* Tampilkan selengkapnya */} {!showMore && ( )} {/* Konten tambahan */} {showMore && ( <> {/* Description */}
Deskripsi Kampanye ( )} />
{/* Sembunyikan */} )}
{/* Sticky Footer */}
) } export default AddEditCampaignDrawer