PozoAppOptimUpdated/src/LandingPageCMS/LandingPageCMS.jsx

272 lines
8.3 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import "./LandingPageCMS.scss";
import {
FaHome,
FaHeading,
FaImage,
FaQuestionCircle,
FaArrowLeft,
FaSave,
FaEye,
FaLock,
FaMoon,
FaSun,
FaBars,
FaTimes
} from "react-icons/fa";
import { MdDashboard, MdEdit } from "react-icons/md";
import { useDispatch } from "react-redux";
import { message } from "antd";
import { getAdminPanel, postAdminPanel, putAdminPanel } from "../features/AdminPanel/AdminPanel";
import { getSession } from "../Services/others";
// Section Components
import HeroContentEditor from "./Sections/HeroContentEditor";
import OfferingsEditor from "./Sections/OfferingsEditor";
import FeaturesEditor from "./Sections/FeaturesEditor";
import FAQEditor from "./Sections/FAQEditor";
const subDirectory = import.meta.env.ENV_BASE_URL;
const LandingPageCMS = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const [activeSection, setActiveSection] = useState("hero");
const [isSaving, setIsSaving] = useState(false);
const [hasChanges, setHasChanges] = useState(false);
const [isAuthorized, setIsAuthorized] = useState(false);
const [isCheckingAuth, setIsCheckingAuth] = useState(true);
const [isDarkMode, setIsDarkMode] = useState(true);
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);
// Load theme preference from localStorage
useEffect(() => {
const savedTheme = localStorage.getItem("landing-cms-theme");
if (savedTheme) {
setIsDarkMode(savedTheme === "dark");
}
}, []);
const toggleTheme = () => {
const newTheme = !isDarkMode;
setIsDarkMode(newTheme);
localStorage.setItem("landing-cms-theme", newTheme ? "dark" : "light");
};
// 📱 Prevent body scroll when mobile sidebar is open
useEffect(() => {
if (isMobileSidebarOpen && window.innerWidth <= 900) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "";
}
return () => {
document.body.style.overflow = "";
};
}, [isMobileSidebarOpen]);
// 🔒 Authentication Check
useEffect(() => {
const checkAuthentication = () => {
const userType = getSession("UserType");
const userId = getSession("UserId");
const authToken = sessionStorage.getItem("auth");
// Allow only Marketing, Super Admin, or Admin
const allowedUserTypes = ["Marketing", "Super Admin", "Admin", "Super Admin User"];
if (!authToken || !userId || !allowedUserTypes.includes(userType)) {
message.error("Unauthorized access! Please login first.");
navigate(`${subDirectory}signin`);
return;
}
setIsAuthorized(true);
setIsCheckingAuth(false);
};
checkAuthentication();
}, [navigate]);
const sections = [
{
id: "hero",
name: "Hero Section",
icon: <FaHeading />,
description: "Main headline, subtext, and CTA button",
component: HeroContentEditor
},
{
id: "offerings",
name: "Offerings",
icon: <FaImage />,
description: "3 key features (Experience, Innovation, Cost)",
component: OfferingsEditor
},
{
id: "features",
name: "Features",
icon: <MdDashboard />,
description: "Product features and benefits",
component: FeaturesEditor
},
{
id: "faq",
name: "FAQ Section",
icon: <FaQuestionCircle />,
description: "Frequently asked questions",
component: FAQEditor
}
];
const currentSection = sections.find(s => s.id === activeSection);
const CurrentComponent = currentSection?.component;
const handlePreview = () => {
window.open(`${subDirectory}`, '_blank');
};
const handleSaveAll = async () => {
setIsSaving(true);
try {
// Save logic will be implemented in each section component
message.success("All changes saved successfully!");
setHasChanges(false);
} catch (error) {
message.error("Failed to save changes");
} finally {
setIsSaving(false);
}
};
// Show loading while checking auth
if (isCheckingAuth) {
return (
<div className="landing-cms-auth-loading">
<div className="auth-loading-spinner"></div>
<p>Verifying access...</p>
</div>
);
}
// Don't render if not authorized (will redirect)
if (!isAuthorized) {
return null;
}
return (
<div className={`landing-cms-container ${isDarkMode ? 'dark-mode' : 'light-mode'}`}>
{/* Top Header */}
<div className="landing-cms-header">
<div className="landing-cms-header-left">
<button
className="landing-cms-mobile-menu-btn"
onClick={() => setIsMobileSidebarOpen(!isMobileSidebarOpen)}
aria-label="Toggle mobile menu"
>
{isMobileSidebarOpen ? <FaTimes /> : <FaBars />}
</button>
<button
className="landing-cms-back-btn"
onClick={() => navigate(`${subDirectory}`)}
>
<FaArrowLeft /> <span>Back to Home</span>
</button>
<div className="landing-cms-title-section">
<h1>Landing Page CMS</h1>
<p>Manage your homepage content dynamically</p>
</div>
</div>
<div className="landing-cms-header-right">
<button
className="landing-cms-theme-toggle"
onClick={toggleTheme}
aria-label={isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode"}
title={isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode"}
>
{isDarkMode ? <FaSun /> : <FaMoon />}
</button>
<button
className="landing-cms-preview-btn"
onClick={handlePreview}
>
<FaEye /> <span>Preview</span>
</button>
<button
className={`landing-cms-save-btn ${hasChanges ? 'has-changes' : ''}`}
onClick={handleSaveAll}
disabled={isSaving || !hasChanges}
>
<FaSave /> <span>{isSaving ? 'Saving...' : 'Save All Changes'}</span>
</button>
</div>
</div>
<div className="landing-cms-main">
{/* Mobile Overlay */}
{isMobileSidebarOpen && (
<div
className="landing-cms-mobile-overlay"
onClick={() => setIsMobileSidebarOpen(false)}
aria-hidden="true"
/>
)}
{/* Sidebar Navigation */}
<div className={`landing-cms-sidebar ${isMobileSidebarOpen ? 'mobile-open' : ''}`}>
<div className="landing-cms-sidebar-header">
<FaHome />
<span>Content Sections</span>
</div>
<div className="landing-cms-nav-items">
{sections.map((section) => (
<button
key={section.id}
className={`landing-cms-nav-item ${activeSection === section.id ? 'active' : ''}`}
onClick={() => {
setActiveSection(section.id);
setIsMobileSidebarOpen(false); // Close on mobile after selection
}}
>
<div className="landing-cms-nav-icon">{section.icon}</div>
<div className="landing-cms-nav-content">
<div className="landing-cms-nav-title">{section.name}</div>
<div className="landing-cms-nav-desc">{section.description}</div>
</div>
</button>
))}
</div>
</div>
{/* Content Area */}
<div className="landing-cms-content">
<div className="landing-cms-content-header">
<div className="landing-cms-breadcrumb">
<span>Landing Page</span>
<span>/</span>
<span>{currentSection?.name}</span>
</div>
{hasChanges && (
<div className="landing-cms-unsaved-badge">
Unsaved changes
</div>
)}
</div>
<div className="landing-cms-content-body">
{CurrentComponent && (
<CurrentComponent
onDataChange={() => setHasChanges(true)}
/>
)}
</div>
</div>
</div>
</div>
);
};
export default LandingPageCMS;