@crmy/web 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/index.html +23 -0
  2. package/package.json +76 -0
  3. package/postcss.config.js +6 -0
  4. package/public/android-chrome-192x192.png +0 -0
  5. package/public/android-chrome-512x512.png +0 -0
  6. package/public/apple-touch-icon.png +0 -0
  7. package/public/favicon-16x16.png +0 -0
  8. package/public/favicon-32x32.png +0 -0
  9. package/public/favicon.ico +0 -0
  10. package/public/favicon.svg +13 -0
  11. package/public/site.webmanifest +1 -0
  12. package/src/App.tsx +158 -0
  13. package/src/api/client.ts +82 -0
  14. package/src/api/hooks.ts +689 -0
  15. package/src/assets/crmy-logo.png +0 -0
  16. package/src/components/CustomFields.tsx +240 -0
  17. package/src/components/NavLink.tsx +28 -0
  18. package/src/components/crm/AIFab.tsx +37 -0
  19. package/src/components/crm/AccountDrawer.tsx +372 -0
  20. package/src/components/crm/ActivityTimeline.tsx +115 -0
  21. package/src/components/crm/AssignmentDrawer.tsx +396 -0
  22. package/src/components/crm/BriefingPanel.tsx +217 -0
  23. package/src/components/crm/CommandPalette.tsx +254 -0
  24. package/src/components/crm/ContactAvatar.tsx +49 -0
  25. package/src/components/crm/ContactDrawer.tsx +438 -0
  26. package/src/components/crm/ContextPanel.tsx +200 -0
  27. package/src/components/crm/CrmWidgets.tsx +417 -0
  28. package/src/components/crm/DrawerShell.tsx +77 -0
  29. package/src/components/crm/ListToolbar.tsx +252 -0
  30. package/src/components/crm/OpportunityDrawer.tsx +372 -0
  31. package/src/components/crm/PaginationBar.tsx +111 -0
  32. package/src/components/crm/QuickAddDrawer.tsx +652 -0
  33. package/src/components/crm/ShortcutsOverlay.tsx +65 -0
  34. package/src/components/crm/UseCaseDrawer.tsx +454 -0
  35. package/src/components/layout/MobileNav.tsx +49 -0
  36. package/src/components/layout/Sidebar.tsx +157 -0
  37. package/src/components/layout/TopBar.tsx +54 -0
  38. package/src/components/settings/ActorsSettings.tsx +1190 -0
  39. package/src/components/ui/accordion.tsx +52 -0
  40. package/src/components/ui/alert-dialog.tsx +104 -0
  41. package/src/components/ui/alert.tsx +43 -0
  42. package/src/components/ui/aspect-ratio.tsx +5 -0
  43. package/src/components/ui/avatar.tsx +38 -0
  44. package/src/components/ui/badge.tsx +29 -0
  45. package/src/components/ui/breadcrumb.tsx +90 -0
  46. package/src/components/ui/button.tsx +47 -0
  47. package/src/components/ui/calendar.tsx +54 -0
  48. package/src/components/ui/card.tsx +43 -0
  49. package/src/components/ui/carousel.tsx +224 -0
  50. package/src/components/ui/chart.tsx +303 -0
  51. package/src/components/ui/checkbox.tsx +26 -0
  52. package/src/components/ui/collapsible.tsx +9 -0
  53. package/src/components/ui/command.tsx +132 -0
  54. package/src/components/ui/context-menu.tsx +178 -0
  55. package/src/components/ui/date-picker.tsx +313 -0
  56. package/src/components/ui/dialog.tsx +95 -0
  57. package/src/components/ui/drawer.tsx +87 -0
  58. package/src/components/ui/dropdown-menu.tsx +179 -0
  59. package/src/components/ui/form.tsx +129 -0
  60. package/src/components/ui/hover-card.tsx +27 -0
  61. package/src/components/ui/input-otp.tsx +61 -0
  62. package/src/components/ui/input.tsx +22 -0
  63. package/src/components/ui/label.tsx +17 -0
  64. package/src/components/ui/menubar.tsx +207 -0
  65. package/src/components/ui/navigation-menu.tsx +120 -0
  66. package/src/components/ui/pagination.tsx +81 -0
  67. package/src/components/ui/popover.tsx +29 -0
  68. package/src/components/ui/progress.tsx +23 -0
  69. package/src/components/ui/radio-group.tsx +36 -0
  70. package/src/components/ui/resizable.tsx +37 -0
  71. package/src/components/ui/scroll-area.tsx +38 -0
  72. package/src/components/ui/select.tsx +143 -0
  73. package/src/components/ui/separator.tsx +20 -0
  74. package/src/components/ui/sheet.tsx +107 -0
  75. package/src/components/ui/sidebar.tsx +637 -0
  76. package/src/components/ui/skeleton.tsx +7 -0
  77. package/src/components/ui/slider.tsx +23 -0
  78. package/src/components/ui/sonner.tsx +24 -0
  79. package/src/components/ui/switch.tsx +27 -0
  80. package/src/components/ui/table.tsx +72 -0
  81. package/src/components/ui/tabs.tsx +53 -0
  82. package/src/components/ui/textarea.tsx +21 -0
  83. package/src/components/ui/toast.tsx +111 -0
  84. package/src/components/ui/toaster.tsx +24 -0
  85. package/src/components/ui/toggle-group.tsx +49 -0
  86. package/src/components/ui/toggle.tsx +37 -0
  87. package/src/components/ui/tooltip.tsx +28 -0
  88. package/src/components/ui/use-toast.ts +1 -0
  89. package/src/components/ui/utils.ts +9 -0
  90. package/src/contexts/AgentSettingsContext.tsx +24 -0
  91. package/src/hooks/use-mobile.tsx +19 -0
  92. package/src/hooks/use-toast.ts +186 -0
  93. package/src/hooks/useKeyboardShortcuts.ts +95 -0
  94. package/src/hooks/useTheme.ts +24 -0
  95. package/src/index.css +245 -0
  96. package/src/lib/entityColors.ts +18 -0
  97. package/src/lib/stageConfig.ts +32 -0
  98. package/src/lib/utils.ts +6 -0
  99. package/src/main.tsx +25 -0
  100. package/src/pages/Accounts.tsx +205 -0
  101. package/src/pages/Activities.tsx +251 -0
  102. package/src/pages/Agent.tsx +237 -0
  103. package/src/pages/AgentSettings.tsx +544 -0
  104. package/src/pages/Assignments.tsx +750 -0
  105. package/src/pages/Contacts.tsx +200 -0
  106. package/src/pages/Dashboard.tsx +143 -0
  107. package/src/pages/Inbox.tsx +615 -0
  108. package/src/pages/NotFound.tsx +24 -0
  109. package/src/pages/Opportunities.tsx +386 -0
  110. package/src/pages/SearchResults.tsx +49 -0
  111. package/src/pages/Settings.tsx +1884 -0
  112. package/src/pages/UseCases.tsx +396 -0
  113. package/src/pages/auth/Login.tsx +261 -0
  114. package/src/pages/hitl/HITL.tsx +101 -0
  115. package/src/store/appStore.ts +103 -0
  116. package/src/vite-env.d.ts +14 -0
  117. package/tailwind.config.js +121 -0
  118. package/tsconfig.json +24 -0
  119. package/vite.config.ts +27 -0
