Android_Retail/src/Pages/Product/SportsMaster.jsx

2523 lines
84 KiB
JavaScript

import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
Form,
Input,
InputNumber,
Button,
TimePicker,
Space,
Checkbox,
Collapse,
Tooltip,
Modal,
Table,
Tag,
Switch,
Select,
message,
} from 'antd';
import {
PlusOutlined,
MinusOutlined,
DeleteOutlined,
InfoCircleOutlined,
ArrowRightOutlined,
PlusCircleOutlined,
} from '@ant-design/icons';
// Import your custom components (adjust paths as needed)
import CropUpload from '../../Components/Forms/CropUpload.jsx';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
import {
getAllsubcatdata,
getProdCatData,
getProdSubCatData,
getUomData,
postProductData,
prodCatDataSelector,
prodSubCatDataSelector,
putProductData,
ServiceType,
uomDataSelector,
} from '../../Features/ProductPage/ProductPage.js';
import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
import { getSession } from '../../Services/Others.js';
import {
ApplicationPreferences,
getCommonAppPreference,
} from '../../Features/BrachLogin/BranchLogin.js';
import { getAdmin, taxSelector } from '../../Features/Tax/Tax.js';
import { changeBreadCrumb } from '../../Features/AppPage/CenterPage.js';
import { useLocation, useNavigate } from 'react-router-dom';
import './SportsMaster.scss';
import {
EmpDepartMentDropDown,
EmpDesgDropDown,
EmpTypeDropDown,
getEmpBasedOnCmpIdBrId,
GettingShiftData,
postEmp,
UserDataBasedOnBranchId,
} from '../../Features/EmpMaster/EmpMaster.js';
import { DatePic } from '../../Components/Forms/DatePickerEmpMaster.jsx';
import moment from 'moment';
import { InputField } from '../../Components/Forms/InputField.jsx';
import Cancellation from '../CancelReschedule/Cancellation.jsx';
import EmployeeMasterForm from '../EmpMaster/EmpMasterForm.jsx';
const { Panel } = Collapse;
const { TextArea } = Input;
const subDirectory = import.meta.env.ENV_BASE_URL;
const { RangePicker } = TimePicker;
export function SafeRangeTimePicker(props) {
const popupClass = 'no-hover-autoscroll-timepicker';
const userScrollTimeout = 150; // ms - time window to consider a scroll as user-initiated
// Attach handlers whenever the panel opens; we use a ref to store cleanup
const cleanupRef = useRef(() => {});
const onOpenChange = useCallback((open) => {
// when closed cleanup immediately
if (!open) {
cleanupRef.current();
cleanupRef.current = () => {};
return;
}
// Wait for panel to render in DOM
requestAnimationFrame(() => {
const columns = document.querySelectorAll(
`.${popupClass} .ant-picker-time-panel-column`
);
const disposers = [];
columns.forEach((column) => {
let rememberedScroll = column.scrollTop;
let lastUserScroll = 0;
let disableHoverAuto = false;
// Mark last user scroll on wheel / touchstart
const onUserScrollAttempt = (e) => {
lastUserScroll = Date.now();
};
// On mouse enter remember current scroll and enable 'guard' for auto-scrolling
const onMouseEnter = () => {
rememberedScroll = column.scrollTop;
disableHoverAuto = true;
};
// On mouse leave, disable the guard so normal behavior resumes
const onMouseLeave = () => {
disableHoverAuto = false;
};
// On scroll: if guard is on and there hasn't been a recent user wheel/touch,
// assume this scroll is the unwanted auto-scroll and revert to rememberedScroll.
const onScroll = () => {
const now = Date.now();
const recentUser = now - lastUserScroll <= userScrollTimeout;
if (disableHoverAuto && !recentUser) {
// cancel the auto scroll by snapping back
// use requestAnimationFrame to avoid layout thrash
requestAnimationFrame(() => {
column.scrollTop = rememberedScroll;
});
} else {
// user scrolled — update remembered position
rememberedScroll = column.scrollTop;
}
};
column.addEventListener('wheel', onUserScrollAttempt, {
passive: true,
});
column.addEventListener('touchstart', onUserScrollAttempt, {
passive: true,
});
column.addEventListener('mouseenter', onMouseEnter);
column.addEventListener('mouseleave', onMouseLeave);
column.addEventListener('scroll', onScroll);
disposers.push(() => {
column.removeEventListener('wheel', onUserScrollAttempt);
column.removeEventListener('touchstart', onUserScrollAttempt);
column.removeEventListener('mouseenter', onMouseEnter);
column.removeEventListener('mouseleave', onMouseLeave);
column.removeEventListener('scroll', onScroll);
});
});
// Save cleanup
cleanupRef.current = () => disposers.forEach((d) => d());
});
}, []);
// cleanup on unmount
useEffect(() => {
return () => cleanupRef.current();
}, []);
return (
<RangePicker
{...props}
popupClassName={popupClass}
onOpenChange={onOpenChange}
/>
);
}
const SportSlotCreation = ({ formType }) => {
const [form] = Form.useForm();
const navigate = useNavigate();
const dispatch = useDispatch();
const location = useLocation();
const state = location?.state;
const editstate = state?.editstate;
console.log(editstate, 'editstate');
const UomData = useSelector(uomDataSelector);
const ApplicationPreferenceData = useSelector(ApplicationPreferences);
const TaxData = useSelector(taxSelector);
const UomTypePreference = ApplicationPreferenceData?.find(
(preference) => preference?.PreferredCatName === 'Product Uom'
)?.PreferenceCatDetails;
const UomPreference = UomData?.filter((item) =>
UomTypePreference?.some?.(
(e) =>
e?.PreferredSubCatName?.toLowerCase() ==
item?.ConfigName?.toLowerCase() && e?.PreferredStatus == 'Y'
)
);
const ProdCatData = useSelector(prodCatDataSelector);
const ProdSubCatData = useSelector(prodSubCatDataSelector);
const [selectedType, setSelectedType] = useState(null);
const [selectedTypeName, setselectedTypeName] = useState(null);
const [selectedCategory, setSelectedCategory] = useState(null);
const [selectedSubCategory, setSelectedSubCategory] = useState(null);
const [selectedCoach, setSelectedCoach] = useState(null);
const [selectedCoachName, setSelectedCoachName] = useState(null);
console.log(selectedType, 'selectedType');
const [slotDuration, setSlotDuration] = useState(1);
const [generatedSlots, setGeneratedSlots] = useState([]);
const [startTime, setStartTime] = useState(null);
const [endTime, setEndTime] = useState(null);
const [defaultPrice, setDefaultPrice] = useState(null);
const [SelectedTaxId, setSelectedTaxId] = useState(null);
const [individualPricing, setIndividualPricing] = useState(false);
const [OnlineBooking, setOnlineBooking] = useState(false);
const [individualDefaultPrice, setIndividualDefaultPrice] = useState(null);
console.log(defaultPrice, 'defaultPricedefaultPrice');
// const [fullSlotDefaultPrice, setFullSlotDefaultPrice] = useState(0);
// const [openCategoryModal, setOpenCategoryModal] = useState(false);
// const [openSubCategoryModal, setOpenSubCategoryModal] = useState(false);
// const [openCoachModal, setOpenCoachModal] = useState(false);
const [ServicesDatas, setServicesDatas] = useState([]);
// const [EmpTypeDropDownData, setEmpTypeDropDownData] = useState([]);
// const [seletedEmpTypeDrop, setseletedEmpTypeDrop] = useState(null);
// const [EmpDesgDropDownData, setEmpDesgDropDownData] = useState([]);
// const [seletedEmpDesigDrop, setseletedEmpDesigDrop] = useState(null);
// const [EmpDeptDropDownData, setEmpDeptDropDownData] = useState([]);
// const [seletedEmpDeptDrop, setseletedEmpDeptDrop] = useState(null);
// const [ShiftDownData, setShiftDownData] = useState([]);
// const [seletedShiftDrop, setseletedShiftDrop] = useState(null);
// const [AppPreference, setAppPreference] = useState([]);
// const [SelectedDate, setSelectedDate] = useState(null);
// const [showPassword, setShowPassword] = useState(false);
const [userDropDown, setuserDropDown] = useState([]);
const [EmployeesDatas, setEmployeesDatas] = useState([]);
const [selectedUserData, setSelectedUserData] = useState(null);
// const [zipCodeData, setZipCodeData] = useState(false);
// state for multiple images
const [imageUrls, setImageUrls] = useState([]);
// Image states
const [imageUrl, setImageUrl] = useState('');
// const [imageopen, setimageOpen] = useState(false);
// const [imagedata, setimagedata] = useState([]);
// const [selectedImage, setSelectedImage] = useState(null);
// const [onlineImage, setOnlineImage] = useState(null);
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const AppId = getSession('AppId');
const UserId = getSession('UserId');
// Day selection states
const [selectedDays, setSelectedDays] = useState({
monday: false,
tuesday: false,
wednesday: false,
thursday: false,
friday: false,
saturday: false,
sunday: false,
});
const [selectAllDays, setSelectAllDays] = useState(false);
// const departmentTypePreference = AppPreference?.[0]?.PreferenceDetails?.find(
// (preference) => preference?.PreferredCatName === 'Department'
// );
// const activeDeptTypes = departmentTypePreference?.PreferenceCatDetails?.filter(
// (payment) => payment.PreferredStatus !== 'Y')
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
{
name: 'Slot',
link: `${subDirectory}setting/product-master/`,
},
{
name: editstate ? 'Edit' : 'New',
link: null,
},
];
useEffect(() => {
const allSelected = Object.values(selectedDays).every((day) => day);
setSelectAllDays(allSelected);
}, [selectedDays]);
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
dispatch(getUomData());
dispatch(getProdCatData({ AppId: AppId }));
// dispatch(getProdTaxData({ AppId: AppId }));
dispatch(getAdmin({ CompId: CompId, AppId: AppId }));
ServiceTypeFn();
getEmployees();
if (formType == 'edit') {
const daysOfWeek = editstate?.SlotDetails?.[0]?.DayOfWeek?.map((e) =>
e.trim()?.toLowerCase()
);
dispatch(getProdSubCatData({ ConfigId: editstate?.ProdCat }));
setselectedTypeName(editstate?.ProdTypeName);
setSelectedType(editstate?.ProdType);
setSelectedCategory(editstate?.ProdCat);
setSelectedTaxId(editstate?.TaxId);
setSelectedSubCategory(editstate?.ProdSubCat);
setSelectedDays({
monday: daysOfWeek?.includes('monday'),
tuesday: daysOfWeek?.includes('tuesday'),
wednesday: daysOfWeek?.includes('wednesday'),
thursday: daysOfWeek?.includes('thursday'),
friday: daysOfWeek?.includes('friday'),
saturday: daysOfWeek?.includes('saturday'),
sunday: daysOfWeek?.includes('sunday'),
});
setIndividualPricing(
editstate?.SlotDetails?.some((e) => e?.SinglePrice != e?.MRP)
);
setOnlineBooking(
editstate?.SlotDetails?.some((e) => e?.OnlineApplicable == 'Y')
);
setDefaultPrice(editstate?.SlotDetails?.[0]?.SellPrice);
setIndividualDefaultPrice(editstate?.SlotDetails?.[0]?.SinglePrice);
form.setFieldsValue({
defaultPrice: editstate?.SlotDetails?.[0]?.SellPrice,
});
form.setFieldsValue({
individualDefaultPrice: editstate?.SlotDetails?.[0]?.SinglePrice,
});
setStartTime(editstate?.SlotDetails?.[0]?.AvailableFrom);
setEndTime(
editstate?.SlotDetails?.[editstate?.SlotDetails?.length - 1]
?.AvailableTo
);
setGeneratedSlots(
editstate?.SlotDetails?.map((e) => {
return {
SlotName: e?.SlotName,
AvailableFrom: e?.AvailableFrom,
AvailableTo: e?.AvailableTo,
OnlineApplicable: e?.OnlineApplicable == 'Y' ? true : false,
individualPurchase: e?.SinglePrice != e?.MRP ? true : false,
individualPrice: e?.SinglePrice,
MRP: e?.MRP,
SellPrice: e?.SellPrice,
ExceptionFrom: '',
ExceptionTo: '',
IsHoliday: 'N',
DayOfWeek: e?.DayOfWeek,
active: true,
Remarks: 'string',
};
})
);
// se
setSelectedCoach(Number(editstate?.TrainerId));
setSelectedCoachName(editstate?.ProdName);
form.setFieldsValue({ coach: Number(editstate?.TrainerId) });
setOnlineBooking(
editstate?.SlotDetails?.some((e) => e?.OnlineApplicable == 'Y')
);
setIndividualPricing(
editstate?.SlotDetails?.some((e) => e?.SinglePrice != e?.MRP)
);
setSlotDuration(editstate?.SlotHours);
setDefaultPrice(editstate?.SlotDetails?.[0]?.SellPrice);
setImageUrl(editstate?.ProdLogo);
form.setFieldsValue({ 'Sport-subCategory': editstate?.ProdSubCat });
form.setFieldsValue({ TaxId: editstate?.TaxId });
form.setFieldsValue({ 'Sport-category': editstate?.ProdCat });
form.setFieldsValue({ type: editstate?.ProdType });
form.setFieldsValue({ maxCapacity: editstate?.Size });
form.setFieldsValue({ groundName: editstate?.ProdName });
form.setFieldsValue({
defaultPrice: editstate?.SlotDetails?.[0]?.SellPrice,
});
form.setFieldsValue({
description: editstate?.SportDec?.[0]?.description,
});
form.setFieldsValue({ facilities: editstate?.SportDec?.[0]?.Facilities });
form.setFieldsValue({ terms: editstate?.SportDec?.[0]?.Terms });
form.setFieldsValue({
cancellationPolicy: editstate?.SportDec?.[0]?.CancellationPolicy,
});
}
}, []);
// useEffect(() => {
// getApplicationPreference()
// BranchDropDownChange()
// }, [])
// const getApplicationPreference = async () => {
// const response = await dispatch(getCommonAppPreference(AppId)).unwrap();
// if (response?.data?.statusCode === 1) {
// setAppPreference(response?.data?.data)
// }
// }
// const BranchDropDownChange = async (e = BranchId) => {
// // formRef.current?.setFieldsValue({ BranchId: e });
// let gettinguserDropDown = [];
// gettinguserDropDown = await dispatch(
// UserDataBasedOnBranchId({
// BranchId: e,
// Type: 'E',
// })
// ).unwrap();
// if (gettinguserDropDown?.data?.statusCode === 1) {
// let finaluserDropDown = gettinguserDropDown?.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettinguserDropDown?.data?.data?.length === 1) {
// setSelectedUserData(
// gettinguserDropDown?.data?.data?.length === 1
// ? gettinguserDropDown?.data?.data[0]?.UserId
// : null
// );
// form?.setFieldsValue({
// UserId:
// gettinguserDropDown?.data?.data?.length === 1
// ? gettinguserDropDown?.data?.data[0]?.UserId
// : null,
// });
// await UserDropDownChangeMobile(
// gettinguserDropDown?.data?.data[0]?.UserId,
// finaluserDropDown
// );
// }
// setuserDropDown(finaluserDropDown);
// }
// };
// const UserDropDownChangeMobile = async (e, Mobile) => {
// // MobileNo
// let mob = Mobile.filter((item) => item?.UserId === e);
// console.log(mob, 'ddddddddd');
// const data = mob?.length > 0 ? mob[0] : {};
// form?.setFieldsValue({
// UserId: e,
// MobileNo: data.MobileNo,
// Address1: data.Address1,
// Address2: data.Address2,
// Latitude: data.Latitude,
// Longitude: data.Longitude,
// Zip: data.Zip,
// MailId: data.MailId,
// State: data.State,
// UserImage: data.UserImage,
// });
// // await getPincodeValues(mob?.[0]?.Zip);
// setSelectedUserData(e);
// const gettingEmpTypeDropDown = await dispatch(EmpTypeDropDown()).unwrap();
// if (gettingEmpTypeDropDown?.data?.statusCode === 1) {
// let finalEmpTypeDropDown = gettingEmpTypeDropDown?.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingEmpTypeDropDown?.data?.data?.length === 1) {
// setseletedEmpTypeDrop(
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null
// );
// form.setFieldsValue({
// EmpType:
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null,
// });
// await EmpTypeDropDownChange(
// gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// );
// }
// //
// setEmpTypeDropDownData(finalEmpTypeDropDown);
// }
// };
// const onChange = async (date, dateString) => {
// if (!dateString) {
// setSelectedDate();
// } else {
// // Convert and format the date properly
// const Date1 = moment(dateString, 'DD-MM-YYYY').format('YYYY-MM-DDTHH:mm:ss');
// form?.setFieldsValue({ EmpDOJ: Date1 });
// await setSelectedDate(Date1);
// }
// };
const handleDayChange = (day) => {
setSelectedDays((prev) => ({
...prev,
[day]: !prev[day],
}));
};
const handleSelectAllDays = (checked) => {
setSelectAllDays(checked);
if (checked) {
setSelectedDays({
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: true,
sunday: true,
});
} else {
setSelectedDays({
monday: false,
tuesday: false,
wednesday: false,
thursday: false,
friday: false,
saturday: false,
sunday: false,
});
}
};
const getEmployees = async () => {
const gettingTableData = await dispatch(
getEmpBasedOnCmpIdBrId({ cmpId: CompId, BranchId: BranchId })
).unwrap();
if (gettingTableData?.data?.statusCode === 1) {
setEmployeesDatas(gettingTableData?.data?.data);
}
};
const ServiceTypeFn = async () => {
let Response = await dispatch(ServiceType()).unwrap();
if (Response?.data?.statusCode == 1) {
setServicesDatas(Response?.data?.data);
} else {
setServicesDatas([]);
}
};
// const HandleEmpTypeDropDownData = async () => {
// const gettingEmpTypeDropDown = await dispatch(EmpTypeDropDown()).unwrap();
// if (gettingEmpTypeDropDown?.data?.statusCode === 1) {
// let finalEmpTypeDropDown = gettingEmpTypeDropDown?.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingEmpTypeDropDown?.data?.data?.length === 1) {
// setseletedEmpTypeDrop(
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null
// );
// form.current?.setFieldsValue({
// EmpType:
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null,
// });
// await EmpTypeDropDownChange(
// gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// );
// }
// //
// setEmpTypeDropDownData(finalEmpTypeDropDown);
// }
// };
// const getPincodeValues = async (pinCode) => {
// let response = '';
// await fetch(`https://api.postalpincode.in/pincode/${pinCode}`)
// .then((res) => res.text())
// .then((text) => (response = JSON.parse(text)));
// if (response[0]['Status'] === 'Success') {
// setZipCodeData(true);
// form?.setFieldsValue({
// City: response[0]['PostOffice'][0]['Block'],
// Dist: response[0]['PostOffice'][0]['District'],
// State: response[0]['PostOffice'][0]['State'],
// });
// } else {
// setZipCodeData(false);
// }
// };
// const UserDropDownChange = async (e) => {
// let mob = userDropDown.filter((item) => item?.UserId === e);
// await getPincodeValues(mob?.[0]?.Zip);
// setSelectedUserData(e);
// const gettingEmpTypeDropDown = await dispatch(EmpTypeDropDown()).unwrap();
// if (gettingEmpTypeDropDown?.data?.statusCode === 1) {
// let finalEmpTypeDropDown = gettingEmpTypeDropDown?.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingEmpTypeDropDown?.data?.data?.length === 1) {
// setseletedEmpTypeDrop(
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null
// );
// form?.setFieldsValue({
// EmpType:
// gettingEmpTypeDropDown?.data?.data?.length === 1
// ? gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// : null,
// });
// await EmpTypeDropDownChange(
// gettingEmpTypeDropDown?.data?.data[0]?.ConfigId
// );
// }
// //
// setEmpTypeDropDownData(finalEmpTypeDropDown);
// }
// };
// const EmpTypeDropDownChange = async (e) => {
// form.setFieldsValue({ EmpType: e });
// setseletedEmpTypeDrop(e);
// const gettingEmpDesgDropDown = await dispatch(
// EmpDesgDropDown({ AppId: AppId })
// ).unwrap();
// if (gettingEmpDesgDropDown.data?.statusCode === 1) {
// let finalEmpDesgDropDown = gettingEmpDesgDropDown.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingEmpDesgDropDown?.data?.data?.length === 1) {
// setseletedEmpDesigDrop(
// gettingEmpDesgDropDown?.data?.data?.length === 1
// ? gettingEmpDesgDropDown?.data?.data[0]?.ConfigId
// : null
// );
// form.setFieldsValue({
// EmpDesig:
// gettingEmpDesgDropDown?.data?.data?.length === 1
// ? gettingEmpDesgDropDown?.data?.data[0]?.ConfigId
// : null,
// });
// await EmpDesigDropDownChange(
// gettingEmpDesgDropDown?.data?.data[0]?.ConfigId
// );
// }
// setEmpDesgDropDownData(finalEmpDesgDropDown);
// }
// };
// const EmpDesigDropDownChange = async (e) => {
// form.setFieldsValue({ EmpDesig: e });
// setseletedEmpDesigDrop(e);
// const gettingEmpDeptDropDown = await dispatch(
// EmpDepartMentDropDown()
// ).unwrap();
// if (gettingEmpDeptDropDown.data?.statusCode === 1) {
// let finalEmpDeptDropDown = gettingEmpDeptDropDown.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingEmpDeptDropDown?.data?.data?.length === 1) {
// setseletedEmpDeptDrop(
// gettingEmpDeptDropDown?.data?.data?.length === 1
// ? gettingEmpDeptDropDown?.data?.data[0]?.ConfigId
// : null
// );
// formsetFieldsValue({
// EmpDept:
// gettingEmpDeptDropDown?.data?.data?.length === 1
// ? gettingEmpDeptDropDown?.data?.data[0]?.ConfigId
// : null,
// });
// await EmpDeptDropDownChange(
// gettingEmpDeptDropDown?.data?.data[0]?.ConfigId
// );
// }
// setEmpDeptDropDownData(finalEmpDeptDropDown);
// }
// };
// const EmpDeptDropDownChange = async (e) => {
// form.setFieldsValue({ EmpDept: e });
// setseletedEmpDeptDrop(e);
// const gettingShiftDropDown = await dispatch(
// GettingShiftData(CompId)
// ).unwrap();
// if (gettingShiftDropDown.data?.statusCode === 1) {
// let finalShiftDropDown = gettingShiftDropDown.data?.data?.filter(
// (value) => value.ActiveStatus === 'A'
// );
// if (gettingShiftDropDown?.data?.data?.length === 1) {
// setseletedShiftDrop(
// gettingShiftDropDown?.data?.data?.length === 1
// ? gettingShiftDropDown?.data?.data[0]?.ShiftId
// : null
// );
// form?.setFieldsValue({
// EmpShiftId:
// gettingShiftDropDown?.data?.data?.length === 1
// ? gettingShiftDropDown?.data?.data[0]?.ShiftId
// : null,
// });
// await ShiftDropDownChange(gettingShiftDropDown?.data?.data[0]?.ShiftId);
// }
// setShiftDownData(finalShiftDropDown);
// }
// };
// const ShiftDropDownChange = async (e) => {
// form?.setFieldsValue({ EmpShiftId: e });
// setseletedShiftDrop(e);
// };
const handleTypeChange = (value) => {
setSelectedType(value);
setselectedTypeName(
ServicesDatas?.find((e) => e?.ConfigId == value)?.ConfigName
);
setSelectedCategory(null);
setSelectedSubCategory(null);
setSelectedCoach(null);
form.setFieldsValue({ type: value });
};
const handleTaxDropDownChange = async (TaxId) => {
form.setFieldsValue({ TaxId: TaxId });
await setSelectedTaxId(TaxId);
};
// Handle category change
const handleCategoryChange = (value) => {
dispatch(getProdSubCatData({ ConfigId: value }));
setSelectedCategory(value);
setSelectedSubCategory(null);
form.setFieldsValue({ 'Sport-category': value });
};
// Handle sub category change
const handleSubCategoryChange = (value) => {
form.setFieldsValue({ 'Sport-subCategory': value });
setSelectedSubCategory(value);
};
// Handle coach change
const handleCoachChange = (value) => {
setSelectedCoach(value);
setSelectedCoachName(
EmployeesDatas?.find((e) => e?.UserId == value)?.EmpFirstName
);
form.setFieldsValue({ coach: value });
};
// Duration controls
const increaseDuration = () => {
setSlotDuration((prev) => Math.min(prev + 1, 24));
};
const decreaseDuration = () => {
setSlotDuration((prev) => Math.max(prev - 1, 1));
};
const handleDurationInput = (value) => {
if (value >= 1 && value <= 24) {
setSlotDuration(value);
}
};
// Get field name based on category
// const getFieldName = () => {
// if (!selectedCategory) return 'Facility Name';
// const category = sportCategories.find(cat => cat.ConfigId === selectedCategory);
// if (!category) return 'Facility Name';
// switch (category.ConfigName.toLowerCase()) {
// case 'tennis':
// case 'badminton':
// case 'basketball':
// return 'Court Name';
// case 'swimming':
// return 'Swimming Pool Name';
// case 'cricket':
// case 'football':
// case 'volleyball':
// default:
// return 'Ground Name';
// }
// };
// Generate slots based on time range and duration
const generateSlots = () => {
if (!startTime || !endTime) {
message.error('Please select start and end time');
return;
}
const start = moment(startTime, 'HH:mm');
const end = moment(endTime, 'HH:mm');
if (end <= start) {
message.error('End time must be after start time');
return;
}
// Check if at least one day is selected
const hasSelectedDays = Object.values(selectedDays).some((day) => day);
if (!hasSelectedDays) {
message.error('Please select at least one day for slot availability');
return;
}
// Validate prices
if (!defaultPrice || defaultPrice < 1) {
message.error('Price Per Slot must be at least ₹1');
return;
}
if (
individualPricing &&
(!individualDefaultPrice || individualDefaultPrice < 1)
) {
message.error('Individual Price must be at least ₹1');
return;
}
const durationMinutes = slotDuration * 60;
const slots = [];
let currentTime = start;
let slotNumber = 1;
while (currentTime < end) {
const slotEnd = moment(currentTime).add(durationMinutes, 'minutes');
if (slotEnd > end) break;
// Set both individual and full slot prices
const individualPrice = individualPricing
? individualDefaultPrice
: defaultPrice;
const fullSlotPrice = defaultPrice;
slots.push({
id: `slot-${slotNumber}`,
SlotName: `Slot ${slotNumber}`,
// startTime: currentTime.format('HH:mm'),
AvailableFrom: currentTime.format('HH:mm'),
AvailableTo: slotEnd.format('HH:mm'),
// endTime: slotEnd.format('HH:mm'),
individualPrice: individualPrice,
MRP: fullSlotPrice,
SellPrice: fullSlotPrice,
// fullSlotPrice: fullSlotPrice,
editable: true,
individualPurchase: individualPricing,
OnlineApplicable: OnlineBooking,
active: true,
IsHoliday: null,
DayOfWeek: Object.keys(selectedDays)?.filter(
(day) => selectedDays[day]
),
});
currentTime = slotEnd;
slotNumber++;
}
if (slots.length === 0) {
Modal.warning({
title: 'No Slots Generated',
content:
'No slots can be generated with the current time range and duration.',
});
return;
}
setGeneratedSlots(slots);
};
// Slot management functions
const updateSlotName = (index, newName) => {
const updatedSlots = [...generatedSlots];
updatedSlots[index].SlotName = newName;
setGeneratedSlots(updatedSlots);
};
const updateIndividualPrice = (index, price) => {
const updatedSlots = [...generatedSlots];
updatedSlots[index].individualPrice = price || 0;
setGeneratedSlots(updatedSlots);
};
// const updateFullSlotPrice = (index, price) => {
// const updatedSlots = [...generatedSlots];
// updatedSlots[index].fullSlotPrice = price || 0;
// setGeneratedSlots(updatedSlots);
// };
const toggleIndividualPurchase = (index) => {
const updatedSlots = [...generatedSlots];
updatedSlots[index].individualPurchase =
!updatedSlots[index].individualPurchase;
setGeneratedSlots(updatedSlots);
};
const toggleOnlineApplicable = (index) => {
const updatedSlots = [...generatedSlots];
updatedSlots[index].OnlineApplicable =
!updatedSlots[index].OnlineApplicable;
setGeneratedSlots(updatedSlots);
};
const removeSlot = (index) => {
Modal.confirm({
title: 'Confirm Delete',
content: 'Are you sure you want to delete this slot?',
okText: 'Yes',
cancelText: 'No',
onOk() {
const updatedSlots = generatedSlots?.filter((_, i) => i !== index);
setGeneratedSlots(updatedSlots);
},
});
};
// const toggleSlotActive = (index) => {
// const updatedSlots = [...generatedSlots];
// updatedSlots[index].active = !updatedSlots[index].active;
// setGeneratedSlots(updatedSlots);
// };
const updateImageUrl = (url, index = 0) => {
// keep legacy single imageUrl for backward compatibility
setImageUrl(url);
setImageUrls((prev) => {
const copy = Array.isArray(prev) ? [...prev] : [];
copy[index] = {
...(copy[index] || {}),
image: url,
};
return copy;
});
};
// Image handling functions
// const updateImageUrls = (url, index = 0) => {
// // support updating a specific index in the images array
// setImageUrls(prev => {
// const copy = Array.isArray(prev) ? [...prev] : [];
// copy[index] = {
// ...(copy[index] || {}),
// image: url,
// };
// return copy;
// });
// // also update main image for legacy places
// setImageUrl(url);
// };
// const updateImageName = (name, index = 0) => {
// setImageUrls(prev => {
// const copy = Array.isArray(prev) ? [...prev] : [];
// copy[index] = {
// ...(copy[index] || {}),
// name: name,
// };
// return copy;
// });
// };
// const addimages = () => {
// setimageOpen(true);
// };
// const handleimage = () => {
// setimageOpen(false);
// setSelectedImage(null);
// };
// const submitimage = async () => {
// if (selectedImage) {
// setImageUrl(selectedImage.image);
// setOnlineImage(selectedImage.image);
// }
// setimageOpen(false);
// };
const getSelectedDaysText = () => {
const daysMap = {
monday: 'Mon',
tuesday: 'Tue',
wednesday: 'Wed',
thursday: 'Thu',
friday: 'Fri',
saturday: 'Sat',
sunday: 'Sun',
};
const selected = Object.entries(selectedDays)
?.filter(([_, isSelected]) => isSelected)
.map(([day]) => daysMap[day]);
return selected.length > 0 ? selected.join(', ') : 'No days selected';
};
const slotColumns = [
{
title: 'Sl.No',
key: 'sno',
align: 'center',
width: '60px',
render: (text, record, index) => index + 1,
},
{
title: 'Slot Name',
dataIndex: 'SlotName',
key: 'SlotName',
align: 'center',
render: (text, record, index) => (
<Input
value={text}
maxLength={30}
onChange={(e) => updateSlotName(index, e.target.value)}
className="sports-master__slot-input"
placeholder="Enter slot name"
/>
),
},
{
title: 'Time Slot',
key: 'time',
align: 'center',
width: '120px',
render: (record) => (
<div className="sports-master__time-slot">
<div className="sports-master__time-value">
{record.AvailableFrom}
</div>
<div className="sports-master__time-separator">to</div>
<div className="sports-master__time-value">{record.AvailableTo}</div>
</div>
),
},
{
title: 'Days',
key: 'DayOfWeek',
align: 'center',
width: '150px',
render: (record) => {
const daysArray = Array.isArray(record?.DayOfWeek)
? record.DayOfWeek.map((day) => day.trim())
: [];
console.log(daysArray, 'daysArray11111111');
return (
<div className="sports-master__days-container">
{daysArray?.map((day, index) => (
<Tag key={index} color="blue" className="sports-master__day-tag">
{day?.[0]?.toUpperCase()}
</Tag>
))}
</div>
);
},
},
{
title: 'Individual Price (₹)',
dataIndex: 'individualPrice',
key: 'individualPrice',
align: 'center',
width: '140px',
render: (text, record, index) =>
record?.individualPurchase ? (
<InputNumber
value={text}
onChange={(value) => updateIndividualPrice(index, value)}
min={0}
max={99999}
className="sports-master__input-number"
formatter={(value) =>
`${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
parser={(value) => value.replace(/₹\s?|(,*)/g, '')}
size="small"
/>
) : (
<span>-</span>
),
},
// {
// title: 'Full Slot Price (₹)',
// dataIndex: 'fullSlotPrice',
// key: 'fullSlotPrice',
// align: 'center',
// width: '140px',
// render: (text, record, index) => (
// <InputNumber
// value={text}
// onChange={(value) => updateFullSlotPrice(index, value)}
// min={0}
// className="sports-master__input-number"
// formatter={value => `₹ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
// parser={value => value.replace(/₹\s?|(,*)/g, '')}
// size="small"
// />
// ),
// },
{
title: 'Individual Purchase',
dataIndex: 'individualPurchase',
key: 'individualPurchase',
align: 'center',
width: '120px',
render: (text, record, index) => (
<Checkbox
checked={text}
onChange={() => toggleIndividualPurchase(index)}
/>
),
},
{
title: 'Online Booking',
dataIndex: 'OnlineApplicable',
key: 'OnlineApplicable',
align: 'center',
width: '120px',
render: (text, record, index) => (
<Checkbox
checked={text}
onChange={() => toggleOnlineApplicable(index)}
/>
),
},
// {
// title: 'Status',
// key: 'status',
// align: 'center',
// width: '100px',
// render: (record, _, index) => (
// <Switch
// checked={record.active}
// onChange={() => toggleSlotActive(index)}
// size="small"
// checkedChildren="A"
// unCheckedChildren="I"
// />
// ),
// },
{
title: 'Action',
key: 'action',
align: 'center',
width: '80px',
render: (text, record, index) => (
<Button
type="text"
danger
icon={<DeleteOutlined />}
onClick={() => removeSlot(index)}
size="small"
/>
),
},
];
const handleSubmit = async (values) => {
let UomId = UomPreference?.filter(
(item) =>
item.ConfigName?.toLowerCase() ===
(values?.maxCapacity > 1 ? 'members' : 'member')
)?.[0]?.['ConfigId'];
const today = new Date();
const formattedDate = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
let postData = {
ProdName:
selectedTypeName.toLowerCase() == 'coach'
? selectedCoachName
: values?.groundName,
...(selectedTypeName.toLowerCase() == 'coach' && {
TrainerId: selectedCoach,
}),
Size: values?.maxCapacity,
UOM: UomId,
MRP: '0',
SellPrice: '0',
ProdCat: selectedCategory,
ProdSubCat: selectedSubCategory,
Brand: null,
ProdCount: null,
ProdType: selectedType,
TaxId: SelectedTaxId,
Cess: 0,
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
SuppId: '',
ProdLogo: imageUrl,
QtyBasedPrice: 'N',
ProdQtywisePriceDetails: [],
StockAvailable: 'N',
TokenAvailable: 'N',
OnePcsAvailable: individualPricing ? 'Y' : 'N',
IsEmiAllowed: 'N',
InwardDate: formattedDate,
AutoGenerateQr: 'N',
AutoGenerateSingleQr: 'N',
CreatedBy: UserId,
Rack: 0,
ProdVariantDetails: [],
ProdVariantName: '',
DiscountLimit: 0,
DiscountLimitType: 'F',
SlotHours: slotDuration,
SlotDetails: generatedSlots?.map((e) => {
return {
SlotName: e?.SlotName,
AvailableFrom: e?.AvailableFrom,
AvailableTo: e?.AvailableTo,
OnlineApplicable: e?.OnlineApplicable ? 'Y' : 'N',
MRP: e?.MRP,
SellPrice: e?.SellPrice,
SinglePrice: e?.individualPurchase ? e?.individualPrice : 0,
ExceptionFrom: '',
ExceptionTo: '',
IsHoliday: 'N',
DayOfWeek:
typeof e?.DayOfWeek === 'object' && e?.DayOfWeek !== null
? Object.keys(selectedDays)?.filter((day) => selectedDays[day])
: e?.DayOfWeek,
Remarks: 'string',
};
}),
SportDec: [
{
description: values?.description || '',
Facilities: values?.facilities || '',
Terms: values?.terms || '',
CancellationPolicy: values?.cancellationPolicy || '',
},
],
};
if (formType == 'add') {
try {
let response = await dispatch(postProductData(postData)).unwrap();
if (response?.data?.statusCode == 1) {
navigate(`${subDirectory}setting/product-master/`, {
state: {
Notiffy: {
messageType: 'success',
messageData: response?.data?.response,
},
},
});
}
} catch (err) {}
} else {
try {
delete postData?.CreatedBy;
postData = {
...postData,
ProdId: editstate?.ProdId,
UniqueId: editstate?.UniqueId,
UpdatedBy: UserId,
};
console.log(postData, 'postData');
let response = await dispatch(putProductData(postData)).unwrap();
if (response?.data?.statusCode == 1) {
navigate(`${subDirectory}setting/product-master/`, {
state: {
Notiffy: {
messageType: 'success',
messageData: response?.data?.response,
},
},
});
}
} catch (err) {}
}
};
// const addCategory = () => {
// setOpenCategoryModal(true);
// };
// const addSubCategory = () => {
// if (!selectedCategory) {
// Modal.warning({
// title: 'Warning',
// content: 'Please select a category first',
// });
// return;
// }
// setOpenSubCategoryModal(true);
// };
const addCoach = () => {
// setOpenCoachModal(true);
navigate(`${subDirectory}setting/employee-master/new`);
};
// const handleCategoryModalClose = () => {
// setOpenCategoryModal(false);
// };
// const handleSubCategoryModalClose = () => {
// setOpenSubCategoryModal(false);
// };
// const handleCoachModalClose = () => {
// setOpenCoachModal(false);
// };
// const submitCategory = () => {
// Modal.success({
// title: 'Success',
// content: 'Category added successfully!',
// });
// setOpenCategoryModal(false);
// };
// const submitSubCategory = () => {
// Modal.success({
// title: 'Success',
// content: 'Sub-category added successfully!',
// });
// setOpenSubCategoryModal(false);
// };
// const submitCoach = async () => {
// let postData = {
// "UserId": selectedUserData,
// "CompId": CompId,
// "BranchId": BranchId,
// "EmpFirstName": userDropDown?.find((e) => e?.UserId == selectedUserData)?.UserName,
// // "EmpLastName": "string",
// "EmpType": seletedEmpTypeDrop,
// "EmpDesig": seletedEmpDesigDrop,
// "EmpDept": seletedEmpDeptDrop,
// "EmpDOJ": "2025-10-14T12:28:22.596Z",
// "EmpPhotoLink": "",
// "RoleId": 0,
// "EmpShiftId": seletedShiftDrop,
// // "MobileAppAccess": "string",
// // "Address1": "string",
// // "Address2": "string",
// // "Zip": 0,
// // "City": "string",
// // "Dist": "string",
// // "State": "string",
// // "Latitude": 0,
// // "Longitude": 0,
// // "Password": "string",
// // "Pin": "string",
// "MobileNo": form?.getFieldValue("MobileNo"),
// // "MailId": "string",
// "Description": form?.getFieldValue("coachQualifications"),
// "Certification": "string",
// "Experience": form?.getFieldValue("coachExperience"),
// // "ImageDetails": [
// // {
// // "ImageUrl": "string",
// // "ImageType": "string",
// // "DisplayOrder": "string"
// // }
// // ],
// ImageDetails: (imageUrls || []).filter(item => item && (item.image || item.name)).map((item, index) => ({
// ImageUrl: item.image || '',
// ImageName: item.name || '',
// ImageType: "Coach",
// DisplayOrder: index + 1
// })) || [],
// "CreatedBy": UserId
// }
// let response = await dispatch(postEmp(postData)).unwrap();
// if (response?.data?.statusCode == 1) {
// Modal.success({
// title: 'Success',
// content: 'Coach added successfully!',
// });
// setOpenCoachModal(false);
// }
// };
// Update all slot prices when pricing settings change
// useEffect(() => {
// if (generatedSlots.length > 0) {
// const updatedSlots = generatedSlots.map(slot => ({
// ...slot,
// individualPrice: individualPricing ? individualDefaultPrice : defaultPrice,
// fullSlotPrice: fullSlotDefaultPrice || defaultPrice,
// // DayOfWeek: { ...selectedDays }
// // Update days for all slots when days change
// }));
// setGeneratedSlots(updatedSlots);
// }
// }, [individualPricing, individualDefaultPrice, defaultPrice, fullSlotDefaultPrice, selectedDays]);
// Load images when modal opens
// useEffect(() => {
// if (imageopen) {
// imagecall();
// }
// }, [imageopen]);
// Calculate totals for summary
const getOptionLabel = (option, selected) => {
return selected
? option.TaxPercentage + ' %'
: option.TaxIdName + ' - ' + option.TaxPercentage + ' % ';
};
const calculateTotals = () => {
const activeSlots = generatedSlots?.filter((slot) => slot.active);
const totalIndividualRevenue = activeSlots?.reduce(
(sum, slot) => sum + (slot.individualPrice || 0),
0
);
const totalFullSlotRevenue = activeSlots?.reduce(
(sum, slot) => sum + (slot.fullSlotPrice || 0),
0
);
return {
totalSlots: generatedSlots.length,
activeSlots: activeSlots.length,
totalIndividualRevenue,
totalFullSlotRevenue,
totalRevenue: totalIndividualRevenue + totalFullSlotRevenue,
};
};
const totals = calculateTotals();
return (
<div className="sports-master">
<div className="sports-master__header">
<h1 className="sports-master__title">Add Slot</h1>
{/* <p className="sports-master__subtitle">
Create and manage time slots for sports grounds and coaching sessions
</p> */}
</div>
<Form
form={form}
layout="vertical"
onFinish={handleSubmit}
initialValues={{
maxPlayers: 1,
slotDuration: 0.5,
defaultPrice: 0,
individualDefaultPrice: 0,
// fullSlotDefaultPrice: 0
}}
>
<div className="sports-master__basic-info">
<div className="sports-master__form-row">
<div className="sports-master__form-container">
<div className="sports-master__form-group">
<div className="sports-master__form-field">
<Form.Item
name="type"
rules={[{ required: true, message: 'Please select type' }]}
>
<DropDowns
options={ServicesDatas?.map((e) => ({
value: e.ConfigId,
label: e.ConfigName,
}))}
// label="Select Type"
label={<label class="required">Select Type</label>}
className="field-DropDown"
onChangeFunction={handleTypeChange}
valueData={selectedType}
isOnchanges={selectedType ? true : false}
disabled={formType === 'edit' ? true : false}
/>
</Form.Item>
</div>
{selectedTypeName?.toLowerCase() === 'ground' && (
<>
<div className="sports-master__form-field">
<Form.Item
name="groundName"
rules={[
{
required: true,
message: `Please enter Ground Name `,
},
]}
>
<InputField
label={
<label class="required">Enter Ground Name</label>
}
isOnChange={form.getFieldValue('groundName')}
/>
</Form.Item>
</div>
<div className="sports-master__form-field">
<Form.Item
name="Sport-category"
// label="Sport Category"
rules={[
{
required: true,
message: 'Please select sport category',
},
]}
>
<div style={{ display: 'flex' }}>
<DropDowns
options={ProdCatData.map((cat) => ({
value: cat.ConfigId,
label: cat.ConfigName,
}))}
label={
<label class="required">Sport Category</label>
}
className="field-DropDown"
onChangeFunction={handleCategoryChange}
valueData={selectedCategory}
isOnchanges={selectedCategory ? true : false}
disabled={formType === 'edit' ? true : false}
/>
{/* <Tooltip title="Add New Category">
<PlusCircleOutlined
onClick={addCategory}
className="sports-master__plus-icon"
/>
</Tooltip> */}
</div>
</Form.Item>
</div>
{selectedCategory && (
<div className="sports-master__form-field">
<Form.Item
name="Sport-subCategory"
rules={[
{
required: true,
message: 'Please select sport sub category',
},
]}
>
<DropDowns
options={ProdSubCatData.map((subCat) => ({
value: subCat.ConfigId,
label: subCat.ConfigName,
}))}
label="Sport Sub Category"
className="field-DropDown"
onChangeFunction={handleSubCategoryChange}
valueData={selectedSubCategory}
isOnchanges={selectedSubCategory ? true : false}
disabled={formType === 'edit' ? true : false}
/>
</Form.Item>
{/* <Tooltip title="Add New Sub Category">
<PlusCircleOutlined
onClick={addSubCategory}
className="sports-master__plus-icon"
/>
</Tooltip> */}
</div>
)}
</>
)}
{selectedTypeName?.toLowerCase() === 'coach' && (
<>
<div className="sports-master__form-field">
<Form.Item
name="coach"
rules={[
{ required: true, message: 'Please select coach' },
]}
>
<div style={{ display: 'flex' }}>
<DropDowns
options={EmployeesDatas?.map((coach) => ({
value: coach.UserId,
label: `${coach.EmpFirstName}`,
}))}
label="Select Coach"
className="field-DropDown"
onChangeFunction={handleCoachChange}
valueData={selectedCoach}
isOnchanges={selectedCoach ? true : false}
/>
<Tooltip title="Add New Coach">
<PlusCircleOutlined
onClick={addCoach}
className="sports-master__plus-icon"
/>
</Tooltip>
</div>
</Form.Item>
</div>
<div className="sports-master__form-field">
<Form.Item name="category">
<DropDowns
options={ProdCatData.map((cat) => ({
value: cat.ConfigId,
label: cat.ConfigName,
}))}
label="Sport Category"
className="field-DropDown"
onChangeFunction={handleCategoryChange}
valueData={selectedCategory}
isOnchanges={false}
// disabled={!!selectedCoach}
/>
</Form.Item>
</div>
{selectedCategory && (
<div className="sports-master__form-field">
<Form.Item name="subCategory">
<DropDowns
options={ProdSubCatData.map((subCat) => ({
value: subCat.ConfigId,
label: subCat.ConfigName,
}))}
label="Sport Sub Category"
className="field-DropDown"
onChangeFunction={handleSubCategoryChange}
valueData={selectedSubCategory}
isOnchanges={false}
// disabled={!!selectedCoach}
/>
</Form.Item>
</div>
)}
</>
)}
<div className="sports-master__tax-field">
<Form.Item
name="TaxId"
rules={[{ required: true, message: 'Please select Tax' }]}
>
<DropDowns
options={TaxData?.map((option) => ({
value: option.TaxId,
label: getOptionLabel(
option,
SelectedTaxId === option.TaxId
),
}))}
label="Tax"
className="field-DropDown"
isOnchanges={SelectedTaxId ? true : false}
onChangeFunction={handleTaxDropDownChange}
valueData={SelectedTaxId}
/>
</Form.Item>
</div>
<div className="sports-master__form-field">
<Form.Item
name="maxCapacity"
//label={selectedTypeName?.toLowerCase() === 'coach' ? "Maximum Trainees" : "Maximum Players"}
rules={[
{ required: true, message: 'Please enter number' },
{ pattern: /^[0-9]+$/, message: 'Only numbers allowed' },
]}
>
<InputField
autoComplete="off"
label={
<label class="required">
{selectedTypeName?.toLowerCase() === 'coach'
? 'Maximum Trainees'
: 'Maximum Players'}
</label>
}
isOnChange={form.getFieldValue('maxCapacity')}
/>
</Form.Item>
</div>
{/* {selectedType === 'coach' && selectedCoach && (
<div className="sports-master__form-field">
<div className="sports-master__coach-details">
<div>
<strong>Coach Details:</strong>
</div>
<div>
{coaches.find(c => c.CoachId === selectedCoach)?.CoachName} -
{coaches.find(c => c.CoachId === selectedCoach)?.Sport} (
{coaches.find(c => c.CoachId === selectedCoach)?.Specialization})
</div>
</div>
</div>
)} */}
{selectedTypeName && (
<div className="sports-master__image-container">
<div className="sports-master__image-upload">
<div style={{ marginBottom: '2px' }}>
<label className="sports-master__image-label">
{selectedTypeName?.toLowerCase() === 'coach'
? 'Coach Image'
: 'Facility Image'}
</label>
</div>
<div className="sports-master__image-actions">
<CropUpload
onlineImage={''}
ImageLink={imageUrl}
updateImageUrl={updateImageUrl}
/>
{/* <div>
<Button
type="default"
onClick={addimages}
style={{ width: '100%' }}
>
Browse Online Images
</Button>
</div> */}
</div>
{/* {imageUrl && (
<div style={{ marginTop: '12px' }}>
<div style={{
width: '100px',
height: '100px',
margin: '0 auto',
border: '1px solid #d9d9d9',
borderRadius: '4px',
overflow: 'hidden'
}}>
<img
src={imageUrl}
alt={selectedType === 'coach' ? 'Coach' : 'Facility'}
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
</div>
</div>
)} */}
</div>
</div>
)}
</div>
</div>
</div>
</div>
<Collapse defaultActiveKey={['1']} className="sports-master__collapse">
<Panel header="Slot Configuration" key="1">
{/* Day Selection */}
<div className="sports-master__days-section">
<Form.Item label="Available Days" required>
<div className="sports-master__days-wrapper">
<div className="sports-master__select-all">
<Checkbox
checked={selectAllDays}
onChange={(e) => handleSelectAllDays(e.target.checked)}
>
<strong>Select All Days</strong>
</Checkbox>
</div>
<div className="sports-master__days-grid">
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.monday}
onChange={() => handleDayChange('monday')}
>
Monday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.tuesday}
onChange={() => handleDayChange('tuesday')}
>
Tuesday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.wednesday}
onChange={() => handleDayChange('wednesday')}
>
Wednesday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.thursday}
onChange={() => handleDayChange('thursday')}
>
Thursday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.friday}
onChange={() => handleDayChange('friday')}
>
Friday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.saturday}
onChange={() => handleDayChange('saturday')}
>
Saturday
</Checkbox>
</div>
<div className="sports-master__day-item">
<Checkbox
checked={selectedDays.sunday}
onChange={() => handleDayChange('sunday')}
>
Sunday
</Checkbox>
</div>
</div>
{/* <div className="sports-master__selected-days">
<strong>Selected Days:</strong> {getSelectedDaysText()}
</div> */}
</div>
</Form.Item>
</div>
<div
style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}
className="slotDurationSprt"
>
<div
style={{
boxSizing: 'border-box',
// padding: '8px',
}}
>
<Form.Item label="Slot Duration (hours)">
<div className="sports-master__duration-controls">
<Button
onClick={decreaseDuration}
disabled={slotDuration <= 1}
type="primary"
className="sports-master__duration-button"
icon={<MinusOutlined />}
/>
<InputNumber
value={slotDuration}
onChange={handleDurationInput}
min={1}
max={24}
step={1}
className="sports-master__duration-input"
formatter={(value) => `${value} hrs`}
parser={(value) => value.replace(' hrs', '')}
/>
<Button
onClick={increaseDuration}
disabled={slotDuration >= 24}
type="primary"
className="sports-master__duration-button"
icon={<PlusOutlined />}
/>
</div>
</Form.Item>
</div>
<div
style={{
boxSizing: 'border-box',
// padding: '8px',
// width: '11%',
}}
>
<Form.Item
label="Start Time - End Time"
rules={[
{ required: true, message: 'Please select time range' },
]}
>
<SafeRangeTimePicker
format="HH:mm"
className="sports-master__input-number"
value={
startTime && endTime
? [moment(startTime, 'HH:mm'), moment(endTime, 'HH:mm')]
: null
}
onChange={(times, timeStrings) => {
if (times && timeStrings) {
setStartTime(timeStrings[0]);
setEndTime(timeStrings[1]);
} else {
setStartTime(null);
setEndTime(null);
}
}}
popupClassName="no-scroll-timepicker"
placeholder={['Start time', 'End time']}
/>
</Form.Item>
</div>
{/* </div> */}
{/* <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}> */}
<div
style={{
boxSizing: 'border-box',
// padding: '4px',
// width: '11%',
}}
>
<Form.Item name="defaultPrice" label="Price Per Slot">
<InputNumber
min={0}
max={99999}
className="sports-master__input-number"
formatter={(value) =>
`${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
parser={(value) => value.replace(/₹\s?|(,*)/g, '')}
onChange={setDefaultPrice}
value={defaultPrice}
/>
</Form.Item>
</div>
<div
style={{
boxSizing: 'border-box',
// padding: '4px',
// width: '14%',
}}
>
<Form.Item>
<Checkbox
checked={individualPricing}
onChange={(e) => setIndividualPricing(e.target.checked)}
>
Individual Pricing
</Checkbox>
</Form.Item>
</div>
<div
style={{
boxSizing: 'border-box',
// padding: '4px',
// width: '15%',
}}
>
<Form.Item>
<Checkbox
checked={OnlineBooking}
onChange={(e) => setOnlineBooking(e.target.checked)}
>
Online Booking
</Checkbox>
</Form.Item>
</div>
{individualPricing && (
<div
style={{
boxSizing: 'border-box',
// padding: '8px',
// width: '13%',
}}
>
<Form.Item
name="individualDefaultPrice"
label="Individual Price"
rules={[
{
required: true,
message: 'Please enter individual price',
},
]}
>
<InputNumber
className="sports-master__input-number"
max={99999}
formatter={(value) =>
`${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
parser={(value) => value.replace(/₹\s?|(,*)/g, '')}
onChange={setIndividualDefaultPrice}
value={individualDefaultPrice}
/>
</Form.Item>
</div>
)}
</div>
<div className="sports-master__config-summary">
<Space
direction="vertical"
className="sports-master__summary-content"
>
<div className="sports-master__summary-title">
<InfoCircleOutlined style={{ marginRight: '8px' }} />
Configuration Summary
</div>
<div>
{selectedTypeName && (
<>
<strong>Type:</strong>{' '}
{selectedTypeName === 'Ground' ? 'Ground' : 'Coach'} |
</>
)}
<strong> Days:</strong> {getSelectedDaysText()}
</div>
{/* <div>
<strong>Pricing Mode:</strong> {individualPricing ? 'Individual ' : 'Standard Pricing'}
</div> */}
{individualPricing && (
<div>
<strong>Default Individual Price:</strong>
{individualDefaultPrice || ' 0'}
</div>
)}
</Space>
</div>
<Button
type="primary"
onClick={generateSlots}
disabled={!startTime || !endTime}
icon={<PlusOutlined />}
size="medium"
>
Generate Slots
</Button>
</Panel>
</Collapse>
{/* Generated Slots Section */}
{generatedSlots.length > 0 && (
<Collapse
defaultActiveKey={['1']}
className="sports-master__collapse"
>
<Panel
header={
<Space>
<span>Generated Slots ({generatedSlots.length} slots)</span>
{individualPricing && (
<Tag color="blue">Dual Pricing Mode</Tag>
)}
<Tag color={totals.activeSlots > 0 ? 'green' : 'red'}>
{totals.activeSlots} Active
</Tag>
<Tag color="purple">{getSelectedDaysText()}</Tag>
</Space>
}
key="1"
>
<Table
columns={slotColumns}
dataSource={generatedSlots}
pagination={false}
rowKey="id"
// scroll={{ x: 1100 }}
size="small"
className="sports-master__collapse"
/>
<div className="sports-master__stats-container">
<div className="sports-master__stats-grid">
<div className="sports-master__stat-item">
<div className="sports-master__stat-content">
<div className="sports-master__stat-label">
Total Slots
</div>
<div className="sports-master__stat-value sports-master__stat-value--primary">
{totals.totalSlots}
</div>
</div>
</div>
<div className="sports-master__stat-item">
<div className="sports-master__stat-content">
<div className="sports-master__stat-label">
Active Slots
</div>
<div className="sports-master__stat-value sports-master__stat-value--success">
{totals.activeSlots}
</div>
</div>
</div>
<div className="sports-master__stat-item">
<div className="sports-master__stat-content">
<div className="sports-master__stat-label">
Individual Revenue
</div>
<div className="sports-master__stat-value sports-master__stat-value--warning">
{totals.totalIndividualRevenue}
</div>
</div>
</div>
{/* <div style={{ flex: '1 1 25%', minWidth: 160 }}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '12px', color: '#666' }}>Full Slot Revenue</div>
<div style={{ fontSize: '18px', fontWeight: 'bold', color: '#eb2f96' }}>
₹{totals.totalFullSlotRevenue}
</div>
</div>
</div> */}
</div>
<div className="sports-master__stats-footer">
<div className="sports-master__stats-footer-text">
Available on: <strong>{getSelectedDaysText()}</strong>
</div>
</div>
</div>
</Panel>
</Collapse>
)}
{/* Additional Information */}
{/* <Collapse className="sports-master__collapse">
<Panel header="Additional Information" key="1">
<div className="sports-master__additional-info">
<div className="sports-master__info-field">
<Form.Item name="description" label="Description">
<TextArea
rows={4}
placeholder="Enter additional description about the slots, facilities, rules, etc..."
/>
</Form.Item>
</div>
<div className="sports-master__info-field">
<Form.Item name="facilities" label="Facilities & Amenities">
<TextArea
rows={4}
placeholder="List available facilities, equipment, amenities..."
/>
</Form.Item>
</div>
</div>
<div className="sports-master__additional-info">
<div className="sports-master__info-field">
<Form.Item name="terms" label="Terms & Conditions">
<TextArea
rows={3}
placeholder="Enter booking terms and conditions..."
/>
</Form.Item>
</div>
<div className="sports-master__info-field">
<Form.Item name="cancellationPolicy" label="Cancellation Policy">
<TextArea
rows={3}
placeholder="Enter cancellation policy..."
/>
</Form.Item>
</div>
</div>
</Panel>
</Collapse> */}
{/* Submit Button */}
<Form.Item>
<Button
type="primary"
htmlType="submit"
size="large"
icon={<ArrowRightOutlined />}
disabled={generatedSlots.length === 0}
className="sports-master__submit-button"
>
Submit
</Button>
</Form.Item>
</Form>
{/* <DefaultModal
title="Browse Online Images"
width={800}
open={imageopen}
footer={true}
buttonText="Select Image"
children={
<div>
<div style={{ marginBottom: '16px' }}>
<p>Select an image for your {selectedType === 'coach' ? 'coach' : 'facility'}:</p>
</div>
<div className="sports-master__image-grid">
{imagedata?.map((item, index) => (
<div
key={index}
className={`sports-master__image-item ${selectedImage === item ? 'sports-master__image-item--selected' : 'sports-master__image-item--default'}`}
onClick={() => setSelectedImage(item)}
>
<img
src={item.image}
alt={`Sports ${selectedType === 'coach' ? 'coach' : 'facility'} ${index + 1}`}
className="sports-master__image-preview"
/>
</div>
))}
</div>
</div>
}
handleSubmit={submitimage}
handleCancel={handleimage}
/> */}
{/* <Modal
title="Add New Category"
open={openCategoryModal}
onOk={submitCategory}
onCancel={handleCategoryModalClose}
okText="Submit"
cancelText="Cancel"
>
<Form layout="vertical">
<Form.Item
label="Category Name"
name="categoryName"
rules={[{ required: true, message: 'Please enter category name' }]}
>
<Input placeholder="Enter category name" />
</Form.Item>
<Form.Item
label="Description"
name="categoryDescription"
>
<TextArea rows={3} placeholder="Enter category description" />
</Form.Item>
</Form>
</Modal> */}
{/* <Modal
title="Add New Sub Category"
open={openSubCategoryModal}
onOk={submitSubCategory}
onCancel={handleSubCategoryModalClose}
okText="Submit"
cancelText="Cancel"
>
<Form layout="vertical">
<Form.Item
label="Category"
name="parentCategory"
>
<DropDowns
options={sportCategories.map(cat => ({ value: cat.ConfigId, label: cat.ConfigName }))}
label="Category"
className="field-DropDown"
valueData={selectedCategory}
isOnchanges={false}
disabled
/>
</Form.Item>
<Form.Item
label="Sub Category Name"
name="subCategoryName"
rules={[{ required: true, message: 'Please enter sub category name' }]}
>
<Input placeholder="Enter sub category name" />
</Form.Item>
<Form.Item
label="Description"
name="subCategoryDescription"
>
<TextArea rows={3} placeholder="Enter sub category description" />
</Form.Item>
</Form>
</Modal> */}
{/* <DefaultModal
title="Add New Coach"
open={openCoachModal}
handleSubmit={submitCoach}
handleCancel={handleCoachModalClose}
footer={true}
width={800}
>
<Form layout="vertical" className='addnewcoatcgForm'>
<Form.Item
name="coachSport"
rules={[{ required: true, message: 'Please select sport' }]}
>
<DropDowns
options={userDropDown?.map((option) => ({
value: option.UserId,
label:
option.UserName != ''
? option.UserName
: option.MobileNo,
}))}
label={<label class="required">User Name</label>}
id="UserId"
field="UserId"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => UserDropDownChange(e)}
isOnchanges={formType == 'edit' ? true : false}
valueData={selectedUserData}
disabled={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="EmpType"
rules={[
{
required: true,
message: 'Please Select Employee Type',
},
]}
>
<DropDowns
options={EmpTypeDropDownData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Employee Type</label>}
id="EmpType"
field="EmpType"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => EmpTypeDropDownChange(e)}
isOnchanges={formType == 'edit' ? true : false}
valueData={seletedEmpTypeDrop}
/>
</Form.Item>
<Form.Item
name="EmpDesig"
rules={[
{
required: true,
message: 'Please Select Designation',
},
]}
>
<DropDowns
options={EmpDesgDropDownData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Designation</label>}
id="EmpDesig"
field="EmpDesig"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => EmpDesigDropDownChange(e)}
isOnchanges={formType == 'edit' ? true : false}
valueData={seletedEmpDesigDrop}
/>
</Form.Item>
<Form.Item
name="EmpDept"
rules={[
{
required: true,
message: 'Please Select Department',
},
]}
>
<DropDowns
options={activeDeptTypes?.map((option) => ({
value: option.PreferredSubCatId,
label: option.PreferredSubCatName,
}))}
label={<label class="required">Department</label>}
id="EmpDept"
field="EmpDept"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => EmpDeptDropDownChange(e)}
isOnchanges={formType == 'edit' ? true : false}
valueData={seletedEmpDeptDrop}
/>
</Form.Item>
<Form.Item
name="EmpShiftId"
rules={[
{
required: true,
message: 'Please Select Shift Name',
},
]}
>
<DropDowns
options={ShiftDownData?.map((option) => ({
value: option.ShiftId,
label: option.ShiftName,
}))}
label={<label class="required">Shift Name</label>}
id="ShiftId"
field="ShiftId"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => ShiftDropDownChange(e)}
isOnchanges={formType == 'edit' ? true : false}
valueData={seletedShiftDrop}
/>
</Form.Item>
<Form.Item
name="EmpDOJ"
// hasFeedback
rules={[
{
required: true,
message: 'Please Select Date of Join',
},
]}
>
<DatePic
canSelectPast={true}
onChange={onChange}
valueData={SelectedDate}
label={<label class="required">Date of Join</label>}
isOnChange={true}
/>
</Form.Item>
<Form.Item
name="MobileNo"
rules={[
{
required: true,
pattern: /^\d{10}$/,
message: 'Please Enter a Valid Mobile Number',
},
]}
>
<InputField
field="MobileNo"
label={<label class="required">Mobile Number</label>}
fieldState={true}
maxLength="10"
fieldApi={true}
autocomplete="off"
isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
label="Experience (Years)"
name="coachExperience"
>
<InputNumber
min={0}
max={50}
style={{ width: '100%' }}
placeholder="Enter years of experience"
/>
</Form.Item>
<Form.Item
label="Qualifications"
name="coachQualifications"
>
<TextArea rows={3} placeholder="Enter coach qualifications" />
</Form.Item>
<div className="sports-master__image-actions">
{Array.from({ length: Math.max(1, imageUrls.length) }).map((_, idx) => (
<div key={idx} style={{ marginBottom: 12 }}>
<CropUpload
onlineImage={onlineImage}
ImageLink={imageUrls[idx]?.image}
updateImageUrl={(url) => updateImageUrls(url, idx)}
/>
<Input
placeholder={`Image name (optional)`}
value={imageUrls[idx]?.name || ''}
onChange={(e) => updateImageName(e.target.value, idx)}
style={{ marginTop: 8 }}
/>
<div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
<Button size="small" onClick={() => setImageUrls(prev => {
const copy = Array.isArray(prev) ? [...prev] : [];
copy.splice(idx + 1, 0, { image: '', name: '' });
return copy;
})}>Add</Button>
<Button size="small" danger onClick={() => setImageUrls(prev => (prev || []).filter((__, i) => i !== idx))}>Remove</Button>
</div>
</div>
))}
</div>
</Form>
</DefaultModal> */}
</div>
);
};
export default SportSlotCreation;