PozoAppCommonUpdatedCode/src/AdminPanel/AdminPanelForms/FooterForm.jsx

520 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;