From 85bc3359d775d6c52a1d16c1efa4de55c85265ba Mon Sep 17 00:00:00 2001 From: SridharRajamani <123048029+SridharRajamani@users.noreply.github.com> Date: Thu, 6 Nov 2025 23:52:53 +0530 Subject: [PATCH] feat: Add Landing Page CMS, enhance Navbar with Solutions dropdown, mobile sticky footer, and optimize homepage features visibility --- sitemap.xml | 2 +- src/.env.development | 8 +- src/.env.production | 29 +- src/AdminPanel/Styles/BlogForm.scss | 20 + src/App.jsx | 23 +- src/LandingPageCMS/LandingPageCMS.jsx | 271 +++++ src/LandingPageCMS/LandingPageCMS.scss | 627 ++++++++++ src/LandingPageCMS/Sections/FAQEditor.jsx | 27 + .../Sections/FeaturesEditor.jsx | 27 + .../Sections/HeroContentEditor.jsx | 216 ++++ .../Sections/OfferingsEditor.jsx | 212 ++++ .../Sections/SectionEditor.scss | 494 ++++++++ src/Pages/application/applicationForm.jsx | 27 +- src/Pages/themeTemplate/AllTemplates.jsx | 2 +- src/Pages/themeTemplate/Template.jsx | 589 +++++----- src/PozoApp/Components/ContactUs.jsx | 9 + src/PozoApp/Components/Footer.jsx | 350 ++++-- src/PozoApp/Components/Industries.jsx | 9 +- src/PozoApp/Components/Navbar.jsx | 147 ++- src/PozoApp/Components/OverView.jsx | 109 +- src/PozoApp/Components/PricingPozoApp.jsx | 9 + src/PozoApp/Components/ResponsiveApp.jsx | 2 +- src/PozoApp/Components/SignIn.jsx | 5 +- src/PozoApp/Pages/CaseStudies.jsx | 31 + src/PozoApp/Pages/CaseStudies.scss | 82 ++ src/PozoApp/Pages/HomePage.jsx | 303 ++--- src/PozoApp/Pages/Solutions.jsx | 97 ++ src/PozoApp/Pages/Solutions.scss | 134 +++ src/PozoApp/Styles/Footer.scss | 355 +++++- src/PozoApp/Styles/Navbar.scss | 137 +++ src/PozoApp/Styles/Offering.scss | 5 +- src/PozoApp/Styles/OverView.scss | 22 +- src/PozoApp/Videos/OverView.webm | Bin 3730813 -> 2386515 bytes src/PozoApp/Videos/OverView0.webm | Bin 0 -> 3730813 bytes src/PozoApp/Videos/OverView1.webm | Bin 0 -> 1404810 bytes src/check.jsx | 1027 +++++++---------- src/check.scss | 101 +- src/routesConfig.jsx | 13 +- vite.config.js | 3 +- 39 files changed, 4288 insertions(+), 1236 deletions(-) create mode 100644 src/LandingPageCMS/LandingPageCMS.jsx create mode 100644 src/LandingPageCMS/LandingPageCMS.scss create mode 100644 src/LandingPageCMS/Sections/FAQEditor.jsx create mode 100644 src/LandingPageCMS/Sections/FeaturesEditor.jsx create mode 100644 src/LandingPageCMS/Sections/HeroContentEditor.jsx create mode 100644 src/LandingPageCMS/Sections/OfferingsEditor.jsx create mode 100644 src/LandingPageCMS/Sections/SectionEditor.scss create mode 100644 src/PozoApp/Pages/CaseStudies.jsx create mode 100644 src/PozoApp/Pages/CaseStudies.scss create mode 100644 src/PozoApp/Pages/Solutions.jsx create mode 100644 src/PozoApp/Pages/Solutions.scss create mode 100644 src/PozoApp/Videos/OverView0.webm create mode 100644 src/PozoApp/Videos/OverView1.webm diff --git a/sitemap.xml b/sitemap.xml index 7accb1d..236d27a 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -17,7 +17,7 @@ 0.8 --> - https://www.pozo.app/pricing-pozoapp + https://www.pozo.app/pricing 2025-10-13 weekly 0.8 diff --git a/src/.env.development b/src/.env.development index f5b3b36..3bb476e 100644 --- a/src/.env.development +++ b/src/.env.development @@ -1,8 +1,8 @@ ENV_BASE_URL='/' -ENV_API_URL='http://192.168.1.37:8013' -ENV_API_URL_TOKEN='http://192.168.1.37:8001' -# ENV_API_URL_TOKEN='https://www.pozo.dev/JwtToken' -# ENV_API_URL='https://www.pozo.dev/pozo-common-api' +# ENV_API_URL='http://192.168.1.37:8013' +# ENV_API_URL_TOKEN='http://192.168.1.37:8001' +ENV_API_URL_TOKEN='https://www.pozo.dev/JwtToken' +ENV_API_URL='https://www.pozo.dev/pozo-common-api' # ENV_IMAGE_UPLOAD_API_URL="https://api.pozo.app/pozo-common-image-api/" ENV_API_URL_RETAIL='http://192.168.1.37:8012/' # ENV_API_URL_TOKEN='https://api.pozo.app/JwtToken' diff --git a/src/.env.production b/src/.env.production index d10dfe2..8eeb796 100644 --- a/src/.env.production +++ b/src/.env.production @@ -1,31 +1,6 @@ -#221 server - -# ENV_BASE_URL='/home/' -# ENV_API_URL='http://api.pozo.co.in/Pozocommonapi_UnderTest' -# # ENV_API_URL='http://api.pozo.co.in/Pozocommonapi' -# ENV_IMAGE_UPLOAD_API_URL="https://api.pozo.app/pozo-common-image-api" -# ENV_SECRET_KEY="3a939a2eed2cca4b64cd47f51b23b135b2b9b765273f695d47682ea803c8429d" -# ENV_URL_SECRET_KEY="f2ef79b8b2d4fc1cc569726a5a753552257b4ff2872d6a71cf3119bce3f07c1b" -# ENV_MAIN_BASE_URL='http://pozo.co.in/' -# ENV_MAIN_REDIRECT_URL='/apps/retail/app-page/home' - -# live server(#173 server) -# ENV_BASE_URL='/home/' -# ENV_API_URL_TOKEN='https://api.pozo.app/JwtToken' -# ENV_API_URL='https://api.pozo.app/pozo-common-api' -# ENV_IMAGE_UPLOAD_API_URL="https://api.pozo.app/pozo-common-image-api" -# ENV_SECRET_KEY="3a939a2eed2cca4b64cd47f51b23b135b2b9b765273f695d47682ea803c8429d" -# ENV_URL_SECRET_KEY="f2ef79b8b2d4fc1cc569726a5a753552257b4ff2872d6a71cf3119bce3f07c1b" -# ENV_MAIN_BASE_URL='https://www.pozo.app' -# ENV_MAIN_REDIRECT_URL='/apps/retail/app-page/home' -# ENV_PAYMENT_URL='https://pozo.app/paymentgateway/PozoPaymentGateway' -# ENV_CUSTOM_PAYMENT_URL='https://pozo.app/CustomPaymentGateway/CustomPaymentGateway' -# ENV_EMAIL_API='https://api.pozo.app/pozo-sms-email-template-api' -# ENV_API_URL_RETAIL='https://api.pozo.app/pozo-retail-api' - #172 server -ENV_BASE_URL='/home/' +ENV_BASE_URL='/' ENV_API_URL_TOKEN='https://www.pozo.dev/JwtToken' ENV_API_URL='https://www.pozo.dev/pozo-common-api' ENV_API_URL_RETAIL='https://www.pozo.dev/pozo-retail-api' @@ -37,5 +12,3 @@ ENV_MAIN_REDIRECT_URL='/apps/retail/app-page/home' ENV_PAYMENT_URL='https://pozo.app/paymentgateway/PozoPaymentGateway' ENV_CUSTOM_PAYMENT_URL='https://pozo.app/CustomPaymentGateway/CustomPaymentGateway' ENV_EMAIL_API='https://www.pozo.dev/pozo-sms-email-template-api' - - diff --git a/src/AdminPanel/Styles/BlogForm.scss b/src/AdminPanel/Styles/BlogForm.scss index 4c74c29..a91edfd 100644 --- a/src/AdminPanel/Styles/BlogForm.scss +++ b/src/AdminPanel/Styles/BlogForm.scss @@ -811,3 +811,23 @@ justify-content: center; } } + + +.filterAssDcc { + display: flex; + align-items: center; + gap: 4px; + button { + width: max-content; + padding: 8px 16px; + border: none; + font-family: "Poppins", sans-serif; + font-size: 14px; + font-weight: 500; + background-color: #e0ecff; + color: #1e6ae4; + border-radius: 6px; + cursor: pointer; + outline: none; + } +} diff --git a/src/App.jsx b/src/App.jsx index e506a3b..51ab05d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -69,6 +69,7 @@ import { useEffect } from "react"; import { checkSession, GenerateLogout } from "./features/signInPage/signInPage.js"; import { useDispatch } from "react-redux"; import { clearSession, getSession } from "./Services/others.js"; +import { PostToken } from "./features/publicHome/publicHome.js"; import LoyaltysettingList from "./Pages/LoyaltySetting/LoyaltysettingList.jsx" import LoyaltysettingsForm from "./Pages/LoyaltySetting/LoyaltysettingsForm.jsx" import ActivationkeyGeneration from "./Pages/ActivationkeyGeneration/ActivationkeyGeneration.jsx"; @@ -128,10 +129,28 @@ const App = () => { const navigate = useNavigate(); const dispatch = useDispatch(); + // 🔑 Global token generation for direct URL access useEffect(() => { - sessionCheckFun() + const ensureToken = async () => { + const existingToken = sessionStorage.getItem("auth"); + + if (!existingToken) { + try { + console.log("🔑 App: Generating global auth token..."); + await dispatch(PostToken({ + username: "1000000001", + password: "1234" + })).unwrap(); + console.log("✅ App: Token generated successfully"); + } catch (error) { + console.error("❌ App: Token generation failed:", error); + } + } + }; - }, [navigate]); + ensureToken(); + sessionCheckFun(); + }, [navigate, dispatch]); const sessionCheckFun=async()=>{ const UserId = getSession('UserId') diff --git a/src/LandingPageCMS/LandingPageCMS.jsx b/src/LandingPageCMS/LandingPageCMS.jsx new file mode 100644 index 0000000..75073ea --- /dev/null +++ b/src/LandingPageCMS/LandingPageCMS.jsx @@ -0,0 +1,271 @@ +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: , + description: "Main headline, subtext, and CTA button", + component: HeroContentEditor + }, + { + id: "offerings", + name: "Offerings", + icon: , + description: "3 key features (Experience, Innovation, Cost)", + component: OfferingsEditor + }, + { + id: "features", + name: "Features", + icon: , + description: "Product features and benefits", + component: FeaturesEditor + }, + { + id: "faq", + name: "FAQ Section", + icon: , + 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 ( +
+
+

