520 lines
22 KiB
React
520 lines
22 KiB
React
|
|
import React, { useState, useEffect, useCallback } from "react";
|
|||
|
|
import { message } from "antd";
|
|||
|
|
import { DefaultModal } from "../../Components/Modal/DefaultModal";
|
|||
|
|
import "../Styles/FooterForm.scss";
|
|||
|
|
import { getSession } from "../../Services/others.js";
|
|||
|
|
import { getAdminPanel, postAdminPanel, putAdminPanel, deleteAdminPanel } from '../../features/AdminPanel/AdminPanel.js';
|
|||
|
|
import { useDispatch } from 'react-redux';
|
|||
|
|
import { Messages } from '../../Components/Notifications/Messages.jsx';
|
|||
|
|
import { uploadImage } from "../../features/applications/bannerImage.js";
|
|||
|
|
|
|||
|
|
const FooterForm = ({ sectionKey = null }) => {
|
|||
|
|
const dispatch = useDispatch();
|
|||
|
|
const [footerData, setFooterData] = useState([]);
|
|||
|
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|||
|
|
const [title, setTitle] = useState("");
|
|||
|
|
const [description, setDescription] = useState("");
|
|||
|
|
const [emailFields, setEmailFields] = useState([{ value: '', uniqueId: null }]);
|
|||
|
|
const [phoneFields, setPhoneFields] = useState([{ value: '', uniqueId: null }]);
|
|||
|
|
const [socialLink, setSocialLink] = useState("");
|
|||
|
|
const [editingIndex, setEditingIndex] = useState(-1);
|
|||
|
|
const [editData, setEditData] = useState(null);
|
|||
|
|
const [titleError, setTitleError] = useState("");
|
|||
|
|
const [descriptionError, setDescriptionError] = useState("");
|
|||
|
|
const [messageData, setMessageData] = useState(null);
|
|||
|
|
const [messageType, setMessageType] = useState(null);
|
|||
|
|
const UserId = getSession('UserId') || 1;
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
const getFooterData = async () => {
|
|||
|
|
const res = await dispatch(getAdminPanel({ sectionName: sectionKey }))?.unwrap();
|
|||
|
|
if (res?.data?.statusCode === 1) {
|
|||
|
|
setFooterData(res?.data?.data);
|
|||
|
|
} else {
|
|||
|
|
setFooterData([]);
|
|||
|
|
setMessageData(res?.data?.response);
|
|||
|
|
setMessageType("error");
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (sectionKey) {
|
|||
|
|
getFooterData();
|
|||
|
|
}
|
|||
|
|
}, [sectionKey, dispatch]);
|
|||
|
|
|
|||
|
|
const openModal = () => {
|
|||
|
|
setIsModalOpen(true);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const closeModal = () => {
|
|||
|
|
setIsModalOpen(false);
|
|||
|
|
setTitle("");
|
|||
|
|
setDescription("");
|
|||
|
|
setEmailFields([{ value: '', uniqueId: null }]);
|
|||
|
|
setPhoneFields([{ value: '', uniqueId: null }]);
|
|||
|
|
setSocialLink("");
|
|||
|
|
setEditingIndex(-1);
|
|||
|
|
setEditData(null);
|
|||
|
|
setTitleError("");
|
|||
|
|
setDescriptionError("");
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleClear = () => {
|
|||
|
|
setTitle("");
|
|||
|
|
setDescription("");
|
|||
|
|
setEmailFields([{ value: '', uniqueId: null }]);
|
|||
|
|
setPhoneFields([{ value: '', uniqueId: null }]);
|
|||
|
|
setSocialLink("");
|
|||
|
|
setTitleError("");
|
|||
|
|
setDescriptionError("");
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const addEmailField = () => {
|
|||
|
|
setEmailFields([...emailFields, { value: '', uniqueId: null }]);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const removeEmailField = (index) => {
|
|||
|
|
if (emailFields.length <= 1) return; // Don't remove if only one field
|
|||
|
|
const updated = emailFields.filter((_, i) => i !== index);
|
|||
|
|
setEmailFields(updated);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const updateEmailField = (index, value) => {
|
|||
|
|
const updated = emailFields.map((email, i) => i === index ? { ...email, value } : email);
|
|||
|
|
setEmailFields(updated);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const addPhoneField = () => {
|
|||
|
|
setPhoneFields([...phoneFields, { value: '', uniqueId: null }]);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const removePhoneField = (index) => {
|
|||
|
|
if (phoneFields.length <= 1) return; // Don't remove if only one field
|
|||
|
|
const updated = phoneFields.filter((_, i) => i !== index);
|
|||
|
|
setPhoneFields(updated);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const updatePhoneField = (index, value) => {
|
|||
|
|
const updated = phoneFields.map((phone, i) => i === index ? { ...phone, value } : phone);
|
|||
|
|
setPhoneFields(updated);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
const handleSave = async () => {
|
|||
|
|
let hasError = false;
|
|||
|
|
|
|||
|
|
if (!title.trim()) {
|
|||
|
|
setTitleError("Title is required");
|
|||
|
|
hasError = true;
|
|||
|
|
} else setTitleError("");
|
|||
|
|
|
|||
|
|
if (!description.trim()) {
|
|||
|
|
setDescriptionError("Description is required");
|
|||
|
|
hasError = true;
|
|||
|
|
} else setDescriptionError("");
|
|||
|
|
|
|||
|
|
if (hasError) {
|
|||
|
|
message.error("Please fix the highlighted fields");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Build clean HomePageDetails array - only current form data
|
|||
|
|
const homePageDetails = [];
|
|||
|
|
|
|||
|
|
// Add emails (only non-empty)
|
|||
|
|
emailFields.forEach(email => {
|
|||
|
|
if (email.value && email.value.trim()) {
|
|||
|
|
homePageDetails.push({
|
|||
|
|
DtlName: 'Email',
|
|||
|
|
DtlDesc: email.value.trim(),
|
|||
|
|
DtlHdr: '',
|
|||
|
|
DtlImgUrl: '',
|
|||
|
|
RStatus: 'A',
|
|||
|
|
CreatedBy: UserId,
|
|||
|
|
...(email.uniqueId && { UniqueId: email.uniqueId })
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Add phones (only non-empty)
|
|||
|
|
phoneFields.forEach(phone => {
|
|||
|
|
if (phone.value && phone.value.trim()) {
|
|||
|
|
homePageDetails.push({
|
|||
|
|
DtlName: 'Phone',
|
|||
|
|
DtlHdr: phone.value.trim(),
|
|||
|
|
DtlDesc: '',
|
|||
|
|
DtlImgUrl: '',
|
|||
|
|
RStatus: 'A',
|
|||
|
|
CreatedBy: UserId,
|
|||
|
|
...(phone.uniqueId && { UniqueId: phone.uniqueId })
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Check if data exists or if we're editing
|
|||
|
|
const hasExistingData = footerData.length > 0;
|
|||
|
|
const isEditing = editingIndex > -1 && editData;
|
|||
|
|
const shouldUpdate = isEditing || hasExistingData;
|
|||
|
|
|
|||
|
|
const data = {
|
|||
|
|
SectionName: sectionKey,
|
|||
|
|
SectionHdr: title.trim(),
|
|||
|
|
SectionDesc: description.trim(),
|
|||
|
|
SectionImgUrl: '',
|
|||
|
|
HomePageDetails: homePageDetails,
|
|||
|
|
CreatedBy: UserId,
|
|||
|
|
RStatus: 'A',
|
|||
|
|
...(shouldUpdate
|
|||
|
|
? { SectionId: editData?.SectionId || footerData[0]?.SectionId }
|
|||
|
|
: {}),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
console.log("API Request Data:", data);
|
|||
|
|
console.log("Has Existing Data:", hasExistingData);
|
|||
|
|
console.log("Is Editing:", isEditing);
|
|||
|
|
console.log("Should Update:", shouldUpdate);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const apiAction = shouldUpdate ? putAdminPanel : postAdminPanel;
|
|||
|
|
console.log("API Action:", shouldUpdate ? "PUT" : "POST");
|
|||
|
|
|
|||
|
|
const res = await dispatch(apiAction(data))?.unwrap();
|
|||
|
|
console.log(`${shouldUpdate ? "Put" : "Post"} response:`, res);
|
|||
|
|
|
|||
|
|
const success = res?.data?.statusCode === 1;
|
|||
|
|
const messageText = shouldUpdate
|
|||
|
|
? "Footer Updated Successfully"
|
|||
|
|
: "Footer Added Successfully";
|
|||
|
|
|
|||
|
|
if (success) {
|
|||
|
|
setMessageData(messageText);
|
|||
|
|
setMessageType("success");
|
|||
|
|
|
|||
|
|
// Refresh data
|
|||
|
|
const refreshRes = await dispatch(
|
|||
|
|
getAdminPanel({ sectionName: sectionKey })
|
|||
|
|
)?.unwrap();
|
|||
|
|
if (refreshRes?.data?.statusCode === 1) {
|
|||
|
|
setFooterData(refreshRes.data.data);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
const errorMessage =
|
|||
|
|
res?.response ||
|
|||
|
|
res?.data?.response ||
|
|||
|
|
res?.message ||
|
|||
|
|
"Error saving footer";
|
|||
|
|
console.log("API Error Response:", errorMessage);
|
|||
|
|
setMessageData(errorMessage);
|
|||
|
|
setMessageType("error");
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error("API Error Details:", {
|
|||
|
|
message: error?.message,
|
|||
|
|
response: error?.response,
|
|||
|
|
status: error?.response?.status,
|
|||
|
|
data: error?.response?.data,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
let errorMessage = "Network error occurred";
|
|||
|
|
if (error?.response?.data?.message) {
|
|||
|
|
errorMessage = error.response.data.message;
|
|||
|
|
} else if (error?.response?.data?.response) {
|
|||
|
|
errorMessage = error.response.data.response;
|
|||
|
|
} else if (error?.message) {
|
|||
|
|
errorMessage = error.message;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setMessageData(errorMessage);
|
|||
|
|
setMessageType("error");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
closeModal();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleEdit = (footer, index) => {
|
|||
|
|
setTitle(footer.SectionHdr || "");
|
|||
|
|
setDescription(footer.SectionDesc || "");
|
|||
|
|
|
|||
|
|
if (footer.HomePageDetails && footer.HomePageDetails.length > 0) {
|
|||
|
|
const emails = footer.HomePageDetails.filter(d => d.DtlName === 'Email').map(d => ({
|
|||
|
|
value: d.DtlDesc || '',
|
|||
|
|
uniqueId: d.UniqueId || null
|
|||
|
|
}));
|
|||
|
|
const phones = footer.HomePageDetails.filter(d => d.DtlName === 'Phone').map(d => ({
|
|||
|
|
value: d.DtlHdr || '',
|
|||
|
|
uniqueId: d.UniqueId || null
|
|||
|
|
}));
|
|||
|
|
setEmailFields(emails.length > 0 ? emails : [{ value: '', uniqueId: null }]);
|
|||
|
|
setPhoneFields(phones.length > 0 ? phones : [{ value: '', uniqueId: null }]);
|
|||
|
|
} else {
|
|||
|
|
setEmailFields([{ value: '', uniqueId: null }]);
|
|||
|
|
setPhoneFields([{ value: '', uniqueId: null }]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setEditingIndex(index);
|
|||
|
|
setEditData(footer);
|
|||
|
|
openModal();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleToggleActive = async (index) => {
|
|||
|
|
const footer = footerData[index];
|
|||
|
|
const newStatus = footer.RStatus === 'A' ? 'D' : 'A';
|
|||
|
|
|
|||
|
|
const deleteData = {
|
|||
|
|
sectionId: footer.SectionId,
|
|||
|
|
activeStatus: newStatus,
|
|||
|
|
updatedBy: UserId
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const res = await dispatch(deleteAdminPanel(deleteData))?.unwrap();
|
|||
|
|
|
|||
|
|
if (res?.data?.statusCode === 1) {
|
|||
|
|
setMessageData(`Footer ${newStatus === 'A' ? 'activated' : 'deactivated'} successfully`);
|
|||
|
|
setMessageType('success');
|
|||
|
|
|
|||
|
|
const refreshRes = await dispatch(getAdminPanel({ sectionName: sectionKey }))?.unwrap();
|
|||
|
|
if (refreshRes?.data?.statusCode === 1) {
|
|||
|
|
setFooterData(refreshRes.data.data);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
setMessageData('Error updating status');
|
|||
|
|
setMessageType('error');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
setMessageData('Network error occurred');
|
|||
|
|
setMessageType('error');
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const onComplete = useCallback(() => {
|
|||
|
|
setMessageData(null);
|
|||
|
|
setMessageType(null);
|
|||
|
|
}, []);
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="footer-form-master">
|
|||
|
|
<Messages
|
|||
|
|
messageType={messageType}
|
|||
|
|
messageData={messageData}
|
|||
|
|
onComplete={onComplete}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
{/* Header Section */}
|
|||
|
|
<div className="footer-form-header">
|
|||
|
|
<div className="footer-form-header-left">
|
|||
|
|
<div className="footer-form-header-content">
|
|||
|
|
<h2>Footer Management</h2>
|
|||
|
|
<p>Manage and organize your footer content and settings.</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<button onClick={openModal} className="footer-form-create-btn">
|
|||
|
|
<span>+</span> {footerData.length > 0 ? 'Edit Footer' : 'Create Footer'}
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Tab Navigation */}
|
|||
|
|
<div className="footer-form-tab-navigation">
|
|||
|
|
<div className="footer-form-tab-buttons">
|
|||
|
|
<button className="footer-form-tab-btn footer-form-active">
|
|||
|
|
Footer Sections ({footerData.length})
|
|||
|
|
</button>
|
|||
|
|
<button className="footer-form-tab-btn">All Status</button>
|
|||
|
|
</div>
|
|||
|
|
<div className="footer-form-tab-controls">
|
|||
|
|
<div className="footer-form-sort-dropdown">
|
|||
|
|
<select>
|
|||
|
|
<option value="newest">Newest First</option>
|
|||
|
|
<option value="oldest">Oldest First</option>
|
|||
|
|
<option value="alphabetical">Alphabetical</option>
|
|||
|
|
</select>
|
|||
|
|
</div>
|
|||
|
|
<div className="footer-form-view-toggle">
|
|||
|
|
<button className="footer-form-view-btn footer-form-active">
|
|||
|
|
<span>⊞</span>
|
|||
|
|
</button>
|
|||
|
|
<button className="footer-form-view-btn">
|
|||
|
|
<span>☰</span>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Content Area */}
|
|||
|
|
{footerData.length > 0 ? (
|
|||
|
|
<div className="footer-form-display">
|
|||
|
|
<div className="footer-form-grid">
|
|||
|
|
{footerData.map((footer, index) => {
|
|||
|
|
const detail = footer.HomePageDetails?.[0];
|
|||
|
|
return (
|
|||
|
|
<div key={footer.SectionId || index} className={`footer-form-card ${footer.RStatus?.trim() !== 'A' ? 'footer-form-inactive' : ''}`}>
|
|||
|
|
<div className="footer-form-card-header">
|
|||
|
|
<h3>{footer.SectionHdr}</h3>
|
|||
|
|
</div>
|
|||
|
|
<div className="footer-form-card-content">
|
|||
|
|
<p><strong>Description:</strong> {footer.SectionDesc || "No description"}</p>
|
|||
|
|
{footer.HomePageDetails && footer.HomePageDetails.length > 0 && (
|
|||
|
|
<>
|
|||
|
|
{footer.HomePageDetails.filter(d => d.DtlName === 'Email').length > 0 && (
|
|||
|
|
<div className="footer-form-contact-section">
|
|||
|
|
<p><strong>Emails:</strong></p>
|
|||
|
|
{footer.HomePageDetails.filter(d => d.DtlName === 'Email').map((email, idx) => (
|
|||
|
|
<div key={idx} className="footer-form-contact-info">
|
|||
|
|
<span>{email.DtlDesc}</span>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
{footer.HomePageDetails.filter(d => d.DtlName === 'Phone').length > 0 && (
|
|||
|
|
<div className="footer-form-contact-section">
|
|||
|
|
<p><strong>Phones:</strong></p>
|
|||
|
|
{footer.HomePageDetails.filter(d => d.DtlName === 'Phone').map((phone, idx) => (
|
|||
|
|
<div key={idx} className="footer-form-contact-info">
|
|||
|
|
<span>{phone.DtlHdr}</span>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</>
|
|||
|
|
)}
|
|||
|
|
<p className={`footer-form-status ${footer.RStatus?.trim() === 'A' ? 'footer-form-status-active' : 'footer-form-status-inactive'}`}>
|
|||
|
|
Status: {footer.RStatus?.trim() === 'A' ? 'Active' : 'Inactive'}
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
<div className="footer-form-card-actions">
|
|||
|
|
<button className="footer-form-edit-btn" onClick={() => handleEdit(footer, index)}>
|
|||
|
|
Edit
|
|||
|
|
</button>
|
|||
|
|
<button
|
|||
|
|
className={`footer-form-status-btn ${footer.RStatus?.trim() === 'A' ? 'footer-form-deactivate' : 'footer-form-activate'}`}
|
|||
|
|
onClick={() => handleToggleActive(index)}
|
|||
|
|
>
|
|||
|
|
{footer.RStatus?.trim() === 'A' ? 'Deactivate' : 'Activate'}
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
})}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div className="footer-form-placeholder-content">
|
|||
|
|
<div className="footer-form-placeholder-icon">
|
|||
|
|
<span>🦶</span>
|
|||
|
|
</div>
|
|||
|
|
<h2>No Footer Sections Found</h2>
|
|||
|
|
<p>Get started by creating your first footer section</p>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{/* Modal */}
|
|||
|
|
<DefaultModal
|
|||
|
|
open={isModalOpen}
|
|||
|
|
title={editingIndex >= 0 ? "Edit Footer" : "Create New Footer"}
|
|||
|
|
handleCancel={closeModal}
|
|||
|
|
handleSubmit={handleSave}
|
|||
|
|
buttonText={editingIndex > -1 ? "Update Footer" : "Add Footer"}
|
|||
|
|
width={600}
|
|||
|
|
destroyOnClose={true}
|
|||
|
|
>
|
|||
|
|
<div className="footer-form">
|
|||
|
|
<div className="footer-form-group">
|
|||
|
|
<label htmlFor="footerTitle">Title</label>
|
|||
|
|
<input
|
|||
|
|
type="text"
|
|||
|
|
id="footerTitle"
|
|||
|
|
value={title?.trim()}
|
|||
|
|
onChange={(e) => {
|
|||
|
|
setTitle(e.target.value);
|
|||
|
|
if (titleError) setTitleError("");
|
|||
|
|
}}
|
|||
|
|
placeholder="Enter footer title"
|
|||
|
|
className={titleError ? "footer-form-error" : ""}
|
|||
|
|
autoFocus
|
|||
|
|
/>
|
|||
|
|
{titleError && <span className="footer-form-error-message">{titleError}</span>}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="footer-form-group">
|
|||
|
|
<label htmlFor="footerDescription">Description</label>
|
|||
|
|
<input
|
|||
|
|
type="text"
|
|||
|
|
id="footerDescription"
|
|||
|
|
value={description?.trim()}
|
|||
|
|
onChange={(e) => {
|
|||
|
|
setDescription(e.target.value);
|
|||
|
|
if (descriptionError) setDescriptionError("");
|
|||
|
|
}}
|
|||
|
|
placeholder="Enter footer description"
|
|||
|
|
className={descriptionError ? "footer-form-error" : ""}
|
|||
|
|
/>
|
|||
|
|
{descriptionError && <span className="footer-form-error-message">{descriptionError}</span>}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="footer-form-group">
|
|||
|
|
<label>Email Addresses</label>
|
|||
|
|
{emailFields.map((email, index) => (
|
|||
|
|
<div key={index} className="footer-form-field-group">
|
|||
|
|
<div className="footer-form-inputs">
|
|||
|
|
<input
|
|||
|
|
type="email"
|
|||
|
|
value={email.value}
|
|||
|
|
onChange={(e) => updateEmailField(index, e.target.value)}
|
|||
|
|
placeholder="Enter email address"
|
|||
|
|
/>
|
|||
|
|
<button type="button" onClick={() => removeEmailField(index)} className="footer-form-remove-btn">
|
|||
|
|
×
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
<button type="button" onClick={addEmailField} className="footer-form-add-btn">
|
|||
|
|
+ Add Email
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="footer-form-group">
|
|||
|
|
<label>Phone Numbers</label>
|
|||
|
|
{phoneFields.map((phone, index) => (
|
|||
|
|
<div key={index} className="footer-form-field-group">
|
|||
|
|
<div className="footer-form-inputs">
|
|||
|
|
<input
|
|||
|
|
type="tel"
|
|||
|
|
value={phone.value}
|
|||
|
|
onChange={(e) => {
|
|||
|
|
const value = e.target.value.replace(/[^0-9]/g, '').slice(0, 10);
|
|||
|
|
updatePhoneField(index, value);
|
|||
|
|
}}
|
|||
|
|
placeholder="Enter 10-digit phone number"
|
|||
|
|
maxLength={10}
|
|||
|
|
/>
|
|||
|
|
<button type="button" onClick={() => removePhoneField(index)} className="footer-form-remove-btn">
|
|||
|
|
×
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
<button type="button" onClick={addPhoneField} className="footer-form-add-btn">
|
|||
|
|
+ Add Phone
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="footer-form-actions">
|
|||
|
|
<button type="button" onClick={handleSave} className="footer-form-save-btn">
|
|||
|
|
{editingIndex > -1 ? "Update" : "Save"}
|
|||
|
|
</button>
|
|||
|
|
<button type="button" onClick={closeModal} className="footer-form-cancel-btn">
|
|||
|
|
Cancel
|
|||
|
|
</button>
|
|||
|
|
<button type="button" onClick={handleClear} className="footer-form-clear-btn">
|
|||
|
|
Clear
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</DefaultModal>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default FooterForm;
|