realtimex-crm 0.7.10 → 0.7.11

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realtimex-crm",
3
- "version": "0.7.10",
3
+ "version": "0.7.11",
4
4
  "description": "RealTimeX CRM - A full-featured CRM built with React, shadcn-admin-kit, and Supabase. Fork of Atomic CRM with RealTimeX App SDK integration.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -3,7 +3,7 @@ import {
3
3
  DropdownMenuLabel,
4
4
  DropdownMenuSeparator,
5
5
  } from "@/components/ui/dropdown-menu";
6
- import { Database, User } from "lucide-react";
6
+ import { Database, Settings, User } from "lucide-react";
7
7
  import { CanAccess } from "ra-core";
8
8
  import { Link, matchPath, useLocation } from "react-router";
9
9
  import { RefreshButton } from "@/components/admin/refresh-button";
@@ -17,88 +17,97 @@ const Header = () => {
17
17
  const { darkModeLogo, lightModeLogo, title } = useConfigurationContext();
18
18
  const location = useLocation();
19
19
 
20
- let currentPath: string | boolean = "/";
21
- if (matchPath("/", location.pathname)) {
22
- currentPath = "/";
23
- } else if (matchPath("/contacts/*", location.pathname)) {
24
- currentPath = "/contacts";
25
- } else if (matchPath("/companies/*", location.pathname)) {
26
- currentPath = "/companies";
27
- } else if (matchPath("/deals/*", location.pathname)) {
28
- currentPath = "/deals";
29
- } else {
30
- currentPath = false;
31
- }
20
+ // Simplified path matching logic
21
+ const navPaths = [
22
+ { path: "/", pattern: "/" },
23
+ { path: "/contacts", pattern: "/contacts/*" },
24
+ { path: "/companies", pattern: "/companies/*" },
25
+ { path: "/deals", pattern: "/deals/*" },
26
+ ];
27
+
28
+ const currentPath =
29
+ navPaths.find((nav) => matchPath(nav.pattern, location.pathname))?.path ||
30
+ false;
32
31
 
33
32
  return (
34
- <nav>
35
- <header className="bg-secondary sticky top-0 z-50">
36
- <div className="px-4">
37
- <div className="flex justify-between items-center flex-1">
38
- <Link
33
+ <header className="bg-secondary sticky top-0 z-50 border-b border-border">
34
+ <div className="px-4">
35
+ <div className="flex justify-between items-center flex-1">
36
+ <Logo darkLogo={darkModeLogo} lightLogo={lightModeLogo} title={title} />
37
+
38
+ <nav className="flex" aria-label="Main navigation">
39
+ <NavigationTab
40
+ label="Dashboard"
39
41
  to="/"
40
- className="flex items-center gap-2 text-secondary-foreground no-underline"
41
- >
42
- <img
43
- className="[.light_&]:hidden h-6"
44
- src={darkModeLogo}
45
- alt={title}
46
- />
47
- <img
48
- className="[.dark_&]:hidden h-6"
49
- src={lightModeLogo}
50
- alt={title}
51
- />
52
- <h1 className="text-xl font-semibold">{title}</h1>
53
- </Link>
54
- <div>
55
- <nav className="flex">
56
- <NavigationTab
57
- label="Dashboard"
58
- to="/"
59
- isActive={currentPath === "/"}
60
- />
61
- <NavigationTab
62
- label="Contacts"
63
- to="/contacts"
64
- isActive={currentPath === "/contacts"}
65
- />
66
- <NavigationTab
67
- label="Companies"
68
- to="/companies"
69
- isActive={currentPath === "/companies"}
70
- />
71
- <NavigationTab
72
- label="Deals"
73
- to="/deals"
74
- isActive={currentPath === "/deals"}
75
- />
76
- </nav>
77
- </div>
78
- <div className="flex items-center">
79
- <ThemeModeToggle />
80
- <RefreshButton />
81
- <UserMenu>
82
- <ConfigurationMenu />
83
- <DatabaseMenu />
84
- <CanAccess resource="sales" action="list">
85
- <UsersMenu />
86
- </CanAccess>
87
- <DropdownMenuSeparator />
88
- <DropdownMenuLabel className="font-normal">
89
- <div className="text-xs text-muted-foreground">
90
- Version {import.meta.env.VITE_APP_VERSION}
91
- </div>
92
- </DropdownMenuLabel>
93
- </UserMenu>
94
- </div>
42
+ isActive={currentPath === "/"}
43
+ />
44
+ <NavigationTab
45
+ label="Contacts"
46
+ to="/contacts"
47
+ isActive={currentPath === "/contacts"}
48
+ />
49
+ <NavigationTab
50
+ label="Companies"
51
+ to="/companies"
52
+ isActive={currentPath === "/companies"}
53
+ />
54
+ <NavigationTab
55
+ label="Deals"
56
+ to="/deals"
57
+ isActive={currentPath === "/deals"}
58
+ />
59
+ </nav>
60
+
61
+ <div className="flex items-center">
62
+ <ThemeModeToggle />
63
+ <RefreshButton />
64
+ <UserMenu>
65
+ <ConfigurationMenu />
66
+ <DatabaseMenu />
67
+ <CanAccess resource="sales" action="list">
68
+ <UsersMenu />
69
+ </CanAccess>
70
+ <DropdownMenuSeparator />
71
+ <DropdownMenuLabel className="font-normal">
72
+ <div className="text-xs text-muted-foreground">
73
+ Version {import.meta.env.VITE_APP_VERSION}
74
+ </div>
75
+ </DropdownMenuLabel>
76
+ </UserMenu>
95
77
  </div>
96
78
  </div>
97
- </header>
98
- </nav>
79
+ </div>
80
+ </header>
99
81
  );
100
82
  };