Verifying access...

+
+ ); + } + + // Don't render if not authorized (will redirect) + if (!isAuthorized) { + return null; + } + + return ( +
+ {/* Top Header */} +
+
+ + +
+

Landing Page CMS

+

Manage your homepage content dynamically

+
+
+
+ + + +
+
+ +
+ {/* Mobile Overlay */} + {isMobileSidebarOpen && ( +
setIsMobileSidebarOpen(false)} + aria-hidden="true" + /> + )} + + {/* Sidebar Navigation */} +
+
+ + Content Sections +
+
+ {sections.map((section) => ( + + ))} +
+
+ + {/* Content Area */} +
+
+
+ Landing Page + / + {currentSection?.name} +
+ {hasChanges && ( +
+ Unsaved changes +
+ )} +
+ +
+ {CurrentComponent && ( + setHasChanges(true)} + /> + )} +
+
+
+
+ ); +}; + +export default LandingPageCMS; + diff --git a/src/LandingPageCMS/LandingPageCMS.scss b/src/LandingPageCMS/LandingPageCMS.scss new file mode 100644 index 0000000..6cc75bc --- /dev/null +++ b/src/LandingPageCMS/LandingPageCMS.scss @@ -0,0 +1,627 @@ +// 🎨 Landing Page CMS - Clean Minimal Design + +.landing-cms-container { + min-height: 100vh; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + transition: background 0.3s ease; + + // Dark Mode + &.dark-mode { + background: #000; + color: #e5e5e5; + } + + // Light Mode + &.light-mode { + background: #fafafa; + color: #171717; + } +} + +// Auth Loading +.landing-cms-auth-loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 100vh; + background: #000; + + .auth-loading-spinner { + width: 40px; + height: 40px; + border: 2px solid #333; + border-top-color: #fff; + border-radius: 50%; + animation: spin 0.6s linear infinite; + } + + p { + margin-top: 1rem; + color: #888; + font-size: 13px; + } +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +// Header +.landing-cms-header { + padding: 1rem 1.5rem; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid; + position: sticky; + top: 0; + z-index: 1002; + + .dark-mode & { + background: #111; + border-color: #222; + } + + .light-mode & { + background: #fff; + border-color: #e5e5e5; + } + + @media (max-width: 768px) { + padding: 0.875rem 1rem; + } + + .landing-cms-header-left { + display: flex; + align-items: center; + gap: 1.5rem; + } + + .landing-cms-mobile-menu-btn { + display: none; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + background: transparent; + border: 1px solid; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + font-size: 18px; + -webkit-tap-highlight-color: transparent; + flex-shrink: 0; + + .dark-mode & { + border-color: #333; + color: #e5e5e5; + + &:hover, &:active { + border-color: #0ea5e9; + background: #1a1a1a; + color: #0ea5e9; + } + } + + .light-mode & { + border-color: #d4d4d4; + color: #171717; + + &:hover, &:active { + border-color: #0969da; + background: #f5f5f5; + color: #0969da; + } + } + + @media (max-width: 900px) { + display: flex; + } + } + + .landing-cms-back-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: transparent; + border: 1px solid; + border-radius: 6px; + font-size: 13px; + cursor: pointer; + transition: all 0.2s; + font-family: inherit; + + .dark-mode & { + border-color: #333; + color: #e5e5e5; + + &:hover { + border-color: #666; + background: #1a1a1a; + } + } + + .light-mode & { + border-color: #d4d4d4; + color: #171717; + + &:hover { + border-color: #999; + background: #f5f5f5; + } + } + + @media (max-width: 768px) { + padding: 0.5rem 0.75rem; + + span { + display: none; + } + } + + svg { + font-size: 14px; + } + } + + .landing-cms-title-section h1 { + margin: 0; + font-size: 16px; + font-weight: 600; + + .dark-mode & { + color: #fff; + } + + .light-mode & { + color: #000; + } + + @media (max-width: 768px) { + font-size: 14px; + } + } + + .landing-cms-title-section p { + display: none; + } + + .landing-cms-header-right { + display: flex; + gap: 0.5rem; + } + + .landing-cms-theme-toggle { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: 1px solid; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + font-size: 18px; + -webkit-tap-highlight-color: transparent; + flex-shrink: 0; + + .dark-mode & { + border-color: #333; + color: #fbbf24; + + &:hover, &:active { + border-color: #fbbf24; + background: #1a1a1a; + } + } + + .light-mode & { + border-color: #d4d4d4; + color: #f59e0b; + + &:hover, &:active { + border-color: #f59e0b; + background: #f5f5f5; + } + } + } + + .landing-cms-preview-btn, + .landing-cms-save-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.625rem 1.25rem; + font-size: 13px; + font-weight: 500; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + font-family: inherit; + + @media (max-width: 768px) { + padding: 0.625rem 0.875rem; + + span { + display: none; + } + } + + svg { + font-size: 14px; + } + } + + .landing-cms-preview-btn { + background: transparent; + border: 1px solid; + + .dark-mode & { + border-color: #333; + color: #e5e5e5; + + &:hover { + border-color: #666; + background: #1a1a1a; + } + } + + .light-mode & { + border-color: #d4d4d4; + color: #171717; + + &:hover { + border-color: #999; + background: #f5f5f5; + } + } + } + + .landing-cms-save-btn { + border: none; + + .dark-mode & { + background: #fff; + color: #000; + + &:hover:not(:disabled) { + background: #e5e5e5; + } + + &.has-changes { + background: #10b981; + color: #fff; + + &:hover { + background: #059669; + } + } + } + + .light-mode & { + background: #000; + color: #fff; + + &:hover:not(:disabled) { + background: #333; + } + + &.has-changes { + background: #10b981; + color: #fff; + + &:hover { + background: #059669; + } + } + } + + &:disabled { + opacity: 0.4; + cursor: not-allowed; + } + } +} + +// Main +.landing-cms-main { + display: flex; + min-height: calc(100vh - 60px); + + @media (max-width: 900px) { + position: relative; + } +} + +// Sidebar +.landing-cms-sidebar { + width: 280px; + padding: 1.5rem 0; + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + border-right: 1px solid; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + + .dark-mode & { + background: #111; + border-color: #222; + } + + .light-mode & { + background: #fff; + border-color: #e5e5e5; + } + + @media (max-width: 900px) { + position: fixed !important; + left: 0; + top: 0; + bottom: 0; + z-index: 1001 !important; + transform: translateX(-100%); + box-shadow: 4px 0 24px rgba(0, 0, 0, 0.6); + padding-top: 70px; + width: 85%; + max-width: 320px; + + &.mobile-open { + transform: translateX(0) !important; + } + } + + @media (max-width: 480px) { + width: 90%; + } + + .landing-cms-sidebar-header { + padding: 0 1.25rem 1rem; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 1px; + display: flex; + align-items: center; + gap: 0.5rem; + + .dark-mode & { + color: #888; + } + + .light-mode & { + color: #999; + } + + svg { + font-size: 14px; + } + } + + .landing-cms-nav-items { + display: flex; + flex-direction: column; + gap: 0.375rem; + padding: 0 0.75rem; + } + + .landing-cms-nav-item { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.875rem 1rem; + background: transparent; + border: 1px solid transparent; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + text-align: left; + -webkit-tap-highlight-color: transparent; + user-select: none; + + @media (max-width: 900px) { + padding: 1rem 1.25rem; + min-height: 60px; + } + + .landing-cms-nav-icon { + width: 20px; + height: 20px; + font-size: 20px; + flex-shrink: 0; + transition: color 0.2s; + + .dark-mode & { + color: #888; + } + + .light-mode & { + color: #999; + } + } + + .landing-cms-nav-content { + flex: 1; + + .landing-cms-nav-title { + font-size: 14px; + font-weight: 500; + margin-bottom: 0.25rem; + transition: color 0.2s; + + .dark-mode & { + color: #e5e5e5; + } + + .light-mode & { + color: #171717; + } + } + + .landing-cms-nav-desc { + font-size: 12px; + line-height: 1.4; + + .dark-mode & { + color: #888; + } + + .light-mode & { + color: #999; + } + } + } + + .dark-mode &:hover { + background: #1a1a1a; + border-color: #333; + } + + .light-mode &:hover { + background: #f5f5f5; + border-color: #e5e5e5; + } + + &.active { + .dark-mode & { + background: #1a1a1a; + border-color: #0ea5e9; + + .landing-cms-nav-icon { + color: #10b981; + } + + .landing-cms-nav-title { + color: #fff; + font-weight: 600; + } + } + + .light-mode & { + background: #f0f9ff; + border-color: #0ea5e9; + + .landing-cms-nav-icon { + color: #10b981; + } + + .landing-cms-nav-title { + color: #000; + font-weight: 600; + } + + .landing-cms-nav-desc { + color: #666; + } + } + } + } +} + +// Mobile Overlay +.landing-cms-mobile-overlay { + display: none; + + @media (max-width: 900px) { + display: block; + position: fixed !important; + inset: 0; + top: 0; + background: rgba(0, 0, 0, 0.75); + z-index: 1000 !important; + animation: fadeIn 0.25s ease; + -webkit-tap-highlight-color: transparent; + } +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +// Content +.landing-cms-content { + flex: 1; + padding: 2rem 2.5rem; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + + .dark-mode & { + background: #000; + } + + .light-mode & { + background: #fafafa; + } + + @media (max-width: 900px) { + padding: 1.5rem 1rem; + } + + @media (max-width: 480px) { + padding: 1rem; + } + + .landing-cms-content-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 2rem; + + .landing-cms-breadcrumb { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 12px; + + .dark-mode & { + color: #888; + + span:last-child { + color: #e5e5e5; + font-weight: 500; + } + } + + .light-mode & { + color: #999; + + span:last-child { + color: #171717; + font-weight: 500; + } + } + } + + .landing-cms-unsaved-badge { + padding: 0.375rem 0.875rem; + background: #fbbf24; + color: #000; + border-radius: 16px; + font-size: 11px; + font-weight: 600; + } + } + + .landing-cms-content-body { + border-radius: 8px; + padding: 2.5rem; + border: 1px solid; + + .dark-mode & { + background: #111; + border-color: #222; + } + + .light-mode & { + background: #fff; + border-color: #e5e5e5; + } + + @media (max-width: 768px) { + padding: 1.5rem; + } + } +} diff --git a/src/LandingPageCMS/Sections/FAQEditor.jsx b/src/LandingPageCMS/Sections/FAQEditor.jsx new file mode 100644 index 0000000..9de1330 --- /dev/null +++ b/src/LandingPageCMS/Sections/FAQEditor.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import "./SectionEditor.scss"; +import { FaQuestionCircle } from "react-icons/fa"; + +const FAQEditor = ({ onDataChange }) => { + return ( +
+
+
+ +
+
+

