PozoAppCommonUpdatedCode/src/AdminPanel/AdminPanelForms/FooterForm.jsx

520 lines
22 KiB
React
Raw Normal View History

2025-12-05 09:45:16 +05:30
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;