101
83
 
84
+ const Logo = ({
85
+ darkLogo,
86
+ lightLogo,
87
+ title,
88
+ }: {
89
+ darkLogo: string;
90
+ lightLogo: string;
91
+ title: string;
92
+ }) => (
93
+ <Link
94
+ to="/"
95
+ className="flex items-center gap-2 text-secondary-foreground no-underline hover:opacity-80 transition-opacity"
96
+ >
97
+ <img
98
+ className="[.light_&]:hidden h-6"
99
+ src={darkLogo}
100
+ alt={`${title} logo`}
101
+ />
102
+ <img
103
+ className="[.dark_&]:hidden h-6"
104
+ src={lightLogo}
105
+ alt={`${title} logo`}
106
+ />
107
+ <h1 className="text-xl font-semibold">{title}</h1>
108
+ </Link>
109
+ );
110
+
102
111
  const NavigationTab = ({
103
112
  label,
104
113
  to,
@@ -125,7 +134,8 @@ const UsersMenu = () => {
125
134
  return (
126
135
  <DropdownMenuItem asChild onClick={onClose}>
127
136
  <Link to="/sales" className="flex items-center gap-2">
128
- <User /> Users
137
+ <User className="h-4 w-4" />
138
+ Users
129
139
  </Link>
130
140
  </DropdownMenuItem>
131
141
  );
@@ -136,7 +146,7 @@ const ConfigurationMenu = () => {
136
146
  return (
137
147
  <DropdownMenuItem asChild onClick={onClose}>
138
148
  <Link to="/settings" className="flex items-center gap-2">
139
- <User />
149
+ <Settings className="h-4 w-4" />
140
150
  My info
141
151
  </Link>
142
152
  </DropdownMenuItem>
@@ -148,7 +158,7 @@ const DatabaseMenu = () => {
148
158
  return (
149
159
  <DropdownMenuItem asChild onClick={onClose}>
150
160
  <Link to="/database" className="flex items-center gap-2">
151
- <Database />
161
+ <Database className="h-4 w-4" />
152
162
  Database
153
163
  </Link>
154
164
  </DropdownMenuItem>