2025-11-06 23:52:53 +05:30
|
|
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
|
|
|
import { useDispatch, useSelector } from 'react-redux'
|
|
|
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
|
|
|
import { Form, Tooltip, Switch } from "antd";
|
|
|
|
|
import { ArrowRightOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
|
|
|
|
import { InputField } from "../../Components/Forms/InputField.jsx";
|
|
|
|
|
import { TextAreaInput } from "../../Components/Forms/TextArea.jsx";
|
|
|
|
|
import Buttons from "../../Components/Forms/Buttons.jsx";
|
|
|
|
|
import { Messages } from "../../Components/Notifications/Messages";
|
|
|
|
|
import Imageupload from "../../Components/Forms/Upload.jsx";
|
|
|
|
|
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
|
|
|
|
|
import FormHeader from '../pageComponents/FormHeader.jsx';
|
|
|
|
|
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
|
|
|
|
|
import { changeBreadCrumb } from '../../features/appPage/centerPage.js';
|
|
|
|
|
import { onlineimages, uploadImage } from '../../features/applications/bannerImage.js'
|
|
|
|
|
import {
|
|
|
|
|
getCategoryData,
|
|
|
|
|
getSubCategoryData,
|
|
|
|
|
categoryActiveDataSelector,
|
|
|
|
|
subCategoryActiveDataSelector,
|
|
|
|
|
postApplicationData,
|
|
|
|
|
putApplicationData
|
|
|
|
|
} from "../../features/applicationPage/applicationPage.js";
|
|
|
|
|
import { getSession, validateSafeInput } from "../../Services/others";
|
|
|
|
|
|
|
|
|
|
const subDirectory = import.meta.env.ENV_BASE_URL
|
|
|
|
|
const homepageurl = import.meta.env.ENV_MAIN_REDIRECT_URL;
|
|
|
|
|
|
|
|
|
|
const ApplicationForm = ({ formType }) => {
|
|
|
|
|
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const location = useLocation();
|
|
|
|
|
const formRef = useRef(null);
|
|
|
|
|
const state = location?.state
|
|
|
|
|
const editstate = state?.editstate
|
|
|
|
|
const categoryData = useSelector(categoryActiveDataSelector)
|
|
|
|
|
const subCategoryData = useSelector(subCategoryActiveDataSelector)
|
|
|
|
|
const [messageType, setMessageType] = useState(null);
|
|
|
|
|
const [messageData, setMessageData] = useState(null);
|
|
|
|
|
const [SelectedCategory, setSelectedCategory] = useState(null);
|
|
|
|
|
const [SelectedSubCategory, setSelectedSubCategory] = useState(null);
|
|
|
|
|
const [imageUrl, setImageUrl] = useState('');
|
|
|
|
|
const [onlineLogo, setOnlineLogo] = useState(false);
|
|
|
|
|
const [imagedata, setimagedata] = useState();
|
|
|
|
|
const [selectedImage, setSelectedImage] = useState();
|
|
|
|
|
const [onlinelogoImage, setOnlinelogoImage] = useState();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const items = [
|
|
|
|
|
{
|
|
|
|
|
name: "Home",
|
|
|
|
|
link: `${subDirectory}landing-page/home`,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
name: "Application",
|
|
|
|
|
link: `${subDirectory}setting/application-master/`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: editstate ? "Edit" : "New",
|
|
|
|
|
link: null
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
dispatch(changeBreadCrumb({ items: items }));
|
|
|
|
|
dispatch(getCategoryData()).unwrap()
|
|
|
|
|
dispatch(getSubCategoryData()).unwrap()
|
|
|
|
|
OnlineImageCall();
|
|
|
|
|
if (editstate) {
|
|
|
|
|
setImageUrl(editstate?.AppLogo)
|
|
|
|
|
formRef.current?.setFieldsValue({ CateId: editstate.CateId, SubCateId: editstate.SubCateId })
|
|
|
|
|
setSelectedCategory(editstate.CateId)
|
|
|
|
|
setSelectedSubCategory(editstate.SubCateId)
|
|
|
|
|
}
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
}, []);
|
|
|
|
|
const OnlineImageCall = async () => {
|
|
|
|
|
let Appname = formRef?.current?.getFieldsValue().AppName;
|
|
|
|
|
if (Appname !== null && Appname !== undefined) {
|
|
|
|
|
let response = await dispatch(onlineimages(formRef?.current?.getFieldsValue().AppName)).unwrap();
|
|
|
|
|
setimagedata(response?.data?.data);
|
|
|
|
|
}
|
2025-11-05 17:52:07 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const onFinish = async (values) => {
|
|
|
|
|
let postData = {};
|
|
|
|
|
postData["AppDescription"] = values.AppDescription;
|
|
|
|
|
postData["AppId"] = values.AppId;
|
|
|
|
|
postData["AppURLType"] = SelectedCategory == categoryData?.filter(item => item?.ConfigName == "Retail")[0]?.ConfigId ? 'I' : 'E';;
|
|
|
|
|
postData["AppLogo"] = imageUrl;
|
|
|
|
|
postData["AppName"] = values.AppName;
|
|
|
|
|
postData["AppURL"] = SelectedCategory == categoryData?.filter(item => item?.ConfigName == "Retail")[0]?.ConfigId ? URLToggle ? homepageurl : values.AppURL : values.AppURL;
|
|
|
|
|
postData["CateId"] = values.CateId;
|
|
|
|
|
postData["CreatedBy"] = getSession('UserId')
|
|
|
|
|
postData["SubCateId"] = values.SubCateId;
|
|
|
|
|
postData["UpdatedBy"] = values.UpdatedBy;
|
|
|
|
|
let response = {}
|
|
|
|
|
if (formType === "add") {
|
|
|
|
|
try {
|
|
|
|
|
response = await dispatch(postApplicationData(postData)).unwrap()
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
console.log(err, "err");
|
|
|
|
|
if (err["message"] == "Request failed with status code 422") {
|
|
|
|
|
response = {
|
|
|
|
|
data: {
|
|
|
|
|
"statusCode": 0,
|
|
|
|
|
"response": "Please Give Required Fields",
|
|
|
|
|
'data': []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
}
|
|
|
|
|
else if (formType === "edit") {
|
|
|
|
|
|
|
|
|
|
postData["AppId"] = editstate?.AppId
|
|
|
|
|
postData["UpdatedBy"] = getSession('UserId')
|
|
|
|
|
try {
|
|
|
|
|
response = await dispatch(putApplicationData(postData)).unwrap()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.log(err, "err");
|
|
|
|
|
if (err["message"] == "Request failed with status code 422") {
|
|
|
|
|
response = {
|
|
|
|
|
data: {
|
|
|
|
|
"statusCode": 0,
|
|
|
|
|
"response": "Please Give Required Fields",
|
|
|
|
|
'data': []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (response?.data?.statusCode == 1) {
|
|
|
|
|
navigate(`${subDirectory}setting/application-master/`, {
|
|
|
|
|
state: {
|
|
|
|
|
Notiffy: {
|
|
|
|
|
messageType: "success",
|
|
|
|
|
messageData: response?.data?.response,
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
setMessageType("error")
|
|
|
|
|
setMessageData(response?.data?.response)
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-05 17:52:07 +05:30
|
|
|
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const onComplete = useCallback(() => {
|
|
|
|
|
setMessageData(null);
|
|
|
|
|
setMessageType(null);
|
2025-11-05 17:52:07 +05:30
|
|
|
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
}, [])
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const selectCategory = async (e) => {
|
|
|
|
|
formRef.current?.setFieldsValue({ CateId: e })
|
|
|
|
|
await setSelectedCategory(e)
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
}
|
|
|
|
|
const selectSubCategory = async (e) => {
|
|
|
|
|
formRef.current?.setFieldsValue({ SubCateId: e })
|
|
|
|
|
await setSelectedSubCategory(e)
|
|
|
|
|
}
|
2025-11-05 17:52:07 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const addLogo = () => {
|
|
|
|
|
let Appname = formRef?.current?.getFieldsValue().AppName
|
|
|
|
|
if (Appname !== null && Appname !== undefined) {
|
|
|
|
|
OnlineImageCall()
|
|
|
|
|
setOnlineLogo(true)
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
setMessageType("error")
|
|
|
|
|
setMessageData("Eneter Application Name")
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-05 17:52:07 +05:30
|
|
|
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const Logosubmit = async () => {
|
|
|
|
|
let response = await fetch(selectedImage.image);
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
let data = await response.blob();
|
|
|
|
|
let metadata = {
|
|
|
|
|
type: "image/jpeg",
|
|
|
|
|
};
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
let file = new File([data], "image.jpg", metadata);
|
|
|
|
|
let uploadImgData = await dispatch(uploadImage(file)).unwrap()
|
|
|
|
|
if (uploadImgData?.data?.status) {
|
|
|
|
|
setOnlinelogoImage(uploadImgData?.data?.image)
|
|
|
|
|
setImageUrl(uploadImgData?.data?.image)
|
2025-11-05 17:52:07 +05:30
|
|
|
}
|
2025-11-06 23:52:53 +05:30
|
|
|
setOnlineLogo(false);
|
2025-11-05 17:52:07 +05:30
|
|
|
}
|
|
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
const [URLToggle, setURLTogglel] = useState(false);
|
|
|
|
|
const onChange = (checked) => {
|
|
|
|
|
console.log(`switch to ${checked}`);
|
|
|
|
|
setURLTogglel(checked);
|
|
|
|
|
};
|
2025-11-05 17:52:07 +05:30
|
|
|
|
2025-11-06 23:52:53 +05:30
|
|
|
formType == "edit" && editstate?.AppUrlType !== 'I' ? formRef?.current?.setFieldsValue({ AppURL: editstate?.AppUrl }) : '';
|
2025-11-05 17:52:07 +05:30
|
|
|
return (
|
2025-11-06 23:52:53 +05:30
|
|
|
<div className='pageOverAll'>
|
|
|
|
|
<div className='userPage'>
|
|
|
|
|
<div className='userPageContent'>
|
|
|
|
|
<Messages messageType={messageType} messageData={messageData} onComplete={onComplete} />
|
|
|
|
|
<div className="formName">
|
|
|
|
|
<FormHeader title={'Application'} />
|
|
|
|
|
</div>
|
|
|
|
|
<div className='formDiv'>
|
|
|
|
|
<Form ref={formRef} className="formDivAnt" onFinish={onFinish} initialValues={editstate}>
|
|
|
|
|
<div className='formDivS'>
|
|
|
|
|
<div className='inputForm'>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="AppName"
|
|
|
|
|
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
pattern: /^(?!\s*$).+/,
|
|
|
|
|
message: "Please Enter Application Name",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
validator: async (_, value) => {
|
|
|
|
|
await validateSafeInput(value);
|
|
|
|
|
|
|
|
|
|
if (value && !/^.{1,50}$/.test(value)) {
|
|
|
|
|
return Promise.reject("Application Name must be 1 to 50 characters.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Promise.resolve();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
<InputField
|
|
|
|
|
field="AppName"
|
|
|
|
|
autoComplete="off"
|
|
|
|
|
label={<label className="required">Application Name </label>}
|
|
|
|
|
fieldState={true}
|
|
|
|
|
fieldApi={true}
|
|
|
|
|
isOnChange={formType == "edit" ? true : false}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="CateId"
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: "Please Select Module",
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<DropDowns
|
|
|
|
|
options={categoryData?.map((option) => ({
|
|
|
|
|
value: option.ConfigId,
|
|
|
|
|
label: option.ConfigName,
|
|
|
|
|
}))}
|
|
|
|
|
label={<label className="required">Module</label>}
|
|
|
|
|
onChangeFunction={selectCategory}
|
|
|
|
|
optionsNames={{ value: "ConfigId", label: "ConfigName" }}
|
|
|
|
|
className='field-DropDown'
|
|
|
|
|
isOnchanges={(formType == "edit" || SelectedCategory) ? true : false}
|
|
|
|
|
valueData={SelectedCategory}
|
|
|
|
|
disabled={formType == "edit" ? true : false}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="SubCateId"
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: "Please Select Sub Module ",
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<DropDowns
|
|
|
|
|
options={subCategoryData?.map((option) => ({
|
|
|
|
|
value: option.ConfigId,
|
|
|
|
|
label: option.ConfigName,
|
|
|
|
|
}))}
|
|
|
|
|
label={<label className="required">Sub Module</label>}
|
|
|
|
|
onChangeFunction={selectSubCategory}
|
|
|
|
|
optionsNames={{ value: "ConfigId", label: "ConfigName" }}
|
|
|
|
|
className='field-DropDown'
|
|
|
|
|
isOnchanges={(formType == "edit" || SelectedSubCategory) ? true : false}
|
|
|
|
|
valueData={SelectedSubCategory}
|
|
|
|
|
disabled={formType == "edit" ? true : false}
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="AppDescription"
|
|
|
|
|
|
|
|
|
|
rules={[
|
|
|
|
|
{
|
|
|
|
|
pattern: /^(?!\s*$).+/,
|
|
|
|
|
message: "Please Enter Application Description",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
validator: async (_, value) => {
|
|
|
|
|
await validateSafeInput(value);
|
|
|
|
|
return Promise.resolve();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]}>
|
|
|
|
|
<TextAreaInput
|
|
|
|
|
field="AppDescription"
|
|
|
|
|
autoComplete="off"
|
|
|
|
|
label="Description"
|
|
|
|
|
fieldState={true}
|
|
|
|
|
fieldApi={true}
|
|
|
|
|
isOnChange={formType == "edit" ? true : false}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="upload_btn">
|
|
|
|
|
<p>Upload Logo</p>
|
|
|
|
|
<Imageupload
|
|
|
|
|
singleImage={true}
|
|
|
|
|
updateImageUrl={setImageUrl}
|
|
|
|
|
ImageLink={onlinelogoImage ? onlinelogoImage : editstate?.AppLogo ? editstate?.AppLogo : ""}
|
|
|
|
|
/>
|
|
|
|
|
<button type="button"
|
|
|
|
|
style={{
|
|
|
|
|
width: '6.5rem',
|
|
|
|
|
backgroundColor: '#dbd1d1',
|
|
|
|
|
color: '#000000',
|
|
|
|
|
border: '0.5px solid gray',
|
|
|
|
|
borderRadius: '3px',
|
|
|
|
|
padding: '3px'
|
|
|
|
|
}}
|
|
|
|
|
onClick={addLogo}
|
|
|
|
|
>Browse Image</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
SelectedCategory == null ? '' :
|
|
|
|
|
SelectedCategory == categoryData?.filter(item => item?.ConfigName == "Retail")?.[0]?.ConfigId ?
|
|
|
|
|
<>
|
|
|
|
|
<div>Retail URL : <Switch onChange={onChange} /> </div>
|
|
|
|
|
{URLToggle ?
|
|
|
|
|
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
|
|
|
|
<p>URL:</p>
|
|
|
|
|
<p style={{ color: '#1292EE' }}>https://pozo.app{homepageurl}</p>
|
|
|
|
|
</div> :
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="AppURL"
|
|
|
|
|
rules={[
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
validator: async (_, value) => {
|
|
|
|
|
await validateSafeInput(value); // To block HTML tags & SQL keywords
|
|
|
|
|
return Promise.resolve();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<InputField
|
|
|
|
|
field="BrMobile"
|
|
|
|
|
label="App URL"
|
|
|
|
|
fieldState={true}
|
|
|
|
|
fieldApi={true}
|
|
|
|
|
autoComplete={"nope"}
|
|
|
|
|
isOnChange={formType == "edit" && editstate?.AppUrl?.length > 0 ? true : false}
|
|
|
|
|
suffix={<Tooltip title={`/apps/yourApplication`}>
|
|
|
|
|
<InfoCircleOutlined
|
|
|
|
|
style={{
|
|
|
|
|
color: 'rgba(0,0,0,.45)',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>}
|
|
|
|
|
</>
|
|
|
|
|
:
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="AppURL"
|
|
|
|
|
rules={[
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
validator: async (_, value) => {
|
|
|
|
|
await validateSafeInput(value); // To block HTML tags & SQL keywords
|
|
|
|
|
return Promise.resolve();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
className='appUrlInput'
|
|
|
|
|
>
|
|
|
|
|
<InputField
|
|
|
|
|
field="BrMobile"
|
|
|
|
|
label="App URL"
|
|
|
|
|
fieldState={true}
|
|
|
|
|
fieldApi={true}
|
|
|
|
|
autoComplete={"nope"}
|
|
|
|
|
isOnChange={formType == "edit" && editstate?.AppUrl?.length > 0 ? true : false}
|
|
|
|
|
suffix={<Tooltip title={`/apps/yourApplication`}>
|
|
|
|
|
<InfoCircleOutlined
|
|
|
|
|
style={{
|
|
|
|
|
color: 'rgba(0,0,0,.45)',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='submitButton'>
|
|
|
|
|
<Buttons
|
|
|
|
|
buttonText="SUBMIT"
|
|
|
|
|
color="901D77"
|
|
|
|
|
icon={<ArrowRightOutlined />}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</Form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-11-05 17:52:07 +05:30
|
|
|
</div>
|
2025-11-06 23:52:53 +05:30
|
|
|
<DefaultModal
|
|
|
|
|
title="ONLINE LOGO IMAGE UPLOADER"
|
|
|
|
|
width={800}
|
|
|
|
|
open={onlineLogo}
|
|
|
|
|
footer={true}
|
|
|
|
|
buttonText="Submit"
|
|
|
|
|
children={
|
|
|
|
|
<Form className="">
|
|
|
|
|
<div className="productonlineImg">
|
|
|
|
|
{imagedata?.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
className={`singleimg ${selectedImage === item ? "selected" : ""
|
|
|
|
|
}`}
|
|
|
|
|
key={index}
|
|
|
|
|
onClick={() => setSelectedImage(item)}
|
|
|
|
|
>
|
|
|
|
|
<img src={item.image} alt="no image" width={120} height={100} />
|
|
|
|
|
</div>
|
2025-11-05 17:52:07 +05:30
|
|
|
))}
|
|
|
|
|
</div>
|
2025-11-06 23:52:53 +05:30
|
|
|
</Form>
|
|
|
|
|
}
|
|
|
|
|
handleSubmit={Logosubmit}
|
|
|
|
|
handleCancel={() => { setOnlineLogo(false) }}
|
|
|
|
|
></DefaultModal>
|
2025-11-05 17:52:07 +05:30
|
|
|
</div>
|
2025-11-06 23:52:53 +05:30
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default ApplicationForm;
|