From 26c352e2ccbd9f0c9f549c1a805d23b0e449e6f7 Mon Sep 17 00:00:00 2001 From: saridsa2 Date: Mon, 16 Mar 2026 18:24:25 +0530 Subject: [PATCH] feat: 3-role auth, role-based routing, role-specific sidebar navigation Add cc-agent role alongside executive and admin. Login page now has 3 tabs (Marketing Executive, Call Center, Admin). RoleRouter renders the appropriate home page per role. Sidebar shows completely different nav items per role with role subtitle. Placeholder pages added for Team Dashboard, Call Desk, Call History, and Follow-ups. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/layout/role-router.tsx | 17 ++++ src/components/layout/sidebar.tsx | 110 +++++++++++++++++++++----- src/main.tsx | 12 ++- src/pages/call-desk.tsx | 15 ++++ src/pages/call-history.tsx | 15 ++++ src/pages/follow-ups-page.tsx | 15 ++++ src/pages/login.tsx | 45 +++++------ src/pages/team-dashboard.tsx | 15 ++++ src/providers/auth-provider.tsx | 12 ++- 9 files changed, 208 insertions(+), 48 deletions(-) create mode 100644 src/components/layout/role-router.tsx create mode 100644 src/pages/call-desk.tsx create mode 100644 src/pages/call-history.tsx create mode 100644 src/pages/follow-ups-page.tsx create mode 100644 src/pages/team-dashboard.tsx diff --git a/src/components/layout/role-router.tsx b/src/components/layout/role-router.tsx new file mode 100644 index 0000000..9893dd4 --- /dev/null +++ b/src/components/layout/role-router.tsx @@ -0,0 +1,17 @@ +import { useAuth } from '@/providers/auth-provider'; +import { LeadWorkspacePage } from '@/pages/lead-workspace'; +import { TeamDashboardPage } from '@/pages/team-dashboard'; +import { CallDeskPage } from '@/pages/call-desk'; + +export const RoleRouter = () => { + const { user } = useAuth(); + + switch (user.role) { + case 'admin': + return ; + case 'cc-agent': + return ; + default: + return ; + } +}; diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx index d8e8c8e..cbaab71 100644 --- a/src/components/layout/sidebar.tsx +++ b/src/components/layout/sidebar.tsx @@ -1,12 +1,16 @@ import type { FC, HTMLAttributes } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { + faBell, faBullhorn, faChartMixed, + faClockRotateLeft, faCommentDots, faGear, faGrid2, + faPhone, faPlug, + faUsers, } from "@fortawesome/pro-duotone-svg-icons"; import { useNavigate } from "react-router"; import { MobileNavigationHeader } from "@/components/application/app-navigation/base-components/mobile-header"; @@ -36,28 +40,100 @@ const IconPlug: FC> = ({ className }) => ( const IconGear: FC> = ({ className }) => ( ); +const IconPhone: FC> = ({ className }) => ( + +); +const IconBell: FC> = ({ className }) => ( + +); +const IconClockRewind: FC> = ({ className }) => ( + +); +const IconUsers: FC> = ({ className }) => ( + +); -const mainItems: NavItemType[] = [ - { label: "Lead Workspace", href: "/", icon: IconGrid2 }, - { label: "Campaigns", href: "/campaigns", icon: IconBullhorn }, - { label: "Outreach", href: "/outreach", icon: IconCommentDots }, -]; +type NavSection = { + label: string; + items: NavItemType[]; +}; -const insightsItems: NavItemType[] = [ - { label: "Analytics", href: "/analytics", icon: IconChartMixed }, -]; +const getNavSections = (role: string): NavSection[] => { + if (role === 'admin') { + return [ + { + label: 'Overview', + items: [ + { label: 'Team Dashboard', href: '/', icon: IconGrid2 }, + ], + }, + { + label: 'Management', + items: [ + { label: 'Campaigns', href: '/campaigns', icon: IconBullhorn }, + { label: 'Analytics', href: '/analytics', icon: IconChartMixed }, + ], + }, + { + label: 'Admin', + items: [ + { label: 'Integrations', href: '/integrations', icon: IconPlug }, + { label: 'Settings', href: '/settings', icon: IconGear }, + ], + }, + ]; + } -const adminItems: NavItemType[] = [ - { label: "Integrations", href: "/integrations", icon: IconPlug }, - { label: "Settings", href: "/settings", icon: IconGear }, -]; + if (role === 'cc-agent') { + return [ + { + label: 'Call Center', + items: [ + { label: 'Call Desk', href: '/', icon: IconPhone }, + { label: 'Follow-ups', href: '/follow-ups', icon: IconBell }, + { label: 'Call History', href: '/call-history', icon: IconClockRewind }, + ], + }, + ]; + } + + // Executive (default) + return [ + { + label: 'Main', + items: [ + { label: 'Lead Workspace', href: '/', icon: IconGrid2 }, + { label: 'All Leads', href: '/leads', icon: IconUsers }, + { label: 'Campaigns', href: '/campaigns', icon: IconBullhorn }, + { label: 'Outreach', href: '/outreach', icon: IconCommentDots }, + ], + }, + { + label: 'Insights', + items: [ + { label: 'Analytics', href: '/analytics', icon: IconChartMixed }, + ], + }, + ]; +}; + +const getRoleSubtitle = (role: string): string => { + switch (role) { + case 'admin': + return 'Marketing Admin'; + case 'cc-agent': + return 'Call Center Agent'; + default: + return 'Marketing Executive'; + } +}; interface SidebarProps { activeUrl?: string; } export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => { - const { logout, isAdmin: authIsAdmin, user } = useAuth(); + const { logout, user } = useAuth(); const navigate = useNavigate(); const handleSignOut = () => { @@ -65,11 +141,7 @@ export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => { navigate('/login'); }; - const navSections = [ - { label: "Main", items: mainItems }, - { label: "Insights", items: insightsItems }, - ...(authIsAdmin ? [{ label: "Admin", items: adminItems }] : []), - ]; + const navSections = getNavSections(user.role); const content = (