@@ -0,0 +1,157 @@
1
+ import { Link, useLocation } from 'react-router-dom';
2
+ import { motion, AnimatePresence } from 'framer-motion';
3
+ import {
4
+ LayoutDashboard,
5
+ Users,
6
+ Building2,
7
+ Briefcase,
8
+ FolderKanban,
9
+ Activity,
10
+ Inbox,
11
+ Settings,
12
+ PanelLeftClose,
13
+ PanelLeft,
14
+ } from 'lucide-react';
15
+ import { useAppStore } from '@/store/appStore';
16
+ import { useInboxCounts } from '@/api/hooks';
17
+ import crmyLogo from '@/assets/crmy-logo.png';
18
+ import { ENTITY_COLORS } from '@/lib/entityColors';
19
+
20
+ export { ENTITY_COLORS };
21
+
22
+ const navItems = [
23
+ { icon: LayoutDashboard, label: 'Dashboard', path: '/', color: ENTITY_COLORS.dashboard },
24
+ { icon: Users, label: 'Contacts', path: '/contacts', color: ENTITY_COLORS.contacts },
25
+ { icon: Building2, label: 'Accounts', path: '/accounts', color: ENTITY_COLORS.accounts },
26
+ { icon: Briefcase, label: 'Opportunities',path: '/opportunities', color: ENTITY_COLORS.opportunities },
27
+ { icon: FolderKanban, label: 'Use Cases', path: '/use-cases', color: ENTITY_COLORS.useCases },
28
+ { icon: Activity, label: 'Activities', path: '/activities', color: ENTITY_COLORS.activities },
29
+ { icon: Inbox, label: 'Assignments', path: '/assignments', color: ENTITY_COLORS.inbox },
30
+ ];
31
+
32
+ const bottomItems = [
33
+ { icon: Settings, label: 'Settings', path: '/settings' },
34
+ ];
35
+
36
+ export function Sidebar() {
37
+ const location = useLocation();
38
+ const { sidebarExpanded, setSidebarExpanded } = useAppStore();
39
+ const { total: inboxCount } = useInboxCounts();
40
+
41
+ return (
42
+ <motion.aside
43
+ className="hidden md:flex flex-col h-screen bg-sidebar border-r border-sidebar-border flex-shrink-0"
44
+ animate={{ width: sidebarExpanded ? 220 : 56 }}
45
+ transition={{ duration: 0.2, ease: 'easeInOut' }}
46
+ >
47
+ {/* Logo */}
48
+ <div className="flex items-center h-14 px-3 gap-2 border-b border-sidebar-border">
49
+ <img src={crmyLogo} alt="CRMy" className="w-8 h-8 flex-shrink-0 rounded-lg" />
50
+ <AnimatePresence>
51
+ {sidebarExpanded && (
52
+ <motion.span
53
+ initial={{ opacity: 0, width: 0 }}
54
+ animate={{ opacity: 1, width: 'auto' }}
55
+ exit={{ opacity: 0, width: 0 }}
56
+ className="font-brand font-bold text-lg text-sidebar-accent-foreground whitespace-nowrap overflow-hidden"
57
+ >
58
+ CRMy
59
+ </motion.span>
60
+ )}
61
+ </AnimatePresence>
62
+ </div>
63
+
64
+ {/* Nav */}
65
+ <nav className="flex-1 flex flex-col py-3 gap-1 px-2">
66
+ {navItems.map((item) => {
67
+ const active = item.path === '/' ? location.pathname === '/' : location.pathname.startsWith(item.path);
68
+ return (
69
+ <Link
70
+ key={item.path}
71
+ to={item.path}
72
+ className={`group relative flex items-center gap-3 rounded-xl px-2.5 py-2.5 text-sm transition-all
73
+ ${active
74
+ ? `${item.color.bg} ${item.color.text}`
75
+ : 'text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground'
76
+ }`}
77
+ title={!sidebarExpanded ? item.label : undefined}
78
+ >
79
+ <item.icon className="w-5 h-5 flex-shrink-0" />
80
+ <AnimatePresence>
81
+ {sidebarExpanded && (
82
+ <motion.span
83
+ initial={{ opacity: 0, width: 0 }}
84
+ animate={{ opacity: 1, width: 'auto' }}
85
+ exit={{ opacity: 0, width: 0 }}
86
+ className="whitespace-nowrap overflow-hidden font-medium flex-1"
87
+ >
88
+ {item.label}
89
+ </motion.span>
90
+ )}
91
+ </AnimatePresence>
92
+ {item.path === '/assignments' && inboxCount > 0 && (
93
+ <span className={`flex-shrink-0 min-w-[18px] h-[18px] px-1 flex items-center justify-center rounded-full bg-destructive text-white text-[10px] font-bold ${sidebarExpanded ? '' : 'absolute -top-1 -right-1'}`}>
94
+ {inboxCount > 99 ? '99+' : inboxCount}
95
+ </span>
96
+ )}
97
+ {active && (
98
+ <motion.div
99
+ layoutId="sidebar-active"
100
+ className={`absolute -left-2 top-2 w-[3px] h-6 ${item.color.bar} rounded-r-full`}
101
+ transition={{ type: 'spring', damping: 25, stiffness: 300 }}
102
+ />
103
+ )}
104
+ {/* Tooltip when collapsed */}
105
+ {!sidebarExpanded && (
106
+ <div className="absolute left-full ml-2 px-2.5 py-1.5 rounded-lg bg-popover text-popover-foreground text-xs shadow-lg opacity-0 group-hover:opacity-100 pointer-events-none transition-opacity whitespace-nowrap z-50 font-medium">
107
+ {item.label}
108
+ </div>
109
+ )}
110
+ </Link>
111
+ );
112
+ })}
113
+ </nav>
114
+
115
+ {/* Bottom */}
116
+ <div className="flex flex-col gap-1 px-2 pb-3 border-t border-sidebar-border pt-3">
117
+ {bottomItems.map((item) => {
118
+ const active = location.pathname.startsWith(item.path);
119
+ return (
120
+ <Link
121
+ key={item.path}
122
+ to={item.path}
123
+ className={`flex items-center gap-3 rounded-xl px-2.5 py-2.5 text-sm transition-all
124
+ ${active
125
+ ? 'bg-sidebar-primary/15 text-sidebar-primary'
126
+ : 'text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground'
127
+ }`}
128
+ title={!sidebarExpanded ? item.label : undefined}
129
+ >
130
+ <item.icon className="w-5 h-5 flex-shrink-0" />
131
+ <AnimatePresence>
132
+ {sidebarExpanded && (
133
+ <motion.span
134
+ initial={{ opacity: 0, width: 0 }}
135
+ animate={{ opacity: 1, width: 'auto' }}
136
+ exit={{ opacity: 0, width: 0 }}
137
+ className="whitespace-nowrap overflow-hidden font-medium"
138
+ >
139
+ {item.label}
140
+ </motion.span>
141
+ )}
142
+ </AnimatePresence>
143
+ </Link>
144
+ );
145
+ })}
146
+
147
+ {/* Toggle button */}
148
+ <button
149
+ onClick={() => setSidebarExpanded(!sidebarExpanded)}
150
+ className="flex items-center justify-center w-8 h-8 rounded-lg text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground mx-auto mt-1 transition-colors"
151
+ >
152
+ {sidebarExpanded ? <PanelLeftClose className="w-4 h-4" /> : <PanelLeft className="w-4 h-4" />}
153
+ </button>
154
+ </div>
155
+ </motion.aside>
156
+ );
157
+ }
@@ -0,0 +1,54 @@
1
+ import { Search, Command, Sun, Moon, LogOut } from 'lucide-react';
2
+ import { useAppStore } from '@/store/appStore';
3
+ import { useTheme } from '@/hooks/useTheme';
4
+ import { useNavigate } from 'react-router-dom';
5
+ import { clearToken } from '@/api/client';
6
+
7
+ interface TopBarProps {
8
+ title: string;
9
+ children?: React.ReactNode;
10
+ }
11
+
12
+ export function TopBar({ title, children }: TopBarProps) {
13
+ const { setCommandPaletteOpen } = useAppStore();
14
+ const { theme, toggle } = useTheme();
15
+ const navigate = useNavigate();
16
+
17
+ const handleLogout = () => {
18
+ clearToken();
19
+ navigate('/login');
20
+ };
21
+
22
+ return (
23
+ <header className="sticky top-0 z-30 flex items-center justify-between h-14 px-4 md:px-6 border-b border-border bg-background/80 backdrop-blur-md gap-2">
24
+ <h1 className="font-display font-bold text-lg text-foreground truncate hidden md:block">{title}</h1>
25
+ <div className="flex items-center gap-1.5 md:ml-auto w-full md:w-auto">
26
+ {children}
27
+ <button
28
+ onClick={toggle}
29
+ className="p-2 rounded-xl text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
30
+ title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
31
+ >
32
+ {theme === 'dark' ? <Sun className="w-4 h-4" /> : <Moon className="w-4 h-4" />}
33
+ </button>
34
+ <button
35
+ onClick={() => setCommandPaletteOpen(true)}
36
+ className="flex items-center gap-2 flex-1 md:flex-none px-3 py-1.5 rounded-xl bg-muted text-muted-foreground text-sm hover:bg-muted/80 transition-colors min-h-[36px] md:min-h-0"
37
+ >
38
+ <Search className="w-4 h-4 md:w-3.5 md:h-3.5 flex-shrink-0" />
39
+ <span className="text-left flex-1 md:flex-none">Search...</span>
40
+ <kbd className="hidden md:inline-flex items-center gap-0.5 text-xs font-mono bg-background px-1.5 py-0.5 rounded-md border border-border">
41
+ <Command className="w-3 h-3" />K
42
+ </kbd>
43
+ </button>
44
+ <button
45
+ onClick={handleLogout}
46
+ className="p-2 rounded-xl text-muted-foreground hover:text-destructive hover:bg-muted transition-colors"
47
+ title="Sign out"
48
+ >
49
+ <LogOut className="w-4 h-4" />
50
+ </button>
51
+ </div>
52
+ </header>
53
+ );
54
+ }