From 3a56e56c69491b3df0398f40044b9ebfed910b28 Mon Sep 17 00:00:00 2001 From: efrilm Date: Thu, 18 Sep 2025 01:21:51 +0700 Subject: [PATCH] Update Tier Drawer --- .../apps/marketing/tier/AddTierDrawer.tsx | 352 +++++++++--------- 1 file changed, 179 insertions(+), 173 deletions(-) diff --git a/src/views/apps/marketing/tier/AddTierDrawer.tsx b/src/views/apps/marketing/tier/AddTierDrawer.tsx index 8049c83..7fb2059 100644 --- a/src/views/apps/marketing/tier/AddTierDrawer.tsx +++ b/src/views/apps/marketing/tier/AddTierDrawer.tsx @@ -32,9 +32,40 @@ type Props = { 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: string + key: keyof typeof STATIC_BENEFIT_KEYS value: any type: 'boolean' | 'number' | 'string' } @@ -43,19 +74,13 @@ type FormValidateType = { name: string min_points: number benefits: BenefitItem[] - newBenefitKey: string - newBenefitValue: string - newBenefitType: 'boolean' | 'number' | 'string' } // Initial form data const initialData: FormValidateType = { name: '', min_points: 0, - benefits: [], - newBenefitKey: '', - newBenefitValue: '', - newBenefitType: 'boolean' + benefits: [] } const AddEditTierDrawer = (props: Props) => { @@ -84,18 +109,17 @@ const AddEditTierDrawer = (props: Props) => { }) const watchedBenefits = watch('benefits') - const watchedNewBenefitKey = watch('newBenefitKey') - const watchedNewBenefitValue = watch('newBenefitValue') - const watchedNewBenefitType = watch('newBenefitType') // Helper function to convert benefits object to BenefitItem array const convertBenefitsToArray = (benefits: Record): BenefitItem[] => { if (!benefits) return [] - return Object.entries(benefits).map(([key, value]) => ({ - key, - value, - type: typeof value === 'boolean' ? 'boolean' : typeof value === 'number' ? 'number' : 'string' - })) + 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 @@ -116,19 +140,26 @@ const AddEditTierDrawer = (props: Props) => { // Helper function to format benefit display const formatBenefitDisplay = (item: BenefitItem): string => { - const readableKey = item.key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()) + const config = STATIC_BENEFIT_KEYS[item.key] if (item.type === 'boolean') { - return `${readableKey}: ${item.value ? 'Ya' : 'Tidak'}` + return `${config.label}: ${item.value ? 'Ya' : 'Tidak'}` } else if (item.type === 'number') { - if (item.key.includes('multiplier')) { - return `${readableKey}: ${item.value}x` - } else if (item.key.includes('discount') || item.key.includes('bonus')) { - return `${readableKey}: ${item.value}%` - } - return `${readableKey}: ${item.value}` + const suffix = config.suffix || '' + return `${config.label}: ${item.value}${suffix}` } - return `${readableKey}: ${item.value}` + 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 @@ -141,10 +172,7 @@ const AddEditTierDrawer = (props: Props) => { const formData: FormValidateType = { name: data.name || '', min_points: data.min_points || 0, - benefits: benefitsArray, - newBenefitKey: '', - newBenefitValue: '', - newBenefitType: 'boolean' + benefits: benefitsArray } resetForm(formData) @@ -156,57 +184,6 @@ const AddEditTierDrawer = (props: Props) => { } }, [data, isEditMode, resetForm]) - const handleAddBenefit = () => { - const key = watchedNewBenefitKey.trim() - const value = watchedNewBenefitValue.trim() - const type = watchedNewBenefitType - - if (key && value) { - // Check if key already exists - const existingKeys = watchedBenefits.map(b => b.key) - if (existingKeys.includes(key)) { - alert('Key benefit sudah ada!') - return - } - - let processedValue: any = value - if (type === 'boolean') { - processedValue = value === 'true' || value === 'yes' || value === '1' - } else if (type === 'number') { - processedValue = Number(value) - if (isNaN(processedValue)) { - alert('Nilai harus berupa angka!') - return - } - } - - const newBenefit: BenefitItem = { - key, - value: processedValue, - type - } - - const currentBenefits = watchedBenefits || [] - setValue('benefits', [...currentBenefits, newBenefit]) - setValue('newBenefitKey', '') - setValue('newBenefitValue', '') - setValue('newBenefitType', 'boolean') - } - } - - const handleRemoveBenefit = (index: number) => { - const currentBenefits = watchedBenefits || [] - const newBenefits = currentBenefits.filter((_, i) => i !== index) - setValue('benefits', newBenefits) - } - - const handleKeyPress = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - event.preventDefault() - handleAddBenefit() - } - } - const handleFormSubmit = async (formData: FormValidateType) => { try { setIsSubmitting(true) @@ -257,6 +234,11 @@ const AddEditTierDrawer = (props: Props) => { 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) } @@ -357,109 +339,133 @@ const AddEditTierDrawer = (props: Props) => { {/* Benefits */}
- + Manfaat Tier * - {/* Display current benefits */} - {watchedBenefits && watchedBenefits.length > 0 && ( -
- {watchedBenefits.map((benefit, index) => ( - handleRemoveBenefit(index)} - color='primary' - variant='outlined' - size='small' - sx={{ - justifyContent: 'space-between', - '& .MuiChip-label': { - overflow: 'visible', - textOverflow: 'unset', - whiteSpace: 'normal' - } - }} - /> - ))} -
- )} + {/* 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) - {/* Add new benefit - Key */} -
- ( - - )} - /> -
+ 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 + : '' - {/* Type selector */} -
- ( - - Tipe Value - - - )} - /> -
+ const newBenefit: BenefitItem = { + key: benefitKey, + value: defaultValue, + type: config.type + } - {/* Add new benefit - Value */} -
- ( - - - - ) - }} - /> - )} - /> + /> + } + 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 ditambahkan + + Minimal satu manfaat harus diaktifkan )}