|
1
|
import { useState } from "react"; |
|
2
|
import { useLocation } from "wouter"; |
|
3
|
import { Button } from "@/components/ui/button"; |
|
4
|
import { |
|
5
|
Sheet, |
|
6
|
SheetContent, |
|
7
|
SheetHeader, |
|
8
|
SheetTitle, |
|
9
|
SheetTrigger, |
|
10
|
} from "@/components/ui/sheet"; |
|
11
|
import { Separator } from "@/components/ui/separator"; |
|
12
|
import { useAuth } from "@/hooks/useAuth"; |
|
13
|
import type { User } from "@shared/schema"; |
|
14
|
|
|
15
|
export function MobileMenu() { |
|
16
|
const [open, setOpen] = useState(false); |
|
17
|
const [, setLocation] = useLocation(); |
|
18
|
const { user, isAuthenticated } = useAuth() as { user: User | undefined; isAuthenticated: boolean }; |
|
19
|
|
|
20
|
const handleNavigation = (path: string) => { |
|
21
|
setLocation(path); |
|
22
|
setOpen(false); |
|
23
|
}; |
|
24
|
|
|
25
|
return ( |
|
26
|
<Sheet open={open} onOpenChange={setOpen}> |
|
27
|
<SheetTrigger asChild> |
|
28
|
<Button variant="ghost" size="icon" className="md:hidden"> |
|
29
|
<i className="material-icons">menu</i> |
|
30
|
<span className="sr-only">Toggle menu</span> |
|
31
|
</Button> |
|
32
|
</SheetTrigger> |
|
33
|
<SheetContent side="left" className="w-80"> |
|
34
|
<SheetHeader> |
|
35
|
<SheetTitle className="flex items-center space-x-2"> |
|
36
|
<i className="material-icons text-primary-700 text-xl">build</i> |
|
37
|
<span>JCR Guide Pro</span> |
|
38
|
</SheetTitle> |
|
39
|
</SheetHeader> |
|
40
|
|
|
41
|
<div className="mt-6 space-y-6"> |
|
42
|
{/* Main Navigation */} |
|
43
|
<div className="space-y-3"> |
|
44
|
<h3 className="text-sm font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wide"> |
|
45
|
Navigation |
|
46
|
</h3> |
|
47
|
<div className="space-y-1"> |
|
48
|
<Button |
|
49
|
variant="ghost" |
|
50
|
className="w-full justify-start" |
|
51
|
onClick={() => handleNavigation("/")} |
|
52
|
> |
|
53
|
<i className="material-icons mr-3 text-lg">home</i> |
|
54
|
Repair Guides |
|
55
|
</Button> |
|
56
|
|
|
57
|
{isAuthenticated && ( |
|
58
|
<Button |
|
59
|
variant="ghost" |
|
60
|
className="w-full justify-start" |
|
61
|
onClick={() => handleNavigation("/favorites")} |
|
62
|
> |
|
63
|
<i className="material-icons mr-3 text-lg">favorite</i> |
|
64
|
Favorites |
|
65
|
</Button> |
|
66
|
)} |
|
67
|
</div> |
|
68
|
</div> |
|
69
|
|
|
70
|
<Separator /> |
|
71
|
|
|
72
|
{/* Tools & Content */} |
|
73
|
<div className="space-y-3"> |
|
74
|
<h3 className="text-sm font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wide"> |
|
75
|
Tools & Content |
|
76
|
</h3> |
|
77
|
<div className="space-y-1"> |
|
78
|
<Button |
|
79
|
variant="ghost" |
|
80
|
className="w-full justify-start" |
|
81
|
onClick={() => handleNavigation("/troubleshooting")} |
|
82
|
> |
|
83
|
<i className="material-icons mr-3 text-lg">help_outline</i> |
|
84
|
Troubleshooting |
|
85
|
</Button> |
|
86
|
<Button |
|
87
|
variant="ghost" |
|
88
|
className="w-full justify-start" |
|
89
|
onClick={() => handleNavigation("/device-finder")} |
|
90
|
> |
|
91
|
<i className="material-icons mr-3 text-lg">search</i> |
|
92
|
Device Finder |
|
93
|
</Button> |
|
94
|
<Button |
|
95
|
variant="ghost" |
|
96
|
className="w-full justify-start" |
|
97
|
onClick={() => handleNavigation("/software-tools")} |
|
98
|
> |
|
99
|
<i className="material-icons mr-3 text-lg">build_circle</i> |
|
100
|
Software Tools |
|
101
|
</Button> |
|
102
|
<Button |
|
103
|
variant="ghost" |
|
104
|
className="w-full justify-start" |
|
105
|
onClick={() => handleNavigation("/create-guide")} |
|
106
|
> |
|
107
|
<i className="material-icons mr-3 text-lg">add_circle</i> |
|
108
|
Create Guide |
|
109
|
</Button> |
|
110
|
<Button |
|
111
|
variant="ghost" |
|
112
|
className="w-full justify-start" |
|
113
|
onClick={() => handleNavigation("/downloads")} |
|
114
|
> |
|
115
|
<i className="material-icons mr-3 text-lg">download</i> |
|
116
|
Downloads |
|
117
|
</Button> |
|
118
|
|
|
119
|
<Button |
|
120
|
variant="ghost" |
|
121
|
className="w-full justify-start" |
|
122
|
onClick={() => handleNavigation("/offline-settings")} |
|
123
|
> |
|
124
|
<i className="material-icons mr-3 text-lg">cloud_off</i> |
|
125
|
Offline Mode |
|
126
|
</Button> |
|
127
|
</div> |
|
128
|
</div> |
|
129
|
|
|
130
|
{/* Authentication */} |
|
131
|
{!isAuthenticated ? ( |
|
132
|
<> |
|
133
|
<Separator /> |
|
134
|
<div className="space-y-3"> |
|
135
|
<Button |
|
136
|
onClick={() => { |
|
137
|
window.location.href = "/api/login"; |
|
138
|
}} |
|
139
|
className="w-full" |
|
140
|
> |
|
141
|
<i className="material-icons mr-2 text-lg">login</i> |
|
142
|
Sign In |
|
143
|
</Button> |
|
144
|
</div> |
|
145
|
</> |
|
146
|
) : ( |
|
147
|
<> |
|
148
|
<Separator /> |
|
149
|
<div className="space-y-3"> |
|
150
|
<div className="flex items-center space-x-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"> |
|
151
|
{user?.profileImageUrl ? ( |
|
152
|
<img |
|
153
|
src={user.profileImageUrl} |
|
154
|
alt="Profile" |
|
155
|
className="w-8 h-8 rounded-full object-cover" |
|
156
|
/> |
|
157
|
) : ( |
|
158
|
<div className="w-8 h-8 bg-primary-100 dark:bg-primary-900 rounded-full flex items-center justify-center"> |
|
159
|
<i className="material-icons text-primary-700 dark:text-primary-300 text-lg">person</i> |
|
160
|
</div> |
|
161
|
)} |
|
162
|
<div className="flex-1 min-w-0"> |
|
163
|
<p className="text-sm font-medium text-gray-900 dark:text-white truncate"> |
|
164
|
{user?.firstName ? `${user.firstName} ${user?.lastName || ''}`.trim() : user?.email} |
|
165
|
</p> |
|
166
|
{user?.email && user?.firstName && ( |
|
167
|
<p className="text-xs text-gray-500 dark:text-gray-400 truncate"> |
|
168
|
{user.email} |
|
169
|
</p> |
|
170
|
)} |
|
171
|
</div> |
|
172
|
</div> |
|
173
|
<Button |
|
174
|
variant="outline" |
|
175
|
onClick={() => { |
|
176
|
window.location.href = "/api/logout"; |
|
177
|
}} |
|
178
|
className="w-full" |
|
179
|
> |
|
180
|
<i className="material-icons mr-2 text-lg">logout</i> |
|
181
|
Sign Out |
|
182
|
</Button> |
|
183
|
</div> |
|
184
|
</> |
|
185
|
)} |
|
186
|
</div> |
|
187
|
</SheetContent> |
|
188
|
</Sheet> |
|
189
|
); |
|
190
|
} |