@salesforce/webapp-template-app-react-sample-b2x-experimental 1.84.0 → 1.85.0
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/dist/.a4drules/skills/{webapp-react-add-component → webapp-react}/SKILL.md +5 -3
- package/dist/.a4drules/skills/{webapp-react-add-component → webapp-react}/implementation/header-footer.md +8 -0
- package/dist/.a4drules/skills/{webapp-react-add-component → webapp-react}/implementation/page.md +8 -7
- package/dist/.a4drules/skills/webapp-ui-ux/SKILL.md +11 -8
- package/dist/.a4drules/webapp-react.md +54 -0
- package/dist/CHANGELOG.md +16 -0
- package/dist/README.md +24 -0
- package/dist/force-app/main/default/data/Property_Image__c.json +1 -1
- package/dist/force-app/main/default/data/Property_Listing__c.json +1 -1
- package/dist/force-app/main/default/data/prepare-import-unique-fields.js +85 -0
- package/dist/force-app/main/default/permissionsets/Property_Management_Access.permissionset-meta.xml +0 -7
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/index.html +6 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/package.json +3 -3
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/applicationApi.ts +9 -9
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/graphql-operations-types.ts +296 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/graphqlClient.ts +12 -7
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/maintenanceRequestApi.ts +50 -38
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/propertyDetailGraphQL.ts +50 -102
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/propertyListingGraphQL.ts +211 -43
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/userApi.ts +43 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/appLayout.tsx +9 -208
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/appliances.svg +13 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/electrical.svg +39 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/hvac.svg +78 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/pest.svg +5 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/plumbing.svg +7 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/zen-logo.svg +5 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/MaintenanceRequestIcon.tsx +46 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/NavMenu.tsx +53 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/PropertyListingCard.tsx +55 -58
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/PropertyMap.tsx +93 -11
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/PropertySearchFilters.tsx +315 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/StatusBadge.tsx +36 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/TopBar.tsx +107 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyAddresses.ts +2 -2
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyListingAmenities.ts +55 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyListingPriceRange.ts +64 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyListingSearch.ts +14 -5
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyMapMarkers.ts +54 -11
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyPrimaryImages.ts +1 -1
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Application.tsx +42 -39
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Contact.tsx +10 -10
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Dashboard.tsx +64 -91
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/HelpCenter.tsx +1 -1
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Home.tsx +19 -9
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Maintenance.tsx +79 -100
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/NotFound.tsx +1 -1
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyDetails.tsx +62 -47
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyListings.tsx +3 -3
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertySearch.tsx +230 -34
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/routes.tsx +10 -1
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/styles/global.css +64 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/geocode.ts +30 -5
- package/dist/package.json +1 -1
- package/dist/setup-cli.mjs +271 -0
- package/package.json +1 -1
- /package/dist/.a4drules/skills/{webapp-react-add-component → webapp-react}/implementation/component.md +0 -0
|
@@ -1,215 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { cn } from "./lib/utils";
|
|
5
|
-
import { useAuth } from "./features/authentication/context/AuthContext";
|
|
6
|
-
import {
|
|
7
|
-
Home,
|
|
8
|
-
Search,
|
|
9
|
-
BarChart3,
|
|
10
|
-
Wrench,
|
|
11
|
-
Menu,
|
|
12
|
-
Heart,
|
|
13
|
-
Bell,
|
|
14
|
-
Building2,
|
|
15
|
-
Phone,
|
|
16
|
-
User,
|
|
17
|
-
LogOut,
|
|
18
|
-
ChevronDown,
|
|
19
|
-
} from "lucide-react";
|
|
1
|
+
import { Outlet } from "react-router";
|
|
2
|
+
import { TopBar } from "@/components/TopBar";
|
|
3
|
+
import { NavMenu } from "@/components/NavMenu";
|
|
20
4
|
|
|
21
|
-
|
|
22
|
-
const FLOAT_INSET = 20;
|
|
23
|
-
const FLOAT_GAP = 20;
|
|
24
|
-
|
|
25
|
-
const HEADER_BUTTON =
|
|
26
|
-
"cursor-pointer text-primary-foreground transition-colors duration-200 hover:bg-primary-foreground/20";
|
|
27
|
-
|
|
28
|
-
interface SidebarLinkProps {
|
|
29
|
-
to: string;
|
|
30
|
-
label: string;
|
|
31
|
-
icon: ComponentType<{ className?: string }>;
|
|
32
|
-
end?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function SidebarLink({ to, label, icon: Icon, end }: SidebarLinkProps) {
|
|
36
|
-
return (
|
|
37
|
-
<NavLink
|
|
38
|
-
to={to}
|
|
39
|
-
end={end}
|
|
40
|
-
className={({ isActive }) =>
|
|
41
|
-
cn(
|
|
42
|
-
"flex min-h-11 w-full flex-shrink-0 cursor-pointer items-center justify-start gap-3 rounded-xl px-3 py-2 text-muted-foreground no-underline transition-colors duration-200",
|
|
43
|
-
isActive && "bg-primary/15 text-primary font-medium",
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
aria-label={label}
|
|
47
|
-
>
|
|
48
|
-
<Icon className="size-[22px] shrink-0" aria-hidden />
|
|
49
|
-
<span className="text-sm font-medium">{label}</span>
|
|
50
|
-
</NavLink>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function UserMenu() {
|
|
55
|
-
const [open, setOpen] = useState(false);
|
|
56
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
57
|
-
const navigate = useNavigate();
|
|
58
|
-
const { user, logout } = useAuth();
|
|
59
|
-
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
if (!open) return;
|
|
62
|
-
function handleClickOutside(e: MouseEvent) {
|
|
63
|
-
if (ref.current && !ref.current.contains(e.target as Node)) {
|
|
64
|
-
setOpen(false);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
68
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
69
|
-
}, [open]);
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<div className="relative" ref={ref}>
|
|
73
|
-
<button
|
|
74
|
-
type="button"
|
|
75
|
-
onClick={() => setOpen((o) => !o)}
|
|
76
|
-
className={cn(
|
|
77
|
-
"flex items-center gap-1.5 rounded-md border-none bg-transparent px-2 py-1.5 text-sm font-medium",
|
|
78
|
-
HEADER_BUTTON,
|
|
79
|
-
)}
|
|
80
|
-
aria-haspopup="true"
|
|
81
|
-
aria-expanded={open}
|
|
82
|
-
>
|
|
83
|
-
{user!.name}
|
|
84
|
-
<ChevronDown
|
|
85
|
-
className={cn("size-4 transition-transform duration-200", open && "rotate-180")}
|
|
86
|
-
aria-hidden
|
|
87
|
-
/>
|
|
88
|
-
</button>
|
|
89
|
-
{open && (
|
|
90
|
-
<div
|
|
91
|
-
className="absolute right-0 top-full z-50 mt-1.5 w-44 overflow-hidden rounded-lg border border-border bg-card py-1 shadow-lg"
|
|
92
|
-
role="menu"
|
|
93
|
-
>
|
|
94
|
-
<button
|
|
95
|
-
type="button"
|
|
96
|
-
role="menuitem"
|
|
97
|
-
className="flex w-full cursor-pointer items-center gap-2 border-none bg-transparent px-3 py-2 text-left text-sm text-foreground transition-colors duration-150 hover:bg-muted"
|
|
98
|
-
onClick={() => {
|
|
99
|
-
setOpen(false);
|
|
100
|
-
navigate("/profile");
|
|
101
|
-
}}
|
|
102
|
-
>
|
|
103
|
-
<User className="size-4" aria-hidden />
|
|
104
|
-
Edit Profile
|
|
105
|
-
</button>
|
|
106
|
-
<button
|
|
107
|
-
type="button"
|
|
108
|
-
role="menuitem"
|
|
109
|
-
className="flex w-full cursor-pointer items-center gap-2 border-none bg-transparent px-3 py-2 text-left text-sm text-destructive transition-colors duration-150 hover:bg-destructive/10"
|
|
110
|
-
onClick={() => {
|
|
111
|
-
setOpen(false);
|
|
112
|
-
logout();
|
|
113
|
-
}}
|
|
114
|
-
>
|
|
115
|
-
<LogOut className="size-4" aria-hidden />
|
|
116
|
-
Log Out
|
|
117
|
-
</button>
|
|
118
|
-
</div>
|
|
119
|
-
)}
|
|
120
|
-
</div>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function Sidebar({ isAuthenticated }: { isAuthenticated: boolean }) {
|
|
5
|
+
export default function AppLayout() {
|
|
125
6
|
return (
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
aria-label="Main navigation"
|
|
129
|
-
>
|
|
130
|
-
<SidebarLink to="/" label="Home" icon={Home} end />
|
|
131
|
-
<SidebarLink to="/properties" label="Property Search" icon={Search} />
|
|
132
|
-
{isAuthenticated && (
|
|
133
|
-
<>
|
|
134
|
-
<SidebarLink to="/dashboard" label="Dashboard" icon={BarChart3} />
|
|
135
|
-
<SidebarLink to="/maintenance" label="Maintenance" icon={Wrench} />
|
|
136
|
-
</>
|
|
137
|
-
)}
|
|
138
|
-
<SidebarLink to="/contact" label="Contact" icon={Phone} />
|
|
139
|
-
</nav>
|
|
140
|
-
);
|
|
141
|
-
}
|
|
7
|
+
<div className="flex h-screen flex-col">
|
|
8
|
+
<TopBar />
|
|
142
9
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const { isAuthenticated, loading, user } = useAuth();
|
|
10
|
+
<div className="flex flex-1 overflow-hidden">
|
|
11
|
+
<NavMenu />
|
|
146
12
|
|
|
147
|
-
|
|
148
|
-
<div className="flex min-h-screen flex-col">
|
|
149
|
-
<header
|
|
150
|
-
className="flex shrink-0 items-center justify-between bg-primary px-6 py-3 text-primary-foreground"
|
|
151
|
-
role="banner"
|
|
152
|
-
>
|
|
153
|
-
<div className="flex items-center gap-3">
|
|
154
|
-
<Button
|
|
155
|
-
type="button"
|
|
156
|
-
variant="ghost"
|
|
157
|
-
size="icon"
|
|
158
|
-
className={cn("min-h-11 min-w-11", HEADER_BUTTON)}
|
|
159
|
-
aria-label={navHidden ? "Show menu" : "Hide menu"}
|
|
160
|
-
onClick={() => setNavHidden((h) => !h)}
|
|
161
|
-
>
|
|
162
|
-
<Menu className="size-6" aria-hidden />
|
|
163
|
-
</Button>
|
|
164
|
-
<div className="flex size-8 items-center justify-center">
|
|
165
|
-
<Building2 className="size-7" aria-hidden />
|
|
166
|
-
</div>
|
|
167
|
-
<span className="text-xl font-semibold tracking-wide">ZENLEASE</span>
|
|
168
|
-
</div>
|
|
169
|
-
<div className="flex items-center gap-4">
|
|
170
|
-
<Button
|
|
171
|
-
type="button"
|
|
172
|
-
variant="ghost"
|
|
173
|
-
size="icon"
|
|
174
|
-
className={HEADER_BUTTON}
|
|
175
|
-
aria-label="Favorites"
|
|
176
|
-
>
|
|
177
|
-
<Heart className="size-5" aria-hidden />
|
|
178
|
-
</Button>
|
|
179
|
-
<Button
|
|
180
|
-
type="button"
|
|
181
|
-
variant="ghost"
|
|
182
|
-
size="icon"
|
|
183
|
-
className={HEADER_BUTTON}
|
|
184
|
-
aria-label="Notifications"
|
|
185
|
-
>
|
|
186
|
-
<Bell className="size-5" aria-hidden />
|
|
187
|
-
</Button>
|
|
188
|
-
{loading ? (
|
|
189
|
-
<span className="text-sm font-medium text-primary-foreground/70" aria-hidden>
|
|
190
|
-
…
|
|
191
|
-
</span>
|
|
192
|
-
) : isAuthenticated && user ? (
|
|
193
|
-
<UserMenu />
|
|
194
|
-
) : (
|
|
195
|
-
<NavLink
|
|
196
|
-
to="/login"
|
|
197
|
-
className="rounded-md px-2 py-1.5 text-sm font-medium text-primary-foreground no-underline transition-colors duration-200 hover:bg-primary-foreground/20 hover:text-primary-foreground/90"
|
|
198
|
-
>
|
|
199
|
-
Sign Up / Sign In
|
|
200
|
-
</NavLink>
|
|
201
|
-
)}
|
|
202
|
-
</div>
|
|
203
|
-
</header>
|
|
204
|
-
<div className="relative flex min-h-0 flex-1">
|
|
205
|
-
{!navHidden && <Sidebar isAuthenticated={isAuthenticated} />}
|
|
206
|
-
<main
|
|
207
|
-
className="min-h-full flex-1 overflow-auto bg-muted/40 p-6 transition-[margin-left] duration-200 ease-[cubic-bezier(0.4,0,0.2,1)]"
|
|
208
|
-
style={{
|
|
209
|
-
marginLeft: navHidden ? 0 : FLOAT_INSET + SIDEBAR_WIDTH + FLOAT_GAP,
|
|
210
|
-
}}
|
|
211
|
-
role="main"
|
|
212
|
-
>
|
|
13
|
+
<main className="flex-1 overflow-auto bg-gray-50 p-8" role="main">
|
|
213
14
|
<Outlet />
|
|
214
15
|
</main>
|
|
215
16
|
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='iso-8859-1'?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="currentColor" height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 463 463" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 463 463">
|
|
4
|
+
<g>
|
|
5
|
+
<path d="m367.5,0h-272c-21.78,0-39.5,17.72-39.5,39.5v368c0,10.336 6.71,19.128 16,22.266v9.734c0,12.958 10.542,23.5 23.5,23.5h272c12.958,0 23.5-10.542 23.5-23.5v-9.734c9.29-3.138 16-11.93 16-22.266v-368c0-21.78-17.72-39.5-39.5-39.5zm-272,15h272c13.51,0 24.5,10.991 24.5,24.5v56.5h-321v-56.5c0-13.509 10.99-24.5 24.5-24.5zm272,433h-272c-4.687,0-8.5-3.813-8.5-8.5v-8.5h289v8.5c0,4.687-3.813,8.5-8.5,8.5zm16-32h-304c-4.687,0-8.5-3.813-8.5-8.5v-296.5h321v296.5c0,4.687-3.813,8.5-8.5,8.5z"/>
|
|
6
|
+
<path d="M231.5,136C161.196,136,104,193.196,104,263.5S161.196,391,231.5,391S359,333.804,359,263.5S301.804,136,231.5,136z M231.5,376C169.468,376,119,325.533,119,263.5S169.468,151,231.5,151S344,201.467,344,263.5S293.532,376,231.5,376z"/>
|
|
7
|
+
<path d="m279.5,79c12.958,0 23.5-10.542 23.5-23.5s-10.542-23.5-23.5-23.5-23.5,10.542-23.5,23.5 10.542,23.5 23.5,23.5zm0-32c4.687,0 8.5,3.813 8.5,8.5s-3.813,8.5-8.5,8.5-8.5-3.813-8.5-8.5 3.813-8.5 8.5-8.5z"/>
|
|
8
|
+
<path d="m343.5,79c12.958,0 23.5-10.542 23.5-23.5s-10.542-23.5-23.5-23.5-23.5,10.542-23.5,23.5 10.542,23.5 23.5,23.5zm0-32c4.687,0 8.5,3.813 8.5,8.5s-3.813,8.5-8.5,8.5-8.5-3.813-8.5-8.5 3.813-8.5 8.5-8.5z"/>
|
|
9
|
+
<path d="m111.5,79h104c8.547,0 15.5-6.953 15.5-15.5v-16c0-8.547-6.953-15.5-15.5-15.5h-104c-8.547,0-15.5,6.953-15.5,15.5v16c0,8.547 6.953,15.5 15.5,15.5zm-.5-31.5c0-0.276 0.225-0.5 0.5-0.5h104c0.275,0 0.5,0.224 0.5,0.5v16c0,0.276-0.225,0.5-0.5,0.5h-104c-0.275,0-0.5-0.224-0.5-0.5v-16z"/>
|
|
10
|
+
<path d="m231.5,168c-52.659,0-95.5,42.841-95.5,95.5s42.841,95.5 95.5,95.5 95.5-42.841 95.5-95.5-42.841-95.5-95.5-95.5zm0,176c-44.388,0-80.5-36.112-80.5-80.5s36.112-80.5 80.5-80.5 80.5,36.112 80.5,80.5-36.112,80.5-80.5,80.5z"/>
|
|
11
|
+
<path d="m231.5,200c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5 7.5,7.5c26.743,0 48.5,21.757 48.5,48.5 0,4.142 3.357,7.5 7.5,7.5s7.5-3.358 7.5-7.5c0-35.014-28.486-63.5-63.5-63.5z"/>
|
|
12
|
+
</g>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="currentColor" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve">
|
|
4
|
+
<g>
|
|
5
|
+
<g>
|
|
6
|
+
<path d="M408.49,193.586c-38.366-34.559-88.566-54.508-142.291-56.752V10.199C266.199,4.566,261.633,0,256,0
|
|
7
|
+
c-5.633,0-10.199,4.566-10.199,10.199v126.634c-53.725,2.245-103.925,22.193-142.291,56.752
|
|
8
|
+
c-41.083,37.008-63.708,86.297-63.708,138.79c0,5.633,4.566,10.199,10.199,10.199h118.284
|
|
9
|
+
c5.513,39.678,42.747,70.459,87.715,70.459s82.202-30.781,87.715-70.459h118.284c5.633,0,10.199-4.566,10.199-10.199
|
|
10
|
+
C472.199,279.883,449.573,230.594,408.49,193.586z M256,392.636c-33.583,0-61.56-21.674-67.047-50.061h134.093
|
|
11
|
+
C317.56,370.961,289.583,392.636,256,392.636z M60.527,322.177c5.917-91.967,91.33-165.163,195.473-165.163
|
|
12
|
+
s189.556,73.196,195.473,165.163H60.527z"/>
|
|
13
|
+
</g>
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<g>
|
|
17
|
+
<path d="M254.924,429.21c-5.633,0-10.199,4.566-10.199,10.199v62.392c0,5.633,4.566,10.199,10.199,10.199
|
|
18
|
+
c5.633,0,10.199-4.566,10.199-10.199v-62.392C265.123,433.776,260.557,429.21,254.924,429.21z"/>
|
|
19
|
+
</g>
|
|
20
|
+
</g>
|
|
21
|
+
<g>
|
|
22
|
+
<g>
|
|
23
|
+
<path d="M381.687,445.438l-2.481-2.482c-3.983-3.983-10.441-3.983-14.425,0c-3.983,3.983-3.983,10.441,0,14.425l2.482,2.482
|
|
24
|
+
c1.992,1.992,4.602,2.987,7.212,2.987s5.221-0.995,7.212-2.987C385.67,455.88,385.67,449.422,381.687,445.438z"/>
|
|
25
|
+
</g>
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<g>
|
|
29
|
+
<path d="M356.8,420.55l-19.229-19.23c-3.983-3.983-10.441-3.983-14.425,0c-3.983,3.983-3.983,10.441,0,14.425l19.23,19.23
|
|
30
|
+
c1.992,1.992,4.602,2.987,7.212,2.987s5.221-0.995,7.212-2.987C360.783,430.992,360.783,424.534,356.8,420.55z"/>
|
|
31
|
+
</g>
|
|
32
|
+
</g>
|
|
33
|
+
<g>
|
|
34
|
+
<g>
|
|
35
|
+
<path d="M185.441,404.363c-3.982-3.983-10.44-3.983-14.424,0L126.9,448.48c-3.983,3.983-3.983,10.441,0,14.425
|
|
36
|
+
c1.992,1.992,4.602,2.987,7.212,2.987s5.221-0.995,7.212-2.987l44.118-44.118C189.424,414.805,189.424,408.347,185.441,404.363z"/>
|
|
37
|
+
</g>
|
|
38
|
+
</g>
|
|
39
|
+
</svg>
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/hvac.svg
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="currentColor" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve">
|
|
4
|
+
<g>
|
|
5
|
+
<g>
|
|
6
|
+
<path d="M482.815,93.937H29.185C13.093,93.937,0,107.029,0,123.123v265.755c0,16.093,13.093,29.186,29.185,29.186h453.63
|
|
7
|
+
c16.092,0,29.185-13.093,29.185-29.186V123.123C512,107.029,498.907,93.937,482.815,93.937z M482.815,397.665H29.185
|
|
8
|
+
c-4.845,0-8.787-3.942-8.787-8.788V123.123c0-4.845,3.942-8.788,8.787-8.788h453.63c4.845,0,8.787,3.942,8.787,8.788v265.755h0
|
|
9
|
+
C491.602,393.722,487.66,397.665,482.815,397.665z"/>
|
|
10
|
+
</g>
|
|
11
|
+
</g>
|
|
12
|
+
<g>
|
|
13
|
+
<g>
|
|
14
|
+
<path d="M165.227,138.709c-64.674,0-117.291,52.617-117.291,117.291s52.617,117.291,117.291,117.291S282.518,320.674,282.518,256
|
|
15
|
+
S229.901,138.709,165.227,138.709z M165.227,352.892c-53.427,0-96.892-43.466-96.892-96.892c0-53.426,43.466-96.892,96.892-96.892
|
|
16
|
+
c53.426,0,96.892,43.466,96.892,96.892C262.12,309.427,218.654,352.892,165.227,352.892z"/>
|
|
17
|
+
</g>
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<g>
|
|
21
|
+
<path d="M252.137,262.786c-4.959-7.802-13.735-11.878-22.893-10.65c-11.264,1.517-22.867,0.816-33.891-2.002
|
|
22
|
+
c-1.243-5.677-4.005-10.79-7.84-14.892c1.022-2.523,2.468-4.881,4.257-6.924c7.147-8.16,11.081-18.629,11.081-29.475
|
|
23
|
+
c0-16.945-13.258-30.862-30.184-31.684l-24.291-1.179c-9.244-0.453-17.627,4.364-21.904,12.56
|
|
24
|
+
c-4.276,8.196-3.424,17.833,2.224,25.151c6.784,8.789,11.772,18.574,14.875,29.144c-4.704,4.049-8.212,9.444-9.922,15.585
|
|
25
|
+
c-2.285,0.198-4.6,0.078-6.844-0.367c-10.64-2.107-21.672-0.283-31.066,5.141c-14.675,8.472-20.099,26.913-12.347,41.981
|
|
26
|
+
l11.124,21.627c4.07,7.911,11.968,12.71,20.788,12.71c0.346,0,0.694-0.007,1.041-0.021c9.236-0.395,17.155-5.951,20.67-14.502
|
|
27
|
+
c4.25-10.345,10.288-19.619,17.974-27.634c2.942,0.902,6.063,1.389,9.298,1.389c2.924,0,5.754-0.405,8.446-1.147
|
|
28
|
+
c1.567,2.072,2.812,4.394,3.646,6.848c3.495,10.269,10.593,18.911,19.985,24.333c4.998,2.885,10.461,4.264,15.855,4.264
|
|
29
|
+
c10.443,0,20.627-5.167,26.675-14.561l13.167-20.447C257.068,280.262,257.096,270.587,252.137,262.786z M118.148,307.238
|
|
30
|
+
c-0.608,1.481-1.788,1.836-2.67,1.874c-0.882,0.035-2.089-0.215-2.821-1.639l-11.124-21.626
|
|
31
|
+
c-2.767-5.379-0.83-11.962,4.407-14.986c5.111-2.951,11.115-3.943,16.901-2.798c3.914,0.775,7.946,1.007,11.937,0.719
|
|
32
|
+
c0.934,2.318,2.133,4.501,3.56,6.513C129.792,284.674,123.018,295.385,118.148,307.238z M164.289,268.347
|
|
33
|
+
c-6.29,0-11.408-5.118-11.408-11.408s5.118-11.407,11.408-11.407s11.407,5.117,11.407,11.407S170.579,268.347,164.289,268.347z
|
|
34
|
+
M176.422,214.879c-2.8,3.198-5.136,6.819-6.93,10.688c-1.694-0.28-3.431-0.432-5.204-0.432c-0.578,0-1.151,0.017-1.723,0.048
|
|
35
|
+
c-3.845-12.279-9.783-23.67-17.721-33.954c-0.978-1.267-0.697-2.466-0.288-3.25c0.409-0.784,1.206-1.696,2.829-1.623l24.291,1.179
|
|
36
|
+
c6.042,0.294,10.774,5.261,10.774,11.309C182.452,204.744,180.31,210.439,176.422,214.879z M234.912,276.991l-13.168,20.448
|
|
37
|
+
c-3.273,5.085-9.942,6.699-15.181,3.676c-5.111-2.951-8.972-7.652-10.873-13.239c-1.421-4.174-3.49-8.141-6.072-11.73
|
|
38
|
+
c1.318-1.734,2.462-3.605,3.407-5.59c12.734,2.905,26.019,3.537,38.94,1.798c1.581-0.216,2.482,0.627,2.957,1.374
|
|
39
|
+
C235.396,274.474,235.779,275.645,234.912,276.991z"/>
|
|
40
|
+
</g>
|
|
41
|
+
</g>
|
|
42
|
+
<g>
|
|
43
|
+
<g>
|
|
44
|
+
<path d="M456.924,141.769H321.275c-5.632,0-10.199,4.566-10.199,10.199s4.567,10.199,10.199,10.199h135.649
|
|
45
|
+
c5.632,0,10.199-4.566,10.199-10.199S462.556,141.769,456.924,141.769z"/>
|
|
46
|
+
</g>
|
|
47
|
+
</g>
|
|
48
|
+
<g>
|
|
49
|
+
<g>
|
|
50
|
+
<path d="M456.924,193.785H321.275c-5.632,0-10.199,4.566-10.199,10.199s4.567,10.199,10.199,10.199h135.649
|
|
51
|
+
c5.632,0,10.199-4.566,10.199-10.199S462.556,193.785,456.924,193.785z"/>
|
|
52
|
+
</g>
|
|
53
|
+
</g>
|
|
54
|
+
<g>
|
|
55
|
+
<g>
|
|
56
|
+
<path d="M456.924,245.801H321.275c-5.632,0-10.199,4.566-10.199,10.199c0,5.633,4.567,10.199,10.199,10.199h135.649
|
|
57
|
+
c5.632,0,10.199-4.566,10.199-10.199C467.124,250.367,462.556,245.801,456.924,245.801z"/>
|
|
58
|
+
</g>
|
|
59
|
+
</g>
|
|
60
|
+
<g>
|
|
61
|
+
<g>
|
|
62
|
+
<path d="M456.924,297.817H321.275c-5.632,0-10.199,4.566-10.199,10.199c0,5.633,4.567,10.199,10.199,10.199h135.649
|
|
63
|
+
c5.632,0,10.199-4.566,10.199-10.199C467.124,302.383,462.556,297.817,456.924,297.817z"/>
|
|
64
|
+
</g>
|
|
65
|
+
</g>
|
|
66
|
+
<g>
|
|
67
|
+
<g>
|
|
68
|
+
<path d="M416.128,349.833h-94.853c-5.632,0-10.199,4.566-10.199,10.199c0,5.633,4.567,10.199,10.199,10.199h94.853
|
|
69
|
+
c5.632,0,10.199-4.566,10.199-10.199C426.327,354.399,421.76,349.833,416.128,349.833z"/>
|
|
70
|
+
</g>
|
|
71
|
+
</g>
|
|
72
|
+
<g>
|
|
73
|
+
<g>
|
|
74
|
+
<path d="M456.924,349.833h-5.1c-5.632,0-10.199,4.566-10.199,10.199c0,5.633,4.567,10.199,10.199,10.199h5.1
|
|
75
|
+
c5.632,0,10.199-4.566,10.199-10.199C467.124,354.399,462.556,349.833,456.924,349.833z"/>
|
|
76
|
+
</g>
|
|
77
|
+
</g>
|
|
78
|
+
</svg>
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/pest.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='iso-8859-1'?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="currentColor" height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 463 463" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 463 463">
|
|
4
|
+
<path d="m355.256,145.405c-34.083-19.724-60.085-50.573-73.704-87.254 4.229-2.018 8.958-3.151 13.947-3.151h15.971c0.008,0 0.015,0.002 0.023,0.002 0.051,0 0.102-0.008 0.153-0.009 0.234-0.005 0.465-0.017 0.693-0.042 0.079-0.009 0.157-0.025 0.236-0.036 0.216-0.031 0.43-0.07 0.639-0.119 0.034-0.008 0.069-0.011 0.103-0.019l25.941-6.485c6.912-1.729 11.74-7.912 11.74-15.037v-11.509c0-7.125-4.828-13.309-11.741-15.037l-25.94-6.485c-0.04-0.01-0.081-0.014-0.121-0.024-0.146-0.034-0.293-0.062-0.442-0.087-0.11-0.019-0.221-0.037-0.331-0.051-0.124-0.015-0.25-0.026-0.376-0.035-0.136-0.01-0.271-0.018-0.406-0.021-0.047,2.45463e-15-0.093-0.006-0.142-0.006h-98.745c-10.551,0-20.471,4.109-27.931,11.569l-56.97,56.971c-4.449,4.449-5.768,11.079-3.36,16.892s8.028,9.568 14.32,9.568h29.187v9h-0.5c-8.547,0-15.5,6.953-15.5,15.5v22.273c0,10.239-2.784,20.291-8.052,29.069l-20.639,34.398c-12.632,21.054-19.31,45.161-19.31,69.714v132.546c0,30.603 24.897,55.5 55.5,55.5h96c30.603,0 55.5-24.897 55.5-55.5v-132.546c0-24.553-6.677-48.66-19.31-69.714l-20.639-34.398c-5.268-8.778-8.052-18.83-8.052-29.069v-22.273c0-8.547-6.953-15.5-15.5-15.5h-0.5v-9h8.5c4.142,0 7.5-3.358 7.5-7.5 0-7.219 2.369-13.893 6.365-19.292 15.273,37.82 42.778,69.577 78.378,90.18 1.183,0.685 2.475,1.01 3.75,1.01 2.589,0 5.108-1.343 6.498-3.745 2.076-3.586 0.852-8.174-2.733-10.248zm-19.257-123.659v11.508c0,0.23-0.156,0.43-0.378,0.485l-16.622,4.155v-20.788l16.621,4.155c0.224,0.055 0.379,0.255 0.379,0.485zm-199.828,191.212l20.639-34.398c5.073-8.455 8.32-17.844 9.585-27.56h33.604v144.037c-1.835-0.565-3.396-1.343-5.197-2.244-4.268-2.135-9.579-4.792-19.346-4.792-9.765,0-15.076,2.658-19.343,4.793-3.721,1.862-6.409,3.207-12.631,3.207-6.225,0-8.914-1.345-12.636-3.208-3.02-1.511-6.572-3.279-11.847-4.186v-13.652c-4.26326e-14-21.836 5.938-43.274 17.172-61.997zm71.328,186.042c4.687,0 8.5,3.813 8.5,8.5v8.5h-17v-8.5c0-4.687 3.813-8.5 8.5-8.5zm48,49h-96c-22.332,0-40.5-18.168-40.5-40.5v-103.517c1.808,0.564 3.356,1.334 5.136,2.225 4.268,2.135 9.58,4.792 19.347,4.792 9.766,0 15.076-2.658 19.344-4.793 3.721-1.862 6.409-3.207 12.63-3.207 6.224,0 8.912,1.345 12.634,3.208 3.032,1.517 6.6,3.293 11.909,4.196v73.096c0,0.575 0.071,1.132 0.193,1.669-9.39,3.081-16.193,11.924-16.193,22.331v16c0,4.142 3.358,7.5 7.5,7.5h32c4.142,0 7.5-3.358 7.5-7.5v-16c0-10.407-6.803-19.25-16.193-22.331 0.122-0.537 0.193-1.094 0.193-1.669v-73.117c5.241-0.91 8.776-2.671 11.785-4.176 3.723-1.862 6.413-3.208 12.639-3.208 6.241,0 8.937,1.346 12.668,3.21 4.273,2.134 9.592,4.79 19.37,4.79s15.097-2.656 19.371-4.79c1.791-0.895 3.347-1.668 5.168-2.233v103.524c-0.001,22.332-18.169,40.5-40.501,40.5zm23.329-235.042c11.234,18.724 17.172,40.162 17.172,61.997v13.65c-5.286,0.906-8.844,2.674-11.87,4.185-3.731,1.864-6.427,3.21-12.668,3.21-6.241,0-8.937-1.346-12.668-3.21-4.273-2.134-9.592-4.79-19.37-4.79-9.768,0-15.081,2.657-19.349,4.792-1.76,0.881-3.293,1.643-5.074,2.205v-143.997h33.604c1.265,9.715 4.512,19.104 9.585,27.56l20.638,34.398zm-30.829-93.458v16.5h-81v-16.5c0-0.276 0.224-0.5 0.5-0.5h80c0.276,0 0.5,0.224 0.5,0.5zm-16-15.5h-49v-9h49v9zm16.592-24h-109.778c-0.179,0-0.334,0-0.462-0.309-0.127-0.309-0.018-0.418 0.108-0.545l56.971-56.971c4.628-4.627 10.78-7.175 17.324-7.175h91.245v25h-8.5c-23.64,0-43.302,17.359-46.908,40z"/>
|
|
5
|
+
</svg>
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/plumbing.svg
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='iso-8859-1'?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="currentColor" height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 463 463" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 463 463">
|
|
4
|
+
<g>
|
|
5
|
+
<path d="m447,341.234v-17.734c0-79.126-64.374-143.5-143.5-143.5h-113.734c-3.138-9.29-11.93-16-22.266-16-4.687,0-8.5-3.813-8.5-8.5v-8.5h0.5c4.142,0 7.5-3.358 7.5-7.5s-3.358-7.5-7.5-7.5h-16.5v-27.077l47.496,9.543c1.786,0.357 3.582,0.533 5.365,0.533 6.219,0 12.28-2.137 17.192-6.165 6.321-5.182 9.947-12.842 9.947-21.016s-3.625-15.833-9.946-21.016c-6.322-5.183-14.544-7.236-22.558-5.632l-50.889,10.177c-4.123-6.796-11.593-11.347-20.107-11.347s-15.984,4.551-20.107,11.348l-50.889-10.178c-8.013-1.602-16.237,0.45-22.558,5.632-6.321,5.182-9.946,12.842-9.946,21.016s3.625,15.834 9.947,21.016c4.913,4.028 10.975,6.166 17.192,6.166 1.781,0 3.575-0.176 5.357-0.532l47.504-9.443v26.975h-16.5c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h0.5v8.5c0,4.687-3.813,8.5-8.5,8.5-10.336,0-19.128,6.71-22.266,16h-25.734c-12.958,0-23.5,10.542-23.5,23.5v64c0,12.958 10.542,23.5 23.5,23.5h25.734c3.138,9.29 11.93,16 22.266,16h96c10.336,0 19.128-6.71 22.266-16h113.734c17.92,0 32.5,14.58 32.5,32.5v17.734c-9.29,3.138-16,11.93-16,22.266v16c0,12.958 10.542,23.5 23.5,23.5h96c12.958,0 23.5-10.542 23.5-23.5v-16c0-10.336-6.71-19.128-16-22.266zm-253.563-265.355c3.589-0.719 7.274,0.201 10.107,2.523 2.832,2.322 4.456,5.753 4.456,9.416s-1.625,7.094-4.457,9.416c-2.832,2.322-6.516,3.242-10.1,2.524l-50.443-10.135v-3.657l50.437-10.087zm-73.937-.879c4.687,0 8.5,3.813 8.5,8.5v16.5h-17v-16.5c0-4.687 3.813-8.5 8.5-8.5zm-73.937,24.757c-3.592,0.719-7.275-0.202-10.106-2.523-2.832-2.322-4.457-5.754-4.457-9.416s1.624-7.094 4.456-9.416c2.832-2.322 6.515-3.243 10.107-2.523l50.437,10.088v3.765l-50.437,10.025zm65.437,15.243h17v17h-17v-17zm-96,152.5v-64c0-4.687 3.813-8.5 8.5-8.5h24.5v81h-24.5c-4.687,0-8.5-3.813-8.5-8.5zm161,16c0,4.687-3.813,8.5-8.5,8.5h-96c-4.68,0-8.488-3.803-8.499-8.481 0-0.007 0.001-0.013 0.001-0.019 0-0.013-0.002-0.026-0.002-0.039v-95.923c0-0.013 0.002-0.026 0.002-0.039 0-0.007-0.001-0.013-0.001-0.019 0.011-4.677 3.819-8.48 8.499-8.48 12.958,0 23.5-10.542 23.5-23.5v-8.5h49v8.5c0,12.958 10.542,23.5 23.5,23.5 4.687,0 8.5,3.813 8.5,8.5v96zm127.5-7.5h-112.5v-81h112.5c70.855,0 128.5,57.645 128.5,128.5v16.5h-81v-16.5c0-26.191-21.309-47.5-47.5-47.5zm144.5,103.5c0,4.687-3.813,8.5-8.5,8.5h-96c-4.687,0-8.5-3.813-8.5-8.5v-16c0-4.687 3.813-8.5 8.5-8.5h96c4.687,0 8.5,3.813 8.5,8.5v16z"/>
|
|
6
|
+
</g>
|
|
7
|
+
</svg>
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/zen-logo.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="40" height="40" rx="8" fill="black" fill-opacity="0.2"/>
|
|
3
|
+
<path d="M10 31V16.3333C13.4868 16.6744 19.9209 18.0046 20.3194 20.5969C20.4604 21.5144 20.45 31 20.45 31M13.4972 31L13.7641 13.9457C13.7641 10.1 25.95 9 25.95 9V31" stroke="white" stroke-width="1.5"/>
|
|
4
|
+
<path d="M29.2494 31.0001V23.4681C25.2137 22.8637 21.6875 23.9923 19.3778 25.2149C18.3982 25.7334 17.6374 26.2688 17.1494 26.6961V31.0001" stroke="white" stroke-width="1.5"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a type-specific icon for maintenance requests (same approach as b2e MaintenanceTable).
|
|
3
|
+
* Uses imported SVG assets; fallback to 🔧 when type has no icon.
|
|
4
|
+
*/
|
|
5
|
+
import PlumbingIcon from "@/assets/icons/plumbing.svg";
|
|
6
|
+
import HVACIcon from "@/assets/icons/hvac.svg";
|
|
7
|
+
import ElectricalIcon from "@/assets/icons/electrical.svg";
|
|
8
|
+
import AppliancesIcon from "@/assets/icons/appliances.svg";
|
|
9
|
+
import PestIcon from "@/assets/icons/pest.svg";
|
|
10
|
+
|
|
11
|
+
const issueIcons: Record<string, string> = {
|
|
12
|
+
Plumbing: PlumbingIcon,
|
|
13
|
+
HVAC: HVACIcon,
|
|
14
|
+
Electrical: ElectricalIcon,
|
|
15
|
+
Appliance: AppliancesIcon,
|
|
16
|
+
Pest: PestIcon,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const issueIconColors: Record<string, string> = {
|
|
20
|
+
Plumbing: "bg-teal-100",
|
|
21
|
+
HVAC: "bg-teal-100",
|
|
22
|
+
Electrical: "bg-teal-100",
|
|
23
|
+
Appliance: "bg-teal-100",
|
|
24
|
+
Pest: "bg-teal-100",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function MaintenanceRequestIcon({ type }: { type: string | null }) {
|
|
28
|
+
const issueType = type?.trim() ?? "";
|
|
29
|
+
const iconSrc = issueIcons[issueType];
|
|
30
|
+
const bgClass = issueIconColors[issueType] ?? "bg-teal-100";
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
className={`flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-lg ${bgClass}`}
|
|
35
|
+
aria-hidden
|
|
36
|
+
>
|
|
37
|
+
{iconSrc ? (
|
|
38
|
+
<img src={iconSrc} alt={issueType || "Request"} className="h-6 w-6" />
|
|
39
|
+
) : (
|
|
40
|
+
<span className="text-2xl" aria-hidden>
|
|
41
|
+
🔧
|
|
42
|
+
</span>
|
|
43
|
+
)}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/NavMenu.tsx
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Link, useLocation } from "react-router";
|
|
2
|
+
import { Home, Search, BarChart3, Wrench, Phone, type LucideIcon } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
interface NavItem {
|
|
5
|
+
path: string;
|
|
6
|
+
icon: LucideIcon;
|
|
7
|
+
label: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const navItems: NavItem[] = [
|
|
11
|
+
{ path: "/", icon: Home, label: "Home" },
|
|
12
|
+
{ path: "/dashboard", icon: BarChart3, label: "Dashboard" },
|
|
13
|
+
{ path: "/properties", icon: Search, label: "Property Search" },
|
|
14
|
+
{ path: "/maintenance/requests", icon: Wrench, label: "Maintenance Requests" },
|
|
15
|
+
{ path: "/contact", icon: Phone, label: "Contact Us" },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export function NavMenu() {
|
|
19
|
+
const location = useLocation();
|
|
20
|
+
|
|
21
|
+
const isActive = (path: string) => {
|
|
22
|
+
if (path === "/") return location.pathname === "/";
|
|
23
|
+
return location.pathname.startsWith(path);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<nav
|
|
28
|
+
className="flex w-24 flex-col border-r border-gray-200 bg-white py-8"
|
|
29
|
+
aria-label="Main navigation"
|
|
30
|
+
>
|
|
31
|
+
{navItems.map((item) => {
|
|
32
|
+
const Icon = item.icon;
|
|
33
|
+
const active = isActive(item.path);
|
|
34
|
+
return (
|
|
35
|
+
<Link
|
|
36
|
+
key={item.path}
|
|
37
|
+
to={item.path}
|
|
38
|
+
className={`flex flex-col items-center justify-center gap-2 px-2 py-4 transition-colors ${
|
|
39
|
+
active
|
|
40
|
+
? "border-l-4 border-teal-700 bg-teal-100 text-teal-700"
|
|
41
|
+
: "text-gray-600 hover:bg-gray-100 hover:text-gray-900"
|
|
42
|
+
}`}
|
|
43
|
+
title={item.label}
|
|
44
|
+
aria-label={item.label}
|
|
45
|
+
>
|
|
46
|
+
<Icon className="size-6 shrink-0" aria-hidden />
|
|
47
|
+
<span className="text-center text-xs font-medium leading-tight">{item.label}</span>
|
|
48
|
+
</Link>
|
|
49
|
+
);
|
|
50
|
+
})}
|
|
51
|
+
</nav>
|
|
52
|
+
);
|
|
53
|
+
}
|