Reubencf commited on
Commit
4416784
·
1 Parent(s): 10299c3

fixing MCP quiz

Browse files
app/api/data/route.ts CHANGED
@@ -53,13 +53,25 @@ export async function GET(request: NextRequest) {
53
  const stats = await stat(itemPath)
54
  const relativePath = path.relative(userDir, itemPath)
55
 
 
 
 
 
 
 
 
 
 
 
 
56
  return {
57
  name: item,
58
  type: stats.isDirectory() ? 'folder' : 'file',
59
  size: stats.size,
60
  modified: stats.mtime.toISOString(),
61
  path: relativePath,
62
- extension: path.extname(item).substring(1)
 
63
  }
64
  }))
65
 
@@ -72,6 +84,39 @@ export async function GET(request: NextRequest) {
72
 
73
  export async function POST(request: NextRequest) {
74
  try {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  const formData = await request.formData()
76
  const file = formData.get('file') as File
77
  const key = formData.get('key') as string
@@ -99,8 +144,8 @@ export async function POST(request: NextRequest) {
99
 
100
  return NextResponse.json({ success: true })
101
  } catch (error) {
102
- console.error('Error uploading file:', error)
103
- return NextResponse.json({ error: 'Upload failed' }, { status: 500 })
104
  }
105
  }
106
 
 
53
  const stats = await stat(itemPath)
54
  const relativePath = path.relative(userDir, itemPath)
55
 
56
+ // Read content for JSON files (like quiz.json, quiz_answers.json)
57
+ let content = undefined
58
+ if (!stats.isDirectory() && path.extname(item).toLowerCase() === '.json') {
59
+ try {
60
+ const fileContent = await fs.promises.readFile(itemPath, 'utf-8')
61
+ content = fileContent
62
+ } catch (err) {
63
+ console.error(`Error reading ${item}:`, err)
64
+ }
65
+ }
66
+
67
  return {
68
  name: item,
69
  type: stats.isDirectory() ? 'folder' : 'file',
70
  size: stats.size,
71
  modified: stats.mtime.toISOString(),
72
  path: relativePath,
73
+ extension: path.extname(item).substring(1),
74
+ ...(content !== undefined && { content })
75
  }
76
  }))
77
 
 
84
 
85
  export async function POST(request: NextRequest) {
86
  try {
87
+ const contentType = request.headers.get('content-type')
88
+
89
+ // Handle JSON body (for save_file action)
90
+ if (contentType?.includes('application/json')) {
91
+ const body = await request.json()
92
+ const { passkey, action, fileName, content, folder = '' } = body
93
+
94
+ if (!passkey) {
95
+ return NextResponse.json({ error: 'Passkey is required' }, { status: 400 })
96
+ }
97
+
98
+ if (action === 'save_file') {
99
+ if (!fileName || !content) {
100
+ return NextResponse.json({ error: 'fileName and content are required' }, { status: 400 })
101
+ }
102
+
103
+ const sanitizedKey = passkey.replace(/[^a-zA-Z0-9_-]/g, '')
104
+ const userDir = path.join(DATA_DIR, sanitizedKey)
105
+ const targetDir = path.join(userDir, folder)
106
+
107
+ // Ensure directories exist
108
+ await mkdir(targetDir, { recursive: true })
109
+
110
+ const filePath = path.join(targetDir, fileName)
111
+ await writeFile(filePath, content, 'utf-8')
112
+
113
+ return NextResponse.json({ success: true })
114
+ }
115
+
116
+ return NextResponse.json({ error: 'Unknown action' }, { status: 400 })
117
+ }
118
+
119
+ // Handle FormData (for file uploads)
120
  const formData = await request.formData()
121
  const file = formData.get('file') as File
122
  const key = formData.get('key') as string
 
144
 
145
  return NextResponse.json({ success: true })
146
  } catch (error) {
147
+ console.error('Error in POST handler:', error)
148
+ return NextResponse.json({ error: 'Operation failed' }, { status: 500 })
149
  }
150
  }
151
 