FAQ Section

+

Manage frequently asked questions (Coming Soon)

+
+
+ +
+ Coming Soon: + FAQ editor will allow you to add, edit, and organize frequently asked questions. +
+
+ ); +}; + +export default FAQEditor; + diff --git a/src/LandingPageCMS/Sections/FeaturesEditor.jsx b/src/LandingPageCMS/Sections/FeaturesEditor.jsx new file mode 100644 index 0000000..bdcc80a --- /dev/null +++ b/src/LandingPageCMS/Sections/FeaturesEditor.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import "./SectionEditor.scss"; +import { MdDashboard } from "react-icons/md"; + +const FeaturesEditor = ({ onDataChange }) => { + return ( +
+
+
+ +
+
+

Features Section

+

Manage product features and benefits (Coming Soon)

+
+
+ +
+ Coming Soon: + Features editor will allow you to manage the product features section dynamically. +
+
+ ); +}; + +export default FeaturesEditor; + diff --git a/src/LandingPageCMS/Sections/HeroContentEditor.jsx b/src/LandingPageCMS/Sections/HeroContentEditor.jsx new file mode 100644 index 0000000..340e0a5 --- /dev/null +++ b/src/LandingPageCMS/Sections/HeroContentEditor.jsx @@ -0,0 +1,216 @@ +import React, { useState, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { message } from "antd"; +import { getAdminPanel, postAdminPanel, putAdminPanel } from "../../features/AdminPanel/AdminPanel"; +import "./SectionEditor.scss"; +import { FaRegLightbulb, FaSave } from "react-icons/fa"; +import { MdTitle, MdDescription } from "react-icons/md"; + +const HeroContentEditor = ({ onDataChange }) => { + const dispatch = useDispatch(); + const [isLoading, setIsLoading] = useState(true); + const [isSaving, setIsSaving] = useState(false); + + // Form fields + const [mainHeadline, setMainHeadline] = useState("Retail ERP & POS built for Indian MSMEs — fast billing, smart inventory, GST-ready."); + const [description, setDescription] = useState("A SaaS platform that empowers Small and Medium Businesses by digitizing operations and reducing Total Cost of Ownership with minimal investment."); + const [ctaButtonText, setCtaButtonText] = useState("Experience Now"); + const [ctaButtonLink, setCtaButtonLink] = useState("/signin"); + + useEffect(() => { + fetchHeroData(); + }, []); + + const fetchHeroData = async () => { + try { + setIsLoading(true); + const res = await dispatch( + getAdminPanel({ sectionName: "HeroSection" }) + ).unwrap(); + + if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) { + const heroData = res.data.data[0]; + if (heroData.Content) { + const content = JSON.parse(heroData.Content); + setMainHeadline(content.mainHeadline || mainHeadline); + setDescription(content.description || description); + setCtaButtonText(content.ctaButtonText || ctaButtonText); + setCtaButtonLink(content.ctaButtonLink || ctaButtonLink); + } + } + } catch (error) { + console.log("No existing hero data, using defaults"); + } finally { + setIsLoading(false); + } + }; + + const handleSave = async () => { + if (!mainHeadline.trim() || !description.trim()) { + message.error("Headline and description are required!"); + return; + } + + try { + setIsSaving(true); + + const data = { + SectionName: "HeroSection", + Content: JSON.stringify({ + mainHeadline: mainHeadline.trim(), + description: description.trim(), + ctaButtonText: ctaButtonText.trim(), + ctaButtonLink: ctaButtonLink.trim() + }), + ActiveStatus: "A", + CreatedBy: 1, + ModifiedBy: 1 + }; + + await dispatch(postAdminPanel(data)).unwrap(); + message.success("Hero section saved successfully!"); + onDataChange?.(); + } catch (error) { + console.error("Save error:", error); + message.error("Failed to save. Please try again."); + } finally { + setIsSaving(false); + } + }; + + if (isLoading) { + return ( +
+
+

Loading hero section...

+
+ ); + } + + return ( +
+
+
+ +
+
+

Hero Section Content

+

Manage the main headline, description, and CTA button on your landing page

+
+
+ +
+ {/* Main Headline */} +
+ +