lattmamb commited on
Commit
6b54f12
·
verified ·
1 Parent(s): 829b91b

Upload 64 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ generated-icon.png filter=lfs diff=lfs merge=lfs -text
App.tsx ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Switch, Route } from "wouter";
2
+ import { queryClient } from "./lib/queryClient";
3
+ import { QueryClientProvider } from "@tanstack/react-query";
4
+ import { Toaster } from "@/components/ui/toaster";
5
+ import NotFound from "@/pages/not-found";
6
+ import Chat from "@/pages/chat";
7
+
8
+ function Router() {
9
+ return (
10
+ <Switch>
11
+ <Route path="/" component={Chat} />
12
+ <Route component={NotFound} />
13
+ </Switch>
14
+ );
15
+ }
16
+
17
+ function App() {
18
+ return (
19
+ <QueryClientProvider client={queryClient}>
20
+ <Router />
21
+ <Toaster />
22
+ </QueryClientProvider>
23
+ );
24
+ }
25
+
26
+ export default App;
Pasted-import-React-useState-useEffect-useRef-from-react-import-motion-from-framer-motion--1742439890124.txt ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { motion } from 'framer-motion';
3
+ import _ from 'lodash';
4
+
5
+ const VisionOSCarousel = () => {
6
+ // State for carousel and navigation
7
+ const [activeChat, setActiveChat] = useState(0);
8
+ const [showModelDropdown, setShowModelDropdown] = useState(false);
9
+ const [showHistoryDropdown, setShowHistoryDropdown] = useState(false);
10
+ const [activeModel, setActiveModel] = useState('Vision GPT-4');
11
+ const carouselRef = useRef(null);
12
+ const [isDragging, setIsDragging] = useState(false);
13
+ const [startX, setStartX] = useState(0);
14
+
15
+ // Sample chat data
16
+ const chats = [
17
+ { id: 1, title: "Project Atlas", preview: "Latest updates on the Atlas project integration..." },
18
+ { id: 2, title: "Meeting Notes", preview: "AI summary of yesterday's team meeting..." },
19
+ { id: 3, title: "Travel Planning", preview: "Vision's suggestions for your upcoming trip..." },
20
+ { id: 4, title: "Code Review", preview: "Analysis of the new codebase structure..." }
21
+ ];
22
+
23
+ // AI models available in the system
24
+ const aiModels = [
25
+ { id: 1, name: 'Vision GPT-4', icon: '🧠' },
26
+ { id: 2, name: 'Vision Assistant', icon: '👁️' },
27
+ { id: 3, name: 'Vision Coder', icon: '💻' },
28
+ { id: 4, name: 'Vision Creative', icon: '🎨' }
29
+ ];
30
+
31
+ // Chat history entries
32
+ const chatHistory = [
33
+ { id: 101, title: "Previous Projects", date: "Mar 15" },
34
+ { id: 102, title: "System Setup", date: "Mar 10" },
35
+ { id: 103, title: "Design Feedback", date: "Mar 5" },
36
+ { id: 104, title: "Initial Consultation", date: "Feb 28" }
37
+ ];
38
+
39
+ // Handle swipe gesture for carousel
40
+ const handleTouchStart = (e) => {
41
+ setIsDragging(true);
42
+ setStartX(e.touches[0].clientX);
43
+ };
44
+
45
+ const handleTouchMove = (e) => {
46
+ if (!isDragging) return;
47
+ const currentX = e.touches[0].clientX;
48
+ const diff = startX - currentX;
49
+
50
+ if (Math.abs(diff) > 50) {
51
+ if (diff > 0 && activeChat < chats.length - 1) {
52
+ setActiveChat(activeChat + 1);
53
+ setIsDragging(false);
54
+ } else if (diff < 0 && activeChat > 0) {
55
+ setActiveChat(activeChat - 1);
56
+ setIsDragging(false);
57
+ }
58
+ }
59
+ };
60
+
61
+ const handleTouchEnd = () => {
62
+ setIsDragging(false);
63
+ };
64
+
65
+ // Handle mouse swipe for desktop
66
+ const handleMouseDown = (e) => {
67
+ setIsDragging(true);
68
+ setStartX(e.clientX);
69
+ };
70
+
71
+ const handleMouseMove = (e) => {
72
+ if (!isDragging) return;
73
+ const currentX = e.clientX;
74
+ const diff = startX - currentX;
75
+
76
+ if (Math.abs(diff) > 50) {
77
+ if (diff > 0 && activeChat < chats.length - 1) {
78
+ setActiveChat(activeChat + 1);
79
+ setIsDragging(false);
80
+ } else if (diff < 0 && activeChat > 0) {
81
+ setActiveChat(activeChat - 1);
82
+ setIsDragging(false);
83
+ }
84
+ }
85
+ };
86
+
87
+ const handleMouseUp = () => {
88
+ setIsDragging(false);
89
+ };
90
+
91
+ // Navigation functions
92
+ const nextChat = () => {
93
+ if (activeChat < chats.length - 1) {
94
+ setActiveChat(activeChat + 1);
95
+ }
96
+ };
97
+
98
+ const prevChat = () => {
99
+ if (activeChat > 0) {
100
+ setActiveChat(activeChat - 1);
101
+ }
102
+ };
103
+
104
+ const selectModel = (model) => {
105
+ setActiveModel(model.name);
106
+ setShowModelDropdown(false);
107
+ };
108
+
109
+ const selectHistoryChat = (chat) => {
110
+ // In a real app, this would load the historical chat
111
+ setShowHistoryDropdown(false);
112
+ };
113
+
114
+ return (
115
+ <div className="flex flex-col h-screen bg-gradient-to-b from-blue-900 to-black text-white">
116
+ {/* Top Navigation Bar - iPhone Dynamic Island Inspired */}
117
+ <div className="relative z-10">
118
+ <motion.div
119
+ className="mx-auto mt-2 px-6 py-2 rounded-full bg-black/60 backdrop-blur-md border border-blue-500/30 flex items-center justify-between w-64"
120
+ initial={{ y: -50 }}
121
+ animate={{ y: 0 }}
122
+ transition={{ type: "spring", stiffness: 300, damping: 25 }}
123
+ >
124
+ <button
125
+ onClick={() => {
126
+ setShowModelDropdown(!showModelDropdown);
127
+ setShowHistoryDropdown(false);
128
+ }}
129
+ className="flex items-center space-x-1 text-sm"
130
+ >
131
+ <span className="text-blue-400">{activeModel.split(' ')[0]}</span>
132
+ <span className="text-xs opacity-70">▼</span>
133
+ </button>
134
+
135
+ <div className="h-4 w-px bg-blue-400/30"></div>
136
+
137
+ <button
138
+ onClick={() => {
139
+ setShowHistoryDropdown(!showHistoryDropdown);
140
+ setShowModelDropdown(false);
141
+ }}
142
+ className="flex items-center space-x-1 text-sm"
143
+ >
144
+ <span>History</span>
145
+ <span className="text-xs opacity-70">▼</span>
146
+ </button>
147
+ </motion.div>
148
+
149
+ {/* Model Selection Dropdown */}
150
+ {showModelDropdown && (
151
+ <motion.div
152
+ className="absolute top-12 left-1/2 transform -translate-x-1/2 w-64 bg-black/80 backdrop-blur-xl rounded-xl border border-blue-500/20 p-2 shadow-lg shadow-blue-500/10"
153
+ initial={{ opacity: 0, y: -10 }}
154
+ animate={{ opacity: 1, y: 0 }}
155
+ exit={{ opacity: 0, y: -10 }}
156
+ transition={{ duration: 0.2 }}
157
+ >
158
+ {aiModels.map(model => (
159
+ <div
160
+ key={model.id}
161
+ onClick={() => selectModel(model)}
162
+ className="flex items-center space-x-2 p-2 hover:bg-blue-900/30 rounded-lg cursor-pointer transition-colors"
163
+ >
164
+ <span className="text-lg">{model.icon}</span>
165
+ <span className={activeModel === model.name ? "text-blue-400" : ""}>{model.name}</span>
166
+ {activeModel === model.name && <span className="ml-auto text-blue-400 text-xs">✓</span>}
167
+ </div>
168
+ ))}
169
+ </motion.div>
170
+ )}
171
+
172
+ {/* History Dropdown */}
173
+ {showHistoryDropdown && (
174
+ <motion.div
175
+ className="absolute top-12 left-1/2 transform -translate-x-1/2 w-64 bg-black/80 backdrop-blur-xl rounded-xl border border-blue-500/20 p-2 shadow-lg shadow-blue-500/10"
176
+ initial={{ opacity: 0, y: -10 }}
177
+ animate={{ opacity: 1, y: 0 }}
178
+ exit={{ opacity: 0, y: -10 }}
179
+ transition={{ duration: 0.2 }}
180
+ >
181
+ {chatHistory.map(chat => (
182
+ <div
183
+ key={chat.id}
184
+ onClick={() => selectHistoryChat(chat)}
185
+ className="flex items-center justify-between p-2 hover:bg-blue-900/30 rounded-lg cursor-pointer transition-colors"
186
+ >
187
+ <span>{chat.title}</span>
188
+ <span className="text-xs opacity-50">{chat.date}</span>
189
+ </div>
190
+ ))}
191
+ </motion.div>
192
+ )}
193
+ </div>
194
+
195
+ {/* 3D Carousel Area */}
196
+ <div
197
+ className="flex-1 flex items-center justify-center overflow-hidden"
198
+ ref={carouselRef}
199
+ onTouchStart={handleTouchStart}
200
+ onTouchMove={handleTouchMove}
201
+ onTouchEnd={handleTouchEnd}
202
+ onMouseDown={handleMouseDown}
203
+ onMouseMove={handleMouseMove}
204
+ onMouseUp={handleMouseUp}
205
+ onMouseLeave={handleMouseUp}
206
+ >
207
+ <div className="relative w-full max-w-4xl h-96">
208
+ {chats.map((chat, index) => {
209
+ // Calculate position and transform for 3D effect
210
+ const offset = index - activeChat;
211
+ const isActive = index === activeChat;
212
+ const zIndex = chats.length - Math.abs(offset);
213
+
214
+ return (
215
+ <motion.div
216
+ key={chat.id}
217
+ className="absolute top-0 w-72 h-80 rounded-2xl bg-gradient-to-br from-blue-900/90 to-indigo-900/90 backdrop-blur-lg border border-blue-500/20 p-4 shadow-lg shadow-blue-500/10"
218
+ style={{
219
+ left: `calc(50% - 144px)`,
220
+ zIndex
221
+ }}
222
+ animate={{
223
+ x: offset * 60,
224
+ rotateY: offset * -15,
225
+ scale: isActive ? 1 : 0.9 - Math.abs(offset) * 0.05,
226
+ opacity: 1 - Math.abs(offset) * 0.2
227
+ }}
228
+ transition={{ type: "spring", stiffness: 300, damping: 30 }}
229
+ >
230
+ <div className="h-full flex flex-col">
231
+ <div className="flex justify-between items-center mb-3">
232
+ <h3 className="font-semibold text-lg text-blue-100">{chat.title}</h3>
233
+ <div className="h-2 w-2 rounded-full bg-blue-400"></div>
234
+ </div>
235
+
236
+ <p className="text-sm text-blue-200/70 mb-4">{chat.preview}</p>
237
+
238
+ {/* Mock chat bubbles */}
239
+ <div className="flex-1 overflow-hidden">
240
+ <div className="bg-blue-900/50 rounded-lg p-2 mb-2 ml-auto max-w-48 text-xs">
241
+ How can Vision help with this project?
242
+ </div>
243
+ <div className="bg-blue-600/40 rounded-lg p-2 mb-2 max-w-48 text-xs">
244
+ I can analyze the data and provide recommendations based on previous outcomes.
245
+ </div>
246
+ {isActive && (
247
+ <motion.div
248
+ className="bg-blue-900/50 rounded-lg p-2 max-w-48 ml-auto text-xs"
249
+ initial={{ opacity: 0, y: 10 }}
250
+ animate={{ opacity: 1, y: 0 }}
251
+ transition={{ delay: 0.1 }}
252
+ >
253
+ Great. Let's see what you can find.
254
+ </motion.div>
255
+ )}
256
+ </div>
257
+
258
+ {isActive && (
259
+ <motion.div
260
+ className="mt-2 bg-blue-500/10 rounded-lg p-2 flex items-center"
261
+ initial={{ opacity: 0 }}
262
+ animate={{ opacity: 1 }}
263
+ transition={{ delay: 0.2 }}
264
+ >
265
+ <input
266
+ type="text"
267
+ placeholder="Message Vision..."
268
+ className="bg-transparent text-sm w-full outline-none placeholder-blue-300/40"
269
+ />
270
+ <button className="ml-2 text-blue-300">
271
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
272
+ <path d="M22 2L11 13" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
273
+ <path d="M22 2L15 22L11 13L2 9L22 2Z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
274
+ </svg>
275
+ </button>
276
+ </motion.div>
277
+ )}
278
+ </div>
279
+ </motion.div>
280
+ );
281
+ })}
282
+ </div>
283
+ </div>
284
+
285
+ {/* Bottom Home Bar - iPhone Style */}
286
+ <div className="relative z-10">
287
+ <motion.div
288
+ className="mx-auto mb-6 px-6 py-4 rounded-2xl bg-black/60 backdrop-blur-md border border-blue-500/20 flex items-center justify-between w-72"
289
+ initial={{ y: 50 }}
290
+ animate={{ y: 0 }}
291
+ transition={{ type: "spring", stiffness: 300, damping: 25 }}
292
+ >
293
+ <button
294
+ onClick={prevChat}
295
+ className={`w-12 h-12 flex items-center justify-center rounded-full ${activeChat > 0 ? 'bg-blue-900/50 text-blue-300' : 'bg-blue-900/20 text-blue-300/30'}`}
296
+ disabled={activeChat === 0}
297
+ >
298
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
299
+ <path d="M15 18L9 12L15 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
300
+ </svg>
301
+ </button>
302
+
303
+ <div className="w-20 h-1 bg-blue-400/30 rounded-full"></div>
304
+
305
+ <button
306
+ onClick={nextChat}
307
+ className={`w-12 h-12 flex items-center justify-center rounded-full ${activeChat < chats.length - 1 ? 'bg-blue-900/50 text-blue-300' : 'bg-blue-900/20 text-blue-300/30'}`}
308
+ disabled={activeChat === chats.length - 1}
309
+ >
310
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
311
+ <path d="M9 6L15 12L9 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
312
+ </svg>
313
+ </button>
314
+ </motion.div>
315
+ </div>
316
+ </div>
317
+ );
318
+ };
319
+
320
+ export default VisionOSCarousel;
QuantumVision.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8579ed427a571035e8035837e8ed195ed277140b969a931e3e03b3db6f5020f
3
+ size 1684042
accordion.tsx ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as AccordionPrimitive from "@radix-ui/react-accordion"
3
+ import { ChevronDown } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Accordion = AccordionPrimitive.Root
8
+
9
+ const AccordionItem = React.forwardRef<
10
+ React.ElementRef<typeof AccordionPrimitive.Item>,
11
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
12
+ >(({ className, ...props }, ref) => (
13
+ <AccordionPrimitive.Item
14
+ ref={ref}
15
+ className={cn("border-b", className)}
16
+ {...props}
17
+ />
18
+ ))
19
+ AccordionItem.displayName = "AccordionItem"
20
+
21
+ const AccordionTrigger = React.forwardRef<
22
+ React.ElementRef<typeof AccordionPrimitive.Trigger>,
23
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
24
+ >(({ className, children, ...props }, ref) => (
25
+ <AccordionPrimitive.Header className="flex">
26
+ <AccordionPrimitive.Trigger
27
+ ref={ref}
28
+ className={cn(
29
+ "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {children}
35
+ <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
36
+ </AccordionPrimitive.Trigger>
37
+ </AccordionPrimitive.Header>
38
+ ))
39
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
40
+
41
+ const AccordionContent = React.forwardRef<
42
+ React.ElementRef<typeof AccordionPrimitive.Content>,
43
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
44
+ >(({ className, children, ...props }, ref) => (
45
+ <AccordionPrimitive.Content
46
+ ref={ref}
47
+ className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
48
+ {...props}
49
+ >
50
+ <div className={cn("pb-4 pt-0", className)}>{children}</div>
51
+ </AccordionPrimitive.Content>
52
+ ))
53
+
54
+ AccordionContent.displayName = AccordionPrimitive.Content.displayName
55
+
56
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
alert-dialog.tsx ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
3
+
4
+ import { cn } from "@/lib/utils"
5
+ import { buttonVariants } from "@/components/ui/button"
6
+
7
+ const AlertDialog = AlertDialogPrimitive.Root
8
+
9
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger
10
+
11
+ const AlertDialogPortal = AlertDialogPrimitive.Portal
12
+
13
+ const AlertDialogOverlay = React.forwardRef<
14
+ React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
15
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
16
+ >(({ className, ...props }, ref) => (
17
+ <AlertDialogPrimitive.Overlay
18
+ className={cn(
19
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
20
+ className
21
+ )}
22
+ {...props}
23
+ ref={ref}
24
+ />
25
+ ))
26
+ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
27
+
28
+ const AlertDialogContent = React.forwardRef<
29
+ React.ElementRef<typeof AlertDialogPrimitive.Content>,
30
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
31
+ >(({ className, ...props }, ref) => (
32
+ <AlertDialogPortal>
33
+ <AlertDialogOverlay />
34
+ <AlertDialogPrimitive.Content
35
+ ref={ref}
36
+ className={cn(
37
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
38
+ className
39
+ )}
40
+ {...props}
41
+ />
42
+ </AlertDialogPortal>
43
+ ))
44
+ AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
45
+
46
+ const AlertDialogHeader = ({
47
+ className,
48
+ ...props
49
+ }: React.HTMLAttributes<HTMLDivElement>) => (
50
+ <div
51
+ className={cn(
52
+ "flex flex-col space-y-2 text-center sm:text-left",
53
+ className
54
+ )}
55
+ {...props}
56
+ />
57
+ )
58
+ AlertDialogHeader.displayName = "AlertDialogHeader"
59
+
60
+ const AlertDialogFooter = ({
61
+ className,
62
+ ...props
63
+ }: React.HTMLAttributes<HTMLDivElement>) => (
64
+ <div
65
+ className={cn(
66
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
67
+ className
68
+ )}
69
+ {...props}
70
+ />
71
+ )
72
+ AlertDialogFooter.displayName = "AlertDialogFooter"
73
+
74
+ const AlertDialogTitle = React.forwardRef<
75
+ React.ElementRef<typeof AlertDialogPrimitive.Title>,
76
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
77
+ >(({ className, ...props }, ref) => (
78
+ <AlertDialogPrimitive.Title
79
+ ref={ref}
80
+ className={cn("text-lg font-semibold", className)}
81
+ {...props}
82
+ />
83
+ ))
84
+ AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
85
+
86
+ const AlertDialogDescription = React.forwardRef<
87
+ React.ElementRef<typeof AlertDialogPrimitive.Description>,
88
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
89
+ >(({ className, ...props }, ref) => (
90
+ <AlertDialogPrimitive.Description
91
+ ref={ref}
92
+ className={cn("text-sm text-muted-foreground", className)}
93
+ {...props}
94
+ />
95
+ ))
96
+ AlertDialogDescription.displayName =
97
+ AlertDialogPrimitive.Description.displayName
98
+
99
+ const AlertDialogAction = React.forwardRef<
100
+ React.ElementRef<typeof AlertDialogPrimitive.Action>,
101
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
102
+ >(({ className, ...props }, ref) => (
103
+ <AlertDialogPrimitive.Action
104
+ ref={ref}
105
+ className={cn(buttonVariants(), className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
110
+
111
+ const AlertDialogCancel = React.forwardRef<
112
+ React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
113
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
114
+ >(({ className, ...props }, ref) => (
115
+ <AlertDialogPrimitive.Cancel
116
+ ref={ref}
117
+ className={cn(
118
+ buttonVariants({ variant: "outline" }),
119
+ "mt-2 sm:mt-0",
120
+ className
121
+ )}
122
+ {...props}
123
+ />
124
+ ))
125
+ AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
126
+
127
+ export {
128
+ AlertDialog,
129
+ AlertDialogPortal,
130
+ AlertDialogOverlay,
131
+ AlertDialogTrigger,
132
+ AlertDialogContent,
133
+ AlertDialogHeader,
134
+ AlertDialogFooter,
135
+ AlertDialogTitle,
136
+ AlertDialogDescription,
137
+ AlertDialogAction,
138
+ AlertDialogCancel,
139
+ }
alert.tsx ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const alertVariants = cva(
7
+ "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-background text-foreground",
12
+ destructive:
13
+ "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: "default",
18
+ },
19
+ }
20
+ )
21
+
22
+ const Alert = React.forwardRef<
23
+ HTMLDivElement,
24
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
25
+ >(({ className, variant, ...props }, ref) => (
26
+ <div
27
+ ref={ref}
28
+ role="alert"
29
+ className={cn(alertVariants({ variant }), className)}
30
+ {...props}
31
+ />
32
+ ))
33
+ Alert.displayName = "Alert"
34
+
35
+ const AlertTitle = React.forwardRef<
36
+ HTMLParagraphElement,
37
+ React.HTMLAttributes<HTMLHeadingElement>
38
+ >(({ className, ...props }, ref) => (
39
+ <h5
40
+ ref={ref}
41
+ className={cn("mb-1 font-medium leading-none tracking-tight", className)}
42
+ {...props}
43
+ />
44
+ ))
45
+ AlertTitle.displayName = "AlertTitle"
46
+
47
+ const AlertDescription = React.forwardRef<
48
+ HTMLParagraphElement,
49
+ React.HTMLAttributes<HTMLParagraphElement>
50
+ >(({ className, ...props }, ref) => (
51
+ <div
52
+ ref={ref}
53
+ className={cn("text-sm [&_p]:leading-relaxed", className)}
54
+ {...props}
55
+ />
56
+ ))
57
+ AlertDescription.displayName = "AlertDescription"
58
+
59
+ export { Alert, AlertTitle, AlertDescription }
aspect-ratio.tsx ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
2
+
3
+ const AspectRatio = AspectRatioPrimitive.Root
4
+
5
+ export { AspectRatio }
atlas-intelligence-code.swift ADDED
@@ -0,0 +1,1453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ATLAS INTELLIGENCE SYSTEM
2
+ // A conceptual implementation integrating VisionOS, Apple Intelligence, and Tesla API
3
+
4
+ // --------- 1. PROJECT STRUCTURE ---------
5
+ /*
6
+ AtlasIntelligence/
7
+ ├── Sources/
8
+ │ ├── Core/
9
+ │ │ ├── AtlasCore.swift
10
+ │ │ ├── NeuralEngine.swift
11
+ │ │ └── RecursiveThinking.swift
12
+ │ ├── Vision/
13
+ │ │ ├── VisionInterface.swift
14
+ │ │ ├── SpatialComputing.swift
15
+ │ │ └── RealityViews.swift
16
+ │ ├── Integration/
17
+ │ │ ├── AppleIntelligence.swift
18
+ │ │ ├── TeslaConnection.swift
19
+ │ │ └── iCloudSync.swift
20
+ │ ├── Payment/
21
+ │ │ └── TapToPay.swift
22
+ │ └── App/
23
+ │ └── AtlasApp.swift
24
+ └── Resources/
25
+ └── Models/
26
+ └── atlas_model.mlpackage
27
+ */
28
+
29
+ // --------- 2. CORE AI ENGINE ---------
30
+
31
+ // AtlasCore.swift - Main intelligence coordinator
32
+ import Foundation
33
+ import CoreML
34
+ import NaturalLanguage
35
+ import CreateML
36
+
37
+ /// The central AI system for Atlas Intelligence
38
+ class AtlasCore {
39
+ // Core AI components
40
+ private let neuralEngine: NeuralEngine
41
+ private let recursiveThinking: RecursiveThinking
42
+ private let contextManager: ContextManager
43
+
44
+ // Integration components
45
+ private let appleIntelligence: AppleIntelligence
46
+ private let teslaConnection: TeslaConnection
47
+ private let iCloudSync: iCloudSync
48
+
49
+ // Initialize the system
50
+ init() {
51
+ self.neuralEngine = NeuralEngine()
52
+ self.recursiveThinking = RecursiveThinking()
53
+ self.contextManager = ContextManager()
54
+
55
+ self.appleIntelligence = AppleIntelligence()
56
+ self.teslaConnection = TeslaConnection()
57
+ self.iCloudSync = iCloudSync()
58
+
59
+ // Load ML models and initialize systems
60
+ loadModels()
61
+ }
62
+
63
+ private func loadModels() {
64
+ // Load pre-trained CoreML models
65
+ do {
66
+ try neuralEngine.loadModel(named: "atlas_quantum_network")
67
+ try recursiveThinking.loadModel(named: "recursive_reasoning")
68
+ } catch {
69
+ print("Error loading models: \(error)")
70
+ }
71
+ }
72
+
73
+ /// Process user input with multi-step reasoning
74
+ func processInput(_ input: String, context: UserContext) async throws -> AtlasResponse {
75
+ // First-level processing
76
+ let initialContext = contextManager.getCurrentContext()
77
+ let initialAnalysis = try await neuralEngine.analyze(input, withContext: initialContext)
78
+
79
+ // Recursive thinking to refine understanding
80
+ let deepAnalysis = try await recursiveThinking.deepProcess(
81
+ input: input,
82
+ initialAnalysis: initialAnalysis,
83
+ maxRecursionDepth: 3
84
+ )
85
+
86
+ // Generate response based on analysis
87
+ let response = try await generateResponse(from: deepAnalysis, context: context)
88
+
89
+ // Update context for future interactions
90
+ contextManager.updateContext(with: input, response: response)
91
+
92
+ return response
93
+ }
94
+
95
+ /// Generate a coherent response based on the AI's analysis
96
+ private func generateResponse(from analysis: DeepAnalysis, context: UserContext) async throws -> AtlasResponse {
97
+ // Decision process to determine the best response
98
+ let intent = analysis.primaryIntent
99
+
100
+ switch intent {
101
+ case .informationQuery:
102
+ return try await neuralEngine.generateInformationalResponse(for: analysis)
103
+ case .actionRequest:
104
+ return try await handleActionRequest(analysis, context: context)
105
+ case .conversation:
106
+ return try await neuralEngine.generateConversationalResponse(for: analysis)
107
+ default:
108
+ throw AtlasError.unrecognizedIntent
109
+ }
110
+ }
111
+
112
+ /// Handle requests that require action (Tesla control, payments, etc.)
113
+ private func handleActionRequest(_ analysis: DeepAnalysis, context: UserContext) async throws -> AtlasResponse {
114
+ let actionType = analysis.actionRequest.type
115
+
116
+ switch actionType {
117
+ case .teslaControl:
118
+ return try await teslaConnection.executeCommand(analysis.actionRequest)
119
+ case .payment:
120
+ return try await handlePaymentRequest(analysis.actionRequest, context: context)
121
+ case .appleSpatial:
122
+ return try await appleIntelligence.executeSpatialCommand(analysis.actionRequest)
123
+ default:
124
+ throw AtlasError.unsupportedAction
125
+ }
126
+ }
127
+
128
+ /// Process payment requests
129
+ private func handlePaymentRequest(_ request: ActionRequest, context: UserContext) async throws -> AtlasResponse {
130
+ // Verify security context and authentication
131
+ guard context.isAuthenticated && context.paymentAuthorized else {
132
+ throw AtlasError.unauthorizedPayment
133
+ }
134
+
135
+ // Process through secure payment channel
136
+ let paymentProcessor = TapToPay()
137
+ return try await paymentProcessor.processPayment(request.paymentDetails)
138
+ }
139
+ }
140
+
141
+ // NeuralEngine.swift - Advanced neural network implementation
142
+ import Foundation
143
+ import CoreML
144
+ import NaturalLanguage
145
+
146
+ /// Neural processing engine that drives core intelligence
147
+ class NeuralEngine {
148
+ private var model: MLModel?
149
+ private let embeddingProvider: NLEmbedding?
150
+ private let tokenizer: NLTokenizer
151
+
152
+ init() {
153
+ self.tokenizer = NLTokenizer(unit: .word)
154
+ self.embeddingProvider = NLEmbedding.wordEmbedding(for: .english)
155
+ }
156
+
157
+ /// Load a CoreML model for neural processing
158
+ func loadModel(named name: String) throws {
159
+ let modelURL = Bundle.main.url(forResource: name, withExtension: "mlmodelc")!
160
+ self.model = try MLModel(contentsOf: modelURL)
161
+ }
162
+
163
+ /// Analyze user input with context
164
+ func analyze(_ input: String, withContext context: Context) async throws -> Analysis {
165
+ // Tokenize and process input
166
+ tokenizer.string = input
167
+ let tokens = tokenizer.tokens(for: input.startIndex..<input.endIndex)
168
+
169
+ // Generate word embeddings
170
+ let embeddings = tokens.compactMap { token -> [Float]? in
171
+ let word = String(input[token])
172
+ return embeddingProvider?.vector(for: word)?.map { Float($0) }
173
+ }
174
+
175
+ // Process through neural network
176
+ let inputFeatures = try createInputFeatures(embeddings: embeddings, context: context)
177
+ let prediction = try model?.prediction(from: inputFeatures)
178
+
179
+ // Interpret model output into structured analysis
180
+ return try interpretModelOutput(prediction)
181
+ }
182
+
183
+ /// Create ML features from text embeddings and context
184
+ private func createInputFeatures(embeddings: [[Float]], context: Context) throws -> MLFeatureProvider {
185
+ // Combine embeddings with context into ML features
186
+ // Implementation would depend on specific model architecture
187
+ fatalError("Implementation required based on model architecture")
188
+ }
189
+
190
+ /// Interpret raw model output into structured analysis
191
+ private func interpretModelOutput(_ output: MLFeatureProvider?) throws -> Analysis {
192
+ // Transform model outputs into semantically meaningful structures
193
+ // Implementation would depend on model architecture and output format
194
+ fatalError("Implementation required based on model architecture")
195
+ }
196
+
197
+ /// Generate informational responses based on analysis
198
+ func generateInformationalResponse(for analysis: DeepAnalysis) async throws -> AtlasResponse {
199
+ // Generate coherent, informative response based on analysis
200
+ // Uses the model to generate natural language from semantic representation
201
+ fatalError("Implementation required")
202
+ }
203
+
204
+ /// Generate conversational responses
205
+ func generateConversationalResponse(for analysis: DeepAnalysis) async throws -> AtlasResponse {
206
+ // Generate natural-sounding conversational response
207
+ fatalError("Implementation required")
208
+ }
209
+ }
210
+
211
+ // RecursiveThinking.swift - Implements multi-step reasoning
212
+ import Foundation
213
+ import CoreML
214
+
215
+ /// Advanced reasoning capabilities with recursive processing
216
+ class RecursiveThinking {
217
+ private var model: MLModel?
218
+
219
+ func loadModel(named name: String) throws {
220
+ let modelURL = Bundle.main.url(forResource: name, withExtension: "mlmodelc")!
221
+ self.model = try MLModel(contentsOf: modelURL)
222
+ }
223
+
224
+ /// Process input through multiple reasoning steps
225
+ func deepProcess(input: String, initialAnalysis: Analysis, maxRecursionDepth: Int) async throws -> DeepAnalysis {
226
+ var currentAnalysis = initialAnalysis
227
+ var reasoning: [ReasoningStep] = []
228
+
229
+ // Recursive reasoning process
230
+ for depth in 0..<maxRecursionDepth {
231
+ // Generate questions about own analysis
232
+ let questions = generateSelfQuestions(from: currentAnalysis, depth: depth)
233
+
234
+ // Answer each question to refine understanding
235
+ let refinements = try await questions.map { question in
236
+ try await answerSelfQuestion(question, currentAnalysis: currentAnalysis)
237
+ }
238
+
239
+ // Integrate refinements into analysis
240
+ currentAnalysis = integrateRefinements(currentAnalysis, refinements: refinements)
241
+
242
+ // Record reasoning step
243
+ reasoning.append(ReasoningStep(
244
+ depth: depth,
245
+ questions: questions,
246
+ refinements: refinements
247
+ ))
248
+
249
+ // Check if further refinement would be beneficial
250
+ if isRefinementComplete(currentAnalysis, reasoning: reasoning) {
251
+ break
252
+ }
253
+ }
254
+
255
+ // Construct final deep analysis
256
+ return DeepAnalysis(
257
+ baseAnalysis: initialAnalysis,
258
+ refinedAnalysis: currentAnalysis,
259
+ reasoningSteps: reasoning
260
+ )
261
+ }
262
+
263
+ /// Generate questions to probe understanding
264
+ private func generateSelfQuestions(from analysis: Analysis, depth: Int) -> [String] {
265
+ // Implementation would generate relevant questions about current understanding
266
+ fatalError("Implementation required")
267
+ }
268
+
269
+ /// Answer self-generated questions to refine understanding
270
+ private func answerSelfQuestion(_ question: String, currentAnalysis: Analysis) async throws -> Refinement {
271
+ // Implementation would answer questions using current understanding
272
+ fatalError("Implementation required")
273
+ }
274
+
275
+ /// Integrate refinements into current analysis
276
+ private func integrateRefinements(_ analysis: Analysis, refinements: [Refinement]) -> Analysis {
277
+ // Implementation would update analysis with new insights
278
+ fatalError("Implementation required")
279
+ }
280
+
281
+ /// Determine if refinement process is complete
282
+ private func isRefinementComplete(_ analysis: Analysis, reasoning: [ReasoningStep]) -> Bool {
283
+ // Implementation would check if further refinement would be beneficial
284
+ fatalError("Implementation required")
285
+ }
286
+ }
287
+
288
+ // ContextManager.swift - Manages conversational context
289
+ import Foundation
290
+
291
+ /// Manages and updates conversation context
292
+ class ContextManager {
293
+ private var contextHistory: [Context] = []
294
+
295
+ /// Get current context for processing
296
+ func getCurrentContext() -> Context {
297
+ return contextHistory.last ?? Context.empty
298
+ }
299
+
300
+ /// Update context with new interaction
301
+ func updateContext(with input: String, response: AtlasResponse) {
302
+ let newContext = Context(
303
+ timestamp: Date(),
304
+ userInput: input,
305
+ systemResponse: response,
306
+ previousContext: getCurrentContext()
307
+ )
308
+
309
+ contextHistory.append(newContext)
310
+
311
+ // Trim context history if too long
312
+ if contextHistory.count > 10 {
313
+ contextHistory.removeFirst()
314
+ }
315
+ }
316
+ }
317
+
318
+ // --------- 3. VISION OS INTEGRATION ---------
319
+
320
+ // VisionInterface.swift - Interface with VisionOS
321
+ import SwiftUI
322
+ import RealityKit
323
+ import RealityKitContent
324
+
325
+ /// Manages integration with VisionOS spatial environment
326
+ struct VisionInterface {
327
+ private let spatialComputing: SpatialComputing
328
+
329
+ init() {
330
+ self.spatialComputing = SpatialComputing()
331
+ }
332
+
333
+ /// Create immersive UI element
334
+ func createImmersiveElement(for response: AtlasResponse) -> some View {
335
+ // If response includes spatial content
336
+ if response.hasSpatialContent {
337
+ return spatialComputing.createSpatialView(for: response)
338
+ } else {
339
+ // Return standard UI element
340
+ return AtlasResponseView(response: response)
341
+ }
342
+ }
343
+
344
+ /// Process spatial gestures
345
+ func processGesture(_ gesture: SpatialGesture) -> GestureIntent {
346
+ return spatialComputing.interpretGesture(gesture)
347
+ }
348
+
349
+ /// Interpret environment data
350
+ func processEnvironmentData(_ environmentData: EnvironmentData) -> EnvironmentContext {
351
+ return spatialComputing.analyzeEnvironment(environmentData)
352
+ }
353
+ }
354
+
355
+ // SpatialComputing.swift - Handles spatial computing features
356
+ import RealityKit
357
+ import ARKit
358
+ import SwiftUI
359
+
360
+ /// Core spatial computing capabilities
361
+ struct SpatialComputing {
362
+ /// Create a spatial interface for responses
363
+ func createSpatialView(for response: AtlasResponse) -> some View {
364
+ // Create appropriate spatial UI elements based on response type
365
+ switch response.spatialContentType {
366
+ case .floatingPanel:
367
+ return FloatingPanelView(content: response.content)
368
+ case .virtualObject:
369
+ return VirtualObjectView(model: response.modelContent)
370
+ case .environmentOverlay:
371
+ return EnvironmentOverlayView(overlay: response.overlayContent)
372
+ default:
373
+ return DefaultResponseView(response: response)
374
+ }
375
+ }
376
+
377
+ /// Interpret spatial gestures
378
+ func interpretGesture(_ gesture: SpatialGesture) -> GestureIntent {
379
+ // Analyze gesture and determine user intent
380
+ switch gesture.type {
381
+ case .tap:
382
+ return GestureIntent.select(position: gesture.position)
383
+ case .swipe:
384
+ return GestureIntent.scroll(direction: gesture.direction)
385
+ case .pinch:
386
+ return GestureIntent.zoom(scale: gesture.scale)
387
+ default:
388
+ return GestureIntent.unknown
389
+ }
390
+ }
391
+
392
+ /// Analyze spatial environment
393
+ func analyzeEnvironment(_ environmentData: EnvironmentData) -> EnvironmentContext {
394
+ // Process environment data to provide context to AI
395
+ let surfaces = detectSurfaces(from: environmentData.depthData)
396
+ let lighting = analyzeLighting(from: environmentData.lightEstimate)
397
+ let objects = identifyObjects(from: environmentData.sceneReconstruction)
398
+
399
+ return EnvironmentContext(
400
+ surfaces: surfaces,
401
+ lighting: lighting,
402
+ identifiedObjects: objects,
403
+ spatialAnchors: environmentData.anchors
404
+ )
405
+ }
406
+
407
+ // Helper functions for environment analysis
408
+ private func detectSurfaces(from depthData: ARDepthData) -> [Surface] {
409
+ // Implementation to detect surfaces from depth data
410
+ fatalError("Implementation required")
411
+ }
412
+
413
+ private func analyzeLighting(from lightEstimate: ARLightEstimate) -> LightingContext {
414
+ // Implementation to analyze lighting conditions
415
+ fatalError("Implementation required")
416
+ }
417
+
418
+ private func identifyObjects(from sceneReconstruction: ARSceneReconstruction) -> [IdentifiedObject] {
419
+ // Implementation to identify objects in environment
420
+ fatalError("Implementation required")
421
+ }
422
+ }
423
+
424
+ // RealityViews.swift - SwiftUI views for VisionOS
425
+ import SwiftUI
426
+ import RealityKit
427
+
428
+ /// Floating panel view for Atlas responses
429
+ struct FloatingPanelView: View {
430
+ let content: String
431
+
432
+ var body: some View {
433
+ VStack {
434
+ Text("Atlas Intelligence")
435
+ .font(.headline)
436
+
437
+ Divider()
438
+
439
+ Text(content)
440
+ .padding()
441
+
442
+ // Interactive elements would go here
443
+ HStack {
444
+ Button("More") {
445
+ // Expand view
446
+ }
447
+
448
+ Spacer()
449
+
450
+ Button("Respond") {
451
+ // Activate voice response
452
+ }
453
+ }
454
+ .padding()
455
+ }
456
+ .frame(width: 400, height: 300)
457
+ .background(.ultraThinMaterial)
458
+ .cornerRadius(20)
459
+ .hoverEffect()
460
+ }
461
+ }
462
+
463
+ /// Virtual 3D object view
464
+ struct VirtualObjectView: View {
465
+ let model: ModelEntity
466
+
467
+ var body: some View {
468
+ RealityView { content in
469
+ content.add(model)
470
+ }
471
+ .gesture(TapGesture().onEnded { _ in
472
+ // Handle interaction with virtual object
473
+ })
474
+ }
475
+ }
476
+
477
+ /// Environment overlay view
478
+ struct EnvironmentOverlayView: View {
479
+ let overlay: EnvironmentOverlay
480
+
481
+ var body: some View {
482
+ ZStack {
483
+ // Render overlay elements
484
+ ForEach(overlay.elements) { element in
485
+ element.view
486
+ .position(element.position)
487
+ }
488
+ }
489
+ }
490
+ }
491
+
492
+ /// Default response view
493
+ struct DefaultResponseView: View {
494
+ let response: AtlasResponse
495
+
496
+ var body: some View {
497
+ Text(response.content)
498
+ .padding()
499
+ .background(.ultraThinMaterial)
500
+ .cornerRadius(12)
501
+ }
502
+ }
503
+
504
+ // --------- 4. INTEGRATION COMPONENTS ---------
505
+
506
+ // AppleIntelligence.swift - Integration with Apple's AI systems
507
+ import Foundation
508
+ import NaturalLanguage
509
+ import Vision
510
+ import SoundAnalysis
511
+
512
+ /// Integration with Apple Intelligence
513
+ class AppleIntelligence {
514
+ private let audioEngine: SNAudioEngine
515
+ private let visionProcessor: VNImageRequestHandler
516
+
517
+ init() {
518
+ self.audioEngine = SNAudioEngine()
519
+ self.visionProcessor = VNImageRequestHandler()
520
+ }
521
+
522
+ /// Execute spatial commands using Apple Intelligence
523
+ func executeSpatialCommand(_ command: ActionRequest) async throws -> AtlasResponse {
524
+ // Delegate to appropriate Apple system based on command
525
+ switch command.spatialType {
526
+ case .objectDetection:
527
+ return try await performObjectDetection(command)
528
+ case .spatialAudio:
529
+ return try await configureSpatialAudio(command)
530
+ case .textRecognition:
531
+ return try await performTextRecognition(command)
532
+ default:
533
+ throw IntegrationError.unsupportedSpatialCommand
534
+ }
535
+ }
536
+
537
+ /// Perform object detection
538
+ private func performObjectDetection(_ command: ActionRequest) async throws -> AtlasResponse {
539
+ // Implementation would use Vision framework for object detection
540
+ fatalError("Implementation required")
541
+ }
542
+
543
+ /// Configure spatial audio
544
+ private func configureSpatialAudio(_ command: ActionRequest) async throws -> AtlasResponse {
545
+ // Implementation would configure spatial audio
546
+ fatalError("Implementation required")
547
+ }
548
+
549
+ /// Perform text recognition in environment
550
+ private func performTextRecognition(_ command: ActionRequest) async throws -> AtlasResponse {
551
+ // Implementation would use Vision framework for text recognition
552
+ fatalError("Implementation required")
553
+ }
554
+ }
555
+
556
+ // TeslaConnection.swift - Integration with Tesla API
557
+ import Foundation
558
+
559
+ /// Integration with Tesla vehicles
560
+ class TeslaConnection {
561
+ private let apiClient: TeslaAPIClient
562
+ private var authToken: String?
563
+
564
+ init() {
565
+ self.apiClient = TeslaAPIClient()
566
+ }
567
+
568
+ /// Authenticate with Tesla API
569
+ func authenticate(using credentials: TeslaCredentials) async throws {
570
+ self.authToken = try await apiClient.authenticate(credentials)
571
+ }
572
+
573
+ /// Execute commands on Tesla vehicle
574
+ func executeCommand(_ command: ActionRequest) async throws -> AtlasResponse {
575
+ guard let authToken = authToken else {
576
+ throw TeslaError.notAuthenticated
577
+ }
578
+
579
+ // Execute command via Tesla API
580
+ switch command.teslaCommandType {
581
+ case .climate:
582
+ return try await executeClimateCommand(command, token: authToken)
583
+ case .charging:
584
+ return try await executeChargingCommand(command, token: authToken)
585
+ case .vehicle:
586
+ return try await executeVehicleCommand(command, token: authToken)
587
+ default:
588
+ throw TeslaError.unsupportedCommand
589
+ }
590
+ }
591
+
592
+ /// Tesla API interaction for climate controls
593
+ private func executeClimateCommand(_ command: ActionRequest, token: String) async throws -> AtlasResponse {
594
+ let response = try await apiClient.executeClimateCommand(
595
+ vehicleId: command.vehicleId,
596
+ settings: command.climateSettings,
597
+ token: token
598
+ )
599
+
600
+ return AtlasResponse(
601
+ content: "Climate control settings updated. Current temperature: \(response.currentTemp)°F",
602
+ status: .success,
603
+ actionPerformed: .teslaClimateControl
604
+ )
605
+ }
606
+
607
+ /// Tesla API interaction for charging functions
608
+ private func executeChargingCommand(_ command: ActionRequest, token: String) async throws -> AtlasResponse {
609
+ let response = try await apiClient.executeChargingCommand(
610
+ vehicleId: command.vehicleId,
611
+ settings: command.chargingSettings,
612
+ token: token
613
+ )
614
+
615
+ return AtlasResponse(
616
+ content: "Charging settings updated. Current charge level: \(response.chargeLevel)%, estimated completion: \(response.estimatedCompletion)",
617
+ status: .success,
618
+ actionPerformed: .teslaChargingControl
619
+ )
620
+ }
621
+
622
+ /// Tesla API interaction for vehicle functions
623
+ private func executeVehicleCommand(_ command: ActionRequest, token: String) async throws -> AtlasResponse {
624
+ let response = try await apiClient.executeVehicleCommand(
625
+ vehicleId: command.vehicleId,
626
+ command: command.vehicleCommand,
627
+ parameters: command.vehicleParameters,
628
+ token: token
629
+ )
630
+
631
+ return AtlasResponse(
632
+ content: "Vehicle command executed: \(response.commandExecuted)",
633
+ status: response.success ? .success : .failure,
634
+ actionPerformed: .teslaVehicleControl
635
+ )
636
+ }
637
+ }
638
+
639
+ /// Tesla API client for direct API interactions
640
+ class TeslaAPIClient {
641
+ private let baseURL = URL(string: "https://owner-api.teslamotors.com/api/1")!
642
+
643
+ /// Authenticate with Tesla API
644
+ func authenticate(_ credentials: TeslaCredentials) async throws -> String {
645
+ // Implementation would handle OAuth authentication with Tesla
646
+ // Returns auth token
647
+ fatalError("Implementation required")
648
+ }
649
+
650
+ /// Execute climate control commands
651
+ func executeClimateCommand(vehicleId: String, settings: ClimateSettings, token: String) async throws -> ClimateResponse {
652
+ // Implementation would execute climate control API calls
653
+ fatalError("Implementation required")
654
+ }
655
+
656
+ /// Execute charging commands
657
+ func executeChargingCommand(vehicleId: String, settings: ChargingSettings, token: String) async throws -> ChargingResponse {
658
+ // Implementation would execute charging API calls
659
+ fatalError("Implementation required")
660
+ }
661
+
662
+ /// Execute general vehicle commands
663
+ func executeVehicleCommand(vehicleId: String, command: String, parameters: [String: Any], token: String) async throws -> VehicleCommandResponse {
664
+ // Implementation would execute vehicle command API calls
665
+ fatalError("Implementation required")
666
+ }
667
+ }
668
+
669
+ // iCloudSync.swift - Integration with iCloud
670
+ import Foundation
671
+ import CloudKit
672
+
673
+ /// iCloud data synchronization
674
+ class iCloudSync {
675
+ private let container: CKContainer
676
+ private let database: CKDatabase
677
+
678
+ init() {
679
+ self.container = CKContainer.default()
680
+ self.database = container.privateCloudDatabase
681
+ }
682
+
683
+ /// Save user preferences to iCloud
684
+ func savePreferences(_ preferences: UserPreferences) async throws {
685
+ let record = CKRecord(recordType: "AtlasPreferences")
686
+ record["settings"] = try JSONEncoder().encode(preferences)
687
+
688
+ try await database.save(record)
689
+ }
690
+
691
+ /// Load user preferences from iCloud
692
+ func loadPreferences() async throws -> UserPreferences {
693
+ let query = CKQuery(recordType: "AtlasPreferences", predicate: NSPredicate(value: true))
694
+ let result = try await database.records(matching: query)
695
+
696
+ guard let record = result.matchResults.first?.1.get() else {
697
+ return UserPreferences.default
698
+ }
699
+
700
+ guard let data = record["settings"] as? Data else {
701
+ return UserPreferences.default
702
+ }
703
+
704
+ return try JSONDecoder().decode(UserPreferences.self, from: data)
705
+ }
706
+
707
+ /// Store interaction history
708
+ func saveInteractionHistory(_ history: InteractionHistory) async throws {
709
+ let record = CKRecord(recordType: "AtlasHistory")
710
+ record["history"] = try JSONEncoder().encode(history)
711
+ record["timestamp"] = Date()
712
+
713
+ try await database.save(record)
714
+ }
715
+
716
+ /// Load interaction history from iCloud
717
+ func loadInteractionHistory(limit: Int = 100) async throws -> [InteractionHistory] {
718
+ let query = CKQuery(
719
+ recordType: "AtlasHistory",
720
+ predicate: NSPredicate(value: true)
721
+ )
722
+ query.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: false)]
723
+
724
+ let result = try await database.records(matching: query, resultsLimit: limit)
725
+
726
+ return try result.matchResults.compactMap { _, recordResult in
727
+ let record = try recordResult.get()
728
+ guard let data = record["history"] as? Data else { return nil }
729
+ return try JSONDecoder().decode(InteractionHistory.self, from: data)
730
+ }
731
+ }
732
+ }
733
+
734
+ // --------- 5. PAYMENT INTEGRATION ---------
735
+
736
+ // TapToPay.swift - Apple Pay integration
737
+ import Foundation
738
+ import PassKit
739
+
740
+ /// Tap to Pay payment processing
741
+ class TapToPay: NSObject, PKPaymentAuthorizationControllerDelegate {
742
+ private var completion: ((Result<PaymentResponse, Error>) -> Void)?
743
+
744
+ /// Process a payment request
745
+ func processPayment(_ details: PaymentDetails) async throws -> AtlasResponse {
746
+ // Verify security requirements
747
+ guard details.isSecureContext else {
748
+ throw PaymentError.unsecureContext
749
+ }
750
+
751
+ // Configure payment request
752
+ let request = createPaymentRequest(from: details)
753
+
754
+ // Process payment through Apple Pay
755
+ return try await withCheckedThrowingContinuation { continuation in
756
+ self.completion = { result in
757
+ switch result {
758
+ case .success(let response):
759
+ let atlasResponse = AtlasResponse(
760
+ content: "Payment of \(details.amount) \(details.currency) completed successfully.",
761
+ status: .success,
762
+ actionPerformed: .payment
763
+ )
764
+ continuation.resume(returning: atlasResponse)
765
+
766
+ case .failure(let error):
767
+ continuation.resume(throwing: error)
768
+ }
769
+ }
770
+
771
+ let controller = PKPaymentAuthorizationController(paymentRequest: request)
772
+ controller.delegate = self
773
+ controller.present(completion: { presented in
774
+ if !presented {
775
+ self.completion?(.failure(PaymentError.presentationFailed))
776
+ }
777
+ })
778
+ }
779
+ }
780
+
781
+ /// Create Apple Pay payment request
782
+ private func createPaymentRequest(from details: PaymentDetails) -> PKPaymentRequest {
783
+ let request = PKPaymentRequest()
784
+
785
+ request.merchantIdentifier = "merchant.com.atlas.intelligence"
786
+ request.countryCode = details.countryCode
787
+ request.currencyCode = details.currency
788
+ request.supportedNetworks = [.visa, .masterCard, .amex]
789
+ request.merchantCapabilities = [.capability3DS, .capabilityDebit, .capabilityCredit]
790
+
791
+ // Add payment items
792
+ let total = PKPaymentSummaryItem(
793
+ label: details.description,
794
+ amount: NSDecimalNumber(value: details.amount)
795
+ )
796
+ request.paymentSummaryItems = [total]
797
+
798
+ return request
799
+ }
800
+
801
+ // MARK: - PKPaymentAuthorizationControllerDelegate
802
+
803
+ func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
804
+ didAuthorizePayment payment: PKPayment,
805
+ handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
806
+ // Process payment with payment processor
807
+ processPaymentWithProcessor(payment) { success, error in
808
+ if success {
809
+ self.completion?(.success(PaymentResponse(
810
+ transactionId: UUID().uuidString,
811
+ timestamp: Date()
812
+ )))
813
+ completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
814
+ } else {
815
+ self.completion?(.failure(error ?? PaymentError.unknown))
816
+ completion(PKPaymentAuthorizationResult(status: .failure, errors: [error].compactMap { $0 as NSError }))
817
+ }
818
+ }
819
+ }
820
+
821
+ func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
822
+ controller.dismiss {}
823
+ }
824
+
825
+ /// Process payment with backend payment processor
826
+ private func processPaymentWithProcessor(_ payment: PKPayment, completion: @escaping (Bool, Error?) -> Void) {
827
+ // In a real app, this would connect to your payment processor
828
+ // For this example, we'll simulate a successful payment
829
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
830
+ completion(true, nil)
831
+ }
832
+ }
833
+ }
834
+
835
+ // --------- 6. APP IMPLEMENTATION ---------
836
+
837
+ // AtlasApp.swift - Main app implementation
838
+ import SwiftUI
839
+
840
+ /// Main Atlas Intelligence app
841
+ @main
842
+ struct AtlasApp: App {
843
+ // Core systems
844
+ @StateObject private var atlasCore = AtlasCoreViewModel()
845
+
846
+ // Environment objects
847
+ @StateObject private var visionSystem = VisionSystem()
848
+ @StateObject private var teslaSystem = TeslaSystem()
849
+
850
+ var body: some Scene {
851
+ WindowGroup {
852
+ ContentView()
853
+ .environmentObject(atlasCore)
854
+ .environmentObject(visionSystem)
855
+ .environmentObject(teslaSystem)
856
+ }
857
+
858
+ // Add immersive space for VisionOS
859
+ ImmersiveSpace(id: "AtlasSpace") {
860
+ AtlasImmersiveView()
861
+ .environmentObject(atlasCore)
862
+ .environmentObject(visionSystem)
863
+ }
864
+ }
865
+ }
866
+
867
+ /// Main content view
868
+ struct ContentView: View {
869
+ @EnvironmentObject var atlasCore: AtlasCoreViewModel
870
+ @State private var userInput: String = ""
871
+
872
+ var body: some View {
873
+ VStack {
874
+ // Response display area
875
+ ScrollView {
876
+ VStack(alignment: .leading) {
877
+ ForEach(atlasCore.conversationHistory) { item in
878
+ ConversationItemView(item: item)
879
+ }
880
+ }
881
+ .padding()
882
+ }
883
+
884
+ // Input area
885
+ HStack {
886
+ TextField("Ask Atlas...", text: $userInput)
887
+ .textFieldStyle(RoundedBorderTextFieldStyle())
888
+ .padding()
889
+
890
+ Button(action: {
891
+ Task {
892
+ await atlasCore.processInput(userInput)
893
+ userInput = ""
894
+ }
895
+ }) {
896
+ Image(systemName: "arrow.up.circle.fill")
897
+ .resizable()
898
+ .frame(width: 30, height: 30)
899
+ }
900
+ .padding(.trailing)
901
+ }
902
+ }
903
+ }
904
+ }
905
+
906
+ /// Immersive view for VisionOS
907
+ struct AtlasImmersiveView: View {
908
+ @EnvironmentObject var atlasCore: AtlasCoreViewModel
909
+ @EnvironmentObject var visionSystem: VisionSystem
910
+
911
+ var body: some View {
912
+ ZStack {
913
+ // Render spatial elements based on context
914
+ if let spatialContent = atlasCore.currentSpatialContent {
915
+ ForEach(spatialContent.elements) { element in
916
+ element.view
917
+ .position(element.position)
918
+ }
919
+ }
920
+
921
+ // Voice indicator when speaking
922
+ if atlasCore.isProcessing {
923
+ VoiceProcessingIndicator()
924
+ }
925
+ }
926
+ }
927
+ }
928
+
929
+ /// View model for Atlas Core
930
+ class AtlasCoreViewModel: ObservableObject {
931
+ private let atlasCore = AtlasCore()
932
+
933
+ @Published var conversationHistory: [ConversationItem] = []
934
+ @Published var isProcessing: Bool = false
935
+ @Published var currentSpatialContent: SpatialContent?
936
+
937
+ /// Process user input
938
+ func processInput(_ input: String) async {
939
+ guard !input.isEmpty else { return }
940
+
941
+ await MainActor.run {
942
+ isProcessing = true
943
+ // Add user message to conversation
944
+ conversationHistory.append(ConversationItem(
945
+ id: UUID(),
946
+ text: input,
947
+ isUser: true,
948
+ timestamp: Date()
949
+ ))
950
+ }
951
+
952
+ do {
953
+ // Process through Atlas Core
954
+ let context = UserContext(
955
+ isAuthenticated: true,
956
+ paymentAuthorized: false,
957
+ spatialContext: nil
958
+ )
959
+
960
+ let response = try await atlasCore.processInput(input, context: context)
961
+
962
+ await MainActor.run {
963
+ // Add response to conversation
964
+ conversationHistory.append(ConversationItem(
965
+ id: UUID(),
966
+ text: response.content,
967
+ isUser: false,
968
+ timestamp: Date()
969
+ ))
970
+
971
+ // Update spatial content if available
972
+ if response.hasSpatialContent {
973
+ currentSpatialContent = response.spatialContent
974
+ }
975
+
976
+ isProcessing = false
977
+ }
978
+ } catch {
979
+ await MainActor.run {
980
+ // Add error response
981
+ conversationHistory.append(ConversationItem(
982
+ id: UUID(),
983
+ text: "Sorry, I encountered an error: \(error.localizedDescription)",
984
+ isUser: false,
985
+ timestamp: Date()
986
+ ))
987
+
988
+ isProcessing = false
989
+ }
990
+ }
991
+ }
992
+ }
993
+
994
+ // --------- 7. DATA MODELS ---------
995
+
996
+ /// User context for request processing
997
+ struct UserContext {
998
+ let isAuthenticated: Bool
999
+ let paymentAuthorized: Bool
1000
+ let spatialContext: SpatialContext?
1001
+ }
1002
+
1003
+ /// Conversation context
1004
+ struct Context {
1005
+ let timestamp: Date
1006
+ let userInput: String
1007
+ let systemResponse: AtlasResponse
1008
+ let previousContext: Context?
1009
+
1010
+ static var empty: Context {
1011
+ return Context(
1012
+ timestamp: Date(),
1013
+ userInput: "",
1014
+ systemResponse: AtlasResponse(content: "", status: .unknown, actionPerformed: nil),
1015
+ previousContext: nil
1016
+ )
1017
+ }
1018
+ }
1019
+
1020
+ /// Atlas response data model
1021
+ struct AtlasResponse {
1022
+ let content: String
1023
+ let status: ResponseStatus
1024
+ let actionPerformed: ActionType?
1025
+ var hasSpatialContent: Bool = false
1026
+ var spatialContent: SpatialContent?
1027
+ var spatialContentType: SpatialContentType?
1028
+ var modelContent: ModelEntity?
1029
+ var overlayContent: EnvironmentOverlay?
1030
+
1031
+ enum ResponseStatus {
1032
+ case success
1033
+ case failure
1034
+ case unknown
1035
+ }
1036
+
1037
+ enum ActionType {
1038
+ case teslaClimateControl
1039
+ case teslaChargingControl
1040
+ case teslaVehicleControl
1041
+ case payment
1042
+ case spatialVisualization
1043
+ }
1044
+
1045
+ enum SpatialContentType {
1046
+ case floatingPanel
1047
+ case virtualObject
1048
+ case environmentOverlay
1049
+ case none
1050
+ }
1051
+ }
1052
+
1053
+ /// Data model for conversation items
1054
+ struct ConversationItem: Identifiable {
1055
+ let id: UUID
1056
+ let text: String
1057
+ let isUser: Bool
1058
+ let timestamp: Date
1059
+ }
1060
+
1061
+ /// Spatial content model
1062
+ struct SpatialContent {
1063
+ var elements: [SpatialElement]
1064
+
1065
+ struct SpatialElement: Identifiable {
1066
+ let id: UUID
1067
+ let position: CGPoint
1068
+ let view: AnyView
1069
+ }
1070
+ }
1071
+
1072
+ /// Environment overlay model
1073
+ struct EnvironmentOverlay {
1074
+ var elements: [OverlayElement]
1075
+
1076
+ struct OverlayElement: Identifiable {
1077
+ let id: UUID
1078
+ let position: CGPoint
1079
+ let view: AnyView
1080
+ }
1081
+ }
1082
+
1083
+ /// Model for deep thought analysis
1084
+ struct DeepAnalysis {
1085
+ let baseAnalysis: Analysis
1086
+ let refinedAnalysis: Analysis
1087
+ let reasoningSteps: [ReasoningStep]
1088
+
1089
+ var primaryIntent: Intent {
1090
+ return refinedAnalysis.intent
1091
+ }
1092
+
1093
+ var actionRequest: ActionRequest {
1094
+ return refinedAnalysis.actionRequest
1095
+ }
1096
+
1097
+ enum Intent {
1098
+ case informationQuery
1099
+ case actionRequest
1100
+ case conversation
1101
+ case unknown
1102
+ }
1103
+ }
1104
+
1105
+ /// Initial analysis structure
1106
+ struct Analysis {
1107
+ let intent: DeepAnalysis.Intent
1108
+ let entities: [Entity]
1109
+ let sentiment: Float
1110
+ let actionRequest: ActionRequest
1111
+
1112
+ struct Entity {
1113
+ let text: String
1114
+ let type: EntityType
1115
+
1116
+ enum EntityType {
1117
+ case person
1118
+ case location
1119
+ case date
1120
+ case organization
1121
+ case product
1122
+ case custom(String)
1123
+ }
1124
+ }
1125
+ }
1126
+
1127
+ /// Action request model
1128
+ struct ActionRequest {
1129
+ let type: ActionType
1130
+ let payload: [String: Any]
1131
+
1132
+ // Tesla-specific properties
1133
+ var vehicleId: String {
1134
+ return payload["vehicleId"] as? String ?? ""
1135
+ }
1136
+
1137
+ var teslaCommandType: TeslaCommandType {
1138
+ let rawValue = payload["teslaCommandType"] as? String ?? ""
1139
+ return TeslaCommandType(rawValue: rawValue) ?? .unknown
1140
+ }
1141
+
1142
+ var climateSettings: ClimateSettings {
1143
+ return payload["climateSettings"] as? ClimateSettings ?? ClimateSettings()
1144
+ }
1145
+
1146
+ var chargingSettings: ChargingSettings {
1147
+ return payload["chargingSettings"] as? ChargingSettings ?? ChargingSettings()
1148
+ }
1149
+
1150
+ var vehicleCommand: String {
1151
+ return payload["vehicleCommand"] as? String ?? ""
1152
+ }
1153
+
1154
+ var vehicleParameters: [String: Any] {
1155
+ return payload["vehicleParameters"] as? [String: Any] ?? [:]
1156
+ }
1157
+
1158
+ // Spatial-specific properties
1159
+ var spatialType: SpatialCommandType {
1160
+ let rawValue = payload["spatialType"] as? String ?? ""
1161
+ return SpatialCommandType(rawValue: rawValue) ?? .unknown
1162
+ }
1163
+
1164
+ // Payment-specific properties
1165
+ var paymentDetails: PaymentDetails {
1166
+ return payload["paymentDetails"] as? PaymentDetails ?? PaymentDetails()
1167
+ }
1168
+
1169
+ var isSecureContext: Bool {
1170
+ return payload["isSecureContext"] as? Bool ?? false
1171
+ }
1172
+
1173
+ enum ActionType {
1174
+ case teslaControl
1175
+ case payment
1176
+ case appleSpatial
1177
+ case unknown
1178
+ }
1179
+
1180
+ enum TeslaCommandType: String {
1181
+ case climate
1182
+ case charging
1183
+ case vehicle
1184
+ case unknown
1185
+ }
1186
+
1187
+ enum SpatialCommandType: String {
1188
+ case objectDetection
1189
+ case spatialAudio
1190
+ case textRecognition
1191
+ case unknown
1192
+ }
1193
+ }
1194
+
1195
+ /// Step in the recursive thinking process
1196
+ struct ReasoningStep {
1197
+ let depth: Int
1198
+ let questions: [String]
1199
+ let refinements: [Refinement]
1200
+
1201
+ struct Refinement {
1202
+ let question: String
1203
+ let answer: String
1204
+ let confidenceScore: Float
1205
+ }
1206
+ }
1207
+
1208
+ /// Climate settings for Tesla
1209
+ struct ClimateSettings {
1210
+ var targetTemperature: Float = 70.0
1211
+ var acEnabled: Bool = true
1212
+ var seatHeaters: [Int: Int] = [:]
1213
+ var defrostMode: Bool = false
1214
+ }
1215
+
1216
+ /// Charging settings for Tesla
1217
+ struct ChargingSettings {
1218
+ var chargeLimit: Int = 80
1219
+ var scheduleEnabled: Bool = false
1220
+ var scheduleTime: Date?
1221
+ }
1222
+
1223
+ /// Response from climate control command
1224
+ struct ClimateResponse {
1225
+ let success: Bool
1226
+ let currentTemp: Float
1227
+ let targetTemp: Float
1228
+ let acStatus: Bool
1229
+ }
1230
+
1231
+ /// Response from charging command
1232
+ struct ChargingResponse {
1233
+ let success: Bool
1234
+ let chargeLevel: Int
1235
+ let estimatedCompletion: String
1236
+ let chargingState: String
1237
+ }
1238
+
1239
+ /// Response from vehicle command
1240
+ struct VehicleCommandResponse {
1241
+ let success: Bool
1242
+ let commandExecuted: String
1243
+ let result: [String: Any]
1244
+ }
1245
+
1246
+ /// Payment details model
1247
+ struct PaymentDetails {
1248
+ var amount: Double = 0
1249
+ var currency: String = "USD"
1250
+ var description: String = ""
1251
+ var countryCode: String = "US"
1252
+ var isSecureContext: Bool = false
1253
+ }
1254
+
1255
+ /// Payment response model
1256
+ struct PaymentResponse {
1257
+ let transactionId: String
1258
+ let timestamp: Date
1259
+ }
1260
+
1261
+ /// User preferences model
1262
+ struct UserPreferences: Codable {
1263
+ var theme: Theme
1264
+ var notifications: NotificationPreferences
1265
+ var accessibility: AccessibilityPreferences
1266
+
1267
+ static var `default`: UserPreferences {
1268
+ return UserPreferences(
1269
+ theme: .system,
1270
+ notifications: NotificationPreferences(),
1271
+ accessibility: AccessibilityPreferences()
1272
+ )
1273
+ }
1274
+
1275
+ enum Theme: String, Codable {
1276
+ case light
1277
+ case dark
1278
+ case system
1279
+ }
1280
+
1281
+ struct NotificationPreferences: Codable {
1282
+ var enabled: Bool = true
1283
+ var soundEnabled: Bool = true
1284
+ var hapticEnabled: Bool = true
1285
+ }
1286
+
1287
+ struct AccessibilityPreferences: Codable {
1288
+ var largeText: Bool = false
1289
+ var highContrast: Bool = false
1290
+ var reduceMotion: Bool = false
1291
+ }
1292
+ }
1293
+
1294
+ /// Interaction history model
1295
+ struct InteractionHistory: Codable {
1296
+ let timestamp: Date
1297
+ let userInput: String
1298
+ let systemResponse: String
1299
+ let actions: [String]
1300
+ }
1301
+
1302
+ // --------- 8. ERROR TYPES ---------
1303
+
1304
+ /// Atlas system errors
1305
+ enum AtlasError: Error {
1306
+ case unrecognizedIntent
1307
+ case unsupportedAction
1308
+ case unauthorizedPayment
1309
+ case modelLoadingFailed
1310
+ }
1311
+
1312
+ /// Integration errors
1313
+ enum IntegrationError: Error {
1314
+ case unsupportedSpatialCommand
1315
+ case appleIntelligenceNotAvailable
1316
+ }
1317
+
1318
+ /// Tesla API errors
1319
+ enum TeslaError: Error {
1320
+ case notAuthenticated
1321
+ case unsupportedCommand
1322
+ case apiError(String)
1323
+ case vehicleOffline
1324
+ }
1325
+
1326
+ /// Payment errors
1327
+ enum PaymentError: Error {
1328
+ case unsecureContext
1329
+ case authorizationFailed
1330
+ case presentationFailed
1331
+ case processingFailed
1332
+ case unknown
1333
+ }
1334
+
1335
+ // --------- 9. ADDITIONAL SUPPORTING COMPONENTS ---------
1336
+
1337
+ /// Tesla credentials model
1338
+ struct TeslaCredentials {
1339
+ let email: String
1340
+ let password: String
1341
+ let mfaCode: String?
1342
+ }
1343
+
1344
+ /// Environment data for spatial computing
1345
+ struct EnvironmentData {
1346
+ let depthData: ARDepthData
1347
+ let lightEstimate: ARLightEstimate
1348
+ let sceneReconstruction: ARSceneReconstruction
1349
+ let anchors: [ARAnchor]
1350
+ }
1351
+
1352
+ /// Environment context for AI processing
1353
+ struct EnvironmentContext {
1354
+ let surfaces: [Surface]
1355
+ let lighting: LightingContext
1356
+ let identifiedObjects: [IdentifiedObject]
1357
+ let spatialAnchors: [ARAnchor]
1358
+
1359
+ struct Surface {
1360
+ let plane: Plane
1361
+ let classification: SurfaceClassification
1362
+
1363
+ enum SurfaceClassification {
1364
+ case floor
1365
+ case wall
1366
+ case ceiling
1367
+ case table
1368
+ case unknown
1369
+ }
1370
+ }
1371
+
1372
+ struct LightingContext {
1373
+ let intensity: Float
1374
+ let temperature: Float
1375
+ let direction: SIMD3<Float>?
1376
+ }
1377
+
1378
+ struct IdentifiedObject {
1379
+ let identifier: String
1380
+ let confidence: Float
1381
+ let boundingBox: CGRect
1382
+ }
1383
+ }
1384
+
1385
+ /// Gesture recognition types
1386
+ struct SpatialGesture {
1387
+ let type: GestureType
1388
+ let position: CGPoint
1389
+ let direction: SIMD2<Float>?
1390
+ let scale: Float?
1391
+
1392
+ enum GestureType {
1393
+ case tap
1394
+ case swipe
1395
+ case pinch
1396
+ case rotate
1397
+ case unknown
1398
+ }
1399
+ }
1400
+
1401
+ /// Gesture intent interpretation
1402
+ enum GestureIntent {
1403
+ case select(position: CGPoint)
1404
+ case scroll(direction: SIMD2<Float>?)
1405
+ case zoom(scale: Float?)
1406
+ case unknown
1407
+ }
1408
+
1409
+ /// Voice processing indicator view
1410
+ struct VoiceProcessingIndicator: View {
1411
+ @State private var animationValue: CGFloat = 0.0
1412
+
1413
+ var body: some View {
1414
+ Circle()
1415
+ .fill(Color.blue.opacity(0.5))
1416
+ .frame(width: 100, height: 100)
1417
+ .scaleEffect(1.0 + animationValue)
1418
+ .opacity(1.0 - animationValue)
1419
+ .onAppear {
1420
+ withAnimation(Animation.easeInOut(duration: 1.0).repeatForever(autoreverses: false)) {
1421
+ animationValue = 1.0
1422
+ }
1423
+ }
1424
+ }
1425
+ }
1426
+
1427
+ /// Environment classes for SwiftUI previews
1428
+ class VisionSystem: ObservableObject {}
1429
+ class TeslaSystem: ObservableObject {}
1430
+
1431
+ /// Conversation item view
1432
+ struct ConversationItemView: View {
1433
+ let item: ConversationItem
1434
+
1435
+ var body: some View {
1436
+ HStack {
1437
+ if item.isUser {
1438
+ Spacer()
1439
+ Text(item.text)
1440
+ .padding()
1441
+ .background(Color.blue.opacity(0.2))
1442
+ .cornerRadius(12)
1443
+ } else {
1444
+ Text(item.text)
1445
+ .padding()
1446
+ .background(Color.gray.opacity(0.2))
1447
+ .cornerRadius(12)
1448
+ Spacer()
1449
+ }
1450
+ }
1451
+ .padding(.vertical, 4)
1452
+ }
1453
+ }
avatar.tsx ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as AvatarPrimitive from "@radix-ui/react-avatar"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Avatar = React.forwardRef<
7
+ React.ElementRef<typeof AvatarPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <AvatarPrimitive.Root
11
+ ref={ref}
12
+ className={cn(
13
+ "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ ))
19
+ Avatar.displayName = AvatarPrimitive.Root.displayName
20
+
21
+ const AvatarImage = React.forwardRef<
22
+ React.ElementRef<typeof AvatarPrimitive.Image>,
23
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
24
+ >(({ className, ...props }, ref) => (
25
+ <AvatarPrimitive.Image
26
+ ref={ref}
27
+ className={cn("aspect-square h-full w-full", className)}
28
+ {...props}
29
+ />
30
+ ))
31
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName
32
+
33
+ const AvatarFallback = React.forwardRef<
34
+ React.ElementRef<typeof AvatarPrimitive.Fallback>,
35
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
36
+ >(({ className, ...props }, ref) => (
37
+ <AvatarPrimitive.Fallback
38
+ ref={ref}
39
+ className={cn(
40
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ ))
46
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
47
+
48
+ export { Avatar, AvatarImage, AvatarFallback }
badge.tsx ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const badgeVariants = cva(
7
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13
+ secondary:
14
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15
+ destructive:
16
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17
+ outline: "text-foreground",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: "default",
22
+ },
23
+ }
24
+ )
25
+
26
+ export interface BadgeProps
27
+ extends React.HTMLAttributes<HTMLDivElement>,
28
+ VariantProps<typeof badgeVariants> {}
29
+
30
+ function Badge({ className, variant, ...props }: BadgeProps) {
31
+ return (
32
+ <div className={cn(badgeVariants({ variant }), className)} {...props} />
33
+ )
34
+ }
35
+
36
+ export { Badge, badgeVariants }
breadcrumb.tsx ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { ChevronRight, MoreHorizontal } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Breadcrumb = React.forwardRef<
8
+ HTMLElement,
9
+ React.ComponentPropsWithoutRef<"nav"> & {
10
+ separator?: React.ReactNode
11
+ }
12
+ >(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
13
+ Breadcrumb.displayName = "Breadcrumb"
14
+
15
+ const BreadcrumbList = React.forwardRef<
16
+ HTMLOListElement,
17
+ React.ComponentPropsWithoutRef<"ol">
18
+ >(({ className, ...props }, ref) => (
19
+ <ol
20
+ ref={ref}
21
+ className={cn(
22
+ "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ ))
28
+ BreadcrumbList.displayName = "BreadcrumbList"
29
+
30
+ const BreadcrumbItem = React.forwardRef<
31
+ HTMLLIElement,
32
+ React.ComponentPropsWithoutRef<"li">
33
+ >(({ className, ...props }, ref) => (
34
+ <li
35
+ ref={ref}
36
+ className={cn("inline-flex items-center gap-1.5", className)}
37
+ {...props}
38
+ />
39
+ ))
40
+ BreadcrumbItem.displayName = "BreadcrumbItem"
41
+
42
+ const BreadcrumbLink = React.forwardRef<
43
+ HTMLAnchorElement,
44
+ React.ComponentPropsWithoutRef<"a"> & {
45
+ asChild?: boolean
46
+ }
47
+ >(({ asChild, className, ...props }, ref) => {
48
+ const Comp = asChild ? Slot : "a"
49
+
50
+ return (
51
+ <Comp
52
+ ref={ref}
53
+ className={cn("transition-colors hover:text-foreground", className)}
54
+ {...props}
55
+ />
56
+ )
57
+ })
58
+ BreadcrumbLink.displayName = "BreadcrumbLink"
59
+
60
+ const BreadcrumbPage = React.forwardRef<
61
+ HTMLSpanElement,
62
+ React.ComponentPropsWithoutRef<"span">
63
+ >(({ className, ...props }, ref) => (
64
+ <span
65
+ ref={ref}
66
+ role="link"
67
+ aria-disabled="true"
68
+ aria-current="page"
69
+ className={cn("font-normal text-foreground", className)}
70
+ {...props}
71
+ />
72
+ ))
73
+ BreadcrumbPage.displayName = "BreadcrumbPage"
74
+
75
+ const BreadcrumbSeparator = ({
76
+ children,
77
+ className,
78
+ ...props
79
+ }: React.ComponentProps<"li">) => (
80
+ <li
81
+ role="presentation"
82
+ aria-hidden="true"
83
+ className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
84
+ {...props}
85
+ >
86
+ {children ?? <ChevronRight />}
87
+ </li>
88
+ )
89
+ BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
90
+
91
+ const BreadcrumbEllipsis = ({
92
+ className,
93
+ ...props
94
+ }: React.ComponentProps<"span">) => (
95
+ <span
96
+ role="presentation"
97
+ aria-hidden="true"
98
+ className={cn("flex h-9 w-9 items-center justify-center", className)}
99
+ {...props}
100
+ >
101
+ <MoreHorizontal className="h-4 w-4" />
102
+ <span className="sr-only">More</span>
103
+ </span>
104
+ )
105
+ BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
106
+
107
+ export {
108
+ Breadcrumb,
109
+ BreadcrumbList,
110
+ BreadcrumbItem,
111
+ BreadcrumbLink,
112
+ BreadcrumbPage,
113
+ BreadcrumbSeparator,
114
+ BreadcrumbEllipsis,
115
+ }
button.tsx ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
+ destructive:
14
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15
+ outline:
16
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17
+ secondary:
18
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
+ ghost: "hover:bg-accent hover:text-accent-foreground",
20
+ link: "text-primary underline-offset-4 hover:underline",
21
+ },
22
+ size: {
23
+ default: "h-10 px-4 py-2",
24
+ sm: "h-9 rounded-md px-3",
25
+ lg: "h-11 rounded-md px-8",
26
+ icon: "h-10 w-10",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ size: "default",
32
+ },
33
+ }
34
+ )
35
+
36
+ export interface ButtonProps
37
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38
+ VariantProps<typeof buttonVariants> {
39
+ asChild?: boolean
40
+ }
41
+
42
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
44
+ const Comp = asChild ? Slot : "button"
45
+ return (
46
+ <Comp
47
+ className={cn(buttonVariants({ variant, size, className }))}
48
+ ref={ref}
49
+ {...props}
50
+ />
51
+ )
52
+ }
53
+ )
54
+ Button.displayName = "Button"
55
+
56
+ export { Button, buttonVariants }
calendar.tsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { ChevronLeft, ChevronRight } from "lucide-react"
3
+ import { DayPicker } from "react-day-picker"
4
+
5
+ import { cn } from "@/lib/utils"
6
+ import { buttonVariants } from "@/components/ui/button"
7
+
8
+ export type CalendarProps = React.ComponentProps<typeof DayPicker>
9
+
10
+ function Calendar({
11
+ className,
12
+ classNames,
13
+ showOutsideDays = true,
14
+ ...props
15
+ }: CalendarProps) {
16
+ return (
17
+ <DayPicker
18
+ showOutsideDays={showOutsideDays}
19
+ className={cn("p-3", className)}
20
+ classNames={{
21
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
22
+ month: "space-y-4",
23
+ caption: "flex justify-center pt-1 relative items-center",
24
+ caption_label: "text-sm font-medium",
25
+ nav: "space-x-1 flex items-center",
26
+ nav_button: cn(
27
+ buttonVariants({ variant: "outline" }),
28
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
29
+ ),
30
+ nav_button_previous: "absolute left-1",
31
+ nav_button_next: "absolute right-1",
32
+ table: "w-full border-collapse space-y-1",
33
+ head_row: "flex",
34
+ head_cell:
35
+ "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
36
+ row: "flex w-full mt-2",
37
+ cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
38
+ day: cn(
39
+ buttonVariants({ variant: "ghost" }),
40
+ "h-9 w-9 p-0 font-normal aria-selected:opacity-100"
41
+ ),
42
+ day_range_end: "day-range-end",
43
+ day_selected:
44
+ "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
45
+ day_today: "bg-accent text-accent-foreground",
46
+ day_outside:
47
+ "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
48
+ day_disabled: "text-muted-foreground opacity-50",
49
+ day_range_middle:
50
+ "aria-selected:bg-accent aria-selected:text-accent-foreground",
51
+ day_hidden: "invisible",
52
+ ...classNames,
53
+ }}
54
+ components={{
55
+ IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
56
+ IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
57
+ }}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+ Calendar.displayName = "Calendar"
63
+
64
+ export { Calendar }
card.tsx ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const Card = React.forwardRef<
6
+ HTMLDivElement,
7
+ React.HTMLAttributes<HTMLDivElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div
10
+ ref={ref}
11
+ className={cn(
12
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
13
+ className
14
+ )}
15
+ {...props}
16
+ />
17
+ ))
18
+ Card.displayName = "Card"
19
+
20
+ const CardHeader = React.forwardRef<
21
+ HTMLDivElement,
22
+ React.HTMLAttributes<HTMLDivElement>
23
+ >(({ className, ...props }, ref) => (
24
+ <div
25
+ ref={ref}
26
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
27
+ {...props}
28
+ />
29
+ ))
30
+ CardHeader.displayName = "CardHeader"
31
+
32
+ const CardTitle = React.forwardRef<
33
+ HTMLParagraphElement,
34
+ React.HTMLAttributes<HTMLHeadingElement>
35
+ >(({ className, ...props }, ref) => (
36
+ <h3
37
+ ref={ref}
38
+ className={cn(
39
+ "text-2xl font-semibold leading-none tracking-tight",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ ))
45
+ CardTitle.displayName = "CardTitle"
46
+
47
+ const CardDescription = React.forwardRef<
48
+ HTMLParagraphElement,
49
+ React.HTMLAttributes<HTMLParagraphElement>
50
+ >(({ className, ...props }, ref) => (
51
+ <p
52
+ ref={ref}
53
+ className={cn("text-sm text-muted-foreground", className)}
54
+ {...props}
55
+ />
56
+ ))
57
+ CardDescription.displayName = "CardDescription"
58
+
59
+ const CardContent = React.forwardRef<
60
+ HTMLDivElement,
61
+ React.HTMLAttributes<HTMLDivElement>
62
+ >(({ className, ...props }, ref) => (
63
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
64
+ ))
65
+ CardContent.displayName = "CardContent"
66
+
67
+ const CardFooter = React.forwardRef<
68
+ HTMLDivElement,
69
+ React.HTMLAttributes<HTMLDivElement>
70
+ >(({ className, ...props }, ref) => (
71
+ <div
72
+ ref={ref}
73
+ className={cn("flex items-center p-6 pt-0", className)}
74
+ {...props}
75
+ />
76
+ ))
77
+ CardFooter.displayName = "CardFooter"
78
+
79
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
carousel.tsx ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import useEmblaCarousel, {
3
+ type UseEmblaCarouselType,
4
+ } from "embla-carousel-react"
5
+ import { ArrowLeft, ArrowRight } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+ import { Button } from "@/components/ui/button"
9
+
10
+ type CarouselApi = UseEmblaCarouselType[1]
11
+ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
12
+ type CarouselOptions = UseCarouselParameters[0]
13
+ type CarouselPlugin = UseCarouselParameters[1]
14
+
15
+ type CarouselProps = {
16
+ opts?: CarouselOptions
17
+ plugins?: CarouselPlugin
18
+ orientation?: "horizontal" | "vertical"
19
+ setApi?: (api: CarouselApi) => void
20
+ }
21
+
22
+ type CarouselContextProps = {
23
+ carouselRef: ReturnType<typeof useEmblaCarousel>[0]
24
+ api: ReturnType<typeof useEmblaCarousel>[1]
25
+ scrollPrev: () => void
26
+ scrollNext: () => void
27
+ canScrollPrev: boolean
28
+ canScrollNext: boolean
29
+ } & CarouselProps
30
+
31
+ const CarouselContext = React.createContext<CarouselContextProps | null>(null)
32
+
33
+ function useCarousel() {
34
+ const context = React.useContext(CarouselContext)
35
+
36
+ if (!context) {
37
+ throw new Error("useCarousel must be used within a <Carousel />")
38
+ }
39
+
40
+ return context
41
+ }
42
+
43
+ const Carousel = React.forwardRef<
44
+ HTMLDivElement,
45
+ React.HTMLAttributes<HTMLDivElement> & CarouselProps
46
+ >(
47
+ (
48
+ {
49
+ orientation = "horizontal",
50
+ opts,
51
+ setApi,
52
+ plugins,
53
+ className,
54
+ children,
55
+ ...props
56
+ },
57
+ ref
58
+ ) => {
59
+ const [carouselRef, api] = useEmblaCarousel(
60
+ {
61
+ ...opts,
62
+ axis: orientation === "horizontal" ? "x" : "y",
63
+ },
64
+ plugins
65
+ )
66
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
67
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
68
+
69
+ const onSelect = React.useCallback((api: CarouselApi) => {
70
+ if (!api) {
71
+ return
72
+ }
73
+
74
+ setCanScrollPrev(api.canScrollPrev())
75
+ setCanScrollNext(api.canScrollNext())
76
+ }, [])
77
+
78
+ const scrollPrev = React.useCallback(() => {
79
+ api?.scrollPrev()
80
+ }, [api])
81
+
82
+ const scrollNext = React.useCallback(() => {
83
+ api?.scrollNext()
84
+ }, [api])
85
+
86
+ const handleKeyDown = React.useCallback(
87
+ (event: React.KeyboardEvent<HTMLDivElement>) => {
88
+ if (event.key === "ArrowLeft") {
89
+ event.preventDefault()
90
+ scrollPrev()
91
+ } else if (event.key === "ArrowRight") {
92
+ event.preventDefault()
93
+ scrollNext()
94
+ }
95
+ },
96
+ [scrollPrev, scrollNext]
97
+ )
98
+
99
+ React.useEffect(() => {
100
+ if (!api || !setApi) {
101
+ return
102
+ }
103
+
104
+ setApi(api)
105
+ }, [api, setApi])
106
+
107
+ React.useEffect(() => {
108
+ if (!api) {
109
+ return
110
+ }
111
+
112
+ onSelect(api)
113
+ api.on("reInit", onSelect)
114
+ api.on("select", onSelect)
115
+
116
+ return () => {
117
+ api?.off("select", onSelect)
118
+ }
119
+ }, [api, onSelect])
120
+
121
+ return (
122
+ <CarouselContext.Provider
123
+ value={{
124
+ carouselRef,
125
+ api: api,
126
+ opts,
127
+ orientation:
128
+ orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
129
+ scrollPrev,
130
+ scrollNext,
131
+ canScrollPrev,
132
+ canScrollNext,
133
+ }}
134
+ >
135
+ <div
136
+ ref={ref}
137
+ onKeyDownCapture={handleKeyDown}
138
+ className={cn("relative", className)}
139
+ role="region"
140
+ aria-roledescription="carousel"
141
+ {...props}
142
+ >
143
+ {children}
144
+ </div>
145
+ </CarouselContext.Provider>
146
+ )
147
+ }
148
+ )
149
+ Carousel.displayName = "Carousel"
150
+
151
+ const CarouselContent = React.forwardRef<
152
+ HTMLDivElement,
153
+ React.HTMLAttributes<HTMLDivElement>
154
+ >(({ className, ...props }, ref) => {
155
+ const { carouselRef, orientation } = useCarousel()
156
+
157
+ return (
158
+ <div ref={carouselRef} className="overflow-hidden">
159
+ <div
160
+ ref={ref}
161
+ className={cn(
162
+ "flex",
163
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
164
+ className
165
+ )}
166
+ {...props}
167
+ />
168
+ </div>
169
+ )
170
+ })
171
+ CarouselContent.displayName = "CarouselContent"
172
+
173
+ const CarouselItem = React.forwardRef<
174
+ HTMLDivElement,
175
+ React.HTMLAttributes<HTMLDivElement>
176
+ >(({ className, ...props }, ref) => {
177
+ const { orientation } = useCarousel()
178
+
179
+ return (
180
+ <div
181
+ ref={ref}
182
+ role="group"
183
+ aria-roledescription="slide"
184
+ className={cn(
185
+ "min-w-0 shrink-0 grow-0 basis-full",
186
+ orientation === "horizontal" ? "pl-4" : "pt-4",
187
+ className
188
+ )}
189
+ {...props}
190
+ />
191
+ )
192
+ })
193
+ CarouselItem.displayName = "CarouselItem"
194
+
195
+ const CarouselPrevious = React.forwardRef<
196
+ HTMLButtonElement,
197
+ React.ComponentProps<typeof Button>
198
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
199
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
200
+
201
+ return (
202
+ <Button
203
+ ref={ref}
204
+ variant={variant}
205
+ size={size}
206
+ className={cn(
207
+ "absolute h-8 w-8 rounded-full",
208
+ orientation === "horizontal"
209
+ ? "-left-12 top-1/2 -translate-y-1/2"
210
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
211
+ className
212
+ )}
213
+ disabled={!canScrollPrev}
214
+ onClick={scrollPrev}
215
+ {...props}
216
+ >
217
+ <ArrowLeft className="h-4 w-4" />
218
+ <span className="sr-only">Previous slide</span>
219
+ </Button>
220
+ )
221
+ })
222
+ CarouselPrevious.displayName = "CarouselPrevious"
223
+
224
+ const CarouselNext = React.forwardRef<
225
+ HTMLButtonElement,
226
+ React.ComponentProps<typeof Button>
227
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
228
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
229
+
230
+ return (
231
+ <Button
232
+ ref={ref}
233
+ variant={variant}
234
+ size={size}
235
+ className={cn(
236
+ "absolute h-8 w-8 rounded-full",
237
+ orientation === "horizontal"
238
+ ? "-right-12 top-1/2 -translate-y-1/2"
239
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
240
+ className
241
+ )}
242
+ disabled={!canScrollNext}
243
+ onClick={scrollNext}
244
+ {...props}
245
+ >
246
+ <ArrowRight className="h-4 w-4" />
247
+ <span className="sr-only">Next slide</span>
248
+ </Button>
249
+ )
250
+ })
251
+ CarouselNext.displayName = "CarouselNext"
252
+
253
+ export {
254
+ type CarouselApi,
255
+ Carousel,
256
+ CarouselContent,
257
+ CarouselItem,
258
+ CarouselPrevious,
259
+ CarouselNext,
260
+ }
chart.tsx ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as RechartsPrimitive from "recharts"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ // Format: { THEME_NAME: CSS_SELECTOR }
7
+ const THEMES = { light: "", dark: ".dark" } as const
8
+
9
+ export type ChartConfig = {
10
+ [k in string]: {
11
+ label?: React.ReactNode
12
+ icon?: React.ComponentType
13
+ } & (
14
+ | { color?: string; theme?: never }
15
+ | { color?: never; theme: Record<keyof typeof THEMES, string> }
16
+ )
17
+ }
18
+
19
+ type ChartContextProps = {
20
+ config: ChartConfig
21
+ }
22
+
23
+ const ChartContext = React.createContext<ChartContextProps | null>(null)
24
+
25
+ function useChart() {
26
+ const context = React.useContext(ChartContext)
27
+
28
+ if (!context) {
29
+ throw new Error("useChart must be used within a <ChartContainer />")
30
+ }
31
+
32
+ return context
33
+ }
34
+
35
+ const ChartContainer = React.forwardRef<
36
+ HTMLDivElement,
37
+ React.ComponentProps<"div"> & {
38
+ config: ChartConfig
39
+ children: React.ComponentProps<
40
+ typeof RechartsPrimitive.ResponsiveContainer
41
+ >["children"]
42
+ }
43
+ >(({ id, className, children, config, ...props }, ref) => {
44
+ const uniqueId = React.useId()
45
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
46
+
47
+ return (
48
+ <ChartContext.Provider value={{ config }}>
49
+ <div
50
+ data-chart={chartId}
51
+ ref={ref}
52
+ className={cn(
53
+ "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
54
+ className
55
+ )}
56
+ {...props}
57
+ >
58
+ <ChartStyle id={chartId} config={config} />
59
+ <RechartsPrimitive.ResponsiveContainer>
60
+ {children}
61
+ </RechartsPrimitive.ResponsiveContainer>
62
+ </div>
63
+ </ChartContext.Provider>
64
+ )
65
+ })
66
+ ChartContainer.displayName = "Chart"
67
+
68
+ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
69
+ const colorConfig = Object.entries(config).filter(
70
+ ([_, config]) => config.theme || config.color
71
+ )
72
+
73
+ if (!colorConfig.length) {
74
+ return null
75
+ }
76
+
77
+ return (
78
+ <style
79
+ dangerouslySetInnerHTML={{
80
+ __html: Object.entries(THEMES)
81
+ .map(
82
+ ([theme, prefix]) => `
83
+ ${prefix} [data-chart=${id}] {
84
+ ${colorConfig
85
+ .map(([key, itemConfig]) => {
86
+ const color =
87
+ itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
88
+ itemConfig.color
89
+ return color ? ` --color-${key}: ${color};` : null
90
+ })
91
+ .join("\n")}
92
+ }
93
+ `
94
+ )
95
+ .join("\n"),
96
+ }}
97
+ />
98
+ )
99
+ }
100
+
101
+ const ChartTooltip = RechartsPrimitive.Tooltip
102
+
103
+ const ChartTooltipContent = React.forwardRef<
104
+ HTMLDivElement,
105
+ React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
106
+ React.ComponentProps<"div"> & {
107
+ hideLabel?: boolean
108
+ hideIndicator?: boolean
109
+ indicator?: "line" | "dot" | "dashed"
110
+ nameKey?: string
111
+ labelKey?: string
112
+ }
113
+ >(
114
+ (
115
+ {
116
+ active,
117
+ payload,
118
+ className,
119
+ indicator = "dot",
120
+ hideLabel = false,
121
+ hideIndicator = false,
122
+ label,
123
+ labelFormatter,
124
+ labelClassName,
125
+ formatter,
126
+ color,
127
+ nameKey,
128
+ labelKey,
129
+ },
130
+ ref
131
+ ) => {
132
+ const { config } = useChart()
133
+
134
+ const tooltipLabel = React.useMemo(() => {
135
+ if (hideLabel || !payload?.length) {
136
+ return null
137
+ }
138
+
139
+ const [item] = payload
140
+ const key = `${labelKey || item.dataKey || item.name || "value"}`
141
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
142
+ const value =
143
+ !labelKey && typeof label === "string"
144
+ ? config[label as keyof typeof config]?.label || label
145
+ : itemConfig?.label
146
+
147
+ if (labelFormatter) {
148
+ return (
149
+ <div className={cn("font-medium", labelClassName)}>
150
+ {labelFormatter(value, payload)}
151
+ </div>
152
+ )
153
+ }
154
+
155
+ if (!value) {
156
+ return null
157
+ }
158
+
159
+ return <div className={cn("font-medium", labelClassName)}>{value}</div>
160
+ }, [
161
+ label,
162
+ labelFormatter,
163
+ payload,
164
+ hideLabel,
165
+ labelClassName,
166
+ config,
167
+ labelKey,
168
+ ])
169
+
170
+ if (!active || !payload?.length) {
171
+ return null
172
+ }
173
+
174
+ const nestLabel = payload.length === 1 && indicator !== "dot"
175
+
176
+ return (
177
+ <div
178
+ ref={ref}
179
+ className={cn(
180
+ "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
181
+ className
182
+ )}
183
+ >
184
+ {!nestLabel ? tooltipLabel : null}
185
+ <div className="grid gap-1.5">
186
+ {payload.map((item, index) => {
187
+ const key = `${nameKey || item.name || item.dataKey || "value"}`
188
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
189
+ const indicatorColor = color || item.payload.fill || item.color
190
+
191
+ return (
192
+ <div
193
+ key={item.dataKey}
194
+ className={cn(
195
+ "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
196
+ indicator === "dot" && "items-center"
197
+ )}
198
+ >
199
+ {formatter && item?.value !== undefined && item.name ? (
200
+ formatter(item.value, item.name, item, index, item.payload)
201
+ ) : (
202
+ <>
203
+ {itemConfig?.icon ? (
204
+ <itemConfig.icon />
205
+ ) : (
206
+ !hideIndicator && (
207
+ <div
208
+ className={cn(
209
+ "shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
210
+ {
211
+ "h-2.5 w-2.5": indicator === "dot",
212
+ "w-1": indicator === "line",
213
+ "w-0 border-[1.5px] border-dashed bg-transparent":
214
+ indicator === "dashed",
215
+ "my-0.5": nestLabel && indicator === "dashed",
216
+ }
217
+ )}
218
+ style={
219
+ {
220
+ "--color-bg": indicatorColor,
221
+ "--color-border": indicatorColor,
222
+ } as React.CSSProperties
223
+ }
224
+ />
225
+ )
226
+ )}
227
+ <div
228
+ className={cn(
229
+ "flex flex-1 justify-between leading-none",
230
+ nestLabel ? "items-end" : "items-center"
231
+ )}
232
+ >
233
+ <div className="grid gap-1.5">
234
+ {nestLabel ? tooltipLabel : null}
235
+ <span className="text-muted-foreground">
236
+ {itemConfig?.label || item.name}
237
+ </span>
238
+ </div>
239
+ {item.value && (
240
+ <span className="font-mono font-medium tabular-nums text-foreground">
241
+ {item.value.toLocaleString()}
242
+ </span>
243
+ )}
244
+ </div>
245
+ </>
246
+ )}
247
+ </div>
248
+ )
249
+ })}
250
+ </div>
251
+ </div>
252
+ )
253
+ }
254
+ )
255
+ ChartTooltipContent.displayName = "ChartTooltip"
256
+
257
+ const ChartLegend = RechartsPrimitive.Legend
258
+
259
+ const ChartLegendContent = React.forwardRef<
260
+ HTMLDivElement,
261
+ React.ComponentProps<"div"> &
262
+ Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
263
+ hideIcon?: boolean
264
+ nameKey?: string
265
+ }
266
+ >(
267
+ (
268
+ { className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
269
+ ref
270
+ ) => {
271
+ const { config } = useChart()
272
+
273
+ if (!payload?.length) {
274
+ return null
275
+ }
276
+
277
+ return (
278
+ <div
279
+ ref={ref}
280
+ className={cn(
281
+ "flex items-center justify-center gap-4",
282
+ verticalAlign === "top" ? "pb-3" : "pt-3",
283
+ className
284
+ )}
285
+ >
286
+ {payload.map((item) => {
287
+ const key = `${nameKey || item.dataKey || "value"}`
288
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
289
+
290
+ return (
291
+ <div
292
+ key={item.value}
293
+ className={cn(
294
+ "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
295
+ )}
296
+ >
297
+ {itemConfig?.icon && !hideIcon ? (
298
+ <itemConfig.icon />
299
+ ) : (
300
+ <div
301
+ className="h-2 w-2 shrink-0 rounded-[2px]"
302
+ style={{
303
+ backgroundColor: item.color,
304
+ }}
305
+ />
306
+ )}
307
+ {itemConfig?.label}
308
+ </div>
309
+ )
310
+ })}
311
+ </div>
312
+ )
313
+ }
314
+ )
315
+ ChartLegendContent.displayName = "ChartLegend"
316
+
317
+ // Helper to extract item config from a payload.
318
+ function getPayloadConfigFromPayload(
319
+ config: ChartConfig,
320
+ payload: unknown,
321
+ key: string
322
+ ) {
323
+ if (typeof payload !== "object" || payload === null) {
324
+ return undefined
325
+ }
326
+
327
+ const payloadPayload =
328
+ "payload" in payload &&
329
+ typeof payload.payload === "object" &&
330
+ payload.payload !== null
331
+ ? payload.payload
332
+ : undefined
333
+
334
+ let configLabelKey: string = key
335
+
336
+ if (
337
+ key in payload &&
338
+ typeof payload[key as keyof typeof payload] === "string"
339
+ ) {
340
+ configLabelKey = payload[key as keyof typeof payload] as string
341
+ } else if (
342
+ payloadPayload &&
343
+ key in payloadPayload &&
344
+ typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
345
+ ) {
346
+ configLabelKey = payloadPayload[
347
+ key as keyof typeof payloadPayload
348
+ ] as string
349
+ }
350
+
351
+ return configLabelKey in config
352
+ ? config[configLabelKey]
353
+ : config[key as keyof typeof config]
354
+ }
355
+
356
+ export {
357
+ ChartContainer,
358
+ ChartTooltip,
359
+ ChartTooltipContent,
360
+ ChartLegend,
361
+ ChartLegendContent,
362
+ ChartStyle,
363
+ }
checkbox.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
3
+ import { Check } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Checkbox = React.forwardRef<
8
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
9
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
10
+ >(({ className, ...props }, ref) => (
11
+ <CheckboxPrimitive.Root
12
+ ref={ref}
13
+ className={cn(
14
+ "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
15
+ className
16
+ )}
17
+ {...props}
18
+ >
19
+ <CheckboxPrimitive.Indicator
20
+ className={cn("flex items-center justify-center text-current")}
21
+ >
22
+ <Check className="h-4 w-4" />
23
+ </CheckboxPrimitive.Indicator>
24
+ </CheckboxPrimitive.Root>
25
+ ))
26
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName
27
+
28
+ export { Checkbox }
collapsible.tsx ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
2
+
3
+ const Collapsible = CollapsiblePrimitive.Root
4
+
5
+ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
6
+
7
+ const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
8
+
9
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }
command.tsx ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { type DialogProps } from "@radix-ui/react-dialog"
3
+ import { Command as CommandPrimitive } from "cmdk"
4
+ import { Search } from "lucide-react"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Dialog, DialogContent } from "@/components/ui/dialog"
8
+
9
+ const Command = React.forwardRef<
10
+ React.ElementRef<typeof CommandPrimitive>,
11
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
12
+ >(({ className, ...props }, ref) => (
13
+ <CommandPrimitive
14
+ ref={ref}
15
+ className={cn(
16
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ ))
22
+ Command.displayName = CommandPrimitive.displayName
23
+
24
+ interface CommandDialogProps extends DialogProps {}
25
+
26
+ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
27
+ return (
28
+ <Dialog {...props}>
29
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
30
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31
+ {children}
32
+ </Command>
33
+ </DialogContent>
34
+ </Dialog>
35
+ )
36
+ }
37
+
38
+ const CommandInput = React.forwardRef<
39
+ React.ElementRef<typeof CommandPrimitive.Input>,
40
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41
+ >(({ className, ...props }, ref) => (
42
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44
+ <CommandPrimitive.Input
45
+ ref={ref}
46
+ className={cn(
47
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ </div>
53
+ ))
54
+
55
+ CommandInput.displayName = CommandPrimitive.Input.displayName
56
+
57
+ const CommandList = React.forwardRef<
58
+ React.ElementRef<typeof CommandPrimitive.List>,
59
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60
+ >(({ className, ...props }, ref) => (
61
+ <CommandPrimitive.List
62
+ ref={ref}
63
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64
+ {...props}
65
+ />
66
+ ))
67
+
68
+ CommandList.displayName = CommandPrimitive.List.displayName
69
+
70
+ const CommandEmpty = React.forwardRef<
71
+ React.ElementRef<typeof CommandPrimitive.Empty>,
72
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
+ >((props, ref) => (
74
+ <CommandPrimitive.Empty
75
+ ref={ref}
76
+ className="py-6 text-center text-sm"
77
+ {...props}
78
+ />
79
+ ))
80
+
81
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
82
+
83
+ const CommandGroup = React.forwardRef<
84
+ React.ElementRef<typeof CommandPrimitive.Group>,
85
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
86
+ >(({ className, ...props }, ref) => (
87
+ <CommandPrimitive.Group
88
+ ref={ref}
89
+ className={cn(
90
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
91
+ className
92
+ )}
93
+ {...props}
94
+ />
95
+ ))
96
+
97
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
98
+
99
+ const CommandSeparator = React.forwardRef<
100
+ React.ElementRef<typeof CommandPrimitive.Separator>,
101
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
102
+ >(({ className, ...props }, ref) => (
103
+ <CommandPrimitive.Separator
104
+ ref={ref}
105
+ className={cn("-mx-1 h-px bg-border", className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
110
+
111
+ const CommandItem = React.forwardRef<
112
+ React.ElementRef<typeof CommandPrimitive.Item>,
113
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
114
+ >(({ className, ...props }, ref) => (
115
+ <CommandPrimitive.Item
116
+ ref={ref}
117
+ className={cn(
118
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
119
+ className
120
+ )}
121
+ {...props}
122
+ />
123
+ ))
124
+
125
+ CommandItem.displayName = CommandPrimitive.Item.displayName
126
+
127
+ const CommandShortcut = ({
128
+ className,
129
+ ...props
130
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
131
+ return (
132
+ <span
133
+ className={cn(
134
+ "ml-auto text-xs tracking-widest text-muted-foreground",
135
+ className
136
+ )}
137
+ {...props}
138
+ />
139
+ )
140
+ }
141
+ CommandShortcut.displayName = "CommandShortcut"
142
+
143
+ export {
144
+ Command,
145
+ CommandDialog,
146
+ CommandInput,
147
+ CommandList,
148
+ CommandEmpty,
149
+ CommandGroup,
150
+ CommandItem,
151
+ CommandShortcut,
152
+ CommandSeparator,
153
+ }
context-menu.tsx ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
3
+ import { Check, ChevronRight, Circle } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const ContextMenu = ContextMenuPrimitive.Root
8
+
9
+ const ContextMenuTrigger = ContextMenuPrimitive.Trigger
10
+
11
+ const ContextMenuGroup = ContextMenuPrimitive.Group
12
+
13
+ const ContextMenuPortal = ContextMenuPrimitive.Portal
14
+
15
+ const ContextMenuSub = ContextMenuPrimitive.Sub
16
+
17
+ const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
18
+
19
+ const ContextMenuSubTrigger = React.forwardRef<
20
+ React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
21
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
22
+ inset?: boolean
23
+ }
24
+ >(({ className, inset, children, ...props }, ref) => (
25
+ <ContextMenuPrimitive.SubTrigger
26
+ ref={ref}
27
+ className={cn(
28
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
29
+ inset && "pl-8",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {children}
35
+ <ChevronRight className="ml-auto h-4 w-4" />
36
+ </ContextMenuPrimitive.SubTrigger>
37
+ ))
38
+ ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
39
+
40
+ const ContextMenuSubContent = React.forwardRef<
41
+ React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
42
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
43
+ >(({ className, ...props }, ref) => (
44
+ <ContextMenuPrimitive.SubContent
45
+ ref={ref}
46
+ className={cn(
47
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ ))
53
+ ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
54
+
55
+ const ContextMenuContent = React.forwardRef<
56
+ React.ElementRef<typeof ContextMenuPrimitive.Content>,
57
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
58
+ >(({ className, ...props }, ref) => (
59
+ <ContextMenuPrimitive.Portal>
60
+ <ContextMenuPrimitive.Content
61
+ ref={ref}
62
+ className={cn(
63
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
64
+ className
65
+ )}
66
+ {...props}
67
+ />
68
+ </ContextMenuPrimitive.Portal>
69
+ ))
70
+ ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
71
+
72
+ const ContextMenuItem = React.forwardRef<
73
+ React.ElementRef<typeof ContextMenuPrimitive.Item>,
74
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
75
+ inset?: boolean
76
+ }
77
+ >(({ className, inset, ...props }, ref) => (
78
+ <ContextMenuPrimitive.Item
79
+ ref={ref}
80
+ className={cn(
81
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
82
+ inset && "pl-8",
83
+ className
84
+ )}
85
+ {...props}
86
+ />
87
+ ))
88
+ ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
89
+
90
+ const ContextMenuCheckboxItem = React.forwardRef<
91
+ React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
92
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
93
+ >(({ className, children, checked, ...props }, ref) => (
94
+ <ContextMenuPrimitive.CheckboxItem
95
+ ref={ref}
96
+ className={cn(
97
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
98
+ className
99
+ )}
100
+ checked={checked}
101
+ {...props}
102
+ >
103
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
104
+ <ContextMenuPrimitive.ItemIndicator>
105
+ <Check className="h-4 w-4" />
106
+ </ContextMenuPrimitive.ItemIndicator>
107
+ </span>
108
+ {children}
109
+ </ContextMenuPrimitive.CheckboxItem>
110
+ ))
111
+ ContextMenuCheckboxItem.displayName =
112
+ ContextMenuPrimitive.CheckboxItem.displayName
113
+
114
+ const ContextMenuRadioItem = React.forwardRef<
115
+ React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
116
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
117
+ >(({ className, children, ...props }, ref) => (
118
+ <ContextMenuPrimitive.RadioItem
119
+ ref={ref}
120
+ className={cn(
121
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
122
+ className
123
+ )}
124
+ {...props}
125
+ >
126
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127
+ <ContextMenuPrimitive.ItemIndicator>
128
+ <Circle className="h-2 w-2 fill-current" />
129
+ </ContextMenuPrimitive.ItemIndicator>
130
+ </span>
131
+ {children}
132
+ </ContextMenuPrimitive.RadioItem>
133
+ ))
134
+ ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
135
+
136
+ const ContextMenuLabel = React.forwardRef<
137
+ React.ElementRef<typeof ContextMenuPrimitive.Label>,
138
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
139
+ inset?: boolean
140
+ }
141
+ >(({ className, inset, ...props }, ref) => (
142
+ <ContextMenuPrimitive.Label
143
+ ref={ref}
144
+ className={cn(
145
+ "px-2 py-1.5 text-sm font-semibold text-foreground",
146
+ inset && "pl-8",
147
+ className
148
+ )}
149
+ {...props}
150
+ />
151
+ ))
152
+ ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
153
+
154
+ const ContextMenuSeparator = React.forwardRef<
155
+ React.ElementRef<typeof ContextMenuPrimitive.Separator>,
156
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
157
+ >(({ className, ...props }, ref) => (
158
+ <ContextMenuPrimitive.Separator
159
+ ref={ref}
160
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
161
+ {...props}
162
+ />
163
+ ))
164
+ ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
165
+
166
+ const ContextMenuShortcut = ({
167
+ className,
168
+ ...props
169
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
170
+ return (
171
+ <span
172
+ className={cn(
173
+ "ml-auto text-xs tracking-widest text-muted-foreground",
174
+ className
175
+ )}
176
+ {...props}
177
+ />
178
+ )
179
+ }
180
+ ContextMenuShortcut.displayName = "ContextMenuShortcut"
181
+
182
+ export {
183
+ ContextMenu,
184
+ ContextMenuTrigger,
185
+ ContextMenuContent,
186
+ ContextMenuItem,
187
+ ContextMenuCheckboxItem,
188
+ ContextMenuRadioItem,
189
+ ContextMenuLabel,
190
+ ContextMenuSeparator,
191
+ ContextMenuShortcut,
192
+ ContextMenuGroup,
193
+ ContextMenuPortal,
194
+ ContextMenuSub,
195
+ ContextMenuSubContent,
196
+ ContextMenuSubTrigger,
197
+ ContextMenuRadioGroup,
198
+ }
dialog.tsx ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
3
+ import { X } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Dialog = DialogPrimitive.Root
8
+
9
+ const DialogTrigger = DialogPrimitive.Trigger
10
+
11
+ const DialogPortal = DialogPrimitive.Portal
12
+
13
+ const DialogClose = DialogPrimitive.Close
14
+
15
+ const DialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay
20
+ ref={ref}
21
+ className={cn(
22
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ ))
28
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
29
+
30
+ const DialogContent = React.forwardRef<
31
+ React.ElementRef<typeof DialogPrimitive.Content>,
32
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
33
+ >(({ className, children, ...props }, ref) => (
34
+ <DialogPortal>
35
+ <DialogOverlay />
36
+ <DialogPrimitive.Content
37
+ ref={ref}
38
+ className={cn(
39
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
40
+ className
41
+ )}
42
+ {...props}
43
+ >
44
+ {children}
45
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
46
+ <X className="h-4 w-4" />
47
+ <span className="sr-only">Close</span>
48
+ </DialogPrimitive.Close>
49
+ </DialogPrimitive.Content>
50
+ </DialogPortal>
51
+ ))
52
+ DialogContent.displayName = DialogPrimitive.Content.displayName
53
+
54
+ const DialogHeader = ({
55
+ className,
56
+ ...props
57
+ }: React.HTMLAttributes<HTMLDivElement>) => (
58
+ <div
59
+ className={cn(
60
+ "flex flex-col space-y-1.5 text-center sm:text-left",
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ DialogHeader.displayName = "DialogHeader"
67
+
68
+ const DialogFooter = ({
69
+ className,
70
+ ...props
71
+ }: React.HTMLAttributes<HTMLDivElement>) => (
72
+ <div
73
+ className={cn(
74
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ )
80
+ DialogFooter.displayName = "DialogFooter"
81
+
82
+ const DialogTitle = React.forwardRef<
83
+ React.ElementRef<typeof DialogPrimitive.Title>,
84
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
85
+ >(({ className, ...props }, ref) => (
86
+ <DialogPrimitive.Title
87
+ ref={ref}
88
+ className={cn(
89
+ "text-lg font-semibold leading-none tracking-tight",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ ))
95
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
96
+
97
+ const DialogDescription = React.forwardRef<
98
+ React.ElementRef<typeof DialogPrimitive.Description>,
99
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
100
+ >(({ className, ...props }, ref) => (
101
+ <DialogPrimitive.Description
102
+ ref={ref}
103
+ className={cn("text-sm text-muted-foreground", className)}
104
+ {...props}
105
+ />
106
+ ))
107
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
108
+
109
+ export {
110
+ Dialog,
111
+ DialogPortal,
112
+ DialogOverlay,
113
+ DialogClose,
114
+ DialogTrigger,
115
+ DialogContent,
116
+ DialogHeader,
117
+ DialogFooter,
118
+ DialogTitle,
119
+ DialogDescription,
120
+ }
drawer.tsx ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { Drawer as DrawerPrimitive } from "vaul"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Drawer = ({
7
+ shouldScaleBackground = true,
8
+ ...props
9
+ }: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
10
+ <DrawerPrimitive.Root
11
+ shouldScaleBackground={shouldScaleBackground}
12
+ {...props}
13
+ />
14
+ )
15
+ Drawer.displayName = "Drawer"
16
+
17
+ const DrawerTrigger = DrawerPrimitive.Trigger
18
+
19
+ const DrawerPortal = DrawerPrimitive.Portal
20
+
21
+ const DrawerClose = DrawerPrimitive.Close
22
+
23
+ const DrawerOverlay = React.forwardRef<
24
+ React.ElementRef<typeof DrawerPrimitive.Overlay>,
25
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
26
+ >(({ className, ...props }, ref) => (
27
+ <DrawerPrimitive.Overlay
28
+ ref={ref}
29
+ className={cn("fixed inset-0 z-50 bg-black/80", className)}
30
+ {...props}
31
+ />
32
+ ))
33
+ DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
34
+
35
+ const DrawerContent = React.forwardRef<
36
+ React.ElementRef<typeof DrawerPrimitive.Content>,
37
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
38
+ >(({ className, children, ...props }, ref) => (
39
+ <DrawerPortal>
40
+ <DrawerOverlay />
41
+ <DrawerPrimitive.Content
42
+ ref={ref}
43
+ className={cn(
44
+ "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
50
+ {children}
51
+ </DrawerPrimitive.Content>
52
+ </DrawerPortal>
53
+ ))
54
+ DrawerContent.displayName = "DrawerContent"
55
+
56
+ const DrawerHeader = ({
57
+ className,
58
+ ...props
59
+ }: React.HTMLAttributes<HTMLDivElement>) => (
60
+ <div
61
+ className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
62
+ {...props}
63
+ />
64
+ )
65
+ DrawerHeader.displayName = "DrawerHeader"
66
+
67
+ const DrawerFooter = ({
68
+ className,
69
+ ...props
70
+ }: React.HTMLAttributes<HTMLDivElement>) => (
71
+ <div
72
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
73
+ {...props}
74
+ />
75
+ )
76
+ DrawerFooter.displayName = "DrawerFooter"
77
+
78
+ const DrawerTitle = React.forwardRef<
79
+ React.ElementRef<typeof DrawerPrimitive.Title>,
80
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
81
+ >(({ className, ...props }, ref) => (
82
+ <DrawerPrimitive.Title
83
+ ref={ref}
84
+ className={cn(
85
+ "text-lg font-semibold leading-none tracking-tight",
86
+ className
87
+ )}
88
+ {...props}
89
+ />
90
+ ))
91
+ DrawerTitle.displayName = DrawerPrimitive.Title.displayName
92
+
93
+ const DrawerDescription = React.forwardRef<
94
+ React.ElementRef<typeof DrawerPrimitive.Description>,
95
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
96
+ >(({ className, ...props }, ref) => (
97
+ <DrawerPrimitive.Description
98
+ ref={ref}
99
+ className={cn("text-sm text-muted-foreground", className)}
100
+ {...props}
101
+ />
102
+ ))
103
+ DrawerDescription.displayName = DrawerPrimitive.Description.displayName
104
+
105
+ export {
106
+ Drawer,
107
+ DrawerPortal,
108
+ DrawerOverlay,
109
+ DrawerTrigger,
110
+ DrawerClose,
111
+ DrawerContent,
112
+ DrawerHeader,
113
+ DrawerFooter,
114
+ DrawerTitle,
115
+ DrawerDescription,
116
+ }
drizzle.config.ts ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ if (!process.env.DATABASE_URL) {
4
+ throw new Error("DATABASE_URL, ensure the database is provisioned");
5
+ }
6
+
7
+ export default defineConfig({
8
+ out: "./migrations",
9
+ schema: "./shared/schema.ts",
10
+ dialect: "postgresql",
11
+ dbCredentials: {
12
+ url: process.env.DATABASE_URL,
13
+ },
14
+ });
dropdown-menu.tsx ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
3
+ import { Check, ChevronRight, Circle } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const DropdownMenu = DropdownMenuPrimitive.Root
8
+
9
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
10
+
11
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group
12
+
13
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal
14
+
15
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub
16
+
17
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
18
+
19
+ const DropdownMenuSubTrigger = React.forwardRef<
20
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
22
+ inset?: boolean
23
+ }
24
+ >(({ className, inset, children, ...props }, ref) => (
25
+ <DropdownMenuPrimitive.SubTrigger
26
+ ref={ref}
27
+ className={cn(
28
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
29
+ inset && "pl-8",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {children}
35
+ <ChevronRight className="ml-auto h-4 w-4" />
36
+ </DropdownMenuPrimitive.SubTrigger>
37
+ ))
38
+ DropdownMenuSubTrigger.displayName =
39
+ DropdownMenuPrimitive.SubTrigger.displayName
40
+
41
+ const DropdownMenuSubContent = React.forwardRef<
42
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
43
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
44
+ >(({ className, ...props }, ref) => (
45
+ <DropdownMenuPrimitive.SubContent
46
+ ref={ref}
47
+ className={cn(
48
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
49
+ className
50
+ )}
51
+ {...props}
52
+ />
53
+ ))
54
+ DropdownMenuSubContent.displayName =
55
+ DropdownMenuPrimitive.SubContent.displayName
56
+
57
+ const DropdownMenuContent = React.forwardRef<
58
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
59
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
60
+ >(({ className, sideOffset = 4, ...props }, ref) => (
61
+ <DropdownMenuPrimitive.Portal>
62
+ <DropdownMenuPrimitive.Content
63
+ ref={ref}
64
+ sideOffset={sideOffset}
65
+ className={cn(
66
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
67
+ className
68
+ )}
69
+ {...props}
70
+ />
71
+ </DropdownMenuPrimitive.Portal>
72
+ ))
73
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
74
+
75
+ const DropdownMenuItem = React.forwardRef<
76
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
77
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
78
+ inset?: boolean
79
+ }
80
+ >(({ className, inset, ...props }, ref) => (
81
+ <DropdownMenuPrimitive.Item
82
+ ref={ref}
83
+ className={cn(
84
+ "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
85
+ inset && "pl-8",
86
+ className
87
+ )}
88
+ {...props}
89
+ />
90
+ ))
91
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
92
+
93
+ const DropdownMenuCheckboxItem = React.forwardRef<
94
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
95
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
96
+ >(({ className, children, checked, ...props }, ref) => (
97
+ <DropdownMenuPrimitive.CheckboxItem
98
+ ref={ref}
99
+ className={cn(
100
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
101
+ className
102
+ )}
103
+ checked={checked}
104
+ {...props}
105
+ >
106
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
107
+ <DropdownMenuPrimitive.ItemIndicator>
108
+ <Check className="h-4 w-4" />
109
+ </DropdownMenuPrimitive.ItemIndicator>
110
+ </span>
111
+ {children}
112
+ </DropdownMenuPrimitive.CheckboxItem>
113
+ ))
114
+ DropdownMenuCheckboxItem.displayName =
115
+ DropdownMenuPrimitive.CheckboxItem.displayName
116
+
117
+ const DropdownMenuRadioItem = React.forwardRef<
118
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
119
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
120
+ >(({ className, children, ...props }, ref) => (
121
+ <DropdownMenuPrimitive.RadioItem
122
+ ref={ref}
123
+ className={cn(
124
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
125
+ className
126
+ )}
127
+ {...props}
128
+ >
129
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
130
+ <DropdownMenuPrimitive.ItemIndicator>
131
+ <Circle className="h-2 w-2 fill-current" />
132
+ </DropdownMenuPrimitive.ItemIndicator>
133
+ </span>
134
+ {children}
135
+ </DropdownMenuPrimitive.RadioItem>
136
+ ))
137
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
138
+
139
+ const DropdownMenuLabel = React.forwardRef<
140
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
141
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
142
+ inset?: boolean
143
+ }
144
+ >(({ className, inset, ...props }, ref) => (
145
+ <DropdownMenuPrimitive.Label
146
+ ref={ref}
147
+ className={cn(
148
+ "px-2 py-1.5 text-sm font-semibold",
149
+ inset && "pl-8",
150
+ className
151
+ )}
152
+ {...props}
153
+ />
154
+ ))
155
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
156
+
157
+ const DropdownMenuSeparator = React.forwardRef<
158
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
159
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
160
+ >(({ className, ...props }, ref) => (
161
+ <DropdownMenuPrimitive.Separator
162
+ ref={ref}
163
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
164
+ {...props}
165
+ />
166
+ ))
167
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
168
+
169
+ const DropdownMenuShortcut = ({
170
+ className,
171
+ ...props
172
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
173
+ return (
174
+ <span
175
+ className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
176
+ {...props}
177
+ />
178
+ )
179
+ }
180
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
181
+
182
+ export {
183
+ DropdownMenu,
184
+ DropdownMenuTrigger,
185
+ DropdownMenuContent,
186
+ DropdownMenuItem,
187
+ DropdownMenuCheckboxItem,
188
+ DropdownMenuRadioItem,
189
+ DropdownMenuLabel,
190
+ DropdownMenuSeparator,
191
+ DropdownMenuShortcut,
192
+ DropdownMenuGroup,
193
+ DropdownMenuPortal,
194
+ DropdownMenuSub,
195
+ DropdownMenuSubContent,
196
+ DropdownMenuSubTrigger,
197
+ DropdownMenuRadioGroup,
198
+ }
form.tsx ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as LabelPrimitive from "@radix-ui/react-label"
3
+ import { Slot } from "@radix-ui/react-slot"
4
+ import {
5
+ Controller,
6
+ ControllerProps,
7
+ FieldPath,
8
+ FieldValues,
9
+ FormProvider,
10
+ useFormContext,
11
+ } from "react-hook-form"
12
+
13
+ import { cn } from "@/lib/utils"
14
+ import { Label } from "@/components/ui/label"
15
+
16
+ const Form = FormProvider
17
+
18
+ type FormFieldContextValue<
19
+ TFieldValues extends FieldValues = FieldValues,
20
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
21
+ > = {
22
+ name: TName
23
+ }
24
+
25
+ const FormFieldContext = React.createContext<FormFieldContextValue>(
26
+ {} as FormFieldContextValue
27
+ )
28
+
29
+ const FormField = <
30
+ TFieldValues extends FieldValues = FieldValues,
31
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
32
+ >({
33
+ ...props
34
+ }: ControllerProps<TFieldValues, TName>) => {
35
+ return (
36
+ <FormFieldContext.Provider value={{ name: props.name }}>
37
+ <Controller {...props} />
38
+ </FormFieldContext.Provider>
39
+ )
40
+ }
41
+
42
+ const useFormField = () => {
43
+ const fieldContext = React.useContext(FormFieldContext)
44
+ const itemContext = React.useContext(FormItemContext)
45
+ const { getFieldState, formState } = useFormContext()
46
+
47
+ const fieldState = getFieldState(fieldContext.name, formState)
48
+
49
+ if (!fieldContext) {
50
+ throw new Error("useFormField should be used within <FormField>")
51
+ }
52
+
53
+ const { id } = itemContext
54
+
55
+ return {
56
+ id,
57
+ name: fieldContext.name,
58
+ formItemId: `${id}-form-item`,
59
+ formDescriptionId: `${id}-form-item-description`,
60
+ formMessageId: `${id}-form-item-message`,
61
+ ...fieldState,
62
+ }
63
+ }
64
+
65
+ type FormItemContextValue = {
66
+ id: string
67
+ }
68
+
69
+ const FormItemContext = React.createContext<FormItemContextValue>(
70
+ {} as FormItemContextValue
71
+ )
72
+
73
+ const FormItem = React.forwardRef<
74
+ HTMLDivElement,
75
+ React.HTMLAttributes<HTMLDivElement>
76
+ >(({ className, ...props }, ref) => {
77
+ const id = React.useId()
78
+
79
+ return (
80
+ <FormItemContext.Provider value={{ id }}>
81
+ <div ref={ref} className={cn("space-y-2", className)} {...props} />
82
+ </FormItemContext.Provider>
83
+ )
84
+ })
85
+ FormItem.displayName = "FormItem"
86
+
87
+ const FormLabel = React.forwardRef<
88
+ React.ElementRef<typeof LabelPrimitive.Root>,
89
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
90
+ >(({ className, ...props }, ref) => {
91
+ const { error, formItemId } = useFormField()
92
+
93
+ return (
94
+ <Label
95
+ ref={ref}
96
+ className={cn(error && "text-destructive", className)}
97
+ htmlFor={formItemId}
98
+ {...props}
99
+ />
100
+ )
101
+ })
102
+ FormLabel.displayName = "FormLabel"
103
+
104
+ const FormControl = React.forwardRef<
105
+ React.ElementRef<typeof Slot>,
106
+ React.ComponentPropsWithoutRef<typeof Slot>
107
+ >(({ ...props }, ref) => {
108
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
109
+
110
+ return (
111
+ <Slot
112
+ ref={ref}
113
+ id={formItemId}
114
+ aria-describedby={
115
+ !error
116
+ ? `${formDescriptionId}`
117
+ : `${formDescriptionId} ${formMessageId}`
118
+ }
119
+ aria-invalid={!!error}
120
+ {...props}
121
+ />
122
+ )
123
+ })
124
+ FormControl.displayName = "FormControl"
125
+
126
+ const FormDescription = React.forwardRef<
127
+ HTMLParagraphElement,
128
+ React.HTMLAttributes<HTMLParagraphElement>
129
+ >(({ className, ...props }, ref) => {
130
+ const { formDescriptionId } = useFormField()
131
+
132
+ return (
133
+ <p
134
+ ref={ref}
135
+ id={formDescriptionId}
136
+ className={cn("text-sm text-muted-foreground", className)}
137
+ {...props}
138
+ />
139
+ )
140
+ })
141
+ FormDescription.displayName = "FormDescription"
142
+
143
+ const FormMessage = React.forwardRef<
144
+ HTMLParagraphElement,
145
+ React.HTMLAttributes<HTMLParagraphElement>
146
+ >(({ className, children, ...props }, ref) => {
147
+ const { error, formMessageId } = useFormField()
148
+ const body = error ? String(error?.message) : children
149
+
150
+ if (!body) {
151
+ return null
152
+ }
153
+
154
+ return (
155
+ <p
156
+ ref={ref}
157
+ id={formMessageId}
158
+ className={cn("text-sm font-medium text-destructive", className)}
159
+ {...props}
160
+ >
161
+ {body}
162
+ </p>
163
+ )
164
+ })
165
+ FormMessage.displayName = "FormMessage"
166
+
167
+ export {
168
+ useFormField,
169
+ Form,
170
+ FormItem,
171
+ FormLabel,
172
+ FormControl,
173
+ FormDescription,
174
+ FormMessage,
175
+ FormField,
176
+ }
generated-icon.png ADDED

Git LFS Details

  • SHA256: 08dd44191f3902abdbad819fe8aed5475d1e12fc7ccd90eaab866a765fa60e53
  • Pointer size: 131 Bytes
  • Size of remote file: 314 kB
hover-card.tsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const HoverCard = HoverCardPrimitive.Root
7
+
8
+ const HoverCardTrigger = HoverCardPrimitive.Trigger
9
+
10
+ const HoverCardContent = React.forwardRef<
11
+ React.ElementRef<typeof HoverCardPrimitive.Content>,
12
+ React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
13
+ >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
14
+ <HoverCardPrimitive.Content
15
+ ref={ref}
16
+ align={align}
17
+ sideOffset={sideOffset}
18
+ className={cn(
19
+ "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ ))
25
+ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName
26
+
27
+ export { HoverCard, HoverCardTrigger, HoverCardContent }
index.css ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ * {
7
+ @apply border-border;
8
+ }
9
+
10
+ body {
11
+ @apply font-sans antialiased bg-background text-foreground;
12
+ }
13
+ }
index.html CHANGED
@@ -1,19 +1,11 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
6
+ </head>
7
+ <body>
8
+ <div id="root"></div>
9
+ <script type="module" src="/src/main.tsx"></script>
10
+ </body>
11
+ </html>
 
 
 
 
 
 
 
 
input-otp.tsx ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { OTPInput, OTPInputContext } from "input-otp"
3
+ import { Dot } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const InputOTP = React.forwardRef<
8
+ React.ElementRef<typeof OTPInput>,
9
+ React.ComponentPropsWithoutRef<typeof OTPInput>
10
+ >(({ className, containerClassName, ...props }, ref) => (
11
+ <OTPInput
12
+ ref={ref}
13
+ containerClassName={cn(
14
+ "flex items-center gap-2 has-[:disabled]:opacity-50",
15
+ containerClassName
16
+ )}
17
+ className={cn("disabled:cursor-not-allowed", className)}
18
+ {...props}
19
+ />
20
+ ))
21
+ InputOTP.displayName = "InputOTP"
22
+
23
+ const InputOTPGroup = React.forwardRef<
24
+ React.ElementRef<"div">,
25
+ React.ComponentPropsWithoutRef<"div">
26
+ >(({ className, ...props }, ref) => (
27
+ <div ref={ref} className={cn("flex items-center", className)} {...props} />
28
+ ))
29
+ InputOTPGroup.displayName = "InputOTPGroup"
30
+
31
+ const InputOTPSlot = React.forwardRef<
32
+ React.ElementRef<"div">,
33
+ React.ComponentPropsWithoutRef<"div"> & { index: number }
34
+ >(({ index, className, ...props }, ref) => {
35
+ const inputOTPContext = React.useContext(OTPInputContext)
36
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]
37
+
38
+ return (
39
+ <div
40
+ ref={ref}
41
+ className={cn(
42
+ "relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
43
+ isActive && "z-10 ring-2 ring-ring ring-offset-background",
44
+ className
45
+ )}
46
+ {...props}
47
+ >
48
+ {char}
49
+ {hasFakeCaret && (
50
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
51
+ <div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
52
+ </div>
53
+ )}
54
+ </div>
55
+ )
56
+ })
57
+ InputOTPSlot.displayName = "InputOTPSlot"
58
+
59
+ const InputOTPSeparator = React.forwardRef<
60
+ React.ElementRef<"div">,
61
+ React.ComponentPropsWithoutRef<"div">
62
+ >(({ ...props }, ref) => (
63
+ <div ref={ref} role="separator" {...props}>
64
+ <Dot />
65
+ </div>
66
+ ))
67
+ InputOTPSeparator.displayName = "InputOTPSeparator"
68
+
69
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
input.tsx ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ export interface InputProps
6
+ extends React.InputHTMLAttributes<HTMLInputElement> {}
7
+
8
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
9
+ ({ className, type, ...props }, ref) => {
10
+ return (
11
+ <input
12
+ type={type}
13
+ className={cn(
14
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
15
+ className
16
+ )}
17
+ ref={ref}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+ )
23
+ Input.displayName = "Input"
24
+
25
+ export { Input }
label.tsx ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as LabelPrimitive from "@radix-ui/react-label"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const labelVariants = cva(
8
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
9
+ )
10
+
11
+ const Label = React.forwardRef<
12
+ React.ElementRef<typeof LabelPrimitive.Root>,
13
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
14
+ VariantProps<typeof labelVariants>
15
+ >(({ className, ...props }, ref) => (
16
+ <LabelPrimitive.Root
17
+ ref={ref}
18
+ className={cn(labelVariants(), className)}
19
+ {...props}
20
+ />
21
+ ))
22
+ Label.displayName = LabelPrimitive.Root.displayName
23
+
24
+ export { Label }
main.tsx ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import { createRoot } from "react-dom/client";
2
+ import App from "./App";
3
+ import "./index.css";
4
+
5
+ createRoot(document.getElementById("root")!).render(<App />);
menubar.tsx ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as MenubarPrimitive from "@radix-ui/react-menubar"
3
+ import { Check, ChevronRight, Circle } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const MenubarMenu = MenubarPrimitive.Menu
8
+
9
+ const MenubarGroup = MenubarPrimitive.Group
10
+
11
+ const MenubarPortal = MenubarPrimitive.Portal
12
+
13
+ const MenubarSub = MenubarPrimitive.Sub
14
+
15
+ const MenubarRadioGroup = MenubarPrimitive.RadioGroup
16
+
17
+ const Menubar = React.forwardRef<
18
+ React.ElementRef<typeof MenubarPrimitive.Root>,
19
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
20
+ >(({ className, ...props }, ref) => (
21
+ <MenubarPrimitive.Root
22
+ ref={ref}
23
+ className={cn(
24
+ "flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
25
+ className
26
+ )}
27
+ {...props}
28
+ />
29
+ ))
30
+ Menubar.displayName = MenubarPrimitive.Root.displayName
31
+
32
+ const MenubarTrigger = React.forwardRef<
33
+ React.ElementRef<typeof MenubarPrimitive.Trigger>,
34
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
35
+ >(({ className, ...props }, ref) => (
36
+ <MenubarPrimitive.Trigger
37
+ ref={ref}
38
+ className={cn(
39
+ "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ ))
45
+ MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName
46
+
47
+ const MenubarSubTrigger = React.forwardRef<
48
+ React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
49
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
50
+ inset?: boolean
51
+ }
52
+ >(({ className, inset, children, ...props }, ref) => (
53
+ <MenubarPrimitive.SubTrigger
54
+ ref={ref}
55
+ className={cn(
56
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
57
+ inset && "pl-8",
58
+ className
59
+ )}
60
+ {...props}
61
+ >
62
+ {children}
63
+ <ChevronRight className="ml-auto h-4 w-4" />
64
+ </MenubarPrimitive.SubTrigger>
65
+ ))
66
+ MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName
67
+
68
+ const MenubarSubContent = React.forwardRef<
69
+ React.ElementRef<typeof MenubarPrimitive.SubContent>,
70
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
71
+ >(({ className, ...props }, ref) => (
72
+ <MenubarPrimitive.SubContent
73
+ ref={ref}
74
+ className={cn(
75
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
76
+ className
77
+ )}
78
+ {...props}
79
+ />
80
+ ))
81
+ MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName
82
+
83
+ const MenubarContent = React.forwardRef<
84
+ React.ElementRef<typeof MenubarPrimitive.Content>,
85
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
86
+ >(
87
+ (
88
+ { className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
89
+ ref
90
+ ) => (
91
+ <MenubarPrimitive.Portal>
92
+ <MenubarPrimitive.Content
93
+ ref={ref}
94
+ align={align}
95
+ alignOffset={alignOffset}
96
+ sideOffset={sideOffset}
97
+ className={cn(
98
+ "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
99
+ className
100
+ )}
101
+ {...props}
102
+ />
103
+ </MenubarPrimitive.Portal>
104
+ )
105
+ )
106
+ MenubarContent.displayName = MenubarPrimitive.Content.displayName
107
+
108
+ const MenubarItem = React.forwardRef<
109
+ React.ElementRef<typeof MenubarPrimitive.Item>,
110
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
111
+ inset?: boolean
112
+ }
113
+ >(({ className, inset, ...props }, ref) => (
114
+ <MenubarPrimitive.Item
115
+ ref={ref}
116
+ className={cn(
117
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
118
+ inset && "pl-8",
119
+ className
120
+ )}
121
+ {...props}
122
+ />
123
+ ))
124
+ MenubarItem.displayName = MenubarPrimitive.Item.displayName
125
+
126
+ const MenubarCheckboxItem = React.forwardRef<
127
+ React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
128
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
129
+ >(({ className, children, checked, ...props }, ref) => (
130
+ <MenubarPrimitive.CheckboxItem
131
+ ref={ref}
132
+ className={cn(
133
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
134
+ className
135
+ )}
136
+ checked={checked}
137
+ {...props}
138
+ >
139
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
140
+ <MenubarPrimitive.ItemIndicator>
141
+ <Check className="h-4 w-4" />
142
+ </MenubarPrimitive.ItemIndicator>
143
+ </span>
144
+ {children}
145
+ </MenubarPrimitive.CheckboxItem>
146
+ ))
147
+ MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName
148
+
149
+ const MenubarRadioItem = React.forwardRef<
150
+ React.ElementRef<typeof MenubarPrimitive.RadioItem>,
151
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
152
+ >(({ className, children, ...props }, ref) => (
153
+ <MenubarPrimitive.RadioItem
154
+ ref={ref}
155
+ className={cn(
156
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
157
+ className
158
+ )}
159
+ {...props}
160
+ >
161
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
162
+ <MenubarPrimitive.ItemIndicator>
163
+ <Circle className="h-2 w-2 fill-current" />
164
+ </MenubarPrimitive.ItemIndicator>
165
+ </span>
166
+ {children}
167
+ </MenubarPrimitive.RadioItem>
168
+ ))
169
+ MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName
170
+
171
+ const MenubarLabel = React.forwardRef<
172
+ React.ElementRef<typeof MenubarPrimitive.Label>,
173
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
174
+ inset?: boolean
175
+ }
176
+ >(({ className, inset, ...props }, ref) => (
177
+ <MenubarPrimitive.Label
178
+ ref={ref}
179
+ className={cn(
180
+ "px-2 py-1.5 text-sm font-semibold",
181
+ inset && "pl-8",
182
+ className
183
+ )}
184
+ {...props}
185
+ />
186
+ ))
187
+ MenubarLabel.displayName = MenubarPrimitive.Label.displayName
188
+
189
+ const MenubarSeparator = React.forwardRef<
190
+ React.ElementRef<typeof MenubarPrimitive.Separator>,
191
+ React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
192
+ >(({ className, ...props }, ref) => (
193
+ <MenubarPrimitive.Separator
194
+ ref={ref}
195
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
196
+ {...props}
197
+ />
198
+ ))
199
+ MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName
200
+
201
+ const MenubarShortcut = ({
202
+ className,
203
+ ...props
204
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
205
+ return (
206
+ <span
207
+ className={cn(
208
+ "ml-auto text-xs tracking-widest text-muted-foreground",
209
+ className
210
+ )}
211
+ {...props}
212
+ />
213
+ )
214
+ }
215
+ MenubarShortcut.displayname = "MenubarShortcut"
216
+
217
+ export {
218
+ Menubar,
219
+ MenubarMenu,
220
+ MenubarTrigger,
221
+ MenubarContent,
222
+ MenubarItem,
223
+ MenubarSeparator,
224
+ MenubarLabel,
225
+ MenubarCheckboxItem,
226
+ MenubarRadioGroup,
227
+ MenubarRadioItem,
228
+ MenubarPortal,
229
+ MenubarSubContent,
230
+ MenubarSubTrigger,
231
+ MenubarGroup,
232
+ MenubarSub,
233
+ MenubarShortcut,
234
+ }
navigation-menu.tsx ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
3
+ import { cva } from "class-variance-authority"
4
+ import { ChevronDown } from "lucide-react"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ const NavigationMenu = React.forwardRef<
9
+ React.ElementRef<typeof NavigationMenuPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
11
+ >(({ className, children, ...props }, ref) => (
12
+ <NavigationMenuPrimitive.Root
13
+ ref={ref}
14
+ className={cn(
15
+ "relative z-10 flex max-w-max flex-1 items-center justify-center",
16
+ className
17
+ )}
18
+ {...props}
19
+ >
20
+ {children}
21
+ <NavigationMenuViewport />
22
+ </NavigationMenuPrimitive.Root>
23
+ ))
24
+ NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
25
+
26
+ const NavigationMenuList = React.forwardRef<
27
+ React.ElementRef<typeof NavigationMenuPrimitive.List>,
28
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
29
+ >(({ className, ...props }, ref) => (
30
+ <NavigationMenuPrimitive.List
31
+ ref={ref}
32
+ className={cn(
33
+ "group flex flex-1 list-none items-center justify-center space-x-1",
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ ))
39
+ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
40
+
41
+ const NavigationMenuItem = NavigationMenuPrimitive.Item
42
+
43
+ const navigationMenuTriggerStyle = cva(
44
+ "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
45
+ )
46
+
47
+ const NavigationMenuTrigger = React.forwardRef<
48
+ React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
49
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
50
+ >(({ className, children, ...props }, ref) => (
51
+ <NavigationMenuPrimitive.Trigger
52
+ ref={ref}
53
+ className={cn(navigationMenuTriggerStyle(), "group", className)}
54
+ {...props}
55
+ >
56
+ {children}{" "}
57
+ <ChevronDown
58
+ className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
59
+ aria-hidden="true"
60
+ />
61
+ </NavigationMenuPrimitive.Trigger>
62
+ ))
63
+ NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
64
+
65
+ const NavigationMenuContent = React.forwardRef<
66
+ React.ElementRef<typeof NavigationMenuPrimitive.Content>,
67
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
68
+ >(({ className, ...props }, ref) => (
69
+ <NavigationMenuPrimitive.Content
70
+ ref={ref}
71
+ className={cn(
72
+ "left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ",
73
+ className
74
+ )}
75
+ {...props}
76
+ />
77
+ ))
78
+ NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
79
+
80
+ const NavigationMenuLink = NavigationMenuPrimitive.Link
81
+
82
+ const NavigationMenuViewport = React.forwardRef<
83
+ React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
84
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
85
+ >(({ className, ...props }, ref) => (
86
+ <div className={cn("absolute left-0 top-full flex justify-center")}>
87
+ <NavigationMenuPrimitive.Viewport
88
+ className={cn(
89
+ "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
90
+ className
91
+ )}
92
+ ref={ref}
93
+ {...props}
94
+ />
95
+ </div>
96
+ ))
97
+ NavigationMenuViewport.displayName =
98
+ NavigationMenuPrimitive.Viewport.displayName
99
+
100
+ const NavigationMenuIndicator = React.forwardRef<
101
+ React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
102
+ React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
103
+ >(({ className, ...props }, ref) => (
104
+ <NavigationMenuPrimitive.Indicator
105
+ ref={ref}
106
+ className={cn(
107
+ "top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
108
+ className
109
+ )}
110
+ {...props}
111
+ >
112
+ <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
113
+ </NavigationMenuPrimitive.Indicator>
114
+ ))
115
+ NavigationMenuIndicator.displayName =
116
+ NavigationMenuPrimitive.Indicator.displayName
117
+
118
+ export {
119
+ navigationMenuTriggerStyle,
120
+ NavigationMenu,
121
+ NavigationMenuList,
122
+ NavigationMenuItem,
123
+ NavigationMenuContent,
124
+ NavigationMenuTrigger,
125
+ NavigationMenuLink,
126
+ NavigationMenuIndicator,
127
+ NavigationMenuViewport,
128
+ }
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "rest-express",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "scripts": {
7
+ "dev": "tsx server/index.ts",
8
+ "build": "vite build && esbuild server/index.ts --platform=node --packages=external --bundle --format=esm --outdir=dist",
9
+ "start": "NODE_ENV=production node dist/index.js",
10
+ "check": "tsc",
11
+ "db:push": "drizzle-kit push"
12
+ },
13
+ "dependencies": {
14
+ "@hookform/resolvers": "^3.9.1",
15
+ "@jridgewell/trace-mapping": "^0.3.25",
16
+ "@neondatabase/serverless": "^0.10.4",
17
+ "@radix-ui/react-accordion": "^1.2.1",
18
+ "@radix-ui/react-alert-dialog": "^1.1.2",
19
+ "@radix-ui/react-aspect-ratio": "^1.1.0",
20
+ "@radix-ui/react-avatar": "^1.1.1",
21
+ "@radix-ui/react-checkbox": "^1.1.2",
22
+ "@radix-ui/react-collapsible": "^1.1.1",
23
+ "@radix-ui/react-context-menu": "^2.2.2",
24
+ "@radix-ui/react-dialog": "^1.1.2",
25
+ "@radix-ui/react-dropdown-menu": "^2.1.2",
26
+ "@radix-ui/react-hover-card": "^1.1.2",
27
+ "@radix-ui/react-label": "^2.1.0",
28
+ "@radix-ui/react-menubar": "^1.1.2",
29
+ "@radix-ui/react-navigation-menu": "^1.2.1",
30
+ "@radix-ui/react-popover": "^1.1.2",
31
+ "@radix-ui/react-progress": "^1.1.0",
32
+ "@radix-ui/react-radio-group": "^1.2.1",
33
+ "@radix-ui/react-scroll-area": "^1.2.0",
34
+ "@radix-ui/react-select": "^2.1.2",
35
+ "@radix-ui/react-separator": "^1.1.0",
36
+ "@radix-ui/react-slider": "^1.2.1",
37
+ "@radix-ui/react-slot": "^1.1.0",
38
+ "@radix-ui/react-switch": "^1.1.1",
39
+ "@radix-ui/react-tabs": "^1.1.1",
40
+ "@radix-ui/react-toast": "^1.2.2",
41
+ "@radix-ui/react-toggle": "^1.1.0",
42
+ "@radix-ui/react-toggle-group": "^1.1.0",
43
+ "@radix-ui/react-tooltip": "^1.1.3",
44
+ "@replit/vite-plugin-shadcn-theme-json": "^0.0.4",
45
+ "@tanstack/react-query": "^5.60.5",
46
+ "class-variance-authority": "^0.7.0",
47
+ "clsx": "^2.1.1",
48
+ "cmdk": "^1.0.0",
49
+ "connect-pg-simple": "^10.0.0",
50
+ "date-fns": "^3.6.0",
51
+ "drizzle-orm": "^0.39.1",
52
+ "drizzle-zod": "^0.7.0",
53
+ "embla-carousel-react": "^8.3.0",
54
+ "express": "^4.21.2",
55
+ "express-session": "^1.18.1",
56
+ "framer-motion": "^11.18.2",
57
+ "input-otp": "^1.2.4",
58
+ "lodash": "^4.17.21",
59
+ "lucide-react": "^0.453.0",
60
+ "memorystore": "^1.6.7",
61
+ "openai": "^4.88.0",
62
+ "passport": "^0.7.0",
63
+ "passport-local": "^1.0.0",
64
+ "react": "^18.3.1",
65
+ "react-day-picker": "^8.10.1",
66
+ "react-dom": "^18.3.1",
67
+ "react-hook-form": "^7.53.1",
68
+ "react-icons": "^5.4.0",
69
+ "react-resizable-panels": "^2.1.4",
70
+ "recharts": "^2.13.0",
71
+ "tailwind-merge": "^2.5.4",
72
+ "tailwindcss-animate": "^1.0.7",
73
+ "vaul": "^1.1.0",
74
+ "wouter": "^3.3.5",
75
+ "ws": "^8.18.0",
76
+ "zod": "^3.23.8",
77
+ "zod-validation-error": "^3.4.0"
78
+ },
79
+ "devDependencies": {
80
+ "@replit/vite-plugin-cartographer": "^0.0.11",
81
+ "@replit/vite-plugin-runtime-error-modal": "^0.0.3",
82
+ "@tailwindcss/typography": "^0.5.15",
83
+ "@types/connect-pg-simple": "^7.0.3",
84
+ "@types/express": "4.17.21",
85
+ "@types/express-session": "^1.18.0",
86
+ "@types/node": "20.16.11",
87
+ "@types/passport": "^1.0.16",
88
+ "@types/passport-local": "^1.0.38",
89
+ "@types/react": "^18.3.11",
90
+ "@types/react-dom": "^18.3.1",
91
+ "@types/ws": "^8.5.13",
92
+ "@vitejs/plugin-react": "^4.3.2",
93
+ "autoprefixer": "^10.4.20",
94
+ "drizzle-kit": "^0.30.4",
95
+ "esbuild": "^0.25.0",
96
+ "postcss": "^8.4.47",
97
+ "tailwindcss": "^3.4.14",
98
+ "tsx": "^4.19.1",
99
+ "typescript": "5.6.3",
100
+ "vite": "^5.4.14"
101
+ },
102
+ "optionalDependencies": {
103
+ "bufferutil": "^4.0.8"
104
+ }
105
+ }
pagination.tsx ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
3
+
4
+ import { cn } from "@/lib/utils"
5
+ import { ButtonProps, buttonVariants } from "@/components/ui/button"
6
+
7
+ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
8
+ <nav
9
+ role="navigation"
10
+ aria-label="pagination"
11
+ className={cn("mx-auto flex w-full justify-center", className)}
12
+ {...props}
13
+ />
14
+ )
15
+ Pagination.displayName = "Pagination"
16
+
17
+ const PaginationContent = React.forwardRef<
18
+ HTMLUListElement,
19
+ React.ComponentProps<"ul">
20
+ >(({ className, ...props }, ref) => (
21
+ <ul
22
+ ref={ref}
23
+ className={cn("flex flex-row items-center gap-1", className)}
24
+ {...props}
25
+ />
26
+ ))
27
+ PaginationContent.displayName = "PaginationContent"
28
+
29
+ const PaginationItem = React.forwardRef<
30
+ HTMLLIElement,
31
+ React.ComponentProps<"li">
32
+ >(({ className, ...props }, ref) => (
33
+ <li ref={ref} className={cn("", className)} {...props} />
34
+ ))
35
+ PaginationItem.displayName = "PaginationItem"
36
+
37
+ type PaginationLinkProps = {
38
+ isActive?: boolean
39
+ } & Pick<ButtonProps, "size"> &
40
+ React.ComponentProps<"a">
41
+
42
+ const PaginationLink = ({
43
+ className,
44
+ isActive,
45
+ size = "icon",
46
+ ...props
47
+ }: PaginationLinkProps) => (
48
+ <a
49
+ aria-current={isActive ? "page" : undefined}
50
+ className={cn(
51
+ buttonVariants({
52
+ variant: isActive ? "outline" : "ghost",
53
+ size,
54
+ }),
55
+ className
56
+ )}
57
+ {...props}
58
+ />
59
+ )
60
+ PaginationLink.displayName = "PaginationLink"
61
+
62
+ const PaginationPrevious = ({
63
+ className,
64
+ ...props
65
+ }: React.ComponentProps<typeof PaginationLink>) => (
66
+ <PaginationLink
67
+ aria-label="Go to previous page"
68
+ size="default"
69
+ className={cn("gap-1 pl-2.5", className)}
70
+ {...props}
71
+ >
72
+ <ChevronLeft className="h-4 w-4" />
73
+ <span>Previous</span>
74
+ </PaginationLink>
75
+ )
76
+ PaginationPrevious.displayName = "PaginationPrevious"
77
+
78
+ const PaginationNext = ({
79
+ className,
80
+ ...props
81
+ }: React.ComponentProps<typeof PaginationLink>) => (
82
+ <PaginationLink
83
+ aria-label="Go to next page"
84
+ size="default"
85
+ className={cn("gap-1 pr-2.5", className)}
86
+ {...props}
87
+ >
88
+ <span>Next</span>
89
+ <ChevronRight className="h-4 w-4" />
90
+ </PaginationLink>
91
+ )
92
+ PaginationNext.displayName = "PaginationNext"
93
+
94
+ const PaginationEllipsis = ({
95
+ className,
96
+ ...props
97
+ }: React.ComponentProps<"span">) => (
98
+ <span
99
+ aria-hidden
100
+ className={cn("flex h-9 w-9 items-center justify-center", className)}
101
+ {...props}
102
+ >
103
+ <MoreHorizontal className="h-4 w-4" />
104
+ <span className="sr-only">More pages</span>
105
+ </span>
106
+ )
107
+ PaginationEllipsis.displayName = "PaginationEllipsis"
108
+
109
+ export {
110
+ Pagination,
111
+ PaginationContent,
112
+ PaginationEllipsis,
113
+ PaginationItem,
114
+ PaginationLink,
115
+ PaginationNext,
116
+ PaginationPrevious,
117
+ }
popover.tsx ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as PopoverPrimitive from "@radix-ui/react-popover"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Popover = PopoverPrimitive.Root
7
+
8
+ const PopoverTrigger = PopoverPrimitive.Trigger
9
+
10
+ const PopoverContent = React.forwardRef<
11
+ React.ElementRef<typeof PopoverPrimitive.Content>,
12
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
13
+ >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
14
+ <PopoverPrimitive.Portal>
15
+ <PopoverPrimitive.Content
16
+ ref={ref}
17
+ align={align}
18
+ sideOffset={sideOffset}
19
+ className={cn(
20
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ </PopoverPrimitive.Portal>
26
+ ))
27
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName
28
+
29
+ export { Popover, PopoverTrigger, PopoverContent }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
progress.tsx ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as ProgressPrimitive from "@radix-ui/react-progress"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Progress = React.forwardRef<
7
+ React.ElementRef<typeof ProgressPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
9
+ >(({ className, value, ...props }, ref) => (
10
+ <ProgressPrimitive.Root
11
+ ref={ref}
12
+ className={cn(
13
+ "relative h-4 w-full overflow-hidden rounded-full bg-secondary",
14
+ className
15
+ )}
16
+ {...props}
17
+ >
18
+ <ProgressPrimitive.Indicator
19
+ className="h-full w-full flex-1 bg-primary transition-all"
20
+ style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
21
+ />
22
+ </ProgressPrimitive.Root>
23
+ ))
24
+ Progress.displayName = ProgressPrimitive.Root.displayName
25
+
26
+ export { Progress }
radio-group.tsx ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
3
+ import { Circle } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const RadioGroup = React.forwardRef<
8
+ React.ElementRef<typeof RadioGroupPrimitive.Root>,
9
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
10
+ >(({ className, ...props }, ref) => {
11
+ return (
12
+ <RadioGroupPrimitive.Root
13
+ className={cn("grid gap-2", className)}
14
+ {...props}
15
+ ref={ref}
16
+ />
17
+ )
18
+ })
19
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
20
+
21
+ const RadioGroupItem = React.forwardRef<
22
+ React.ElementRef<typeof RadioGroupPrimitive.Item>,
23
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
24
+ >(({ className, ...props }, ref) => {
25
+ return (
26
+ <RadioGroupPrimitive.Item
27
+ ref={ref}
28
+ className={cn(
29
+ "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
35
+ <Circle className="h-2.5 w-2.5 fill-current text-current" />
36
+ </RadioGroupPrimitive.Indicator>
37
+ </RadioGroupPrimitive.Item>
38
+ )
39
+ })
40
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
41
+
42
+ export { RadioGroup, RadioGroupItem }
resizable.tsx ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { GripVertical } from "lucide-react"
2
+ import * as ResizablePrimitive from "react-resizable-panels"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const ResizablePanelGroup = ({
7
+ className,
8
+ ...props
9
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
10
+ <ResizablePrimitive.PanelGroup
11
+ className={cn(
12
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
13
+ className
14
+ )}
15
+ {...props}
16
+ />
17
+ )
18
+
19
+ const ResizablePanel = ResizablePrimitive.Panel
20
+
21
+ const ResizableHandle = ({
22
+ withHandle,
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
26
+ withHandle?: boolean
27
+ }) => (
28
+ <ResizablePrimitive.PanelResizeHandle
29
+ className={cn(
30
+ "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
31
+ className
32
+ )}
33
+ {...props}
34
+ >
35
+ {withHandle && (
36
+ <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
37
+ <GripVertical className="h-2.5 w-2.5" />
38
+ </div>
39
+ )}
40
+ </ResizablePrimitive.PanelResizeHandle>
41
+ )
42
+
43
+ export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
scroll-area.tsx ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const ScrollArea = React.forwardRef<
7
+ React.ElementRef<typeof ScrollAreaPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
9
+ >(({ className, children, ...props }, ref) => (
10
+ <ScrollAreaPrimitive.Root
11
+ ref={ref}
12
+ className={cn("relative overflow-hidden", className)}
13
+ {...props}
14
+ >
15
+ <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
16
+ {children}
17
+ </ScrollAreaPrimitive.Viewport>
18
+ <ScrollBar />
19
+ <ScrollAreaPrimitive.Corner />
20
+ </ScrollAreaPrimitive.Root>
21
+ ))
22
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
23
+
24
+ const ScrollBar = React.forwardRef<
25
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
26
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
27
+ >(({ className, orientation = "vertical", ...props }, ref) => (
28
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
29
+ ref={ref}
30
+ orientation={orientation}
31
+ className={cn(
32
+ "flex touch-none select-none transition-colors",
33
+ orientation === "vertical" &&
34
+ "h-full w-2.5 border-l border-l-transparent p-[1px]",
35
+ orientation === "horizontal" &&
36
+ "h-2.5 flex-col border-t border-t-transparent p-[1px]",
37
+ className
38
+ )}
39
+ {...props}
40
+ >
41
+ <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
42
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
43
+ ))
44
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
45
+
46
+ export { ScrollArea, ScrollBar }
select.tsx ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as SelectPrimitive from "@radix-ui/react-select"
3
+ import { Check, ChevronDown, ChevronUp } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Select = SelectPrimitive.Root
8
+
9
+ const SelectGroup = SelectPrimitive.Group
10
+
11
+ const SelectValue = SelectPrimitive.Value
12
+
13
+ const SelectTrigger = React.forwardRef<
14
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
15
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
16
+ >(({ className, children, ...props }, ref) => (
17
+ <SelectPrimitive.Trigger
18
+ ref={ref}
19
+ className={cn(
20
+ "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
21
+ className
22
+ )}
23
+ {...props}
24
+ >
25
+ {children}
26
+ <SelectPrimitive.Icon asChild>
27
+ <ChevronDown className="h-4 w-4 opacity-50" />
28
+ </SelectPrimitive.Icon>
29
+ </SelectPrimitive.Trigger>
30
+ ))
31
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
32
+
33
+ const SelectScrollUpButton = React.forwardRef<
34
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
35
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
36
+ >(({ className, ...props }, ref) => (
37
+ <SelectPrimitive.ScrollUpButton
38
+ ref={ref}
39
+ className={cn(
40
+ "flex cursor-default items-center justify-center py-1",
41
+ className
42
+ )}
43
+ {...props}
44
+ >
45
+ <ChevronUp className="h-4 w-4" />
46
+ </SelectPrimitive.ScrollUpButton>
47
+ ))
48
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
49
+
50
+ const SelectScrollDownButton = React.forwardRef<
51
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
52
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
53
+ >(({ className, ...props }, ref) => (
54
+ <SelectPrimitive.ScrollDownButton
55
+ ref={ref}
56
+ className={cn(
57
+ "flex cursor-default items-center justify-center py-1",
58
+ className
59
+ )}
60
+ {...props}
61
+ >
62
+ <ChevronDown className="h-4 w-4" />
63
+ </SelectPrimitive.ScrollDownButton>
64
+ ))
65
+ SelectScrollDownButton.displayName =
66
+ SelectPrimitive.ScrollDownButton.displayName
67
+
68
+ const SelectContent = React.forwardRef<
69
+ React.ElementRef<typeof SelectPrimitive.Content>,
70
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
71
+ >(({ className, children, position = "popper", ...props }, ref) => (
72
+ <SelectPrimitive.Portal>
73
+ <SelectPrimitive.Content
74
+ ref={ref}
75
+ className={cn(
76
+ "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
77
+ position === "popper" &&
78
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
79
+ className
80
+ )}
81
+ position={position}
82
+ {...props}
83
+ >
84
+ <SelectScrollUpButton />
85
+ <SelectPrimitive.Viewport
86
+ className={cn(
87
+ "p-1",
88
+ position === "popper" &&
89
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
90
+ )}
91
+ >
92
+ {children}
93
+ </SelectPrimitive.Viewport>
94
+ <SelectScrollDownButton />
95
+ </SelectPrimitive.Content>
96
+ </SelectPrimitive.Portal>
97
+ ))
98
+ SelectContent.displayName = SelectPrimitive.Content.displayName
99
+
100
+ const SelectLabel = React.forwardRef<
101
+ React.ElementRef<typeof SelectPrimitive.Label>,
102
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
103
+ >(({ className, ...props }, ref) => (
104
+ <SelectPrimitive.Label
105
+ ref={ref}
106
+ className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
107
+ {...props}
108
+ />
109
+ ))
110
+ SelectLabel.displayName = SelectPrimitive.Label.displayName
111
+
112
+ const SelectItem = React.forwardRef<
113
+ React.ElementRef<typeof SelectPrimitive.Item>,
114
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
115
+ >(({ className, children, ...props }, ref) => (
116
+ <SelectPrimitive.Item
117
+ ref={ref}
118
+ className={cn(
119
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
120
+ className
121
+ )}
122
+ {...props}
123
+ >
124
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
125
+ <SelectPrimitive.ItemIndicator>
126
+ <Check className="h-4 w-4" />
127
+ </SelectPrimitive.ItemIndicator>
128
+ </span>
129
+
130
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
131
+ </SelectPrimitive.Item>
132
+ ))
133
+ SelectItem.displayName = SelectPrimitive.Item.displayName
134
+
135
+ const SelectSeparator = React.forwardRef<
136
+ React.ElementRef<typeof SelectPrimitive.Separator>,
137
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
138
+ >(({ className, ...props }, ref) => (
139
+ <SelectPrimitive.Separator
140
+ ref={ref}
141
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
142
+ {...props}
143
+ />
144
+ ))
145
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName
146
+
147
+ export {
148
+ Select,
149
+ SelectGroup,
150
+ SelectValue,
151
+ SelectTrigger,
152
+ SelectContent,
153
+ SelectLabel,
154
+ SelectItem,
155
+ SelectSeparator,
156
+ SelectScrollUpButton,
157
+ SelectScrollDownButton,
158
+ }
separator.tsx ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Separator = React.forwardRef<
7
+ React.ElementRef<typeof SeparatorPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
9
+ >(
10
+ (
11
+ { className, orientation = "horizontal", decorative = true, ...props },
12
+ ref
13
+ ) => (
14
+ <SeparatorPrimitive.Root
15
+ ref={ref}
16
+ decorative={decorative}
17
+ orientation={orientation}
18
+ className={cn(
19
+ "shrink-0 bg-border",
20
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ )
27
+ Separator.displayName = SeparatorPrimitive.Root.displayName
28
+
29
+ export { Separator }
sheet.tsx ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as SheetPrimitive from "@radix-ui/react-dialog"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+ import { X } from "lucide-react"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ const Sheet = SheetPrimitive.Root
9
+
10
+ const SheetTrigger = SheetPrimitive.Trigger
11
+
12
+ const SheetClose = SheetPrimitive.Close
13
+
14
+ const SheetPortal = SheetPrimitive.Portal
15
+
16
+ const SheetOverlay = React.forwardRef<
17
+ React.ElementRef<typeof SheetPrimitive.Overlay>,
18
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
19
+ >(({ className, ...props }, ref) => (
20
+ <SheetPrimitive.Overlay
21
+ className={cn(
22
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
+ className
24
+ )}
25
+ {...props}
26
+ ref={ref}
27
+ />
28
+ ))
29
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
30
+
31
+ const sheetVariants = cva(
32
+ "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
33
+ {
34
+ variants: {
35
+ side: {
36
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
37
+ bottom:
38
+ "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
39
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
40
+ right:
41
+ "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
42
+ },
43
+ },
44
+ defaultVariants: {
45
+ side: "right",
46
+ },
47
+ }
48
+ )
49
+
50
+ interface SheetContentProps
51
+ extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
52
+ VariantProps<typeof sheetVariants> {}
53
+
54
+ const SheetContent = React.forwardRef<
55
+ React.ElementRef<typeof SheetPrimitive.Content>,
56
+ SheetContentProps
57
+ >(({ side = "right", className, children, ...props }, ref) => (
58
+ <SheetPortal>
59
+ <SheetOverlay />
60
+ <SheetPrimitive.Content
61
+ ref={ref}
62
+ className={cn(sheetVariants({ side }), className)}
63
+ {...props}
64
+ >
65
+ {children}
66
+ <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
67
+ <X className="h-4 w-4" />
68
+ <span className="sr-only">Close</span>
69
+ </SheetPrimitive.Close>
70
+ </SheetPrimitive.Content>
71
+ </SheetPortal>
72
+ ))
73
+ SheetContent.displayName = SheetPrimitive.Content.displayName
74
+
75
+ const SheetHeader = ({
76
+ className,
77
+ ...props
78
+ }: React.HTMLAttributes<HTMLDivElement>) => (
79
+ <div
80
+ className={cn(
81
+ "flex flex-col space-y-2 text-center sm:text-left",
82
+ className
83
+ )}
84
+ {...props}
85
+ />
86
+ )
87
+ SheetHeader.displayName = "SheetHeader"
88
+
89
+ const SheetFooter = ({
90
+ className,
91
+ ...props
92
+ }: React.HTMLAttributes<HTMLDivElement>) => (
93
+ <div
94
+ className={cn(
95
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
96
+ className
97
+ )}
98
+ {...props}
99
+ />
100
+ )
101
+ SheetFooter.displayName = "SheetFooter"
102
+
103
+ const SheetTitle = React.forwardRef<
104
+ React.ElementRef<typeof SheetPrimitive.Title>,
105
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
106
+ >(({ className, ...props }, ref) => (
107
+ <SheetPrimitive.Title
108
+ ref={ref}
109
+ className={cn("text-lg font-semibold text-foreground", className)}
110
+ {...props}
111
+ />
112
+ ))
113
+ SheetTitle.displayName = SheetPrimitive.Title.displayName
114
+
115
+ const SheetDescription = React.forwardRef<
116
+ React.ElementRef<typeof SheetPrimitive.Description>,
117
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
118
+ >(({ className, ...props }, ref) => (
119
+ <SheetPrimitive.Description
120
+ ref={ref}
121
+ className={cn("text-sm text-muted-foreground", className)}
122
+ {...props}
123
+ />
124
+ ))
125
+ SheetDescription.displayName = SheetPrimitive.Description.displayName
126
+
127
+ export {
128
+ Sheet,
129
+ SheetPortal,
130
+ SheetOverlay,
131
+ SheetTrigger,
132
+ SheetClose,
133
+ SheetContent,
134
+ SheetHeader,
135
+ SheetFooter,
136
+ SheetTitle,
137
+ SheetDescription,
138
+ }
sidebar.tsx ADDED
@@ -0,0 +1,762 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { VariantProps, cva } from "class-variance-authority"
4
+ import { PanelLeft } from "lucide-react"
5
+
6
+ import { useIsMobile } from "@/hooks/use-mobile"
7
+ import { cn } from "@/lib/utils"
8
+ import { Button } from "@/components/ui/button"
9
+ import { Input } from "@/components/ui/input"
10
+ import { Separator } from "@/components/ui/separator"
11
+ import { Sheet, SheetContent } from "@/components/ui/sheet"
12
+ import { Skeleton } from "@/components/ui/skeleton"
13
+ import {
14
+ Tooltip,
15
+ TooltipContent,
16
+ TooltipProvider,
17
+ TooltipTrigger,
18
+ } from "@/components/ui/tooltip"
19
+
20
+ const SIDEBAR_COOKIE_NAME = "sidebar:state"
21
+ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
22
+ const SIDEBAR_WIDTH = "16rem"
23
+ const SIDEBAR_WIDTH_MOBILE = "18rem"
24
+ const SIDEBAR_WIDTH_ICON = "3rem"
25
+ const SIDEBAR_KEYBOARD_SHORTCUT = "b"
26
+
27
+ type SidebarContext = {
28
+ state: "expanded" | "collapsed"
29
+ open: boolean
30
+ setOpen: (open: boolean) => void
31
+ openMobile: boolean
32
+ setOpenMobile: (open: boolean) => void
33
+ isMobile: boolean
34
+ toggleSidebar: () => void
35
+ }
36
+
37
+ const SidebarContext = React.createContext<SidebarContext | null>(null)
38
+
39
+ function useSidebar() {
40
+ const context = React.useContext(SidebarContext)
41
+ if (!context) {
42
+ throw new Error("useSidebar must be used within a SidebarProvider.")
43
+ }
44
+
45
+ return context
46
+ }
47
+
48
+ const SidebarProvider = React.forwardRef<
49
+ HTMLDivElement,
50
+ React.ComponentProps<"div"> & {
51
+ defaultOpen?: boolean
52
+ open?: boolean
53
+ onOpenChange?: (open: boolean) => void
54
+ }
55
+ >(
56
+ (
57
+ {
58
+ defaultOpen = true,
59
+ open: openProp,
60
+ onOpenChange: setOpenProp,
61
+ className,
62
+ style,
63
+ children,
64
+ ...props
65
+ },
66
+ ref
67
+ ) => {
68
+ const isMobile = useIsMobile()
69
+ const [openMobile, setOpenMobile] = React.useState(false)
70
+
71
+ // This is the internal state of the sidebar.
72
+ // We use openProp and setOpenProp for control from outside the component.
73
+ const [_open, _setOpen] = React.useState(defaultOpen)
74
+ const open = openProp ?? _open
75
+ const setOpen = React.useCallback(
76
+ (value: boolean | ((value: boolean) => boolean)) => {
77
+ if (setOpenProp) {
78
+ return setOpenProp?.(
79
+ typeof value === "function" ? value(open) : value
80
+ )
81
+ }
82
+
83
+ _setOpen(value)
84
+
85
+ // This sets the cookie to keep the sidebar state.
86
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
87
+ },
88
+ [setOpenProp, open]
89
+ )
90
+
91
+ // Helper to toggle the sidebar.
92
+ const toggleSidebar = React.useCallback(() => {
93
+ return isMobile
94
+ ? setOpenMobile((open) => !open)
95
+ : setOpen((open) => !open)
96
+ }, [isMobile, setOpen, setOpenMobile])
97
+
98
+ // Adds a keyboard shortcut to toggle the sidebar.
99
+ React.useEffect(() => {
100
+ const handleKeyDown = (event: KeyboardEvent) => {
101
+ if (
102
+ event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
103
+ (event.metaKey || event.ctrlKey)
104
+ ) {
105
+ event.preventDefault()
106
+ toggleSidebar()
107
+ }
108
+ }
109
+
110
+ window.addEventListener("keydown", handleKeyDown)
111
+ return () => window.removeEventListener("keydown", handleKeyDown)
112
+ }, [toggleSidebar])
113
+
114
+ // We add a state so that we can do data-state="expanded" or "collapsed".
115
+ // This makes it easier to style the sidebar with Tailwind classes.
116
+ const state = open ? "expanded" : "collapsed"
117
+
118
+ const contextValue = React.useMemo<SidebarContext>(
119
+ () => ({
120
+ state,
121
+ open,
122
+ setOpen,
123
+ isMobile,
124
+ openMobile,
125
+ setOpenMobile,
126
+ toggleSidebar,
127
+ }),
128
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
129
+ )
130
+
131
+ return (
132
+ <SidebarContext.Provider value={contextValue}>
133
+ <TooltipProvider delayDuration={0}>
134
+ <div
135
+ style={
136
+ {
137
+ "--sidebar-width": SIDEBAR_WIDTH,
138
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
139
+ ...style,
140
+ } as React.CSSProperties
141
+ }
142
+ className={cn(
143
+ "group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar",
144
+ className
145
+ )}
146
+ ref={ref}
147
+ {...props}
148
+ >
149
+ {children}
150
+ </div>
151
+ </TooltipProvider>
152
+ </SidebarContext.Provider>
153
+ )
154
+ }
155
+ )
156
+ SidebarProvider.displayName = "SidebarProvider"
157
+
158
+ const Sidebar = React.forwardRef<
159
+ HTMLDivElement,
160
+ React.ComponentProps<"div"> & {
161
+ side?: "left" | "right"
162
+ variant?: "sidebar" | "floating" | "inset"
163
+ collapsible?: "offcanvas" | "icon" | "none"
164
+ }
165
+ >(
166
+ (
167
+ {
168
+ side = "left",
169
+ variant = "sidebar",
170
+ collapsible = "offcanvas",
171
+ className,
172
+ children,
173
+ ...props
174
+ },
175
+ ref
176
+ ) => {
177
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
178
+
179
+ if (collapsible === "none") {
180
+ return (
181
+ <div
182
+ className={cn(
183
+ "flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground",
184
+ className
185
+ )}
186
+ ref={ref}
187
+ {...props}
188
+ >
189
+ {children}
190
+ </div>
191
+ )
192
+ }
193
+
194
+ if (isMobile) {
195
+ return (
196
+ <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
197
+ <SheetContent
198
+ data-sidebar="sidebar"
199
+ data-mobile="true"
200
+ className="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
201
+ style={
202
+ {
203
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
204
+ } as React.CSSProperties
205
+ }
206
+ side={side}
207
+ >
208
+ <div className="flex h-full w-full flex-col">{children}</div>
209
+ </SheetContent>
210
+ </Sheet>
211
+ )
212
+ }
213
+
214
+ return (
215
+ <div
216
+ ref={ref}
217
+ className="group peer hidden md:block"
218
+ data-state={state}
219
+ data-collapsible={state === "collapsed" ? collapsible : ""}
220
+ data-variant={variant}
221
+ data-side={side}
222
+ >
223
+ {/* This is what handles the sidebar gap on desktop */}
224
+ <div
225
+ className={cn(
226
+ "duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear",
227
+ "group-data-[collapsible=offcanvas]:w-0",
228
+ "group-data-[side=right]:rotate-180",
229
+ variant === "floating" || variant === "inset"
230
+ ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
231
+ : "group-data-[collapsible=icon]:w-[--sidebar-width-icon]"
232
+ )}
233
+ />
234
+ <div
235
+ className={cn(
236
+ "duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex",
237
+ side === "left"
238
+ ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
239
+ : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
240
+ // Adjust the padding for floating and inset variants.
241
+ variant === "floating" || variant === "inset"
242
+ ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]"
243
+ : "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",
244
+ className
245
+ )}
246
+ {...props}
247
+ >
248
+ <div
249
+ data-sidebar="sidebar"
250
+ className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
251
+ >
252
+ {children}
253
+ </div>
254
+ </div>
255
+ </div>
256
+ )
257
+ }
258
+ )
259
+ Sidebar.displayName = "Sidebar"
260
+
261
+ const SidebarTrigger = React.forwardRef<
262
+ React.ElementRef<typeof Button>,
263
+ React.ComponentProps<typeof Button>
264
+ >(({ className, onClick, ...props }, ref) => {
265
+ const { toggleSidebar } = useSidebar()
266
+
267
+ return (
268
+ <Button
269
+ ref={ref}
270
+ data-sidebar="trigger"
271
+ variant="ghost"
272
+ size="icon"
273
+ className={cn("h-7 w-7", className)}
274
+ onClick={(event) => {
275
+ onClick?.(event)
276
+ toggleSidebar()
277
+ }}
278
+ {...props}
279
+ >
280
+ <PanelLeft />
281
+ <span className="sr-only">Toggle Sidebar</span>
282
+ </Button>
283
+ )
284
+ })
285
+ SidebarTrigger.displayName = "SidebarTrigger"
286
+
287
+ const SidebarRail = React.forwardRef<
288
+ HTMLButtonElement,
289
+ React.ComponentProps<"button">
290
+ >(({ className, ...props }, ref) => {
291
+ const { toggleSidebar } = useSidebar()
292
+
293
+ return (
294
+ <button
295
+ ref={ref}
296
+ data-sidebar="rail"
297
+ aria-label="Toggle Sidebar"
298
+ tabIndex={-1}
299
+ onClick={toggleSidebar}
300
+ title="Toggle Sidebar"
301
+ className={cn(
302
+ "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
303
+ "[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize",
304
+ "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
305
+ "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
306
+ "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
307
+ "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
308
+ className
309
+ )}
310
+ {...props}
311
+ />
312
+ )
313
+ })
314
+ SidebarRail.displayName = "SidebarRail"
315
+
316
+ const SidebarInset = React.forwardRef<
317
+ HTMLDivElement,
318
+ React.ComponentProps<"main">
319
+ >(({ className, ...props }, ref) => {
320
+ return (
321
+ <main
322
+ ref={ref}
323
+ className={cn(
324
+ "relative flex min-h-svh flex-1 flex-col bg-background",
325
+ "peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
326
+ className
327
+ )}
328
+ {...props}
329
+ />
330
+ )
331
+ })
332
+ SidebarInset.displayName = "SidebarInset"
333
+
334
+ const SidebarInput = React.forwardRef<
335
+ React.ElementRef<typeof Input>,
336
+ React.ComponentProps<typeof Input>
337
+ >(({ className, ...props }, ref) => {
338
+ return (
339
+ <Input
340
+ ref={ref}
341
+ data-sidebar="input"
342
+ className={cn(
343
+ "h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
344
+ className
345
+ )}
346
+ {...props}
347
+ />
348
+ )
349
+ })
350
+ SidebarInput.displayName = "SidebarInput"
351
+
352
+ const SidebarHeader = React.forwardRef<
353
+ HTMLDivElement,
354
+ React.ComponentProps<"div">
355
+ >(({ className, ...props }, ref) => {
356
+ return (
357
+ <div
358
+ ref={ref}
359
+ data-sidebar="header"
360
+ className={cn("flex flex-col gap-2 p-2", className)}
361
+ {...props}
362
+ />
363
+ )
364
+ })
365
+ SidebarHeader.displayName = "SidebarHeader"
366
+
367
+ const SidebarFooter = React.forwardRef<
368
+ HTMLDivElement,
369
+ React.ComponentProps<"div">
370
+ >(({ className, ...props }, ref) => {
371
+ return (
372
+ <div
373
+ ref={ref}
374
+ data-sidebar="footer"
375
+ className={cn("flex flex-col gap-2 p-2", className)}
376
+ {...props}
377
+ />
378
+ )
379
+ })
380
+ SidebarFooter.displayName = "SidebarFooter"
381
+
382
+ const SidebarSeparator = React.forwardRef<
383
+ React.ElementRef<typeof Separator>,
384
+ React.ComponentProps<typeof Separator>
385
+ >(({ className, ...props }, ref) => {
386
+ return (
387
+ <Separator
388
+ ref={ref}
389
+ data-sidebar="separator"
390
+ className={cn("mx-2 w-auto bg-sidebar-border", className)}
391
+ {...props}
392
+ />
393
+ )
394
+ })
395
+ SidebarSeparator.displayName = "SidebarSeparator"
396
+
397
+ const SidebarContent = React.forwardRef<
398
+ HTMLDivElement,
399
+ React.ComponentProps<"div">
400
+ >(({ className, ...props }, ref) => {
401
+ return (
402
+ <div
403
+ ref={ref}
404
+ data-sidebar="content"
405
+ className={cn(
406
+ "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
407
+ className
408
+ )}
409
+ {...props}
410
+ />
411
+ )
412
+ })
413
+ SidebarContent.displayName = "SidebarContent"
414
+
415
+ const SidebarGroup = React.forwardRef<
416
+ HTMLDivElement,
417
+ React.ComponentProps<"div">
418
+ >(({ className, ...props }, ref) => {
419
+ return (
420
+ <div
421
+ ref={ref}
422
+ data-sidebar="group"
423
+ className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
424
+ {...props}
425
+ />
426
+ )
427
+ })
428
+ SidebarGroup.displayName = "SidebarGroup"
429
+
430
+ const SidebarGroupLabel = React.forwardRef<
431
+ HTMLDivElement,
432
+ React.ComponentProps<"div"> & { asChild?: boolean }
433
+ >(({ className, asChild = false, ...props }, ref) => {
434
+ const Comp = asChild ? Slot : "div"
435
+
436
+ return (
437
+ <Comp
438
+ ref={ref}
439
+ data-sidebar="group-label"
440
+ className={cn(
441
+ "duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
442
+ "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
443
+ className
444
+ )}
445
+ {...props}
446
+ />
447
+ )
448
+ })
449
+ SidebarGroupLabel.displayName = "SidebarGroupLabel"
450
+
451
+ const SidebarGroupAction = React.forwardRef<
452
+ HTMLButtonElement,
453
+ React.ComponentProps<"button"> & { asChild?: boolean }
454
+ >(({ className, asChild = false, ...props }, ref) => {
455
+ const Comp = asChild ? Slot : "button"
456
+
457
+ return (
458
+ <Comp
459
+ ref={ref}
460
+ data-sidebar="group-action"
461
+ className={cn(
462
+ "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
463
+ // Increases the hit area of the button on mobile.
464
+ "after:absolute after:-inset-2 after:md:hidden",
465
+ "group-data-[collapsible=icon]:hidden",
466
+ className
467
+ )}
468
+ {...props}
469
+ />
470
+ )
471
+ })
472
+ SidebarGroupAction.displayName = "SidebarGroupAction"
473
+
474
+ const SidebarGroupContent = React.forwardRef<
475
+ HTMLDivElement,
476
+ React.ComponentProps<"div">
477
+ >(({ className, ...props }, ref) => (
478
+ <div
479
+ ref={ref}
480
+ data-sidebar="group-content"
481
+ className={cn("w-full text-sm", className)}
482
+ {...props}
483
+ />
484
+ ))
485
+ SidebarGroupContent.displayName = "SidebarGroupContent"
486
+
487
+ const SidebarMenu = React.forwardRef<
488
+ HTMLUListElement,
489
+ React.ComponentProps<"ul">
490
+ >(({ className, ...props }, ref) => (
491
+ <ul
492
+ ref={ref}
493
+ data-sidebar="menu"
494
+ className={cn("flex w-full min-w-0 flex-col gap-1", className)}
495
+ {...props}
496
+ />
497
+ ))
498
+ SidebarMenu.displayName = "SidebarMenu"
499
+
500
+ const SidebarMenuItem = React.forwardRef<
501
+ HTMLLIElement,
502
+ React.ComponentProps<"li">
503
+ >(({ className, ...props }, ref) => (
504
+ <li
505
+ ref={ref}
506
+ data-sidebar="menu-item"
507
+ className={cn("group/menu-item relative", className)}
508
+ {...props}
509
+ />
510
+ ))
511
+ SidebarMenuItem.displayName = "SidebarMenuItem"
512
+
513
+ const sidebarMenuButtonVariants = cva(
514
+ "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
515
+ {
516
+ variants: {
517
+ variant: {
518
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
519
+ outline:
520
+ "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
521
+ },
522
+ size: {
523
+ default: "h-8 text-sm",
524
+ sm: "h-7 text-xs",
525
+ lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0",
526
+ },
527
+ },
528
+ defaultVariants: {
529
+ variant: "default",
530
+ size: "default",
531
+ },
532
+ }
533
+ )
534
+
535
+ const SidebarMenuButton = React.forwardRef<
536
+ HTMLButtonElement,
537
+ React.ComponentProps<"button"> & {
538
+ asChild?: boolean
539
+ isActive?: boolean
540
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>
541
+ } & VariantProps<typeof sidebarMenuButtonVariants>
542
+ >(
543
+ (
544
+ {
545
+ asChild = false,
546
+ isActive = false,
547
+ variant = "default",
548
+ size = "default",
549
+ tooltip,
550
+ className,
551
+ ...props
552
+ },
553
+ ref
554
+ ) => {
555
+ const Comp = asChild ? Slot : "button"
556
+ const { isMobile, state } = useSidebar()
557
+
558
+ const button = (
559
+ <Comp
560
+ ref={ref}
561
+ data-sidebar="menu-button"
562
+ data-size={size}
563
+ data-active={isActive}
564
+ className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
565
+ {...props}
566
+ />
567
+ )
568
+
569
+ if (!tooltip) {
570
+ return button
571
+ }
572
+
573
+ if (typeof tooltip === "string") {
574
+ tooltip = {
575
+ children: tooltip,
576
+ }
577
+ }
578
+
579
+ return (
580
+ <Tooltip>
581
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
582
+ <TooltipContent
583
+ side="right"
584
+ align="center"
585
+ hidden={state !== "collapsed" || isMobile}
586
+ {...tooltip}
587
+ />
588
+ </Tooltip>
589
+ )
590
+ }
591
+ )
592
+ SidebarMenuButton.displayName = "SidebarMenuButton"
593
+
594
+ const SidebarMenuAction = React.forwardRef<
595
+ HTMLButtonElement,
596
+ React.ComponentProps<"button"> & {
597
+ asChild?: boolean
598
+ showOnHover?: boolean
599
+ }
600
+ >(({ className, asChild = false, showOnHover = false, ...props }, ref) => {
601
+ const Comp = asChild ? Slot : "button"
602
+
603
+ return (
604
+ <Comp
605
+ ref={ref}
606
+ data-sidebar="menu-action"
607
+ className={cn(
608
+ "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
609
+ // Increases the hit area of the button on mobile.
610
+ "after:absolute after:-inset-2 after:md:hidden",
611
+ "peer-data-[size=sm]/menu-button:top-1",
612
+ "peer-data-[size=default]/menu-button:top-1.5",
613
+ "peer-data-[size=lg]/menu-button:top-2.5",
614
+ "group-data-[collapsible=icon]:hidden",
615
+ showOnHover &&
616
+ "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
617
+ className
618
+ )}
619
+ {...props}
620
+ />
621
+ )
622
+ })
623
+ SidebarMenuAction.displayName = "SidebarMenuAction"
624
+
625
+ const SidebarMenuBadge = React.forwardRef<
626
+ HTMLDivElement,
627
+ React.ComponentProps<"div">
628
+ >(({ className, ...props }, ref) => (
629
+ <div
630
+ ref={ref}
631
+ data-sidebar="menu-badge"
632
+ className={cn(
633
+ "absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none",
634
+ "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
635
+ "peer-data-[size=sm]/menu-button:top-1",
636
+ "peer-data-[size=default]/menu-button:top-1.5",
637
+ "peer-data-[size=lg]/menu-button:top-2.5",
638
+ "group-data-[collapsible=icon]:hidden",
639
+ className
640
+ )}
641
+ {...props}
642
+ />
643
+ ))
644
+ SidebarMenuBadge.displayName = "SidebarMenuBadge"
645
+
646
+ const SidebarMenuSkeleton = React.forwardRef<
647
+ HTMLDivElement,
648
+ React.ComponentProps<"div"> & {
649
+ showIcon?: boolean
650
+ }
651
+ >(({ className, showIcon = false, ...props }, ref) => {
652
+ // Random width between 50 to 90%.
653
+ const width = React.useMemo(() => {
654
+ return `${Math.floor(Math.random() * 40) + 50}%`
655
+ }, [])
656
+
657
+ return (
658
+ <div
659
+ ref={ref}
660
+ data-sidebar="menu-skeleton"
661
+ className={cn("rounded-md h-8 flex gap-2 px-2 items-center", className)}
662
+ {...props}
663
+ >
664
+ {showIcon && (
665
+ <Skeleton
666
+ className="size-4 rounded-md"
667
+ data-sidebar="menu-skeleton-icon"
668
+ />
669
+ )}
670
+ <Skeleton
671
+ className="h-4 flex-1 max-w-[--skeleton-width]"
672
+ data-sidebar="menu-skeleton-text"
673
+ style={
674
+ {
675
+ "--skeleton-width": width,
676
+ } as React.CSSProperties
677
+ }
678
+ />
679
+ </div>
680
+ )
681
+ })
682
+ SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton"
683
+
684
+ const SidebarMenuSub = React.forwardRef<
685
+ HTMLUListElement,
686
+ React.ComponentProps<"ul">
687
+ >(({ className, ...props }, ref) => (
688
+ <ul
689
+ ref={ref}
690
+ data-sidebar="menu-sub"
691
+ className={cn(
692
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
693
+ "group-data-[collapsible=icon]:hidden",
694
+ className
695
+ )}
696
+ {...props}
697
+ />
698
+ ))
699
+ SidebarMenuSub.displayName = "SidebarMenuSub"
700
+
701
+ const SidebarMenuSubItem = React.forwardRef<
702
+ HTMLLIElement,
703
+ React.ComponentProps<"li">
704
+ >(({ ...props }, ref) => <li ref={ref} {...props} />)
705
+ SidebarMenuSubItem.displayName = "SidebarMenuSubItem"
706
+
707
+ const SidebarMenuSubButton = React.forwardRef<
708
+ HTMLAnchorElement,
709
+ React.ComponentProps<"a"> & {
710
+ asChild?: boolean
711
+ size?: "sm" | "md"
712
+ isActive?: boolean
713
+ }
714
+ >(({ asChild = false, size = "md", isActive, className, ...props }, ref) => {
715
+ const Comp = asChild ? Slot : "a"
716
+
717
+ return (
718
+ <Comp
719
+ ref={ref}
720
+ data-sidebar="menu-sub-button"
721
+ data-size={size}
722
+ data-active={isActive}
723
+ className={cn(
724
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
725
+ "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
726
+ size === "sm" && "text-xs",
727
+ size === "md" && "text-sm",
728
+ "group-data-[collapsible=icon]:hidden",
729
+ className
730
+ )}
731
+ {...props}
732
+ />
733
+ )
734
+ })
735
+ SidebarMenuSubButton.displayName = "SidebarMenuSubButton"
736
+
737
+ export {
738
+ Sidebar,
739
+ SidebarContent,
740
+ SidebarFooter,
741
+ SidebarGroup,
742
+ SidebarGroupAction,
743
+ SidebarGroupContent,
744
+ SidebarGroupLabel,
745
+ SidebarHeader,
746
+ SidebarInput,
747
+ SidebarInset,
748
+ SidebarMenu,
749
+ SidebarMenuAction,
750
+ SidebarMenuBadge,
751
+ SidebarMenuButton,
752
+ SidebarMenuItem,
753
+ SidebarMenuSkeleton,
754
+ SidebarMenuSub,
755
+ SidebarMenuSubButton,
756
+ SidebarMenuSubItem,
757
+ SidebarProvider,
758
+ SidebarRail,
759
+ SidebarSeparator,
760
+ SidebarTrigger,
761
+ useSidebar,
762
+ }
skeleton.tsx ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { cn } from "@/lib/utils"
2
+
3
+ function Skeleton({
4
+ className,
5
+ ...props
6
+ }: React.HTMLAttributes<HTMLDivElement>) {
7
+ return (
8
+ <div
9
+ className={cn("animate-pulse rounded-md bg-muted", className)}
10
+ {...props}
11
+ />
12
+ )
13
+ }
14
+
15
+ export { Skeleton }