adds campaignX as upcoming feature
This commit is contained in:
@@ -49,6 +49,7 @@ import CustomerEstimateWizard from './modules/estimateWizard/CustomerEstimateWiz
|
||||
import EstimateWizardAdmin from './modules/estimateWizard/EstimateWizardAdmin';
|
||||
import SocialAdsEngine from './modules/socialAdsEngine/SocialAdsEngine';
|
||||
import PublicAdLanding from './modules/socialAdsEngine/PublicAdLanding';
|
||||
import CampaignXComingSoon from './pages/CampaignXComingSoon';
|
||||
|
||||
// ... (existing imports)
|
||||
const ProtectedRoute = ({ children, allowedRoles }) => {
|
||||
@@ -93,6 +94,12 @@ function App() {
|
||||
<SocialAdsEngine />
|
||||
</ProtectedRoute>
|
||||
} />
|
||||
{/* CampaignX — placeholder teaser screen for the upcoming marketing module (Owner/Admin) */}
|
||||
<Route path="/campaignx" element={
|
||||
<ProtectedRoute allowedRoles={['OWNER', 'ADMIN']}>
|
||||
<CampaignXComingSoon />
|
||||
</ProtectedRoute>
|
||||
} />
|
||||
<Route
|
||||
path="/chat-assistant"
|
||||
element={
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
LayoutDashboard, Map, Calendar, LogOut, User, Home, MessageSquare,
|
||||
ChevronLeft, ChevronRight, Sun, Moon, Trophy, Users, Briefcase,
|
||||
FileText, Menu, X, Calculator, PlusCircle, ClipboardList, Zap, LayoutGrid, Settings, CloudLightning,
|
||||
HardHat, ShieldCheck, Sparkles, Megaphone
|
||||
HardHat, ShieldCheck, Sparkles, Megaphone, Rocket
|
||||
} from 'lucide-react';
|
||||
|
||||
import PageTransition from './PageTransition';
|
||||
@@ -160,6 +160,8 @@ const Layout = () => {
|
||||
...commonItems,
|
||||
{ to: "/estimate-wizard/admin", icon: Settings, label: "Wizard Admin" },
|
||||
{ to: "/marketing", icon: Megaphone, label: "Ad Engine" },
|
||||
{ type: "section", label: "Upcoming Features" },
|
||||
{ to: "/campaignx", icon: Rocket, label: <span>Campaign<span className="text-amber-500">X</span></span> },
|
||||
];
|
||||
case 'ADMIN':
|
||||
return [
|
||||
@@ -183,6 +185,8 @@ const Layout = () => {
|
||||
...commonItems,
|
||||
{ to: "/estimate-wizard/admin", icon: Settings, label: "Wizard Admin" },
|
||||
{ to: "/marketing", icon: Megaphone, label: "Ad Engine" },
|
||||
{ type: "section", label: "Upcoming Features" },
|
||||
{ to: "/campaignx", icon: Rocket, label: <span>Campaign<span className="text-amber-500">X</span></span> },
|
||||
];
|
||||
case 'CONTRACTOR':
|
||||
case 'SUBCONTRACTOR':
|
||||
@@ -288,7 +292,22 @@ const Layout = () => {
|
||||
|
||||
{/* 2. Navigation Items */}
|
||||
<nav className="flex-1 px-3 py-6 space-y-1 overflow-y-auto custom-scrollbar" role="navigation">
|
||||
{navItems.map((item) => (
|
||||
{navItems.map((item, idx) => {
|
||||
// Section header — a divider line followed by a small uppercase label.
|
||||
if (item.type === 'section') {
|
||||
const collapsed = isCollapsed && !isMobileMenuOpen;
|
||||
return (
|
||||
<div key={`section-${idx}`} className="pt-4 pb-1">
|
||||
<div className="h-px bg-zinc-200 dark:bg-white/10 mb-2" />
|
||||
{!collapsed && (
|
||||
<span className="px-3 text-[10px] font-bold uppercase tracking-widest text-zinc-400 dark:text-zinc-500">
|
||||
{item.label}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SidebarItem
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
@@ -297,7 +316,8 @@ const Layout = () => {
|
||||
isCollapsed={isCollapsed && !isMobileMenuOpen}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
/>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* 3. User Profile & Footer */}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* CampaignXComingSoon — placeholder / teaser screen for the upcoming CampaignX module.
|
||||
*
|
||||
* Rendered at /campaignx. This is intentionally a "coming soon" experience: a hero
|
||||
* that explains what CampaignX is, followed by a vertical timeline of the upcoming
|
||||
* features that will ship with the module. No real functionality is wired yet.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
Rocket, Sparkles, Target, BarChart3, Bot, Layers, Send, Clock,
|
||||
} from 'lucide-react';
|
||||
|
||||
const UPCOMING = [
|
||||
{
|
||||
icon: Target,
|
||||
title: 'Multi-Channel Campaign Orchestration',
|
||||
desc: 'Design once and launch across email, SMS, social and ads from a single canvas — with audience targeting baked in.',
|
||||
},
|
||||
{
|
||||
icon: Bot,
|
||||
title: 'AI Campaign Copilot',
|
||||
desc: 'Generate copy, subject lines and creative variants instantly, then let the assistant recommend the best-performing mix.',
|
||||
},
|
||||
{
|
||||
icon: Layers,
|
||||
title: 'Visual Journey Builder',
|
||||
desc: 'Drag-and-drop branching journeys with triggers, delays and conditions to nurture every lead automatically.',
|
||||
},
|
||||
{
|
||||
icon: Send,
|
||||
title: 'Smart Send-Time Optimization',
|
||||
desc: 'CampaignX learns when each contact is most likely to engage and schedules delivery for peak response.',
|
||||
},
|
||||
{
|
||||
icon: BarChart3,
|
||||
title: 'Real-Time Performance Analytics',
|
||||
desc: 'Track opens, clicks, conversions and ROI live, with attribution that ties revenue back to every touchpoint.',
|
||||
},
|
||||
];
|
||||
|
||||
export default function CampaignXComingSoon() {
|
||||
return (
|
||||
<div className="min-h-full bg-zinc-50 dark:bg-[#09090b]">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 py-10 sm:py-16">
|
||||
|
||||
{/* --- Hero --- */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 12 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className="text-center"
|
||||
>
|
||||
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-amber-500/10 text-amber-600 dark:text-amber-400 text-xs font-bold uppercase tracking-wider mb-6 ring-1 ring-amber-500/20">
|
||||
<Clock size={13} />
|
||||
Coming Soon
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center mb-6">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 rounded-3xl bg-gradient-to-tr from-amber-400 to-orange-600 blur-2xl opacity-40" />
|
||||
<div className="relative p-5 rounded-3xl bg-gradient-to-tr from-amber-400 to-orange-600 text-white shadow-xl shadow-amber-500/30">
|
||||
<Rocket size={40} strokeWidth={2} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="text-3xl sm:text-5xl font-extrabold tracking-tight text-zinc-900 dark:text-white">
|
||||
Campaign<span className="text-amber-500">X</span>
|
||||
</h1>
|
||||
<p className="mt-4 text-base sm:text-lg text-zinc-600 dark:text-zinc-400 max-w-2xl mx-auto leading-relaxed">
|
||||
Your next-generation marketing command center. CampaignX brings every channel,
|
||||
audience and automation into one intelligent workspace — so you can launch
|
||||
smarter campaigns and turn more leads into jobs.
|
||||
</p>
|
||||
|
||||
<div className="mt-6 inline-flex items-center gap-2 text-sm text-zinc-400 dark:text-zinc-500">
|
||||
<Sparkles size={15} className="text-amber-500" />
|
||||
We're building something special. Stay tuned.
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* --- Upcoming features timeline --- */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.4, delay: 0.15 }}
|
||||
className="mt-14 sm:mt-20"
|
||||
>
|
||||
<h2 className="text-xs font-bold uppercase tracking-widest text-zinc-400 dark:text-zinc-500 mb-8 text-center">
|
||||
What's coming to CampaignX
|
||||
</h2>
|
||||
|
||||
{/* Vertical line + feature items */}
|
||||
<div className="relative pl-8 sm:pl-10">
|
||||
{/* The vertical line */}
|
||||
<div className="absolute left-[11px] sm:left-[15px] top-2 bottom-2 w-px bg-gradient-to-b from-amber-400 via-amber-500/40 to-transparent" />
|
||||
|
||||
<div className="space-y-8">
|
||||
{UPCOMING.map((feature, i) => {
|
||||
const Icon = feature.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{ opacity: 0, x: 12 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.35, delay: 0.2 + i * 0.08 }}
|
||||
className="relative"
|
||||
>
|
||||
{/* Node on the line */}
|
||||
<div className="absolute -left-8 sm:-left-10 top-0.5 flex items-center justify-center w-6 h-6 rounded-full bg-white dark:bg-zinc-900 ring-2 ring-amber-500 shadow-sm">
|
||||
<Icon size={13} className="text-amber-500" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-base sm:text-lg font-bold text-zinc-900 dark:text-white">
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed max-w-xl">
|
||||
{feature.desc}
|
||||
</p>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* --- Footer note --- */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.4, delay: 0.6 }}
|
||||
className="mt-16 text-center"
|
||||
>
|
||||
<div className="inline-block px-5 py-3 rounded-2xl bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-white/5 shadow-sm">
|
||||
<p className="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
CampaignX is currently in active development — it'll appear here the moment it's ready.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user