This commit is contained in:
rohit 2025-08-05 18:15:16 +05:30
parent 27807fc9d6
commit 9d579385d7
6 changed files with 270 additions and 10 deletions

View File

@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Channel Partner Dashboard</title>
<title>Cloudtopiaa reseller Dashboard</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -31,7 +31,7 @@ import ResellerBilling from './pages/reseller/Billing';
import ResellerSupport from './pages/reseller/Support';
import ResellerReports from './pages/reseller/Reports';
import ResellerTraining from './pages/reseller/Training';
import ResellerLayout from './components/reseller/layout/ResellerLayout';
import ResellerLayout from './components/Layout/ResellerLayout';
import CookieConsent from './components/CookieConsent';
import './index.css';

View File

@ -0,0 +1,92 @@
import React from 'react';
import ResellerSidebar from './ResellerSidebar';
interface ResellerLayoutProps {
children: React.ReactNode;
}
const ResellerLayout: React.FC<ResellerLayoutProps> = ({ children }) => {
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-emerald-50 to-teal-50 dark:from-slate-900 dark:via-slate-800 dark:to-slate-900">
<div className="flex h-screen">
{/* Sidebar */}
<div className="flex-shrink-0">
<ResellerSidebar />
</div>
{/* Main Content */}
<div className="flex-1 flex flex-col overflow-hidden">
{/* Top Navigation Bar */}
<div className="bg-white/90 dark:bg-slate-900/95 backdrop-blur-xl border-b border-slate-200/50 dark:border-slate-700/50 sticky top-0 z-40 shadow-sm">
<div className="flex items-center justify-between px-8 py-5 h-20">
{/* Left Side - Logo and Title */}
<div className="flex items-center space-x-5">
<div className="w-10 h-10 bg-gradient-to-br from-emerald-500 via-teal-500 to-cyan-500 rounded-xl flex items-center justify-center flex-shrink-0 shadow-lg">
<div className="w-5 h-5 bg-white rounded-md shadow-sm"></div>
</div>
<div className="flex flex-col justify-center">
<h1 className="text-xl font-bold text-slate-900 dark:text-white leading-tight tracking-tight">
Reseller Portal
</h1>
<p className="text-sm font-medium text-slate-500 dark:text-slate-400 leading-tight">
Cloud Services Management
</p>
</div>
</div>
{/* Right Side - Search, Notifications, User */}
<div className="flex items-center space-x-6">
{/* Search Bar */}
<div className="relative flex-shrink-0">
<input
type="text"
placeholder="Search anything..."
className="w-72 pl-12 pr-6 py-3 bg-slate-50 dark:bg-slate-800/80 border border-slate-200/50 dark:border-slate-600/50 rounded-xl text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-emerald-500/50 focus:border-emerald-500/50 transition-all duration-200 backdrop-blur-sm"
/>
<div className="absolute left-4 top-1/2 transform -translate-y-1/2">
<svg className="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
</div>
{/* Notifications */}
<button className="relative p-3 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100/80 dark:hover:bg-slate-700/50 rounded-xl transition-all duration-200 flex-shrink-0 group">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 17h5l-5 5v-5zM4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5z" />
</svg>
<span className="absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full border-2 border-white dark:border-slate-900"></span>
</button>
{/* Divider */}
<div className="w-px h-8 bg-slate-200 dark:bg-slate-700"></div>
{/* User Menu */}
<div className="flex items-center space-x-4 flex-shrink-0 group cursor-pointer">
<div className="text-right flex flex-col justify-center">
<p className="text-sm font-semibold text-slate-900 dark:text-white leading-tight">John Reseller</p>
<p className="text-xs font-medium text-slate-500 dark:text-slate-400 leading-tight">Tech Solutions Inc</p>
</div>
<div className="w-10 h-10 bg-gradient-to-br from-emerald-500 via-teal-500 to-cyan-500 rounded-xl flex items-center justify-center flex-shrink-0 shadow-lg group-hover:shadow-xl transition-all duration-200">
<span className="text-white text-sm font-bold">JR</span>
</div>
</div>
</div>
</div>
</div>
{/* Page Content */}
<div className="flex-1 overflow-auto">
<div className="p-6">
<div className="max-w-7xl mx-auto">
{children}
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default ResellerLayout;

View File

@ -0,0 +1,163 @@
import React, { useState } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { useAppSelector, useAppDispatch } from '../../store/hooks';
import {
Home,
Users,
Cloud,
CreditCard,
Headphones,
BarChart3,
Wallet,
BookOpen,
ShoppingBag,
Award,
HelpCircle,
Settings,
Menu,
X,
Sun,
Moon,
LogOut,
Building,
Target,
TrendingUp,
Package
} from 'lucide-react';
import { RootState } from '../../store';
import { toggleTheme } from '../../store/slices/themeSlice';
import { logout } from '../../store/slices/authSlice';
import { cn } from '../../utils/cn';
const resellerNavigation = [
{ name: 'Dashboard', href: '/reseller-dashboard', icon: Home },
{ name: 'Customers', href: '/reseller-dashboard/customers', icon: Users },
{ name: 'Cloud Instances', href: '/reseller-dashboard/instances', icon: Cloud },
{ name: 'Billing', href: '/reseller-dashboard/billing', icon: CreditCard },
{ name: 'Support', href: '/reseller-dashboard/support', icon: Headphones },
{ name: 'Reports', href: '/reseller-dashboard/reports', icon: BarChart3 },
{ name: 'Wallet', href: '/reseller-dashboard/wallet', icon: Wallet },
{ name: 'Training', href: '/reseller-dashboard/training', icon: BookOpen },
{ name: 'Marketplace', href: '/reseller-dashboard/marketplace', icon: ShoppingBag },
{ name: 'Certifications', href: '/reseller-dashboard/certifications', icon: Award },
{ name: 'Knowledge Base', href: '/reseller-dashboard/knowledge-base', icon: HelpCircle },
{ name: 'Settings', href: '/reseller-dashboard/settings', icon: Settings },
];
const ResellerSidebar: React.FC = () => {
const [isCollapsed, setIsCollapsed] = useState(false);
const location = useLocation();
const dispatch = useAppDispatch();
const { theme } = useAppSelector((state: RootState) => state.theme);
const { user } = useAppSelector((state: RootState) => state.auth);
const handleLogout = () => {
dispatch(logout());
};
return (
<div className={cn(
"flex flex-col h-full bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 border-r border-slate-700/50 transition-all duration-300",
isCollapsed ? "w-16" : "w-64"
)}>
{/* Header */}
<div className="flex items-center justify-between p-4 border-b border-slate-700/50">
{!isCollapsed && (
<div className="flex items-center space-x-2">
<div className="w-8 h-8 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-lg flex items-center justify-center">
<Cloud className="w-5 h-5 text-white" />
</div>
<span className="text-lg font-semibold text-white">
Reseller
</span>
</div>
)}
<button
onClick={() => setIsCollapsed(!isCollapsed)}
className="p-1 rounded-md hover:bg-slate-700/50 transition-colors"
>
{isCollapsed ? (
<Menu className="w-6 h-6 text-slate-400" />
) : (
<X className="w-5 h-5 text-slate-400" />
)}
</button>
</div>
{/* Navigation */}
<nav className={cn(
"flex-1 py-4 space-y-1 overflow-y-auto",
isCollapsed ? "px-3" : "px-2"
)}>
{resellerNavigation.map((item) => {
const isActive = location.pathname === item.href;
return (
<Link
key={item.name}
to={item.href}
className={cn(
"flex items-center text-sm font-medium rounded-xl transition-all duration-200 group",
isCollapsed ? "px-2 py-3 justify-center" : "px-4 py-3",
isActive
? "bg-gradient-to-r from-emerald-500/20 to-teal-500/20 text-emerald-400 border border-emerald-500/30 shadow-lg"
: "text-slate-300 hover:bg-slate-800/50 hover:text-white"
)}
>
<item.icon className={cn(
"flex-shrink-0 transition-colors duration-200",
isCollapsed ? "w-6 h-6" : "w-5 h-5",
isActive
? "text-emerald-400"
: "text-slate-400 group-hover:text-white"
)} />
{!isCollapsed && (
<span className="ml-3">{item.name}</span>
)}
</Link>
);
})}
</nav>
{/* User Profile & Actions */}
<div className="border-t border-slate-700/50 p-4 space-y-2">
{/* Theme Toggle */}
<button
onClick={() => dispatch(toggleTheme())}
className={cn(
"w-full flex items-center rounded-xl text-sm font-medium transition-all duration-200",
isCollapsed ? "justify-center px-2 py-3" : "px-4 py-3",
"text-slate-300 hover:bg-slate-800/50 hover:text-white"
)}
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{theme === 'dark' ? (
<Sun className="w-6 h-6 text-amber-400" />
) : (
<Moon className="w-6 h-6 text-slate-400" />
)}
{!isCollapsed && (
<span className="ml-3">
{theme === 'dark' ? 'Light Mode' : 'Dark Mode'}
</span>
)}
</button>
{/* Logout */}
<button
onClick={handleLogout}
className={cn(
"w-full flex items-center rounded-xl text-sm font-medium transition-all duration-200",
isCollapsed ? "justify-center px-2 py-3" : "px-4 py-3",
"text-red-400 hover:bg-red-500/10 hover:text-red-300"
)}
title="Logout"
>
<LogOut className="w-6 h-6" />
{!isCollapsed && <span className="ml-3">Logout</span>}
</button>
</div>
</div>
);
};
export default ResellerSidebar;

View File

@ -82,7 +82,7 @@ const Sidebar: React.FC = () => {
className="p-1 rounded-md hover:bg-secondary-100 dark:hover:bg-secondary-800 transition-colors"
>
{isCollapsed ? (
<Menu className="w-5 h-5 text-secondary-600 dark:text-secondary-400" />
<Menu className="w-6 h-6 text-secondary-600 dark:text-secondary-400" />
) : (
<X className="w-5 h-5 text-secondary-600 dark:text-secondary-400" />
)}
@ -90,7 +90,10 @@ const Sidebar: React.FC = () => {
</div>
{/* Navigation */}
<nav className="flex-1 px-2 py-4 space-y-1 overflow-y-auto">
<nav className={cn(
"flex-1 py-4 space-y-1 overflow-y-auto",
isCollapsed ? "px-3" : "px-2"
)}>
{navigation.map((item) => {
const isActive = location.pathname === item.href;
return (
@ -98,14 +101,16 @@ const Sidebar: React.FC = () => {
key={item.name}
to={item.href}
className={cn(
"flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors group",
"flex items-center text-sm font-medium rounded-md transition-colors group",
isCollapsed ? "px-2 py-3 justify-center" : "px-3 py-2",
isActive
? "bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300"
: "text-secondary-700 hover:bg-secondary-100 hover:text-secondary-900 dark:text-secondary-300 dark:hover:bg-secondary-800 dark:hover:text-white"
)}
>
<item.icon className={cn(
"flex-shrink-0 w-5 h-5 transition-colors",
"flex-shrink-0 transition-colors",
isCollapsed ? "w-6 h-6" : "w-5 h-5",
isActive
? "text-primary-600 dark:text-primary-400"
: "text-secondary-500 group-hover:text-secondary-700 dark:text-secondary-400 dark:group-hover:text-white"
@ -133,9 +138,9 @@ const Sidebar: React.FC = () => {
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{theme === 'dark' ? (
<Sun className="w-5 h-5 text-secondary-600 dark:text-secondary-400" />
<Sun className={cn(isCollapsed ? "w-6 h-6" : "w-5 h-5", "text-secondary-600 dark:text-secondary-400")} />
) : (
<Moon className="w-5 h-5 text-secondary-600 dark:text-secondary-400" />
<Moon className={cn(isCollapsed ? "w-6 h-6" : "w-5 h-5", "text-secondary-600 dark:text-secondary-400")} />
)}
</button>
</div>
@ -175,7 +180,7 @@ const Sidebar: React.FC = () => {
className="p-1 rounded-md hover:bg-secondary-100 dark:hover:bg-secondary-800 transition-colors"
title="Logout"
>
<LogOut className="w-4 h-4 text-secondary-600 dark:text-secondary-400" />
<LogOut className={cn(isCollapsed ? "w-5 h-5" : "w-4 h-4", "text-secondary-600 dark:text-secondary-400")} />
</button>
</div>
)}

View File

@ -103,7 +103,7 @@ const ResellerDashboard: React.FC = () => {
<div className="relative z-10">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold mb-2">Welcome back, John! 👋</h1>
<h1 className="text-3xl font-bold mb-2">Welcome back, John! </h1>
<p className="text-emerald-100 text-lg">Here's what's happening with your cloud services business today.</p>
</div>
<div className="hidden lg:flex items-center space-x-4">