app/components/Calendar.tsx CHANGED
@@ -235,9 +235,9 @@ export function Calendar({ onClose, onMinimize, onMaximize, onFocus, zIndex }: C
235
  {['Home', 'Work', 'Holidays', 'Birthdays'].map((cal, i) => (
236
  <div key={cal} className="flex items-center gap-3 px-2 py-1.5 rounded-md hover:bg-white/5 cursor-pointer group">
237
  <div className={`w-3 h-3 rounded-full border-2 ${i === 0 ? 'border-blue-500 bg-blue-500' :
238
- i === 1 ? 'border-purple-500 bg-purple-500' :
239
- i === 2 ? 'border-green-500 bg-green-500' :
240
- 'border-red-500 bg-red-500'
241
  }`} />
242
  <span className="text-sm text-gray-300">{cal}</span>
243
  <Check size={12} className="ml-auto opacity-0 group-hover:opacity-100 text-gray-500" />
@@ -308,61 +308,63 @@ export function Calendar({ onClose, onMinimize, onMaximize, onFocus, zIndex }: C
308
  animate={{ opacity: 1, scale: 1 }}
309
  exit={{ opacity: 0, scale: 1.02 }}
310
  transition={{ duration: 0.2 }}
311
- className="h-full flex flex-col"
312
  >
313
- <div className="grid grid-cols-7 border-b border-white/5 bg-black/10">
314
- {weekDays.map(day => (
315
- <div key={day} className="py-2 text-right pr-4 text-xs font-medium text-gray-500 uppercase tracking-wider">
316
- {day}
317
- </div>
318
- ))}
319
- </div>
320
- <div className="flex-1 grid grid-cols-7 grid-rows-6">
321
- {calendarDays.map((dateObj, index) => {
322
- const dateStr = `${dateObj.year}-${String(dateObj.month + 1).padStart(2, '0')}-${String(dateObj.day).padStart(2, '0')}`
323
- const dayEvents = getEventsForDate(dateStr)
324
- const isCurrentDay = isToday(dateObj.day, dateObj.month, dateObj.year)
325
-
326
- return (
327
- <div
328
- key={index}
329
- className={`
 
330
  border-b border-r border-white/5 p-1 relative group transition-colors
331
  ${!dateObj.isCurrentMonth ? 'bg-black/20 text-gray-600' : 'hover:bg-white/5'}
332
  `}
333
- onClick={() => {
334
- setCurrentDate(new Date(dateObj.year, dateObj.month, dateObj.day))
335
- setView('day')
336
- }}
337
- >
338
- <div className="flex justify-end mb-1">
339
- <span
340
- className={`
341
  text-sm font-medium w-7 h-7 flex items-center justify-center rounded-full
342
  ${isCurrentDay
343
- ? 'bg-red-500 text-white shadow-lg shadow-red-900/50'
344
- : dateObj.isCurrentMonth ? 'text-gray-300' : 'text-gray-600'}
345
  `}
346
- >
347
- {dateObj.day}
348
- </span>
349
- </div>
350
- <div className="space-y-1 overflow-y-auto max-h-[calc(100%-2rem)] [&::-webkit-scrollbar]:hidden">
351
- {dayEvents.map((event, i) => (
352
- <div
353
- key={i}
354
- className={`
355
  text-[10px] px-1.5 py-0.5 rounded-sm truncate cursor-pointer hover:opacity-80
356
  ${event.color || 'bg-blue-500'} text-white font-medium shadow-sm backdrop-blur-sm bg-opacity-80
357
  `}
358
- >
359
- {event.title}
360
- </div>
361
- ))}
 
362
  </div>
363
- </div>
364
- )
365
- })}
366
  </div>
367
  </motion.div>
368
  )}
@@ -373,9 +375,9 @@ export function Calendar({ onClose, onMinimize, onMaximize, onFocus, zIndex }: C
373
  initial={{ opacity: 0 }}
374
  animate={{ opacity: 1 }}
375
  exit={{ opacity: 0 }}
376
- className="h-full overflow-y-auto p-8 [&::-webkit-scrollbar-thumb]:bg-white/20 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar]:w-2"
377
  >
378
- <div className="grid grid-cols-4 gap-x-8 gap-y-12">
379
  {monthNames.map((month, monthIndex) => {
380
  const days = getDaysInMonth(currentDate.getFullYear(), monthIndex)
381
  return (
 
235
  {['Home', 'Work', 'Holidays', 'Birthdays'].map((cal, i) => (
236
  <div key={cal} className="flex items-center gap-3 px-2 py-1.5 rounded-md hover:bg-white/5 cursor-pointer group">
237
  <div className={`w-3 h-3 rounded-full border-2 ${i === 0 ? 'border-blue-500 bg-blue-500' :
238
+ i === 1 ? 'border-purple-500 bg-purple-500' :
239
+ i === 2 ? 'border-green-500 bg-green-500' :
240
+ 'border-red-500 bg-red-500'
241
  }`} />
242
  <span className="text-sm text-gray-300">{cal}</span>
243
  <Check size={12} className="ml-auto opacity-0 group-hover:opacity-100 text-gray-500" />
 
308
  animate={{ opacity: 1, scale: 1 }}
309
  exit={{ opacity: 0, scale: 1.02 }}
310
  transition={{ duration: 0.2 }}
311
+ className="h-full flex flex-col overflow-auto"
312
  >
313
+ <div className="min-w-[600px] h-full flex flex-col">
314
+ <div className="grid grid-cols-7 border-b border-white/5 bg-black/10">
315
+ {weekDays.map(day => (
316
+ <div key={day} className="py-2 text-right pr-4 text-xs font-medium text-gray-500 uppercase tracking-wider">
317
+ {day}
318
+ </div>
319
+ ))}
320
+ </div>
321
+ <div className="flex-1 grid grid-cols-7 grid-rows-6">
322
+ {calendarDays.map((dateObj, index) => {
323
+ const dateStr = `${dateObj.year}-${String(dateObj.month + 1).padStart(2, '0')}-${String(dateObj.day).padStart(2, '0')}`
324
+ const dayEvents = getEventsForDate(dateStr)
325
+ const isCurrentDay = isToday(dateObj.day, dateObj.month, dateObj.year)
326
+
327
+ return (
328
+ <div
329
+ key={index}
330
+ className={`
331
  border-b border-r border-white/5 p-1 relative group transition-colors
332
  ${!dateObj.isCurrentMonth ? 'bg-black/20 text-gray-600' : 'hover:bg-white/5'}
333
  `}
334
+ onClick={() => {
335
+ setCurrentDate(new Date(dateObj.year, dateObj.month, dateObj.day))
336
+ setView('day')
337
+ }}
338
+ >
339
+ <div className="flex justify-end mb-1">
340
+ <span
341
+ className={`
342
  text-sm font-medium w-7 h-7 flex items-center justify-center rounded-full
343
  ${isCurrentDay
344
+ ? 'bg-red-500 text-white shadow-lg shadow-red-900/50'
345
+ : dateObj.isCurrentMonth ? 'text-gray-300' : 'text-gray-600'}
346
  `}
347
+ >
348
+ {dateObj.day}
349
+ </span>
350
+ </div>
351
+ <div className="space-y-1 overflow-y-auto max-h-[calc(100%-2rem)] [&::-webkit-scrollbar]:hidden">
352
+ {dayEvents.map((event, i) => (
353
+ <div
354
+ key={i}
355
+ className={`
356
  text-[10px] px-1.5 py-0.5 rounded-sm truncate cursor-pointer hover:opacity-80
357
  ${event.color || 'bg-blue-500'} text-white font-medium shadow-sm backdrop-blur-sm bg-opacity-80
358
  `}
359
+ >
360
+ {event.title}
361
+ </div>
362
+ ))}
363
+ </div>
364
  </div>
365
+ )
366
+ })}
367
+ </div>
368
  </div>
369
  </motion.div>
370
  )}
 
375
  initial={{ opacity: 0 }}
376
  animate={{ opacity: 1 }}
377
  exit={{ opacity: 0 }}
378
+ className="h-full overflow-y-auto p-4 md:p-8 [&::-webkit-scrollbar-thumb]:bg-white/20 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar]:w-2"
379
  >
380
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 gap-y-12">
381
  {monthNames.map((month, monthIndex) => {
382
  const days = getDaysInMonth(currentDate.getFullYear(), monthIndex)
383
  return (
app/components/Messages.tsx CHANGED
@@ -115,7 +115,7 @@ export function Messages({ onClose, onMinimize, onMaximize, onFocus, zIndex }: M
115
  width={800}
116
  height={600}
117
  x={100}
118
- y={100}
119
  className="messages-window !bg-[#1e1e1e]/80 !backdrop-blur-2xl border border-white/10 shadow-2xl !rounded-xl overflow-hidden"
120
  contentClassName="!bg-transparent"
121
  headerClassName="!bg-transparent border-b border-white/5"
 
115
  width={800}
116
  height={600}
117
  x={100}
118
+ y={50}
119
  className="messages-window !bg-[#1e1e1e]/80 !backdrop-blur-2xl border border-white/10 shadow-2xl !rounded-xl overflow-hidden"
120
  contentClassName="!bg-transparent"
121
  headerClassName="!bg-transparent border-b border-white/5"