819 lines
28 KiB
JavaScript
819 lines
28 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react';
|
|
import { Input, InputNumber, Select, Radio, Button, message } from 'antd';
|
|
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
|
import './MembershipForm.scss';
|
|
import { useDispatch } from 'react-redux';
|
|
import { getSession } from '../../Services/Others';
|
|
import { changeBreadCrumb } from '../../Features/AppPage/CenterPage.js';
|
|
import { Messages } from '../../Components/Notifications/Messages.jsx';
|
|
import {
|
|
postMembership,
|
|
putMembership,
|
|
} from '../../Features/Membership/Membership.js';
|
|
import { getAdmin } from '../../Features/ProductPage/ProductPage.js';
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
const subDirectory = import.meta.env.ENV_BASE_URL;
|
|
const { Option } = Select;
|
|
|
|
const DAYS_OF_WEEK = [
|
|
{ label: 'Monday', value: 'Monday' },
|
|
{ label: 'Tuesday', value: 'Tuesday' },
|
|
{ label: 'Wednesday', value: 'Wednesday' },
|
|
{ label: 'Thursday', value: 'Thursday' },
|
|
{ label: 'Friday', value: 'Friday' },
|
|
{ label: 'Saturday', value: 'Saturday' },
|
|
{ label: 'Sunday', value: 'Sunday' },
|
|
];
|
|
|
|
const MembershipForm = ({ formType = 'add' }) => {
|
|
const dispatch = useDispatch();
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
|
|
const state = location?.state;
|
|
const editstate = state?.editstate;
|
|
console.log(editstate, 'editstate');
|
|
const AppId = getSession('AppId');
|
|
const CompId = getSession('CompId');
|
|
const BranchId = getSession('BranchId');
|
|
const UserId = getSession('UserId');
|
|
|
|
const [messageType, setMessageType] = useState(null);
|
|
const [messageData, setMessageData] = useState(null);
|
|
const [taxData, setTaxData] = useState([]);
|
|
const [membershipName, setMembershipName] = useState('');
|
|
const [nameError, setNameError] = useState('');
|
|
const [schedules, setSchedules] = useState([
|
|
{
|
|
id: Date.now(),
|
|
days: null,
|
|
price: null,
|
|
displayPrice: null,
|
|
taxId: null,
|
|
hrs: null,
|
|
discountType: 'F',
|
|
discountValue: null,
|
|
priority: 'N',
|
|
selectedDays: [],
|
|
remarks: '',
|
|
membershipId: null,
|
|
uniqueId: null,
|
|
planId: null,
|
|
activeStatus: null,
|
|
errors: {},
|
|
},
|
|
]);
|
|
|
|
const items = [
|
|
{
|
|
name: 'Home',
|
|
link: `${subDirectory}app-page/home`,
|
|
},
|
|
|
|
{
|
|
name: 'Membership List',
|
|
link: `${subDirectory}setting/membership-master/list`,
|
|
},
|
|
{
|
|
name: editstate ? 'Edit' : 'New',
|
|
link: null,
|
|
},
|
|
];
|
|
|
|
console.log(taxData, 'taxData');
|
|
|
|
useEffect(() => {
|
|
getTaxData();
|
|
dispatch(changeBreadCrumb({ items: items }));
|
|
|
|
if (editstate) {
|
|
// Populate membership name
|
|
setMembershipName(editstate?.MembershipName || '');
|
|
|
|
// Populate schedules from MembershipPlanDtl
|
|
if (
|
|
editstate?.MembershipPlanDtl &&
|
|
editstate.MembershipPlanDtl.length > 0
|
|
) {
|
|
const populatedSchedules = editstate.MembershipPlanDtl.map((plan) => ({
|
|
id: plan.UniqueId || Date.now(),
|
|
days: plan.PlanDuration,
|
|
price: plan.Price,
|
|
displayPrice: plan.DisplayPrice,
|
|
taxId: plan.TaxId,
|
|
hrs: plan.FreeSessionHrs,
|
|
discountType: plan.DiscountType,
|
|
discountValue: plan.Discount,
|
|
priority: plan.Priority,
|
|
selectedDays:
|
|
plan.Prioritydays?.[0]?.split(',')?.map((day) => day.trim()) || [],
|
|
remarks: plan.Remarks || '',
|
|
membershipId: plan.MembershipId,
|
|
uniqueId: plan.UniqueId,
|
|
planId: plan.PlanId,
|
|
activeStatus: plan.ActiveStatus,
|
|
errors: {},
|
|
}));
|
|
setSchedules(populatedSchedules);
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
const getTaxData = async () => {
|
|
const res = await dispatch(
|
|
getAdmin({ CompId: CompId, AppId: AppId })
|
|
).unwrap();
|
|
if (res?.data?.statusCode === 1) {
|
|
setTaxData(res?.data?.data);
|
|
} else {
|
|
setTaxData([]);
|
|
}
|
|
};
|
|
|
|
const validateMembershipName = (value) => {
|
|
if (!value || value.trim() === '') {
|
|
setNameError('Membership name is required');
|
|
return false;
|
|
}
|
|
setNameError('');
|
|
return true;
|
|
};
|
|
|
|
const handleScheduleChange = (id, field, value) => {
|
|
const index = schedules.findIndex((schedule) => schedule.id === id);
|
|
const newSchedules = [...schedules];
|
|
newSchedules[index] = { ...newSchedules[index], [field]: value };
|
|
|
|
// ✅ Clear hrs when days change
|
|
if (field === 'days') {
|
|
newSchedules[index].hrs = null;
|
|
}
|
|
|
|
// ✅ Reset selectedDays if priority is N
|
|
if (field === 'priority' && value === 'N') {
|
|
newSchedules[index].selectedDays = [];
|
|
}
|
|
|
|
// Only validate the current field being changed
|
|
const currentErrors = { ...newSchedules[index].errors };
|
|
const fieldValidation = validateSingleField(
|
|
newSchedules[index],
|
|
field,
|
|
newSchedules
|
|
);
|
|
|
|
if (fieldValidation) {
|
|
currentErrors[field] = fieldValidation;
|
|
} else {
|
|
delete currentErrors[field];
|
|
}
|
|
|
|
newSchedules[index].errors = currentErrors;
|
|
setSchedules(newSchedules);
|
|
};
|
|
|
|
const validateSingleField = (schedule, field, allSchedules = schedules) => {
|
|
switch (field) {
|
|
case 'days':
|
|
if (!schedule.days) return 'Days is required';
|
|
break;
|
|
case 'price':
|
|
if (!schedule.price) return 'Price is required';
|
|
break;
|
|
case 'displayPrice':
|
|
if (!schedule.displayPrice) return 'Display price is required';
|
|
if (
|
|
schedule.displayPrice &&
|
|
schedule.price &&
|
|
Number(schedule.displayPrice) > Number(schedule.price)
|
|
) {
|
|
return 'Display price cannot be greater than price';
|
|
}
|
|
break;
|
|
case 'taxId':
|
|
if (!schedule.taxId) return 'Tax is required';
|
|
break;
|
|
case 'hrs':
|
|
if (!schedule.hrs) return 'Hours is required';
|
|
if (
|
|
schedule.days &&
|
|
schedule.hrs &&
|
|
schedule.hrs > schedule.days * 24
|
|
) {
|
|
return `Hours cannot exceed ${schedule.days * 24}`;
|
|
}
|
|
break;
|
|
case 'discountValue':
|
|
if (schedule.discountValue === null || schedule.discountValue === '')
|
|
return 'Discount is required';
|
|
if (schedule.discountType === 'P' && schedule.discountValue > 99) {
|
|
return 'Percentage discount cannot exceed 99%';
|
|
}
|
|
if (
|
|
schedule.discountType === 'F' &&
|
|
schedule.discountValue >= schedule.displayPrice
|
|
) {
|
|
return 'Fixed discount cannot be greater than or equal to display price';
|
|
}
|
|
break;
|
|
case 'selectedDays':
|
|
if (schedule.priority === 'Y' && schedule.selectedDays.length === 0) {
|
|
return 'Please select at least one day';
|
|
}
|
|
break;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const validateSchedule = (schedule, index, allSchedules = schedules) => {
|
|
const errors = {};
|
|
|
|
// ✅ Required fields
|
|
if (!schedule.days) errors.days = 'Days is required';
|
|
if (!schedule.price) errors.price = 'Price is required';
|
|
if (!schedule.displayPrice)
|
|
errors.displayPrice = 'Display price is required';
|
|
if (!schedule.taxId) errors.taxId = 'Tax is required';
|
|
if (!schedule.hrs) errors.hrs = 'Hours is required';
|
|
if (schedule.discountValue === null || schedule.discountValue === '')
|
|
errors.discountValue = 'Discount is required';
|
|
|
|
if (schedule.priority === 'Y' && schedule.selectedDays.length === 0)
|
|
errors.selectedDays = 'Please select at least one day';
|
|
|
|
// ✅ Display price <= price
|
|
if (
|
|
schedule.displayPrice &&
|
|
schedule.price &&
|
|
Number(schedule.displayPrice) > Number(schedule.price)
|
|
) {
|
|
errors.displayPrice = 'Display price cannot be greater than price';
|
|
}
|
|
|
|
// ✅ Hours ≤ days * 24
|
|
if (schedule.days && schedule.hrs && schedule.hrs > schedule.days * 24) {
|
|
errors.hrs = `Hours cannot exceed ${schedule.days * 24}`;
|
|
}
|
|
|
|
// ✅ Discount validation
|
|
if (schedule.discountType === 'P' && schedule.discountValue > 99) {
|
|
errors.discountValue = 'Percentage discount cannot exceed 99%';
|
|
}
|
|
if (
|
|
schedule.discountType === 'F' &&
|
|
schedule.discountValue >= schedule.displayPrice
|
|
) {
|
|
errors.discountValue =
|
|
'Fixed discount cannot be greater than or equal to display price';
|
|
}
|
|
|
|
// ✅ Duplicate Check (uses current updated allSchedules)
|
|
allSchedules.forEach((other, idx) => {
|
|
if (idx === index) return; // skip self
|
|
|
|
const baseMatch =
|
|
Number(other.days) === Number(schedule.days) &&
|
|
Number(other.price) === Number(schedule.price) &&
|
|
Number(other.displayPrice) === Number(schedule.displayPrice) &&
|
|
String(other.taxId) === String(schedule.taxId) &&
|
|
Number(other.hrs) === Number(schedule.hrs) &&
|
|
String(other.discountType) === String(schedule.discountType) &&
|
|
Number(other.discountValue) === Number(schedule.discountValue) &&
|
|
String(other.priority) === String(schedule.priority);
|
|
|
|
if (baseMatch) {
|
|
// both are non-priority plans
|
|
if (schedule.priority === 'N' && other.priority === 'N') {
|
|
errors.duplicate = 'Plan already exists';
|
|
}
|
|
// both are priority plans -> check selectedDays array match
|
|
else if (schedule.priority === 'Y' && other.priority === 'Y') {
|
|
const daysMatch =
|
|
schedule.selectedDays.length === other.selectedDays.length &&
|
|
schedule.selectedDays.every((d) => other.selectedDays.includes(d));
|
|
|
|
if (daysMatch) {
|
|
errors.duplicate = 'Plan already exists (same priority days)';
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return errors;
|
|
};
|
|
|
|
const addSchedule = () => {
|
|
if (!validateMembershipName(membershipName)) {
|
|
message.error('Please enter membership name first');
|
|
return;
|
|
}
|
|
|
|
const validatedSchedules = schedules.map((schedule, index) => ({
|
|
...schedule,
|
|
errors: validateSchedule(schedule, index, schedules),
|
|
}));
|
|
|
|
setSchedules(validatedSchedules);
|
|
|
|
const hasErrors = validatedSchedules.some(
|
|
(schedule) => Object.keys(schedule.errors).length > 0
|
|
);
|
|
|
|
if (hasErrors) {
|
|
message.error('Please fix all errors before adding a another plan');
|
|
return;
|
|
}
|
|
|
|
const membershipId = (editstate && editstate.MembershipId) ? editstate.MembershipId : null;
|
|
|
|
setSchedules([
|
|
...schedules,
|
|
{
|
|
id: Date.now(),
|
|
days: null,
|
|
price: null,
|
|
displayPrice: null,
|
|
taxId: null,
|
|
hrs: null,
|
|
discountType: 'F',
|
|
discountValue: null,
|
|
priority: 'N',
|
|
selectedDays: [],
|
|
remarks: '',
|
|
membershipId: membershipId,
|
|
uniqueId: null,
|
|
planId: null,
|
|
activeStatus: null,
|
|
errors: {},
|
|
},
|
|
]);
|
|
};
|
|
|
|
const removeSchedule = (id) => {
|
|
if (schedules?.filter(schedule => schedule?.activeStatus !== 'D').length === 1) {
|
|
message.warning('At least one plan is required');
|
|
return;
|
|
}
|
|
|
|
const scheduleToRemove = schedules.find((sch) => sch.id === id);
|
|
const index = schedules.findIndex((sch) => sch.id === id);
|
|
|
|
if (scheduleToRemove.planId) {
|
|
// If planId exists, set activeStatus to 'D'
|
|
const newSchedules = [...schedules];
|
|
newSchedules[index] = { ...newSchedules[index], activeStatus: 'D' };
|
|
setSchedules(newSchedules);
|
|
} else {
|
|
// If no planId, filter out the record
|
|
const newSchedules = schedules.filter((_, i) => i !== index);
|
|
setSchedules(newSchedules);
|
|
}
|
|
};
|
|
|
|
const handleSubmit = async () => {
|
|
if (!validateMembershipName(membershipName)) {
|
|
message.error('Please enter membership name');
|
|
return;
|
|
}
|
|
|
|
// Validate all schedules and set errors
|
|
const validatedSchedules = schedules.map((schedule, index) => ({
|
|
...schedule,
|
|
errors: validateSchedule(schedule, index, schedules),
|
|
}));
|
|
|
|
setSchedules(validatedSchedules);
|
|
|
|
const hasErrors = validatedSchedules.some(
|
|
(schedule) => Object.keys(schedule.errors).length > 0
|
|
);
|
|
|
|
if (hasErrors) {
|
|
message.error('Please fix all errors before submitting');
|
|
return;
|
|
}
|
|
|
|
const formData = {
|
|
AppId: AppId,
|
|
CompId: CompId,
|
|
BranchId: BranchId,
|
|
MembershipName: membershipName,
|
|
MembershipPlanDtl: schedules.map((schedule) => ({
|
|
PlanDuration: schedule.days,
|
|
DisplayPrice: schedule.displayPrice,
|
|
Price: schedule.price,
|
|
TaxId: schedule.taxId || null,
|
|
FreeSessionHrs: schedule.hrs,
|
|
Discount: schedule.discountValue,
|
|
DiscountType: schedule.discountType,
|
|
Priority: schedule.priority,
|
|
Prioritydays: schedule.selectedDays,
|
|
Remarks: schedule.remarks || '',
|
|
UniqueId: schedule.uniqueId || null,
|
|
PlanId: schedule.planId || null,
|
|
MembershipId: schedule.membershipId || null,
|
|
ActiveStatus: schedule.activeStatus || null,
|
|
TaxAmount: calculateTaxAmount(schedule.displayPrice, schedule.taxId),
|
|
})),
|
|
};
|
|
|
|
// Add edit-specific fields if in edit mode
|
|
let res = {};
|
|
if (editstate) {
|
|
formData.MembershipId = editstate.MembershipId;
|
|
formData.UpdatedBy = UserId;
|
|
formData.ActiveStatus = editstate.ActiveStatus;
|
|
formData.UniqueId = editstate.UniqueId;
|
|
res = await dispatch(putMembership(formData)).unwrap();
|
|
} else {
|
|
formData.CreatedBy = UserId;
|
|
res = await dispatch(postMembership(formData)).unwrap();
|
|
}
|
|
|
|
if (res?.data?.statusCode === 1) {
|
|
navigate(`${subDirectory}setting/membership-master/list`, {
|
|
state: {
|
|
Notify: {
|
|
messageType: 'success',
|
|
messageData: res?.data?.response,
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
setMessageData(res?.data?.response);
|
|
setMessageType('error');
|
|
}
|
|
|
|
console.log('Form Data:', formData);
|
|
};
|
|
|
|
const calculateTaxAmount = (price, taxId) => {
|
|
const taxRate = taxData.find((tax) => tax.TaxId === taxId)?.TaxPercentage;
|
|
return price * (taxRate / 100);
|
|
};
|
|
|
|
const onComplete = useCallback(() => {
|
|
setMessageData(null);
|
|
setMessageType(null);
|
|
}, []);
|
|
|
|
return (
|
|
<section className="membershipContainer">
|
|
<Messages
|
|
messageType={messageType}
|
|
messageData={messageData}
|
|
onComplete={onComplete}
|
|
/>
|
|
<div className="membershipWrapper">
|
|
<div className="membership-content">
|
|
<h2 className="membershipTitle">
|
|
{editstate ? 'Edit Membership' : 'Create Membership'}
|
|
</h2>
|
|
|
|
<div className="membershipFormGroup" style={{ width: '250px' }}>
|
|
<label className="membershipFormLabel required">
|
|
Membership Name
|
|
</label>
|
|
<Input
|
|
placeholder="Enter membership name"
|
|
value={membershipName}
|
|
onChange={(e) => {
|
|
setMembershipName(e.target.value);
|
|
validateMembershipName(e.target.value);
|
|
}}
|
|
onBlur={(e) => validateMembershipName(e.target.value)}
|
|
status={nameError ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
/>
|
|
{nameError && (
|
|
<div className="membershipErrorText">{nameError}</div>
|
|
)}
|
|
</div>
|
|
|
|
{schedules?.filter(schedule => schedule?.activeStatus !== 'D').map((schedule, index) => (
|
|
<div key={schedule.id} className="membershipScheduleCard">
|
|
<div className="membershipScheduleHeader">
|
|
<h3 className="membershipScheduleTitle">Plan {index + 1}</h3>
|
|
{schedules?.filter(schedule => schedule?.activeStatus !== 'D').length > 1 && (
|
|
<Button
|
|
type="text"
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
onClick={() => removeSchedule(schedule.id)}
|
|
className="membershipRemoveBtn"
|
|
>
|
|
Remove
|
|
</Button>
|
|
)}
|
|
</div>
|
|
|
|
<div className="membershipFormRow">
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">Days</label>
|
|
<Input
|
|
placeholder="Enter days"
|
|
value={schedule.days}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'days', value?.target?.value)
|
|
}
|
|
status={schedule.errors.days ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
style={{ width: '100%' }}
|
|
inputMode="decimal"
|
|
onInput={(e) => {
|
|
const cleanedValue = e.target.value.replace(
|
|
/[^0-9.]/g,
|
|
''
|
|
);
|
|
const parts = cleanedValue.split('.');
|
|
e.target.value =
|
|
parts.length > 2
|
|
? `${parts[0]}.${parts.slice(1).join('')}`
|
|
: cleanedValue;
|
|
}}
|
|
/>
|
|
{schedule.errors.days && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.days}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">Price</label>
|
|
<Input
|
|
placeholder="Enter price"
|
|
value={schedule.price}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'price', value?.target?.value)
|
|
}
|
|
// min={0}
|
|
// prefix="₹"
|
|
status={schedule.errors.price ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
style={{ width: '100%' }}
|
|
inputMode="decimal"
|
|
onInput={(e) => {
|
|
const cleanedValue = e.target.value.replace(
|
|
/[^0-9.]/g,
|
|
''
|
|
);
|
|
const parts = cleanedValue.split('.');
|
|
e.target.value =
|
|
parts.length > 2
|
|
? `${parts[0]}.${parts.slice(1).join('')}`
|
|
: cleanedValue;
|
|
}}
|
|
/>
|
|
{schedule.errors.price && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.price}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">
|
|
Display Price
|
|
</label>
|
|
<Input
|
|
placeholder="Enter display price"
|
|
value={schedule.displayPrice}
|
|
onChange={(value) =>
|
|
handleScheduleChange(
|
|
schedule.id,
|
|
'displayPrice',
|
|
value?.target?.value
|
|
)
|
|
}
|
|
// min={0}
|
|
// prefix="₹"
|
|
status={schedule.errors.displayPrice ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
style={{ width: '100%' }}
|
|
inputMode="decimal"
|
|
onInput={(e) => {
|
|
const cleanedValue = e.target.value.replace(
|
|
/[^0-9.]/g,
|
|
''
|
|
);
|
|
const parts = cleanedValue.split('.');
|
|
e.target.value =
|
|
parts.length > 2
|
|
? `${parts[0]}.${parts.slice(1).join('')}`
|
|
: cleanedValue;
|
|
}}
|
|
/>
|
|
{schedule.errors.displayPrice && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.displayPrice}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="membershipFormRow1">
|
|
<div className="membershipFormGroup TaxinputMemeber">
|
|
<label className="membershipFormLabel required">
|
|
Tax (%)
|
|
</label>
|
|
<Select
|
|
placeholder="Select Tax"
|
|
value={schedule.taxId}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'taxId', value)
|
|
}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
>
|
|
{taxData?.map((item) => (
|
|
<Option
|
|
key={item.TaxId}
|
|
value={item.TaxId}
|
|
>{`${item.TaxIdName} - ${item?.TaxPercentage}%`}</Option>
|
|
))}
|
|
</Select>
|
|
{schedule.errors.taxId && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.taxId}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="membershipFormGroup hourinputMemeber">
|
|
<label className="membershipFormLabel required">Hours</label>
|
|
<Input
|
|
placeholder="Enter hours"
|
|
value={schedule.hrs}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'hrs', value?.target?.value)
|
|
}
|
|
// min={0}
|
|
status={schedule.errors.hrs ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
style={{ width: '100%' }}
|
|
inputMode="decimal"
|
|
onInput={(e) => {
|
|
const cleanedValue = e.target.value.replace(
|
|
/[^0-9.]/g,
|
|
''
|
|
);
|
|
const parts = cleanedValue.split('.');
|
|
e.target.value =
|
|
parts.length > 2
|
|
? `${parts[0]}.${parts.slice(1).join('')}`
|
|
: cleanedValue;
|
|
}}
|
|
/>
|
|
{schedule.errors.hrs && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.hrs}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">
|
|
Discount Type
|
|
</label>
|
|
<Select
|
|
placeholder="Select discount type"
|
|
value={schedule.discountType}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'discountType', value)
|
|
}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
>
|
|
<Option value="F">Fixed</Option>
|
|
<Option value="P">Percentage</Option>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">
|
|
Discount Value
|
|
</label>
|
|
<InputNumber
|
|
placeholder="Enter discount"
|
|
value={schedule.discountValue}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'discountValue', value)
|
|
}
|
|
min={0}
|
|
prefix={schedule.discountType === 'F' ? '₹' : ''}
|
|
suffix={schedule.discountType === 'P' ? '%' : ''}
|
|
max={schedule.discountType === 'P' ? 100 : undefined}
|
|
status={schedule.errors.discountValue ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
style={{ width: '100%' }}
|
|
/>
|
|
{schedule.errors.discountValue && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.discountValue}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">Priority</label>
|
|
<Radio.Group
|
|
value={schedule.priority}
|
|
onChange={(e) =>
|
|
handleScheduleChange(schedule.id, 'priority', e.target.value)
|
|
}
|
|
size="large"
|
|
>
|
|
<Radio value="Y">Yes</Radio>
|
|
<Radio value="N">No</Radio>
|
|
</Radio.Group>
|
|
</div>
|
|
|
|
{schedule.priority === 'Y' && (
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel required">
|
|
Select Days
|
|
</label>
|
|
<Select
|
|
mode="multiple"
|
|
placeholder="Select days"
|
|
value={schedule.selectedDays}
|
|
onChange={(value) =>
|
|
handleScheduleChange(schedule.id, 'selectedDays', value)
|
|
}
|
|
status={schedule.errors.selectedDays ? 'error' : ''}
|
|
className="membershipFormInput"
|
|
size="large"
|
|
>
|
|
{DAYS_OF_WEEK.map((day) => (
|
|
<Option key={day.value} value={day.value}>
|
|
{day.label}
|
|
</Option>
|
|
))}
|
|
</Select>
|
|
{schedule.errors.selectedDays && (
|
|
<div className="membershipErrorText">
|
|
{schedule.errors.selectedDays}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
<div className="membershipFormGroup">
|
|
<label className="membershipFormLabel">Remarks</label>
|
|
<Input.TextArea
|
|
placeholder="Enter remarks"
|
|
value={schedule.remarks}
|
|
onChange={(e) =>
|
|
handleScheduleChange(schedule.id, 'remarks', e.target.value)
|
|
}
|
|
rows={3} // Adjust the number of rows as needed
|
|
className="membershipFormInputTextArea"
|
|
size="large"
|
|
/>
|
|
</div>
|
|
|
|
{schedule.errors.duplicate && (
|
|
<div className="membershipDuplicateError">
|
|
<span className="membershipErrorText">
|
|
{schedule.errors.duplicate}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
|
|
<div className="membershipFormActions">
|
|
<Button
|
|
type="dashed"
|
|
icon={<PlusOutlined />}
|
|
onClick={addSchedule}
|
|
className="membershipAddBtn"
|
|
size="large"
|
|
>
|
|
Add More Plan
|
|
</Button>
|
|
<Button
|
|
type="primary"
|
|
onClick={handleSubmit}
|
|
className="membershipSubmitBtn"
|
|
size="large"
|
|
>
|
|
{formType === 'add' ? `Create Membership` : `Update Membership`}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default MembershipForm;
|